commit f79ed7c8e454ce408bee6cf0f57a2887386b95c7 Author: ld3zian <42660576+ld3z@users.noreply.github.com> Date: Sat Jan 4 22:46:09 2025 -0700 init diff --git a/.vitepress/config.mts b/.vitepress/config.mts new file mode 100644 index 0000000..f0fbfc2 --- /dev/null +++ b/.vitepress/config.mts @@ -0,0 +1,102 @@ +import { defineConfig } from "vitepress"; +import UnoCSS from "unocss/vite"; +import { emojiRender, defs, movePlugin } from "./configs/"; +import { generateSidebar } from "vitepress-sidebar"; + +// @unocss-include + +// https://vitepress.dev/reference/site-config +export default defineConfig({ + title: "DP-Salad", + description: "A guide to fully deploy the DP-Salad Stack", + cleanUrls: true, + appearance: "dark", + themeConfig: { + // https://vitepress.dev/reference/default-theme-config + logo: "/saladicon.png", + nav: [ + { text: "Home", link: "/" }, + { text: "FAQ", link: "/faq" }, + { text: "Docker Compose", link: "/docker-compose" }, + { text: "Maintenance", link: "/maintenance/maintain-guide" }, + { + text: "Install", + items: [ + { text: "DP-Salad Requirements", link: "/install/requirements" }, + { + text: "Installing Debian and Portainer", + link: "/install/dp-setup", + }, + { text: "Configuration", link: "/install/dp-config" }, + { text: "DP-Salad Setup", link: "/install/salad-setup" }, + ], + }, + { + text: "Config", + items: [ + { text: "Swag Config", link: "/configuration/swag-config" }, + { text: "Authelia Config", link: "/configuration/auth-config" }, + { text: "LLDAP Config", link: "/configuration/lldap-config" }, + { text: "Authy/Duo Config", link: "/configuration/authy-duo-config" }, + ], + }, + { + text: "Misc", + items: [ + { text: "X11 Guide", link: "/x11-guide" }, + { text: "Cloudflare Tunneling", link: "/cf-tunnel" }, + ], + }, + ], + + sidebar: generateSidebar({ + documentRootPath: "/", + collapsed: false, + capitalizeFirst: true, + useTitleFromFrontmatter: true, + manualSortFileNameByPriority: ["home.md"], + excludePattern: [ + "changelog.md", + "cf-tunnel.md", + "faq.md", + "docker-compose.md", + "x11-guide.md", + ], + }), + + search: { + provider: "local", + }, + footer: { + message: "Docs created by @ldez", + copyright: "Copyright © 2024-present @Cdez", + }, + }, + head: [ + ["link", { rel: "icon", type: "image/x-icon", href: "/asset/favicon.ico" }], + ], + markdown: { + emoji: { defs }, + config(md) { + md.use(emojiRender); + }, + }, + vite: { + plugins: [ + UnoCSS({ + configFile: "../unocss.config.ts", + }), + { + name: "custom:adjust-order", + configResolved(c) { + movePlugin( + c.plugins as any, + "vitepress", + "before", + "unocss:transformers:pre" + ); + }, + }, + ], + }, +}); diff --git a/.vitepress/configs/emoji.ts b/.vitepress/configs/emoji.ts new file mode 100644 index 0000000..a75a5f0 --- /dev/null +++ b/.vitepress/configs/emoji.ts @@ -0,0 +1,76 @@ +import type { MarkdownRenderer } from "vitepress"; +import type { IconifyJSON } from "@iconify-json/octicon"; + +// Icons that need to be used should be imported here +import { icons as twemoji } from "@iconify-json/twemoji"; +import { icons as octicon } from "@iconify-json/octicon"; +import { icons as logos } from "@iconify-json/logos"; +import { icons as ic } from "@iconify-json/ic"; +import { icons as mingcute } from "@iconify-json/mingcute"; +import { icons as mdi } from "@iconify-json/mdi"; +import { icons as materials } from "@iconify-json/material-symbols"; +import { icons as simple } from "@iconify-json/simple-icons"; +import { icons as gg } from "@iconify-json/gg"; + +// 1. Install emoji pack with `pnpm add -g @iconify-json/` +// 2. Import them like I did above +// 3. Add it to this emojis array, like I did for octicon, and add a prefix +const emojis: { pack: IconifyJSON; prefix?: string }[] = [ + // Default emojis (twemoji) + { pack: twemoji }, + // octicon emojis, prefixed with "octicon-" + { pack: octicon, prefix: "octicon-" }, + { pack: logos, prefix: "logos-" }, + { pack: ic, prefix: "ic-" }, + { pack: mingcute, prefix: "mingcute-" }, + { pack: mdi, prefix: "mdi-" }, + { pack: materials, prefix: "material-symbols-" }, + { pack: simple, prefix: "simple-icons-" }, + { pack: gg, prefix: "gg-" }, +]; + +const defs: Record = {}; + +for (const elem of emojis) { + for (const key in elem.pack.icons) { + if (elem.prefix) defs[elem.prefix + key] = ""; + else defs[key] = ""; + } +} + +export { defs }; + +export function emojiRender(md: MarkdownRenderer) { + md.renderer.rules.emoji = (tokens, idx) => { + for (const emoji of emojis) { + if (tokens[idx].markup.startsWith(emoji.prefix!)) { + return ``; + } + } + + return ``; + }; +} + +export function movePlugin( + plugins: { name: string }[], + pluginAName: string, + order: "before" | "after", + pluginBName: string, +) { + const pluginBIndex = plugins.findIndex((p) => p.name === pluginBName); + if (pluginBIndex === -1) return; + + const pluginAIndex = plugins.findIndex((p) => p.name === pluginAName); + if (pluginAIndex === -1) return; + + if (order === "before" && pluginAIndex > pluginBIndex) { + const pluginA = plugins.splice(pluginAIndex, 1)[0]; + plugins.splice(pluginBIndex, 0, pluginA); + } + + if (order === "after" && pluginAIndex < pluginBIndex) { + const pluginA = plugins.splice(pluginAIndex, 1)[0]; + plugins.splice(pluginBIndex, 0, pluginA); + } +} \ No newline at end of file diff --git a/.vitepress/configs/index.ts b/.vitepress/configs/index.ts new file mode 100644 index 0000000..7c9e612 --- /dev/null +++ b/.vitepress/configs/index.ts @@ -0,0 +1 @@ +export * from "./emoji"; \ No newline at end of file diff --git a/.vitepress/dist/404.html b/.vitepress/dist/404.html new file mode 100644 index 0000000..f4a4abf --- /dev/null +++ b/.vitepress/dist/404.html @@ -0,0 +1,23 @@ + + + + + + 404 | DP-Salad + + + + + + + + + + + + +
+ + + + \ No newline at end of file diff --git a/.vitepress/dist/asset/favicon.ico b/.vitepress/dist/asset/favicon.ico new file mode 100644 index 0000000..6a4e41c Binary files /dev/null and b/.vitepress/dist/asset/favicon.ico differ diff --git a/.vitepress/dist/assets/app.D2AcNbxn.js b/.vitepress/dist/assets/app.D2AcNbxn.js new file mode 100644 index 0000000..73efdfd --- /dev/null +++ b/.vitepress/dist/assets/app.D2AcNbxn.js @@ -0,0 +1 @@ +import{R as i}from"./chunks/theme.Chl5AtGS.js";import{R as o,a4 as u,a5 as c,a6 as l,a7 as f,a8 as d,a9 as m,aa as h,ab as g,ac as A,ad as v,d as P,u as R,v as w,s as y,ae as C,af as b,ag as E,a2 as S}from"./chunks/framework.DtMx7FFi.js";function p(e){if(e.extends){const a=p(e.extends);return{...a,...e,async enhanceApp(t){a.enhanceApp&&await a.enhanceApp(t),e.enhanceApp&&await e.enhanceApp(t)}}}return e}const s=p(i),T=P({name:"VitePressApp",setup(){const{site:e,lang:a,dir:t}=R();return w(()=>{y(()=>{document.documentElement.lang=a.value,document.documentElement.dir=t.value})}),e.value.router.prefetchLinks&&C(),b(),E(),s.setup&&s.setup(),()=>S(s.Layout)}});async function D(){globalThis.__VITEPRESS__=!0;const e=j(),a=_();a.provide(c,e);const t=l(e.route);return a.provide(f,t),a.component("Content",d),a.component("ClientOnly",m),Object.defineProperties(a.config.globalProperties,{$frontmatter:{get(){return t.frontmatter.value}},$params:{get(){return t.page.value.params}}}),s.enhanceApp&&await s.enhanceApp({app:a,router:e,siteData:h}),{app:a,router:e,data:t}}function _(){return g(T)}function j(){let e=o,a;return A(t=>{let n=v(t),r=null;return n&&(e&&(a=n),(e||a===n)&&(n=n.replace(/\.js$/,".lean.js")),r=import(n)),o&&(e=!1),r},s.NotFound)}o&&D().then(({app:e,router:a,data:t})=>{a.go().then(()=>{u(a.route,t.site),e.mount("#app")})});export{D as createApp}; diff --git a/.vitepress/dist/assets/cf-tunnel.md.DCFtN7s5.js b/.vitepress/dist/assets/cf-tunnel.md.DCFtN7s5.js new file mode 100644 index 0000000..c99cf1f --- /dev/null +++ b/.vitepress/dist/assets/cf-tunnel.md.DCFtN7s5.js @@ -0,0 +1,70 @@ +import{_ as i,c as a,a3 as n,o as l}from"./chunks/framework.DtMx7FFi.js";const e="/cat-typing.gif",g=JSON.parse('{"title":"Cloudflare Tunneling","description":"","frontmatter":{"title":"Cloudflare Tunneling"},"headers":[],"relativePath":"cf-tunnel.md","filePath":"cf-tunnel.md"}'),t={name:"cf-tunnel.md"};function p(h,s,k,E,r,d){return l(),a("div",null,s[0]||(s[0]=[n(`

Cloudflare Tunnel Setup: ​

Sometimes, someone might want to deploy the DP-SALAD stack behind NAT or you don't want to open your network's ports exposing them to the outside.

Note:

You do not need to have your domain registered through Cloudflare to use Cloudflare Tunnels

THE SOLUTION? ​

Cloudflare Tunnels

Of course, running the stack this way comes with some extra configuartion on both the Docker side and Cloudflare/domain side.

This is an excerpt from the One-Click Docker Compose file:

In order to make this work with cloudflare tunneling, you must add some more lines to your docker compose. The first being a directive which is highlighted below:

yml
version: "2.1"
+services:
+  swag:
+    image: lscr.io/linuxserver/swag:latest
+    container_name: swag
+    cap_add:
+      - NET_ADMIN
+    environment:
+      - PUID=1000
+      - PGID=1000
+      - TZ=America/Phoenix
+      - URL=[sakura.nt]
+      - VALIDATION=dns
+      - SUBDOMAINS=wildcard
+      - DNSPLUGIN=cloudflare
+      - EMAIL=[sakurant@gmail.com]
+      - ONLY_SUBDOMAINS=false
+      #- EXTRA_DOMAINS= #optional
+      - STAGING=false
+      - DOCKER_MODS=linuxserver/mods:universal-docker|linuxserver/mods:swag-auto-reload|linuxserver/mods:swag-dashboard|linuxserver/mods:swag-dbip|linuxserver/mods:universal-cloudflared
+    extra_hosts:
+        - domain.tld:127.0.0.1
+    volumes:
+      - /home/[INSERT USER FOLDER HERE]/appdata/swag:/config
+    ports:
+      - 443:443
+      - 80:80
+    networks:
+      - [INSERT NETWORK NAME HERE]
+    restart: unless-stopped

Next, you'll want to generate an API key with Cloudflare , go to Overview in your domain, and click "get your api token", click Create Token, use → "Edit zone DNS" template, add a permission, select "Account", → "Cloudflare Tunnel", → "Edit", under account resources, include your account, under zone resources, include your domain. Continue with setup, make sure you keep track of the API key somewhere.

After you have completed these steps, you will need to add these credentials to your Swag configuration in the docker-compose.yml. After the Docker_Mods environment variable, add these lines:

yml
version: "2.1"
+services:
+  swag:
+    image: lscr.io/linuxserver/swag:latest
+    container_name: swag
+    cap_add:
+      - NET_ADMIN
+    environment:
+      - PUID=1000
+      - PGID=1000
+      - TZ=America/Phoenix
+      - URL=[sakura.nt]
+      - VALIDATION=dns
+      - SUBDOMAINS=wildcard
+      - DNSPLUGIN=cloudflare
+      - EMAIL=[sakurant@gmail.com]
+      - ONLY_SUBDOMAINS=false
+      #- EXTRA_DOMAINS= #optional
+      - STAGING=false
+      - DOCKER_MODS=linuxserver/mods:universal-docker|linuxserver/mods:swag-auto-reload|linuxserver/mods:swag-dashboard|linuxserver/mods:swag-dbip|linuxserver/mods:universal-cloudflared
+      - CF_ZONE_ID=zone id from cloudflare domain overview
+      - CF_ACCOUNT_ID=account id from cloudflare domain overview
+      - CF_API_TOKEN=api token generated
+      - CF_TUNNEL_NAME=create a tunnel, name it whatever
+      - CF_TUNNEL_PASSWORD=generate a long password
+      - FILE__CF_TUNNEL_CONFIG=/config/tunnelconfig.yml
+    extra_hosts:
+        - domain.tld:127.0.0.1
+    volumes:
+      - /home/[INSERT USER FOLDER HERE]/appdata/swag:/config
+    ports:
+      - 443:443
+      - 80:80
+    networks:
+      - [INSERT NETWORK NAME HERE]
+    restart: unless-stopped

You're not quite done yet...

You'll need to add more to finish the installation: First, nano /home/[USER]/appdata/swag/tunnelconfig.yml, and add these contents:

yml
ingress:
+  - hostname: domain.tld
+    service: https://domain.tld
+  - hostname: "*.domain.tld"
+    service: https://domain.tld
+  - service: http_status:404

Then, edit the /home/[USER]/appdata/swag/dns-conf/cloudflare.ini, add the API token, you'll comment the top two lines, add the token after uncommenting the bottom line.

insert funni meeme here:

/cat-typing.gif

',17)]))}const c=i(t,[["render",p]]);export{g as __pageData,c as default}; diff --git a/.vitepress/dist/assets/cf-tunnel.md.DCFtN7s5.lean.js b/.vitepress/dist/assets/cf-tunnel.md.DCFtN7s5.lean.js new file mode 100644 index 0000000..c99cf1f --- /dev/null +++ b/.vitepress/dist/assets/cf-tunnel.md.DCFtN7s5.lean.js @@ -0,0 +1,70 @@ +import{_ as i,c as a,a3 as n,o as l}from"./chunks/framework.DtMx7FFi.js";const e="/cat-typing.gif",g=JSON.parse('{"title":"Cloudflare Tunneling","description":"","frontmatter":{"title":"Cloudflare Tunneling"},"headers":[],"relativePath":"cf-tunnel.md","filePath":"cf-tunnel.md"}'),t={name:"cf-tunnel.md"};function p(h,s,k,E,r,d){return l(),a("div",null,s[0]||(s[0]=[n(`

Cloudflare Tunnel Setup: ​

Sometimes, someone might want to deploy the DP-SALAD stack behind NAT or you don't want to open your network's ports exposing them to the outside.

Note:

You do not need to have your domain registered through Cloudflare to use Cloudflare Tunnels

THE SOLUTION? ​

Cloudflare Tunnels

Of course, running the stack this way comes with some extra configuartion on both the Docker side and Cloudflare/domain side.

This is an excerpt from the One-Click Docker Compose file:

In order to make this work with cloudflare tunneling, you must add some more lines to your docker compose. The first being a directive which is highlighted below:

yml
version: "2.1"
+services:
+  swag:
+    image: lscr.io/linuxserver/swag:latest
+    container_name: swag
+    cap_add:
+      - NET_ADMIN
+    environment:
+      - PUID=1000
+      - PGID=1000
+      - TZ=America/Phoenix
+      - URL=[sakura.nt]
+      - VALIDATION=dns
+      - SUBDOMAINS=wildcard
+      - DNSPLUGIN=cloudflare
+      - EMAIL=[sakurant@gmail.com]
+      - ONLY_SUBDOMAINS=false
+      #- EXTRA_DOMAINS= #optional
+      - STAGING=false
+      - DOCKER_MODS=linuxserver/mods:universal-docker|linuxserver/mods:swag-auto-reload|linuxserver/mods:swag-dashboard|linuxserver/mods:swag-dbip|linuxserver/mods:universal-cloudflared
+    extra_hosts:
+        - domain.tld:127.0.0.1
+    volumes:
+      - /home/[INSERT USER FOLDER HERE]/appdata/swag:/config
+    ports:
+      - 443:443
+      - 80:80
+    networks:
+      - [INSERT NETWORK NAME HERE]
+    restart: unless-stopped

Next, you'll want to generate an API key with Cloudflare , go to Overview in your domain, and click "get your api token", click Create Token, use → "Edit zone DNS" template, add a permission, select "Account", → "Cloudflare Tunnel", → "Edit", under account resources, include your account, under zone resources, include your domain. Continue with setup, make sure you keep track of the API key somewhere.

After you have completed these steps, you will need to add these credentials to your Swag configuration in the docker-compose.yml. After the Docker_Mods environment variable, add these lines:

yml
version: "2.1"
+services:
+  swag:
+    image: lscr.io/linuxserver/swag:latest
+    container_name: swag
+    cap_add:
+      - NET_ADMIN
+    environment:
+      - PUID=1000
+      - PGID=1000
+      - TZ=America/Phoenix
+      - URL=[sakura.nt]
+      - VALIDATION=dns
+      - SUBDOMAINS=wildcard
+      - DNSPLUGIN=cloudflare
+      - EMAIL=[sakurant@gmail.com]
+      - ONLY_SUBDOMAINS=false
+      #- EXTRA_DOMAINS= #optional
+      - STAGING=false
+      - DOCKER_MODS=linuxserver/mods:universal-docker|linuxserver/mods:swag-auto-reload|linuxserver/mods:swag-dashboard|linuxserver/mods:swag-dbip|linuxserver/mods:universal-cloudflared
+      - CF_ZONE_ID=zone id from cloudflare domain overview
+      - CF_ACCOUNT_ID=account id from cloudflare domain overview
+      - CF_API_TOKEN=api token generated
+      - CF_TUNNEL_NAME=create a tunnel, name it whatever
+      - CF_TUNNEL_PASSWORD=generate a long password
+      - FILE__CF_TUNNEL_CONFIG=/config/tunnelconfig.yml
+    extra_hosts:
+        - domain.tld:127.0.0.1
+    volumes:
+      - /home/[INSERT USER FOLDER HERE]/appdata/swag:/config
+    ports:
+      - 443:443
+      - 80:80
+    networks:
+      - [INSERT NETWORK NAME HERE]
+    restart: unless-stopped

You're not quite done yet...

You'll need to add more to finish the installation: First, nano /home/[USER]/appdata/swag/tunnelconfig.yml, and add these contents:

yml
ingress:
+  - hostname: domain.tld
+    service: https://domain.tld
+  - hostname: "*.domain.tld"
+    service: https://domain.tld
+  - service: http_status:404

Then, edit the /home/[USER]/appdata/swag/dns-conf/cloudflare.ini, add the API token, you'll comment the top two lines, add the token after uncommenting the bottom line.

insert funni meeme here:

/cat-typing.gif

',17)]))}const c=i(t,[["render",p]]);export{g as __pageData,c as default}; diff --git a/.vitepress/dist/assets/changelog.md.DF8BSN3_.js b/.vitepress/dist/assets/changelog.md.DF8BSN3_.js new file mode 100644 index 0000000..d2d32e1 --- /dev/null +++ b/.vitepress/dist/assets/changelog.md.DF8BSN3_.js @@ -0,0 +1 @@ +import{_ as l,c as a,a3 as i,o}from"./chunks/framework.DtMx7FFi.js";const m=JSON.parse('{"title":"Changelog","description":"","frontmatter":{"title":"Changelog","sidebar":false},"headers":[],"relativePath":"changelog.md","filePath":"changelog.md"}'),d={name:"changelog.md"};function n(t,e,s,r,c,h){return o(),a("div",null,e[0]||(e[0]=[i('

Changelog ​

Version 1.1.0: 11-20-24 ​

Version 1.0.4: 10-11-24 ​

Version 1.0.3: 07-07-24 ​

Version 1.0.2: 06-22-24 ​

Version 1.0.1: 06-19-24 ​

',11)]))}const g=l(d,[["render",n]]);export{m as __pageData,g as default}; diff --git a/.vitepress/dist/assets/changelog.md.DF8BSN3_.lean.js b/.vitepress/dist/assets/changelog.md.DF8BSN3_.lean.js new file mode 100644 index 0000000..d2d32e1 --- /dev/null +++ b/.vitepress/dist/assets/changelog.md.DF8BSN3_.lean.js @@ -0,0 +1 @@ +import{_ as l,c as a,a3 as i,o}from"./chunks/framework.DtMx7FFi.js";const m=JSON.parse('{"title":"Changelog","description":"","frontmatter":{"title":"Changelog","sidebar":false},"headers":[],"relativePath":"changelog.md","filePath":"changelog.md"}'),d={name:"changelog.md"};function n(t,e,s,r,c,h){return o(),a("div",null,e[0]||(e[0]=[i('

Changelog ​

Version 1.1.0: 11-20-24 ​

Version 1.0.4: 10-11-24 ​

Version 1.0.3: 07-07-24 ​

Version 1.0.2: 06-22-24 ​

Version 1.0.1: 06-19-24 ​

',11)]))}const g=l(d,[["render",n]]);export{m as __pageData,g as default}; diff --git a/.vitepress/dist/assets/chunks/@localSearchIndexroot.DDTBqYgg.js b/.vitepress/dist/assets/chunks/@localSearchIndexroot.DDTBqYgg.js new file mode 100644 index 0000000..7931f5b --- /dev/null +++ b/.vitepress/dist/assets/chunks/@localSearchIndexroot.DDTBqYgg.js @@ -0,0 +1 @@ +const e='{"documentCount":57,"nextId":57,"documentIds":{"0":"/cf-tunnel#cloudflare-tunnel-setup","1":"/cf-tunnel#the-solution","2":"/changelog#changelog","3":"/changelog#version-1-1-0-11-20-24","4":"/changelog#version-1-0-4-10-11-24","5":"/changelog#version-1-0-3-07-07-24","6":"/changelog#version-1-0-2-06-22-24","7":"/changelog#version-1-0-1-06-19-24","8":"/configuration/authy-duo-config#authy-duo-configuration","9":"/configuration/auth-config#authelia-configuration","10":"/configuration/lldap-config#lldap-configuration","11":"/configuration/swag-config#swag-configuration","12":"/docker-compose#one-file-docker-compose-one-file-to-rule-them-all","13":"/faq#frequently-asked-questions","14":"/faq#how-do-i-insert-question-here","15":"/faq#how-do-i-add-a-new-application-to-my-stack","16":"/faq#how-do-i-add-lldap-authentication-to-service","17":"/faq#how-do-i-handle-user-creation","18":"/home#welcome","19":"/home#legacy-instructions","20":"/install/dp-config#configuration","21":"/install/dp-config#debian-configuration","22":"/install/dp-config#portainer-configuration","23":"/install/dp-config#app-templates","24":"/install/dp-setup#dp-setup","25":"/install/dp-setup#debian-12-setup","26":"/install/dp-setup#sudo-no-worky","27":"/install/dp-setup#disabling-gui","28":"/install/dp-setup#updating-your-system","29":"/install/dp-setup#installing-the-docker","30":"/install/dp-setup#portainer-ce-setup","31":"/install/dp-setup#some-changes-need-to-be-made","32":"/install/requirements#dp-sala-d-stack-pronounced-as-dp-salad-but-stylized-as-dp-sala-d","33":"/install/requirements#where-does-the-acronym-originate-from","34":"/install/requirements#minimum-requirements-for-the-dp-sala-d-stack","35":"/install/requirements#debian-12","36":"/install/requirements#portainer","37":"/install/requirements#swag","38":"/install/requirements#authelia","39":"/install/requirements#authy-duo","40":"/install/requirements#overall-minimum","41":"/install/requirements#what-this-guide-assumes","42":"/install/salad-setup#sala-d-setup","43":"/install/salad-setup#overview-of-the-sala-d-stack","44":"/maintenance/maintain-guide#maintenance-of-the-dp-sala-d-stack","45":"/maintenance/maintain-guide#required-maintenance-for-the-dp-sala-d-stack","46":"/x11-guide#windows-setup","47":"/x11-guide#windows-x11-window-manager-client-server","48":"/x11-guide#running-the-x11-local-server-aka-the-client-that-connects-to-the-real-x11-server","49":"/x11-guide#connecting-to-the-domain-tld-x11-server","50":"/x11-guide#putty-instructions-including-setting-up-a-profile-for-easier-management","51":"/x11-guide#windows-powershell-instructions","52":"/x11-guide#windows-command-prompt-instructions-a-k-a-cmd","53":"/x11-guide#macos-setup","54":"/x11-guide#macos-x11-window-manager-client-server","55":"/x11-guide#running-the-x11-local-server-on-mac-aka-the-client-that-connects-to-the-real-x11-server","56":"/x11-guide#connecting-to-the-domain-tld-x11-server-on-mac"},"fieldIds":{"title":0,"titles":1,"text":2},"fieldLength":{"0":[4,1,37],"1":[3,4,224],"2":[1,1,1],"3":[6,1,22],"4":[7,1,10],"5":[6,1,20],"6":[7,1,22],"7":[6,1,28],"8":[3,1,158],"9":[2,1,1311],"10":[2,1,404],"11":[2,1,167],"12":[9,1,196],"13":[3,1,1],"14":[7,3,15],"15":[11,3,182],"16":[9,3,304],"17":[7,3,147],"18":[2,1,68],"19":[3,2,82],"20":[1,1,1],"21":[2,1,42],"22":[2,1,78],"23":[2,1,65],"24":[2,1,10],"25":[3,2,153],"26":[3,2,83],"27":[2,2,33],"28":[3,2,36],"29":[3,2,112],"30":[3,2,99],"31":[6,2,46],"32":[10,1,1],"33":[7,10,25],"34":[9,10,32],"35":[2,14,12],"36":[1,14,12],"37":[1,14,18],"38":[1,14,13],"39":[2,14,31],"40":[3,14,38],"41":[5,10,102],"42":[3,1,11],"43":[7,3,123],"44":[7,1,9],"45":[8,7,158],"46":[3,1,1],"47":[6,3,16],"48":[13,7,81],"49":[7,7,21],"50":[11,7,110],"51":[3,7,59],"52":[8,7,54],"53":[3,1,1],"54":[6,3,25],"55":[15,7,22],"56":[9,7,37]},"averageFieldLength":[4.947368421052629,4.1228070175438605,90.68421052631582],"storedFields":{"0":{"title":"Cloudflare Tunnel Setup:","titles":[]},"1":{"title":"THE SOLUTION?","titles":["Cloudflare Tunnel Setup:"]},"2":{"title":"Changelog","titles":[]},"3":{"title":"Version 1.1.0: 11-20-24","titles":["Changelog"]},"4":{"title":"Version 1.0.4: 10-11-24","titles":["Changelog"]},"5":{"title":"Version 1.0.3: 07-07-24","titles":["Changelog"]},"6":{"title":"Version 1.0.2: 06-22-24","titles":["Changelog"]},"7":{"title":"Version 1.0.1: 06-19-24","titles":["Changelog"]},"8":{"title":"Authy/Duo Configuration","titles":[]},"9":{"title":"Authelia Configuration","titles":[]},"10":{"title":"LLDAP Configuration","titles":[]},"11":{"title":"SWAG Configuration","titles":[]},"12":{"title":"One File Docker Compose (One File to Rule them all!)","titles":[]},"13":{"title":"Frequently Asked Questions","titles":[]},"14":{"title":"How do I [Insert Question Here]?","titles":["Frequently Asked Questions"]},"15":{"title":"How do I add a new application to my stack?","titles":["Frequently Asked Questions"]},"16":{"title":"How do I add LLDAP Authentication to [SERVICE]?","titles":["Frequently Asked Questions"]},"17":{"title":"How do I handle user creation?","titles":["Frequently Asked Questions"]},"18":{"title":"Welcome!","titles":[]},"19":{"title":"Legacy Instructions:","titles":["Welcome!"]},"20":{"title":"Configuration","titles":[]},"21":{"title":"Debian Configuration","titles":["Configuration"]},"22":{"title":"Portainer Configuration","titles":["Configuration"]},"23":{"title":"App Templates","titles":["Configuration"]},"24":{"title":"DP-Setup","titles":[]},"25":{"title":"Debian 12 Setup","titles":["DP-Setup"]},"26":{"title":"Sudo no worky","titles":["DP-Setup"]},"27":{"title":"Disabling GUI","titles":["DP-Setup"]},"28":{"title":"Updating your system","titles":["DP-Setup"]},"29":{"title":"Installing the Docker","titles":["DP-Setup"]},"30":{"title":"Portainer CE Setup","titles":["DP-Setup"]},"31":{"title":"Some changes need to be made","titles":["DP-Setup"]},"32":{"title":"DP-SALA/D Stack (pronounced as DP-Salad but stylized as DP-SALA/D)","titles":[]},"33":{"title":"Where does the acronym originate from?","titles":["DP-SALA/D Stack (pronounced as DP-Salad but stylized as DP-SALA/D)"]},"34":{"title":"Minimum Requirements for the DP-SALA/D Stack:","titles":["DP-SALA/D Stack (pronounced as DP-Salad but stylized as DP-SALA/D)"]},"35":{"title":"Debian 12","titles":["DP-SALA/D Stack (pronounced as DP-Salad but stylized as DP-SALA/D)","Minimum Requirements for the DP-SALA/D Stack:"]},"36":{"title":"Portainer","titles":["DP-SALA/D Stack (pronounced as DP-Salad but stylized as DP-SALA/D)","Minimum Requirements for the DP-SALA/D Stack:"]},"37":{"title":"SWAG","titles":["DP-SALA/D Stack (pronounced as DP-Salad but stylized as DP-SALA/D)","Minimum Requirements for the DP-SALA/D Stack:"]},"38":{"title":"Authelia","titles":["DP-SALA/D Stack (pronounced as DP-Salad but stylized as DP-SALA/D)","Minimum Requirements for the DP-SALA/D Stack:"]},"39":{"title":"Authy/Duo","titles":["DP-SALA/D Stack (pronounced as DP-Salad but stylized as DP-SALA/D)","Minimum Requirements for the DP-SALA/D Stack:"]},"40":{"title":"Overall Minimum:","titles":["DP-SALA/D Stack (pronounced as DP-Salad but stylized as DP-SALA/D)","Minimum Requirements for the DP-SALA/D Stack:"]},"41":{"title":"What this guide assumes:","titles":["DP-SALA/D Stack (pronounced as DP-Salad but stylized as DP-SALA/D)"]},"42":{"title":"SALA/D Setup","titles":[]},"43":{"title":"Overview of the SALA/D Stack:","titles":["SALA/D Setup"]},"44":{"title":"Maintenance of the DP-SALA/D Stack","titles":[]},"45":{"title":"Required Maintenance for the DP-SALA/D Stack","titles":["Maintenance of the DP-SALA/D Stack"]},"46":{"title":"Windows Setup:","titles":[]},"47":{"title":"Windows X11 Window Manager Client/Server","titles":["Windows Setup:"]},"48":{"title":"Running the X11 Local Server (aka the client that connects to the real X11 server)","titles":["Windows Setup:","Windows X11 Window Manager Client/Server"]},"49":{"title":"Connecting to the \'domain.tld\' X11 Server","titles":["Windows Setup:","Windows X11 Window Manager Client/Server"]},"50":{"title":"PuTTY Instructions (including setting up a profile for easier management)","titles":["Windows Setup:","Windows X11 Window Manager Client/Server"]},"51":{"title":"Windows Powershell Instructions","titles":["Windows Setup:","Windows X11 Window Manager Client/Server"]},"52":{"title":"Windows Command Prompt Instructions (a.k.a. CMD)","titles":["Windows Setup:","Windows X11 Window Manager Client/Server"]},"53":{"title":"MacOS Setup:","titles":[]},"54":{"title":"MacOS X11 Window Manager Client/Server","titles":["MacOS Setup:"]},"55":{"title":"Running the X11 Local Server on Mac (aka the client that connects to the real X11 server)","titles":["MacOS Setup:","MacOS X11 Window Manager Client/Server"]},"56":{"title":"Connecting to the \'domain.tld\' X11 Server on Mac","titles":["MacOS Setup:","MacOS X11 Window Manager Client/Server"]}},"dirtCount":0,"index":[["755",{"2":{"29":1}}],["71lggzn0fdhi1qu2h8m0hhk7tfw+5q6rlrldsyk0pitj71s9en7r8px820nafehz",{"2":{"9":6}}],["~",{"2":{"10":1}}],["+",{"2":{"10":1,"23":1,"34":1}}],["+5j3uayowgmk+dx7glasrgtvbqpuaivjah0rxdci3huvj1bbfakvizmxd9rgzaew",{"2":{"9":6}}],[">",{"2":{"9":1,"10":1,"29":1}}],["$env",{"2":{"51":1}}],["$version",{"2":{"29":1}}],["$protocal",{"2":{"15":1}}],["$port",{"2":{"15":1}}],["$location",{"2":{"15":1}}],["$upstream",{"2":{"15":7}}],["$",{"2":{"9":4,"29":1}}],["^~",{"2":{"15":1}}],["^appgroup2",{"2":{"9":1}}],["^appgroup",{"2":{"9":1}}],["^",{"2":{"9":7,"10":1}}],["=>",{"2":{"10":1}}],["=",{"2":{"9":6,"10":16,"16":3}}],["xterm",{"2":{"56":1}}],["xtem",{"2":{"55":1}}],["xquartz",{"2":{"54":2,"55":1}}],["xclock",{"2":{"50":1,"51":1,"52":1,"56":1}}],["x",{"2":{"50":1,"51":2,"52":2,"56":1}}],["xlaunch",{"2":{"48":2,"49":1}}],["x11",{"0":{"47":1,"48":2,"49":1,"54":1,"55":2,"56":1},"1":{"48":1,"49":1,"50":1,"51":1,"52":1,"55":1,"56":1},"2":{"48":1,"50":3,"51":1,"52":1,"56":1}}],["xfce",{"2":{"25":1}}],["x509",{"2":{"9":1}}],["x26",{"2":{"9":7,"10":1,"16":2,"29":2}}],["xwmm0chwube6sdrrud7sy20ku",{"2":{"9":6}}],["x3c",{"2":{"9":9,"10":5}}],["z0",{"2":{"10":1}}],["za",{"2":{"10":1}}],["zadbgnvhq4efgqu",{"2":{"9":6}}],["zxcvbn",{"2":{"9":2}}],["zxjpg7xz+hgfwm",{"2":{"9":6}}],["ze5m4whasleet+m00gevnau9nd+z0wbfi+",{"2":{"9":6}}],["z7ata3mzfc0insba5fimfelxa3owdqyjkozihvcnaqelbqadggebaee5hm1mtlk",{"2":{"9":6}}],["zftvm+xnejqkfqfgimerfg",{"2":{"9":6}}],["zsjnr9jqhtjhylvbdrlmjzcqoj4jhbks6",{"2":{"9":6}}],["zone",{"2":{"1":3}}],["q1nulyu2bc6tn",{"2":{"9":6}}],["qocikt3wadu^invalid",{"2":{"9":6}}],["qiiw5s6fdaevgleeod4zochywz",{"2":{"9":6}}],["qi",{"2":{"9":6}}],["q",{"2":{"9":6,"14":1}}],["quick",{"2":{"14":1,"16":1,"50":1}}],["quite",{"2":{"1":1}}],["question",{"0":{"14":1}}],["questions",{"0":{"13":1},"1":{"14":1,"15":1,"16":1,"17":1},"2":{"14":1}}],["query",{"2":{"9":1}}],["queries",{"2":{"9":2}}],["quotes",{"2":{"9":1,"26":1,"50":1}}],["quot",{"2":{"1":10,"6":4,"8":4,"11":2,"12":2,"16":8,"17":2,"22":4,"25":6,"30":2,"43":2,"45":2,"51":2}}],["|",{"2":{"9":13,"10":2,"16":2,"29":2}}],["`postgres`",{"2":{"9":1}}],["`mysql`",{"2":{"9":1}}],["`memory`",{"2":{"9":1}}],["`local`",{"2":{"9":1}}],["`ldap`",{"2":{"9":1}}],["`redis`",{"2":{"9":1}}],["`groupofuniquenames`",{"2":{"9":1}}],["`certificates",{"2":{"9":5}}],["`file`",{"2":{"9":1}}],["6379",{"2":{"9":3,"12":1}}],["65536",{"2":{"9":1}}],["6dzcp9ghlnaxnmsp9etdckoszh636jpgvj6m+gpjssbkuruiq3oyokmnwfqvlnos",{"2":{"9":6}}],["6icfosz4fuhewyyps8sspu",{"2":{"9":6}}],["60s",{"2":{"9":1}}],["6",{"2":{"9":2,"26":1}}],["6s",{"2":{"9":4}}],["9443",{"2":{"30":3}}],["90m",{"2":{"9":1}}],["9091",{"2":{"9":1,"12":1}}],["9",{"2":{"9":1,"10":1}}],["9ogan+fz2d",{"2":{"9":6}}],["91amjlhpivg8e4jwkq4lvqukbmifywidk8xqin4bly9wwxwjfys5sq",{"2":{"9":6}}],["9959",{"2":{"9":1}}],["k",{"0":{"52":1}}],["kubernetes",{"2":{"9":4}}],["kxou5jhasfhkuxi3lrlcb9hey1d8srzvnvaaqrgmwl6cqjkornhhhnh44+qerzf+",{"2":{"9":6}}],["kvicohh4evbpw7rxpxdftiqlqyttvmm4ewy",{"2":{"9":6}}],["knrmkfzzqasvcgv0ld5kwvucnl6wgf1otxg7aztdua4oskup321gpombc5+5elu7",{"2":{"9":6}}],["knowledge",{"2":{"40":1,"41":1}}],["known",{"2":{"9":2}}],["know",{"2":{"9":3,"17":1}}],["kwzl8ifo0vbssrdf1alehnlekp1spaxxg",{"2":{"9":6}}],["kwoh7gejfxgouopauiuezsmslqp7zqah39n0zsyb6cs0npj57qowzsy3ak87ebcr",{"2":{"9":6}}],["keep",{"2":{"1":1,"9":1,"15":3,"25":2,"45":3}}],["keyrings",{"2":{"29":4}}],["keys",{"2":{"9":1,"11":1}}],["key",{"2":{"1":2,"9":50,"10":14,"50":1}}],["john",{"2":{"9":3}}],["jxweixt3cgemo4mj4+kwiwochrti3qfbg6i6ldyys6qyls7slfbudc7hltcroeme",{"2":{"9":6}}],["jah",{"2":{"9":6}}],["jfxy4emo9s1s6y7oobsukwkdsnihakhx",{"2":{"9":6}}],["json",{"2":{"9":2,"23":1}}],["jwts",{"2":{"10":1}}],["jwt",{"2":{"9":5,"10":4,"12":1}}],["just",{"2":{"6":1,"9":2,"10":1,"16":1,"17":1,"28":1,"45":3}}],["502",{"2":{"15":2}}],["50000",{"2":{"9":1}}],["587",{"2":{"9":1}}],["5432",{"2":{"9":1}}],["5vxr6ohro",{"2":{"9":6}}],["5s",{"2":{"9":4,"16":1}}],["5m",{"2":{"9":4}}],["5",{"2":{"8":1,"25":1,"26":1,"40":1,"45":1}}],["8f2tf",{"2":{"9":6}}],["8",{"2":{"8":2,"9":6,"10":1,"19":2,"43":1}}],["8000",{"2":{"30":2}}],["8080",{"2":{"9":1}}],["80",{"2":{"1":4,"12":2}}],["38pm",{"2":{"19":1}}],["389",{"2":{"16":1}}],["3890",{"2":{"9":1,"10":1,"12":2,"16":2}}],["3306",{"2":{"9":1,"12":1}}],["310000",{"2":{"9":1}}],["35s6pvoakynaggqjtfp5ljuq",{"2":{"9":6}}],["3s",{"2":{"9":1}}],["32pm",{"2":{"19":1}}],["32",{"2":{"9":4,"10":1}}],["30",{"2":{"9":1,"40":1}}],["30s",{"2":{"9":2}}],["3",{"0":{"5":1},"2":{"9":8,"26":1,"45":1}}],["4096",{"2":{"9":4}}],["404",{"2":{"1":1}}],["4",{"0":{"4":1},"2":{"9":2,"26":1,"37":1,"40":1}}],["443",{"2":{"1":4,"12":2}}],["→",{"2":{"1":3,"23":1}}],["gb",{"2":{"35":2,"36":2,"37":2,"40":3}}],["gpg",{"2":{"29":4}}],["gnupg",{"2":{"29":1}}],["gnome",{"2":{"25":1}}],["guarantee",{"2":{"28":1}}],["gui",{"0":{"27":1},"2":{"23":1,"27":2}}],["guided",{"2":{"25":1}}],["guide",{"0":{"41":1},"2":{"22":1,"24":1,"29":1,"41":2,"43":1}}],["guidebook",{"2":{"19":1}}],["githubusercontent",{"2":{"23":1}}],["github",{"2":{"16":3,"43":1,"45":1}}],["giving",{"2":{"9":1}}],["given",{"2":{"17":1}}],["give",{"2":{"8":1,"16":1,"17":1}}],["gt",{"2":{"15":4}}],["gateway",{"2":{"11":2,"15":1}}],["gywcoqlntol1l+ej20eqozm23ngr5fisunsbwleptrdb",{"2":{"9":6}}],["gchq49q4i55lixkvcnvooaff03rljhvpxlq2mpntchzljjdqtzt5",{"2":{"9":6}}],["graphical",{"2":{"25":1}}],["grants",{"2":{"9":1}}],["grant",{"2":{"9":2}}],["greet",{"2":{"9":1,"16":1}}],["grey",{"2":{"9":1}}],["grouping",{"2":{"16":1}}],["group>",{"2":{"9":1}}],["groupname>",{"2":{"9":1}}],["group",{"2":{"9":15,"10":1,"16":11}}],["groups",{"2":{"9":15,"16":5,"17":1}}],["geoipblock",{"2":{"43":1}}],["generally",{"2":{"9":1,"45":1}}],["generation",{"2":{"9":1}}],["generates",{"2":{"8":1}}],["generated",{"2":{"1":1,"9":4,"10":1}}],["generate",{"2":{"1":1,"9":2,"10":2}}],["gesture",{"2":{"9":1}}],["getting",{"2":{"11":1,"15":1,"30":1}}],["get",{"2":{"1":1,"9":1,"21":2,"25":1,"28":2,"29":4,"43":1,"45":2}}],["gotten",{"2":{"40":1}}],["goes",{"2":{"17":1}}],["good",{"2":{"16":2,"30":1}}],["google",{"2":{"5":1,"16":2,"45":1}}],["going",{"2":{"8":1,"16":1,"30":1,"50":1}}],["go",{"2":{"1":1,"11":2,"17":2,"41":2}}],["gmail",{"2":{"1":2,"9":4,"10":3,"12":1,"41":2,"45":1}}],["vcxsrv",{"2":{"47":1}}],["v",{"2":{"30":2}}],["volume",{"2":{"30":1,"45":1}}],["volumes",{"2":{"1":2,"12":5}}],["vm",{"2":{"12":1,"19":1,"22":1}}],["vpn",{"2":{"9":2}}],["visit",{"2":{"15":1,"25":1,"30":1}}],["view",{"2":{"11":1}}],["vibvvwx8g2lv5fgoa+j2y7o9qurs8t5",{"2":{"9":6}}],["via",{"2":{"8":2,"10":1,"43":5}}],["very",{"2":{"34":1}}],["verbose=false",{"2":{"10":1}}],["verbose",{"2":{"10":2}}],["verbosity",{"2":{"9":1}}],["verify",{"2":{"9":6,"15":1,"16":1,"49":1,"50":1,"51":1,"52":1,"56":1}}],["verifying",{"2":{"9":6}}],["verification",{"2":{"9":2}}],["version",{"0":{"3":1,"4":1,"5":1,"6":1,"7":1},"2":{"3":1,"4":1,"5":1,"9":23,"16":1,"22":1,"25":1}}],["ve",{"2":{"8":1,"9":1,"11":1,"17":1,"45":1,"48":1}}],["var",{"2":{"9":1,"30":2}}],["variant",{"2":{"9":4}}],["variables",{"2":{"10":3}}],["variable",{"2":{"1":1,"10":9,"51":1,"52":1}}],["various",{"2":{"9":2}}],["vars",{"2":{"9":1}}],["validity",{"2":{"9":2}}],["validate",{"2":{"9":3}}],["validation",{"2":{"9":11}}],["validation=dns",{"2":{"1":2,"12":1}}],["validating",{"2":{"9":1}}],["valid",{"2":{"9":3}}],["value",{"2":{"9":13,"10":2,"50":1}}],["values",{"2":{"9":6,"10":5,"12":3,"50":1}}],["vaultwarden",{"2":{"8":2,"43":1}}],["03pm",{"2":{"19":2}}],["06",{"0":{"6":1,"7":1}}],["07",{"0":{"5":2}}],["0",{"0":{"3":1,"4":1,"5":1,"6":1,"7":1},"2":{"1":4,"9":31,"10":12,"17":1,"25":1,"50":3,"51":3,"52":3,"56":3}}],["utilities",{"2":{"25":1}}],["utilised",{"2":{"9":1}}],["u",{"2":{"21":1}}],["ui",{"2":{"16":1,"23":1}}],["uid=bind",{"2":{"16":1}}],["uid=",{"2":{"16":2}}],["uid",{"2":{"9":4,"16":6}}],["uymwbfi0h",{"2":{"9":6}}],["urandom",{"2":{"10":1}}],["uri",{"2":{"9":2}}],["uris",{"2":{"9":3}}],["urpfo4e7owdqyjkozihvcnaqelbqaw",{"2":{"9":6}}],["urls",{"2":{"10":1}}],["url",{"2":{"9":9,"10":5,"16":1,"23":1}}],["url=",{"2":{"1":2,"12":1}}],["upgrades",{"2":{"45":1}}],["upgrade",{"2":{"28":1}}],["updating",{"0":{"28":1}}],["updates",{"2":{"28":1,"33":1,"45":1}}],["update",{"2":{"9":1,"16":1,"28":1,"29":2,"45":7}}],["updated",{"2":{"3":1,"4":1,"5":1,"9":1,"19":4}}],["upper",{"2":{"12":1}}],["uppercase",{"2":{"9":2}}],["upon",{"2":{"9":1}}],["up",{"0":{"50":1},"2":{"8":1,"9":1,"11":1,"17":1,"25":1,"26":1,"28":2,"30":1,"41":1,"42":1,"43":2,"45":4,"50":1}}],["usr",{"2":{"29":2}}],["usb",{"2":{"25":2,"41":1}}],["usage",{"2":{"9":1}}],["usyy7uc9gfmuzodtpantkojfqcqasxlr1fojvbrx5qgjsvxwbqn3dtwma7xwsl6",{"2":{"9":6}}],["usually",{"2":{"9":3,"10":2,"11":1,"16":3,"43":1}}],["using",{"2":{"8":1,"9":15,"11":2,"12":1,"15":5,"16":1,"17":1,"18":1,"19":2,"22":1,"25":3,"26":2,"30":2,"50":2,"54":1,"56":1}}],["use==",{"2":{"9":6}}],["use=",{"2":{"9":12}}],["uses",{"2":{"9":4,"10":1,"15":3,"25":3,"27":1,"28":1,"30":1}}],["useful",{"2":{"9":10}}],["used",{"2":{"8":1,"9":39,"10":4,"11":5,"12":3,"15":1,"16":4,"25":1}}],["user=",{"2":{"10":1}}],["userprincipalname",{"2":{"10":1}}],["userinfo",{"2":{"9":3}}],["user>",{"2":{"9":1}}],["usernames",{"2":{"10":1}}],["username>",{"2":{"9":1}}],["username",{"2":{"9":23,"10":2,"16":12,"17":3,"26":1,"30":1,"50":1,"51":3,"52":3,"56":3}}],["users",{"2":{"8":2,"9":28,"10":3,"16":4,"17":2,"22":1,"39":1,"41":2}}],["user",{"0":{"17":1},"2":{"1":4,"8":2,"9":48,"10":17,"11":7,"12":9,"15":6,"16":21,"17":8,"25":3,"26":2,"27":1,"31":2,"39":1,"43":2}}],["use",{"2":{"0":1,"1":1,"9":18,"10":3,"11":1,"15":4,"16":6,"18":1,"19":1,"25":2,"26":2,"29":2,"30":2,"41":1,"45":1,"50":2,"51":1,"52":1,"55":1}}],["unraid",{"2":{"34":1}}],["until",{"2":{"25":3,"47":1,"54":1}}],["unchanged",{"2":{"15":1}}],["uncommenting",{"2":{"1":1}}],["unknown",{"2":{"10":1}}],["unauthenticated",{"2":{"9":2}}],["undesirable",{"2":{"9":1}}],["under",{"2":{"1":2,"9":1,"11":1,"12":1,"23":1,"50":1}}],["unix",{"2":{"9":1}}],["uniquemember=",{"2":{"9":1}}],["unique",{"2":{"9":2}}],["universal",{"2":{"1":4,"12":1}}],["unless",{"2":{"1":2,"9":4,"12":4,"16":1,"22":1,"45":1}}],["pkg",{"2":{"54":1}}],["pkce",{"2":{"9":1}}],["phone",{"2":{"43":1}}],["phoenix",{"2":{"1":2,"12":2}}],["pc",{"2":{"26":1}}],["pdf",{"2":{"19":2}}],["pieces",{"2":{"12":1}}],["pick",{"2":{"8":1,"16":1,"43":1}}],["p",{"2":{"9":2,"30":2,"31":2}}],["pbkdf2",{"2":{"9":1}}],["plug",{"2":{"25":1}}],["plugin",{"2":{"16":1,"29":2}}],["plan",{"2":{"40":1}}],["places",{"2":{"11":1}}],["placeholders",{"2":{"9":2}}],["plain",{"2":{"9":1}}],["please",{"2":{"9":5,"10":1,"12":1,"25":1}}],["powershell",{"0":{"51":1}}],["porkbun",{"2":{"41":1}}],["portainer",{"0":{"22":1,"30":1,"36":1},"2":{"12":1,"22":3,"23":5,"30":9,"31":1,"33":1,"45":3}}],["portal",{"2":{"9":1}}],["port=6360",{"2":{"10":1}}],["port=587",{"2":{"10":1}}],["port>",{"2":{"9":1}}],["port",{"2":{"9":14,"10":10,"15":8,"16":2,"25":1}}],["portions",{"2":{"12":1}}],["portion",{"2":{"9":3}}],["ports",{"2":{"0":1,"1":2,"11":1,"12":2}}],["poor",{"2":{"19":1}}],["poke",{"2":{"18":1}}],["points",{"2":{"25":1}}],["point",{"2":{"16":1}}],["potential",{"2":{"11":1,"41":1}}],["post",{"2":{"9":1}}],["postgres",{"2":{"9":2,"10":3}}],["postgresql",{"2":{"9":2,"10":1}}],["possible",{"2":{"9":1,"45":1}}],["policy",{"2":{"9":37}}],["populate",{"2":{"9":1}}],["pprof",{"2":{"9":2}}],["purpose",{"2":{"41":1}}],["purposes",{"2":{"10":1}}],["pull",{"2":{"17":1,"45":2}}],["putty",{"0":{"50":1},"2":{"48":1,"50":1}}],["put",{"2":{"9":1,"25":2,"50":2}}],["public",{"2":{"9":11,"10":1,"18":1}}],["push",{"2":{"8":1,"9":2,"43":1}}],["puid=1000",{"2":{"1":2,"12":1}}],["pricing",{"2":{"41":1}}],["print",{"2":{"29":1}}],["primarily",{"2":{"11":1}}],["private",{"2":{"9":38,"10":5,"45":1,"50":1}}],["predetermined",{"2":{"23":1}}],["premade",{"2":{"15":1}}],["previous",{"2":{"45":1}}],["previously",{"2":{"9":1}}],["prevent",{"2":{"9":1}}],["prevents",{"2":{"8":1,"9":2}}],["pre",{"2":{"9":3}}],["prefixed",{"2":{"9":2,"10":1}}],["preferably",{"2":{"15":1}}],["preference",{"2":{"9":7}}],["preferred",{"2":{"9":3,"49":1}}],["present",{"2":{"9":1,"10":2}}],["prompt",{"0":{"52":1},"2":{"51":1,"52":1}}],["program",{"2":{"48":1}}],["properly",{"2":{"45":1}}],["proper",{"2":{"41":1}}],["propagate",{"2":{"17":1}}],["pronounced",{"0":{"32":1},"1":{"33":1,"34":1,"35":1,"36":1,"37":1,"38":1,"39":1,"40":1,"41":1}}],["problems",{"2":{"14":1}}],["probably",{"2":{"8":1,"10":1,"45":2}}],["proxy",{"2":{"11":3,"15":11,"40":1,"43":2}}],["protocol",{"2":{"10":1}}],["protect",{"2":{"9":2}}],["protected",{"2":{"9":1}}],["profile",{"0":{"50":1},"2":{"9":2,"17":1,"50":4}}],["production",{"2":{"9":2}}],["provides",{"2":{"9":1}}],["providers",{"2":{"9":9,"11":1}}],["provider",{"2":{"9":16}}],["provided",{"2":{"9":7}}],["processors",{"2":{"40":1}}],["processor",{"2":{"9":1,"35":1,"36":1,"37":1}}],["process",{"2":{"8":1,"9":6,"25":1}}],["pem",{"2":{"9":4,"10":2}}],["personal",{"2":{"45":1}}],["permitted",{"2":{"9":1}}],["permit",{"2":{"9":2}}],["permission",{"2":{"1":1,"16":3}}],["perform",{"2":{"9":1,"10":1}}],["perfect",{"2":{"9":1}}],["periods",{"2":{"9":1}}],["period",{"2":{"9":5}}],["people",{"2":{"8":1,"9":2}}],["package",{"2":{"28":1}}],["pairwise",{"2":{"9":1}}],["patience",{"2":{"11":1}}],["patterns",{"2":{"9":1}}],["pattern",{"2":{"9":1,"16":1}}],["path",{"2":{"9":12,"10":3,"15":3}}],["page",{"2":{"9":2,"17":1,"18":3,"25":1,"43":1,"45":1,"48":4}}],["pages",{"2":{"3":1,"6":1}}],["pajjpaijtxmp8k",{"2":{"9":6}}],["panwvzspgrjf2axvnbmss2uqodr7tbv+fb4",{"2":{"9":6}}],["panel",{"2":{"9":1}}],["partition",{"2":{"25":1}}],["partitioning",{"2":{"25":2}}],["particular",{"2":{"16":1}}],["part",{"2":{"16":1,"34":1,"42":1,"43":1}}],["parts",{"2":{"16":2}}],["partner",{"2":{"9":1}}],["parallelism",{"2":{"9":2}}],["parameters",{"2":{"9":3,"10":1}}],["parameter",{"2":{"9":6}}],["paste",{"2":{"9":1,"23":1}}],["passwd",{"2":{"25":1}}],["password=",{"2":{"10":1}}],["password=generate",{"2":{"1":1}}],["passwords",{"2":{"9":7,"10":2,"12":1,"16":1}}],["password",{"2":{"1":1,"8":1,"9":27,"10":15,"12":7,"16":7,"17":4,"25":3,"26":1,"30":2,"41":1}}],["pass=replace",{"2":{"12":1}}],["pass",{"2":{"9":1,"10":3}}],["passed",{"2":{"8":1}}],["pgid=1000",{"2":{"1":2,"12":1}}],["easily",{"2":{"23":1}}],["easier",{"0":{"50":1},"2":{"17":1,"21":1,"39":1}}],["easiest",{"2":{"8":1}}],["each",{"2":{"10":1,"34":1,"50":1}}],["echo",{"2":{"10":1,"29":1}}],["ehlo",{"2":{"9":1}}],["etcher",{"2":{"25":1}}],["etc",{"2":{"9":1,"11":1,"26":1,"29":7}}],["empty",{"2":{"9":1}}],["emails",{"2":{"9":3,"10":2}}],["emailaddressrelay",{"2":{"9":2}}],["email",{"2":{"9":11,"10":7,"16":5,"17":1,"41":3,"43":1}}],["email=",{"2":{"1":2,"12":1}}],["else",{"2":{"15":1,"21":1,"38":1}}],["elli",{"2":{"9":6}}],["elements",{"2":{"9":1}}],["element",{"2":{"9":1}}],["errgvfxwp3g8xlepabsi",{"2":{"9":6}}],["errors",{"2":{"15":1}}],["error",{"2":{"9":1,"15":1}}],["eghjf9xiey6ltnxe8atvok4ntwdufzbaoequ3gd50",{"2":{"9":6}}],["ezerma8ga1uechmiqxv0agvsawewhhcnnzawmtaxmdawmdawwhcnnzewmtaxmdaw",{"2":{"9":12}}],["e",{"2":{"9":13}}],["ever",{"2":{"15":1}}],["everything",{"2":{"15":1}}],["everyone",{"2":{"9":1}}],["every",{"2":{"9":2,"50":1}}],["even",{"2":{"9":1,"10":1,"45":1}}],["enforce",{"2":{"9":1}}],["enter",{"2":{"26":1,"50":1}}],["entire",{"2":{"25":1}}],["entirely",{"2":{"9":6}}],["entropy",{"2":{"9":1}}],["encodes",{"2":{"10":1}}],["encoded",{"2":{"9":1}}],["encrypted",{"2":{"10":1}}],["encryption",{"2":{"9":2,"10":2}}],["encrypt",{"2":{"9":2,"11":2}}],["enqqtcwhw937k8pxy",{"2":{"9":6}}],["enough",{"2":{"9":1,"40":1}}],["enrollment",{"2":{"9":1}}],["env",{"2":{"9":2,"10":4}}],["environments",{"2":{"9":1}}],["environment",{"2":{"1":3,"9":1,"10":8,"12":4,"25":1}}],["endpoints",{"2":{"9":3}}],["endpoint",{"2":{"9":3}}],["end",{"2":{"9":20,"12":1,"21":1,"43":2}}],["enables",{"2":{"9":3}}],["enabled=true",{"2":{"10":1}}],["enabled",{"2":{"9":5,"10":1}}],["enable",{"2":{"8":1,"9":6,"10":4,"23":1,"50":1}}],["especially",{"2":{"8":1,"9":1,"40":1}}],["either",{"2":{"8":1,"9":9,"10":1,"16":1,"22":1,"25":1,"30":1}}],["edit",{"2":{"1":3,"11":1}}],["exactly",{"2":{"11":1,"51":1}}],["examples",{"2":{"9":1,"29":2}}],["example",{"2":{"9":30,"10":4,"16":6,"17":1,"19":3,"25":1,"29":1}}],["except",{"2":{"9":1}}],["excerpt",{"2":{"1":1}}],["exclude",{"2":{"9":2}}],["existing",{"2":{"9":1}}],["exist",{"2":{"9":2,"10":2}}],["exit",{"2":{"9":1,"15":1,"26":1}}],["extension",{"2":{"19":2}}],["extensions",{"2":{"9":1}}],["extend",{"2":{"10":1}}],["externally",{"2":{"15":1}}],["external",{"2":{"9":2,"12":1,"15":1}}],["extra",{"2":{"1":5,"12":1}}],["expand",{"2":{"50":1}}],["expanlanation",{"2":{"7":1}}],["expose",{"2":{"12":3}}],["exposing",{"2":{"0":1}}],["expected",{"2":{"37":1}}],["expects",{"2":{"9":1}}],["expensive",{"2":{"10":1}}],["expires",{"2":{"9":2}}],["expiration",{"2":{"9":4}}],["expressions",{"2":{"9":1}}],["expvars",{"2":{"9":2}}],["explanation",{"2":{"7":1,"9":1}}],["lt",{"2":{"15":4}}],["lc",{"2":{"10":1}}],["layer",{"2":{"22":1}}],["last",{"2":{"9":2,"40":1,"45":1}}],["lax",{"2":{"9":2}}],["latency",{"2":{"9":2}}],["later",{"2":{"8":2,"35":1,"36":1,"37":1}}],["latest",{"2":{"1":2,"3":1,"4":1,"5":1,"12":4,"25":2,"30":1}}],["lxccv2meelzv7tagvxsi3do6dsjfsehyemd5j9mbaogax8hv+0goqzqcsotaq8nx",{"2":{"9":6}}],["ljjlyxkqhqpjtbwaycdvzqirnaom9knvihagxiswcz4xbsu0y9nl+woarpyrvqvg",{"2":{"9":6}}],["lqery6hsysn",{"2":{"9":6}}],["lfftcj91vhcmj73meff2e2s2prpjdxbg5fmcaweaaantmfewdgydvr0paqh",{"2":{"9":6}}],["lyblmmunyfmcfvamu0eixxafq2qcwv8umcqft0z",{"2":{"9":6}}],["luyx2rbyslmsn5uzqm",{"2":{"9":6}}],["ldaps",{"2":{"9":1,"10":4,"16":1}}],["ldap",{"2":{"9":15,"10":19,"12":3,"16":16,"43":2}}],["ldez",{"2":{"3":4,"4":2,"5":3,"6":4,"7":5}}],["legacy",{"0":{"19":1},"2":{"18":2}}],["left",{"2":{"15":1}}],["lets",{"2":{"45":1}}],["letsencrypt",{"2":{"11":1}}],["let",{"2":{"11":2,"15":1,"17":2,"26":2,"41":1}}],["less",{"2":{"9":1}}],["leasing",{"2":{"41":1}}],["leased",{"2":{"25":1}}],["least",{"2":{"9":2,"10":1,"45":4}}],["learn",{"2":{"21":1}}],["learning",{"2":{"11":1,"43":1}}],["lead",{"2":{"19":1}}],["leave",{"2":{"9":1,"15":2}}],["level",{"2":{"9":3}}],["lengthy",{"2":{"12":2,"16":1}}],["length",{"2":{"9":13}}],["lissy93",{"2":{"23":1}}],["listed",{"2":{"12":1}}],["listening",{"2":{"15":1}}],["listens",{"2":{"9":1}}],["listen",{"2":{"9":3,"10":1}}],["list",{"2":{"8":1,"9":9,"10":1,"16":1,"21":1,"29":6}}],["little",{"2":{"17":1,"21":1,"39":1,"50":1,"51":1,"52":1}}],["live",{"2":{"11":1}}],["lifespan",{"2":{"9":4}}],["lifespans",{"2":{"9":1}}],["lightweight",{"2":{"9":1,"10":1,"34":1}}],["light",{"2":{"9":1,"10":2}}],["likely",{"2":{"11":2}}],["like",{"2":{"8":1,"9":4,"10":2,"12":1,"16":2,"17":2,"25":1,"27":1,"34":1,"43":1,"50":1,"51":1,"52":1}}],["linux",{"2":{"10":1,"29":2}}],["linuxserver",{"2":{"1":2,"12":2}}],["link",{"2":{"9":2}}],["links",{"2":{"8":1,"9":1,"10":1}}],["linked",{"2":{"8":1,"16":1}}],["line",{"2":{"1":1,"40":1}}],["lines",{"2":{"1":3}}],["looking",{"2":{"18":2}}],["lookups",{"2":{"9":1}}],["lot",{"2":{"11":1}}],["locate",{"2":{"48":1,"55":1}}],["locations",{"2":{"19":1}}],["location",{"2":{"11":1,"45":1,"50":1}}],["localhost>",{"2":{"10":1}}],["localhost",{"2":{"9":2,"10":3}}],["local",{"0":{"48":1,"55":1},"2":{"9":3,"10":2,"48":1}}],["lockouts",{"2":{"8":1}}],["lower",{"2":{"12":1}}],["lowercase",{"2":{"9":2}}],["lowest",{"2":{"9":1,"45":1}}],["loaded",{"2":{"22":1,"50":1}}],["load",{"2":{"9":1,"25":1,"50":1}}],["logging",{"2":{"10":1}}],["logged",{"2":{"9":3}}],["logins",{"2":{"11":1}}],["login",{"2":{"9":8,"10":2,"45":1,"50":1}}],["logs",{"2":{"9":4}}],["log",{"2":{"9":5,"26":1,"30":1}}],["logout",{"2":{"54":1}}],["logo",{"2":{"5":1}}],["longer",{"2":{"9":2}}],["long",{"2":{"1":1,"10":2}}],["lldap",{"0":{"10":1,"16":1},"2":{"9":4,"10":17,"12":8,"16":11,"19":2,"33":1,"43":4,"45":1}}],["ll",{"2":{"1":3,"8":3,"15":3,"48":1,"51":1,"52":1,"54":1,"55":1}}],["lscr",{"2":{"1":2,"12":1}}],["1ghz",{"2":{"35":1,"36":1,"37":1}}],["13",{"2":{"19":1}}],["17170",{"2":{"10":1,"12":2}}],["1w",{"2":{"9":1}}],["1m",{"2":{"9":1,"16":1}}],["1h",{"2":{"9":5}}],["168",{"2":{"9":2}}],["16",{"2":{"9":7}}],["1fa",{"2":{"9":1}}],["12+",{"2":{"30":1}}],["12h",{"2":{"9":1}}],["12",{"0":{"25":1,"35":1},"2":{"9":1,"10":1,"19":3,"25":1,"33":1,"45":1}}],["123",{"2":{"9":1}}],["1234567890abcdefghifjkl",{"2":{"9":1}}],["123456789",{"2":{"9":1}}],["127",{"2":{"1":2,"9":1,"10":2,"50":1,"51":1}}],["192",{"2":{"9":2}}],["19",{"0":{"7":1}}],["10m",{"2":{"9":1}}],["10",{"0":{"4":1},"2":{"9":5,"19":4,"35":1,"37":1,"39":1}}],["11",{"0":{"3":1,"4":1},"2":{"19":2}}],["1",{"0":{"3":2,"4":1,"5":1,"6":1,"7":2},"2":{"1":4,"9":6,"10":4,"12":1,"23":1,"50":1,"51":1,"52":1,"56":1}}],["2m",{"2":{"9":1}}],["27goe2i5mh6yez6vaybuuns3fcwismywlq043tu2dnkx9ijooauqzw^invalid",{"2":{"9":6}}],["2pjcp+aujsj6fqqpmgoygtplcsdh+ptctngud8jswipztcjmanqdphaoymcgtf4b",{"2":{"9":6}}],["26",{"2":{"9":1,"12":1}}],["2fa",{"2":{"8":9,"9":7,"39":2,"41":1,"43":6}}],["22",{"0":{"6":1}}],["24",{"0":{"3":1,"4":1,"5":1,"6":1,"7":1},"2":{"9":2,"17":1}}],["2010",{"2":{"35":1,"36":1,"37":1}}],["2023",{"2":{"19":4}}],["20",{"0":{"3":1},"2":{"9":2,"36":1}}],["2",{"0":{"6":1},"2":{"1":2,"9":6,"12":1,"16":1,"26":1,"27":1,"28":1,"35":1,"36":1,"40":1}}],["years",{"2":{"40":1}}],["yet",{"2":{"1":1}}],["y",{"2":{"26":1}}],["ykw3vrgoe3o1t1g2m2tn8uggasez842jzwjioddsi5+icysqguulkt86h",{"2":{"9":6}}],["y4ob",{"2":{"9":6}}],["ysorzvd12o9qj",{"2":{"9":6}}],["yamllint",{"2":{"9":1}}],["yaml",{"2":{"9":2,"10":1}}],["ymmv",{"2":{"8":1}}],["ymlingress",{"2":{"1":1}}],["yml",{"2":{"1":3,"9":3,"16":2,"19":2}}],["ymlversion",{"2":{"1":2,"12":1}}],["yourself",{"2":{"12":1,"22":1}}],["your",{"0":{"28":1},"2":{"0":2,"1":6,"8":3,"9":4,"10":4,"11":3,"12":4,"15":3,"16":2,"18":1,"22":1,"23":1,"25":4,"26":3,"28":1,"29":1,"30":1,"41":2,"43":1,"45":4,"47":1,"49":1,"51":1,"52":1,"56":1}}],["you",{"2":{"0":2,"1":8,"8":7,"9":35,"10":15,"11":9,"12":6,"15":27,"16":7,"17":3,"18":5,"21":1,"22":5,"23":2,"25":5,"26":5,"27":1,"29":2,"30":3,"31":1,"40":1,"41":8,"43":2,"45":8,"48":4,"50":3,"51":2,"52":2,"54":1,"55":1}}],["hit",{"2":{"48":3,"50":2}}],["highest",{"2":{"17":1}}],["high",{"2":{"9":2}}],["highly",{"2":{"9":2,"11":1,"27":1,"50":1}}],["highlighted",{"2":{"1":1}}],["hmac",{"2":{"9":3}}],["hkosfjz7b5hfgudkmtvm6bardxahoqcmk4ycu96e9d4pb4ei+xgc+mnuyvov3rbb",{"2":{"9":6}}],["h6a3u6gdkt1siytiqr7v7ku",{"2":{"9":6}}],["html",{"2":{"9":3,"16":1}}],["http",{"2":{"1":1,"9":1,"10":7}}],["https",{"2":{"1":2,"8":2,"9":36,"16":3,"29":2,"30":1,"54":1}}],["hence",{"2":{"33":1}}],["helpful",{"2":{"23":1}}],["helo",{"2":{"9":1}}],["head",{"2":{"10":1}}],["header",{"2":{"9":1,"10":1}}],["headers",{"2":{"9":2}}],["healthcheck",{"2":{"9":5}}],["health",{"2":{"9":1}}],["here",{"0":{"14":1},"2":{"1":5,"8":1,"9":1,"10":1,"12":11,"16":5,"18":1,"21":1,"26":1,"30":1,"43":1}}],["had",{"2":{"17":1,"26":1}}],["having",{"2":{"17":1,"23":1,"41":1,"50":1}}],["have",{"2":{"0":1,"1":1,"5":1,"8":1,"9":12,"10":4,"11":2,"15":6,"16":1,"17":5,"18":1,"19":1,"21":1,"23":1,"25":2,"26":2,"31":1,"39":1,"41":5,"45":1,"54":1}}],["happens",{"2":{"11":1}}],["handling",{"2":{"17":1}}],["handles",{"2":{"43":3}}],["handle",{"0":{"17":1},"2":{"8":1,"17":1}}],["handled",{"2":{"8":1,"43":3}}],["handshake",{"2":{"9":1}}],["harry",{"2":{"9":3}}],["hard",{"2":{"8":1}}],["ha",{"2":{"9":5}}],["hashed",{"2":{"10":1}}],["has",{"2":{"9":10,"11":2,"16":1,"22":1,"43":4}}],["hooks",{"2":{"39":2,"43":1}}],["hours",{"2":{"17":1}}],["however",{"2":{"11":1,"15":1,"16":2,"19":1,"21":1,"39":1,"41":1,"43":1}}],["how",{"0":{"14":1,"15":1,"16":1,"17":1},"2":{"9":1,"10":2,"11":3,"16":3,"17":1,"41":1,"43":2}}],["hold",{"2":{"17":1}}],["holds",{"2":{"9":1,"11":4}}],["holding",{"2":{"9":4,"16":2}}],["hosting",{"2":{"11":1}}],["hosted",{"2":{"10":2,"11":1}}],["host",{"2":{"9":21,"10":6,"11":2,"17":2,"43":1}}],["hostname",{"2":{"1":2,"9":2,"16":1,"25":1,"50":1}}],["hosts",{"2":{"1":2,"9":1}}],["homepage",{"2":{"6":1}}],["home",{"2":{"1":4,"11":7,"12":5,"15":6,"31":2}}],["aka",{"0":{"48":1,"55":1}}],["away",{"2":{"40":1}}],["aas",{"2":{"39":2}}],["aaguid",{"2":{"9":1}}],["a+r",{"2":{"29":1}}],["aexa",{"2":{"17":1}}],["aegis",{"2":{"8":1}}],["amp",{"2":{"14":1,"16":3,"45":2}}],["amount",{"2":{"9":1,"22":1}}],["audience",{"2":{"9":2}}],["authorize",{"2":{"9":1}}],["authorization",{"2":{"9":4}}],["authorizations",{"2":{"9":2}}],["authority",{"2":{"9":5}}],["auth",{"2":{"9":3,"16":5,"17":1,"43":1}}],["authenticator",{"2":{"9":2}}],["authenticated",{"2":{"9":2,"16":1}}],["authenticate",{"2":{"9":2}}],["authentication",{"0":{"16":1},"2":{"8":2,"9":23,"16":4,"43":1}}],["authelia",{"0":{"9":1,"38":1},"2":{"8":6,"9":58,"10":1,"11":1,"12":7,"16":8,"19":1,"33":1,"39":2,"41":2,"43":4,"45":2}}],["authy",{"0":{"8":1,"39":1},"2":{"8":3,"9":2,"33":1,"39":1,"43":5,"45":1}}],["automatically",{"2":{"9":1,"15":1}}],["auto",{"2":{"1":2,"9":3,"12":1,"15":1,"43":1,"50":1}}],["availability",{"2":{"9":2}}],["available",{"2":{"9":8,"11":1,"45":1}}],["around",{"2":{"30":1}}],["architecture",{"2":{"29":1}}],["arch=$",{"2":{"29":1}}],["arbitrary",{"2":{"10":1}}],["argon2id",{"2":{"9":1}}],["argon2",{"2":{"9":2}}],["are",{"2":{"8":3,"9":27,"10":2,"11":3,"12":3,"15":8,"16":11,"18":2,"19":1,"22":3,"25":1,"29":1,"30":1,"41":2,"45":1,"48":1,"50":1}}],["aogbap1i",{"2":{"9":6}}],["aqelbqadggebahsitqiqsnzonfl3dzxhpezr2hp6peo45buaatu8fzhoa+u7icfh",{"2":{"9":6}}],["again",{"2":{"9":1}}],["against",{"2":{"9":6}}],["agkkma8ga1udjqqimaygbfudjqawdwydvr0taqh",{"2":{"9":6}}],["agwgmbmga1udjqqmmaogccsgaqufbwmbmawga1udeweb",{"2":{"9":6}}],["affect",{"2":{"9":1}}],["affects",{"2":{"9":3}}],["after",{"2":{"1":3,"9":3,"15":1,"21":1}}],["although",{"2":{"40":1}}],["alternatively",{"2":{"10":1}}],["alternative",{"2":{"9":1}}],["already",{"2":{"17":1}}],["alice",{"2":{"17":1}}],["always",{"2":{"9":2,"19":1}}],["algorithm",{"2":{"9":7}}],["alphanumeric",{"2":{"9":1,"12":1}}],["also",{"2":{"9":14,"10":2,"16":1,"18":1,"41":2,"43":1}}],["all=",{"2":{"26":1}}],["all=c",{"2":{"10":1}}],["allowing",{"2":{"23":1}}],["allowed",{"2":{"9":11}}],["allow",{"2":{"9":2,"10":2,"16":1,"25":1,"48":1}}],["allows",{"2":{"9":5,"22":1,"43":2,"45":2}}],["all",{"0":{"12":1},"2":{"8":1,"9":12,"10":3,"11":7,"12":2,"15":1,"16":4,"17":2,"25":1,"26":3,"43":2,"45":1,"50":1}}],["attempt",{"2":{"9":1}}],["attempts",{"2":{"9":2}}],["attestation",{"2":{"9":2}}],["attacker",{"2":{"10":1}}],["attackers",{"2":{"9":2}}],["attack",{"2":{"9":1,"10":1}}],["attached",{"2":{"9":1}}],["attributed",{"2":{"9":1}}],["attributes",{"2":{"9":4,"10":4,"16":1}}],["attribute",{"2":{"9":18,"10":2,"16":10}}],["at",{"2":{"9":17,"10":1,"17":1,"41":1,"45":4}}],["acronym",{"0":{"33":1}}],["acl",{"2":{"9":1}}],["actual",{"2":{"16":1,"19":1}}],["actually",{"2":{"8":1,"10":1}}],["activity",{"2":{"9":1}}],["active",{"2":{"9":5}}],["activedirectory",{"2":{"9":1}}],["action",{"2":{"9":1}}],["accurate",{"2":{"9":1}}],["accepts",{"2":{"9":2}}],["acceptable",{"2":{"9":1}}],["accept",{"2":{"9":1}}],["accessed",{"2":{"9":1}}],["access",{"2":{"9":8,"10":1,"11":1,"16":7,"17":2,"23":1,"26":1,"43":1,"48":2}}],["account",{"2":{"1":4,"8":1,"10":2,"16":2}}],["abc123abc123abc",{"2":{"9":1}}],["abcdef",{"2":{"9":1}}],["above",{"2":{"9":6,"10":2}}],["about",{"2":{"7":1,"9":3,"10":1,"14":1,"18":1,"48":1}}],["able",{"2":{"8":2,"11":1,"26":1,"29":1,"47":1,"54":1}}],["asc",{"2":{"29":1}}],["asks",{"2":{"48":1}}],["ask",{"2":{"17":1}}],["asked",{"0":{"13":1},"1":{"14":1,"15":1,"16":1,"17":1}}],["assumes",{"0":{"41":1},"2":{"41":1}}],["assuming",{"2":{"11":1}}],["asset",{"2":{"9":1}}],["assets",{"2":{"9":3}}],["as",{"0":{"32":2},"1":{"33":2,"34":2,"35":2,"36":2,"37":2,"38":2,"39":2,"40":2,"41":2},"2":{"5":1,"8":2,"9":9,"10":4,"11":2,"12":1,"15":3,"17":1,"19":1,"25":3,"26":1,"27":1,"28":1,"33":1,"41":3,"43":2,"45":4,"48":1,"50":2,"51":2,"52":1}}],["apt",{"2":{"21":2,"28":3,"29":14,"45":2}}],["apgravnf9v7nj5jytarks5nm6inf46ls4qprexnmhqseswj6lpngbyxogzc9q+cc",{"2":{"9":6}}],["apps",{"2":{"17":1,"23":1,"40":1}}],["appear",{"2":{"50":1,"51":1,"52":1}}],["appears",{"2":{"10":1}}],["append",{"2":{"17":1}}],["apply",{"2":{"9":3}}],["applies",{"2":{"9":2,"45":1}}],["applied",{"2":{"9":10}}],["applications",{"2":{"8":1,"12":1,"16":1,"22":1,"45":1}}],["application",{"0":{"15":1},"2":{"7":1,"8":1,"9":4,"10":1,"11":4,"12":1,"15":11,"16":4,"43":2,"48":2,"49":1,"55":1}}],["app",{"0":{"23":1},"2":{"9":3,"15":4,"16":2,"23":2,"43":1}}],["appdata",{"2":{"1":4,"11":7,"12":5,"15":6,"31":2}}],["api",{"2":{"1":5,"9":6,"11":1}}],["advised",{"2":{"9":1}}],["advise",{"2":{"9":1}}],["adventure",{"2":{"8":1}}],["adccaqocggebamxhbvvxuzyk0u34",{"2":{"9":6}}],["adccaqocggebapkv3psyp4ozgeivlj14diwfcegegq7wumi0szzqqa2id0l59u",{"2":{"9":6}}],["adjust",{"2":{"9":1}}],["adjusts",{"2":{"9":1}}],["administration",{"2":{"10":4}}],["administrator",{"2":{"9":5,"16":1,"30":1}}],["admins",{"2":{"9":3}}],["admin",{"2":{"1":2,"9":4,"10":12,"12":1,"16":2,"25":2,"30":1,"39":1}}],["addon",{"2":{"16":1}}],["adding",{"2":{"11":1,"16":1}}],["additional",{"2":{"9":8,"16":2}}],["addition",{"2":{"8":1,"9":2,"38":1}}],["adds",{"2":{"9":1}}],["addresses",{"2":{"9":1}}],["address>",{"2":{"9":2}}],["address",{"2":{"9":10,"10":3,"15":1,"16":1,"17":1,"30":1,"41":2,"45":1,"50":2,"56":1}}],["added",{"2":{"3":2,"4":1,"5":1,"6":1,"7":4,"9":5}}],["add",{"0":{"15":1,"16":1},"2":{"1":10,"7":1,"9":5,"10":1,"11":2,"12":1,"15":1,"16":3,"17":2,"22":1,"26":2}}],["a",{"0":{"15":1,"50":1,"52":2},"2":{"1":4,"5":1,"8":1,"9":73,"10":11,"11":8,"12":2,"14":1,"15":11,"16":11,"17":8,"18":1,"19":1,"21":2,"22":4,"23":1,"25":5,"26":1,"30":2,"34":2,"38":1,"39":2,"41":7,"43":8,"45":4,"50":7,"51":3,"52":3}}],["analog",{"2":{"50":1,"51":1,"52":1}}],["anyway",{"2":{"17":1}}],["anything",{"2":{"15":2,"26":1,"29":1}}],["anyone",{"2":{"9":1}}],["any",{"2":{"9":8,"10":1}}],["another",{"2":{"8":1,"10":1,"45":1}}],["an",{"2":{"1":2,"7":2,"8":1,"9":12,"10":3,"15":3,"16":5,"25":1,"29":1,"41":1,"43":3,"45":2,"55":1}}],["and",{"2":{"1":3,"8":3,"9":48,"10":13,"11":3,"12":7,"15":4,"16":7,"17":7,"18":1,"19":1,"22":3,"25":5,"26":2,"27":1,"28":1,"31":1,"33":1,"41":3,"43":7,"45":7,"50":4,"51":1,"52":1,"56":1}}],["mkdir",{"2":{"31":1}}],["m",{"2":{"29":1}}],["mv",{"2":{"15":1}}],["my",{"0":{"15":1},"2":{"9":1,"10":2,"11":1,"16":1,"17":3,"41":1}}],["myapp",{"2":{"9":1}}],["mypassword",{"2":{"9":1}}],["mysql",{"2":{"9":5,"10":4,"12":8}}],["mysentinel",{"2":{"9":1}}],["myredis",{"2":{"9":1}}],["mx2",{"2":{"9":1}}],["mdawwjatmrewdwydvqqkewhbdxrozwxpytccasiwdqyjkozihvcnaqebbqadggep",{"2":{"9":12}}],["multi",{"2":{"27":1}}],["multiple",{"2":{"9":1,"11":1,"45":1,"48":1}}],["much",{"2":{"21":1}}],["mutual",{"2":{"9":10}}],["must",{"2":{"1":1,"9":23,"15":2}}],["messages",{"2":{"9":2}}],["mechanism",{"2":{"9":1}}],["me",{"2":{"9":6,"16":1}}],["memberof=cn=",{"2":{"16":3}}],["member=",{"2":{"9":1,"16":1}}],["memory",{"2":{"9":2}}],["meaning",{"2":{"25":1}}],["meant",{"2":{"9":1}}],["means",{"2":{"8":1,"9":1}}],["mentioned",{"2":{"9":1}}],["metadata",{"2":{"9":1}}],["metrics",{"2":{"9":6}}],["methods",{"2":{"9":1}}],["method",{"2":{"8":1,"9":4,"49":1}}],["meeme",{"2":{"1":1}}],["mac",{"0":{"55":1,"56":1}}],["macos",{"0":{"53":1,"54":1},"1":{"54":1,"55":2,"56":2},"2":{"54":1}}],["machine",{"2":{"26":1,"30":1,"47":1}}],["making",{"2":{"50":1}}],["makes",{"2":{"9":1}}],["make",{"2":{"1":2,"9":2,"11":2,"15":4,"17":1,"21":1,"25":1,"30":2,"31":1,"45":4,"48":1,"50":1,"51":1,"52":1}}],["markup",{"2":{"41":1}}],["markdown1",{"2":{"26":1,"27":1,"28":1}}],["mariadb",{"2":{"9":1,"12":4}}],["matter",{"2":{"15":1}}],["matching",{"2":{"9":2}}],["match",{"2":{"9":1,"15":4,"16":1}}],["matches",{"2":{"9":8}}],["magic",{"2":{"11":1}}],["made",{"0":{"31":1},"2":{"9":1,"15":1,"31":1,"45":1,"50":1}}],["master",{"2":{"9":2}}],["many",{"2":{"9":1,"10":1,"11":1,"23":1}}],["manually",{"2":{"9":1,"15":1}}],["manager",{"0":{"47":1,"54":1},"1":{"48":1,"49":1,"50":1,"51":1,"52":1,"55":1,"56":1},"2":{"16":1,"28":1,"51":1,"52":1}}],["managers",{"2":{"8":1}}],["manage",{"2":{"16":1,"45":1}}],["management",{"0":{"50":1},"2":{"9":1,"16":1,"17":1,"43":1}}],["mail=",{"2":{"16":1}}],["mail",{"2":{"9":8,"10":1,"16":4}}],["maintenance",{"0":{"44":1,"45":1},"1":{"45":1},"2":{"44":1,"45":1}}],["maintain",{"2":{"9":1}}],["main",{"2":{"9":2,"16":2,"18":1,"23":1}}],["ma4o1cwtgb6rqcnnn",{"2":{"9":6}}],["mappings",{"2":{"9":1}}],["maximum",{"2":{"9":14}}],["max",{"2":{"9":6,"39":1}}],["may",{"2":{"8":2,"9":6,"15":1,"16":1,"17":2,"29":1,"41":1}}],["mixtures",{"2":{"16":1}}],["min",{"2":{"9":2}}],["minimum",{"0":{"34":1,"40":1},"1":{"35":1,"36":1,"37":1,"38":1,"39":1,"40":1},"2":{"9":16,"10":1,"16":1,"34":1,"40":2,"45":1}}],["mini",{"2":{"6":1}}],["minify",{"2":{"3":1}}],["miiepaibaakcaqea8q",{"2":{"9":6}}],["miidbdccaeygawibagiraljspg21ka0zy4f1wuciuomwdqyjkozihvcnaqelbqaw",{"2":{"9":6}}],["miic5jccac6gawibagirak4sj7fin6pxo",{"2":{"9":6}}],["microsoft",{"2":{"9":3}}],["miscellaneous",{"2":{"4":1}}],["misc",{"2":{"3":1}}],["might",{"2":{"0":1}}],["monthly",{"2":{"45":3}}],["move",{"2":{"29":1}}],["moved",{"2":{"3":1,"5":1}}],["most",{"2":{"9":2,"11":2,"15":2,"16":1,"40":1,"41":1}}],["mobile",{"2":{"9":1}}],["modification",{"2":{"45":1}}],["modify",{"2":{"8":1,"11":1,"15":2,"48":1}}],["mod",{"2":{"15":1}}],["mode=rwc",{"2":{"10":2}}],["modes",{"2":{"9":3}}],["moderators",{"2":{"9":1}}],["mode",{"2":{"9":4,"10":1}}],["mods",{"2":{"1":11,"12":4,"43":1}}],["mods=linuxserver",{"2":{"1":2,"12":1}}],["more",{"2":{"1":2,"7":1,"8":2,"9":7,"10":2,"11":1,"15":1,"22":1,"23":1,"27":1}}],["icloud",{"2":{"41":1}}],["icloud+",{"2":{"41":1}}],["icons",{"2":{"6":1}}],["ignore",{"2":{"10":1}}],["ignored",{"2":{"10":3}}],["ip",{"2":{"15":1,"16":1,"30":1,"50":2,"56":1}}],["ipv6",{"2":{"10":4}}],["ipzgpzziiz9ov1wbdaqcwrj7rawnsspfpx",{"2":{"9":6}}],["ietf",{"2":{"9":1}}],["iukfkdk27q5nc9vjsuupyelolc1wyoouf6okrze72dkmqv",{"2":{"9":6}}],["ivlozc8n27dpqwwkh8537vy7anciaacr",{"2":{"9":6}}],["ijmysjusnxh0hyuiqyscrtzqwjrjlmpadygpqvn1",{"2":{"9":6}}],["iwd",{"2":{"9":6}}],["i^invalid",{"2":{"9":6}}],["immediately",{"2":{"9":1}}],["impossible",{"2":{"45":1}}],["important",{"2":{"9":16,"15":1,"17":1,"45":2}}],["implications",{"2":{"9":1}}],["implemented",{"2":{"9":1}}],["implementation",{"2":{"9":2,"10":1,"16":1}}],["image",{"2":{"1":2,"12":5}}],["ifeaulix06w9yvmo60c",{"2":{"9":6}}],["if",{"2":{"8":2,"9":49,"10":6,"11":2,"12":1,"15":7,"16":8,"17":3,"18":2,"21":1,"22":2,"25":1,"27":1,"29":1,"30":3,"40":1,"41":2,"45":1,"48":1,"50":6,"51":1,"52":1}}],["i",{"0":{"14":1,"15":1,"16":1,"17":1},"2":{"8":2,"9":14,"10":1,"11":1,"12":2,"17":13,"41":1}}],["iterations",{"2":{"9":4}}],["it",{"2":{"1":1,"8":4,"9":33,"10":15,"11":3,"15":7,"16":4,"17":5,"22":1,"23":1,"25":2,"26":1,"28":1,"30":2,"31":1,"33":1,"45":7,"48":2,"55":1}}],["identifier",{"2":{"9":4}}],["identifiers",{"2":{"9":3}}],["identify",{"2":{"9":1}}],["identity",{"2":{"9":4,"43":2}}],["idle",{"2":{"9":6}}],["id=account",{"2":{"1":1}}],["id=zone",{"2":{"1":1}}],["id",{"2":{"1":2,"9":4}}],["io",{"2":{"1":2,"9":1,"12":1,"29":1}}],["involved",{"2":{"43":1}}],["involving",{"2":{"22":1}}],["invalid",{"2":{"29":1}}],["invalidate",{"2":{"10":1}}],["inactivity",{"2":{"9":3}}],["inxjbkapbznp2hucuw87ie5zk2of",{"2":{"9":6}}],["index",{"2":{"9":2}}],["indentation",{"2":{"9":1}}],["individual",{"2":{"9":1}}],["indirect",{"2":{"9":2}}],["introspection",{"2":{"9":1}}],["internet",{"2":{"25":2}}],["internal",{"2":{"9":3,"15":4}}],["interface",{"2":{"10":3}}],["interval",{"2":{"9":3,"16":1}}],["interaction",{"2":{"9":1}}],["integrations",{"2":{"43":1}}],["integration",{"2":{"9":1,"10":1}}],["into",{"2":{"8":1,"9":1,"15":5,"25":1,"30":1,"39":2,"41":1,"43":1,"50":1,"51":1,"52":1}}],["input",{"2":{"9":9,"16":3}}],["information",{"2":{"9":7,"10":1,"11":3,"17":1}}],["info",{"2":{"9":1}}],["increase",{"2":{"9":1}}],["including",{"0":{"50":1},"2":{"9":2,"41":1}}],["included",{"2":{"9":1,"45":1}}],["include",{"2":{"1":2,"10":1}}],["incoming",{"2":{"9":1}}],["initially",{"2":{"10":2}}],["ini",{"2":{"1":1}}],["insensitive",{"2":{"9":1}}],["insert",{"0":{"14":1},"2":{"1":5,"12":11,"30":1}}],["instructions",{"0":{"19":1,"50":1,"51":1,"52":1},"2":{"18":4,"19":2,"26":1,"27":1,"29":1,"30":1,"42":1,"47":1,"49":1,"54":1}}],["installed",{"2":{"30":1,"31":1,"48":1,"55":1}}],["installer",{"2":{"25":3}}],["installing",{"0":{"29":1},"2":{"24":1}}],["install",{"2":{"15":2,"21":4,"22":1,"25":2,"29":5,"30":2,"45":1,"47":2,"54":3}}],["installations",{"2":{"9":1}}],["installation",{"2":{"1":1,"31":1,"47":1,"54":1}}],["instance",{"2":{"9":2,"10":1}}],["instead",{"2":{"9":3,"10":1,"16":1,"50":2}}],["in",{"2":{"1":3,"8":1,"9":54,"10":9,"11":4,"12":4,"15":2,"16":9,"17":1,"18":1,"19":2,"21":1,"23":2,"25":4,"26":1,"27":1,"29":1,"34":1,"38":1,"43":1,"45":1,"48":1,"49":1,"50":9,"51":2,"52":2}}],["iso",{"2":{"25":3}}],["isn",{"2":{"15":1}}],["isk9ktvlsug3upgirgyjompfhb41ilyfwidaqabaoibaqdtodff2jjhh1um",{"2":{"9":6}}],["issued",{"2":{"11":1}}],["issuer",{"2":{"9":9}}],["issues",{"2":{"6":1}}],["is",{"2":{"1":2,"8":9,"9":110,"10":13,"11":5,"12":2,"15":2,"16":12,"17":4,"18":1,"19":1,"21":2,"22":3,"25":4,"28":2,"29":2,"30":1,"31":1,"34":2,"38":1,"39":1,"41":1,"43":6,"45":9,"48":1,"49":1,"50":2,"56":2}}],["fssl",{"2":{"29":1}}],["fully",{"2":{"17":1,"25":1}}],["full",{"2":{"16":2,"17":2}}],["function",{"2":{"11":1,"16":2,"31":1}}],["functionality",{"2":{"3":1,"9":2}}],["funni",{"2":{"1":1}}],["feel",{"2":{"18":1}}],["few",{"2":{"10":1}}],["feature",{"2":{"9":2,"45":1}}],["frequently",{"0":{"13":1},"1":{"14":1,"15":1,"16":1,"17":1}}],["free",{"2":{"10":1,"18":1,"39":1}}],["front",{"2":{"12":1,"43":1}}],["from=",{"2":{"10":1}}],["from",{"0":{"33":1},"2":{"1":3,"9":13,"10":8,"33":1,"35":1,"36":1,"37":1,"41":1,"45":2}}],["fragment",{"2":{"9":1}}],["fpfpgscgyeap",{"2":{"9":6}}],["ftalhaofjbzi9wndttqxpugwjphj4hqbc67jc",{"2":{"9":6}}],["fkh3odn+ztewobmdzpd+kgtrk8ysv2ou",{"2":{"9":6}}],["failing",{"2":{"15":1}}],["failed",{"2":{"9":2}}],["failure",{"2":{"9":1}}],["false",{"2":{"9":32,"16":3}}],["factor",{"2":{"8":1,"9":24}}],["faq",{"2":{"7":1}}],["found",{"2":{"9":2,"18":1}}],["followed",{"2":{"10":1}}],["follow",{"2":{"9":3,"25":1,"27":1,"29":1,"30":1,"47":1,"49":1,"54":1}}],["follows",{"2":{"9":2,"48":1}}],["following",{"2":{"9":2,"10":2,"15":2,"25":1,"26":2,"29":2,"30":1}}],["folder",{"2":{"1":2,"11":5,"12":5,"15":9}}],["forwarder",{"2":{"56":1}}],["forwarding",{"2":{"25":1,"50":1}}],["forget",{"2":{"30":2,"45":1,"48":1}}],["forged",{"2":{"9":1}}],["forgot",{"2":{"17":1}}],["forcing",{"2":{"9":1}}],["force",{"2":{"9":2,"10":1}}],["form",{"2":{"9":4,"10":1}}],["formatted",{"2":{"9":1}}],["formatting",{"2":{"6":1,"18":1,"19":1}}],["format",{"2":{"9":13,"10":2}}],["for",{"0":{"34":1,"45":1,"50":1},"1":{"35":1,"36":1,"37":1,"38":1,"39":1,"40":1},"2":{"7":1,"8":9,"9":68,"10":17,"11":7,"12":5,"14":1,"15":1,"16":9,"17":4,"18":2,"19":4,"21":1,"22":4,"25":3,"29":1,"30":1,"31":1,"34":1,"39":2,"41":4,"43":3,"44":1,"45":5,"48":1,"50":2}}],["firewall",{"2":{"48":1}}],["first",{"2":{"1":2,"9":3,"10":2,"16":1,"25":1,"26":1,"49":1}}],["fix",{"2":{"26":1}}],["fixed",{"2":{"6":1,"7":1}}],["fits",{"2":{"18":1}}],["figure",{"2":{"17":1}}],["field",{"2":{"10":1}}],["filled",{"2":{"9":1}}],["filter",{"2":{"9":10,"16":9}}],["filters",{"2":{"9":1}}],["files",{"2":{"11":4,"25":2,"43":1,"45":1}}],["filesystem",{"2":{"9":2}}],["file=",{"2":{"10":2}}],["filename",{"2":{"9":1}}],["file",{"0":{"12":2},"2":{"1":2,"9":9,"10":17,"11":2,"12":2,"19":6,"26":2,"43":1,"45":2,"54":1}}],["finding",{"2":{"17":1}}],["find",{"2":{"9":6,"10":1,"15":1,"18":2,"41":1}}],["finished",{"2":{"31":1}}],["finish",{"2":{"1":1,"8":1,"30":1,"48":1}}],["blob",{"2":{"16":1}}],["block",{"2":{"3":1,"9":1}}],["bcrypt",{"2":{"9":1}}],["bi",{"2":{"45":1}}],["bios",{"2":{"25":1}}],["bitnami",{"2":{"12":2}}],["bit",{"2":{"11":1,"17":1,"39":1,"43":3}}],["bitwarden",{"2":{"8":1}}],["bind",{"2":{"10":1,"16":5}}],["binding",{"2":{"9":1}}],["bqwmtt0baogbapuw5z32esznepaev3e2mpfuc5cliqaxagzjundo2pktyn29ettr",{"2":{"9":6}}],["buildx",{"2":{"29":1}}],["button",{"2":{"48":1,"50":2}}],["but",{"0":{"32":1},"1":{"33":1,"34":1,"35":1,"36":1,"37":1,"38":1,"39":1,"40":1,"41":1},"2":{"9":7,"10":2,"11":1,"16":1,"17":2,"22":1,"26":1,"39":1,"45":2}}],["buffer",{"2":{"9":7}}],["buffers",{"2":{"9":5}}],["bridge",{"2":{"12":1}}],["brute",{"2":{"9":1,"10":1}}],["break",{"2":{"9":1,"12":1}}],["browser",{"2":{"9":1}}],["brackets",{"2":{"9":1,"10":1,"12":1,"30":1}}],["basic",{"2":{"40":1,"41":1}}],["based",{"2":{"9":3,"16":1,"49":1}}],["base",{"2":{"9":5,"10":3,"12":1,"15":1,"16":4,"45":1}}],["base64",{"2":{"9":3}}],["balena",{"2":{"25":1}}],["bad",{"2":{"15":1,"18":1,"19":1}}],["ban",{"2":{"9":2}}],["banned",{"2":{"9":4}}],["bans",{"2":{"9":1}}],["bauwaweb",{"2":{"9":6}}],["baqd",{"2":{"9":12}}],["backed",{"2":{"45":3}}],["backend",{"2":{"9":5,"16":1}}],["backups",{"2":{"45":2}}],["backup",{"2":{"12":1,"45":1}}],["back",{"2":{"3":1,"8":1}}],["by=",{"2":{"29":1}}],["bypass",{"2":{"9":4}}],["bytes",{"2":{"9":1}}],["by",{"2":{"8":1,"9":21,"10":4,"16":1,"26":1,"56":1}}],["bound",{"2":{"10":2}}],["boot",{"2":{"25":1,"41":1}}],["boolean",{"2":{"9":1}}],["books",{"2":{"8":1}}],["bob",{"2":{"9":4}}],["box",{"2":{"9":1,"15":1,"16":1,"22":1}}],["bottom",{"2":{"1":1}}],["both",{"2":{"1":1,"8":1,"9":2,"10":1,"12":3,"16":1,"25":1}}],["becoming",{"2":{"25":1}}],["because",{"2":{"9":3,"16":2}}],["beware",{"2":{"9":1}}],["beginning",{"2":{"9":1}}],["begin",{"2":{"9":18}}],["belonged",{"2":{"9":1}}],["belong",{"2":{"9":2}}],["below",{"2":{"1":1,"8":1,"9":10,"16":1,"18":1,"30":1,"49":1}}],["between",{"2":{"9":3,"10":1,"43":1}}],["before",{"2":{"9":12,"19":2,"25":1,"31":1,"41":1,"48":1}}],["behaviour",{"2":{"9":2}}],["behind",{"2":{"0":1,"15":3}}],["been",{"2":{"9":2,"21":1}}],["best",{"2":{"8":1,"19":1}}],["be",{"0":{"31":1},"2":{"8":5,"9":55,"10":15,"11":4,"12":1,"15":6,"16":9,"17":1,"18":2,"22":2,"25":1,"26":1,"29":2,"31":3,"40":1,"45":2,"50":2}}],["being",{"2":{"1":1,"9":1,"10":1}}],["wrong",{"2":{"17":1}}],["written",{"2":{"9":3,"25":1,"51":1}}],["write",{"2":{"9":10,"25":1}}],["writing",{"2":{"9":1,"25":1,"41":1}}],["w+",{"2":{"9":2}}],["wsdc",{"2":{"9":6}}],["wqcmaawdqyjkozihvcn",{"2":{"9":6}}],["weekly",{"2":{"45":1}}],["welcome",{"0":{"18":1},"1":{"19":1}}],["well",{"2":{"9":1,"40":1,"41":1,"43":1,"45":1}}],["weblogin",{"2":{"43":1}}],["website",{"2":{"18":1}}],["webserver",{"2":{"11":1,"43":2,"45":1}}],["web",{"2":{"11":1,"12":1,"15":1,"23":1}}],["webauthn",{"2":{"9":8}}],["we",{"2":{"9":13,"10":1,"18":1}}],["would",{"2":{"9":1,"10":1,"17":3}}],["woz2sq",{"2":{"9":6}}],["won",{"2":{"9":1,"48":1}}],["worky",{"0":{"26":1}}],["working",{"2":{"25":1,"29":1,"43":1}}],["works",{"2":{"9":1,"10":1,"16":3}}],["work",{"2":{"1":1,"9":1,"11":1,"15":1,"27":1,"40":1}}],["www",{"2":{"8":2,"9":30,"11":1,"16":1,"54":1}}],["why",{"2":{"26":1}}],["while",{"2":{"17":1,"23":2}}],["which",{"2":{"1":1,"9":23,"10":3,"15":1,"16":3,"17":1,"22":1,"30":1,"45":1}}],["who",{"2":{"16":1}}],["whether",{"2":{"9":1,"10":2}}],["whenever",{"2":{"43":1,"45":1}}],["when",{"2":{"9":13,"10":4,"11":1,"15":3,"17":1,"18":1,"25":2,"26":1,"33":1}}],["where",{"0":{"33":1},"2":{"9":10,"10":1,"11":2,"56":1}}],["what",{"0":{"41":1},"2":{"8":1,"9":3,"16":1,"17":1,"43":2}}],["whatever",{"2":{"1":1,"15":1,"25":1,"38":1,"43":1}}],["wish",{"2":{"30":1}}],["wiki",{"2":{"22":1}}],["windows",{"0":{"46":1,"47":1,"51":1,"52":1},"1":{"47":1,"48":2,"49":2,"50":2,"51":2,"52":2},"2":{"47":1,"48":2}}],["window",{"0":{"47":1,"54":1},"1":{"48":1,"49":1,"50":1,"51":1,"52":1,"55":1,"56":1},"2":{"9":1,"50":1,"51":2,"52":2,"55":2,"56":1}}],["wildcards",{"2":{"9":1}}],["wildcard",{"2":{"9":1}}],["will",{"2":{"1":1,"9":19,"10":8,"11":5,"12":2,"15":9,"16":5,"17":1,"18":1,"19":1,"25":2,"26":2,"41":4,"45":1,"50":1,"51":1,"52":1}}],["within",{"2":{"9":1,"40":1,"45":1}}],["without",{"2":{"9":2,"10":1,"23":1}}],["with",{"2":{"1":4,"9":27,"10":18,"12":2,"15":4,"16":3,"23":2,"25":2,"33":1,"40":1,"43":2,"51":2,"52":2,"56":1}}],["was",{"2":{"16":1,"17":1,"45":1}}],["warn",{"2":{"10":1}}],["warning",{"2":{"9":1,"10":1,"15":1,"19":1,"45":1}}],["watch",{"2":{"9":1}}],["wait",{"2":{"9":1}}],["way",{"2":{"1":1,"8":2,"9":1,"15":1,"17":3,"41":1,"43":2}}],["want",{"2":{"0":2,"1":1,"8":1,"9":1,"10":5,"11":1,"12":2,"15":5,"17":1,"21":1,"48":2,"51":1,"52":1,"55":1}}],["ram",{"2":{"35":1,"36":1,"37":1,"40":1}}],["rather",{"2":{"34":1}}],["raw",{"2":{"23":1}}],["ran",{"2":{"31":1}}],["rand0m",{"2":{"10":1}}],["random",{"2":{"10":4,"12":2}}],["randomly",{"2":{"9":2,"10":1}}],["range",{"2":{"9":1}}],["rtf",{"2":{"19":3}}],["root",{"2":{"12":4,"25":2,"26":2}}],["route",{"2":{"9":2,"41":1}}],["right",{"2":{"11":1,"16":1,"22":1,"45":1}}],["rs256",{"2":{"9":1}}],["rsa",{"2":{"9":12}}],["r",{"2":{"9":1}}],["rfc5322",{"2":{"9":1}}],["rfc2307",{"2":{"9":1}}],["rfc",{"2":{"9":1}}],["rbotcci1gqznlqwovq65zieiai7o1vpbzo2gmqezuq8mdkfsomthvvtrm5caep84",{"2":{"9":6}}],["r4bf6tkjd+ovr17fafkswkgahz5xa7j48kiq+yc4jbnyksxztyykpjh",{"2":{"9":6}}],["rxmtxflk2b51wgeeydfi+necsqkzr4r54eopkbewrfvuy",{"2":{"9":6}}],["rufus",{"2":{"25":1}}],["run",{"2":{"9":1,"10":1,"15":4,"28":2,"30":3,"45":1,"51":1,"52":1,"56":3}}],["running",{"0":{"48":1,"55":1},"2":{"1":1,"22":1,"48":1,"49":1}}],["rules",{"2":{"9":11}}],["rule",{"0":{"12":1},"2":{"9":5}}],["renew",{"2":{"45":1}}],["renewing",{"2":{"41":1}}],["rename",{"2":{"19":1}}],["reboot",{"2":{"25":2,"26":1,"27":1}}],["recovering",{"2":{"45":1}}],["recognize",{"2":{"25":1}}],["recommendation",{"2":{"10":1,"16":1,"41":1}}],["recommend",{"2":{"9":8,"11":1,"12":2,"41":1,"50":1}}],["recommended",{"2":{"8":2,"9":10,"16":1,"21":1,"27":1,"37":1}}],["reverse",{"2":{"11":1,"15":3,"40":1,"43":2}}],["revocation",{"2":{"9":1}}],["real",{"0":{"48":1,"55":1}}],["really",{"2":{"15":1,"50":1}}],["reason",{"2":{"26":1,"45":1}}],["reasons",{"2":{"9":1}}],["readonly",{"2":{"16":1}}],["ready",{"2":{"9":1,"22":1}}],["read",{"2":{"9":26}}],["reject",{"2":{"9":1}}],["remain",{"2":{"12":2}}],["remains",{"2":{"9":1}}],["remembered",{"2":{"9":1}}],["remember",{"2":{"9":6}}],["remove",{"2":{"15":2,"19":2,"30":1}}],["removed",{"2":{"5":1,"9":1}}],["remote",{"2":{"9":1}}],["reputable",{"2":{"41":1}}],["repertoire",{"2":{"11":1}}],["replacing",{"2":{"51":1,"52":1}}],["replace",{"2":{"10":4,"12":1,"16":1}}],["replaced",{"2":{"9":1,"56":2}}],["replacements",{"2":{"9":2}}],["reply",{"2":{"10":3}}],["represents",{"2":{"9":1}}],["release",{"2":{"29":1}}],["relevant",{"2":{"9":1,"10":2,"11":1}}],["reloaded",{"2":{"15":1}}],["reload",{"2":{"15":2,"43":1}}],["reload|linuxserver",{"2":{"1":2,"12":1}}],["relying",{"2":{"10":1}}],["referred",{"2":{"9":1}}],["referrals",{"2":{"9":2}}],["referer",{"2":{"9":1}}],["refresh",{"2":{"9":7,"16":1}}],["retries",{"2":{"9":2}}],["retrieve",{"2":{"9":1}}],["returned",{"2":{"9":2}}],["return",{"2":{"9":1,"50":1}}],["registrars",{"2":{"41":1}}],["registrar",{"2":{"41":1}}],["registration",{"2":{"9":2}}],["register",{"2":{"9":1,"43":1}}],["registered",{"2":{"0":1}}],["regulation",{"2":{"9":3}}],["regular",{"2":{"9":1,"25":1}}],["regex",{"2":{"9":5}}],["regardless",{"2":{"9":1}}],["redis",{"2":{"9":20,"12":7,"31":5,"38":1}}],["redirects",{"2":{"9":1}}],["redirected",{"2":{"9":1}}],["redirect",{"2":{"9":6}}],["redirection",{"2":{"9":3}}],["reduce",{"2":{"9":1}}],["redacted",{"2":{"9":8}}],["redo",{"2":{"6":1,"12":1}}],["reinjected",{"2":{"8":1}}],["requrires",{"2":{"15":1}}],["requirement",{"2":{"9":1,"37":1}}],["requirements",{"0":{"34":1},"1":{"35":1,"36":1,"37":1,"38":1,"39":1,"40":1},"2":{"6":1,"18":2}}],["requires",{"2":{"9":2,"16":3,"38":1,"39":1,"43":1}}],["require",{"2":{"9":17,"10":1,"25":1,"41":1}}],["required",{"0":{"45":1},"2":{"9":6,"16":1,"21":1}}],["requests",{"2":{"9":11,"37":1}}],["request",{"2":{"9":4,"10":1}}],["req",{"2":{"6":1}}],["re",{"2":{"1":1,"9":2,"10":1,"18":1}}],["research",{"2":{"41":1}}],["reset=true",{"2":{"10":1}}],["resetting",{"2":{"9":1}}],["reset",{"2":{"9":9,"10":3,"16":2,"41":1}}],["respective",{"2":{"17":1}}],["response",{"2":{"9":5}}],["responses",{"2":{"9":3}}],["result",{"2":{"15":1}}],["results",{"2":{"9":1,"19":1}}],["restore",{"2":{"29":1}}],["rest",{"2":{"11":1}}],["restrict",{"2":{"10":2}}],["restricted",{"2":{"9":1}}],["restrictions",{"2":{"9":1}}],["restart=always",{"2":{"30":1}}],["restarts",{"2":{"26":1}}],["restart",{"2":{"1":2,"12":4,"22":1,"26":1,"45":2}}],["resource",{"2":{"9":5}}],["resources",{"2":{"1":2,"9":8,"27":1}}],["cmd",{"0":{"52":1}}],["ctrl+x",{"2":{"26":1}}],["ce",{"0":{"30":1},"2":{"22":1,"29":2,"30":3}}],["cert",{"2":{"10":2}}],["certain",{"2":{"9":1}}],["certificate",{"2":{"9":77,"10":2,"11":1}}],["certificates",{"2":{"9":14,"11":3,"29":1,"45":1}}],["cer",{"2":{"9":1}}],["cp",{"2":{"15":1,"29":1}}],["cn=",{"2":{"16":1}}],["cn=admin",{"2":{"9":1,"10":1}}],["cn",{"2":{"9":1,"16":2}}],["curve",{"2":{"43":1}}],["curl",{"2":{"29":1}}],["currently",{"2":{"9":1}}],["current",{"2":{"9":1,"11":1,"51":1,"52":1,"56":1}}],["customize",{"2":{"23":1}}],["customization",{"2":{"9":1}}],["custom",{"2":{"9":5,"12":2,"16":1,"22":1,"41":1}}],["csp",{"2":{"9":2}}],["c",{"2":{"9":24,"10":1}}],["crazy",{"2":{"45":1}}],["crucial",{"2":{"12":2}}],["cross",{"2":{"9":2}}],["critical",{"2":{"9":2}}],["crt",{"2":{"9":1}}],["creation",{"0":{"17":1},"2":{"17":2}}],["creating",{"2":{"10":2}}],["created",{"2":{"16":1}}],["create",{"2":{"1":1,"10":3,"17":3,"30":3}}],["credits",{"2":{"3":1}}],["credentials",{"2":{"1":1,"50":1}}],["category",{"2":{"50":2}}],["ca",{"2":{"29":1}}],["careful",{"2":{"16":1}}],["called",{"2":{"16":1}}],["callback",{"2":{"9":1}}],["callbacks",{"2":{"9":1}}],["caveat",{"2":{"15":1}}],["cases",{"2":{"9":2,"16":1}}],["case",{"2":{"9":3,"10":3,"12":2,"29":1}}],["canvas",{"2":{"16":1}}],["can",{"2":{"8":3,"9":30,"10":14,"11":2,"12":1,"15":7,"16":3,"17":1,"18":3,"22":2,"31":1,"39":1,"40":1,"43":1,"50":3}}],["caps",{"2":{"12":1}}],["cap",{"2":{"1":2,"12":1}}],["chmod",{"2":{"29":1}}],["checkbox",{"2":{"50":1}}],["check",{"2":{"9":13,"15":1,"16":2}}],["cheapest",{"2":{"8":1}}],["chain",{"2":{"9":19}}],["changing",{"2":{"9":8,"10":1}}],["changes",{"0":{"31":1},"2":{"15":4,"17":1,"25":1,"31":1,"50":1}}],["change",{"2":{"9":4,"10":3,"12":2,"15":1,"16":1,"22":1,"25":1,"30":2}}],["changed",{"2":{"6":1,"9":1,"15":1}}],["changelog",{"0":{"2":1},"1":{"3":1,"4":1,"5":1,"6":1,"7":1}}],["character",{"2":{"12":1}}],["characters",{"2":{"9":5,"10":2,"12":1,"16":1,"30":1}}],["chars",{"2":{"9":1}}],["choice",{"2":{"8":1,"9":1,"10":1,"28":1}}],["choose",{"2":{"8":2,"9":2,"41":1}}],["cisco",{"2":{"5":1}}],["cdez",{"2":{"3":1}}],["cf",{"2":{"1":6}}],["clustered",{"2":{"22":2}}],["cli",{"2":{"9":1,"27":1,"29":1}}],["clientid",{"2":{"9":1}}],["clients",{"2":{"9":5}}],["client",{"0":{"47":1,"48":1,"54":1,"55":1},"1":{"48":1,"49":1,"50":1,"51":1,"52":1,"55":1,"56":1},"2":{"9":27,"48":1}}],["click",{"2":{"1":3,"23":1,"30":2,"48":2,"50":2}}],["clock",{"2":{"50":1,"51":1,"52":1}}],["close",{"2":{"47":1,"54":1}}],["closure",{"2":{"3":1}}],["cloud",{"2":{"12":1}}],["cloudflared",{"2":{"1":2}}],["cloudflare",{"0":{"0":1},"1":{"1":1},"2":{"0":2,"1":8,"3":1,"7":1,"9":1,"11":1,"41":1}}],["cover",{"2":{"16":1,"41":1}}],["could",{"2":{"16":1,"45":2}}],["course",{"2":{"1":1}}],["cors",{"2":{"9":2}}],["correctly",{"2":{"16":1,"31":1}}],["correct",{"2":{"9":2,"15":1,"56":1}}],["cookie",{"2":{"9":7}}],["cookies",{"2":{"9":1}}],["cost",{"2":{"9":1}}],["collect",{"2":{"9":1}}],["copy",{"2":{"9":1,"29":1}}],["codename",{"2":{"29":1}}],["code",{"2":{"3":1,"8":1,"9":5,"43":1}}],["congratulations",{"2":{"48":1}}],["conjunction",{"2":{"9":1}}],["connects",{"0":{"48":1,"55":1}}],["connected",{"2":{"25":1}}],["connecting",{"0":{"49":1,"56":1}}],["connectivity",{"2":{"16":1,"50":1,"51":1,"52":1,"56":1}}],["connections",{"2":{"9":8,"10":2}}],["connection",{"2":{"9":13,"10":1,"16":2,"25":1,"50":3}}],["connect",{"2":{"9":6,"11":1,"12":1,"51":1,"52":1,"55":1}}],["concurrent",{"2":{"9":1}}],["constantly",{"2":{"23":1}}],["constraints",{"2":{"17":1}}],["consume",{"2":{"10":1}}],["consumer",{"2":{"9":1}}],["consult",{"2":{"8":1,"15":1,"16":1}}],["consent",{"2":{"9":7}}],["considered",{"2":{"9":1}}],["considering",{"2":{"9":1}}],["conveyance",{"2":{"9":2}}],["conform",{"2":{"17":1}}],["confs",{"2":{"11":3,"15":7}}],["confirm",{"2":{"9":1}}],["confirmation",{"2":{"9":1}}],["configs",{"2":{"16":3}}],["config=",{"2":{"1":1}}],["configuring",{"2":{"9":3,"11":1,"16":1,"41":1}}],["configures",{"2":{"9":4}}],["configured",{"2":{"9":10,"16":1}}],["configure",{"2":{"8":2,"9":3,"10":3,"16":1,"22":1}}],["configurations",{"2":{"9":2,"11":1,"15":1,"43":1,"45":1}}],["configuration",{"0":{"8":1,"9":1,"10":1,"11":1,"20":1,"21":1,"22":1},"1":{"21":1,"22":1,"23":1},"2":{"1":1,"8":2,"9":39,"10":2,"11":3,"15":4,"16":5,"19":3,"23":1,"33":1,"43":5,"45":3,"48":1}}],["configuartion",{"2":{"1":1}}],["config",{"2":{"1":3,"9":8,"10":1,"12":3,"16":2,"19":1,"45":1,"48":1,"50":1}}],["conf",{"2":{"1":1,"11":3,"15":9,"43":1}}],["control",{"2":{"9":4,"43":1,"48":1}}],["controls",{"2":{"9":5}}],["contact",{"2":{"9":3}}],["contains",{"2":{"10":1}}],["containing",{"2":{"9":1}}],["contain",{"2":{"9":1}}],["containers",{"2":{"45":1}}],["containerd",{"2":{"29":1}}],["container",{"2":{"1":2,"9":2,"12":5,"15":3,"45":4}}],["contents",{"2":{"1":1,"10":2}}],["continue",{"2":{"1":1,"9":1,"25":4}}],["com>",{"2":{"10":1}}],["come",{"2":{"10":1}}],["comes",{"2":{"1":1,"15":1,"33":1}}],["combined",{"2":{"9":1}}],["com$",{"2":{"9":5}}],["commandline",{"2":{"21":1}}],["command",{"0":{"52":1},"2":{"9":1,"15":2,"26":1,"29":1,"30":1,"40":1,"51":2,"52":2,"56":3}}],["commands",{"2":{"7":1,"9":1,"26":1,"28":1,"31":1}}],["comma",{"2":{"9":2}}],["commonly",{"2":{"16":1}}],["common",{"2":{"9":4,"14":1}}],["communication",{"2":{"9":1}}],["comments",{"2":{"9":1}}],["comment",{"2":{"1":1}}],["computing",{"2":{"41":1}}],["computer",{"2":{"22":1,"41":1}}],["compilation",{"2":{"34":1}}],["comparison",{"2":{"34":1}}],["complexity",{"2":{"22":1}}],["completely",{"2":{"17":1,"45":2}}],["complete",{"2":{"8":1,"25":1,"54":1}}],["completed",{"2":{"1":1}}],["component",{"2":{"9":1}}],["compose",{"0":{"12":1},"2":{"1":3,"10":1,"11":1,"12":2,"19":4,"30":1}}],["com",{"2":{"1":2,"8":2,"9":54,"10":3,"12":1,"16":4,"23":1,"25":1,"29":2}}],["null",{"2":{"29":1}}],["numeric",{"2":{"9":1}}],["number",{"2":{"9":7,"17":1}}],["nginx",{"2":{"11":5,"15":8}}],["n6hjr4ecgyabwcbssnr0mkvvth",{"2":{"9":6}}],["nf4rcvzlby7lon7qyckxmcadd3x2+nypwh8caweaaam1mdmwdgydvr0paqh",{"2":{"9":6}}],["normal",{"2":{"16":1,"17":1}}],["normally",{"2":{"16":1}}],["noreply",{"2":{"10":1}}],["now",{"2":{"11":1,"16":1,"26":1,"28":2,"50":3}}],["node2",{"2":{"9":1}}],["node1",{"2":{"9":1}}],["nodes",{"2":{"9":2}}],["node",{"2":{"9":3}}],["no",{"0":{"26":1},"2":{"9":2,"10":1,"16":1,"26":1,"48":1,"50":1}}],["non",{"2":{"9":2,"25":2}}],["none",{"2":{"9":4,"10":1}}],["nothing",{"2":{"21":1,"22":1}}],["notice",{"2":{"9":2}}],["notifier",{"2":{"9":3}}],["notifications",{"2":{"9":2}}],["notification",{"2":{"8":1,"9":4,"43":1}}],["notably",{"2":{"9":1}}],["notation",{"2":{"9":9}}],["not",{"2":{"0":1,"1":1,"8":1,"9":58,"10":3,"11":1,"12":1,"16":5,"18":1,"19":2,"26":2,"41":3,"48":1}}],["note",{"2":{"0":1,"9":11,"10":3,"31":1}}],["ntp",{"2":{"9":8}}],["nt",{"2":{"1":2,"12":1}}],["nano",{"2":{"1":1,"15":4,"26":2}}],["namespace",{"2":{"10":1}}],["named",{"2":{"8":1,"17":1}}],["name=create",{"2":{"1":1}}],["name",{"2":{"1":5,"9":29,"10":3,"11":1,"12":11,"15":5,"16":10,"17":3,"25":3,"30":3,"50":1}}],["nat",{"2":{"0":1}}],["necessary",{"2":{"9":1}}],["newer",{"2":{"22":1}}],["newly",{"2":{"9":2,"48":1,"55":1}}],["new",{"0":{"15":1},"2":{"9":2,"11":3,"33":1,"43":1,"45":1}}],["never",{"2":{"8":1,"9":2}}],["next",{"2":{"1":1,"16":1,"29":2,"48":4}}],["netinst",{"2":{"25":1,"29":1}}],["net",{"2":{"1":2,"12":1}}],["networks",{"2":{"1":2,"9":4,"12":7}}],["network",{"2":{"0":1,"1":2,"9":2,"12":7,"15":2,"30":4,"48":1}}],["needs",{"2":{"16":1}}],["needed",{"2":{"10":1,"16":1,"19":1,"29":1,"33":1}}],["need",{"0":{"31":1},"2":{"0":1,"1":2,"8":2,"9":1,"10":2,"12":2,"16":1,"18":1,"22":2,"31":2}}],["o",{"2":{"29":1}}],["os",{"2":{"25":1,"29":1,"41":1,"45":1}}],["ova",{"2":{"19":2}}],["overall",{"0":{"40":1}}],["over",{"2":{"9":1,"16":1,"55":1}}],["override",{"2":{"10":1}}],["overrides",{"2":{"9":2}}],["overridden",{"2":{"10":3}}],["overriding",{"2":{"9":1}}],["overview",{"0":{"43":1},"2":{"1":3,"8":1}}],["omitted",{"2":{"10":1}}],["obtain",{"2":{"9":1}}],["obtained",{"2":{"9":1}}],["object",{"2":{"9":1}}],["objectclass=groupofuniquenames",{"2":{"9":2}}],["objectclass=inetorgperson",{"2":{"9":1}}],["objectclass=person",{"2":{"9":3,"16":5}}],["objectclass=user",{"2":{"9":1}}],["objectcategory=person",{"2":{"9":1}}],["objects",{"2":{"9":1}}],["occasionally",{"2":{"9":1}}],["occurs",{"2":{"9":1}}],["oauth2",{"2":{"9":2}}],["oidc",{"2":{"9":3}}],["odbnl98meoramnij7nt6jnyb3zz578fjawfthibpagiti8gzmg4s4ovh2jbhen8i",{"2":{"9":6}}],["ou",{"2":{"16":2}}],["ou=groups",{"2":{"9":3,"16":5}}],["ou=people",{"2":{"9":2,"10":1,"16":6}}],["ou=users",{"2":{"9":2}}],["our",{"2":{"9":1,"10":2}}],["output",{"2":{"51":1,"52":1}}],["outgoing",{"2":{"9":1}}],["out",{"2":{"9":2,"15":1,"16":2,"17":1,"22":2,"34":1,"45":1}}],["outline",{"2":{"8":1,"17":1}}],["outside",{"2":{"0":1}}],["otherwise",{"2":{"9":2,"15":2,"18":2}}],["other",{"2":{"8":1,"9":1,"10":2,"11":1,"29":1,"34":1,"45":1}}],["own",{"2":{"8":1,"10":1,"15":1}}],["operations",{"2":{"9":2}}],["operate",{"2":{"9":1}}],["opens",{"2":{"55":1}}],["openid",{"2":{"9":4}}],["opening",{"2":{"9":1}}],["openldap",{"2":{"9":2}}],["open",{"2":{"0":1,"9":1,"48":1,"50":1,"55":1}}],["option",{"2":{"9":30,"48":1}}],["options",{"2":{"8":1,"9":9,"10":8,"11":1,"15":1,"23":1,"48":1}}],["optional",{"2":{"1":2,"9":7,"10":2,"12":1,"48":1,"50":1}}],["onto",{"2":{"9":1,"25":1,"30":1}}],["once",{"2":{"9":3,"15":1,"17":1,"25":1,"26":1,"29":1}}],["only",{"2":{"1":2,"9":15,"10":5,"12":1,"27":1,"39":1}}],["ones",{"2":{"16":1}}],["one",{"0":{"12":2},"2":{"1":1,"8":2,"9":24,"10":1,"11":1,"16":1,"17":1,"22":1,"25":1,"30":1,"43":2}}],["on",{"0":{"55":1,"56":1},"2":{"1":1,"6":1,"8":2,"9":17,"10":7,"12":1,"15":1,"16":2,"17":1,"18":2,"22":1,"29":1,"37":1,"39":1,"41":1,"43":2,"47":1,"48":4,"49":1,"50":1}}],["often",{"2":{"16":1,"23":1}}],["offer",{"2":{"22":1}}],["offload",{"2":{"9":1}}],["offline",{"2":{"9":1}}],["offset",{"2":{"9":1}}],["off",{"2":{"8":1}}],["of",{"0":{"43":1,"44":1},"1":{"45":1},"2":{"1":2,"8":3,"9":75,"10":7,"11":4,"12":1,"15":5,"16":9,"17":5,"21":1,"22":4,"24":1,"25":3,"28":1,"29":3,"34":2,"39":1,"41":2,"42":1,"43":4,"45":4,"50":5,"56":1}}],["originate",{"0":{"33":1}}],["origins",{"2":{"9":5}}],["origin",{"2":{"9":4}}],["org",{"2":{"9":1,"54":1}}],["order",{"2":{"1":1,"9":1,"11":2,"29":1}}],["or",{"2":{"0":1,"8":1,"9":33,"10":2,"11":2,"16":6,"17":1,"22":2,"25":2,"35":1,"36":1,"37":1,"41":1,"43":3,"48":1}}],["dynip",{"2":{"51":1,"52":1}}],["dynamic",{"2":{"50":1}}],["drive",{"2":{"45":1}}],["driver",{"2":{"12":1}}],["dc",{"2":{"10":2,"16":1}}],["dc=google",{"2":{"16":1}}],["dc=nt",{"2":{"12":1}}],["dc=example",{"2":{"10":1,"16":2}}],["dc=com",{"2":{"9":4,"10":1,"16":2}}],["dc=a",{"2":{"9":4}}],["dc=",{"2":{"9":4,"10":2,"16":12}}],["dbip",{"2":{"12":1}}],["dbip|linuxserver",{"2":{"1":2}}],["db",{"2":{"9":3,"10":2}}],["dn=dc=sakura",{"2":{"12":1}}],["dn",{"2":{"9":13,"10":4,"16":6}}],["dns",{"2":{"1":2,"11":2}}],["dnsplugin=cloudflare",{"2":{"1":2,"12":1}}],["dwjyibv8pqdgrbizfrphtpjgquldr",{"2":{"9":6}}],["d0s8icyojeypvlerz4whjzu68z5frazhz68ybzns8j2fibkkhkhylg1iqyf+ljvj",{"2":{"9":6}}],["dtngxkmwacqa",{"2":{"9":6}}],["duplicate",{"2":{"17":1}}],["dump",{"2":{"10":1}}],["during",{"2":{"9":8}}],["duration",{"2":{"9":13}}],["duo",{"0":{"8":1,"39":1},"2":{"5":1,"8":6,"9":5,"33":1,"39":1,"43":4,"45":1}}],["danger",{"2":{"29":1}}],["date",{"2":{"28":2,"45":1}}],["database",{"2":{"9":11,"10":7,"12":1}}],["data",{"2":{"9":3,"10":4,"11":1,"12":1,"30":3,"31":1,"45":2,"50":1}}],["dark",{"2":{"9":2}}],["dashboard|linuxserver",{"2":{"1":2,"12":1}}],["d",{"0":{"32":2,"34":1,"42":1,"43":1,"44":1,"45":1},"1":{"33":2,"34":2,"35":3,"36":3,"37":3,"38":3,"39":3,"40":3,"41":2,"43":1,"45":1},"2":{"8":1,"9":1,"12":2,"14":1,"17":2,"19":5,"27":1,"29":2,"30":1,"34":2,"42":1,"43":2,"44":1,"50":1,"51":1,"52":1}}],["didn",{"2":{"16":1}}],["diy",{"2":{"15":1}}],["dinmsf+uioekkoajorc6mi9ww8ytpvo7t2s",{"2":{"9":6}}],["dial",{"2":{"9":1,"16":1}}],["dialogues",{"2":{"9":1}}],["different",{"2":{"9":1,"17":1,"45":1}}],["disabling",{"0":{"27":1}}],["disables",{"2":{"9":6}}],["disabled",{"2":{"9":3}}],["disable",{"2":{"9":20,"16":1,"27":1,"48":1}}],["distinguished",{"2":{"9":1}}],["discouraged",{"2":{"9":8}}],["disk",{"2":{"9":1,"25":3}}],["display=127",{"2":{"52":1,"56":1}}],["display=",{"2":{"51":1}}],["displays",{"2":{"48":1}}],["displayname",{"2":{"9":1,"16":2}}],["displayed",{"2":{"9":1,"16":1}}],["display",{"2":{"9":5,"15":1,"16":2,"17":1,"48":1,"50":1,"51":1,"52":1,"56":1}}],["directly",{"2":{"25":1}}],["direct",{"2":{"9":1}}],["directory`",{"2":{"9":5}}],["directory",{"2":{"9":16,"10":1,"11":1}}],["directive",{"2":{"1":1,"15":2}}],["digits",{"2":{"8":1,"9":3}}],["digit",{"2":{"8":1,"43":1}}],["dearmor",{"2":{"29":1}}],["demonstrates",{"2":{"24":1,"43":1}}],["demand",{"2":{"9":1}}],["degree",{"2":{"17":1}}],["dedicated",{"2":{"16":2}}],["decide",{"2":{"11":1,"15":2}}],["delivery",{"2":{"9":1}}],["delimited",{"2":{"9":2}}],["detailed",{"2":{"16":1,"19":1}}],["details",{"2":{"9":1}}],["detected",{"2":{"9":1}}],["deselect",{"2":{"25":1}}],["desktop",{"2":{"25":1}}],["descriptive",{"2":{"16":1}}],["description",{"2":{"9":2}}],["destroyed",{"2":{"9":3}}],["desync",{"2":{"9":2}}],["deny",{"2":{"9":4}}],["dev",{"2":{"9":8,"10":1,"29":1}}],["device",{"2":{"9":1}}],["defender",{"2":{"48":1}}],["define",{"2":{"9":2}}],["defines",{"2":{"9":2}}],["defined",{"2":{"9":15}}],["definition",{"2":{"9":1}}],["defining",{"2":{"9":1}}],["defaults",{"2":{"9":4}}],["default",{"2":{"8":1,"9":20,"10":2,"23":1,"26":1,"27":1,"29":1}}],["deb",{"2":{"29":1}}],["debug",{"2":{"9":4}}],["debian",{"0":{"21":1,"25":1,"35":1},"2":{"7":1,"21":1,"25":8,"26":2,"28":1,"29":3,"31":1,"33":1,"45":2}}],["der",{"2":{"9":2}}],["depends",{"2":{"12":1,"37":1}}],["depending",{"2":{"9":1,"16":1}}],["dependencies",{"2":{"3":1,"4":1,"5":1}}],["deployed",{"2":{"31":1}}],["deployment",{"2":{"18":1,"19":2}}],["deploy",{"2":{"0":1,"7":1,"18":2,"23":1}}],["download",{"2":{"19":1,"25":2,"29":2}}],["down",{"2":{"18":1}}],["doing",{"2":{"9":2,"17":1}}],["doesn",{"2":{"9":1,"10":1,"15":1}}],["does",{"0":{"33":1},"2":{"9":4,"11":1,"17":1,"22":1,"26":1,"43":1}}],["doc",{"2":{"29":2}}],["docs",{"2":{"9":6,"16":1}}],["documentation",{"2":{"7":1,"8":1,"9":9,"15":1,"18":1}}],["dockercompose",{"2":{"29":1}}],["docker|linuxserver",{"2":{"1":2,"12":1}}],["docker",{"0":{"12":1,"29":1},"2":{"1":7,"10":2,"11":1,"12":2,"15":8,"19":4,"29":11,"30":6,"43":1,"45":2}}],["domains",{"2":{"5":1,"9":1}}],["domains=",{"2":{"1":2,"12":1}}],["domain",{"0":{"49":1,"56":1},"2":{"0":1,"1":11,"9":42,"10":4,"11":1,"15":7,"16":6,"17":1,"25":2,"41":4,"43":1,"50":1,"51":2,"52":2,"56":3}}],["do",{"0":{"14":1,"15":1,"16":1,"17":1},"2":{"0":1,"9":20,"10":1,"11":1,"15":2,"16":1,"17":2,"18":2,"19":1,"22":1,"26":1,"31":1,"41":3,"48":1}}],["done",{"2":{"1":1,"15":2,"17":1,"22":1,"29":1}}],["don",{"2":{"0":1,"9":1,"10":2,"16":1,"30":2,"45":1}}],["dpkg",{"2":{"29":1}}],["dpsaladstackuser",{"2":{"25":1}}],["dpsaladstack",{"2":{"25":1,"30":1}}],["dpsalad",{"2":{"19":1,"25":1}}],["dp",{"0":{"24":1,"32":3,"34":1,"44":1,"45":1},"1":{"25":1,"26":1,"27":1,"28":1,"29":1,"30":1,"31":1,"33":3,"34":3,"35":4,"36":4,"37":4,"38":4,"39":4,"40":4,"41":3,"45":1},"2":{"0":1,"6":1,"7":1,"14":1,"18":5,"19":6,"24":1,"33":1,"34":1,"44":1}}],["tmux",{"2":{"21":2}}],["take",{"2":{"11":1,"17":1}}],["target",{"2":{"9":1,"27":1}}],["typical",{"2":{"10":1,"16":1}}],["typically",{"2":{"9":1,"45":1}}],["types",{"2":{"9":5}}],["type",{"2":{"9":1,"10":1,"26":1,"50":3,"51":1,"52":1}}],["tier",{"2":{"39":1}}],["tip",{"2":{"11":1,"12":1,"15":2,"19":3,"30":1}}],["title",{"2":{"9":2}}],["times",{"2":{"9":2}}],["time",{"2":{"9":21,"15":1,"28":1,"30":1,"41":1,"50":2}}],["timeout",{"2":{"9":14,"16":2}}],["timeouts",{"2":{"9":4}}],["tunable",{"2":{"9":1}}],["tune",{"2":{"9":1,"10":1}}],["tuning",{"2":{"9":1}}],["tunnelconfig",{"2":{"1":2}}],["tunneling",{"2":{"1":1,"3":1,"7":1,"25":1}}],["tunnels",{"2":{"0":1,"1":1}}],["tunnel",{"0":{"0":1},"1":{"1":1},"2":{"1":5}}],["txt",{"2":{"9":2}}],["txe1",{"2":{"9":6}}],["tbc20wwk",{"2":{"9":6}}],["tqxt36ovlp+y84wwqzsjmelbiva9phdvgjmmhz3i1cmni8elpjzweca3pfng6tm9",{"2":{"9":6}}],["t9d9szllu4l2b8xtm4noka22q6mvbxaczgvhuu6nugtflccnk9fbtcfco3awdtdz",{"2":{"9":6}}],["tcp",{"2":{"9":1}}],["tls1",{"2":{"9":10,"16":1}}],["tls",{"2":{"9":50,"10":2,"16":3}}],["tldr",{"2":{"21":3}}],["tld",{"0":{"49":1,"56":1},"2":{"1":6,"9":14,"10":2,"16":6,"17":1,"50":1,"51":2,"52":2,"56":3}}],["tray",{"2":{"48":1,"49":1}}],["trace",{"2":{"9":1}}],["track",{"2":{"1":1,"15":2}}],["try",{"2":{"12":1,"16":1,"26":1}}],["trying",{"2":{"9":1,"15":2,"16":1,"17":1,"25":1}}],["tricky",{"2":{"11":1}}],["tries",{"2":{"9":1}}],["tr",{"2":{"10":1}}],["tree",{"2":{"9":1,"16":1}}],["truly",{"2":{"9":1}}],["true",{"2":{"9":8,"10":1,"12":1}}],["trusted",{"2":{"9":2}}],["terminal",{"2":{"48":1,"50":1,"51":1,"52":1}}],["tee",{"2":{"29":1}}],["temporarily",{"2":{"26":1}}],["temporary",{"2":{"17":1}}],["templates",{"0":{"23":1},"2":{"22":1,"23":6}}],["template",{"2":{"1":1,"9":2,"12":2,"15":6,"19":2,"22":1,"23":1,"25":4,"30":1}}],["tells",{"2":{"45":1}}],["tell",{"2":{"10":1}}],["telemetry",{"2":{"9":2}}],["textbox",{"2":{"50":1}}],["text",{"2":{"9":2,"43":1}}],["technically",{"2":{"9":1}}],["technical",{"2":{"8":1}}],["two",{"2":{"1":1,"9":13,"11":1,"15":1,"31":1,"41":1}}],["tz=america",{"2":{"1":2,"12":2}}],["thing",{"2":{"45":1}}],["things",{"2":{"10":1,"12":1,"45":1}}],["this",{"0":{"41":1},"2":{"1":3,"8":3,"9":101,"10":15,"11":11,"12":1,"15":2,"16":9,"17":5,"18":2,"19":1,"22":2,"23":1,"24":1,"25":2,"26":1,"29":4,"30":1,"33":1,"34":1,"41":5,"43":6,"45":8,"48":4,"50":2,"51":1,"52":1,"55":2}}],["though",{"2":{"9":1,"30":1}}],["those",{"2":{"8":1,"9":1}}],["three",{"2":{"8":1,"9":1}}],["through",{"2":{"0":1,"8":1,"10":2,"11":3,"12":1,"16":1,"17":1,"23":1,"41":3,"43":3}}],["than",{"2":{"8":1,"9":2,"22":1,"29":1}}],["that",{"0":{"48":1,"55":1},"2":{"8":1,"9":11,"10":7,"11":1,"12":5,"15":7,"16":7,"17":3,"22":1,"25":4,"31":2,"38":1,"41":3,"43":1,"45":6}}],["there",{"2":{"9":1,"11":1,"15":1,"16":4,"22":2,"29":1,"34":1,"45":3}}],["therefore",{"2":{"9":2}}],["their",{"2":{"9":3,"17":6,"41":1,"43":1}}],["they",{"2":{"5":1,"9":7,"12":2,"16":2,"17":2,"18":1,"19":1,"22":1}}],["then",{"2":{"1":1,"8":1,"9":1,"15":2,"16":1,"17":3,"26":1,"45":1,"49":1,"50":1}}],["these",{"2":{"1":4,"8":1,"9":7,"10":3,"12":4,"16":2,"19":1,"27":1,"28":1,"31":1,"41":1,"50":2}}],["themselves",{"2":{"17":1,"41":1}}],["theme",{"2":{"9":2}}],["them",{"0":{"12":1},"2":{"0":1,"9":2,"10":1,"12":2,"15":2,"17":3,"18":1,"45":1}}],["the",{"0":{"1":1,"29":1,"33":1,"34":1,"43":1,"44":1,"45":1,"48":3,"49":1,"55":3,"56":1},"1":{"35":1,"36":1,"37":1,"38":1,"39":1,"40":1,"45":1},"2":{"0":2,"1":13,"6":2,"7":1,"8":14,"9":407,"10":69,"11":17,"12":11,"14":1,"15":42,"16":38,"17":12,"18":11,"19":5,"21":3,"22":6,"23":1,"24":2,"25":23,"26":6,"27":1,"28":1,"29":6,"30":7,"31":2,"34":3,"39":1,"40":1,"41":5,"42":2,"43":11,"44":1,"45":14,"47":1,"48":12,"49":3,"50":21,"51":7,"52":7,"54":2,"55":1,"56":8}}],["t",{"2":{"0":1,"9":7,"10":3,"15":2,"16":2,"30":2,"45":1,"48":1}}],["together",{"2":{"43":1}}],["toml",{"2":{"19":1}}],["touched",{"2":{"11":1}}],["to=",{"2":{"10":1}}],["totp",{"2":{"9":14}}],["too",{"2":{"8":1,"9":1}}],["top",{"2":{"1":1,"9":5}}],["tokens",{"2":{"9":5,"10":1}}],["token=api",{"2":{"1":1}}],["token",{"2":{"1":5,"9":6}}],["to",{"0":{"12":1,"15":1,"16":1,"31":1,"48":1,"49":1,"55":1,"56":1},"2":{"0":5,"1":8,"3":3,"4":1,"5":2,"6":2,"7":2,"8":14,"9":172,"10":44,"11":15,"12":6,"15":22,"16":22,"17":13,"18":5,"19":3,"21":3,"22":4,"23":5,"25":9,"26":6,"27":1,"28":4,"29":6,"30":7,"31":4,"34":1,"38":1,"40":1,"41":7,"42":1,"43":4,"45":10,"47":1,"48":2,"50":6,"51":4,"52":4,"54":3,"55":2,"56":3}}],["ssh",{"2":{"25":1,"48":1,"49":1,"50":1,"51":1,"52":1,"55":1,"56":1}}],["ssl",{"2":{"11":2,"16":1,"45":1}}],["sso",{"2":{"9":1}}],["switch",{"2":{"10":2,"23":1}}],["swap",{"2":{"8":1}}],["swag",{"0":{"11":1,"37":1},"2":{"1":17,"11":12,"12":7,"15":10,"19":1,"33":1,"43":2,"45":1}}],["smtp",{"2":{"9":13,"10":9}}],["sqlite",{"2":{"10":3}}],["sqlite3",{"2":{"9":3}}],["square",{"2":{"9":1,"10":1,"12":1,"30":1}}],["space",{"2":{"45":1}}],["specs",{"2":{"34":1}}],["special",{"2":{"9":2}}],["specifically",{"2":{"41":1}}],["specifications",{"2":{"9":1}}],["specific",{"2":{"9":6}}],["specifies",{"2":{"9":2}}],["specifying",{"2":{"10":2}}],["specify",{"2":{"9":1}}],["spy",{"2":{"9":1}}],["scalability",{"2":{"22":1}}],["scaled",{"2":{"9":1}}],["scope",{"2":{"22":1}}],["scopes",{"2":{"9":2}}],["score",{"2":{"9":2}}],["screen",{"2":{"9":1}}],["scrypt",{"2":{"9":1}}],["schema",{"2":{"9":1}}],["scheme",{"2":{"9":2,"25":1}}],["scheme>",{"2":{"9":1}}],["skip",{"2":{"9":10,"16":1}}],["skew",{"2":{"9":3}}],["slow",{"2":{"9":1}}],["slightly",{"2":{"9":1}}],["slashes",{"2":{"9":1}}],["syntactically",{"2":{"9":1}}],["sync",{"2":{"9":1}}],["systemctl",{"2":{"26":1,"27":1}}],["system",{"0":{"28":1},"2":{"9":2,"17":1,"18":1,"25":3,"28":2,"43":1,"48":1,"49":1}}],["similar",{"2":{"34":1}}],["simply",{"2":{"10":2}}],["simple",{"2":{"9":1,"43":1}}],["silence",{"2":{"10":1}}],["site",{"2":{"9":2,"11":4}}],["situations",{"2":{"9":5}}],["since",{"2":{"9":2,"45":1}}],["singlefactor",{"2":{"9":1}}],["single",{"2":{"9":2}}],["signature",{"2":{"10":1}}],["sign",{"2":{"9":5,"16":1,"17":1}}],["signed",{"2":{"9":6,"29":1}}],["signing",{"2":{"9":6}}],["size",{"2":{"9":6}}],["sizes",{"2":{"9":1}}],["side",{"2":{"1":2,"9":1}}],["shmkdir",{"2":{"31":1}}],["shecho",{"2":{"29":1}}],["shcurl",{"2":{"29":1}}],["shhttps",{"2":{"23":1}}],["ships",{"2":{"23":1}}],["shitspace",{"2":{"5":1}}],["shsudo",{"2":{"21":2,"29":6,"30":3}}],["short",{"2":{"9":1}}],["show",{"2":{"9":2}}],["should",{"2":{"9":12,"10":5,"11":1,"12":1,"15":4,"16":4,"21":1,"22":1,"25":1,"26":1,"29":1,"40":1}}],["share",{"2":{"29":2}}],["shared",{"2":{"9":2,"10":1}}],["sharing",{"2":{"9":1}}],["sha2crypt",{"2":{"9":1}}],["sha512",{"2":{"9":2}}],["sha1",{"2":{"8":1,"9":1}}],["sh",{"2":{"9":2}}],["su",{"2":{"26":1}}],["suggested",{"2":{"44":1}}],["suggest",{"2":{"18":1}}],["support",{"2":{"10":2,"16":1}}],["supports",{"2":{"9":1,"16":1}}],["supported",{"2":{"8":3,"16":3}}],["subcategory",{"2":{"50":3}}],["subfolder",{"2":{"15":3}}],["sub",{"2":{"15":7}}],["subdomain",{"2":{"9":2,"15":3}}],["subdomains=false",{"2":{"1":2,"12":1}}],["subdomains=wildcard",{"2":{"1":2,"12":1}}],["subject",{"2":{"9":23}}],["sufficient",{"2":{"9":1}}],["successful",{"2":{"9":1}}],["successfully",{"2":{"7":1,"31":1}}],["such",{"2":{"9":2,"10":1,"12":1,"33":2}}],["surrounded",{"2":{"9":1}}],["sure",{"2":{"1":1,"9":1,"15":4,"25":1,"30":2,"31":1,"45":4,"48":1}}],["sudoers",{"2":{"26":2}}],["sudo",{"0":{"26":1},"2":{"7":1,"21":1,"26":3,"27":2,"28":2,"29":3,"45":2}}],["stylized",{"0":{"32":1},"1":{"33":1,"34":1,"35":1,"36":1,"37":1,"38":1,"39":1,"40":1,"41":1}}],["stick",{"2":{"25":3,"41":1}}],["still",{"2":{"10":1}}],["stuff",{"2":{"11":2}}],["str1ng",{"2":{"10":1}}],["string",{"2":{"9":1,"10":1,"12":1}}],["strings",{"2":{"9":1}}],["strict",{"2":{"9":1,"16":1}}],["strongest",{"2":{"9":1}}],["strongly",{"2":{"9":11}}],["strength",{"2":{"9":1}}],["structure",{"2":{"9":1}}],["stdout",{"2":{"9":3}}],["storage",{"2":{"9":5,"35":1,"36":1,"37":1,"40":1}}],["stores",{"2":{"9":1}}],["stored",{"2":{"9":2,"16":2}}],["store",{"2":{"9":1,"10":2}}],["stolen",{"2":{"9":1}}],["stopped",{"2":{"1":2,"12":4}}],["steps",{"2":{"1":1,"8":1}}],["stable",{"2":{"12":1,"29":1}}],["stand",{"2":{"9":1}}],["standards",{"2":{"17":1}}],["standard",{"2":{"9":4,"16":1,"17":1,"25":1,"45":1}}],["started",{"2":{"30":1}}],["starting",{"2":{"16":1,"17":1}}],["start",{"2":{"9":1,"16":1,"48":1}}],["starttls",{"2":{"9":1,"10":1,"16":1}}],["startup",{"2":{"9":8}}],["statelessness",{"2":{"9":4}}],["stateful",{"2":{"9":2}}],["statement",{"2":{"9":1}}],["static",{"2":{"9":1,"11":3,"15":1}}],["status",{"2":{"1":1}}],["staging=false",{"2":{"1":2,"12":1}}],["stacks",{"2":{"23":1,"34":1}}],["stack",{"0":{"15":1,"32":1,"34":1,"43":1,"44":1,"45":1},"1":{"33":1,"34":1,"35":2,"36":2,"37":2,"38":2,"39":2,"40":2,"41":1,"45":1},"2":{"0":1,"1":1,"7":1,"8":2,"11":1,"12":1,"14":1,"17":1,"18":4,"19":6,"22":1,"24":1,"31":2,"34":3,"41":1,"42":1,"43":2,"44":1,"45":1}}],["safe",{"2":{"45":1}}],["safely",{"2":{"10":2}}],["say",{"2":{"17":1}}],["saved",{"2":{"50":1}}],["save",{"2":{"15":1,"45":2,"48":2,"50":2}}],["salt",{"2":{"9":4}}],["sala",{"0":{"32":2,"34":1,"42":1,"43":1,"44":1,"45":1},"1":{"33":2,"34":2,"35":3,"36":3,"37":3,"38":3,"39":3,"40":3,"41":2,"43":1,"45":1},"2":{"8":1,"14":1,"19":5,"34":2,"42":1,"43":1,"44":1}}],["salad",{"0":{"32":1},"1":{"33":1,"34":1,"35":1,"36":1,"37":1,"38":1,"39":1,"40":1,"41":1},"2":{"0":1,"18":4,"19":1,"24":1,"33":1}}],["sample",{"2":{"10":2,"15":3,"43":1}}],["samaccountname",{"2":{"9":2,"10":1}}],["samesite",{"2":{"9":1}}],["same",{"2":{"9":4,"10":1}}],["sane",{"2":{"9":1}}],["san",{"2":{"9":5}}],["sakurant",{"2":{"1":2,"12":1}}],["sakura",{"2":{"1":2,"12":1}}],["separate",{"2":{"50":1,"51":1,"52":1}}],["send",{"2":{"10":1}}],["sender",{"2":{"9":2,"10":3}}],["sending",{"2":{"9":2,"41":2}}],["sent",{"2":{"9":3}}],["sentinel",{"2":{"9":15}}],["sensitive",{"2":{"9":2,"45":1}}],["search",{"2":{"9":3,"16":2}}],["searching",{"2":{"9":2}}],["searched",{"2":{"9":3}}],["sessions",{"2":{"10":1}}],["session",{"2":{"9":13,"50":2}}],["server=",{"2":{"10":1}}],["servers",{"2":{"9":8,"10":1}}],["server",{"0":{"47":1,"48":2,"49":1,"54":1,"55":2,"56":1},"1":{"48":1,"49":1,"50":1,"51":1,"52":1,"55":1,"56":1},"2":{"9":46,"10":9,"15":1,"25":2,"38":1,"48":1,"56":1}}],["service",{"0":{"16":1},"2":{"1":3,"9":2,"10":1,"11":1,"16":5}}],["services",{"2":{"1":2,"10":4,"11":1,"12":1,"16":1,"17":2,"23":1}}],["seed",{"2":{"9":1,"10":4}}],["see",{"2":{"9":9,"10":1,"11":1,"15":1,"16":3,"18":1,"23":1,"25":1,"26":1}}],["sector",{"2":{"9":2}}],["section",{"2":{"4":1,"7":1,"9":5,"29":1}}],["secure",{"2":{"9":3,"11":1,"16":1,"30":1,"45":1}}],["security",{"2":{"9":6,"45":1}}],["secret=replace",{"2":{"12":1}}],["secrets",{"2":{"9":11,"10":1,"16":1}}],["secret",{"2":{"9":27,"10":8,"12":2,"16":1}}],["seconds",{"2":{"9":3}}],["second",{"2":{"8":1,"16":1}}],["sets",{"2":{"9":2}}],["settings",{"2":{"9":7,"15":1,"16":1,"23":1,"41":1,"48":1}}],["setting",{"0":{"50":1},"2":{"9":7,"10":1,"30":1,"43":1}}],["set",{"2":{"8":1,"9":30,"10":8,"11":1,"12":1,"16":4,"17":1,"26":1,"27":1,"41":1,"42":1,"43":1,"45":1,"50":3,"51":2,"52":3,"56":3}}],["setup",{"0":{"0":1,"24":1,"25":1,"30":1,"42":1,"46":1,"53":1},"1":{"1":1,"25":1,"26":1,"27":1,"28":1,"29":1,"30":1,"31":1,"43":1,"47":1,"48":1,"49":1,"50":1,"51":1,"52":1,"54":1,"55":1,"56":1},"2":{"1":1,"6":1,"8":4,"11":1,"12":1,"16":2,"17":2,"18":1,"21":2,"22":2,"25":5,"30":1,"38":1,"39":2,"41":2,"43":3,"45":1,"48":1}}],["self",{"2":{"9":6,"10":2,"43":1}}],["selfhosted",{"2":{"8":1}}],["selections",{"2":{"25":1}}],["selection",{"2":{"25":1}}],["selected",{"2":{"9":2,"25":2,"48":1}}],["select",{"2":{"1":1,"9":2,"25":4,"48":2}}],["sources",{"2":{"23":1,"29":7}}],["software",{"2":{"21":1,"25":1}}],["so",{"2":{"15":2,"17":1,"18":1,"22":1,"45":1}}],["sock",{"2":{"9":1,"30":2}}],["socket",{"2":{"9":1}}],["solution",{"0":{"1":1},"2":{"43":1}}],["something",{"2":{"15":1,"17":1,"22":1,"25":1}}],["sometimes",{"2":{"0":1,"9":1,"10":1}}],["somewhere",{"2":{"1":1,"48":1}}],["some",{"0":{"31":1},"2":{"1":2,"6":1,"7":1,"8":1,"9":7,"10":1,"11":1,"12":1,"16":3,"17":3,"23":1,"31":1,"40":1,"41":1,"45":1}}],["someone",{"2":{"0":1}}],["s",{"2":{"0":1,"3":1,"7":1,"8":1,"9":17,"10":3,"11":3,"15":4,"17":1,"23":1,"25":2,"28":1,"31":1,"41":1,"43":1,"45":1}}]],"serializationVersion":2}';export{e as default}; diff --git a/.vitepress/dist/assets/chunks/VPLocalSearchBox.BgYvNrGg.js b/.vitepress/dist/assets/chunks/VPLocalSearchBox.BgYvNrGg.js new file mode 100644 index 0000000..79e5616 --- /dev/null +++ b/.vitepress/dist/assets/chunks/VPLocalSearchBox.BgYvNrGg.js @@ -0,0 +1,8 @@ +var Ft=Object.defineProperty;var Ot=(a,e,t)=>e in a?Ft(a,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):a[e]=t;var Ae=(a,e,t)=>Ot(a,typeof e!="symbol"?e+"":e,t);import{V as Ct,p as ie,h as me,ah as tt,ai as Rt,aj as At,q as $e,ak as Mt,d as Lt,D as xe,al as st,am as Dt,an as zt,s as Pt,ao as jt,v as Me,P as he,O as _e,ap as Vt,aq as $t,W as Bt,R as Wt,$ as Kt,o as H,b as Jt,j as _,a0 as Ut,k as L,ar as qt,as as Gt,at as Ht,c as Z,n as nt,e as Se,C as it,F as rt,a as fe,t as pe,au as Qt,av as at,aw as Yt,a7 as Zt,ad as Xt,ax as es,_ as ts}from"./framework.DtMx7FFi.js";import{u as ss,c as ns}from"./theme.Chl5AtGS.js";const is={root:()=>Ct(()=>import("./@localSearchIndexroot.DDTBqYgg.js"),[])};/*! +* tabbable 6.2.0 +* @license MIT, https://github.com/focus-trap/tabbable/blob/master/LICENSE +*/var mt=["input:not([inert])","select:not([inert])","textarea:not([inert])","a[href]:not([inert])","button:not([inert])","[tabindex]:not(slot):not([inert])","audio[controls]:not([inert])","video[controls]:not([inert])",'[contenteditable]:not([contenteditable="false"]):not([inert])',"details>summary:first-of-type:not([inert])","details:not([inert])"],Ne=mt.join(","),gt=typeof Element>"u",ae=gt?function(){}:Element.prototype.matches||Element.prototype.msMatchesSelector||Element.prototype.webkitMatchesSelector,Fe=!gt&&Element.prototype.getRootNode?function(a){var e;return a==null||(e=a.getRootNode)===null||e===void 0?void 0:e.call(a)}:function(a){return a==null?void 0:a.ownerDocument},Oe=function a(e,t){var s;t===void 0&&(t=!0);var n=e==null||(s=e.getAttribute)===null||s===void 0?void 0:s.call(e,"inert"),r=n===""||n==="true",i=r||t&&e&&a(e.parentNode);return i},rs=function(e){var t,s=e==null||(t=e.getAttribute)===null||t===void 0?void 0:t.call(e,"contenteditable");return s===""||s==="true"},bt=function(e,t,s){if(Oe(e))return[];var n=Array.prototype.slice.apply(e.querySelectorAll(Ne));return t&&ae.call(e,Ne)&&n.unshift(e),n=n.filter(s),n},yt=function a(e,t,s){for(var n=[],r=Array.from(e);r.length;){var i=r.shift();if(!Oe(i,!1))if(i.tagName==="SLOT"){var o=i.assignedElements(),l=o.length?o:i.children,c=a(l,!0,s);s.flatten?n.push.apply(n,c):n.push({scopeParent:i,candidates:c})}else{var h=ae.call(i,Ne);h&&s.filter(i)&&(t||!e.includes(i))&&n.push(i);var m=i.shadowRoot||typeof s.getShadowRoot=="function"&&s.getShadowRoot(i),f=!Oe(m,!1)&&(!s.shadowRootFilter||s.shadowRootFilter(i));if(m&&f){var b=a(m===!0?i.children:m.children,!0,s);s.flatten?n.push.apply(n,b):n.push({scopeParent:i,candidates:b})}else r.unshift.apply(r,i.children)}}return n},wt=function(e){return!isNaN(parseInt(e.getAttribute("tabindex"),10))},re=function(e){if(!e)throw new Error("No node provided");return e.tabIndex<0&&(/^(AUDIO|VIDEO|DETAILS)$/.test(e.tagName)||rs(e))&&!wt(e)?0:e.tabIndex},as=function(e,t){var s=re(e);return s<0&&t&&!wt(e)?0:s},os=function(e,t){return e.tabIndex===t.tabIndex?e.documentOrder-t.documentOrder:e.tabIndex-t.tabIndex},xt=function(e){return e.tagName==="INPUT"},ls=function(e){return xt(e)&&e.type==="hidden"},cs=function(e){var t=e.tagName==="DETAILS"&&Array.prototype.slice.apply(e.children).some(function(s){return s.tagName==="SUMMARY"});return t},us=function(e,t){for(var s=0;ssummary:first-of-type"),i=r?e.parentElement:e;if(ae.call(i,"details:not([open]) *"))return!0;if(!s||s==="full"||s==="legacy-full"){if(typeof n=="function"){for(var o=e;e;){var l=e.parentElement,c=Fe(e);if(l&&!l.shadowRoot&&n(l)===!0)return ot(e);e.assignedSlot?e=e.assignedSlot:!l&&c!==e.ownerDocument?e=c.host:e=l}e=o}if(ps(e))return!e.getClientRects().length;if(s!=="legacy-full")return!0}else if(s==="non-zero-area")return ot(e);return!1},ms=function(e){if(/^(INPUT|BUTTON|SELECT|TEXTAREA)$/.test(e.tagName))for(var t=e.parentElement;t;){if(t.tagName==="FIELDSET"&&t.disabled){for(var s=0;s=0)},bs=function a(e){var t=[],s=[];return e.forEach(function(n,r){var i=!!n.scopeParent,o=i?n.scopeParent:n,l=as(o,i),c=i?a(n.candidates):o;l===0?i?t.push.apply(t,c):t.push(o):s.push({documentOrder:r,tabIndex:l,item:n,isScope:i,content:c})}),s.sort(os).reduce(function(n,r){return r.isScope?n.push.apply(n,r.content):n.push(r.content),n},[]).concat(t)},ys=function(e,t){t=t||{};var s;return t.getShadowRoot?s=yt([e],t.includeContainer,{filter:Be.bind(null,t),flatten:!1,getShadowRoot:t.getShadowRoot,shadowRootFilter:gs}):s=bt(e,t.includeContainer,Be.bind(null,t)),bs(s)},ws=function(e,t){t=t||{};var s;return t.getShadowRoot?s=yt([e],t.includeContainer,{filter:Ce.bind(null,t),flatten:!0,getShadowRoot:t.getShadowRoot}):s=bt(e,t.includeContainer,Ce.bind(null,t)),s},oe=function(e,t){if(t=t||{},!e)throw new Error("No node provided");return ae.call(e,Ne)===!1?!1:Be(t,e)},xs=mt.concat("iframe").join(","),Le=function(e,t){if(t=t||{},!e)throw new Error("No node provided");return ae.call(e,xs)===!1?!1:Ce(t,e)};/*! +* focus-trap 7.6.2 +* @license MIT, https://github.com/focus-trap/focus-trap/blob/master/LICENSE +*/function We(a,e){(e==null||e>a.length)&&(e=a.length);for(var t=0,s=Array(e);t0){var s=e[e.length-1];s!==t&&s.pause()}var n=e.indexOf(t);n===-1||e.splice(n,1),e.push(t)},deactivateTrap:function(e,t){var s=e.indexOf(t);s!==-1&&e.splice(s,1),e.length>0&&e[e.length-1].unpause()}},Os=function(e){return e.tagName&&e.tagName.toLowerCase()==="input"&&typeof e.select=="function"},Cs=function(e){return(e==null?void 0:e.key)==="Escape"||(e==null?void 0:e.key)==="Esc"||(e==null?void 0:e.keyCode)===27},ge=function(e){return(e==null?void 0:e.key)==="Tab"||(e==null?void 0:e.keyCode)===9},Rs=function(e){return ge(e)&&!e.shiftKey},As=function(e){return ge(e)&&e.shiftKey},dt=function(e){return setTimeout(e,0)},ve=function(e){for(var t=arguments.length,s=new Array(t>1?t-1:0),n=1;n1&&arguments[1]!==void 0?arguments[1]:{},g=d.hasFallback,T=g===void 0?!1:g,k=d.params,O=k===void 0?[]:k,S=r[u];if(typeof S=="function"&&(S=S.apply(void 0,Is(O))),S===!0&&(S=void 0),!S){if(S===void 0||S===!1)return S;throw new Error("`".concat(u,"` was specified but was not a node, or did not return a node"))}var C=S;if(typeof S=="string"){try{C=s.querySelector(S)}catch(v){throw new Error("`".concat(u,'` appears to be an invalid selector; error="').concat(v.message,'"'))}if(!C&&!T)throw new Error("`".concat(u,"` as selector refers to no known node"))}return C},m=function(){var u=h("initialFocus",{hasFallback:!0});if(u===!1)return!1;if(u===void 0||u&&!Le(u,r.tabbableOptions))if(c(s.activeElement)>=0)u=s.activeElement;else{var d=i.tabbableGroups[0],g=d&&d.firstTabbableNode;u=g||h("fallbackFocus")}else u===null&&(u=h("fallbackFocus"));if(!u)throw new Error("Your focus-trap needs to have at least one focusable element");return u},f=function(){if(i.containerGroups=i.containers.map(function(u){var d=ys(u,r.tabbableOptions),g=ws(u,r.tabbableOptions),T=d.length>0?d[0]:void 0,k=d.length>0?d[d.length-1]:void 0,O=g.find(function(v){return oe(v)}),S=g.slice().reverse().find(function(v){return oe(v)}),C=!!d.find(function(v){return re(v)>0});return{container:u,tabbableNodes:d,focusableNodes:g,posTabIndexesFound:C,firstTabbableNode:T,lastTabbableNode:k,firstDomTabbableNode:O,lastDomTabbableNode:S,nextTabbableNode:function(p){var E=arguments.length>1&&arguments[1]!==void 0?arguments[1]:!0,F=d.indexOf(p);return F<0?E?g.slice(g.indexOf(p)+1).find(function(z){return oe(z)}):g.slice(0,g.indexOf(p)).reverse().find(function(z){return oe(z)}):d[F+(E?1:-1)]}}}),i.tabbableGroups=i.containerGroups.filter(function(u){return u.tabbableNodes.length>0}),i.tabbableGroups.length<=0&&!h("fallbackFocus"))throw new Error("Your focus-trap must have at least one container with at least one tabbable node in it at all times");if(i.containerGroups.find(function(u){return u.posTabIndexesFound})&&i.containerGroups.length>1)throw new Error("At least one node with a positive tabindex was found in one of your focus-trap's multiple containers. Positive tabindexes are only supported in single-container focus-traps.")},b=function(u){var d=u.activeElement;if(d)return d.shadowRoot&&d.shadowRoot.activeElement!==null?b(d.shadowRoot):d},y=function(u){if(u!==!1&&u!==b(document)){if(!u||!u.focus){y(m());return}u.focus({preventScroll:!!r.preventScroll}),i.mostRecentlyFocusedNode=u,Os(u)&&u.select()}},x=function(u){var d=h("setReturnFocus",{params:[u]});return d||(d===!1?!1:u)},w=function(u){var d=u.target,g=u.event,T=u.isBackward,k=T===void 0?!1:T;d=d||Ee(g),f();var O=null;if(i.tabbableGroups.length>0){var S=c(d,g),C=S>=0?i.containerGroups[S]:void 0;if(S<0)k?O=i.tabbableGroups[i.tabbableGroups.length-1].lastTabbableNode:O=i.tabbableGroups[0].firstTabbableNode;else if(k){var v=i.tabbableGroups.findIndex(function(j){var I=j.firstTabbableNode;return d===I});if(v<0&&(C.container===d||Le(d,r.tabbableOptions)&&!oe(d,r.tabbableOptions)&&!C.nextTabbableNode(d,!1))&&(v=S),v>=0){var p=v===0?i.tabbableGroups.length-1:v-1,E=i.tabbableGroups[p];O=re(d)>=0?E.lastTabbableNode:E.lastDomTabbableNode}else ge(g)||(O=C.nextTabbableNode(d,!1))}else{var F=i.tabbableGroups.findIndex(function(j){var I=j.lastTabbableNode;return d===I});if(F<0&&(C.container===d||Le(d,r.tabbableOptions)&&!oe(d,r.tabbableOptions)&&!C.nextTabbableNode(d))&&(F=S),F>=0){var z=F===i.tabbableGroups.length-1?0:F+1,P=i.tabbableGroups[z];O=re(d)>=0?P.firstTabbableNode:P.firstDomTabbableNode}else ge(g)||(O=C.nextTabbableNode(d))}}else O=h("fallbackFocus");return O},R=function(u){var d=Ee(u);if(!(c(d,u)>=0)){if(ve(r.clickOutsideDeactivates,u)){o.deactivate({returnFocus:r.returnFocusOnDeactivate});return}ve(r.allowOutsideClick,u)||u.preventDefault()}},A=function(u){var d=Ee(u),g=c(d,u)>=0;if(g||d instanceof Document)g&&(i.mostRecentlyFocusedNode=d);else{u.stopImmediatePropagation();var T,k=!0;if(i.mostRecentlyFocusedNode)if(re(i.mostRecentlyFocusedNode)>0){var O=c(i.mostRecentlyFocusedNode),S=i.containerGroups[O].tabbableNodes;if(S.length>0){var C=S.findIndex(function(v){return v===i.mostRecentlyFocusedNode});C>=0&&(r.isKeyForward(i.recentNavEvent)?C+1=0&&(T=S[C-1],k=!1))}}else i.containerGroups.some(function(v){return v.tabbableNodes.some(function(p){return re(p)>0})})||(k=!1);else k=!1;k&&(T=w({target:i.mostRecentlyFocusedNode,isBackward:r.isKeyBackward(i.recentNavEvent)})),y(T||i.mostRecentlyFocusedNode||m())}i.recentNavEvent=void 0},J=function(u){var d=arguments.length>1&&arguments[1]!==void 0?arguments[1]:!1;i.recentNavEvent=u;var g=w({event:u,isBackward:d});g&&(ge(u)&&u.preventDefault(),y(g))},Q=function(u){(r.isKeyForward(u)||r.isKeyBackward(u))&&J(u,r.isKeyBackward(u))},W=function(u){Cs(u)&&ve(r.escapeDeactivates,u)!==!1&&(u.preventDefault(),o.deactivate())},V=function(u){var d=Ee(u);c(d,u)>=0||ve(r.clickOutsideDeactivates,u)||ve(r.allowOutsideClick,u)||(u.preventDefault(),u.stopImmediatePropagation())},$=function(){if(i.active)return ut.activateTrap(n,o),i.delayInitialFocusTimer=r.delayInitialFocus?dt(function(){y(m())}):y(m()),s.addEventListener("focusin",A,!0),s.addEventListener("mousedown",R,{capture:!0,passive:!1}),s.addEventListener("touchstart",R,{capture:!0,passive:!1}),s.addEventListener("click",V,{capture:!0,passive:!1}),s.addEventListener("keydown",Q,{capture:!0,passive:!1}),s.addEventListener("keydown",W),o},be=function(){if(i.active)return s.removeEventListener("focusin",A,!0),s.removeEventListener("mousedown",R,!0),s.removeEventListener("touchstart",R,!0),s.removeEventListener("click",V,!0),s.removeEventListener("keydown",Q,!0),s.removeEventListener("keydown",W),o},M=function(u){var d=u.some(function(g){var T=Array.from(g.removedNodes);return T.some(function(k){return k===i.mostRecentlyFocusedNode})});d&&y(m())},U=typeof window<"u"&&"MutationObserver"in window?new MutationObserver(M):void 0,q=function(){U&&(U.disconnect(),i.active&&!i.paused&&i.containers.map(function(u){U.observe(u,{subtree:!0,childList:!0})}))};return o={get active(){return i.active},get paused(){return i.paused},activate:function(u){if(i.active)return this;var d=l(u,"onActivate"),g=l(u,"onPostActivate"),T=l(u,"checkCanFocusTrap");T||f(),i.active=!0,i.paused=!1,i.nodeFocusedBeforeActivation=s.activeElement,d==null||d();var k=function(){T&&f(),$(),q(),g==null||g()};return T?(T(i.containers.concat()).then(k,k),this):(k(),this)},deactivate:function(u){if(!i.active)return this;var d=ct({onDeactivate:r.onDeactivate,onPostDeactivate:r.onPostDeactivate,checkCanReturnFocus:r.checkCanReturnFocus},u);clearTimeout(i.delayInitialFocusTimer),i.delayInitialFocusTimer=void 0,be(),i.active=!1,i.paused=!1,q(),ut.deactivateTrap(n,o);var g=l(d,"onDeactivate"),T=l(d,"onPostDeactivate"),k=l(d,"checkCanReturnFocus"),O=l(d,"returnFocus","returnFocusOnDeactivate");g==null||g();var S=function(){dt(function(){O&&y(x(i.nodeFocusedBeforeActivation)),T==null||T()})};return O&&k?(k(x(i.nodeFocusedBeforeActivation)).then(S,S),this):(S(),this)},pause:function(u){if(i.paused||!i.active)return this;var d=l(u,"onPause"),g=l(u,"onPostPause");return i.paused=!0,d==null||d(),be(),q(),g==null||g(),this},unpause:function(u){if(!i.paused||!i.active)return this;var d=l(u,"onUnpause"),g=l(u,"onPostUnpause");return i.paused=!1,d==null||d(),f(),$(),q(),g==null||g(),this},updateContainerElements:function(u){var d=[].concat(u).filter(Boolean);return i.containers=d.map(function(g){return typeof g=="string"?s.querySelector(g):g}),i.active&&f(),q(),this}},o.updateContainerElements(e),o};function Ds(a,e={}){let t;const{immediate:s,...n}=e,r=ie(!1),i=ie(!1),o=f=>t&&t.activate(f),l=f=>t&&t.deactivate(f),c=()=>{t&&(t.pause(),i.value=!0)},h=()=>{t&&(t.unpause(),i.value=!1)},m=me(()=>{const f=tt(a);return(Array.isArray(f)?f:[f]).map(b=>{const y=tt(b);return typeof y=="string"?y:Rt(y)}).filter(At)});return $e(m,f=>{f.length&&(t=Ls(f,{...n,onActivate(){r.value=!0,e.onActivate&&e.onActivate()},onDeactivate(){r.value=!1,e.onDeactivate&&e.onDeactivate()}}),s&&o())},{flush:"post"}),Mt(()=>l()),{hasFocus:r,isPaused:i,activate:o,deactivate:l,pause:c,unpause:h}}class ce{constructor(e,t=!0,s=[],n=5e3){this.ctx=e,this.iframes=t,this.exclude=s,this.iframesTimeout=n}static matches(e,t){const s=typeof t=="string"?[t]:t,n=e.matches||e.matchesSelector||e.msMatchesSelector||e.mozMatchesSelector||e.oMatchesSelector||e.webkitMatchesSelector;if(n){let r=!1;return s.every(i=>n.call(e,i)?(r=!0,!1):!0),r}else return!1}getContexts(){let e,t=[];return typeof this.ctx>"u"||!this.ctx?e=[]:NodeList.prototype.isPrototypeOf(this.ctx)?e=Array.prototype.slice.call(this.ctx):Array.isArray(this.ctx)?e=this.ctx:typeof this.ctx=="string"?e=Array.prototype.slice.call(document.querySelectorAll(this.ctx)):e=[this.ctx],e.forEach(s=>{const n=t.filter(r=>r.contains(s)).length>0;t.indexOf(s)===-1&&!n&&t.push(s)}),t}getIframeContents(e,t,s=()=>{}){let n;try{const r=e.contentWindow;if(n=r.document,!r||!n)throw new Error("iframe inaccessible")}catch{s()}n&&t(n)}isIframeBlank(e){const t="about:blank",s=e.getAttribute("src").trim();return e.contentWindow.location.href===t&&s!==t&&s}observeIframeLoad(e,t,s){let n=!1,r=null;const i=()=>{if(!n){n=!0,clearTimeout(r);try{this.isIframeBlank(e)||(e.removeEventListener("load",i),this.getIframeContents(e,t,s))}catch{s()}}};e.addEventListener("load",i),r=setTimeout(i,this.iframesTimeout)}onIframeReady(e,t,s){try{e.contentWindow.document.readyState==="complete"?this.isIframeBlank(e)?this.observeIframeLoad(e,t,s):this.getIframeContents(e,t,s):this.observeIframeLoad(e,t,s)}catch{s()}}waitForIframes(e,t){let s=0;this.forEachIframe(e,()=>!0,n=>{s++,this.waitForIframes(n.querySelector("html"),()=>{--s||t()})},n=>{n||t()})}forEachIframe(e,t,s,n=()=>{}){let r=e.querySelectorAll("iframe"),i=r.length,o=0;r=Array.prototype.slice.call(r);const l=()=>{--i<=0&&n(o)};i||l(),r.forEach(c=>{ce.matches(c,this.exclude)?l():this.onIframeReady(c,h=>{t(c)&&(o++,s(h)),l()},l)})}createIterator(e,t,s){return document.createNodeIterator(e,t,s,!1)}createInstanceOnIframe(e){return new ce(e.querySelector("html"),this.iframes)}compareNodeIframe(e,t,s){const n=e.compareDocumentPosition(s),r=Node.DOCUMENT_POSITION_PRECEDING;if(n&r)if(t!==null){const i=t.compareDocumentPosition(s),o=Node.DOCUMENT_POSITION_FOLLOWING;if(i&o)return!0}else return!0;return!1}getIteratorNode(e){const t=e.previousNode();let s;return t===null?s=e.nextNode():s=e.nextNode()&&e.nextNode(),{prevNode:t,node:s}}checkIframeFilter(e,t,s,n){let r=!1,i=!1;return n.forEach((o,l)=>{o.val===s&&(r=l,i=o.handled)}),this.compareNodeIframe(e,t,s)?(r===!1&&!i?n.push({val:s,handled:!0}):r!==!1&&!i&&(n[r].handled=!0),!0):(r===!1&&n.push({val:s,handled:!1}),!1)}handleOpenIframes(e,t,s,n){e.forEach(r=>{r.handled||this.getIframeContents(r.val,i=>{this.createInstanceOnIframe(i).forEachNode(t,s,n)})})}iterateThroughNodes(e,t,s,n,r){const i=this.createIterator(t,e,n);let o=[],l=[],c,h,m=()=>({prevNode:h,node:c}=this.getIteratorNode(i),c);for(;m();)this.iframes&&this.forEachIframe(t,f=>this.checkIframeFilter(c,h,f,o),f=>{this.createInstanceOnIframe(f).forEachNode(e,b=>l.push(b),n)}),l.push(c);l.forEach(f=>{s(f)}),this.iframes&&this.handleOpenIframes(o,e,s,n),r()}forEachNode(e,t,s,n=()=>{}){const r=this.getContexts();let i=r.length;i||n(),r.forEach(o=>{const l=()=>{this.iterateThroughNodes(e,o,t,s,()=>{--i<=0&&n()})};this.iframes?this.waitForIframes(o,l):l()})}}let zs=class{constructor(e){this.ctx=e,this.ie=!1;const t=window.navigator.userAgent;(t.indexOf("MSIE")>-1||t.indexOf("Trident")>-1)&&(this.ie=!0)}set opt(e){this._opt=Object.assign({},{element:"",className:"",exclude:[],iframes:!1,iframesTimeout:5e3,separateWordSearch:!0,diacritics:!0,synonyms:{},accuracy:"partially",acrossElements:!1,caseSensitive:!1,ignoreJoiners:!1,ignoreGroups:0,ignorePunctuation:[],wildcards:"disabled",each:()=>{},noMatch:()=>{},filter:()=>!0,done:()=>{},debug:!1,log:window.console},e)}get opt(){return this._opt}get iterator(){return new ce(this.ctx,this.opt.iframes,this.opt.exclude,this.opt.iframesTimeout)}log(e,t="debug"){const s=this.opt.log;this.opt.debug&&typeof s=="object"&&typeof s[t]=="function"&&s[t](`mark.js: ${e}`)}escapeStr(e){return e.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g,"\\$&")}createRegExp(e){return this.opt.wildcards!=="disabled"&&(e=this.setupWildcardsRegExp(e)),e=this.escapeStr(e),Object.keys(this.opt.synonyms).length&&(e=this.createSynonymsRegExp(e)),(this.opt.ignoreJoiners||this.opt.ignorePunctuation.length)&&(e=this.setupIgnoreJoinersRegExp(e)),this.opt.diacritics&&(e=this.createDiacriticsRegExp(e)),e=this.createMergedBlanksRegExp(e),(this.opt.ignoreJoiners||this.opt.ignorePunctuation.length)&&(e=this.createJoinersRegExp(e)),this.opt.wildcards!=="disabled"&&(e=this.createWildcardsRegExp(e)),e=this.createAccuracyRegExp(e),e}createSynonymsRegExp(e){const t=this.opt.synonyms,s=this.opt.caseSensitive?"":"i",n=this.opt.ignoreJoiners||this.opt.ignorePunctuation.length?"\0":"";for(let r in t)if(t.hasOwnProperty(r)){const i=t[r],o=this.opt.wildcards!=="disabled"?this.setupWildcardsRegExp(r):this.escapeStr(r),l=this.opt.wildcards!=="disabled"?this.setupWildcardsRegExp(i):this.escapeStr(i);o!==""&&l!==""&&(e=e.replace(new RegExp(`(${this.escapeStr(o)}|${this.escapeStr(l)})`,`gm${s}`),n+`(${this.processSynomyms(o)}|${this.processSynomyms(l)})`+n))}return e}processSynomyms(e){return(this.opt.ignoreJoiners||this.opt.ignorePunctuation.length)&&(e=this.setupIgnoreJoinersRegExp(e)),e}setupWildcardsRegExp(e){return e=e.replace(/(?:\\)*\?/g,t=>t.charAt(0)==="\\"?"?":""),e.replace(/(?:\\)*\*/g,t=>t.charAt(0)==="\\"?"*":"")}createWildcardsRegExp(e){let t=this.opt.wildcards==="withSpaces";return e.replace(/\u0001/g,t?"[\\S\\s]?":"\\S?").replace(/\u0002/g,t?"[\\S\\s]*?":"\\S*")}setupIgnoreJoinersRegExp(e){return e.replace(/[^(|)\\]/g,(t,s,n)=>{let r=n.charAt(s+1);return/[(|)\\]/.test(r)||r===""?t:t+"\0"})}createJoinersRegExp(e){let t=[];const s=this.opt.ignorePunctuation;return Array.isArray(s)&&s.length&&t.push(this.escapeStr(s.join(""))),this.opt.ignoreJoiners&&t.push("\\u00ad\\u200b\\u200c\\u200d"),t.length?e.split(/\u0000+/).join(`[${t.join("")}]*`):e}createDiacriticsRegExp(e){const t=this.opt.caseSensitive?"":"i",s=this.opt.caseSensitive?["aàáảãạăằắẳẵặâầấẩẫậäåāą","AÀÁẢÃẠĂẰẮẲẴẶÂẦẤẨẪẬÄÅĀĄ","cçćč","CÇĆČ","dđď","DĐĎ","eèéẻẽẹêềếểễệëěēę","EÈÉẺẼẸÊỀẾỂỄỆËĚĒĘ","iìíỉĩịîïī","IÌÍỈĨỊÎÏĪ","lł","LŁ","nñňń","NÑŇŃ","oòóỏõọôồốổỗộơởỡớờợöøō","OÒÓỎÕỌÔỒỐỔỖỘƠỞỠỚỜỢÖØŌ","rř","RŘ","sšśșş","SŠŚȘŞ","tťțţ","TŤȚŢ","uùúủũụưừứửữựûüůū","UÙÚỦŨỤƯỪỨỬỮỰÛÜŮŪ","yýỳỷỹỵÿ","YÝỲỶỸỴŸ","zžżź","ZŽŻŹ"]:["aàáảãạăằắẳẵặâầấẩẫậäåāąAÀÁẢÃẠĂẰẮẲẴẶÂẦẤẨẪẬÄÅĀĄ","cçćčCÇĆČ","dđďDĐĎ","eèéẻẽẹêềếểễệëěēęEÈÉẺẼẸÊỀẾỂỄỆËĚĒĘ","iìíỉĩịîïīIÌÍỈĨỊÎÏĪ","lłLŁ","nñňńNÑŇŃ","oòóỏõọôồốổỗộơởỡớờợöøōOÒÓỎÕỌÔỒỐỔỖỘƠỞỠỚỜỢÖØŌ","rřRŘ","sšśșşSŠŚȘŞ","tťțţTŤȚŢ","uùúủũụưừứửữựûüůūUÙÚỦŨỤƯỪỨỬỮỰÛÜŮŪ","yýỳỷỹỵÿYÝỲỶỸỴŸ","zžżźZŽŻŹ"];let n=[];return e.split("").forEach(r=>{s.every(i=>{if(i.indexOf(r)!==-1){if(n.indexOf(i)>-1)return!1;e=e.replace(new RegExp(`[${i}]`,`gm${t}`),`[${i}]`),n.push(i)}return!0})}),e}createMergedBlanksRegExp(e){return e.replace(/[\s]+/gmi,"[\\s]+")}createAccuracyRegExp(e){const t="!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~¡¿";let s=this.opt.accuracy,n=typeof s=="string"?s:s.value,r=typeof s=="string"?[]:s.limiters,i="";switch(r.forEach(o=>{i+=`|${this.escapeStr(o)}`}),n){case"partially":default:return`()(${e})`;case"complementary":return i="\\s"+(i||this.escapeStr(t)),`()([^${i}]*${e}[^${i}]*)`;case"exactly":return`(^|\\s${i})(${e})(?=$|\\s${i})`}}getSeparatedKeywords(e){let t=[];return e.forEach(s=>{this.opt.separateWordSearch?s.split(" ").forEach(n=>{n.trim()&&t.indexOf(n)===-1&&t.push(n)}):s.trim()&&t.indexOf(s)===-1&&t.push(s)}),{keywords:t.sort((s,n)=>n.length-s.length),length:t.length}}isNumeric(e){return Number(parseFloat(e))==e}checkRanges(e){if(!Array.isArray(e)||Object.prototype.toString.call(e[0])!=="[object Object]")return this.log("markRanges() will only accept an array of objects"),this.opt.noMatch(e),[];const t=[];let s=0;return e.sort((n,r)=>n.start-r.start).forEach(n=>{let{start:r,end:i,valid:o}=this.callNoMatchOnInvalidRanges(n,s);o&&(n.start=r,n.length=i-r,t.push(n),s=i)}),t}callNoMatchOnInvalidRanges(e,t){let s,n,r=!1;return e&&typeof e.start<"u"?(s=parseInt(e.start,10),n=s+parseInt(e.length,10),this.isNumeric(e.start)&&this.isNumeric(e.length)&&n-t>0&&n-s>0?r=!0:(this.log(`Ignoring invalid or overlapping range: ${JSON.stringify(e)}`),this.opt.noMatch(e))):(this.log(`Ignoring invalid range: ${JSON.stringify(e)}`),this.opt.noMatch(e)),{start:s,end:n,valid:r}}checkWhitespaceRanges(e,t,s){let n,r=!0,i=s.length,o=t-i,l=parseInt(e.start,10)-o;return l=l>i?i:l,n=l+parseInt(e.length,10),n>i&&(n=i,this.log(`End range automatically set to the max value of ${i}`)),l<0||n-l<0||l>i||n>i?(r=!1,this.log(`Invalid range: ${JSON.stringify(e)}`),this.opt.noMatch(e)):s.substring(l,n).replace(/\s+/g,"")===""&&(r=!1,this.log("Skipping whitespace only range: "+JSON.stringify(e)),this.opt.noMatch(e)),{start:l,end:n,valid:r}}getTextNodes(e){let t="",s=[];this.iterator.forEachNode(NodeFilter.SHOW_TEXT,n=>{s.push({start:t.length,end:(t+=n.textContent).length,node:n})},n=>this.matchesExclude(n.parentNode)?NodeFilter.FILTER_REJECT:NodeFilter.FILTER_ACCEPT,()=>{e({value:t,nodes:s})})}matchesExclude(e){return ce.matches(e,this.opt.exclude.concat(["script","style","title","head","html"]))}wrapRangeInTextNode(e,t,s){const n=this.opt.element?this.opt.element:"mark",r=e.splitText(t),i=r.splitText(s-t);let o=document.createElement(n);return o.setAttribute("data-markjs","true"),this.opt.className&&o.setAttribute("class",this.opt.className),o.textContent=r.textContent,r.parentNode.replaceChild(o,r),i}wrapRangeInMappedTextNode(e,t,s,n,r){e.nodes.every((i,o)=>{const l=e.nodes[o+1];if(typeof l>"u"||l.start>t){if(!n(i.node))return!1;const c=t-i.start,h=(s>i.end?i.end:s)-i.start,m=e.value.substr(0,i.start),f=e.value.substr(h+i.start);if(i.node=this.wrapRangeInTextNode(i.node,c,h),e.value=m+f,e.nodes.forEach((b,y)=>{y>=o&&(e.nodes[y].start>0&&y!==o&&(e.nodes[y].start-=h),e.nodes[y].end-=h)}),s-=h,r(i.node.previousSibling,i.start),s>i.end)t=i.end;else return!1}return!0})}wrapMatches(e,t,s,n,r){const i=t===0?0:t+1;this.getTextNodes(o=>{o.nodes.forEach(l=>{l=l.node;let c;for(;(c=e.exec(l.textContent))!==null&&c[i]!=="";){if(!s(c[i],l))continue;let h=c.index;if(i!==0)for(let m=1;m{let l;for(;(l=e.exec(o.value))!==null&&l[i]!=="";){let c=l.index;if(i!==0)for(let m=1;ms(l[i],m),(m,f)=>{e.lastIndex=f,n(m)})}r()})}wrapRangeFromIndex(e,t,s,n){this.getTextNodes(r=>{const i=r.value.length;e.forEach((o,l)=>{let{start:c,end:h,valid:m}=this.checkWhitespaceRanges(o,i,r.value);m&&this.wrapRangeInMappedTextNode(r,c,h,f=>t(f,o,r.value.substring(c,h),l),f=>{s(f,o)})}),n()})}unwrapMatches(e){const t=e.parentNode;let s=document.createDocumentFragment();for(;e.firstChild;)s.appendChild(e.removeChild(e.firstChild));t.replaceChild(s,e),this.ie?this.normalizeTextNode(t):t.normalize()}normalizeTextNode(e){if(e){if(e.nodeType===3)for(;e.nextSibling&&e.nextSibling.nodeType===3;)e.nodeValue+=e.nextSibling.nodeValue,e.parentNode.removeChild(e.nextSibling);else this.normalizeTextNode(e.firstChild);this.normalizeTextNode(e.nextSibling)}}markRegExp(e,t){this.opt=t,this.log(`Searching with expression "${e}"`);let s=0,n="wrapMatches";const r=i=>{s++,this.opt.each(i)};this.opt.acrossElements&&(n="wrapMatchesAcrossElements"),this[n](e,this.opt.ignoreGroups,(i,o)=>this.opt.filter(o,i,s),r,()=>{s===0&&this.opt.noMatch(e),this.opt.done(s)})}mark(e,t){this.opt=t;let s=0,n="wrapMatches";const{keywords:r,length:i}=this.getSeparatedKeywords(typeof e=="string"?[e]:e),o=this.opt.caseSensitive?"":"i",l=c=>{let h=new RegExp(this.createRegExp(c),`gm${o}`),m=0;this.log(`Searching with expression "${h}"`),this[n](h,1,(f,b)=>this.opt.filter(b,c,s,m),f=>{m++,s++,this.opt.each(f)},()=>{m===0&&this.opt.noMatch(c),r[i-1]===c?this.opt.done(s):l(r[r.indexOf(c)+1])})};this.opt.acrossElements&&(n="wrapMatchesAcrossElements"),i===0?this.opt.done(s):l(r[0])}markRanges(e,t){this.opt=t;let s=0,n=this.checkRanges(e);n&&n.length?(this.log("Starting to mark with the following ranges: "+JSON.stringify(n)),this.wrapRangeFromIndex(n,(r,i,o,l)=>this.opt.filter(r,i,o,l),(r,i)=>{s++,this.opt.each(r,i)},()=>{this.opt.done(s)})):this.opt.done(s)}unmark(e){this.opt=e;let t=this.opt.element?this.opt.element:"*";t+="[data-markjs]",this.opt.className&&(t+=`.${this.opt.className}`),this.log(`Removal selector "${t}"`),this.iterator.forEachNode(NodeFilter.SHOW_ELEMENT,s=>{this.unwrapMatches(s)},s=>{const n=ce.matches(s,t),r=this.matchesExclude(s);return!n||r?NodeFilter.FILTER_REJECT:NodeFilter.FILTER_ACCEPT},this.opt.done)}};function Ps(a){const e=new zs(a);return this.mark=(t,s)=>(e.mark(t,s),this),this.markRegExp=(t,s)=>(e.markRegExp(t,s),this),this.markRanges=(t,s)=>(e.markRanges(t,s),this),this.unmark=t=>(e.unmark(t),this),this}function ke(a,e,t,s){function n(r){return r instanceof t?r:new t(function(i){i(r)})}return new(t||(t=Promise))(function(r,i){function o(h){try{c(s.next(h))}catch(m){i(m)}}function l(h){try{c(s.throw(h))}catch(m){i(m)}}function c(h){h.done?r(h.value):n(h.value).then(o,l)}c((s=s.apply(a,[])).next())})}const js="ENTRIES",_t="KEYS",St="VALUES",D="";class De{constructor(e,t){const s=e._tree,n=Array.from(s.keys());this.set=e,this._type=t,this._path=n.length>0?[{node:s,keys:n}]:[]}next(){const e=this.dive();return this.backtrack(),e}dive(){if(this._path.length===0)return{done:!0,value:void 0};const{node:e,keys:t}=le(this._path);if(le(t)===D)return{done:!1,value:this.result()};const s=e.get(le(t));return this._path.push({node:s,keys:Array.from(s.keys())}),this.dive()}backtrack(){if(this._path.length===0)return;const e=le(this._path).keys;e.pop(),!(e.length>0)&&(this._path.pop(),this.backtrack())}key(){return this.set._prefix+this._path.map(({keys:e})=>le(e)).filter(e=>e!==D).join("")}value(){return le(this._path).node.get(D)}result(){switch(this._type){case St:return this.value();case _t:return this.key();default:return[this.key(),this.value()]}}[Symbol.iterator](){return this}}const le=a=>a[a.length-1],Vs=(a,e,t)=>{const s=new Map;if(e===void 0)return s;const n=e.length+1,r=n+t,i=new Uint8Array(r*n).fill(t+1);for(let o=0;o{const l=r*i;e:for(const c of a.keys())if(c===D){const h=n[l-1];h<=t&&s.set(o,[a.get(c),h])}else{let h=r;for(let m=0;mt)continue e}Et(a.get(c),e,t,s,n,h,i,o+c)}};class X{constructor(e=new Map,t=""){this._size=void 0,this._tree=e,this._prefix=t}atPrefix(e){if(!e.startsWith(this._prefix))throw new Error("Mismatched prefix");const[t,s]=Re(this._tree,e.slice(this._prefix.length));if(t===void 0){const[n,r]=qe(s);for(const i of n.keys())if(i!==D&&i.startsWith(r)){const o=new Map;return o.set(i.slice(r.length),n.get(i)),new X(o,e)}}return new X(t,e)}clear(){this._size=void 0,this._tree.clear()}delete(e){return this._size=void 0,$s(this._tree,e)}entries(){return new De(this,js)}forEach(e){for(const[t,s]of this)e(t,s,this)}fuzzyGet(e,t){return Vs(this._tree,e,t)}get(e){const t=Ke(this._tree,e);return t!==void 0?t.get(D):void 0}has(e){const t=Ke(this._tree,e);return t!==void 0&&t.has(D)}keys(){return new De(this,_t)}set(e,t){if(typeof e!="string")throw new Error("key must be a string");return this._size=void 0,ze(this._tree,e).set(D,t),this}get size(){if(this._size)return this._size;this._size=0;const e=this.entries();for(;!e.next().done;)this._size+=1;return this._size}update(e,t){if(typeof e!="string")throw new Error("key must be a string");this._size=void 0;const s=ze(this._tree,e);return s.set(D,t(s.get(D))),this}fetch(e,t){if(typeof e!="string")throw new Error("key must be a string");this._size=void 0;const s=ze(this._tree,e);let n=s.get(D);return n===void 0&&s.set(D,n=t()),n}values(){return new De(this,St)}[Symbol.iterator](){return this.entries()}static from(e){const t=new X;for(const[s,n]of e)t.set(s,n);return t}static fromObject(e){return X.from(Object.entries(e))}}const Re=(a,e,t=[])=>{if(e.length===0||a==null)return[a,t];for(const s of a.keys())if(s!==D&&e.startsWith(s))return t.push([a,s]),Re(a.get(s),e.slice(s.length),t);return t.push([a,e]),Re(void 0,"",t)},Ke=(a,e)=>{if(e.length===0||a==null)return a;for(const t of a.keys())if(t!==D&&e.startsWith(t))return Ke(a.get(t),e.slice(t.length))},ze=(a,e)=>{const t=e.length;e:for(let s=0;a&&s{const[t,s]=Re(a,e);if(t!==void 0){if(t.delete(D),t.size===0)Tt(s);else if(t.size===1){const[n,r]=t.entries().next().value;It(s,n,r)}}},Tt=a=>{if(a.length===0)return;const[e,t]=qe(a);if(e.delete(t),e.size===0)Tt(a.slice(0,-1));else if(e.size===1){const[s,n]=e.entries().next().value;s!==D&&It(a.slice(0,-1),s,n)}},It=(a,e,t)=>{if(a.length===0)return;const[s,n]=qe(a);s.set(n+e,t),s.delete(n)},qe=a=>a[a.length-1],Ge="or",kt="and",Bs="and_not";class ue{constructor(e){if((e==null?void 0:e.fields)==null)throw new Error('MiniSearch: option "fields" must be provided');const t=e.autoVacuum==null||e.autoVacuum===!0?Ve:e.autoVacuum;this._options=Object.assign(Object.assign(Object.assign({},je),e),{autoVacuum:t,searchOptions:Object.assign(Object.assign({},ht),e.searchOptions||{}),autoSuggestOptions:Object.assign(Object.assign({},qs),e.autoSuggestOptions||{})}),this._index=new X,this._documentCount=0,this._documentIds=new Map,this._idToShortId=new Map,this._fieldIds={},this._fieldLength=new Map,this._avgFieldLength=[],this._nextId=0,this._storedFields=new Map,this._dirtCount=0,this._currentVacuum=null,this._enqueuedVacuum=null,this._enqueuedVacuumConditions=Ue,this.addFields(this._options.fields)}add(e){const{extractField:t,tokenize:s,processTerm:n,fields:r,idField:i}=this._options,o=t(e,i);if(o==null)throw new Error(`MiniSearch: document does not have ID field "${i}"`);if(this._idToShortId.has(o))throw new Error(`MiniSearch: duplicate ID ${o}`);const l=this.addDocumentId(o);this.saveStoredFields(l,e);for(const c of r){const h=t(e,c);if(h==null)continue;const m=s(h.toString(),c),f=this._fieldIds[c],b=new Set(m).size;this.addFieldLength(l,f,this._documentCount-1,b);for(const y of m){const x=n(y,c);if(Array.isArray(x))for(const w of x)this.addTerm(f,l,w);else x&&this.addTerm(f,l,x)}}}addAll(e){for(const t of e)this.add(t)}addAllAsync(e,t={}){const{chunkSize:s=10}=t,n={chunk:[],promise:Promise.resolve()},{chunk:r,promise:i}=e.reduce(({chunk:o,promise:l},c,h)=>(o.push(c),(h+1)%s===0?{chunk:[],promise:l.then(()=>new Promise(m=>setTimeout(m,0))).then(()=>this.addAll(o))}:{chunk:o,promise:l}),n);return i.then(()=>this.addAll(r))}remove(e){const{tokenize:t,processTerm:s,extractField:n,fields:r,idField:i}=this._options,o=n(e,i);if(o==null)throw new Error(`MiniSearch: document does not have ID field "${i}"`);const l=this._idToShortId.get(o);if(l==null)throw new Error(`MiniSearch: cannot remove document with ID ${o}: it is not in the index`);for(const c of r){const h=n(e,c);if(h==null)continue;const m=t(h.toString(),c),f=this._fieldIds[c],b=new Set(m).size;this.removeFieldLength(l,f,this._documentCount,b);for(const y of m){const x=s(y,c);if(Array.isArray(x))for(const w of x)this.removeTerm(f,l,w);else x&&this.removeTerm(f,l,x)}}this._storedFields.delete(l),this._documentIds.delete(l),this._idToShortId.delete(o),this._fieldLength.delete(l),this._documentCount-=1}removeAll(e){if(e)for(const t of e)this.remove(t);else{if(arguments.length>0)throw new Error("Expected documents to be present. Omit the argument to remove all documents.");this._index=new X,this._documentCount=0,this._documentIds=new Map,this._idToShortId=new Map,this._fieldLength=new Map,this._avgFieldLength=[],this._storedFields=new Map,this._nextId=0}}discard(e){const t=this._idToShortId.get(e);if(t==null)throw new Error(`MiniSearch: cannot discard document with ID ${e}: it is not in the index`);this._idToShortId.delete(e),this._documentIds.delete(t),this._storedFields.delete(t),(this._fieldLength.get(t)||[]).forEach((s,n)=>{this.removeFieldLength(t,n,this._documentCount,s)}),this._fieldLength.delete(t),this._documentCount-=1,this._dirtCount+=1,this.maybeAutoVacuum()}maybeAutoVacuum(){if(this._options.autoVacuum===!1)return;const{minDirtFactor:e,minDirtCount:t,batchSize:s,batchWait:n}=this._options.autoVacuum;this.conditionalVacuum({batchSize:s,batchWait:n},{minDirtCount:t,minDirtFactor:e})}discardAll(e){const t=this._options.autoVacuum;try{this._options.autoVacuum=!1;for(const s of e)this.discard(s)}finally{this._options.autoVacuum=t}this.maybeAutoVacuum()}replace(e){const{idField:t,extractField:s}=this._options,n=s(e,t);this.discard(n),this.add(e)}vacuum(e={}){return this.conditionalVacuum(e)}conditionalVacuum(e,t){return this._currentVacuum?(this._enqueuedVacuumConditions=this._enqueuedVacuumConditions&&t,this._enqueuedVacuum!=null?this._enqueuedVacuum:(this._enqueuedVacuum=this._currentVacuum.then(()=>{const s=this._enqueuedVacuumConditions;return this._enqueuedVacuumConditions=Ue,this.performVacuuming(e,s)}),this._enqueuedVacuum)):this.vacuumConditionsMet(t)===!1?Promise.resolve():(this._currentVacuum=this.performVacuuming(e),this._currentVacuum)}performVacuuming(e,t){return ke(this,void 0,void 0,function*(){const s=this._dirtCount;if(this.vacuumConditionsMet(t)){const n=e.batchSize||Je.batchSize,r=e.batchWait||Je.batchWait;let i=1;for(const[o,l]of this._index){for(const[c,h]of l)for(const[m]of h)this._documentIds.has(m)||(h.size<=1?l.delete(c):h.delete(m));this._index.get(o).size===0&&this._index.delete(o),i%n===0&&(yield new Promise(c=>setTimeout(c,r))),i+=1}this._dirtCount-=s}yield null,this._currentVacuum=this._enqueuedVacuum,this._enqueuedVacuum=null})}vacuumConditionsMet(e){if(e==null)return!0;let{minDirtCount:t,minDirtFactor:s}=e;return t=t||Ve.minDirtCount,s=s||Ve.minDirtFactor,this.dirtCount>=t&&this.dirtFactor>=s}get isVacuuming(){return this._currentVacuum!=null}get dirtCount(){return this._dirtCount}get dirtFactor(){return this._dirtCount/(1+this._documentCount+this._dirtCount)}has(e){return this._idToShortId.has(e)}getStoredFields(e){const t=this._idToShortId.get(e);if(t!=null)return this._storedFields.get(t)}search(e,t={}){const s=this.executeQuery(e,t),n=[];for(const[r,{score:i,terms:o,match:l}]of s){const c=o.length||1,h={id:this._documentIds.get(r),score:i*c,terms:Object.keys(l),queryTerms:o,match:l};Object.assign(h,this._storedFields.get(r)),(t.filter==null||t.filter(h))&&n.push(h)}return e===ue.wildcard&&t.boostDocument==null&&this._options.searchOptions.boostDocument==null||n.sort(pt),n}autoSuggest(e,t={}){t=Object.assign(Object.assign({},this._options.autoSuggestOptions),t);const s=new Map;for(const{score:r,terms:i}of this.search(e,t)){const o=i.join(" "),l=s.get(o);l!=null?(l.score+=r,l.count+=1):s.set(o,{score:r,terms:i,count:1})}const n=[];for(const[r,{score:i,terms:o,count:l}]of s)n.push({suggestion:r,terms:o,score:i/l});return n.sort(pt),n}get documentCount(){return this._documentCount}get termCount(){return this._index.size}static loadJSON(e,t){if(t==null)throw new Error("MiniSearch: loadJSON should be given the same options used when serializing the index");return this.loadJS(JSON.parse(e),t)}static loadJSONAsync(e,t){return ke(this,void 0,void 0,function*(){if(t==null)throw new Error("MiniSearch: loadJSON should be given the same options used when serializing the index");return this.loadJSAsync(JSON.parse(e),t)})}static getDefault(e){if(je.hasOwnProperty(e))return Pe(je,e);throw new Error(`MiniSearch: unknown option "${e}"`)}static loadJS(e,t){const{index:s,documentIds:n,fieldLength:r,storedFields:i,serializationVersion:o}=e,l=this.instantiateMiniSearch(e,t);l._documentIds=Te(n),l._fieldLength=Te(r),l._storedFields=Te(i);for(const[c,h]of l._documentIds)l._idToShortId.set(h,c);for(const[c,h]of s){const m=new Map;for(const f of Object.keys(h)){let b=h[f];o===1&&(b=b.ds),m.set(parseInt(f,10),Te(b))}l._index.set(c,m)}return l}static loadJSAsync(e,t){return ke(this,void 0,void 0,function*(){const{index:s,documentIds:n,fieldLength:r,storedFields:i,serializationVersion:o}=e,l=this.instantiateMiniSearch(e,t);l._documentIds=yield Ie(n),l._fieldLength=yield Ie(r),l._storedFields=yield Ie(i);for(const[h,m]of l._documentIds)l._idToShortId.set(m,h);let c=0;for(const[h,m]of s){const f=new Map;for(const b of Object.keys(m)){let y=m[b];o===1&&(y=y.ds),f.set(parseInt(b,10),yield Ie(y))}++c%1e3===0&&(yield Nt(0)),l._index.set(h,f)}return l})}static instantiateMiniSearch(e,t){const{documentCount:s,nextId:n,fieldIds:r,averageFieldLength:i,dirtCount:o,serializationVersion:l}=e;if(l!==1&&l!==2)throw new Error("MiniSearch: cannot deserialize an index created with an incompatible version");const c=new ue(t);return c._documentCount=s,c._nextId=n,c._idToShortId=new Map,c._fieldIds=r,c._avgFieldLength=i,c._dirtCount=o||0,c._index=new X,c}executeQuery(e,t={}){if(e===ue.wildcard)return this.executeWildcardQuery(t);if(typeof e!="string"){const f=Object.assign(Object.assign(Object.assign({},t),e),{queries:void 0}),b=e.queries.map(y=>this.executeQuery(y,f));return this.combineResults(b,f.combineWith)}const{tokenize:s,processTerm:n,searchOptions:r}=this._options,i=Object.assign(Object.assign({tokenize:s,processTerm:n},r),t),{tokenize:o,processTerm:l}=i,m=o(e).flatMap(f=>l(f)).filter(f=>!!f).map(Us(i)).map(f=>this.executeQuerySpec(f,i));return this.combineResults(m,i.combineWith)}executeQuerySpec(e,t){const s=Object.assign(Object.assign({},this._options.searchOptions),t),n=(s.fields||this._options.fields).reduce((x,w)=>Object.assign(Object.assign({},x),{[w]:Pe(s.boost,w)||1}),{}),{boostDocument:r,weights:i,maxFuzzy:o,bm25:l}=s,{fuzzy:c,prefix:h}=Object.assign(Object.assign({},ht.weights),i),m=this._index.get(e.term),f=this.termResults(e.term,e.term,1,e.termBoost,m,n,r,l);let b,y;if(e.prefix&&(b=this._index.atPrefix(e.term)),e.fuzzy){const x=e.fuzzy===!0?.2:e.fuzzy,w=x<1?Math.min(o,Math.round(e.term.length*x)):x;w&&(y=this._index.fuzzyGet(e.term,w))}if(b)for(const[x,w]of b){const R=x.length-e.term.length;if(!R)continue;y==null||y.delete(x);const A=h*x.length/(x.length+.3*R);this.termResults(e.term,x,A,e.termBoost,w,n,r,l,f)}if(y)for(const x of y.keys()){const[w,R]=y.get(x);if(!R)continue;const A=c*x.length/(x.length+R);this.termResults(e.term,x,A,e.termBoost,w,n,r,l,f)}return f}executeWildcardQuery(e){const t=new Map,s=Object.assign(Object.assign({},this._options.searchOptions),e);for(const[n,r]of this._documentIds){const i=s.boostDocument?s.boostDocument(r,"",this._storedFields.get(n)):1;t.set(n,{score:i,terms:[],match:{}})}return t}combineResults(e,t=Ge){if(e.length===0)return new Map;const s=t.toLowerCase(),n=Ws[s];if(!n)throw new Error(`Invalid combination operator: ${t}`);return e.reduce(n)||new Map}toJSON(){const e=[];for(const[t,s]of this._index){const n={};for(const[r,i]of s)n[r]=Object.fromEntries(i);e.push([t,n])}return{documentCount:this._documentCount,nextId:this._nextId,documentIds:Object.fromEntries(this._documentIds),fieldIds:this._fieldIds,fieldLength:Object.fromEntries(this._fieldLength),averageFieldLength:this._avgFieldLength,storedFields:Object.fromEntries(this._storedFields),dirtCount:this._dirtCount,index:e,serializationVersion:2}}termResults(e,t,s,n,r,i,o,l,c=new Map){if(r==null)return c;for(const h of Object.keys(i)){const m=i[h],f=this._fieldIds[h],b=r.get(f);if(b==null)continue;let y=b.size;const x=this._avgFieldLength[f];for(const w of b.keys()){if(!this._documentIds.has(w)){this.removeTerm(f,w,t),y-=1;continue}const R=o?o(this._documentIds.get(w),t,this._storedFields.get(w)):1;if(!R)continue;const A=b.get(w),J=this._fieldLength.get(w)[f],Q=Js(A,y,this._documentCount,J,x,l),W=s*n*m*R*Q,V=c.get(w);if(V){V.score+=W,Gs(V.terms,e);const $=Pe(V.match,t);$?$.push(h):V.match[t]=[h]}else c.set(w,{score:W,terms:[e],match:{[t]:[h]}})}}return c}addTerm(e,t,s){const n=this._index.fetch(s,vt);let r=n.get(e);if(r==null)r=new Map,r.set(t,1),n.set(e,r);else{const i=r.get(t);r.set(t,(i||0)+1)}}removeTerm(e,t,s){if(!this._index.has(s)){this.warnDocumentChanged(t,e,s);return}const n=this._index.fetch(s,vt),r=n.get(e);r==null||r.get(t)==null?this.warnDocumentChanged(t,e,s):r.get(t)<=1?r.size<=1?n.delete(e):r.delete(t):r.set(t,r.get(t)-1),this._index.get(s).size===0&&this._index.delete(s)}warnDocumentChanged(e,t,s){for(const n of Object.keys(this._fieldIds))if(this._fieldIds[n]===t){this._options.logger("warn",`MiniSearch: document with ID ${this._documentIds.get(e)} has changed before removal: term "${s}" was not present in field "${n}". Removing a document after it has changed can corrupt the index!`,"version_conflict");return}}addDocumentId(e){const t=this._nextId;return this._idToShortId.set(e,t),this._documentIds.set(t,e),this._documentCount+=1,this._nextId+=1,t}addFields(e){for(let t=0;tObject.prototype.hasOwnProperty.call(a,e)?a[e]:void 0,Ws={[Ge]:(a,e)=>{for(const t of e.keys()){const s=a.get(t);if(s==null)a.set(t,e.get(t));else{const{score:n,terms:r,match:i}=e.get(t);s.score=s.score+n,s.match=Object.assign(s.match,i),ft(s.terms,r)}}return a},[kt]:(a,e)=>{const t=new Map;for(const s of e.keys()){const n=a.get(s);if(n==null)continue;const{score:r,terms:i,match:o}=e.get(s);ft(n.terms,i),t.set(s,{score:n.score+r,terms:n.terms,match:Object.assign(n.match,o)})}return t},[Bs]:(a,e)=>{for(const t of e.keys())a.delete(t);return a}},Ks={k:1.2,b:.7,d:.5},Js=(a,e,t,s,n,r)=>{const{k:i,b:o,d:l}=r;return Math.log(1+(t-e+.5)/(e+.5))*(l+a*(i+1)/(a+i*(1-o+o*s/n)))},Us=a=>(e,t,s)=>{const n=typeof a.fuzzy=="function"?a.fuzzy(e,t,s):a.fuzzy||!1,r=typeof a.prefix=="function"?a.prefix(e,t,s):a.prefix===!0,i=typeof a.boostTerm=="function"?a.boostTerm(e,t,s):1;return{term:e,fuzzy:n,prefix:r,termBoost:i}},je={idField:"id",extractField:(a,e)=>a[e],tokenize:a=>a.split(Hs),processTerm:a=>a.toLowerCase(),fields:void 0,searchOptions:void 0,storeFields:[],logger:(a,e)=>{typeof(console==null?void 0:console[a])=="function"&&console[a](e)},autoVacuum:!0},ht={combineWith:Ge,prefix:!1,fuzzy:!1,maxFuzzy:6,boost:{},weights:{fuzzy:.45,prefix:.375},bm25:Ks},qs={combineWith:kt,prefix:(a,e,t)=>e===t.length-1},Je={batchSize:1e3,batchWait:10},Ue={minDirtFactor:.1,minDirtCount:20},Ve=Object.assign(Object.assign({},Je),Ue),Gs=(a,e)=>{a.includes(e)||a.push(e)},ft=(a,e)=>{for(const t of e)a.includes(t)||a.push(t)},pt=({score:a},{score:e})=>e-a,vt=()=>new Map,Te=a=>{const e=new Map;for(const t of Object.keys(a))e.set(parseInt(t,10),a[t]);return e},Ie=a=>ke(void 0,void 0,void 0,function*(){const e=new Map;let t=0;for(const s of Object.keys(a))e.set(parseInt(s,10),a[s]),++t%1e3===0&&(yield Nt(0));return e}),Nt=a=>new Promise(e=>setTimeout(e,a)),Hs=/[\n\r\p{Z}\p{P}]+/u;class Qs{constructor(e=10){Ae(this,"max");Ae(this,"cache");this.max=e,this.cache=new Map}get(e){let t=this.cache.get(e);return t!==void 0&&(this.cache.delete(e),this.cache.set(e,t)),t}set(e,t){this.cache.has(e)?this.cache.delete(e):this.cache.size===this.max&&this.cache.delete(this.first()),this.cache.set(e,t)}first(){return this.cache.keys().next().value}clear(){this.cache.clear()}}const Ys=["aria-owns"],Zs={class:"shell"},Xs=["title"],en={class:"search-actions before"},tn=["title"],sn=["aria-activedescendant","aria-controls","placeholder"],nn={class:"search-actions"},rn=["title"],an=["disabled","title"],on=["id","role","aria-labelledby"],ln=["id","aria-selected"],cn=["href","aria-label","onMouseenter","onFocusin","data-index"],un={class:"titles"},dn=["innerHTML"],hn={class:"title main"},fn=["innerHTML"],pn={key:0,class:"excerpt-wrapper"},vn={key:0,class:"excerpt",inert:""},mn=["innerHTML"],gn={key:0,class:"no-results"},bn={class:"search-keyboard-shortcuts"},yn=["aria-label"],wn=["aria-label"],xn=["aria-label"],_n=["aria-label"],Sn=Lt({__name:"VPLocalSearchBox",emits:["close"],setup(a,{emit:e}){var S,C;const t=e,s=xe(),n=xe(),r=xe(is),i=ss(),{activate:o}=Ds(s,{immediate:!0,allowOutsideClick:!0,clickOutsideDeactivates:!0,escapeDeactivates:!0}),{localeIndex:l,theme:c}=i,h=st(async()=>{var v,p,E,F,z,P,j,I,K;return at(ue.loadJSON((E=await((p=(v=r.value)[l.value])==null?void 0:p.call(v)))==null?void 0:E.default,{fields:["title","titles","text"],storeFields:["title","titles"],searchOptions:{fuzzy:.2,prefix:!0,boost:{title:4,text:2,titles:1},...((F=c.value.search)==null?void 0:F.provider)==="local"&&((P=(z=c.value.search.options)==null?void 0:z.miniSearch)==null?void 0:P.searchOptions)},...((j=c.value.search)==null?void 0:j.provider)==="local"&&((K=(I=c.value.search.options)==null?void 0:I.miniSearch)==null?void 0:K.options)}))}),f=me(()=>{var v,p;return((v=c.value.search)==null?void 0:v.provider)==="local"&&((p=c.value.search.options)==null?void 0:p.disableQueryPersistence)===!0}).value?ie(""):Dt("vitepress:local-search-filter",""),b=zt("vitepress:local-search-detailed-list",((S=c.value.search)==null?void 0:S.provider)==="local"&&((C=c.value.search.options)==null?void 0:C.detailedView)===!0),y=me(()=>{var v,p,E;return((v=c.value.search)==null?void 0:v.provider)==="local"&&(((p=c.value.search.options)==null?void 0:p.disableDetailedView)===!0||((E=c.value.search.options)==null?void 0:E.detailedView)===!1)}),x=me(()=>{var p,E,F,z,P,j,I;const v=((p=c.value.search)==null?void 0:p.options)??c.value.algolia;return((P=(z=(F=(E=v==null?void 0:v.locales)==null?void 0:E[l.value])==null?void 0:F.translations)==null?void 0:z.button)==null?void 0:P.buttonText)||((I=(j=v==null?void 0:v.translations)==null?void 0:j.button)==null?void 0:I.buttonText)||"Search"});Pt(()=>{y.value&&(b.value=!1)});const w=xe([]),R=ie(!1);$e(f,()=>{R.value=!1});const A=st(async()=>{if(n.value)return at(new Ps(n.value))},null),J=new Qs(16);jt(()=>[h.value,f.value,b.value],async([v,p,E],F,z)=>{var ee,ye,He,Qe;(F==null?void 0:F[0])!==v&&J.clear();let P=!1;if(z(()=>{P=!0}),!v)return;w.value=v.search(p).slice(0,16),R.value=!0;const j=E?await Promise.all(w.value.map(B=>Q(B.id))):[];if(P)return;for(const{id:B,mod:te}of j){const se=B.slice(0,B.indexOf("#"));let Y=J.get(se);if(Y)continue;Y=new Map,J.set(se,Y);const G=te.default??te;if(G!=null&&G.render||G!=null&&G.setup){const ne=Yt(G);ne.config.warnHandler=()=>{},ne.provide(Zt,i),Object.defineProperties(ne.config.globalProperties,{$frontmatter:{get(){return i.frontmatter.value}},$params:{get(){return i.page.value.params}}});const Ye=document.createElement("div");ne.mount(Ye),Ye.querySelectorAll("h1, h2, h3, h4, h5, h6").forEach(de=>{var et;const we=(et=de.querySelector("a"))==null?void 0:et.getAttribute("href"),Ze=(we==null?void 0:we.startsWith("#"))&&we.slice(1);if(!Ze)return;let Xe="";for(;(de=de.nextElementSibling)&&!/^h[1-6]$/i.test(de.tagName);)Xe+=de.outerHTML;Y.set(Ze,Xe)}),ne.unmount()}if(P)return}const I=new Set;if(w.value=w.value.map(B=>{const[te,se]=B.id.split("#"),Y=J.get(te),G=(Y==null?void 0:Y.get(se))??"";for(const ne in B.match)I.add(ne);return{...B,text:G}}),await he(),P)return;await new Promise(B=>{var te;(te=A.value)==null||te.unmark({done:()=>{var se;(se=A.value)==null||se.markRegExp(k(I),{done:B})}})});const K=((ee=s.value)==null?void 0:ee.querySelectorAll(".result .excerpt"))??[];for(const B of K)(ye=B.querySelector('mark[data-markjs="true"]'))==null||ye.scrollIntoView({block:"center"});(Qe=(He=n.value)==null?void 0:He.firstElementChild)==null||Qe.scrollIntoView({block:"start"})},{debounce:200,immediate:!0});async function Q(v){const p=Xt(v.slice(0,v.indexOf("#")));try{if(!p)throw new Error(`Cannot find file for id: ${v}`);return{id:v,mod:await import(p)}}catch(E){return console.error(E),{id:v,mod:{}}}}const W=ie(),V=me(()=>{var v;return((v=f.value)==null?void 0:v.length)<=0});function $(v=!0){var p,E;(p=W.value)==null||p.focus(),v&&((E=W.value)==null||E.select())}Me(()=>{$()});function be(v){v.pointerType==="mouse"&&$()}const M=ie(-1),U=ie(!0);$e(w,v=>{M.value=v.length?0:-1,q()});function q(){he(()=>{const v=document.querySelector(".result.selected");v==null||v.scrollIntoView({block:"nearest"})})}_e("ArrowUp",v=>{v.preventDefault(),M.value--,M.value<0&&(M.value=w.value.length-1),U.value=!0,q()}),_e("ArrowDown",v=>{v.preventDefault(),M.value++,M.value>=w.value.length&&(M.value=0),U.value=!0,q()});const N=Vt();_e("Enter",v=>{if(v.isComposing||v.target instanceof HTMLButtonElement&&v.target.type!=="submit")return;const p=w.value[M.value];if(v.target instanceof HTMLInputElement&&!p){v.preventDefault();return}p&&(N.go(p.id),t("close"))}),_e("Escape",()=>{t("close")});const d=ns({modal:{displayDetails:"Display detailed list",resetButtonTitle:"Reset search",backButtonTitle:"Close search",noResultsText:"No results for",footer:{selectText:"to select",selectKeyAriaLabel:"enter",navigateText:"to navigate",navigateUpKeyAriaLabel:"up arrow",navigateDownKeyAriaLabel:"down arrow",closeText:"to close",closeKeyAriaLabel:"escape"}}});Me(()=>{window.history.pushState(null,"",null)}),$t("popstate",v=>{v.preventDefault(),t("close")});const g=Bt(Wt?document.body:null);Me(()=>{he(()=>{g.value=!0,he().then(()=>o())})}),Kt(()=>{g.value=!1});function T(){f.value="",he().then(()=>$(!1))}function k(v){return new RegExp([...v].sort((p,E)=>E.length-p.length).map(p=>`(${es(p)})`).join("|"),"gi")}function O(v){var F;if(!U.value)return;const p=(F=v.target)==null?void 0:F.closest(".result"),E=Number.parseInt(p==null?void 0:p.dataset.index);E>=0&&E!==M.value&&(M.value=E),U.value=!1}return(v,p)=>{var E,F,z,P,j;return H(),Jt(Qt,{to:"body"},[_("div",{ref_key:"el",ref:s,role:"button","aria-owns":(E=w.value)!=null&&E.length?"localsearch-list":void 0,"aria-expanded":"true","aria-haspopup":"listbox","aria-labelledby":"localsearch-label",class:"VPLocalSearchBox"},[_("div",{class:"backdrop",onClick:p[0]||(p[0]=I=>v.$emit("close"))}),_("div",Zs,[_("form",{class:"search-bar",onPointerup:p[4]||(p[4]=I=>be(I)),onSubmit:p[5]||(p[5]=Ut(()=>{},["prevent"]))},[_("label",{title:x.value,id:"localsearch-label",for:"localsearch-input"},p[7]||(p[7]=[_("span",{"aria-hidden":"true",class:"vpi-search search-icon local-search-icon"},null,-1)]),8,Xs),_("div",en,[_("button",{class:"back-button",title:L(d)("modal.backButtonTitle"),onClick:p[1]||(p[1]=I=>v.$emit("close"))},p[8]||(p[8]=[_("span",{class:"vpi-arrow-left local-search-icon"},null,-1)]),8,tn)]),qt(_("input",{ref_key:"searchInput",ref:W,"onUpdate:modelValue":p[2]||(p[2]=I=>Ht(f)?f.value=I:null),"aria-activedescendant":M.value>-1?"localsearch-item-"+M.value:void 0,"aria-autocomplete":"both","aria-controls":(F=w.value)!=null&&F.length?"localsearch-list":void 0,"aria-labelledby":"localsearch-label",autocapitalize:"off",autocomplete:"off",autocorrect:"off",class:"search-input",id:"localsearch-input",enterkeyhint:"go",maxlength:"64",placeholder:x.value,spellcheck:"false",type:"search"},null,8,sn),[[Gt,L(f)]]),_("div",nn,[y.value?Se("",!0):(H(),Z("button",{key:0,class:nt(["toggle-layout-button",{"detailed-list":L(b)}]),type:"button",title:L(d)("modal.displayDetails"),onClick:p[3]||(p[3]=I=>M.value>-1&&(b.value=!L(b)))},p[9]||(p[9]=[_("span",{class:"vpi-layout-list local-search-icon"},null,-1)]),10,rn)),_("button",{class:"clear-button",type:"reset",disabled:V.value,title:L(d)("modal.resetButtonTitle"),onClick:T},p[10]||(p[10]=[_("span",{class:"vpi-delete local-search-icon"},null,-1)]),8,an)])],32),_("ul",{ref_key:"resultsEl",ref:n,id:(z=w.value)!=null&&z.length?"localsearch-list":void 0,role:(P=w.value)!=null&&P.length?"listbox":void 0,"aria-labelledby":(j=w.value)!=null&&j.length?"localsearch-label":void 0,class:"results",onMousemove:O},[(H(!0),Z(rt,null,it(w.value,(I,K)=>(H(),Z("li",{key:I.id,id:"localsearch-item-"+K,"aria-selected":M.value===K?"true":"false",role:"option"},[_("a",{href:I.id,class:nt(["result",{selected:M.value===K}]),"aria-label":[...I.titles,I.title].join(" > "),onMouseenter:ee=>!U.value&&(M.value=K),onFocusin:ee=>M.value=K,onClick:p[6]||(p[6]=ee=>v.$emit("close")),"data-index":K},[_("div",null,[_("div",un,[p[12]||(p[12]=_("span",{class:"title-icon"},"#",-1)),(H(!0),Z(rt,null,it(I.titles,(ee,ye)=>(H(),Z("span",{key:ye,class:"title"},[_("span",{class:"text",innerHTML:ee},null,8,dn),p[11]||(p[11]=_("span",{class:"vpi-chevron-right local-search-icon"},null,-1))]))),128)),_("span",hn,[_("span",{class:"text",innerHTML:I.title},null,8,fn)])]),L(b)?(H(),Z("div",pn,[I.text?(H(),Z("div",vn,[_("div",{class:"vp-doc",innerHTML:I.text},null,8,mn)])):Se("",!0),p[13]||(p[13]=_("div",{class:"excerpt-gradient-bottom"},null,-1)),p[14]||(p[14]=_("div",{class:"excerpt-gradient-top"},null,-1))])):Se("",!0)])],42,cn)],8,ln))),128)),L(f)&&!w.value.length&&R.value?(H(),Z("li",gn,[fe(pe(L(d)("modal.noResultsText"))+' "',1),_("strong",null,pe(L(f)),1),p[15]||(p[15]=fe('" '))])):Se("",!0)],40,on),_("div",bn,[_("span",null,[_("kbd",{"aria-label":L(d)("modal.footer.navigateUpKeyAriaLabel")},p[16]||(p[16]=[_("span",{class:"vpi-arrow-up navigate-icon"},null,-1)]),8,yn),_("kbd",{"aria-label":L(d)("modal.footer.navigateDownKeyAriaLabel")},p[17]||(p[17]=[_("span",{class:"vpi-arrow-down navigate-icon"},null,-1)]),8,wn),fe(" "+pe(L(d)("modal.footer.navigateText")),1)]),_("span",null,[_("kbd",{"aria-label":L(d)("modal.footer.selectKeyAriaLabel")},p[18]||(p[18]=[_("span",{class:"vpi-corner-down-left navigate-icon"},null,-1)]),8,xn),fe(" "+pe(L(d)("modal.footer.selectText")),1)]),_("span",null,[_("kbd",{"aria-label":L(d)("modal.footer.closeKeyAriaLabel")},"esc",8,_n),fe(" "+pe(L(d)("modal.footer.closeText")),1)])])])],8,Ys)])}}}),Fn=ts(Sn,[["__scopeId","data-v-4278b464"]]);export{Fn as default}; diff --git a/.vitepress/dist/assets/chunks/framework.DtMx7FFi.js b/.vitepress/dist/assets/chunks/framework.DtMx7FFi.js new file mode 100644 index 0000000..c480127 --- /dev/null +++ b/.vitepress/dist/assets/chunks/framework.DtMx7FFi.js @@ -0,0 +1,18 @@ +/** +* @vue/shared v3.5.13 +* (c) 2018-present Yuxi (Evan) You and Vue contributors +* @license MIT +**//*! #__NO_SIDE_EFFECTS__ */function Ns(e){const t=Object.create(null);for(const n of e.split(","))t[n]=1;return n=>n in t}const Z={},Et=[],ke=()=>{},Ko=()=>!1,en=e=>e.charCodeAt(0)===111&&e.charCodeAt(1)===110&&(e.charCodeAt(2)>122||e.charCodeAt(2)<97),Fs=e=>e.startsWith("onUpdate:"),ae=Object.assign,Hs=(e,t)=>{const n=e.indexOf(t);n>-1&&e.splice(n,1)},qo=Object.prototype.hasOwnProperty,z=(e,t)=>qo.call(e,t),W=Array.isArray,Tt=e=>In(e)==="[object Map]",ii=e=>In(e)==="[object Set]",q=e=>typeof e=="function",re=e=>typeof e=="string",Xe=e=>typeof e=="symbol",ne=e=>e!==null&&typeof e=="object",oi=e=>(ne(e)||q(e))&&q(e.then)&&q(e.catch),li=Object.prototype.toString,In=e=>li.call(e),Go=e=>In(e).slice(8,-1),ci=e=>In(e)==="[object Object]",$s=e=>re(e)&&e!=="NaN"&&e[0]!=="-"&&""+parseInt(e,10)===e,Ct=Ns(",key,ref,ref_for,ref_key,onVnodeBeforeMount,onVnodeMounted,onVnodeBeforeUpdate,onVnodeUpdated,onVnodeBeforeUnmount,onVnodeUnmounted"),Nn=e=>{const t=Object.create(null);return n=>t[n]||(t[n]=e(n))},Yo=/-(\w)/g,Le=Nn(e=>e.replace(Yo,(t,n)=>n?n.toUpperCase():"")),Xo=/\B([A-Z])/g,st=Nn(e=>e.replace(Xo,"-$1").toLowerCase()),Fn=Nn(e=>e.charAt(0).toUpperCase()+e.slice(1)),_n=Nn(e=>e?`on${Fn(e)}`:""),tt=(e,t)=>!Object.is(e,t),bn=(e,...t)=>{for(let n=0;n{Object.defineProperty(e,t,{configurable:!0,enumerable:!1,writable:s,value:n})},vs=e=>{const t=parseFloat(e);return isNaN(t)?e:t},Jo=e=>{const t=re(e)?Number(e):NaN;return isNaN(t)?e:t};let ar;const Hn=()=>ar||(ar=typeof globalThis<"u"?globalThis:typeof self<"u"?self:typeof window<"u"?window:typeof global<"u"?global:{});function Ds(e){if(W(e)){const t={};for(let n=0;n{if(n){const s=n.split(Qo);s.length>1&&(t[s[0].trim()]=s[1].trim())}}),t}function js(e){let t="";if(re(e))t=e;else if(W(e))for(let n=0;n!!(e&&e.__v_isRef===!0),sl=e=>re(e)?e:e==null?"":W(e)||ne(e)&&(e.toString===li||!q(e.toString))?ui(e)?sl(e.value):JSON.stringify(e,di,2):String(e),di=(e,t)=>ui(t)?di(e,t.value):Tt(t)?{[`Map(${t.size})`]:[...t.entries()].reduce((n,[s,r],i)=>(n[zn(s,i)+" =>"]=r,n),{})}:ii(t)?{[`Set(${t.size})`]:[...t.values()].map(n=>zn(n))}:Xe(t)?zn(t):ne(t)&&!W(t)&&!ci(t)?String(t):t,zn=(e,t="")=>{var n;return Xe(e)?`Symbol(${(n=e.description)!=null?n:t})`:e};/** +* @vue/reactivity v3.5.13 +* (c) 2018-present Yuxi (Evan) You and Vue contributors +* @license MIT +**/let we;class rl{constructor(t=!1){this.detached=t,this._active=!0,this.effects=[],this.cleanups=[],this._isPaused=!1,this.parent=we,!t&&we&&(this.index=(we.scopes||(we.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;if(jt){let t=jt;for(jt=void 0;t;){const n=t.next;t.next=void 0,t.flags&=-9,t=n}}let e;for(;Dt;){let t=Dt;for(Dt=void 0;t;){const n=t.next;if(t.next=void 0,t.flags&=-9,t.flags&1)try{t.trigger()}catch(s){e||(e=s)}t=n}}if(e)throw e}function yi(e){for(let t=e.deps;t;t=t.nextDep)t.version=-1,t.prevActiveLink=t.dep.activeLink,t.dep.activeLink=t}function vi(e){let t,n=e.depsTail,s=n;for(;s;){const r=s.prevDep;s.version===-1?(s===n&&(n=r),ks(s),ol(s)):t=s,s.dep.activeLink=s.prevActiveLink,s.prevActiveLink=void 0,s=r}e.deps=t,e.depsTail=n}function _s(e){for(let t=e.deps;t;t=t.nextDep)if(t.dep.version!==t.version||t.dep.computed&&(_i(t.dep.computed)||t.dep.version!==t.version))return!0;return!!e._dirty}function _i(e){if(e.flags&4&&!(e.flags&16)||(e.flags&=-17,e.globalVersion===Kt))return;e.globalVersion=Kt;const t=e.dep;if(e.flags|=2,t.version>0&&!e.isSSR&&e.deps&&!_s(e)){e.flags&=-3;return}const n=te,s=Ne;te=e,Ne=!0;try{yi(e);const r=e.fn(e._value);(t.version===0||tt(r,e._value))&&(e._value=r,t.version++)}catch(r){throw t.version++,r}finally{te=n,Ne=s,vi(e),e.flags&=-3}}function ks(e,t=!1){const{dep:n,prevSub:s,nextSub:r}=e;if(s&&(s.nextSub=r,e.prevSub=void 0),r&&(r.prevSub=s,e.nextSub=void 0),n.subs===e&&(n.subs=s,!s&&n.computed)){n.computed.flags&=-5;for(let i=n.computed.deps;i;i=i.nextDep)ks(i,!0)}!t&&!--n.sc&&n.map&&n.map.delete(n.key)}function ol(e){const{prevDep:t,nextDep:n}=e;t&&(t.nextDep=n,e.prevDep=void 0),n&&(n.prevDep=t,e.nextDep=void 0)}let Ne=!0;const bi=[];function rt(){bi.push(Ne),Ne=!1}function it(){const e=bi.pop();Ne=e===void 0?!0:e}function fr(e){const{cleanup:t}=e;if(e.cleanup=void 0,t){const n=te;te=void 0;try{t()}finally{te=n}}}let Kt=0;class ll{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 $n{constructor(t){this.computed=t,this.version=0,this.activeLink=void 0,this.subs=void 0,this.map=void 0,this.key=void 0,this.sc=0}track(t){if(!te||!Ne||te===this.computed)return;let n=this.activeLink;if(n===void 0||n.sub!==te)n=this.activeLink=new ll(te,this),te.deps?(n.prevDep=te.depsTail,te.depsTail.nextDep=n,te.depsTail=n):te.deps=te.depsTail=n,wi(n);else if(n.version===-1&&(n.version=this.version,n.nextDep)){const s=n.nextDep;s.prevDep=n.prevDep,n.prevDep&&(n.prevDep.nextDep=s),n.prevDep=te.depsTail,n.nextDep=void 0,te.depsTail.nextDep=n,te.depsTail=n,te.deps===n&&(te.deps=s)}return n}trigger(t){this.version++,Kt++,this.notify(t)}notify(t){Vs();try{for(let n=this.subs;n;n=n.prevSub)n.sub.notify()&&n.sub.dep.notify()}finally{Us()}}}function wi(e){if(e.dep.sc++,e.sub.flags&4){const t=e.dep.computed;if(t&&!e.dep.subs){t.flags|=20;for(let s=t.deps;s;s=s.nextDep)wi(s)}const n=e.dep.subs;n!==e&&(e.prevSub=n,n&&(n.nextSub=e)),e.dep.subs=e}}const Cn=new WeakMap,dt=Symbol(""),bs=Symbol(""),qt=Symbol("");function me(e,t,n){if(Ne&&te){let s=Cn.get(e);s||Cn.set(e,s=new Map);let r=s.get(n);r||(s.set(n,r=new $n),r.map=s,r.key=n),r.track()}}function Ge(e,t,n,s,r,i){const o=Cn.get(e);if(!o){Kt++;return}const l=c=>{c&&c.trigger()};if(Vs(),t==="clear")o.forEach(l);else{const c=W(e),f=c&&$s(n);if(c&&n==="length"){const a=Number(s);o.forEach((h,y)=>{(y==="length"||y===qt||!Xe(y)&&y>=a)&&l(h)})}else switch((n!==void 0||o.has(void 0))&&l(o.get(n)),f&&l(o.get(qt)),t){case"add":c?f&&l(o.get("length")):(l(o.get(dt)),Tt(e)&&l(o.get(bs)));break;case"delete":c||(l(o.get(dt)),Tt(e)&&l(o.get(bs)));break;case"set":Tt(e)&&l(o.get(dt));break}}Us()}function cl(e,t){const n=Cn.get(e);return n&&n.get(t)}function _t(e){const t=J(e);return t===e?t:(me(t,"iterate",qt),Pe(e)?t:t.map(ye))}function Dn(e){return me(e=J(e),"iterate",qt),e}const al={__proto__:null,[Symbol.iterator](){return Zn(this,Symbol.iterator,ye)},concat(...e){return _t(this).concat(...e.map(t=>W(t)?_t(t):t))},entries(){return Zn(this,"entries",e=>(e[1]=ye(e[1]),e))},every(e,t){return We(this,"every",e,t,void 0,arguments)},filter(e,t){return We(this,"filter",e,t,n=>n.map(ye),arguments)},find(e,t){return We(this,"find",e,t,ye,arguments)},findIndex(e,t){return We(this,"findIndex",e,t,void 0,arguments)},findLast(e,t){return We(this,"findLast",e,t,ye,arguments)},findLastIndex(e,t){return We(this,"findLastIndex",e,t,void 0,arguments)},forEach(e,t){return We(this,"forEach",e,t,void 0,arguments)},includes(...e){return es(this,"includes",e)},indexOf(...e){return es(this,"indexOf",e)},join(e){return _t(this).join(e)},lastIndexOf(...e){return es(this,"lastIndexOf",e)},map(e,t){return We(this,"map",e,t,void 0,arguments)},pop(){return Ft(this,"pop")},push(...e){return Ft(this,"push",e)},reduce(e,...t){return ur(this,"reduce",e,t)},reduceRight(e,...t){return ur(this,"reduceRight",e,t)},shift(){return Ft(this,"shift")},some(e,t){return We(this,"some",e,t,void 0,arguments)},splice(...e){return Ft(this,"splice",e)},toReversed(){return _t(this).toReversed()},toSorted(e){return _t(this).toSorted(e)},toSpliced(...e){return _t(this).toSpliced(...e)},unshift(...e){return Ft(this,"unshift",e)},values(){return Zn(this,"values",ye)}};function Zn(e,t,n){const s=Dn(e),r=s[t]();return s!==e&&!Pe(e)&&(r._next=r.next,r.next=()=>{const i=r._next();return i.value&&(i.value=n(i.value)),i}),r}const fl=Array.prototype;function We(e,t,n,s,r,i){const o=Dn(e),l=o!==e&&!Pe(e),c=o[t];if(c!==fl[t]){const h=c.apply(e,i);return l?ye(h):h}let f=n;o!==e&&(l?f=function(h,y){return n.call(this,ye(h),y,e)}:n.length>2&&(f=function(h,y){return n.call(this,h,y,e)}));const a=c.call(o,f,s);return l&&r?r(a):a}function ur(e,t,n,s){const r=Dn(e);let i=n;return r!==e&&(Pe(e)?n.length>3&&(i=function(o,l,c){return n.call(this,o,l,c,e)}):i=function(o,l,c){return n.call(this,o,ye(l),c,e)}),r[t](i,...s)}function es(e,t,n){const s=J(e);me(s,"iterate",qt);const r=s[t](...n);return(r===-1||r===!1)&&Ks(n[0])?(n[0]=J(n[0]),s[t](...n)):r}function Ft(e,t,n=[]){rt(),Vs();const s=J(e)[t].apply(e,n);return Us(),it(),s}const ul=Ns("__proto__,__v_isRef,__isVue"),Si=new Set(Object.getOwnPropertyNames(Symbol).filter(e=>e!=="arguments"&&e!=="caller").map(e=>Symbol[e]).filter(Xe));function dl(e){Xe(e)||(e=String(e));const t=J(this);return me(t,"has",e),t.hasOwnProperty(e)}class xi{constructor(t=!1,n=!1){this._isReadonly=t,this._isShallow=n}get(t,n,s){if(n==="__v_skip")return t.__v_skip;const r=this._isReadonly,i=this._isShallow;if(n==="__v_isReactive")return!r;if(n==="__v_isReadonly")return r;if(n==="__v_isShallow")return i;if(n==="__v_raw")return s===(r?i?Sl:Ai:i?Ci:Ti).get(t)||Object.getPrototypeOf(t)===Object.getPrototypeOf(s)?t:void 0;const o=W(t);if(!r){let c;if(o&&(c=al[n]))return c;if(n==="hasOwnProperty")return dl}const l=Reflect.get(t,n,fe(t)?t:s);return(Xe(n)?Si.has(n):ul(n))||(r||me(t,"get",n),i)?l:fe(l)?o&&$s(n)?l:l.value:ne(l)?r?Vn(l):jn(l):l}}class Ei extends xi{constructor(t=!1){super(!1,t)}set(t,n,s,r){let i=t[n];if(!this._isShallow){const c=yt(i);if(!Pe(s)&&!yt(s)&&(i=J(i),s=J(s)),!W(t)&&fe(i)&&!fe(s))return c?!1:(i.value=s,!0)}const o=W(t)&&$s(n)?Number(n)e,cn=e=>Reflect.getPrototypeOf(e);function yl(e,t,n){return function(...s){const r=this.__v_raw,i=J(r),o=Tt(i),l=e==="entries"||e===Symbol.iterator&&o,c=e==="keys"&&o,f=r[e](...s),a=n?ws:t?Ss:ye;return!t&&me(i,"iterate",c?bs:dt),{next(){const{value:h,done:y}=f.next();return y?{value:h,done:y}:{value:l?[a(h[0]),a(h[1])]:a(h),done:y}},[Symbol.iterator](){return this}}}}function an(e){return function(...t){return e==="delete"?!1:e==="clear"?void 0:this}}function vl(e,t){const n={get(r){const i=this.__v_raw,o=J(i),l=J(r);e||(tt(r,l)&&me(o,"get",r),me(o,"get",l));const{has:c}=cn(o),f=t?ws:e?Ss:ye;if(c.call(o,r))return f(i.get(r));if(c.call(o,l))return f(i.get(l));i!==o&&i.get(r)},get size(){const r=this.__v_raw;return!e&&me(J(r),"iterate",dt),Reflect.get(r,"size",r)},has(r){const i=this.__v_raw,o=J(i),l=J(r);return e||(tt(r,l)&&me(o,"has",r),me(o,"has",l)),r===l?i.has(r):i.has(r)||i.has(l)},forEach(r,i){const o=this,l=o.__v_raw,c=J(l),f=t?ws:e?Ss:ye;return!e&&me(c,"iterate",dt),l.forEach((a,h)=>r.call(i,f(a),f(h),o))}};return ae(n,e?{add:an("add"),set:an("set"),delete:an("delete"),clear:an("clear")}:{add(r){!t&&!Pe(r)&&!yt(r)&&(r=J(r));const i=J(this);return cn(i).has.call(i,r)||(i.add(r),Ge(i,"add",r,r)),this},set(r,i){!t&&!Pe(i)&&!yt(i)&&(i=J(i));const o=J(this),{has:l,get:c}=cn(o);let f=l.call(o,r);f||(r=J(r),f=l.call(o,r));const a=c.call(o,r);return o.set(r,i),f?tt(i,a)&&Ge(o,"set",r,i):Ge(o,"add",r,i),this},delete(r){const i=J(this),{has:o,get:l}=cn(i);let c=o.call(i,r);c||(r=J(r),c=o.call(i,r)),l&&l.call(i,r);const f=i.delete(r);return c&&Ge(i,"delete",r,void 0),f},clear(){const r=J(this),i=r.size!==0,o=r.clear();return i&&Ge(r,"clear",void 0,void 0),o}}),["keys","values","entries",Symbol.iterator].forEach(r=>{n[r]=yl(r,e,t)}),n}function Bs(e,t){const n=vl(e,t);return(s,r,i)=>r==="__v_isReactive"?!e:r==="__v_isReadonly"?e:r==="__v_raw"?s:Reflect.get(z(n,r)&&r in s?n:s,r,i)}const _l={get:Bs(!1,!1)},bl={get:Bs(!1,!0)},wl={get:Bs(!0,!1)};const Ti=new WeakMap,Ci=new WeakMap,Ai=new WeakMap,Sl=new WeakMap;function xl(e){switch(e){case"Object":case"Array":return 1;case"Map":case"Set":case"WeakMap":case"WeakSet":return 2;default:return 0}}function El(e){return e.__v_skip||!Object.isExtensible(e)?0:xl(Go(e))}function jn(e){return yt(e)?e:Ws(e,!1,pl,_l,Ti)}function Tl(e){return Ws(e,!1,ml,bl,Ci)}function Vn(e){return Ws(e,!0,gl,wl,Ai)}function Ws(e,t,n,s,r){if(!ne(e)||e.__v_raw&&!(t&&e.__v_isReactive))return e;const i=r.get(e);if(i)return i;const o=El(e);if(o===0)return e;const l=new Proxy(e,o===2?s:n);return r.set(e,l),l}function ht(e){return yt(e)?ht(e.__v_raw):!!(e&&e.__v_isReactive)}function yt(e){return!!(e&&e.__v_isReadonly)}function Pe(e){return!!(e&&e.__v_isShallow)}function Ks(e){return e?!!e.__v_raw:!1}function J(e){const t=e&&e.__v_raw;return t?J(t):e}function wn(e){return!z(e,"__v_skip")&&Object.isExtensible(e)&&ai(e,"__v_skip",!0),e}const ye=e=>ne(e)?jn(e):e,Ss=e=>ne(e)?Vn(e):e;function fe(e){return e?e.__v_isRef===!0:!1}function oe(e){return Ri(e,!1)}function qs(e){return Ri(e,!0)}function Ri(e,t){return fe(e)?e:new Cl(e,t)}class Cl{constructor(t,n){this.dep=new $n,this.__v_isRef=!0,this.__v_isShallow=!1,this._rawValue=n?t:J(t),this._value=n?t:ye(t),this.__v_isShallow=n}get value(){return this.dep.track(),this._value}set value(t){const n=this._rawValue,s=this.__v_isShallow||Pe(t)||yt(t);t=s?t:J(t),tt(t,n)&&(this._rawValue=t,this._value=s?t:ye(t),this.dep.trigger())}}function Oi(e){return fe(e)?e.value:e}const Al={get:(e,t,n)=>t==="__v_raw"?e:Oi(Reflect.get(e,t,n)),set:(e,t,n,s)=>{const r=e[t];return fe(r)&&!fe(n)?(r.value=n,!0):Reflect.set(e,t,n,s)}};function Mi(e){return ht(e)?e:new Proxy(e,Al)}class Rl{constructor(t){this.__v_isRef=!0,this._value=void 0;const n=this.dep=new $n,{get:s,set:r}=t(n.track.bind(n),n.trigger.bind(n));this._get=s,this._set=r}get value(){return this._value=this._get()}set value(t){this._set(t)}}function Ol(e){return new Rl(e)}class Ml{constructor(t,n,s){this._object=t,this._key=n,this._defaultValue=s,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 cl(J(this._object),this._key)}}class Pl{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 Ll(e,t,n){return fe(e)?e:q(e)?new Pl(e):ne(e)&&arguments.length>1?Il(e,t,n):oe(e)}function Il(e,t,n){const s=e[t];return fe(s)?s:new Ml(e,t,n)}class Nl{constructor(t,n,s){this.fn=t,this.setter=n,this._value=void 0,this.dep=new $n(this),this.__v_isRef=!0,this.deps=void 0,this.depsTail=void 0,this.flags=16,this.globalVersion=Kt-1,this.next=void 0,this.effect=this,this.__v_isReadonly=!n,this.isSSR=s}notify(){if(this.flags|=16,!(this.flags&8)&&te!==this)return mi(this,!0),!0}get value(){const t=this.dep.track();return _i(this),t&&(t.version=this.dep.version),this._value}set value(t){this.setter&&this.setter(t)}}function Fl(e,t,n=!1){let s,r;return q(e)?s=e:(s=e.get,r=e.set),new Nl(s,r,n)}const fn={},An=new WeakMap;let ft;function Hl(e,t=!1,n=ft){if(n){let s=An.get(n);s||An.set(n,s=[]),s.push(e)}}function $l(e,t,n=Z){const{immediate:s,deep:r,once:i,scheduler:o,augmentJob:l,call:c}=n,f=g=>r?g:Pe(g)||r===!1||r===0?Ye(g,1):Ye(g);let a,h,y,v,S=!1,_=!1;if(fe(e)?(h=()=>e.value,S=Pe(e)):ht(e)?(h=()=>f(e),S=!0):W(e)?(_=!0,S=e.some(g=>ht(g)||Pe(g)),h=()=>e.map(g=>{if(fe(g))return g.value;if(ht(g))return f(g);if(q(g))return c?c(g,2):g()})):q(e)?t?h=c?()=>c(e,2):e:h=()=>{if(y){rt();try{y()}finally{it()}}const g=ft;ft=a;try{return c?c(e,3,[v]):e(v)}finally{ft=g}}:h=ke,t&&r){const g=h,O=r===!0?1/0:r;h=()=>Ye(g(),O)}const K=hi(),N=()=>{a.stop(),K&&K.active&&Hs(K.effects,a)};if(i&&t){const g=t;t=(...O)=>{g(...O),N()}}let j=_?new Array(e.length).fill(fn):fn;const p=g=>{if(!(!(a.flags&1)||!a.dirty&&!g))if(t){const O=a.run();if(r||S||(_?O.some((F,$)=>tt(F,j[$])):tt(O,j))){y&&y();const F=ft;ft=a;try{const $=[O,j===fn?void 0:_&&j[0]===fn?[]:j,v];c?c(t,3,$):t(...$),j=O}finally{ft=F}}}else a.run()};return l&&l(p),a=new pi(h),a.scheduler=o?()=>o(p,!1):p,v=g=>Hl(g,!1,a),y=a.onStop=()=>{const g=An.get(a);if(g){if(c)c(g,4);else for(const O of g)O();An.delete(a)}},t?s?p(!0):j=a.run():o?o(p.bind(null,!0),!0):a.run(),N.pause=a.pause.bind(a),N.resume=a.resume.bind(a),N.stop=N,N}function Ye(e,t=1/0,n){if(t<=0||!ne(e)||e.__v_skip||(n=n||new Set,n.has(e)))return e;if(n.add(e),t--,fe(e))Ye(e.value,t,n);else if(W(e))for(let s=0;s{Ye(s,t,n)});else if(ci(e)){for(const s in e)Ye(e[s],t,n);for(const s of Object.getOwnPropertySymbols(e))Object.prototype.propertyIsEnumerable.call(e,s)&&Ye(e[s],t,n)}return e}/** +* @vue/runtime-core v3.5.13 +* (c) 2018-present Yuxi (Evan) You and Vue contributors +* @license MIT +**/function tn(e,t,n,s){try{return s?e(...s):e()}catch(r){nn(r,t,n)}}function He(e,t,n,s){if(q(e)){const r=tn(e,t,n,s);return r&&oi(r)&&r.catch(i=>{nn(i,t,n)}),r}if(W(e)){const r=[];for(let i=0;i>>1,r=Se[s],i=Gt(r);i=Gt(n)?Se.push(e):Se.splice(jl(t),0,e),e.flags|=1,Li()}}function Li(){Rn||(Rn=Pi.then(Ii))}function Vl(e){W(e)?At.push(...e):Qe&&e.id===-1?Qe.splice(wt+1,0,e):e.flags&1||(At.push(e),e.flags|=1),Li()}function dr(e,t,n=Ve+1){for(;nGt(n)-Gt(s));if(At.length=0,Qe){Qe.push(...t);return}for(Qe=t,wt=0;wte.id==null?e.flags&2?-1:1/0:e.id;function Ii(e){try{for(Ve=0;Ve{s._d&&Ar(-1);const i=Mn(t);let o;try{o=e(...r)}finally{Mn(i),s._d&&Ar(1)}return o};return s._n=!0,s._c=!0,s._d=!0,s}function _f(e,t){if(de===null)return e;const n=Gn(de),s=e.dirs||(e.dirs=[]);for(let r=0;re.__isTeleport,Vt=e=>e&&(e.disabled||e.disabled===""),hr=e=>e&&(e.defer||e.defer===""),pr=e=>typeof SVGElement<"u"&&e instanceof SVGElement,gr=e=>typeof MathMLElement=="function"&&e instanceof MathMLElement,xs=(e,t)=>{const n=e&&e.to;return re(n)?t?t(n):null:n},$i={name:"Teleport",__isTeleport:!0,process(e,t,n,s,r,i,o,l,c,f){const{mc:a,pc:h,pbc:y,o:{insert:v,querySelector:S,createText:_,createComment:K}}=f,N=Vt(t.props);let{shapeFlag:j,children:p,dynamicChildren:g}=t;if(e==null){const O=t.el=_(""),F=t.anchor=_("");v(O,n,s),v(F,n,s);const $=(R,b)=>{j&16&&(r&&r.isCE&&(r.ce._teleportTarget=R),a(p,R,b,r,i,o,l,c))},V=()=>{const R=t.target=xs(t.props,S),b=Di(R,t,_,v);R&&(o!=="svg"&&pr(R)?o="svg":o!=="mathml"&&gr(R)&&(o="mathml"),N||($(R,b),Sn(t,!1)))};N&&($(n,F),Sn(t,!0)),hr(t.props)?be(()=>{V(),t.el.__isMounted=!0},i):V()}else{if(hr(t.props)&&!e.el.__isMounted){be(()=>{$i.process(e,t,n,s,r,i,o,l,c,f),delete e.el.__isMounted},i);return}t.el=e.el,t.targetStart=e.targetStart;const O=t.anchor=e.anchor,F=t.target=e.target,$=t.targetAnchor=e.targetAnchor,V=Vt(e.props),R=V?n:F,b=V?O:$;if(o==="svg"||pr(F)?o="svg":(o==="mathml"||gr(F))&&(o="mathml"),g?(y(e.dynamicChildren,g,R,r,i,o,l),Qs(e,t,!0)):c||h(e,t,R,b,r,i,o,l,!1),N)V?t.props&&e.props&&t.props.to!==e.props.to&&(t.props.to=e.props.to):un(t,n,O,f,1);else if((t.props&&t.props.to)!==(e.props&&e.props.to)){const I=t.target=xs(t.props,S);I&&un(t,I,null,f,0)}else V&&un(t,F,$,f,1);Sn(t,N)}},remove(e,t,n,{um:s,o:{remove:r}},i){const{shapeFlag:o,children:l,anchor:c,targetStart:f,targetAnchor:a,target:h,props:y}=e;if(h&&(r(f),r(a)),i&&r(c),o&16){const v=i||!Vt(y);for(let S=0;S{e.isMounted=!0}),Ki(()=>{e.isUnmounting=!0}),e}const Re=[Function,Array],ji={mode:String,appear:Boolean,persisted:Boolean,onBeforeEnter:Re,onEnter:Re,onAfterEnter:Re,onEnterCancelled:Re,onBeforeLeave:Re,onLeave:Re,onAfterLeave:Re,onLeaveCancelled:Re,onBeforeAppear:Re,onAppear:Re,onAfterAppear:Re,onAppearCancelled:Re},Vi=e=>{const t=e.subTree;return t.component?Vi(t.component):t},Wl={name:"BaseTransition",props:ji,setup(e,{slots:t}){const n=qn(),s=Bl();return()=>{const r=t.default&&Bi(t.default(),!0);if(!r||!r.length)return;const i=Ui(r),o=J(e),{mode:l}=o;if(s.isLeaving)return ts(i);const c=mr(i);if(!c)return ts(i);let f=Es(c,o,s,n,h=>f=h);c.type!==ve&&Yt(c,f);let a=n.subTree&&mr(n.subTree);if(a&&a.type!==ve&&!ut(c,a)&&Vi(n).type!==ve){let h=Es(a,o,s,n);if(Yt(a,h),l==="out-in"&&c.type!==ve)return s.isLeaving=!0,h.afterLeave=()=>{s.isLeaving=!1,n.job.flags&8||n.update(),delete h.afterLeave,a=void 0},ts(i);l==="in-out"&&c.type!==ve?h.delayLeave=(y,v,S)=>{const _=ki(s,a);_[String(a.key)]=a,y[Ze]=()=>{v(),y[Ze]=void 0,delete f.delayedLeave,a=void 0},f.delayedLeave=()=>{S(),delete f.delayedLeave,a=void 0}}:a=void 0}else a&&(a=void 0);return i}}};function Ui(e){let t=e[0];if(e.length>1){for(const n of e)if(n.type!==ve){t=n;break}}return t}const Kl=Wl;function ki(e,t){const{leavingVNodes:n}=e;let s=n.get(t.type);return s||(s=Object.create(null),n.set(t.type,s)),s}function Es(e,t,n,s,r){const{appear:i,mode:o,persisted:l=!1,onBeforeEnter:c,onEnter:f,onAfterEnter:a,onEnterCancelled:h,onBeforeLeave:y,onLeave:v,onAfterLeave:S,onLeaveCancelled:_,onBeforeAppear:K,onAppear:N,onAfterAppear:j,onAppearCancelled:p}=t,g=String(e.key),O=ki(n,e),F=(R,b)=>{R&&He(R,s,9,b)},$=(R,b)=>{const I=b[1];F(R,b),W(R)?R.every(x=>x.length<=1)&&I():R.length<=1&&I()},V={mode:o,persisted:l,beforeEnter(R){let b=c;if(!n.isMounted)if(i)b=K||c;else return;R[Ze]&&R[Ze](!0);const I=O[g];I&&ut(e,I)&&I.el[Ze]&&I.el[Ze](),F(b,[R])},enter(R){let b=f,I=a,x=h;if(!n.isMounted)if(i)b=N||f,I=j||a,x=p||h;else return;let B=!1;const se=R[dn]=le=>{B||(B=!0,le?F(x,[R]):F(I,[R]),V.delayedLeave&&V.delayedLeave(),R[dn]=void 0)};b?$(b,[R,se]):se()},leave(R,b){const I=String(e.key);if(R[dn]&&R[dn](!0),n.isUnmounting)return b();F(y,[R]);let x=!1;const B=R[Ze]=se=>{x||(x=!0,b(),se?F(_,[R]):F(S,[R]),R[Ze]=void 0,O[I]===e&&delete O[I])};O[I]=e,v?$(v,[R,B]):B()},clone(R){const b=Es(R,t,n,s,r);return r&&r(b),b}};return V}function ts(e){if(sn(e))return e=nt(e),e.children=null,e}function mr(e){if(!sn(e))return Hi(e.type)&&e.children?Ui(e.children):e;const{shapeFlag:t,children:n}=e;if(n){if(t&16)return n[0];if(t&32&&q(n.default))return n.default()}}function Yt(e,t){e.shapeFlag&6&&e.component?(e.transition=t,Yt(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 Bi(e,t=!1,n){let s=[],r=0;for(let i=0;i1)for(let i=0;iXt(S,t&&(W(t)?t[_]:t),n,s,r));return}if(pt(s)&&!r){s.shapeFlag&512&&s.type.__asyncResolved&&s.component.subTree.component&&Xt(e,t,n,s.component.subTree);return}const i=s.shapeFlag&4?Gn(s.component):s.el,o=r?null:i,{i:l,r:c}=e,f=t&&t.r,a=l.refs===Z?l.refs={}:l.refs,h=l.setupState,y=J(h),v=h===Z?()=>!1:S=>z(y,S);if(f!=null&&f!==c&&(re(f)?(a[f]=null,v(f)&&(h[f]=null)):fe(f)&&(f.value=null)),q(c))tn(c,l,12,[o,a]);else{const S=re(c),_=fe(c);if(S||_){const K=()=>{if(e.f){const N=S?v(c)?h[c]:a[c]:c.value;r?W(N)&&Hs(N,i):W(N)?N.includes(i)||N.push(i):S?(a[c]=[i],v(c)&&(h[c]=a[c])):(c.value=[i],e.k&&(a[e.k]=c.value))}else S?(a[c]=o,v(c)&&(h[c]=o)):_&&(c.value=o,e.k&&(a[e.k]=o))};o?(K.id=-1,be(K,n)):K()}}}let yr=!1;const bt=()=>{yr||(console.error("Hydration completed but contains mismatches."),yr=!0)},ql=e=>e.namespaceURI.includes("svg")&&e.tagName!=="foreignObject",Gl=e=>e.namespaceURI.includes("MathML"),hn=e=>{if(e.nodeType===1){if(ql(e))return"svg";if(Gl(e))return"mathml"}},xt=e=>e.nodeType===8;function Yl(e){const{mt:t,p:n,o:{patchProp:s,createText:r,nextSibling:i,parentNode:o,remove:l,insert:c,createComment:f}}=e,a=(p,g)=>{if(!g.hasChildNodes()){n(null,p,g),On(),g._vnode=p;return}h(g.firstChild,p,null,null,null),On(),g._vnode=p},h=(p,g,O,F,$,V=!1)=>{V=V||!!g.dynamicChildren;const R=xt(p)&&p.data==="[",b=()=>_(p,g,O,F,$,R),{type:I,ref:x,shapeFlag:B,patchFlag:se}=g;let le=p.nodeType;g.el=p,se===-2&&(V=!1,g.dynamicChildren=null);let U=null;switch(I){case gt:le!==3?g.children===""?(c(g.el=r(""),o(p),p),U=p):U=b():(p.data!==g.children&&(bt(),p.data=g.children),U=i(p));break;case ve:j(p)?(U=i(p),N(g.el=p.content.firstChild,p,O)):le!==8||R?U=b():U=i(p);break;case kt:if(R&&(p=i(p),le=p.nodeType),le===1||le===3){U=p;const Y=!g.children.length;for(let D=0;D{V=V||!!g.dynamicChildren;const{type:R,props:b,patchFlag:I,shapeFlag:x,dirs:B,transition:se}=g,le=R==="input"||R==="option";if(le||I!==-1){B&&Ue(g,null,O,"created");let U=!1;if(j(p)){U=co(null,se)&&O&&O.vnode.props&&O.vnode.props.appear;const D=p.content.firstChild;U&&se.beforeEnter(D),N(D,p,O),g.el=p=D}if(x&16&&!(b&&(b.innerHTML||b.textContent))){let D=v(p.firstChild,g,p,O,F,$,V);for(;D;){pn(p,1)||bt();const he=D;D=D.nextSibling,l(he)}}else if(x&8){let D=g.children;D[0]===` +`&&(p.tagName==="PRE"||p.tagName==="TEXTAREA")&&(D=D.slice(1)),p.textContent!==D&&(pn(p,0)||bt(),p.textContent=g.children)}if(b){if(le||!V||I&48){const D=p.tagName.includes("-");for(const he in b)(le&&(he.endsWith("value")||he==="indeterminate")||en(he)&&!Ct(he)||he[0]==="."||D)&&s(p,he,null,b[he],void 0,O)}else if(b.onClick)s(p,"onClick",null,b.onClick,void 0,O);else if(I&4&&ht(b.style))for(const D in b.style)b.style[D]}let Y;(Y=b&&b.onVnodeBeforeMount)&&Oe(Y,O,g),B&&Ue(g,null,O,"beforeMount"),((Y=b&&b.onVnodeMounted)||B||U)&&go(()=>{Y&&Oe(Y,O,g),U&&se.enter(p),B&&Ue(g,null,O,"mounted")},F)}return p.nextSibling},v=(p,g,O,F,$,V,R)=>{R=R||!!g.dynamicChildren;const b=g.children,I=b.length;for(let x=0;x{const{slotScopeIds:R}=g;R&&($=$?$.concat(R):R);const b=o(p),I=v(i(p),g,b,O,F,$,V);return I&&xt(I)&&I.data==="]"?i(g.anchor=I):(bt(),c(g.anchor=f("]"),b,I),I)},_=(p,g,O,F,$,V)=>{if(pn(p.parentElement,1)||bt(),g.el=null,V){const I=K(p);for(;;){const x=i(p);if(x&&x!==I)l(x);else break}}const R=i(p),b=o(p);return l(p),n(null,g,b,R,O,F,hn(b),$),O&&(O.vnode.el=g.el,ho(O,g.el)),R},K=(p,g="[",O="]")=>{let F=0;for(;p;)if(p=i(p),p&&xt(p)&&(p.data===g&&F++,p.data===O)){if(F===0)return i(p);F--}return p},N=(p,g,O)=>{const F=g.parentNode;F&&F.replaceChild(p,g);let $=O;for(;$;)$.vnode.el===g&&($.vnode.el=$.subTree.el=p),$=$.parent},j=p=>p.nodeType===1&&p.tagName==="TEMPLATE";return[a,h]}const vr="data-allow-mismatch",Xl={0:"text",1:"children",2:"class",3:"style",4:"attribute"};function pn(e,t){if(t===0||t===1)for(;e&&!e.hasAttribute(vr);)e=e.parentElement;const n=e&&e.getAttribute(vr);if(n==null)return!1;if(n==="")return!0;{const s=n.split(",");return t===0&&s.includes("children")?!0:n.split(",").includes(Xl[t])}}Hn().requestIdleCallback;Hn().cancelIdleCallback;function Jl(e,t){if(xt(e)&&e.data==="["){let n=1,s=e.nextSibling;for(;s;){if(s.nodeType===1){if(t(s)===!1)break}else if(xt(s))if(s.data==="]"){if(--n===0)break}else s.data==="["&&n++;s=s.nextSibling}}else t(e)}const pt=e=>!!e.type.__asyncLoader;/*! #__NO_SIDE_EFFECTS__ */function wf(e){q(e)&&(e={loader:e});const{loader:t,loadingComponent:n,errorComponent:s,delay:r=200,hydrate:i,timeout:o,suspensible:l=!0,onError:c}=e;let f=null,a,h=0;const y=()=>(h++,f=null,v()),v=()=>{let S;return f||(S=f=t().catch(_=>{if(_=_ instanceof Error?_:new Error(String(_)),c)return new Promise((K,N)=>{c(_,()=>K(y()),()=>N(_),h+1)});throw _}).then(_=>S!==f&&f?f:(_&&(_.__esModule||_[Symbol.toStringTag]==="Module")&&(_=_.default),a=_,_)))};return Ys({name:"AsyncComponentWrapper",__asyncLoader:v,__asyncHydrate(S,_,K){const N=i?()=>{const j=i(K,p=>Jl(S,p));j&&(_.bum||(_.bum=[])).push(j)}:K;a?N():v().then(()=>!_.isUnmounted&&N())},get __asyncResolved(){return a},setup(){const S=ue;if(Xs(S),a)return()=>ns(a,S);const _=p=>{f=null,nn(p,S,13,!s)};if(l&&S.suspense||Mt)return v().then(p=>()=>ns(p,S)).catch(p=>(_(p),()=>s?ce(s,{error:p}):null));const K=oe(!1),N=oe(),j=oe(!!r);return r&&setTimeout(()=>{j.value=!1},r),o!=null&&setTimeout(()=>{if(!K.value&&!N.value){const p=new Error(`Async component timed out after ${o}ms.`);_(p),N.value=p}},o),v().then(()=>{K.value=!0,S.parent&&sn(S.parent.vnode)&&S.parent.update()}).catch(p=>{_(p),N.value=p}),()=>{if(K.value&&a)return ns(a,S);if(N.value&&s)return ce(s,{error:N.value});if(n&&!j.value)return ce(n)}}})}function ns(e,t){const{ref:n,props:s,children:r,ce:i}=t.vnode,o=ce(e,s,r);return o.ref=n,o.ce=i,delete t.vnode.ce,o}const sn=e=>e.type.__isKeepAlive;function zl(e,t){Wi(e,"a",t)}function Ql(e,t){Wi(e,"da",t)}function Wi(e,t,n=ue){const s=e.__wdc||(e.__wdc=()=>{let r=n;for(;r;){if(r.isDeactivated)return;r=r.parent}return e()});if(kn(t,s,n),n){let r=n.parent;for(;r&&r.parent;)sn(r.parent.vnode)&&Zl(s,t,n,r),r=r.parent}}function Zl(e,t,n,s){const r=kn(t,e,s,!0);Bn(()=>{Hs(s[t],r)},n)}function kn(e,t,n=ue,s=!1){if(n){const r=n[e]||(n[e]=[]),i=t.__weh||(t.__weh=(...o)=>{rt();const l=rn(n),c=He(t,n,e,o);return l(),it(),c});return s?r.unshift(i):r.push(i),i}}const Je=e=>(t,n=ue)=>{(!Mt||e==="sp")&&kn(e,(...s)=>t(...s),n)},ec=Je("bm"),Lt=Je("m"),tc=Je("bu"),nc=Je("u"),Ki=Je("bum"),Bn=Je("um"),sc=Je("sp"),rc=Je("rtg"),ic=Je("rtc");function oc(e,t=ue){kn("ec",e,t)}const qi="components";function Sf(e,t){return Yi(qi,e,!0,t)||e}const Gi=Symbol.for("v-ndc");function xf(e){return re(e)?Yi(qi,e,!1)||e:e||Gi}function Yi(e,t,n=!0,s=!1){const r=de||ue;if(r){const i=r.type;{const l=Wc(i,!1);if(l&&(l===t||l===Le(t)||l===Fn(Le(t))))return i}const o=_r(r[e]||i[e],t)||_r(r.appContext[e],t);return!o&&s?i:o}}function _r(e,t){return e&&(e[t]||e[Le(t)]||e[Fn(Le(t))])}function Ef(e,t,n,s){let r;const i=n,o=W(e);if(o||re(e)){const l=o&&ht(e);let c=!1;l&&(c=!Pe(e),e=Dn(e)),r=new Array(e.length);for(let f=0,a=e.length;ft(l,c,void 0,i));else{const l=Object.keys(e);r=new Array(l.length);for(let c=0,f=l.length;czt(t)?!(t.type===ve||t.type===xe&&!Xi(t.children)):!0)?e:null}function Cf(e,t){const n={};for(const s in e)n[/[A-Z]/.test(s)?`on:${s}`:_n(s)]=e[s];return n}const Ts=e=>e?bo(e)?Gn(e):Ts(e.parent):null,Ut=ae(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=>Ts(e.parent),$root:e=>Ts(e.root),$host:e=>e.ce,$emit:e=>e.emit,$options:e=>Js(e),$forceUpdate:e=>e.f||(e.f=()=>{Gs(e.update)}),$nextTick:e=>e.n||(e.n=Un.bind(e.proxy)),$watch:e=>Rc.bind(e)}),ss=(e,t)=>e!==Z&&!e.__isScriptSetup&&z(e,t),lc={get({_:e},t){if(t==="__v_skip")return!0;const{ctx:n,setupState:s,data:r,props:i,accessCache:o,type:l,appContext:c}=e;let f;if(t[0]!=="$"){const v=o[t];if(v!==void 0)switch(v){case 1:return s[t];case 2:return r[t];case 4:return n[t];case 3:return i[t]}else{if(ss(s,t))return o[t]=1,s[t];if(r!==Z&&z(r,t))return o[t]=2,r[t];if((f=e.propsOptions[0])&&z(f,t))return o[t]=3,i[t];if(n!==Z&&z(n,t))return o[t]=4,n[t];Cs&&(o[t]=0)}}const a=Ut[t];let h,y;if(a)return t==="$attrs"&&me(e.attrs,"get",""),a(e);if((h=l.__cssModules)&&(h=h[t]))return h;if(n!==Z&&z(n,t))return o[t]=4,n[t];if(y=c.config.globalProperties,z(y,t))return y[t]},set({_:e},t,n){const{data:s,setupState:r,ctx:i}=e;return ss(r,t)?(r[t]=n,!0):s!==Z&&z(s,t)?(s[t]=n,!0):z(e.props,t)||t[0]==="$"&&t.slice(1)in e?!1:(i[t]=n,!0)},has({_:{data:e,setupState:t,accessCache:n,ctx:s,appContext:r,propsOptions:i}},o){let l;return!!n[o]||e!==Z&&z(e,o)||ss(t,o)||(l=i[0])&&z(l,o)||z(s,o)||z(Ut,o)||z(r.config.globalProperties,o)},defineProperty(e,t,n){return n.get!=null?e._.accessCache[t]=0:z(n,"value")&&this.set(e,t,n.value,null),Reflect.defineProperty(e,t,n)}};function Af(){return cc().slots}function cc(){const e=qn();return e.setupContext||(e.setupContext=So(e))}function br(e){return W(e)?e.reduce((t,n)=>(t[n]=null,t),{}):e}let Cs=!0;function ac(e){const t=Js(e),n=e.proxy,s=e.ctx;Cs=!1,t.beforeCreate&&wr(t.beforeCreate,e,"bc");const{data:r,computed:i,methods:o,watch:l,provide:c,inject:f,created:a,beforeMount:h,mounted:y,beforeUpdate:v,updated:S,activated:_,deactivated:K,beforeDestroy:N,beforeUnmount:j,destroyed:p,unmounted:g,render:O,renderTracked:F,renderTriggered:$,errorCaptured:V,serverPrefetch:R,expose:b,inheritAttrs:I,components:x,directives:B,filters:se}=t;if(f&&fc(f,s,null),o)for(const Y in o){const D=o[Y];q(D)&&(s[Y]=D.bind(n))}if(r){const Y=r.call(n,n);ne(Y)&&(e.data=jn(Y))}if(Cs=!0,i)for(const Y in i){const D=i[Y],he=q(D)?D.bind(n,n):q(D.get)?D.get.bind(n,n):ke,on=!q(D)&&q(D.set)?D.set.bind(n):ke,ot=ie({get:he,set:on});Object.defineProperty(s,Y,{enumerable:!0,configurable:!0,get:()=>ot.value,set:De=>ot.value=De})}if(l)for(const Y in l)Ji(l[Y],s,n,Y);if(c){const Y=q(c)?c.call(n):c;Reflect.ownKeys(Y).forEach(D=>{mc(D,Y[D])})}a&&wr(a,e,"c");function U(Y,D){W(D)?D.forEach(he=>Y(he.bind(n))):D&&Y(D.bind(n))}if(U(ec,h),U(Lt,y),U(tc,v),U(nc,S),U(zl,_),U(Ql,K),U(oc,V),U(ic,F),U(rc,$),U(Ki,j),U(Bn,g),U(sc,R),W(b))if(b.length){const Y=e.exposed||(e.exposed={});b.forEach(D=>{Object.defineProperty(Y,D,{get:()=>n[D],set:he=>n[D]=he})})}else e.exposed||(e.exposed={});O&&e.render===ke&&(e.render=O),I!=null&&(e.inheritAttrs=I),x&&(e.components=x),B&&(e.directives=B),R&&Xs(e)}function fc(e,t,n=ke){W(e)&&(e=As(e));for(const s in e){const r=e[s];let i;ne(r)?"default"in r?i=Ot(r.from||s,r.default,!0):i=Ot(r.from||s):i=Ot(r),fe(i)?Object.defineProperty(t,s,{enumerable:!0,configurable:!0,get:()=>i.value,set:o=>i.value=o}):t[s]=i}}function wr(e,t,n){He(W(e)?e.map(s=>s.bind(t.proxy)):e.bind(t.proxy),t,n)}function Ji(e,t,n,s){let r=s.includes(".")?fo(n,s):()=>n[s];if(re(e)){const i=t[e];q(i)&&Fe(r,i)}else if(q(e))Fe(r,e.bind(n));else if(ne(e))if(W(e))e.forEach(i=>Ji(i,t,n,s));else{const i=q(e.handler)?e.handler.bind(n):t[e.handler];q(i)&&Fe(r,i,e)}}function Js(e){const t=e.type,{mixins:n,extends:s}=t,{mixins:r,optionsCache:i,config:{optionMergeStrategies:o}}=e.appContext,l=i.get(t);let c;return l?c=l:!r.length&&!n&&!s?c=t:(c={},r.length&&r.forEach(f=>Pn(c,f,o,!0)),Pn(c,t,o)),ne(t)&&i.set(t,c),c}function Pn(e,t,n,s=!1){const{mixins:r,extends:i}=t;i&&Pn(e,i,n,!0),r&&r.forEach(o=>Pn(e,o,n,!0));for(const o in t)if(!(s&&o==="expose")){const l=uc[o]||n&&n[o];e[o]=l?l(e[o],t[o]):t[o]}return e}const uc={data:Sr,props:xr,emits:xr,methods:$t,computed:$t,beforeCreate:_e,created:_e,beforeMount:_e,mounted:_e,beforeUpdate:_e,updated:_e,beforeDestroy:_e,beforeUnmount:_e,destroyed:_e,unmounted:_e,activated:_e,deactivated:_e,errorCaptured:_e,serverPrefetch:_e,components:$t,directives:$t,watch:hc,provide:Sr,inject:dc};function Sr(e,t){return t?e?function(){return ae(q(e)?e.call(this,this):e,q(t)?t.call(this,this):t)}:t:e}function dc(e,t){return $t(As(e),As(t))}function As(e){if(W(e)){const t={};for(let n=0;n1)return n&&q(t)?t.call(s&&s.proxy):t}}const Qi={},Zi=()=>Object.create(Qi),eo=e=>Object.getPrototypeOf(e)===Qi;function yc(e,t,n,s=!1){const r={},i=Zi();e.propsDefaults=Object.create(null),to(e,t,r,i);for(const o in e.propsOptions[0])o in r||(r[o]=void 0);n?e.props=s?r:Tl(r):e.type.props?e.props=r:e.props=i,e.attrs=i}function vc(e,t,n,s){const{props:r,attrs:i,vnode:{patchFlag:o}}=e,l=J(r),[c]=e.propsOptions;let f=!1;if((s||o>0)&&!(o&16)){if(o&8){const a=e.vnode.dynamicProps;for(let h=0;h{c=!0;const[y,v]=no(h,t,!0);ae(o,y),v&&l.push(...v)};!n&&t.mixins.length&&t.mixins.forEach(a),e.extends&&a(e.extends),e.mixins&&e.mixins.forEach(a)}if(!i&&!c)return ne(e)&&s.set(e,Et),Et;if(W(i))for(let a=0;ae[0]==="_"||e==="$stable",zs=e=>W(e)?e.map(Me):[Me(e)],bc=(e,t,n)=>{if(t._n)return t;const s=Ul((...r)=>zs(t(...r)),n);return s._c=!1,s},ro=(e,t,n)=>{const s=e._ctx;for(const r in e){if(so(r))continue;const i=e[r];if(q(i))t[r]=bc(r,i,s);else if(i!=null){const o=zs(i);t[r]=()=>o}}},io=(e,t)=>{const n=zs(t);e.slots.default=()=>n},oo=(e,t,n)=>{for(const s in t)(n||s!=="_")&&(e[s]=t[s])},wc=(e,t,n)=>{const s=e.slots=Zi();if(e.vnode.shapeFlag&32){const r=t._;r?(oo(s,t,n),n&&ai(s,"_",r,!0)):ro(t,s)}else t&&io(e,t)},Sc=(e,t,n)=>{const{vnode:s,slots:r}=e;let i=!0,o=Z;if(s.shapeFlag&32){const l=t._;l?n&&l===1?i=!1:oo(r,t,n):(i=!t.$stable,ro(t,r)),o=t}else t&&(io(e,t),o={default:1});if(i)for(const l in r)!so(l)&&o[l]==null&&delete r[l]},be=go;function xc(e){return lo(e)}function Ec(e){return lo(e,Yl)}function lo(e,t){const n=Hn();n.__VUE__=!0;const{insert:s,remove:r,patchProp:i,createElement:o,createText:l,createComment:c,setText:f,setElementText:a,parentNode:h,nextSibling:y,setScopeId:v=ke,insertStaticContent:S}=e,_=(u,d,m,T=null,w=null,E=null,P=void 0,M=null,A=!!d.dynamicChildren)=>{if(u===d)return;u&&!ut(u,d)&&(T=ln(u),De(u,w,E,!0),u=null),d.patchFlag===-2&&(A=!1,d.dynamicChildren=null);const{type:C,ref:k,shapeFlag:L}=d;switch(C){case gt:K(u,d,m,T);break;case ve:N(u,d,m,T);break;case kt:u==null&&j(d,m,T,P);break;case xe:x(u,d,m,T,w,E,P,M,A);break;default:L&1?O(u,d,m,T,w,E,P,M,A):L&6?B(u,d,m,T,w,E,P,M,A):(L&64||L&128)&&C.process(u,d,m,T,w,E,P,M,A,vt)}k!=null&&w&&Xt(k,u&&u.ref,E,d||u,!d)},K=(u,d,m,T)=>{if(u==null)s(d.el=l(d.children),m,T);else{const w=d.el=u.el;d.children!==u.children&&f(w,d.children)}},N=(u,d,m,T)=>{u==null?s(d.el=c(d.children||""),m,T):d.el=u.el},j=(u,d,m,T)=>{[u.el,u.anchor]=S(u.children,d,m,T,u.el,u.anchor)},p=({el:u,anchor:d},m,T)=>{let w;for(;u&&u!==d;)w=y(u),s(u,m,T),u=w;s(d,m,T)},g=({el:u,anchor:d})=>{let m;for(;u&&u!==d;)m=y(u),r(u),u=m;r(d)},O=(u,d,m,T,w,E,P,M,A)=>{d.type==="svg"?P="svg":d.type==="math"&&(P="mathml"),u==null?F(d,m,T,w,E,P,M,A):R(u,d,w,E,P,M,A)},F=(u,d,m,T,w,E,P,M)=>{let A,C;const{props:k,shapeFlag:L,transition:H,dirs:G}=u;if(A=u.el=o(u.type,E,k&&k.is,k),L&8?a(A,u.children):L&16&&V(u.children,A,null,T,w,rs(u,E),P,M),G&&Ue(u,null,T,"created"),$(A,u,u.scopeId,P,T),k){for(const ee in k)ee!=="value"&&!Ct(ee)&&i(A,ee,null,k[ee],E,T);"value"in k&&i(A,"value",null,k.value,E),(C=k.onVnodeBeforeMount)&&Oe(C,T,u)}G&&Ue(u,null,T,"beforeMount");const X=co(w,H);X&&H.beforeEnter(A),s(A,d,m),((C=k&&k.onVnodeMounted)||X||G)&&be(()=>{C&&Oe(C,T,u),X&&H.enter(A),G&&Ue(u,null,T,"mounted")},w)},$=(u,d,m,T,w)=>{if(m&&v(u,m),T)for(let E=0;E{for(let C=A;C{const M=d.el=u.el;let{patchFlag:A,dynamicChildren:C,dirs:k}=d;A|=u.patchFlag&16;const L=u.props||Z,H=d.props||Z;let G;if(m&<(m,!1),(G=H.onVnodeBeforeUpdate)&&Oe(G,m,d,u),k&&Ue(d,u,m,"beforeUpdate"),m&<(m,!0),(L.innerHTML&&H.innerHTML==null||L.textContent&&H.textContent==null)&&a(M,""),C?b(u.dynamicChildren,C,M,m,T,rs(d,w),E):P||D(u,d,M,null,m,T,rs(d,w),E,!1),A>0){if(A&16)I(M,L,H,m,w);else if(A&2&&L.class!==H.class&&i(M,"class",null,H.class,w),A&4&&i(M,"style",L.style,H.style,w),A&8){const X=d.dynamicProps;for(let ee=0;ee{G&&Oe(G,m,d,u),k&&Ue(d,u,m,"updated")},T)},b=(u,d,m,T,w,E,P)=>{for(let M=0;M{if(d!==m){if(d!==Z)for(const E in d)!Ct(E)&&!(E in m)&&i(u,E,d[E],null,w,T);for(const E in m){if(Ct(E))continue;const P=m[E],M=d[E];P!==M&&E!=="value"&&i(u,E,M,P,w,T)}"value"in m&&i(u,"value",d.value,m.value,w)}},x=(u,d,m,T,w,E,P,M,A)=>{const C=d.el=u?u.el:l(""),k=d.anchor=u?u.anchor:l("");let{patchFlag:L,dynamicChildren:H,slotScopeIds:G}=d;G&&(M=M?M.concat(G):G),u==null?(s(C,m,T),s(k,m,T),V(d.children||[],m,k,w,E,P,M,A)):L>0&&L&64&&H&&u.dynamicChildren?(b(u.dynamicChildren,H,m,w,E,P,M),(d.key!=null||w&&d===w.subTree)&&Qs(u,d,!0)):D(u,d,m,k,w,E,P,M,A)},B=(u,d,m,T,w,E,P,M,A)=>{d.slotScopeIds=M,u==null?d.shapeFlag&512?w.ctx.activate(d,m,T,P,A):se(d,m,T,w,E,P,A):le(u,d,A)},se=(u,d,m,T,w,E,P)=>{const M=u.component=Vc(u,T,w);if(sn(u)&&(M.ctx.renderer=vt),Uc(M,!1,P),M.asyncDep){if(w&&w.registerDep(M,U,P),!u.el){const A=M.subTree=ce(ve);N(null,A,d,m)}}else U(M,u,d,m,w,E,P)},le=(u,d,m)=>{const T=d.component=u.component;if(Ic(u,d,m))if(T.asyncDep&&!T.asyncResolved){Y(T,d,m);return}else T.next=d,T.update();else d.el=u.el,T.vnode=d},U=(u,d,m,T,w,E,P)=>{const M=()=>{if(u.isMounted){let{next:L,bu:H,u:G,parent:X,vnode:ee}=u;{const Te=ao(u);if(Te){L&&(L.el=ee.el,Y(u,L,P)),Te.asyncDep.then(()=>{u.isUnmounted||M()});return}}let Q=L,Ee;lt(u,!1),L?(L.el=ee.el,Y(u,L,P)):L=ee,H&&bn(H),(Ee=L.props&&L.props.onVnodeBeforeUpdate)&&Oe(Ee,X,L,ee),lt(u,!0);const pe=is(u),Ie=u.subTree;u.subTree=pe,_(Ie,pe,h(Ie.el),ln(Ie),u,w,E),L.el=pe.el,Q===null&&ho(u,pe.el),G&&be(G,w),(Ee=L.props&&L.props.onVnodeUpdated)&&be(()=>Oe(Ee,X,L,ee),w)}else{let L;const{el:H,props:G}=d,{bm:X,m:ee,parent:Q,root:Ee,type:pe}=u,Ie=pt(d);if(lt(u,!1),X&&bn(X),!Ie&&(L=G&&G.onVnodeBeforeMount)&&Oe(L,Q,d),lt(u,!0),H&&Jn){const Te=()=>{u.subTree=is(u),Jn(H,u.subTree,u,w,null)};Ie&&pe.__asyncHydrate?pe.__asyncHydrate(H,u,Te):Te()}else{Ee.ce&&Ee.ce._injectChildStyle(pe);const Te=u.subTree=is(u);_(null,Te,m,T,u,w,E),d.el=Te.el}if(ee&&be(ee,w),!Ie&&(L=G&&G.onVnodeMounted)){const Te=d;be(()=>Oe(L,Q,Te),w)}(d.shapeFlag&256||Q&&pt(Q.vnode)&&Q.vnode.shapeFlag&256)&&u.a&&be(u.a,w),u.isMounted=!0,d=m=T=null}};u.scope.on();const A=u.effect=new pi(M);u.scope.off();const C=u.update=A.run.bind(A),k=u.job=A.runIfDirty.bind(A);k.i=u,k.id=u.uid,A.scheduler=()=>Gs(k),lt(u,!0),C()},Y=(u,d,m)=>{d.component=u;const T=u.vnode.props;u.vnode=d,u.next=null,vc(u,d.props,T,m),Sc(u,d.children,m),rt(),dr(u),it()},D=(u,d,m,T,w,E,P,M,A=!1)=>{const C=u&&u.children,k=u?u.shapeFlag:0,L=d.children,{patchFlag:H,shapeFlag:G}=d;if(H>0){if(H&128){on(C,L,m,T,w,E,P,M,A);return}else if(H&256){he(C,L,m,T,w,E,P,M,A);return}}G&8?(k&16&&It(C,w,E),L!==C&&a(m,L)):k&16?G&16?on(C,L,m,T,w,E,P,M,A):It(C,w,E,!0):(k&8&&a(m,""),G&16&&V(L,m,T,w,E,P,M,A))},he=(u,d,m,T,w,E,P,M,A)=>{u=u||Et,d=d||Et;const C=u.length,k=d.length,L=Math.min(C,k);let H;for(H=0;Hk?It(u,w,E,!0,!1,L):V(d,m,T,w,E,P,M,A,L)},on=(u,d,m,T,w,E,P,M,A)=>{let C=0;const k=d.length;let L=u.length-1,H=k-1;for(;C<=L&&C<=H;){const G=u[C],X=d[C]=A?et(d[C]):Me(d[C]);if(ut(G,X))_(G,X,m,null,w,E,P,M,A);else break;C++}for(;C<=L&&C<=H;){const G=u[L],X=d[H]=A?et(d[H]):Me(d[H]);if(ut(G,X))_(G,X,m,null,w,E,P,M,A);else break;L--,H--}if(C>L){if(C<=H){const G=H+1,X=GH)for(;C<=L;)De(u[C],w,E,!0),C++;else{const G=C,X=C,ee=new Map;for(C=X;C<=H;C++){const Ce=d[C]=A?et(d[C]):Me(d[C]);Ce.key!=null&&ee.set(Ce.key,C)}let Q,Ee=0;const pe=H-X+1;let Ie=!1,Te=0;const Nt=new Array(pe);for(C=0;C=pe){De(Ce,w,E,!0);continue}let je;if(Ce.key!=null)je=ee.get(Ce.key);else for(Q=X;Q<=H;Q++)if(Nt[Q-X]===0&&ut(Ce,d[Q])){je=Q;break}je===void 0?De(Ce,w,E,!0):(Nt[je-X]=C+1,je>=Te?Te=je:Ie=!0,_(Ce,d[je],m,null,w,E,P,M,A),Ee++)}const lr=Ie?Tc(Nt):Et;for(Q=lr.length-1,C=pe-1;C>=0;C--){const Ce=X+C,je=d[Ce],cr=Ce+1{const{el:E,type:P,transition:M,children:A,shapeFlag:C}=u;if(C&6){ot(u.component.subTree,d,m,T);return}if(C&128){u.suspense.move(d,m,T);return}if(C&64){P.move(u,d,m,vt);return}if(P===xe){s(E,d,m);for(let L=0;LM.enter(E),w);else{const{leave:L,delayLeave:H,afterLeave:G}=M,X=()=>s(E,d,m),ee=()=>{L(E,()=>{X(),G&&G()})};H?H(E,X,ee):ee()}else s(E,d,m)},De=(u,d,m,T=!1,w=!1)=>{const{type:E,props:P,ref:M,children:A,dynamicChildren:C,shapeFlag:k,patchFlag:L,dirs:H,cacheIndex:G}=u;if(L===-2&&(w=!1),M!=null&&Xt(M,null,m,u,!0),G!=null&&(d.renderCache[G]=void 0),k&256){d.ctx.deactivate(u);return}const X=k&1&&H,ee=!pt(u);let Q;if(ee&&(Q=P&&P.onVnodeBeforeUnmount)&&Oe(Q,d,u),k&6)Wo(u.component,m,T);else{if(k&128){u.suspense.unmount(m,T);return}X&&Ue(u,null,d,"beforeUnmount"),k&64?u.type.remove(u,d,m,vt,T):C&&!C.hasOnce&&(E!==xe||L>0&&L&64)?It(C,d,m,!1,!0):(E===xe&&L&384||!w&&k&16)&&It(A,d,m),T&&ir(u)}(ee&&(Q=P&&P.onVnodeUnmounted)||X)&&be(()=>{Q&&Oe(Q,d,u),X&&Ue(u,null,d,"unmounted")},m)},ir=u=>{const{type:d,el:m,anchor:T,transition:w}=u;if(d===xe){Bo(m,T);return}if(d===kt){g(u);return}const E=()=>{r(m),w&&!w.persisted&&w.afterLeave&&w.afterLeave()};if(u.shapeFlag&1&&w&&!w.persisted){const{leave:P,delayLeave:M}=w,A=()=>P(m,E);M?M(u.el,E,A):A()}else E()},Bo=(u,d)=>{let m;for(;u!==d;)m=y(u),r(u),u=m;r(d)},Wo=(u,d,m)=>{const{bum:T,scope:w,job:E,subTree:P,um:M,m:A,a:C}=u;Tr(A),Tr(C),T&&bn(T),w.stop(),E&&(E.flags|=8,De(P,u,d,m)),M&&be(M,d),be(()=>{u.isUnmounted=!0},d),d&&d.pendingBranch&&!d.isUnmounted&&u.asyncDep&&!u.asyncResolved&&u.suspenseId===d.pendingId&&(d.deps--,d.deps===0&&d.resolve())},It=(u,d,m,T=!1,w=!1,E=0)=>{for(let P=E;P{if(u.shapeFlag&6)return ln(u.component.subTree);if(u.shapeFlag&128)return u.suspense.next();const d=y(u.anchor||u.el),m=d&&d[Fi];return m?y(m):d};let Yn=!1;const or=(u,d,m)=>{u==null?d._vnode&&De(d._vnode,null,null,!0):_(d._vnode||null,u,d,null,null,null,m),d._vnode=u,Yn||(Yn=!0,dr(),On(),Yn=!1)},vt={p:_,um:De,m:ot,r:ir,mt:se,mc:V,pc:D,pbc:b,n:ln,o:e};let Xn,Jn;return t&&([Xn,Jn]=t(vt)),{render:or,hydrate:Xn,createApp:gc(or,Xn)}}function rs({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 lt({effect:e,job:t},n){n?(e.flags|=32,t.flags|=4):(e.flags&=-33,t.flags&=-5)}function co(e,t){return(!e||e&&!e.pendingBranch)&&t&&!t.persisted}function Qs(e,t,n=!1){const s=e.children,r=t.children;if(W(s)&&W(r))for(let i=0;i>1,e[n[l]]0&&(t[s]=n[i-1]),n[i]=s)}}for(i=n.length,o=n[i-1];i-- >0;)n[i]=o,o=t[o];return n}function ao(e){const t=e.subTree.component;if(t)return t.asyncDep&&!t.asyncResolved?t:ao(t)}function Tr(e){if(e)for(let t=0;tOt(Cc);function Zs(e,t){return Wn(e,null,t)}function Rf(e,t){return Wn(e,null,{flush:"post"})}function Fe(e,t,n){return Wn(e,t,n)}function Wn(e,t,n=Z){const{immediate:s,deep:r,flush:i,once:o}=n,l=ae({},n),c=t&&s||!t&&i!=="post";let f;if(Mt){if(i==="sync"){const v=Ac();f=v.__watcherHandles||(v.__watcherHandles=[])}else if(!c){const v=()=>{};return v.stop=ke,v.resume=ke,v.pause=ke,v}}const a=ue;l.call=(v,S,_)=>He(v,a,S,_);let h=!1;i==="post"?l.scheduler=v=>{be(v,a&&a.suspense)}:i!=="sync"&&(h=!0,l.scheduler=(v,S)=>{S?v():Gs(v)}),l.augmentJob=v=>{t&&(v.flags|=4),h&&(v.flags|=2,a&&(v.id=a.uid,v.i=a))};const y=$l(e,t,l);return Mt&&(f?f.push(y):c&&y()),y}function Rc(e,t,n){const s=this.proxy,r=re(e)?e.includes(".")?fo(s,e):()=>s[e]:e.bind(s,s);let i;q(t)?i=t:(i=t.handler,n=t);const o=rn(this),l=Wn(r,i.bind(s),n);return o(),l}function fo(e,t){const n=t.split(".");return()=>{let s=e;for(let r=0;rt==="modelValue"||t==="model-value"?e.modelModifiers:e[`${t}Modifiers`]||e[`${Le(t)}Modifiers`]||e[`${st(t)}Modifiers`];function Mc(e,t,...n){if(e.isUnmounted)return;const s=e.vnode.props||Z;let r=n;const i=t.startsWith("update:"),o=i&&Oc(s,t.slice(7));o&&(o.trim&&(r=n.map(a=>re(a)?a.trim():a)),o.number&&(r=n.map(vs)));let l,c=s[l=_n(t)]||s[l=_n(Le(t))];!c&&i&&(c=s[l=_n(st(t))]),c&&He(c,e,6,r);const f=s[l+"Once"];if(f){if(!e.emitted)e.emitted={};else if(e.emitted[l])return;e.emitted[l]=!0,He(f,e,6,r)}}function uo(e,t,n=!1){const s=t.emitsCache,r=s.get(e);if(r!==void 0)return r;const i=e.emits;let o={},l=!1;if(!q(e)){const c=f=>{const a=uo(f,t,!0);a&&(l=!0,ae(o,a))};!n&&t.mixins.length&&t.mixins.forEach(c),e.extends&&c(e.extends),e.mixins&&e.mixins.forEach(c)}return!i&&!l?(ne(e)&&s.set(e,null),null):(W(i)?i.forEach(c=>o[c]=null):ae(o,i),ne(e)&&s.set(e,o),o)}function Kn(e,t){return!e||!en(t)?!1:(t=t.slice(2).replace(/Once$/,""),z(e,t[0].toLowerCase()+t.slice(1))||z(e,st(t))||z(e,t))}function is(e){const{type:t,vnode:n,proxy:s,withProxy:r,propsOptions:[i],slots:o,attrs:l,emit:c,render:f,renderCache:a,props:h,data:y,setupState:v,ctx:S,inheritAttrs:_}=e,K=Mn(e);let N,j;try{if(n.shapeFlag&4){const g=r||s,O=g;N=Me(f.call(O,g,a,h,v,y,S)),j=l}else{const g=t;N=Me(g.length>1?g(h,{attrs:l,slots:o,emit:c}):g(h,null)),j=t.props?l:Pc(l)}}catch(g){Bt.length=0,nn(g,e,1),N=ce(ve)}let p=N;if(j&&_!==!1){const g=Object.keys(j),{shapeFlag:O}=p;g.length&&O&7&&(i&&g.some(Fs)&&(j=Lc(j,i)),p=nt(p,j,!1,!0))}return n.dirs&&(p=nt(p,null,!1,!0),p.dirs=p.dirs?p.dirs.concat(n.dirs):n.dirs),n.transition&&Yt(p,n.transition),N=p,Mn(K),N}const Pc=e=>{let t;for(const n in e)(n==="class"||n==="style"||en(n))&&((t||(t={}))[n]=e[n]);return t},Lc=(e,t)=>{const n={};for(const s in e)(!Fs(s)||!(s.slice(9)in t))&&(n[s]=e[s]);return n};function Ic(e,t,n){const{props:s,children:r,component:i}=e,{props:o,children:l,patchFlag:c}=t,f=i.emitsOptions;if(t.dirs||t.transition)return!0;if(n&&c>=0){if(c&1024)return!0;if(c&16)return s?Cr(s,o,f):!!o;if(c&8){const a=t.dynamicProps;for(let h=0;he.__isSuspense;function go(e,t){t&&t.pendingBranch?W(e)?t.effects.push(...e):t.effects.push(e):Vl(e)}const xe=Symbol.for("v-fgt"),gt=Symbol.for("v-txt"),ve=Symbol.for("v-cmt"),kt=Symbol.for("v-stc"),Bt=[];let Ae=null;function Os(e=!1){Bt.push(Ae=e?null:[])}function Nc(){Bt.pop(),Ae=Bt[Bt.length-1]||null}let Jt=1;function Ar(e,t=!1){Jt+=e,e<0&&Ae&&t&&(Ae.hasOnce=!0)}function mo(e){return e.dynamicChildren=Jt>0?Ae||Et:null,Nc(),Jt>0&&Ae&&Ae.push(e),e}function Of(e,t,n,s,r,i){return mo(vo(e,t,n,s,r,i,!0))}function Ms(e,t,n,s,r){return mo(ce(e,t,n,s,r,!0))}function zt(e){return e?e.__v_isVNode===!0:!1}function ut(e,t){return e.type===t.type&&e.key===t.key}const yo=({key:e})=>e??null,xn=({ref:e,ref_key:t,ref_for:n})=>(typeof e=="number"&&(e=""+e),e!=null?re(e)||fe(e)||q(e)?{i:de,r:e,k:t,f:!!n}:e:null);function vo(e,t=null,n=null,s=0,r=null,i=e===xe?0:1,o=!1,l=!1){const c={__v_isVNode:!0,__v_skip:!0,type:e,props:t,key:t&&yo(t),ref:t&&xn(t),scopeId:Ni,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:i,patchFlag:s,dynamicProps:r,dynamicChildren:null,appContext:null,ctx:de};return l?(er(c,n),i&128&&e.normalize(c)):n&&(c.shapeFlag|=re(n)?8:16),Jt>0&&!o&&Ae&&(c.patchFlag>0||i&6)&&c.patchFlag!==32&&Ae.push(c),c}const ce=Fc;function Fc(e,t=null,n=null,s=0,r=null,i=!1){if((!e||e===Gi)&&(e=ve),zt(e)){const l=nt(e,t,!0);return n&&er(l,n),Jt>0&&!i&&Ae&&(l.shapeFlag&6?Ae[Ae.indexOf(e)]=l:Ae.push(l)),l.patchFlag=-2,l}if(Kc(e)&&(e=e.__vccOpts),t){t=Hc(t);let{class:l,style:c}=t;l&&!re(l)&&(t.class=js(l)),ne(c)&&(Ks(c)&&!W(c)&&(c=ae({},c)),t.style=Ds(c))}const o=re(e)?1:po(e)?128:Hi(e)?64:ne(e)?4:q(e)?2:0;return vo(e,t,n,s,r,o,i,!0)}function Hc(e){return e?Ks(e)||eo(e)?ae({},e):e:null}function nt(e,t,n=!1,s=!1){const{props:r,ref:i,patchFlag:o,children:l,transition:c}=e,f=t?$c(r||{},t):r,a={__v_isVNode:!0,__v_skip:!0,type:e.type,props:f,key:f&&yo(f),ref:t&&t.ref?n&&i?W(i)?i.concat(xn(t)):[i,xn(t)]:xn(t):i,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!==xe?o===-1?16:o|16:o,dynamicProps:e.dynamicProps,dynamicChildren:e.dynamicChildren,appContext:e.appContext,dirs:e.dirs,transition:c,component:e.component,suspense:e.suspense,ssContent:e.ssContent&&nt(e.ssContent),ssFallback:e.ssFallback&&nt(e.ssFallback),el:e.el,anchor:e.anchor,ctx:e.ctx,ce:e.ce};return c&&s&&Yt(a,c.clone(a)),a}function _o(e=" ",t=0){return ce(gt,null,e,t)}function Mf(e,t){const n=ce(kt,null,e);return n.staticCount=t,n}function Pf(e="",t=!1){return t?(Os(),Ms(ve,null,e)):ce(ve,null,e)}function Me(e){return e==null||typeof e=="boolean"?ce(ve):W(e)?ce(xe,null,e.slice()):zt(e)?et(e):ce(gt,null,String(e))}function et(e){return e.el===null&&e.patchFlag!==-1||e.memo?e:nt(e)}function er(e,t){let n=0;const{shapeFlag:s}=e;if(t==null)t=null;else if(W(t))n=16;else if(typeof t=="object")if(s&65){const r=t.default;r&&(r._c&&(r._d=!1),er(e,r()),r._c&&(r._d=!0));return}else{n=32;const r=t._;!r&&!eo(t)?t._ctx=de:r===3&&de&&(de.slots._===1?t._=1:(t._=2,e.patchFlag|=1024))}else q(t)?(t={default:t,_ctx:de},n=32):(t=String(t),s&64?(n=16,t=[_o(t)]):n=8);e.children=t,e.shapeFlag|=n}function $c(...e){const t={};for(let n=0;nue||de;let Ln,Ps;{const e=Hn(),t=(n,s)=>{let r;return(r=e[n])||(r=e[n]=[]),r.push(s),i=>{r.length>1?r.forEach(o=>o(i)):r[0](i)}};Ln=t("__VUE_INSTANCE_SETTERS__",n=>ue=n),Ps=t("__VUE_SSR_SETTERS__",n=>Mt=n)}const rn=e=>{const t=ue;return Ln(e),e.scope.on(),()=>{e.scope.off(),Ln(t)}},Rr=()=>{ue&&ue.scope.off(),Ln(null)};function bo(e){return e.vnode.shapeFlag&4}let Mt=!1;function Uc(e,t=!1,n=!1){t&&Ps(t);const{props:s,children:r}=e.vnode,i=bo(e);yc(e,s,i,t),wc(e,r,n);const o=i?kc(e,t):void 0;return t&&Ps(!1),o}function kc(e,t){const n=e.type;e.accessCache=Object.create(null),e.proxy=new Proxy(e.ctx,lc);const{setup:s}=n;if(s){rt();const r=e.setupContext=s.length>1?So(e):null,i=rn(e),o=tn(s,e,0,[e.props,r]),l=oi(o);if(it(),i(),(l||e.sp)&&!pt(e)&&Xs(e),l){if(o.then(Rr,Rr),t)return o.then(c=>{Or(e,c,t)}).catch(c=>{nn(c,e,0)});e.asyncDep=o}else Or(e,o,t)}else wo(e,t)}function Or(e,t,n){q(t)?e.type.__ssrInlineRender?e.ssrRender=t:e.render=t:ne(t)&&(e.setupState=Mi(t)),wo(e,n)}let Mr;function wo(e,t,n){const s=e.type;if(!e.render){if(!t&&Mr&&!s.render){const r=s.template||Js(e).template;if(r){const{isCustomElement:i,compilerOptions:o}=e.appContext.config,{delimiters:l,compilerOptions:c}=s,f=ae(ae({isCustomElement:i,delimiters:l},o),c);s.render=Mr(r,f)}}e.render=s.render||ke}{const r=rn(e);rt();try{ac(e)}finally{it(),r()}}}const Bc={get(e,t){return me(e,"get",""),e[t]}};function So(e){const t=n=>{e.exposed=n||{}};return{attrs:new Proxy(e.attrs,Bc),slots:e.slots,emit:e.emit,expose:t}}function Gn(e){return e.exposed?e.exposeProxy||(e.exposeProxy=new Proxy(Mi(wn(e.exposed)),{get(t,n){if(n in t)return t[n];if(n in Ut)return Ut[n](e)},has(t,n){return n in t||n in Ut}})):e.proxy}function Wc(e,t=!0){return q(e)?e.displayName||e.name:e.name||t&&e.__name}function Kc(e){return q(e)&&"__vccOpts"in e}const ie=(e,t)=>Fl(e,t,Mt);function Ls(e,t,n){const s=arguments.length;return s===2?ne(t)&&!W(t)?zt(t)?ce(e,null,[t]):ce(e,t):ce(e,null,t):(s>3?n=Array.prototype.slice.call(arguments,2):s===3&&zt(n)&&(n=[n]),ce(e,t,n))}const qc="3.5.13";/** +* @vue/runtime-dom v3.5.13 +* (c) 2018-present Yuxi (Evan) You and Vue contributors +* @license MIT +**/let Is;const Pr=typeof window<"u"&&window.trustedTypes;if(Pr)try{Is=Pr.createPolicy("vue",{createHTML:e=>e})}catch{}const xo=Is?e=>Is.createHTML(e):e=>e,Gc="http://www.w3.org/2000/svg",Yc="http://www.w3.org/1998/Math/MathML",qe=typeof document<"u"?document:null,Lr=qe&&qe.createElement("template"),Xc={insert:(e,t,n)=>{t.insertBefore(e,n||null)},remove:e=>{const t=e.parentNode;t&&t.removeChild(e)},createElement:(e,t,n,s)=>{const r=t==="svg"?qe.createElementNS(Gc,e):t==="mathml"?qe.createElementNS(Yc,e):n?qe.createElement(e,{is:n}):qe.createElement(e);return e==="select"&&s&&s.multiple!=null&&r.setAttribute("multiple",s.multiple),r},createText:e=>qe.createTextNode(e),createComment:e=>qe.createComment(e),setText:(e,t)=>{e.nodeValue=t},setElementText:(e,t)=>{e.textContent=t},parentNode:e=>e.parentNode,nextSibling:e=>e.nextSibling,querySelector:e=>qe.querySelector(e),setScopeId(e,t){e.setAttribute(t,"")},insertStaticContent(e,t,n,s,r,i){const o=n?n.previousSibling:t.lastChild;if(r&&(r===i||r.nextSibling))for(;t.insertBefore(r.cloneNode(!0),n),!(r===i||!(r=r.nextSibling)););else{Lr.innerHTML=xo(s==="svg"?`${e}`:s==="mathml"?`${e}`:e);const l=Lr.content;if(s==="svg"||s==="mathml"){const c=l.firstChild;for(;c.firstChild;)l.appendChild(c.firstChild);l.removeChild(c)}t.insertBefore(l,n)}return[o?o.nextSibling:t.firstChild,n?n.previousSibling:t.lastChild]}},ze="transition",Ht="animation",Qt=Symbol("_vtc"),Eo={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},Jc=ae({},ji,Eo),zc=e=>(e.displayName="Transition",e.props=Jc,e),Lf=zc((e,{slots:t})=>Ls(Kl,Qc(e),t)),ct=(e,t=[])=>{W(e)?e.forEach(n=>n(...t)):e&&e(...t)},Ir=e=>e?W(e)?e.some(t=>t.length>1):e.length>1:!1;function Qc(e){const t={};for(const x in e)x in Eo||(t[x]=e[x]);if(e.css===!1)return t;const{name:n="v",type:s,duration:r,enterFromClass:i=`${n}-enter-from`,enterActiveClass:o=`${n}-enter-active`,enterToClass:l=`${n}-enter-to`,appearFromClass:c=i,appearActiveClass:f=o,appearToClass:a=l,leaveFromClass:h=`${n}-leave-from`,leaveActiveClass:y=`${n}-leave-active`,leaveToClass:v=`${n}-leave-to`}=e,S=Zc(r),_=S&&S[0],K=S&&S[1],{onBeforeEnter:N,onEnter:j,onEnterCancelled:p,onLeave:g,onLeaveCancelled:O,onBeforeAppear:F=N,onAppear:$=j,onAppearCancelled:V=p}=t,R=(x,B,se,le)=>{x._enterCancelled=le,at(x,B?a:l),at(x,B?f:o),se&&se()},b=(x,B)=>{x._isLeaving=!1,at(x,h),at(x,v),at(x,y),B&&B()},I=x=>(B,se)=>{const le=x?$:j,U=()=>R(B,x,se);ct(le,[B,U]),Nr(()=>{at(B,x?c:i),Ke(B,x?a:l),Ir(le)||Fr(B,s,_,U)})};return ae(t,{onBeforeEnter(x){ct(N,[x]),Ke(x,i),Ke(x,o)},onBeforeAppear(x){ct(F,[x]),Ke(x,c),Ke(x,f)},onEnter:I(!1),onAppear:I(!0),onLeave(x,B){x._isLeaving=!0;const se=()=>b(x,B);Ke(x,h),x._enterCancelled?(Ke(x,y),Dr()):(Dr(),Ke(x,y)),Nr(()=>{x._isLeaving&&(at(x,h),Ke(x,v),Ir(g)||Fr(x,s,K,se))}),ct(g,[x,se])},onEnterCancelled(x){R(x,!1,void 0,!0),ct(p,[x])},onAppearCancelled(x){R(x,!0,void 0,!0),ct(V,[x])},onLeaveCancelled(x){b(x),ct(O,[x])}})}function Zc(e){if(e==null)return null;if(ne(e))return[os(e.enter),os(e.leave)];{const t=os(e);return[t,t]}}function os(e){return Jo(e)}function Ke(e,t){t.split(/\s+/).forEach(n=>n&&e.classList.add(n)),(e[Qt]||(e[Qt]=new Set)).add(t)}function at(e,t){t.split(/\s+/).forEach(s=>s&&e.classList.remove(s));const n=e[Qt];n&&(n.delete(t),n.size||(e[Qt]=void 0))}function Nr(e){requestAnimationFrame(()=>{requestAnimationFrame(e)})}let ea=0;function Fr(e,t,n,s){const r=e._endId=++ea,i=()=>{r===e._endId&&s()};if(n!=null)return setTimeout(i,n);const{type:o,timeout:l,propCount:c}=ta(e,t);if(!o)return s();const f=o+"end";let a=0;const h=()=>{e.removeEventListener(f,y),i()},y=v=>{v.target===e&&++a>=c&&h()};setTimeout(()=>{a(n[S]||"").split(", "),r=s(`${ze}Delay`),i=s(`${ze}Duration`),o=Hr(r,i),l=s(`${Ht}Delay`),c=s(`${Ht}Duration`),f=Hr(l,c);let a=null,h=0,y=0;t===ze?o>0&&(a=ze,h=o,y=i.length):t===Ht?f>0&&(a=Ht,h=f,y=c.length):(h=Math.max(o,f),a=h>0?o>f?ze:Ht:null,y=a?a===ze?i.length:c.length:0);const v=a===ze&&/\b(transform|all)(,|$)/.test(s(`${ze}Property`).toString());return{type:a,timeout:h,propCount:y,hasTransform:v}}function Hr(e,t){for(;e.length$r(n)+$r(e[s])))}function $r(e){return e==="auto"?0:Number(e.slice(0,-1).replace(",","."))*1e3}function Dr(){return document.body.offsetHeight}function na(e,t,n){const s=e[Qt];s&&(t=(t?[t,...s]:[...s]).join(" ")),t==null?e.removeAttribute("class"):n?e.setAttribute("class",t):e.className=t}const jr=Symbol("_vod"),sa=Symbol("_vsh"),ra=Symbol(""),ia=/(^|;)\s*display\s*:/;function oa(e,t,n){const s=e.style,r=re(n);let i=!1;if(n&&!r){if(t)if(re(t))for(const o of t.split(";")){const l=o.slice(0,o.indexOf(":")).trim();n[l]==null&&En(s,l,"")}else for(const o in t)n[o]==null&&En(s,o,"");for(const o in n)o==="display"&&(i=!0),En(s,o,n[o])}else if(r){if(t!==n){const o=s[ra];o&&(n+=";"+o),s.cssText=n,i=ia.test(n)}}else t&&e.removeAttribute("style");jr in e&&(e[jr]=i?s.display:"",e[sa]&&(s.display="none"))}const Vr=/\s*!important$/;function En(e,t,n){if(W(n))n.forEach(s=>En(e,t,s));else if(n==null&&(n=""),t.startsWith("--"))e.setProperty(t,n);else{const s=la(e,t);Vr.test(n)?e.setProperty(st(s),n.replace(Vr,""),"important"):e[s]=n}}const Ur=["Webkit","Moz","ms"],ls={};function la(e,t){const n=ls[t];if(n)return n;let s=Le(t);if(s!=="filter"&&s in e)return ls[t]=s;s=Fn(s);for(let r=0;rcs||(ua.then(()=>cs=0),cs=Date.now());function ha(e,t){const n=s=>{if(!s._vts)s._vts=Date.now();else if(s._vts<=n.attached)return;He(pa(s,n.value),t,5,[s])};return n.value=e,n.attached=da(),n}function pa(e,t){if(W(t)){const n=e.stopImmediatePropagation;return e.stopImmediatePropagation=()=>{n.call(e),e._stopped=!0},t.map(s=>r=>!r._stopped&&s&&s(r))}else return t}const Gr=e=>e.charCodeAt(0)===111&&e.charCodeAt(1)===110&&e.charCodeAt(2)>96&&e.charCodeAt(2)<123,ga=(e,t,n,s,r,i)=>{const o=r==="svg";t==="class"?na(e,s,o):t==="style"?oa(e,n,s):en(t)?Fs(t)||aa(e,t,n,s,i):(t[0]==="."?(t=t.slice(1),!0):t[0]==="^"?(t=t.slice(1),!1):ma(e,t,s,o))?(Wr(e,t,s),!e.tagName.includes("-")&&(t==="value"||t==="checked"||t==="selected")&&Br(e,t,s,o,i,t!=="value")):e._isVueCE&&(/[A-Z]/.test(t)||!re(s))?Wr(e,Le(t),s,i,t):(t==="true-value"?e._trueValue=s:t==="false-value"&&(e._falseValue=s),Br(e,t,s,o))};function ma(e,t,n,s){if(s)return!!(t==="innerHTML"||t==="textContent"||t in e&&Gr(t)&&q(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 r=e.tagName;if(r==="IMG"||r==="VIDEO"||r==="CANVAS"||r==="SOURCE")return!1}return Gr(t)&&re(n)?!1:t in e}const Yr=e=>{const t=e.props["onUpdate:modelValue"]||!1;return W(t)?n=>bn(t,n):t};function ya(e){e.target.composing=!0}function Xr(e){const t=e.target;t.composing&&(t.composing=!1,t.dispatchEvent(new Event("input")))}const as=Symbol("_assign"),If={created(e,{modifiers:{lazy:t,trim:n,number:s}},r){e[as]=Yr(r);const i=s||r.props&&r.props.type==="number";St(e,t?"change":"input",o=>{if(o.target.composing)return;let l=e.value;n&&(l=l.trim()),i&&(l=vs(l)),e[as](l)}),n&&St(e,"change",()=>{e.value=e.value.trim()}),t||(St(e,"compositionstart",ya),St(e,"compositionend",Xr),St(e,"change",Xr))},mounted(e,{value:t}){e.value=t??""},beforeUpdate(e,{value:t,oldValue:n,modifiers:{lazy:s,trim:r,number:i}},o){if(e[as]=Yr(o),e.composing)return;const l=(i||e.type==="number")&&!/^0\d/.test(e.value)?vs(e.value):e.value,c=t??"";l!==c&&(document.activeElement===e&&e.type!=="range"&&(s&&t===n||r&&e.value.trim()===c)||(e.value=c))}},va=["ctrl","shift","alt","meta"],_a={stop:e=>e.stopPropagation(),prevent:e=>e.preventDefault(),self:e=>e.target!==e.currentTarget,ctrl:e=>!e.ctrlKey,shift:e=>!e.shiftKey,alt:e=>!e.altKey,meta:e=>!e.metaKey,left:e=>"button"in e&&e.button!==0,middle:e=>"button"in e&&e.button!==1,right:e=>"button"in e&&e.button!==2,exact:(e,t)=>va.some(n=>e[`${n}Key`]&&!t.includes(n))},Nf=(e,t)=>{const n=e._withMods||(e._withMods={}),s=t.join(".");return n[s]||(n[s]=(r,...i)=>{for(let o=0;o{const n=e._withKeys||(e._withKeys={}),s=t.join(".");return n[s]||(n[s]=r=>{if(!("key"in r))return;const i=st(r.key);if(t.some(o=>o===i||ba[o]===i))return e(r)})},To=ae({patchProp:ga},Xc);let Wt,Jr=!1;function wa(){return Wt||(Wt=xc(To))}function Sa(){return Wt=Jr?Wt:Ec(To),Jr=!0,Wt}const Hf=(...e)=>{const t=wa().createApp(...e),{mount:n}=t;return t.mount=s=>{const r=Ao(s);if(!r)return;const i=t._component;!q(i)&&!i.render&&!i.template&&(i.template=r.innerHTML),r.nodeType===1&&(r.textContent="");const o=n(r,!1,Co(r));return r instanceof Element&&(r.removeAttribute("v-cloak"),r.setAttribute("data-v-app","")),o},t},$f=(...e)=>{const t=Sa().createApp(...e),{mount:n}=t;return t.mount=s=>{const r=Ao(s);if(r)return n(r,!0,Co(r))},t};function Co(e){if(e instanceof SVGElement)return"svg";if(typeof MathMLElement=="function"&&e instanceof MathMLElement)return"mathml"}function Ao(e){return re(e)?document.querySelector(e):e}const Df=(e,t)=>{const n=e.__vccOpts||e;for(const[s,r]of t)n[s]=r;return n},xa=window.__VP_SITE_DATA__;function tr(e){return hi()?(il(e),!0):!1}function Be(e){return typeof e=="function"?e():Oi(e)}const Ro=typeof window<"u"&&typeof document<"u";typeof WorkerGlobalScope<"u"&&globalThis instanceof WorkerGlobalScope;const jf=e=>e!=null,Ea=Object.prototype.toString,Ta=e=>Ea.call(e)==="[object Object]",Zt=()=>{},zr=Ca();function Ca(){var e,t;return Ro&&((e=window==null?void 0:window.navigator)==null?void 0:e.userAgent)&&(/iP(?:ad|hone|od)/.test(window.navigator.userAgent)||((t=window==null?void 0:window.navigator)==null?void 0:t.maxTouchPoints)>2&&/iPad|Macintosh/.test(window==null?void 0:window.navigator.userAgent))}function Aa(e,t){function n(...s){return new Promise((r,i)=>{Promise.resolve(e(()=>t.apply(this,s),{fn:t,thisArg:this,args:s})).then(r).catch(i)})}return n}const Oo=e=>e();function Ra(e,t={}){let n,s,r=Zt;const i=l=>{clearTimeout(l),r(),r=Zt};return l=>{const c=Be(e),f=Be(t.maxWait);return n&&i(n),c<=0||f!==void 0&&f<=0?(s&&(i(s),s=null),Promise.resolve(l())):new Promise((a,h)=>{r=t.rejectOnCancel?h:a,f&&!s&&(s=setTimeout(()=>{n&&i(n),s=null,a(l())},f)),n=setTimeout(()=>{s&&i(s),s=null,a(l())},c)})}}function Oa(e=Oo){const t=oe(!0);function n(){t.value=!1}function s(){t.value=!0}const r=(...i)=>{t.value&&e(...i)};return{isActive:Vn(t),pause:n,resume:s,eventFilter:r}}function Ma(e){return qn()}function Mo(...e){if(e.length!==1)return Ll(...e);const t=e[0];return typeof t=="function"?Vn(Ol(()=>({get:t,set:Zt}))):oe(t)}function Po(e,t,n={}){const{eventFilter:s=Oo,...r}=n;return Fe(e,Aa(s,t),r)}function Pa(e,t,n={}){const{eventFilter:s,...r}=n,{eventFilter:i,pause:o,resume:l,isActive:c}=Oa(s);return{stop:Po(e,t,{...r,eventFilter:i}),pause:o,resume:l,isActive:c}}function nr(e,t=!0,n){Ma()?Lt(e,n):t?e():Un(e)}function Vf(e,t,n={}){const{debounce:s=0,maxWait:r=void 0,...i}=n;return Po(e,t,{...i,eventFilter:Ra(s,{maxWait:r})})}function Uf(e,t,n){let s;fe(n)?s={evaluating:n}:s={};const{lazy:r=!1,evaluating:i=void 0,shallow:o=!0,onError:l=Zt}=s,c=oe(!r),f=o?qs(t):oe(t);let a=0;return Zs(async h=>{if(!c.value)return;a++;const y=a;let v=!1;i&&Promise.resolve().then(()=>{i.value=!0});try{const S=await e(_=>{h(()=>{i&&(i.value=!1),v||_()})});y===a&&(f.value=S)}catch(S){l(S)}finally{i&&y===a&&(i.value=!1),v=!0}}),r?ie(()=>(c.value=!0,f.value)):f}const $e=Ro?window:void 0;function Lo(e){var t;const n=Be(e);return(t=n==null?void 0:n.$el)!=null?t:n}function Pt(...e){let t,n,s,r;if(typeof e[0]=="string"||Array.isArray(e[0])?([n,s,r]=e,t=$e):[t,n,s,r]=e,!t)return Zt;Array.isArray(n)||(n=[n]),Array.isArray(s)||(s=[s]);const i=[],o=()=>{i.forEach(a=>a()),i.length=0},l=(a,h,y,v)=>(a.addEventListener(h,y,v),()=>a.removeEventListener(h,y,v)),c=Fe(()=>[Lo(t),Be(r)],([a,h])=>{if(o(),!a)return;const y=Ta(h)?{...h}:h;i.push(...n.flatMap(v=>s.map(S=>l(a,v,S,y))))},{immediate:!0,flush:"post"}),f=()=>{c(),o()};return tr(f),f}function La(e){return typeof e=="function"?e:typeof e=="string"?t=>t.key===e:Array.isArray(e)?t=>e.includes(t.key):()=>!0}function kf(...e){let t,n,s={};e.length===3?(t=e[0],n=e[1],s=e[2]):e.length===2?typeof e[1]=="object"?(t=!0,n=e[0],s=e[1]):(t=e[0],n=e[1]):(t=!0,n=e[0]);const{target:r=$e,eventName:i="keydown",passive:o=!1,dedupe:l=!1}=s,c=La(t);return Pt(r,i,a=>{a.repeat&&Be(l)||c(a)&&n(a)},o)}function Ia(){const e=oe(!1),t=qn();return t&&Lt(()=>{e.value=!0},t),e}function Na(e){const t=Ia();return ie(()=>(t.value,!!e()))}function Io(e,t={}){const{window:n=$e}=t,s=Na(()=>n&&"matchMedia"in n&&typeof n.matchMedia=="function");let r;const i=oe(!1),o=f=>{i.value=f.matches},l=()=>{r&&("removeEventListener"in r?r.removeEventListener("change",o):r.removeListener(o))},c=Zs(()=>{s.value&&(l(),r=n.matchMedia(Be(e)),"addEventListener"in r?r.addEventListener("change",o):r.addListener(o),i.value=r.matches)});return tr(()=>{c(),l(),r=void 0}),i}const gn=typeof globalThis<"u"?globalThis:typeof window<"u"?window:typeof global<"u"?global:typeof self<"u"?self:{},mn="__vueuse_ssr_handlers__",Fa=Ha();function Ha(){return mn in gn||(gn[mn]=gn[mn]||{}),gn[mn]}function No(e,t){return Fa[e]||t}function sr(e){return Io("(prefers-color-scheme: dark)",e)}function $a(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 Da={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()}},Qr="vueuse-storage";function rr(e,t,n,s={}){var r;const{flush:i="pre",deep:o=!0,listenToStorageChanges:l=!0,writeDefaults:c=!0,mergeDefaults:f=!1,shallow:a,window:h=$e,eventFilter:y,onError:v=b=>{console.error(b)},initOnMounted:S}=s,_=(a?qs:oe)(typeof t=="function"?t():t);if(!n)try{n=No("getDefaultStorage",()=>{var b;return(b=$e)==null?void 0:b.localStorage})()}catch(b){v(b)}if(!n)return _;const K=Be(t),N=$a(K),j=(r=s.serializer)!=null?r:Da[N],{pause:p,resume:g}=Pa(_,()=>F(_.value),{flush:i,deep:o,eventFilter:y});h&&l&&nr(()=>{n instanceof Storage?Pt(h,"storage",V):Pt(h,Qr,R),S&&V()}),S||V();function O(b,I){if(h){const x={key:e,oldValue:b,newValue:I,storageArea:n};h.dispatchEvent(n instanceof Storage?new StorageEvent("storage",x):new CustomEvent(Qr,{detail:x}))}}function F(b){try{const I=n.getItem(e);if(b==null)O(I,null),n.removeItem(e);else{const x=j.write(b);I!==x&&(n.setItem(e,x),O(I,x))}}catch(I){v(I)}}function $(b){const I=b?b.newValue:n.getItem(e);if(I==null)return c&&K!=null&&n.setItem(e,j.write(K)),K;if(!b&&f){const x=j.read(I);return typeof f=="function"?f(x,K):N==="object"&&!Array.isArray(x)?{...K,...x}:x}else return typeof I!="string"?I:j.read(I)}function V(b){if(!(b&&b.storageArea!==n)){if(b&&b.key==null){_.value=K;return}if(!(b&&b.key!==e)){p();try{(b==null?void 0:b.newValue)!==j.write(_.value)&&(_.value=$(b))}catch(I){v(I)}finally{b?Un(g):g()}}}}function R(b){V(b.detail)}return _}const ja="*,*::before,*::after{-webkit-transition:none!important;-moz-transition:none!important;-o-transition:none!important;-ms-transition:none!important;transition:none!important}";function Va(e={}){const{selector:t="html",attribute:n="class",initialValue:s="auto",window:r=$e,storage:i,storageKey:o="vueuse-color-scheme",listenToStorageChanges:l=!0,storageRef:c,emitAuto:f,disableTransition:a=!0}=e,h={auto:"",light:"light",dark:"dark",...e.modes||{}},y=sr({window:r}),v=ie(()=>y.value?"dark":"light"),S=c||(o==null?Mo(s):rr(o,s,i,{window:r,listenToStorageChanges:l})),_=ie(()=>S.value==="auto"?v.value:S.value),K=No("updateHTMLAttrs",(g,O,F)=>{const $=typeof g=="string"?r==null?void 0:r.document.querySelector(g):Lo(g);if(!$)return;const V=new Set,R=new Set;let b=null;if(O==="class"){const x=F.split(/\s/g);Object.values(h).flatMap(B=>(B||"").split(/\s/g)).filter(Boolean).forEach(B=>{x.includes(B)?V.add(B):R.add(B)})}else b={key:O,value:F};if(V.size===0&&R.size===0&&b===null)return;let I;a&&(I=r.document.createElement("style"),I.appendChild(document.createTextNode(ja)),r.document.head.appendChild(I));for(const x of V)$.classList.add(x);for(const x of R)$.classList.remove(x);b&&$.setAttribute(b.key,b.value),a&&(r.getComputedStyle(I).opacity,document.head.removeChild(I))});function N(g){var O;K(t,n,(O=h[g])!=null?O:g)}function j(g){e.onChanged?e.onChanged(g,N):N(g)}Fe(_,j,{flush:"post",immediate:!0}),nr(()=>j(_.value));const p=ie({get(){return f?S.value:_.value},set(g){S.value=g}});try{return Object.assign(p,{store:S,system:v,state:_})}catch{return p}}function Ua(e={}){const{valueDark:t="dark",valueLight:n="",window:s=$e}=e,r=Va({...e,onChanged:(l,c)=>{var f;e.onChanged?(f=e.onChanged)==null||f.call(e,l==="dark",c,l):c(l)},modes:{dark:t,light:n}}),i=ie(()=>r.system?r.system.value:sr({window:s}).value?"dark":"light");return ie({get(){return r.value==="dark"},set(l){const c=l?"dark":"light";i.value===c?r.value="auto":r.value=c}})}function fs(e){return typeof Window<"u"&&e instanceof Window?e.document.documentElement:typeof Document<"u"&&e instanceof Document?e.documentElement:e}function Bf(e,t,n={}){const{window:s=$e}=n;return rr(e,t,s==null?void 0:s.localStorage,n)}function Fo(e){const t=window.getComputedStyle(e);if(t.overflowX==="scroll"||t.overflowY==="scroll"||t.overflowX==="auto"&&e.clientWidth1?!0:(t.preventDefault&&t.preventDefault(),!1)}const us=new WeakMap;function Wf(e,t=!1){const n=oe(t);let s=null,r="";Fe(Mo(e),l=>{const c=fs(Be(l));if(c){const f=c;if(us.get(f)||us.set(f,f.style.overflow),f.style.overflow!=="hidden"&&(r=f.style.overflow),f.style.overflow==="hidden")return n.value=!0;if(n.value)return f.style.overflow="hidden"}},{immediate:!0});const i=()=>{const l=fs(Be(e));!l||n.value||(zr&&(s=Pt(l,"touchmove",c=>{ka(c)},{passive:!1})),l.style.overflow="hidden",n.value=!0)},o=()=>{const l=fs(Be(e));!l||!n.value||(zr&&(s==null||s()),l.style.overflow=r,us.delete(l),n.value=!1)};return tr(o),ie({get(){return n.value},set(l){l?i():o()}})}function Kf(e,t,n={}){const{window:s=$e}=n;return rr(e,t,s==null?void 0:s.sessionStorage,n)}function qf(e={}){const{window:t=$e,behavior:n="auto"}=e;if(!t)return{x:oe(0),y:oe(0)};const s=oe(t.scrollX),r=oe(t.scrollY),i=ie({get(){return s.value},set(l){scrollTo({left:l,behavior:n})}}),o=ie({get(){return r.value},set(l){scrollTo({top:l,behavior:n})}});return Pt(t,"scroll",()=>{s.value=t.scrollX,r.value=t.scrollY},{capture:!1,passive:!0}),{x:i,y:o}}function Gf(e={}){const{window:t=$e,initialWidth:n=Number.POSITIVE_INFINITY,initialHeight:s=Number.POSITIVE_INFINITY,listenOrientation:r=!0,includeScrollbar:i=!0,type:o="inner"}=e,l=oe(n),c=oe(s),f=()=>{t&&(o==="outer"?(l.value=t.outerWidth,c.value=t.outerHeight):i?(l.value=t.innerWidth,c.value=t.innerHeight):(l.value=t.document.documentElement.clientWidth,c.value=t.document.documentElement.clientHeight))};if(f(),nr(f),Pt("resize",f,{passive:!0}),r){const a=Io("(orientation: portrait)");Fe(a,()=>f())}return{width:l,height:c}}const ds={BASE_URL:"/",DEV:!1,MODE:"production",PROD:!0,SSR:!1};var hs={};const Ho=/^(?:[a-z]+:|\/\/)/i,Ba="vitepress-theme-appearance",Wa=/#.*$/,Ka=/[?#].*$/,qa=/(?:(^|\/)index)?\.(?:md|html)$/,ge=typeof document<"u",$o={relativePath:"404.md",filePath:"",title:"404",description:"Not Found",headers:[],frontmatter:{sidebar:!1,layout:"page"},lastUpdated:0,isNotFound:!0};function Ga(e,t,n=!1){if(t===void 0)return!1;if(e=Zr(`/${e}`),n)return new RegExp(t).test(e);if(Zr(t)!==e)return!1;const s=t.match(Wa);return s?(ge?location.hash:"")===s[0]:!0}function Zr(e){return decodeURI(e).replace(Ka,"").replace(qa,"$1")}function Ya(e){return Ho.test(e)}function Xa(e,t){return Object.keys((e==null?void 0:e.locales)||{}).find(n=>n!=="root"&&!Ya(n)&&Ga(t,`/${n}/`,!0))||"root"}function Ja(e,t){var s,r,i,o,l,c,f;const n=Xa(e,t);return Object.assign({},e,{localeIndex:n,lang:((s=e.locales[n])==null?void 0:s.lang)??e.lang,dir:((r=e.locales[n])==null?void 0:r.dir)??e.dir,title:((i=e.locales[n])==null?void 0:i.title)??e.title,titleTemplate:((o=e.locales[n])==null?void 0:o.titleTemplate)??e.titleTemplate,description:((l=e.locales[n])==null?void 0:l.description)??e.description,head:jo(e.head,((c=e.locales[n])==null?void 0:c.head)??[]),themeConfig:{...e.themeConfig,...(f=e.locales[n])==null?void 0:f.themeConfig}})}function Do(e,t){const n=t.title||e.title,s=t.titleTemplate??e.titleTemplate;if(typeof s=="string"&&s.includes(":title"))return s.replace(/:title/g,n);const r=za(e.title,s);return n===r.slice(3)?n:`${n}${r}`}function za(e,t){return t===!1?"":t===!0||t===void 0?` | ${e}`:e===t?"":` | ${t}`}function Qa(e,t){const[n,s]=t;if(n!=="meta")return!1;const r=Object.entries(s)[0];return r==null?!1:e.some(([i,o])=>i===n&&o[r[0]]===r[1])}function jo(e,t){return[...e.filter(n=>!Qa(t,n)),...t]}const Za=/[\u0000-\u001F"#$&*+,:;<=>?[\]^`{|}\u007F]/g,ef=/^[a-z]:/i;function ei(e){const t=ef.exec(e),n=t?t[0]:"";return n+e.slice(n.length).replace(Za,"_").replace(/(^|\/)_+(?=[^/]*$)/,"$1")}const ps=new Set;function tf(e){if(ps.size===0){const n=typeof process=="object"&&(hs==null?void 0:hs.VITE_EXTRA_EXTENSIONS)||(ds==null?void 0:ds.VITE_EXTRA_EXTENSIONS)||"";("3g2,3gp,aac,ai,apng,au,avif,bin,bmp,cer,class,conf,crl,css,csv,dll,doc,eps,epub,exe,gif,gz,ics,ief,jar,jpe,jpeg,jpg,js,json,jsonld,m4a,man,mid,midi,mjs,mov,mp2,mp3,mp4,mpe,mpeg,mpg,mpp,oga,ogg,ogv,ogx,opus,otf,p10,p7c,p7m,p7s,pdf,png,ps,qt,roff,rtf,rtx,ser,svg,t,tif,tiff,tr,ts,tsv,ttf,txt,vtt,wav,weba,webm,webp,woff,woff2,xhtml,xml,yaml,yml,zip"+(n&&typeof n=="string"?","+n:"")).split(",").forEach(s=>ps.add(s))}const t=e.split(".").pop();return t==null||!ps.has(t.toLowerCase())}function Yf(e){return e.replace(/[|\\{}()[\]^$+*?.]/g,"\\$&").replace(/-/g,"\\x2d")}const nf=Symbol(),mt=qs(xa);function Xf(e){const t=ie(()=>Ja(mt.value,e.data.relativePath)),n=t.value.appearance,s=n==="force-dark"?oe(!0):n==="force-auto"?sr():n?Ua({storageKey:Ba,initialValue:()=>n==="dark"?"dark":"auto",...typeof n=="object"?n:{}}):oe(!1),r=oe(ge?location.hash:"");return ge&&window.addEventListener("hashchange",()=>{r.value=location.hash}),Fe(()=>e.data,()=>{r.value=ge?location.hash:""}),{site:t,theme:ie(()=>t.value.themeConfig),page:ie(()=>e.data),frontmatter:ie(()=>e.data.frontmatter),params:ie(()=>e.data.params),lang:ie(()=>t.value.lang),dir:ie(()=>e.data.frontmatter.dir||t.value.dir),localeIndex:ie(()=>t.value.localeIndex||"root"),title:ie(()=>Do(t.value,e.data)),description:ie(()=>e.data.description||t.value.description),isDark:s,hash:ie(()=>r.value)}}function sf(){const e=Ot(nf);if(!e)throw new Error("vitepress data not properly injected in app");return e}function rf(e,t){return`${e}${t}`.replace(/\/+/g,"/")}function ti(e){return Ho.test(e)||!e.startsWith("/")?e:rf(mt.value.base,e)}function of(e){let t=e.replace(/\.html$/,"");if(t=decodeURIComponent(t),t=t.replace(/\/$/,"/index"),ge){const n="/";t=ei(t.slice(n.length).replace(/\//g,"_")||"index")+".md";let s=__VP_HASH_MAP__[t.toLowerCase()];if(s||(t=t.endsWith("_index.md")?t.slice(0,-9)+".md":t.slice(0,-3)+"_index.md",s=__VP_HASH_MAP__[t.toLowerCase()]),!s)return null;t=`${n}assets/${t}.${s}.js`}else t=`./${ei(t.slice(1).replace(/\//g,"_"))}.md.js`;return t}let Tn=[];function Jf(e){Tn.push(e),Bn(()=>{Tn=Tn.filter(t=>t!==e)})}function lf(){let e=mt.value.scrollOffset,t=0,n=24;if(typeof e=="object"&&"padding"in e&&(n=e.padding,e=e.selector),typeof e=="number")t=e;else if(typeof e=="string")t=ni(e,n);else if(Array.isArray(e))for(const s of e){const r=ni(s,n);if(r){t=r;break}}return t}function ni(e,t){const n=document.querySelector(e);if(!n)return 0;const s=n.getBoundingClientRect().bottom;return s<0?0:s+t}const cf=Symbol(),Vo="http://a.com",af=()=>({path:"/",component:null,data:$o});function zf(e,t){const n=jn(af()),s={route:n,go:r};async function r(l=ge?location.href:"/"){var c,f;l=gs(l),await((c=s.onBeforeRouteChange)==null?void 0:c.call(s,l))!==!1&&(ge&&l!==gs(location.href)&&(history.replaceState({scrollPosition:window.scrollY},""),history.pushState({},"",l)),await o(l),await((f=s.onAfterRouteChanged)==null?void 0:f.call(s,l)))}let i=null;async function o(l,c=0,f=!1){var y,v;if(await((y=s.onBeforePageLoad)==null?void 0:y.call(s,l))===!1)return;const a=new URL(l,Vo),h=i=a.pathname;try{let S=await e(h);if(!S)throw new Error(`Page not found: ${h}`);if(i===h){i=null;const{default:_,__pageData:K}=S;if(!_)throw new Error(`Invalid route component: ${_}`);await((v=s.onAfterPageLoad)==null?void 0:v.call(s,l)),n.path=ge?h:ti(h),n.component=wn(_),n.data=wn(K),ge&&Un(()=>{let N=mt.value.base+K.relativePath.replace(/(?:(^|\/)index)?\.md$/,"$1");if(!mt.value.cleanUrls&&!N.endsWith("/")&&(N+=".html"),N!==a.pathname&&(a.pathname=N,l=N+a.search+a.hash,history.replaceState({},"",l)),a.hash&&!c){let j=null;try{j=document.getElementById(decodeURIComponent(a.hash).slice(1))}catch(p){console.warn(p)}if(j){si(j,a.hash);return}}window.scrollTo(0,c)})}}catch(S){if(!/fetch|Page not found/.test(S.message)&&!/^\/404(\.html|\/)?$/.test(l)&&console.error(S),!f)try{const _=await fetch(mt.value.base+"hashmap.json");window.__VP_HASH_MAP__=await _.json(),await o(l,c,!0);return}catch{}if(i===h){i=null,n.path=ge?h:ti(h),n.component=t?wn(t):null;const _=ge?h.replace(/(^|\/)$/,"$1index").replace(/(\.html)?$/,".md").replace(/^\//,""):"404.md";n.data={...$o,relativePath:_}}}}return ge&&(history.state===null&&history.replaceState({},""),window.addEventListener("click",l=>{if(l.defaultPrevented||!(l.target instanceof Element)||l.target.closest("button")||l.button!==0||l.ctrlKey||l.shiftKey||l.altKey||l.metaKey)return;const c=l.target.closest("a");if(!c||c.closest(".vp-raw")||c.hasAttribute("download")||c.hasAttribute("target"))return;const f=c.getAttribute("href")??(c instanceof SVGAElement?c.getAttribute("xlink:href"):null);if(f==null)return;const{href:a,origin:h,pathname:y,hash:v,search:S}=new URL(f,c.baseURI),_=new URL(location.href);h===_.origin&&tf(y)&&(l.preventDefault(),y===_.pathname&&S===_.search?(v!==_.hash&&(history.pushState({},"",a),window.dispatchEvent(new HashChangeEvent("hashchange",{oldURL:_.href,newURL:a}))),v?si(c,v,c.classList.contains("header-anchor")):window.scrollTo(0,0)):r(a))},{capture:!0}),window.addEventListener("popstate",async l=>{var c;l.state!==null&&(await o(gs(location.href),l.state&&l.state.scrollPosition||0),(c=s.onAfterRouteChanged)==null||c.call(s,location.href))}),window.addEventListener("hashchange",l=>{l.preventDefault()})),s}function ff(){const e=Ot(cf);if(!e)throw new Error("useRouter() is called without provider.");return e}function Uo(){return ff().route}function si(e,t,n=!1){let s=null;try{s=e.classList.contains("header-anchor")?e:document.getElementById(decodeURIComponent(t).slice(1))}catch(r){console.warn(r)}if(s){let r=function(){!n||Math.abs(o-window.scrollY)>window.innerHeight?window.scrollTo(0,o):window.scrollTo({left:0,top:o,behavior:"smooth"})};const i=parseInt(window.getComputedStyle(s).paddingTop,10),o=window.scrollY+s.getBoundingClientRect().top-lf()+i;requestAnimationFrame(r)}}function gs(e){const t=new URL(e,Vo);return t.pathname=t.pathname.replace(/(^|\/)index(\.html)?$/,"$1"),mt.value.cleanUrls?t.pathname=t.pathname.replace(/\.html$/,""):!t.pathname.endsWith("/")&&!t.pathname.endsWith(".html")&&(t.pathname+=".html"),t.pathname+t.search+t.hash}const yn=()=>Tn.forEach(e=>e()),Qf=Ys({name:"VitePressContent",props:{as:{type:[Object,String],default:"div"}},setup(e){const t=Uo(),{frontmatter:n,site:s}=sf();return Fe(n,yn,{deep:!0,flush:"post"}),()=>Ls(e.as,s.value.contentProps??{style:{position:"relative"}},[t.component?Ls(t.component,{onVnodeMounted:yn,onVnodeUpdated:yn,onVnodeUnmounted:yn}):"404 Page Not Found"])}}),uf="modulepreload",df=function(e){return"/"+e},ri={},Zf=function(t,n,s){let r=Promise.resolve();if(n&&n.length>0){document.getElementsByTagName("link");const o=document.querySelector("meta[property=csp-nonce]"),l=(o==null?void 0:o.nonce)||(o==null?void 0:o.getAttribute("nonce"));r=Promise.allSettled(n.map(c=>{if(c=df(c),c in ri)return;ri[c]=!0;const f=c.endsWith(".css"),a=f?'[rel="stylesheet"]':"";if(document.querySelector(`link[href="${c}"]${a}`))return;const h=document.createElement("link");if(h.rel=f?"stylesheet":uf,f||(h.as="script"),h.crossOrigin="",h.href=c,l&&h.setAttribute("nonce",l),document.head.appendChild(h),f)return new Promise((y,v)=>{h.addEventListener("load",y),h.addEventListener("error",()=>v(new Error(`Unable to preload CSS for ${c}`)))})}))}function i(o){const l=new Event("vite:preloadError",{cancelable:!0});if(l.payload=o,window.dispatchEvent(l),!l.defaultPrevented)throw o}return r.then(o=>{for(const l of o||[])l.status==="rejected"&&i(l.reason);return t().catch(i)})},eu=Ys({setup(e,{slots:t}){const n=oe(!1);return Lt(()=>{n.value=!0}),()=>n.value&&t.default?t.default():null}});function tu(){ge&&window.addEventListener("click",e=>{var n;const t=e.target;if(t.matches(".vp-code-group input")){const s=(n=t.parentElement)==null?void 0:n.parentElement;if(!s)return;const r=Array.from(s.querySelectorAll("input")).indexOf(t);if(r<0)return;const i=s.querySelector(".blocks");if(!i)return;const o=Array.from(i.children).find(f=>f.classList.contains("active"));if(!o)return;const l=i.children[r];if(!l||o===l)return;o.classList.remove("active"),l.classList.add("active");const c=s==null?void 0:s.querySelector(`label[for="${t.id}"]`);c==null||c.scrollIntoView({block:"nearest"})}})}function nu(){if(ge){const e=new WeakMap;window.addEventListener("click",t=>{var s;const n=t.target;if(n.matches('div[class*="language-"] > button.copy')){const r=n.parentElement,i=(s=n.nextElementSibling)==null?void 0:s.nextElementSibling;if(!r||!i)return;const o=/language-(shellscript|shell|bash|sh|zsh)/.test(r.className),l=[".vp-copy-ignore",".diff.remove"],c=i.cloneNode(!0);c.querySelectorAll(l.join(",")).forEach(a=>a.remove());let f=c.textContent||"";o&&(f=f.replace(/^ *(\$|>) /gm,"").trim()),hf(f).then(()=>{n.classList.add("copied"),clearTimeout(e.get(n));const a=setTimeout(()=>{n.classList.remove("copied"),n.blur(),e.delete(n)},2e3);e.set(n,a)})}})}}async function hf(e){try{return navigator.clipboard.writeText(e)}catch{const t=document.createElement("textarea"),n=document.activeElement;t.value=e,t.setAttribute("readonly",""),t.style.contain="strict",t.style.position="absolute",t.style.left="-9999px",t.style.fontSize="12pt";const s=document.getSelection(),r=s?s.rangeCount>0&&s.getRangeAt(0):null;document.body.appendChild(t),t.select(),t.selectionStart=0,t.selectionEnd=e.length,document.execCommand("copy"),document.body.removeChild(t),r&&(s.removeAllRanges(),s.addRange(r)),n&&n.focus()}}function su(e,t){let n=!0,s=[];const r=i=>{if(n){n=!1,i.forEach(l=>{const c=ms(l);for(const f of document.head.children)if(f.isEqualNode(c)){s.push(f);return}});return}const o=i.map(ms);s.forEach((l,c)=>{const f=o.findIndex(a=>a==null?void 0:a.isEqualNode(l??null));f!==-1?delete o[f]:(l==null||l.remove(),delete s[c])}),o.forEach(l=>l&&document.head.appendChild(l)),s=[...s,...o].filter(Boolean)};Zs(()=>{const i=e.data,o=t.value,l=i&&i.description,c=i&&i.frontmatter.head||[],f=Do(o,i);f!==document.title&&(document.title=f);const a=l||o.description;let h=document.querySelector("meta[name=description]");h?h.getAttribute("content")!==a&&h.setAttribute("content",a):ms(["meta",{name:"description",content:a}]),r(jo(o.head,gf(c)))})}function ms([e,t,n]){const s=document.createElement(e);for(const r in t)s.setAttribute(r,t[r]);return n&&(s.innerHTML=n),e==="script"&&t.async==null&&(s.async=!1),s}function pf(e){return e[0]==="meta"&&e[1]&&e[1].name==="description"}function gf(e){return e.filter(t=>!pf(t))}const ys=new Set,ko=()=>document.createElement("link"),mf=e=>{const t=ko();t.rel="prefetch",t.href=e,document.head.appendChild(t)},yf=e=>{const t=new XMLHttpRequest;t.open("GET",e,t.withCredentials=!0),t.send()};let vn;const vf=ge&&(vn=ko())&&vn.relList&&vn.relList.supports&&vn.relList.supports("prefetch")?mf:yf;function ru(){if(!ge||!window.IntersectionObserver)return;let e;if((e=navigator.connection)&&(e.saveData||/2g/.test(e.effectiveType)))return;const t=window.requestIdleCallback||setTimeout;let n=null;const s=()=>{n&&n.disconnect(),n=new IntersectionObserver(i=>{i.forEach(o=>{if(o.isIntersecting){const l=o.target;n.unobserve(l);const{pathname:c}=l;if(!ys.has(c)){ys.add(c);const f=of(c);f&&vf(f)}}})}),t(()=>{document.querySelectorAll("#app a").forEach(i=>{const{hostname:o,pathname:l}=new URL(i.href instanceof SVGAnimatedString?i.href.animVal:i.href,i.baseURI),c=l.match(/\.\w+$/);c&&c[0]!==".html"||i.target!=="_blank"&&o===location.hostname&&(l!==location.pathname?n.observe(i):ys.add(l))})})};Lt(s);const r=Uo();Fe(()=>r.path,s),Bn(()=>{n&&n.disconnect()})}export{Ki as $,lf as A,Sf as B,Ef as C,qs as D,Jf as E,xe as F,ce as G,xf as H,Ho as I,Uo as J,$c as K,Ot as L,Gf as M,Ds as N,kf as O,Un as P,qf as Q,ge as R,Vn as S,Lf as T,wf as U,Zf as V,Wf as W,mc as X,Ff as Y,Cf as Z,Df as _,_o as a,Nf as a0,Af as a1,Ls as a2,Mf as a3,su as a4,cf as a5,Xf as a6,nf as a7,Qf as a8,eu as a9,mt as aa,$f as ab,zf as ac,of as ad,ru as ae,nu as af,tu as ag,Be as ah,Lo as ai,jf as aj,tr as ak,Uf as al,Kf as am,Bf as an,Vf as ao,ff as ap,Pt as aq,_f as ar,If as as,fe as at,bf as au,wn as av,Hf as aw,Yf as ax,Ms as b,Of as c,Ys as d,Pf as e,tf as f,ti as g,ie as h,Ya as i,vo as j,Oi as k,Ga as l,Io as m,js as n,Os as o,oe as p,Fe as q,Tf as r,Zs as s,sl as t,sf as u,Lt as v,Ul as w,Bn as x,Rf as y,nc as z}; diff --git a/.vitepress/dist/assets/chunks/theme.Chl5AtGS.js b/.vitepress/dist/assets/chunks/theme.Chl5AtGS.js new file mode 100644 index 0000000..1cbdf49 --- /dev/null +++ b/.vitepress/dist/assets/chunks/theme.Chl5AtGS.js @@ -0,0 +1,2 @@ +const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/chunks/VPLocalSearchBox.BgYvNrGg.js","assets/chunks/framework.DtMx7FFi.js"])))=>i.map(i=>d[i]); +import{d as h,o as a,c as u,r as c,n as N,a as j,t as M,b as k,w as f,e as m,T as pe,_ as g,u as we,i as je,f as Re,g as fe,h as y,j as v,k as l,l as R,m as le,p as T,q as F,s as Z,v as O,x as me,y as he,z as ze,A as Ke,B as z,F as I,C,D as Ne,E as x,G as _,H as E,I as Me,J,K as U,L as ee,M as We,N as Ie,O as ie,P as W,Q as Ae,R as te,S as Je,U as Ye,V as Xe,W as Be,X as Ce,Y as Qe,Z as Ze,$ as xe,a0 as et,a1 as tt,a2 as nt}from"./framework.DtMx7FFi.js";const ot=h({__name:"VPBadge",props:{text:{},type:{default:"tip"}},setup(s){return(e,t)=>(a(),u("span",{class:N(["VPBadge",e.type])},[c(e.$slots,"default",{},()=>[j(M(e.text),1)])],2))}}),st={key:0,class:"VPBackdrop"},at=h({__name:"VPBackdrop",props:{show:{type:Boolean}},setup(s){return(e,t)=>(a(),k(pe,{name:"fade"},{default:f(()=>[e.show?(a(),u("div",st)):m("",!0)]),_:1}))}}),rt=g(at,[["__scopeId","data-v-2090a59e"]]),L=we;function lt(s,e){let t,o=!1;return()=>{t&&clearTimeout(t),o?t=setTimeout(s,e):(s(),(o=!0)&&setTimeout(()=>o=!1,e))}}function ce(s){return/^\//.test(s)?s:`/${s}`}function _e(s){const{pathname:e,search:t,hash:o,protocol:n}=new URL(s,"http://a.com");if(je(s)||s.startsWith("#")||!n.startsWith("http")||!Re(e))return s;const{site:r}=L(),i=e.endsWith("/")||e.endsWith(".html")?s:s.replace(/(?:(^\.+)\/)?.*$/,`$1${e.replace(/(\.md)?$/,r.value.cleanUrls?"":".html")}${t}${o}`);return fe(i)}function Y({correspondingLink:s=!1}={}){const{site:e,localeIndex:t,page:o,theme:n,hash:r}=L(),i=y(()=>{var p,$;return{label:(p=e.value.locales[t.value])==null?void 0:p.label,link:(($=e.value.locales[t.value])==null?void 0:$.link)||(t.value==="root"?"/":`/${t.value}/`)}});return{localeLinks:y(()=>Object.entries(e.value.locales).flatMap(([p,$])=>i.value.label===$.label?[]:{text:$.label,link:it($.link||(p==="root"?"/":`/${p}/`),n.value.i18nRouting!==!1&&s,o.value.relativePath.slice(i.value.link.length-1),!e.value.cleanUrls)+r.value})),currentLang:i}}function it(s,e,t,o){return e?s.replace(/\/$/,"")+ce(t.replace(/(^|\/)index\.md$/,"$1").replace(/\.md$/,o?".html":"")):s}const ct={class:"NotFound"},ut={class:"code"},dt={class:"title"},vt={class:"quote"},pt={class:"action"},ft=["href","aria-label"],mt=h({__name:"NotFound",setup(s){const{theme:e}=L(),{currentLang:t}=Y();return(o,n)=>{var r,i,d,p,$;return a(),u("div",ct,[v("p",ut,M(((r=l(e).notFound)==null?void 0:r.code)??"404"),1),v("h1",dt,M(((i=l(e).notFound)==null?void 0:i.title)??"PAGE NOT FOUND"),1),n[0]||(n[0]=v("div",{class:"divider"},null,-1)),v("blockquote",vt,M(((d=l(e).notFound)==null?void 0:d.quote)??"But if you don't change your direction, and if you keep looking, you may end up where you are heading."),1),v("div",pt,[v("a",{class:"link",href:l(fe)(l(t).link),"aria-label":((p=l(e).notFound)==null?void 0:p.linkLabel)??"go to home"},M((($=l(e).notFound)==null?void 0:$.linkText)??"Take me home"),9,ft)])])}}}),ht=g(mt,[["__scopeId","data-v-51bbc008"]]);function He(s,e){if(Array.isArray(s))return X(s);if(s==null)return[];e=ce(e);const t=Object.keys(s).sort((n,r)=>r.split("/").length-n.split("/").length).find(n=>e.startsWith(ce(n))),o=t?s[t]:[];return Array.isArray(o)?X(o):X(o.items,o.base)}function _t(s){const e=[];let t=0;for(const o in s){const n=s[o];if(n.items){t=e.push(n);continue}e[t]||e.push({items:[]}),e[t].items.push(n)}return e}function kt(s){const e=[];function t(o){for(const n of o)n.text&&n.link&&e.push({text:n.text,link:n.link,docFooterText:n.docFooterText}),n.items&&t(n.items)}return t(s),e}function ue(s,e){return Array.isArray(e)?e.some(t=>ue(s,t)):R(s,e.link)?!0:e.items?ue(s,e.items):!1}function X(s,e){return[...s].map(t=>{const o={...t},n=o.base||e;return n&&o.link&&(o.link=n+o.link),o.items&&(o.items=X(o.items,n)),o})}function G(){const{frontmatter:s,page:e,theme:t}=L(),o=le("(min-width: 960px)"),n=T(!1),r=y(()=>{const B=t.value.sidebar,S=e.value.relativePath;return B?He(B,S):[]}),i=T(r.value);F(r,(B,S)=>{JSON.stringify(B)!==JSON.stringify(S)&&(i.value=r.value)});const d=y(()=>s.value.sidebar!==!1&&i.value.length>0&&s.value.layout!=="home"),p=y(()=>$?s.value.aside==null?t.value.aside==="left":s.value.aside==="left":!1),$=y(()=>s.value.layout==="home"?!1:s.value.aside!=null?!!s.value.aside:t.value.aside!==!1),V=y(()=>d.value&&o.value),b=y(()=>d.value?_t(i.value):[]);function P(){n.value=!0}function w(){n.value=!1}function A(){n.value?w():P()}return{isOpen:n,sidebar:i,sidebarGroups:b,hasSidebar:d,hasAside:$,leftAside:p,isSidebarEnabled:V,open:P,close:w,toggle:A}}function bt(s,e){let t;Z(()=>{t=s.value?document.activeElement:void 0}),O(()=>{window.addEventListener("keyup",o)}),me(()=>{window.removeEventListener("keyup",o)});function o(n){n.key==="Escape"&&s.value&&(e(),t==null||t.focus())}}function gt(s){const{page:e,hash:t}=L(),o=T(!1),n=y(()=>s.value.collapsed!=null),r=y(()=>!!s.value.link),i=T(!1),d=()=>{i.value=R(e.value.relativePath,s.value.link)};F([e,s,t],d),O(d);const p=y(()=>i.value?!0:s.value.items?ue(e.value.relativePath,s.value.items):!1),$=y(()=>!!(s.value.items&&s.value.items.length));Z(()=>{o.value=!!(n.value&&s.value.collapsed)}),he(()=>{(i.value||p.value)&&(o.value=!1)});function V(){n.value&&(o.value=!o.value)}return{collapsed:o,collapsible:n,isLink:r,isActiveLink:i,hasActiveLink:p,hasChildren:$,toggle:V}}function $t(){const{hasSidebar:s}=G(),e=le("(min-width: 960px)"),t=le("(min-width: 1280px)");return{isAsideEnabled:y(()=>!t.value&&!e.value?!1:s.value?t.value:e.value)}}const de=[];function Ee(s){return typeof s.outline=="object"&&!Array.isArray(s.outline)&&s.outline.label||s.outlineTitle||"On this page"}function ke(s){const e=[...document.querySelectorAll(".VPDoc :where(h1,h2,h3,h4,h5,h6)")].filter(t=>t.id&&t.hasChildNodes()).map(t=>{const o=Number(t.tagName[1]);return{element:t,title:yt(t),link:"#"+t.id,level:o}});return Pt(e,s)}function yt(s){let e="";for(const t of s.childNodes)if(t.nodeType===1){if(t.classList.contains("VPBadge")||t.classList.contains("header-anchor")||t.classList.contains("ignore-header"))continue;e+=t.textContent}else t.nodeType===3&&(e+=t.textContent);return e.trim()}function Pt(s,e){if(e===!1)return[];const t=(typeof e=="object"&&!Array.isArray(e)?e.level:e)||2,[o,n]=typeof t=="number"?[t,t]:t==="deep"?[2,6]:t;return St(s,o,n)}function Lt(s,e){const{isAsideEnabled:t}=$t(),o=lt(r,100);let n=null;O(()=>{requestAnimationFrame(r),window.addEventListener("scroll",o)}),ze(()=>{i(location.hash)}),me(()=>{window.removeEventListener("scroll",o)});function r(){if(!t.value)return;const d=window.scrollY,p=window.innerHeight,$=document.body.offsetHeight,V=Math.abs(d+p-$)<1,b=de.map(({element:w,link:A})=>({link:A,top:Vt(w)})).filter(({top:w})=>!Number.isNaN(w)).sort((w,A)=>w.top-A.top);if(!b.length){i(null);return}if(d<1){i(null);return}if(V){i(b[b.length-1].link);return}let P=null;for(const{link:w,top:A}of b){if(A>d+Ke()+4)break;P=w}i(P)}function i(d){n&&n.classList.remove("active"),d==null?n=null:n=s.value.querySelector(`a[href="${decodeURIComponent(d)}"]`);const p=n;p?(p.classList.add("active"),e.value.style.top=p.offsetTop+39+"px",e.value.style.opacity="1"):(e.value.style.top="33px",e.value.style.opacity="0")}}function Vt(s){let e=0;for(;s!==document.body;){if(s===null)return NaN;e+=s.offsetTop,s=s.offsetParent}return e}function St(s,e,t){de.length=0;const o=[],n=[];return s.forEach(r=>{const i={...r,children:[]};let d=n[n.length-1];for(;d&&d.level>=i.level;)n.pop(),d=n[n.length-1];if(i.element.classList.contains("ignore-header")||d&&"shouldIgnore"in d){n.push({level:i.level,shouldIgnore:!0});return}i.level>t||i.level{const n=z("VPDocOutlineItem",!0);return a(),u("ul",{class:N(["VPDocOutlineItem",t.root?"root":"nested"])},[(a(!0),u(I,null,C(t.headers,({children:r,link:i,title:d})=>(a(),u("li",null,[v("a",{class:"outline-link",href:i,onClick:e,title:d},M(d),9,Tt),r!=null&&r.length?(a(),k(n,{key:0,headers:r},null,8,["headers"])):m("",!0)]))),256))],2)}}}),De=g(wt,[["__scopeId","data-v-a993366b"]]),Nt={class:"content"},Mt={"aria-level":"2",class:"outline-title",id:"doc-outline-aria-label",role:"heading"},It=h({__name:"VPDocAsideOutline",setup(s){const{frontmatter:e,theme:t}=L(),o=Ne([]);x(()=>{o.value=ke(e.value.outline??t.value.outline)});const n=T(),r=T();return Lt(n,r),(i,d)=>(a(),u("nav",{"aria-labelledby":"doc-outline-aria-label",class:N(["VPDocAsideOutline",{"has-outline":o.value.length>0}]),ref_key:"container",ref:n},[v("div",Nt,[v("div",{class:"outline-marker",ref_key:"marker",ref:r},null,512),v("div",Mt,M(l(Ee)(l(t))),1),_(De,{headers:o.value,root:!0},null,8,["headers"])])],2))}}),At=g(It,[["__scopeId","data-v-154faa32"]]),Bt={class:"VPDocAsideCarbonAds"},Ct=h({__name:"VPDocAsideCarbonAds",props:{carbonAds:{}},setup(s){const e=()=>null;return(t,o)=>(a(),u("div",Bt,[_(l(e),{"carbon-ads":t.carbonAds},null,8,["carbon-ads"])]))}}),Ht={class:"VPDocAside"},Et=h({__name:"VPDocAside",setup(s){const{theme:e}=L();return(t,o)=>(a(),u("div",Ht,[c(t.$slots,"aside-top",{},void 0,!0),c(t.$slots,"aside-outline-before",{},void 0,!0),_(At),c(t.$slots,"aside-outline-after",{},void 0,!0),o[0]||(o[0]=v("div",{class:"spacer"},null,-1)),c(t.$slots,"aside-ads-before",{},void 0,!0),l(e).carbonAds?(a(),k(Ct,{key:0,"carbon-ads":l(e).carbonAds},null,8,["carbon-ads"])):m("",!0),c(t.$slots,"aside-ads-after",{},void 0,!0),c(t.$slots,"aside-bottom",{},void 0,!0)]))}}),Dt=g(Et,[["__scopeId","data-v-c0d770e2"]]);function Ft(){const{theme:s,page:e}=L();return y(()=>{const{text:t="Edit this page",pattern:o=""}=s.value.editLink||{};let n;return typeof o=="function"?n=o(e.value):n=o.replace(/:path/g,e.value.filePath),{url:n,text:t}})}function Ot(){const{page:s,theme:e,frontmatter:t}=L();return y(()=>{var $,V,b,P,w,A,B,S;const o=He(e.value.sidebar,s.value.relativePath),n=kt(o),r=Gt(n,H=>H.link.replace(/[?#].*$/,"")),i=r.findIndex(H=>R(s.value.relativePath,H.link)),d=(($=e.value.docFooter)==null?void 0:$.prev)===!1&&!t.value.prev||t.value.prev===!1,p=((V=e.value.docFooter)==null?void 0:V.next)===!1&&!t.value.next||t.value.next===!1;return{prev:d?void 0:{text:(typeof t.value.prev=="string"?t.value.prev:typeof t.value.prev=="object"?t.value.prev.text:void 0)??((b=r[i-1])==null?void 0:b.docFooterText)??((P=r[i-1])==null?void 0:P.text),link:(typeof t.value.prev=="object"?t.value.prev.link:void 0)??((w=r[i-1])==null?void 0:w.link)},next:p?void 0:{text:(typeof t.value.next=="string"?t.value.next:typeof t.value.next=="object"?t.value.next.text:void 0)??((A=r[i+1])==null?void 0:A.docFooterText)??((B=r[i+1])==null?void 0:B.text),link:(typeof t.value.next=="object"?t.value.next.link:void 0)??((S=r[i+1])==null?void 0:S.link)}}})}function Gt(s,e){const t=new Set;return s.filter(o=>{const n=e(o);return t.has(n)?!1:t.add(n)})}const D=h({__name:"VPLink",props:{tag:{},href:{},noIcon:{type:Boolean},target:{},rel:{}},setup(s){const e=s,t=y(()=>e.tag??(e.href?"a":"span")),o=y(()=>e.href&&Me.test(e.href)||e.target==="_blank");return(n,r)=>(a(),k(E(t.value),{class:N(["VPLink",{link:n.href,"vp-external-link-icon":o.value,"no-icon":n.noIcon}]),href:n.href?l(_e)(n.href):void 0,target:n.target??(o.value?"_blank":void 0),rel:n.rel??(o.value?"noreferrer":void 0)},{default:f(()=>[c(n.$slots,"default")]),_:3},8,["class","href","target","rel"]))}}),qt={class:"VPLastUpdated"},Ut=["datetime"],jt=h({__name:"VPDocFooterLastUpdated",setup(s){const{theme:e,page:t,lang:o}=L(),n=y(()=>new Date(t.value.lastUpdated)),r=y(()=>n.value.toISOString()),i=T("");return O(()=>{Z(()=>{var d,p,$;i.value=new Intl.DateTimeFormat((p=(d=e.value.lastUpdated)==null?void 0:d.formatOptions)!=null&&p.forceLocale?o.value:void 0,(($=e.value.lastUpdated)==null?void 0:$.formatOptions)??{dateStyle:"short",timeStyle:"short"}).format(n.value)})}),(d,p)=>{var $;return a(),u("p",qt,[j(M((($=l(e).lastUpdated)==null?void 0:$.text)||l(e).lastUpdatedText||"Last updated")+": ",1),v("time",{datetime:r.value},M(i.value),9,Ut)])}}}),Rt=g(jt,[["__scopeId","data-v-acf4bd3a"]]),zt={key:0,class:"VPDocFooter"},Kt={key:0,class:"edit-info"},Wt={key:0,class:"edit-link"},Jt={key:1,class:"last-updated"},Yt={key:1,class:"prev-next","aria-labelledby":"doc-footer-aria-label"},Xt={class:"pager"},Qt=["innerHTML"],Zt=["innerHTML"],xt={class:"pager"},en=["innerHTML"],tn=["innerHTML"],nn=h({__name:"VPDocFooter",setup(s){const{theme:e,page:t,frontmatter:o}=L(),n=Ft(),r=Ot(),i=y(()=>e.value.editLink&&o.value.editLink!==!1),d=y(()=>t.value.lastUpdated),p=y(()=>i.value||d.value||r.value.prev||r.value.next);return($,V)=>{var b,P,w,A;return p.value?(a(),u("footer",zt,[c($.$slots,"doc-footer-before",{},void 0,!0),i.value||d.value?(a(),u("div",Kt,[i.value?(a(),u("div",Wt,[_(D,{class:"edit-link-button",href:l(n).url,"no-icon":!0},{default:f(()=>[V[0]||(V[0]=v("span",{class:"vpi-square-pen edit-link-icon"},null,-1)),j(" "+M(l(n).text),1)]),_:1},8,["href"])])):m("",!0),d.value?(a(),u("div",Jt,[_(Rt)])):m("",!0)])):m("",!0),(b=l(r).prev)!=null&&b.link||(P=l(r).next)!=null&&P.link?(a(),u("nav",Yt,[V[1]||(V[1]=v("span",{class:"visually-hidden",id:"doc-footer-aria-label"},"Pager",-1)),v("div",Xt,[(w=l(r).prev)!=null&&w.link?(a(),k(D,{key:0,class:"pager-link prev",href:l(r).prev.link},{default:f(()=>{var B;return[v("span",{class:"desc",innerHTML:((B=l(e).docFooter)==null?void 0:B.prev)||"Previous page"},null,8,Qt),v("span",{class:"title",innerHTML:l(r).prev.text},null,8,Zt)]}),_:1},8,["href"])):m("",!0)]),v("div",xt,[(A=l(r).next)!=null&&A.link?(a(),k(D,{key:0,class:"pager-link next",href:l(r).next.link},{default:f(()=>{var B;return[v("span",{class:"desc",innerHTML:((B=l(e).docFooter)==null?void 0:B.next)||"Next page"},null,8,en),v("span",{class:"title",innerHTML:l(r).next.text},null,8,tn)]}),_:1},8,["href"])):m("",!0)])])):m("",!0)])):m("",!0)}}}),on=g(nn,[["__scopeId","data-v-a287ad5f"]]),sn={class:"container"},an={class:"aside-container"},rn={class:"aside-content"},ln={class:"content"},cn={class:"content-container"},un={class:"main"},dn=h({__name:"VPDoc",setup(s){const{theme:e}=L(),t=J(),{hasSidebar:o,hasAside:n,leftAside:r}=G(),i=y(()=>t.path.replace(/[./]+/g,"_").replace(/_html$/,""));return(d,p)=>{const $=z("Content");return a(),u("div",{class:N(["VPDoc",{"has-sidebar":l(o),"has-aside":l(n)}])},[c(d.$slots,"doc-top",{},void 0,!0),v("div",sn,[l(n)?(a(),u("div",{key:0,class:N(["aside",{"left-aside":l(r)}])},[p[0]||(p[0]=v("div",{class:"aside-curtain"},null,-1)),v("div",an,[v("div",rn,[_(Dt,null,{"aside-top":f(()=>[c(d.$slots,"aside-top",{},void 0,!0)]),"aside-bottom":f(()=>[c(d.$slots,"aside-bottom",{},void 0,!0)]),"aside-outline-before":f(()=>[c(d.$slots,"aside-outline-before",{},void 0,!0)]),"aside-outline-after":f(()=>[c(d.$slots,"aside-outline-after",{},void 0,!0)]),"aside-ads-before":f(()=>[c(d.$slots,"aside-ads-before",{},void 0,!0)]),"aside-ads-after":f(()=>[c(d.$slots,"aside-ads-after",{},void 0,!0)]),_:3})])])],2)):m("",!0),v("div",ln,[v("div",cn,[c(d.$slots,"doc-before",{},void 0,!0),v("main",un,[_($,{class:N(["vp-doc",[i.value,l(e).externalLinkIcon&&"external-link-icon-enabled"]])},null,8,["class"])]),_(on,null,{"doc-footer-before":f(()=>[c(d.$slots,"doc-footer-before",{},void 0,!0)]),_:3}),c(d.$slots,"doc-after",{},void 0,!0)])])]),c(d.$slots,"doc-bottom",{},void 0,!0)],2)}}}),vn=g(dn,[["__scopeId","data-v-f87ade32"]]),pn=h({__name:"VPButton",props:{tag:{},size:{default:"medium"},theme:{default:"brand"},text:{},href:{},target:{},rel:{}},setup(s){const e=s,t=y(()=>e.href&&Me.test(e.href)),o=y(()=>e.tag||(e.href?"a":"button"));return(n,r)=>(a(),k(E(o.value),{class:N(["VPButton",[n.size,n.theme]]),href:n.href?l(_e)(n.href):void 0,target:e.target??(t.value?"_blank":void 0),rel:e.rel??(t.value?"noreferrer":void 0)},{default:f(()=>[j(M(n.text),1)]),_:1},8,["class","href","target","rel"]))}}),fn=g(pn,[["__scopeId","data-v-913f79e0"]]),mn=["src","alt"],hn=h({inheritAttrs:!1,__name:"VPImage",props:{image:{},alt:{}},setup(s){return(e,t)=>{const o=z("VPImage",!0);return e.image?(a(),u(I,{key:0},[typeof e.image=="string"||"src"in e.image?(a(),u("img",U({key:0,class:"VPImage"},typeof e.image=="string"?e.$attrs:{...e.image,...e.$attrs},{src:l(fe)(typeof e.image=="string"?e.image:e.image.src),alt:e.alt??(typeof e.image=="string"?"":e.image.alt||"")}),null,16,mn)):(a(),u(I,{key:1},[_(o,U({class:"dark",image:e.image.dark,alt:e.image.alt},e.$attrs),null,16,["image","alt"]),_(o,U({class:"light",image:e.image.light,alt:e.image.alt},e.$attrs),null,16,["image","alt"])],64))],64)):m("",!0)}}}),Q=g(hn,[["__scopeId","data-v-e838cdb3"]]),_n={class:"container"},kn={class:"main"},bn={key:0,class:"name"},gn=["innerHTML"],$n=["innerHTML"],yn=["innerHTML"],Pn={key:0,class:"actions"},Ln={key:0,class:"image"},Vn={class:"image-container"},Sn=h({__name:"VPHero",props:{name:{},text:{},tagline:{},image:{},actions:{}},setup(s){const e=ee("hero-image-slot-exists");return(t,o)=>(a(),u("div",{class:N(["VPHero",{"has-image":t.image||l(e)}])},[v("div",_n,[v("div",kn,[c(t.$slots,"home-hero-info-before",{},void 0,!0),c(t.$slots,"home-hero-info",{},()=>[t.name?(a(),u("h1",bn,[v("span",{innerHTML:t.name,class:"clip"},null,8,gn)])):m("",!0),t.text?(a(),u("p",{key:1,innerHTML:t.text,class:"text"},null,8,$n)):m("",!0),t.tagline?(a(),u("p",{key:2,innerHTML:t.tagline,class:"tagline"},null,8,yn)):m("",!0)],!0),c(t.$slots,"home-hero-info-after",{},void 0,!0),t.actions?(a(),u("div",Pn,[(a(!0),u(I,null,C(t.actions,n=>(a(),u("div",{key:n.link,class:"action"},[_(fn,{tag:"a",size:"medium",theme:n.theme,text:n.text,href:n.link,target:n.target,rel:n.rel},null,8,["theme","text","href","target","rel"])]))),128))])):m("",!0),c(t.$slots,"home-hero-actions-after",{},void 0,!0)]),t.image||l(e)?(a(),u("div",Ln,[v("div",Vn,[o[0]||(o[0]=v("div",{class:"image-bg"},null,-1)),c(t.$slots,"home-hero-image",{},()=>[t.image?(a(),k(Q,{key:0,class:"image-src",image:t.image},null,8,["image"])):m("",!0)],!0)])])):m("",!0)])],2))}}),Tn=g(Sn,[["__scopeId","data-v-a8266bd2"]]),wn=h({__name:"VPHomeHero",setup(s){const{frontmatter:e}=L();return(t,o)=>l(e).hero?(a(),k(Tn,{key:0,class:"VPHomeHero",name:l(e).hero.name,text:l(e).hero.text,tagline:l(e).hero.tagline,image:l(e).hero.image,actions:l(e).hero.actions},{"home-hero-info-before":f(()=>[c(t.$slots,"home-hero-info-before")]),"home-hero-info":f(()=>[c(t.$slots,"home-hero-info")]),"home-hero-info-after":f(()=>[c(t.$slots,"home-hero-info-after")]),"home-hero-actions-after":f(()=>[c(t.$slots,"home-hero-actions-after")]),"home-hero-image":f(()=>[c(t.$slots,"home-hero-image")]),_:3},8,["name","text","tagline","image","actions"])):m("",!0)}}),Nn={class:"box"},Mn={key:0,class:"icon"},In=["innerHTML"],An=["innerHTML"],Bn=["innerHTML"],Cn={key:4,class:"link-text"},Hn={class:"link-text-value"},En=h({__name:"VPFeature",props:{icon:{},title:{},details:{},link:{},linkText:{},rel:{},target:{}},setup(s){return(e,t)=>(a(),k(D,{class:"VPFeature",href:e.link,rel:e.rel,target:e.target,"no-icon":!0,tag:e.link?"a":"div"},{default:f(()=>[v("article",Nn,[typeof e.icon=="object"&&e.icon.wrap?(a(),u("div",Mn,[_(Q,{image:e.icon,alt:e.icon.alt,height:e.icon.height||48,width:e.icon.width||48},null,8,["image","alt","height","width"])])):typeof e.icon=="object"?(a(),k(Q,{key:1,image:e.icon,alt:e.icon.alt,height:e.icon.height||48,width:e.icon.width||48},null,8,["image","alt","height","width"])):e.icon?(a(),u("div",{key:2,class:"icon",innerHTML:e.icon},null,8,In)):m("",!0),v("h2",{class:"title",innerHTML:e.title},null,8,An),e.details?(a(),u("p",{key:3,class:"details",innerHTML:e.details},null,8,Bn)):m("",!0),e.linkText?(a(),u("div",Cn,[v("p",Hn,[j(M(e.linkText)+" ",1),t[0]||(t[0]=v("span",{class:"vpi-arrow-right link-text-icon"},null,-1))])])):m("",!0)])]),_:1},8,["href","rel","target","tag"]))}}),Dn=g(En,[["__scopeId","data-v-b2767c9d"]]),Fn={key:0,class:"VPFeatures"},On={class:"container"},Gn={class:"items"},qn=h({__name:"VPFeatures",props:{features:{}},setup(s){const e=s,t=y(()=>{const o=e.features.length;if(o){if(o===2)return"grid-2";if(o===3)return"grid-3";if(o%3===0)return"grid-6";if(o>3)return"grid-4"}else return});return(o,n)=>o.features?(a(),u("div",Fn,[v("div",On,[v("div",Gn,[(a(!0),u(I,null,C(o.features,r=>(a(),u("div",{key:r.title,class:N(["item",[t.value]])},[_(Dn,{icon:r.icon,title:r.title,details:r.details,link:r.link,"link-text":r.linkText,rel:r.rel,target:r.target},null,8,["icon","title","details","link","link-text","rel","target"])],2))),128))])])])):m("",!0)}}),Un=g(qn,[["__scopeId","data-v-364f1c1e"]]),jn=h({__name:"VPHomeFeatures",setup(s){const{frontmatter:e}=L();return(t,o)=>l(e).features?(a(),k(Un,{key:0,class:"VPHomeFeatures",features:l(e).features},null,8,["features"])):m("",!0)}}),Rn=h({__name:"VPHomeContent",setup(s){const{width:e}=We({initialWidth:0,includeScrollbar:!1});return(t,o)=>(a(),u("div",{class:"vp-doc container",style:Ie(l(e)?{"--vp-offset":`calc(50% - ${l(e)/2}px)`}:{})},[c(t.$slots,"default",{},void 0,!0)],4))}}),zn=g(Rn,[["__scopeId","data-v-ec979b25"]]),Kn={class:"VPHome"},Wn=h({__name:"VPHome",setup(s){const{frontmatter:e}=L();return(t,o)=>{const n=z("Content");return a(),u("div",Kn,[c(t.$slots,"home-hero-before",{},void 0,!0),_(wn,null,{"home-hero-info-before":f(()=>[c(t.$slots,"home-hero-info-before",{},void 0,!0)]),"home-hero-info":f(()=>[c(t.$slots,"home-hero-info",{},void 0,!0)]),"home-hero-info-after":f(()=>[c(t.$slots,"home-hero-info-after",{},void 0,!0)]),"home-hero-actions-after":f(()=>[c(t.$slots,"home-hero-actions-after",{},void 0,!0)]),"home-hero-image":f(()=>[c(t.$slots,"home-hero-image",{},void 0,!0)]),_:3}),c(t.$slots,"home-hero-after",{},void 0,!0),c(t.$slots,"home-features-before",{},void 0,!0),_(jn),c(t.$slots,"home-features-after",{},void 0,!0),l(e).markdownStyles!==!1?(a(),k(zn,{key:0},{default:f(()=>[_(n)]),_:1})):(a(),k(n,{key:1}))])}}}),Jn=g(Wn,[["__scopeId","data-v-30316261"]]),Yn={},Xn={class:"VPPage"};function Qn(s,e){const t=z("Content");return a(),u("div",Xn,[c(s.$slots,"page-top"),_(t),c(s.$slots,"page-bottom")])}const Zn=g(Yn,[["render",Qn]]),xn=h({__name:"VPContent",setup(s){const{page:e,frontmatter:t}=L(),{hasSidebar:o}=G();return(n,r)=>(a(),u("div",{class:N(["VPContent",{"has-sidebar":l(o),"is-home":l(t).layout==="home"}]),id:"VPContent"},[l(e).isNotFound?c(n.$slots,"not-found",{key:0},()=>[_(ht)],!0):l(t).layout==="page"?(a(),k(Zn,{key:1},{"page-top":f(()=>[c(n.$slots,"page-top",{},void 0,!0)]),"page-bottom":f(()=>[c(n.$slots,"page-bottom",{},void 0,!0)]),_:3})):l(t).layout==="home"?(a(),k(Jn,{key:2},{"home-hero-before":f(()=>[c(n.$slots,"home-hero-before",{},void 0,!0)]),"home-hero-info-before":f(()=>[c(n.$slots,"home-hero-info-before",{},void 0,!0)]),"home-hero-info":f(()=>[c(n.$slots,"home-hero-info",{},void 0,!0)]),"home-hero-info-after":f(()=>[c(n.$slots,"home-hero-info-after",{},void 0,!0)]),"home-hero-actions-after":f(()=>[c(n.$slots,"home-hero-actions-after",{},void 0,!0)]),"home-hero-image":f(()=>[c(n.$slots,"home-hero-image",{},void 0,!0)]),"home-hero-after":f(()=>[c(n.$slots,"home-hero-after",{},void 0,!0)]),"home-features-before":f(()=>[c(n.$slots,"home-features-before",{},void 0,!0)]),"home-features-after":f(()=>[c(n.$slots,"home-features-after",{},void 0,!0)]),_:3})):l(t).layout&&l(t).layout!=="doc"?(a(),k(E(l(t).layout),{key:3})):(a(),k(vn,{key:4},{"doc-top":f(()=>[c(n.$slots,"doc-top",{},void 0,!0)]),"doc-bottom":f(()=>[c(n.$slots,"doc-bottom",{},void 0,!0)]),"doc-footer-before":f(()=>[c(n.$slots,"doc-footer-before",{},void 0,!0)]),"doc-before":f(()=>[c(n.$slots,"doc-before",{},void 0,!0)]),"doc-after":f(()=>[c(n.$slots,"doc-after",{},void 0,!0)]),"aside-top":f(()=>[c(n.$slots,"aside-top",{},void 0,!0)]),"aside-outline-before":f(()=>[c(n.$slots,"aside-outline-before",{},void 0,!0)]),"aside-outline-after":f(()=>[c(n.$slots,"aside-outline-after",{},void 0,!0)]),"aside-ads-before":f(()=>[c(n.$slots,"aside-ads-before",{},void 0,!0)]),"aside-ads-after":f(()=>[c(n.$slots,"aside-ads-after",{},void 0,!0)]),"aside-bottom":f(()=>[c(n.$slots,"aside-bottom",{},void 0,!0)]),_:3}))],2))}}),eo=g(xn,[["__scopeId","data-v-cc09d6e0"]]),to={class:"container"},no=["innerHTML"],oo=["innerHTML"],so=h({__name:"VPFooter",setup(s){const{theme:e,frontmatter:t}=L(),{hasSidebar:o}=G();return(n,r)=>l(e).footer&&l(t).footer!==!1?(a(),u("footer",{key:0,class:N(["VPFooter",{"has-sidebar":l(o)}])},[v("div",to,[l(e).footer.message?(a(),u("p",{key:0,class:"message",innerHTML:l(e).footer.message},null,8,no)):m("",!0),l(e).footer.copyright?(a(),u("p",{key:1,class:"copyright",innerHTML:l(e).footer.copyright},null,8,oo)):m("",!0)])],2)):m("",!0)}}),ao=g(so,[["__scopeId","data-v-ed47955f"]]);function ro(){const{theme:s,frontmatter:e}=L(),t=Ne([]),o=y(()=>t.value.length>0);return x(()=>{t.value=ke(e.value.outline??s.value.outline)}),{headers:t,hasLocalNav:o}}const lo={class:"menu-text"},io={class:"header"},co={class:"outline"},uo=h({__name:"VPLocalNavOutlineDropdown",props:{headers:{},navHeight:{}},setup(s){const e=s,{theme:t}=L(),o=T(!1),n=T(0),r=T(),i=T();function d(b){var P;(P=r.value)!=null&&P.contains(b.target)||(o.value=!1)}F(o,b=>{if(b){document.addEventListener("click",d);return}document.removeEventListener("click",d)}),ie("Escape",()=>{o.value=!1}),x(()=>{o.value=!1});function p(){o.value=!o.value,n.value=window.innerHeight+Math.min(window.scrollY-e.navHeight,0)}function $(b){b.target.classList.contains("outline-link")&&(i.value&&(i.value.style.transition="none"),W(()=>{o.value=!1}))}function V(){o.value=!1,window.scrollTo({top:0,left:0,behavior:"smooth"})}return(b,P)=>(a(),u("div",{class:"VPLocalNavOutlineDropdown",style:Ie({"--vp-vh":n.value+"px"}),ref_key:"main",ref:r},[b.headers.length>0?(a(),u("button",{key:0,onClick:p,class:N({open:o.value})},[v("span",lo,M(l(Ee)(l(t))),1),P[0]||(P[0]=v("span",{class:"vpi-chevron-right icon"},null,-1))],2)):(a(),u("button",{key:1,onClick:V},M(l(t).returnToTopLabel||"Return to top"),1)),_(pe,{name:"flyout"},{default:f(()=>[o.value?(a(),u("div",{key:0,ref_key:"items",ref:i,class:"items",onClick:$},[v("div",io,[v("a",{class:"top-link",href:"#",onClick:V},M(l(t).returnToTopLabel||"Return to top"),1)]),v("div",co,[_(De,{headers:b.headers},null,8,["headers"])])],512)):m("",!0)]),_:1})],4))}}),vo=g(uo,[["__scopeId","data-v-ebf966df"]]),po={class:"container"},fo=["aria-expanded"],mo={class:"menu-text"},ho=h({__name:"VPLocalNav",props:{open:{type:Boolean}},emits:["open-menu"],setup(s){const{theme:e,frontmatter:t}=L(),{hasSidebar:o}=G(),{headers:n}=ro(),{y:r}=Ae(),i=T(0);O(()=>{i.value=parseInt(getComputedStyle(document.documentElement).getPropertyValue("--vp-nav-height"))}),x(()=>{n.value=ke(t.value.outline??e.value.outline)});const d=y(()=>n.value.length===0),p=y(()=>d.value&&!o.value),$=y(()=>({VPLocalNav:!0,"has-sidebar":o.value,empty:d.value,fixed:p.value}));return(V,b)=>l(t).layout!=="home"&&(!p.value||l(r)>=i.value)?(a(),u("div",{key:0,class:N($.value)},[v("div",po,[l(o)?(a(),u("button",{key:0,class:"menu","aria-expanded":V.open,"aria-controls":"VPSidebarNav",onClick:b[0]||(b[0]=P=>V.$emit("open-menu"))},[b[1]||(b[1]=v("span",{class:"vpi-align-left menu-icon"},null,-1)),v("span",mo,M(l(e).sidebarMenuLabel||"Menu"),1)],8,fo)):m("",!0),_(vo,{headers:l(n),navHeight:i.value},null,8,["headers","navHeight"])])],2)):m("",!0)}}),_o=g(ho,[["__scopeId","data-v-e758e1b7"]]);function ko(){const s=T(!1);function e(){s.value=!0,window.addEventListener("resize",n)}function t(){s.value=!1,window.removeEventListener("resize",n)}function o(){s.value?t():e()}function n(){window.outerWidth>=768&&t()}const r=J();return F(()=>r.path,t),{isScreenOpen:s,openScreen:e,closeScreen:t,toggleScreen:o}}const bo={},go={class:"VPSwitch",type:"button",role:"switch"},$o={class:"check"},yo={key:0,class:"icon"};function Po(s,e){return a(),u("button",go,[v("span",$o,[s.$slots.default?(a(),u("span",yo,[c(s.$slots,"default",{},void 0,!0)])):m("",!0)])])}const Lo=g(bo,[["render",Po],["__scopeId","data-v-2ed556eb"]]),Vo=h({__name:"VPSwitchAppearance",setup(s){const{isDark:e,theme:t}=L(),o=ee("toggle-appearance",()=>{e.value=!e.value}),n=T("");return he(()=>{n.value=e.value?t.value.lightModeSwitchTitle||"Switch to light theme":t.value.darkModeSwitchTitle||"Switch to dark theme"}),(r,i)=>(a(),k(Lo,{title:n.value,class:"VPSwitchAppearance","aria-checked":l(e),onClick:l(o)},{default:f(()=>i[0]||(i[0]=[v("span",{class:"vpi-sun sun"},null,-1),v("span",{class:"vpi-moon moon"},null,-1)])),_:1},8,["title","aria-checked","onClick"]))}}),be=g(Vo,[["__scopeId","data-v-2994eab3"]]),So={key:0,class:"VPNavBarAppearance"},To=h({__name:"VPNavBarAppearance",setup(s){const{site:e}=L();return(t,o)=>l(e).appearance&&l(e).appearance!=="force-dark"&&l(e).appearance!=="force-auto"?(a(),u("div",So,[_(be)])):m("",!0)}}),wo=g(To,[["__scopeId","data-v-407d5c63"]]),ge=T();let Fe=!1,ae=0;function No(s){const e=T(!1);if(te){!Fe&&Mo(),ae++;const t=F(ge,o=>{var n,r,i;o===s.el.value||(n=s.el.value)!=null&&n.contains(o)?(e.value=!0,(r=s.onFocus)==null||r.call(s)):(e.value=!1,(i=s.onBlur)==null||i.call(s))});me(()=>{t(),ae--,ae||Io()})}return Je(e)}function Mo(){document.addEventListener("focusin",Oe),Fe=!0,ge.value=document.activeElement}function Io(){document.removeEventListener("focusin",Oe)}function Oe(){ge.value=document.activeElement}const Ao={class:"VPMenuLink"},Bo=["innerHTML"],Co=h({__name:"VPMenuLink",props:{item:{}},setup(s){const{page:e}=L();return(t,o)=>(a(),u("div",Ao,[_(D,{class:N({active:l(R)(l(e).relativePath,t.item.activeMatch||t.item.link,!!t.item.activeMatch)}),href:t.item.link,target:t.item.target,rel:t.item.rel,"no-icon":t.item.noIcon},{default:f(()=>[v("span",{innerHTML:t.item.text},null,8,Bo)]),_:1},8,["class","href","target","rel","no-icon"])]))}}),ne=g(Co,[["__scopeId","data-v-15160b25"]]),Ho={class:"VPMenuGroup"},Eo={key:0,class:"title"},Do=h({__name:"VPMenuGroup",props:{text:{},items:{}},setup(s){return(e,t)=>(a(),u("div",Ho,[e.text?(a(),u("p",Eo,M(e.text),1)):m("",!0),(a(!0),u(I,null,C(e.items,o=>(a(),u(I,null,["link"in o?(a(),k(ne,{key:0,item:o},null,8,["item"])):m("",!0)],64))),256))]))}}),Fo=g(Do,[["__scopeId","data-v-8e34546a"]]),Oo={class:"VPMenu"},Go={key:0,class:"items"},qo=h({__name:"VPMenu",props:{items:{}},setup(s){return(e,t)=>(a(),u("div",Oo,[e.items?(a(),u("div",Go,[(a(!0),u(I,null,C(e.items,o=>(a(),u(I,{key:JSON.stringify(o)},["link"in o?(a(),k(ne,{key:0,item:o},null,8,["item"])):"component"in o?(a(),k(E(o.component),U({key:1,ref_for:!0},o.props),null,16)):(a(),k(Fo,{key:2,text:o.text,items:o.items},null,8,["text","items"]))],64))),128))])):m("",!0),c(e.$slots,"default",{},void 0,!0)]))}}),Uo=g(qo,[["__scopeId","data-v-b71e5dd0"]]),jo=["aria-expanded","aria-label"],Ro={key:0,class:"text"},zo=["innerHTML"],Ko={key:1,class:"vpi-more-horizontal icon"},Wo={class:"menu"},Jo=h({__name:"VPFlyout",props:{icon:{},button:{},label:{},items:{}},setup(s){const e=T(!1),t=T();No({el:t,onBlur:o});function o(){e.value=!1}return(n,r)=>(a(),u("div",{class:"VPFlyout",ref_key:"el",ref:t,onMouseenter:r[1]||(r[1]=i=>e.value=!0),onMouseleave:r[2]||(r[2]=i=>e.value=!1)},[v("button",{type:"button",class:"button","aria-haspopup":"true","aria-expanded":e.value,"aria-label":n.label,onClick:r[0]||(r[0]=i=>e.value=!e.value)},[n.button||n.icon?(a(),u("span",Ro,[n.icon?(a(),u("span",{key:0,class:N([n.icon,"option-icon"])},null,2)):m("",!0),n.button?(a(),u("span",{key:1,innerHTML:n.button},null,8,zo)):m("",!0),r[3]||(r[3]=v("span",{class:"vpi-chevron-down text-icon"},null,-1))])):(a(),u("span",Ko))],8,jo),v("div",Wo,[_(Uo,{items:n.items},{default:f(()=>[c(n.$slots,"default",{},void 0,!0)]),_:3},8,["items"])])],544))}}),$e=g(Jo,[["__scopeId","data-v-f1cced18"]]),Yo=["href","aria-label","innerHTML"],Xo=h({__name:"VPSocialLink",props:{icon:{},link:{},ariaLabel:{}},setup(s){const e=s,t=T();O(async()=>{var r;await W();const n=(r=t.value)==null?void 0:r.children[0];n instanceof HTMLElement&&n.className.startsWith("vpi-social-")&&(getComputedStyle(n).maskImage||getComputedStyle(n).webkitMaskImage)==="none"&&n.style.setProperty("--icon",`url('https://api.iconify.design/simple-icons/${e.icon}.svg')`)});const o=y(()=>typeof e.icon=="object"?e.icon.svg:``);return(n,r)=>(a(),u("a",{ref_key:"el",ref:t,class:"VPSocialLink no-icon",href:n.link,"aria-label":n.ariaLabel??(typeof n.icon=="string"?n.icon:""),target:"_blank",rel:"noopener",innerHTML:o.value},null,8,Yo))}}),Qo=g(Xo,[["__scopeId","data-v-1dde8092"]]),Zo={class:"VPSocialLinks"},xo=h({__name:"VPSocialLinks",props:{links:{}},setup(s){return(e,t)=>(a(),u("div",Zo,[(a(!0),u(I,null,C(e.links,({link:o,icon:n,ariaLabel:r})=>(a(),k(Qo,{key:o,icon:n,link:o,ariaLabel:r},null,8,["icon","link","ariaLabel"]))),128))]))}}),ye=g(xo,[["__scopeId","data-v-b299d3ce"]]),es={key:0,class:"group translations"},ts={class:"trans-title"},ns={key:1,class:"group"},os={class:"item appearance"},ss={class:"label"},as={class:"appearance-action"},rs={key:2,class:"group"},ls={class:"item social-links"},is=h({__name:"VPNavBarExtra",setup(s){const{site:e,theme:t}=L(),{localeLinks:o,currentLang:n}=Y({correspondingLink:!0}),r=y(()=>o.value.length&&n.value.label||e.value.appearance||t.value.socialLinks);return(i,d)=>r.value?(a(),k($e,{key:0,class:"VPNavBarExtra",label:"extra navigation"},{default:f(()=>[l(o).length&&l(n).label?(a(),u("div",es,[v("p",ts,M(l(n).label),1),(a(!0),u(I,null,C(l(o),p=>(a(),k(ne,{key:p.link,item:p},null,8,["item"]))),128))])):m("",!0),l(e).appearance&&l(e).appearance!=="force-dark"&&l(e).appearance!=="force-auto"?(a(),u("div",ns,[v("div",os,[v("p",ss,M(l(t).darkModeSwitchLabel||"Appearance"),1),v("div",as,[_(be)])])])):m("",!0),l(t).socialLinks?(a(),u("div",rs,[v("div",ls,[_(ye,{class:"social-links-list",links:l(t).socialLinks},null,8,["links"])])])):m("",!0)]),_:1})):m("",!0)}}),cs=g(is,[["__scopeId","data-v-d10923a3"]]),us=["aria-expanded"],ds=h({__name:"VPNavBarHamburger",props:{active:{type:Boolean}},emits:["click"],setup(s){return(e,t)=>(a(),u("button",{type:"button",class:N(["VPNavBarHamburger",{active:e.active}]),"aria-label":"mobile navigation","aria-expanded":e.active,"aria-controls":"VPNavScreen",onClick:t[0]||(t[0]=o=>e.$emit("click"))},t[1]||(t[1]=[v("span",{class:"container"},[v("span",{class:"top"}),v("span",{class:"middle"}),v("span",{class:"bottom"})],-1)]),10,us))}}),vs=g(ds,[["__scopeId","data-v-661d4f1a"]]),ps=["innerHTML"],fs=h({__name:"VPNavBarMenuLink",props:{item:{}},setup(s){const{page:e}=L();return(t,o)=>(a(),k(D,{class:N({VPNavBarMenuLink:!0,active:l(R)(l(e).relativePath,t.item.activeMatch||t.item.link,!!t.item.activeMatch)}),href:t.item.link,target:t.item.target,rel:t.item.rel,"no-icon":t.item.noIcon,tabindex:"0"},{default:f(()=>[v("span",{innerHTML:t.item.text},null,8,ps)]),_:1},8,["class","href","target","rel","no-icon"]))}}),ms=g(fs,[["__scopeId","data-v-f334ebb6"]]),hs=h({__name:"VPNavBarMenuGroup",props:{item:{}},setup(s){const e=s,{page:t}=L(),o=r=>"component"in r?!1:"link"in r?R(t.value.relativePath,r.link,!!e.item.activeMatch):r.items.some(o),n=y(()=>o(e.item));return(r,i)=>(a(),k($e,{class:N({VPNavBarMenuGroup:!0,active:l(R)(l(t).relativePath,r.item.activeMatch,!!r.item.activeMatch)||n.value}),button:r.item.text,items:r.item.items},null,8,["class","button","items"]))}}),_s={key:0,"aria-labelledby":"main-nav-aria-label",class:"VPNavBarMenu"},ks=h({__name:"VPNavBarMenu",setup(s){const{theme:e}=L();return(t,o)=>l(e).nav?(a(),u("nav",_s,[o[0]||(o[0]=v("span",{id:"main-nav-aria-label",class:"visually-hidden"}," Main Navigation ",-1)),(a(!0),u(I,null,C(l(e).nav,n=>(a(),u(I,{key:JSON.stringify(n)},["link"in n?(a(),k(ms,{key:0,item:n},null,8,["item"])):"component"in n?(a(),k(E(n.component),U({key:1,ref_for:!0},n.props),null,16)):(a(),k(hs,{key:2,item:n},null,8,["item"]))],64))),128))])):m("",!0)}}),bs=g(ks,[["__scopeId","data-v-d62dda7e"]]);function gs(s){const{localeIndex:e,theme:t}=L();function o(n){var A,B,S;const r=n.split("."),i=(A=t.value.search)==null?void 0:A.options,d=i&&typeof i=="object",p=d&&((S=(B=i.locales)==null?void 0:B[e.value])==null?void 0:S.translations)||null,$=d&&i.translations||null;let V=p,b=$,P=s;const w=r.pop();for(const H of r){let q=null;const K=P==null?void 0:P[H];K&&(q=P=K);const oe=b==null?void 0:b[H];oe&&(q=b=oe);const se=V==null?void 0:V[H];se&&(q=V=se),K||(P=q),oe||(b=q),se||(V=q)}return(V==null?void 0:V[w])??(b==null?void 0:b[w])??(P==null?void 0:P[w])??""}return o}const $s=["aria-label"],ys={class:"DocSearch-Button-Container"},Ps={class:"DocSearch-Button-Placeholder"},Pe=h({__name:"VPNavBarSearchButton",setup(s){const t=gs({button:{buttonText:"Search",buttonAriaLabel:"Search"}});return(o,n)=>(a(),u("button",{type:"button",class:"DocSearch DocSearch-Button","aria-label":l(t)("button.buttonAriaLabel")},[v("span",ys,[n[0]||(n[0]=v("span",{class:"vp-icon DocSearch-Search-Icon"},null,-1)),v("span",Ps,M(l(t)("button.buttonText")),1)]),n[1]||(n[1]=v("span",{class:"DocSearch-Button-Keys"},[v("kbd",{class:"DocSearch-Button-Key"}),v("kbd",{class:"DocSearch-Button-Key"},"K")],-1))],8,$s))}}),Ls={class:"VPNavBarSearch"},Vs={id:"local-search"},Ss={key:1,id:"docsearch"},Ts=h({__name:"VPNavBarSearch",setup(s){const e=Ye(()=>Xe(()=>import("./VPLocalSearchBox.BgYvNrGg.js"),__vite__mapDeps([0,1]))),t=()=>null,{theme:o}=L(),n=T(!1),r=T(!1);O(()=>{});function i(){n.value||(n.value=!0,setTimeout(d,16))}function d(){const b=new Event("keydown");b.key="k",b.metaKey=!0,window.dispatchEvent(b),setTimeout(()=>{document.querySelector(".DocSearch-Modal")||d()},16)}function p(b){const P=b.target,w=P.tagName;return P.isContentEditable||w==="INPUT"||w==="SELECT"||w==="TEXTAREA"}const $=T(!1);ie("k",b=>{(b.ctrlKey||b.metaKey)&&(b.preventDefault(),$.value=!0)}),ie("/",b=>{p(b)||(b.preventDefault(),$.value=!0)});const V="local";return(b,P)=>{var w;return a(),u("div",Ls,[l(V)==="local"?(a(),u(I,{key:0},[$.value?(a(),k(l(e),{key:0,onClose:P[0]||(P[0]=A=>$.value=!1)})):m("",!0),v("div",Vs,[_(Pe,{onClick:P[1]||(P[1]=A=>$.value=!0)})])],64)):l(V)==="algolia"?(a(),u(I,{key:1},[n.value?(a(),k(l(t),{key:0,algolia:((w=l(o).search)==null?void 0:w.options)??l(o).algolia,onVnodeBeforeMount:P[2]||(P[2]=A=>r.value=!0)},null,8,["algolia"])):m("",!0),r.value?m("",!0):(a(),u("div",Ss,[_(Pe,{onClick:i})]))],64)):m("",!0)])}}}),ws=h({__name:"VPNavBarSocialLinks",setup(s){const{theme:e}=L();return(t,o)=>l(e).socialLinks?(a(),k(ye,{key:0,class:"VPNavBarSocialLinks",links:l(e).socialLinks},null,8,["links"])):m("",!0)}}),Ns=g(ws,[["__scopeId","data-v-05a069e5"]]),Ms=["href","rel","target"],Is=["innerHTML"],As={key:2},Bs=h({__name:"VPNavBarTitle",setup(s){const{site:e,theme:t}=L(),{hasSidebar:o}=G(),{currentLang:n}=Y(),r=y(()=>{var p;return typeof t.value.logoLink=="string"?t.value.logoLink:(p=t.value.logoLink)==null?void 0:p.link}),i=y(()=>{var p;return typeof t.value.logoLink=="string"||(p=t.value.logoLink)==null?void 0:p.rel}),d=y(()=>{var p;return typeof t.value.logoLink=="string"||(p=t.value.logoLink)==null?void 0:p.target});return(p,$)=>(a(),u("div",{class:N(["VPNavBarTitle",{"has-sidebar":l(o)}])},[v("a",{class:"title",href:r.value??l(_e)(l(n).link),rel:i.value,target:d.value},[c(p.$slots,"nav-bar-title-before",{},void 0,!0),l(t).logo?(a(),k(Q,{key:0,class:"logo",image:l(t).logo},null,8,["image"])):m("",!0),l(t).siteTitle?(a(),u("span",{key:1,innerHTML:l(t).siteTitle},null,8,Is)):l(t).siteTitle===void 0?(a(),u("span",As,M(l(e).title),1)):m("",!0),c(p.$slots,"nav-bar-title-after",{},void 0,!0)],8,Ms)],2))}}),Cs=g(Bs,[["__scopeId","data-v-91ea8bb2"]]),Hs={class:"items"},Es={class:"title"},Ds=h({__name:"VPNavBarTranslations",setup(s){const{theme:e}=L(),{localeLinks:t,currentLang:o}=Y({correspondingLink:!0});return(n,r)=>l(t).length&&l(o).label?(a(),k($e,{key:0,class:"VPNavBarTranslations",icon:"vpi-languages",label:l(e).langMenuLabel||"Change language"},{default:f(()=>[v("div",Hs,[v("p",Es,M(l(o).label),1),(a(!0),u(I,null,C(l(t),i=>(a(),k(ne,{key:i.link,item:i},null,8,["item"]))),128))])]),_:1},8,["label"])):m("",!0)}}),Fs=g(Ds,[["__scopeId","data-v-d986342a"]]),Os={class:"wrapper"},Gs={class:"container"},qs={class:"title"},Us={class:"content"},js={class:"content-body"},Rs=h({__name:"VPNavBar",props:{isScreenOpen:{type:Boolean}},emits:["toggle-screen"],setup(s){const e=s,{y:t}=Ae(),{hasSidebar:o}=G(),{frontmatter:n}=L(),r=T({});return he(()=>{r.value={"has-sidebar":o.value,home:n.value.layout==="home",top:t.value===0,"screen-open":e.isScreenOpen}}),(i,d)=>(a(),u("div",{class:N(["VPNavBar",r.value])},[v("div",Os,[v("div",Gs,[v("div",qs,[_(Cs,null,{"nav-bar-title-before":f(()=>[c(i.$slots,"nav-bar-title-before",{},void 0,!0)]),"nav-bar-title-after":f(()=>[c(i.$slots,"nav-bar-title-after",{},void 0,!0)]),_:3})]),v("div",Us,[v("div",js,[c(i.$slots,"nav-bar-content-before",{},void 0,!0),_(Ts,{class:"search"}),_(bs,{class:"menu"}),_(Fs,{class:"translations"}),_(wo,{class:"appearance"}),_(Ns,{class:"social-links"}),_(cs,{class:"extra"}),c(i.$slots,"nav-bar-content-after",{},void 0,!0),_(vs,{class:"hamburger",active:i.isScreenOpen,onClick:d[0]||(d[0]=p=>i.$emit("toggle-screen"))},null,8,["active"])])])])]),d[1]||(d[1]=v("div",{class:"divider"},[v("div",{class:"divider-line"})],-1))],2))}}),zs=g(Rs,[["__scopeId","data-v-8c74a6bf"]]),Ks={key:0,class:"VPNavScreenAppearance"},Ws={class:"text"},Js=h({__name:"VPNavScreenAppearance",setup(s){const{site:e,theme:t}=L();return(o,n)=>l(e).appearance&&l(e).appearance!=="force-dark"&&l(e).appearance!=="force-auto"?(a(),u("div",Ks,[v("p",Ws,M(l(t).darkModeSwitchLabel||"Appearance"),1),_(be)])):m("",!0)}}),Ys=g(Js,[["__scopeId","data-v-c279db8a"]]),Xs=["innerHTML"],Qs=h({__name:"VPNavScreenMenuLink",props:{item:{}},setup(s){const e=ee("close-screen");return(t,o)=>(a(),k(D,{class:"VPNavScreenMenuLink",href:t.item.link,target:t.item.target,rel:t.item.rel,"no-icon":t.item.noIcon,onClick:l(e)},{default:f(()=>[v("span",{innerHTML:t.item.text},null,8,Xs)]),_:1},8,["href","target","rel","no-icon","onClick"]))}}),Zs=g(Qs,[["__scopeId","data-v-9414c9d4"]]),xs=["innerHTML"],ea=h({__name:"VPNavScreenMenuGroupLink",props:{item:{}},setup(s){const e=ee("close-screen");return(t,o)=>(a(),k(D,{class:"VPNavScreenMenuGroupLink",href:t.item.link,target:t.item.target,rel:t.item.rel,"no-icon":t.item.noIcon,onClick:l(e)},{default:f(()=>[v("span",{innerHTML:t.item.text},null,8,xs)]),_:1},8,["href","target","rel","no-icon","onClick"]))}}),Ge=g(ea,[["__scopeId","data-v-893eacf4"]]),ta={class:"VPNavScreenMenuGroupSection"},na={key:0,class:"title"},oa=h({__name:"VPNavScreenMenuGroupSection",props:{text:{},items:{}},setup(s){return(e,t)=>(a(),u("div",ta,[e.text?(a(),u("p",na,M(e.text),1)):m("",!0),(a(!0),u(I,null,C(e.items,o=>(a(),k(Ge,{key:o.text,item:o},null,8,["item"]))),128))]))}}),sa=g(oa,[["__scopeId","data-v-420cc732"]]),aa=["aria-controls","aria-expanded"],ra=["innerHTML"],la=["id"],ia={key:0,class:"item"},ca={key:1,class:"item"},ua={key:2,class:"group"},da=h({__name:"VPNavScreenMenuGroup",props:{text:{},items:{}},setup(s){const e=s,t=T(!1),o=y(()=>`NavScreenGroup-${e.text.replace(" ","-").toLowerCase()}`);function n(){t.value=!t.value}return(r,i)=>(a(),u("div",{class:N(["VPNavScreenMenuGroup",{open:t.value}])},[v("button",{class:"button","aria-controls":o.value,"aria-expanded":t.value,onClick:n},[v("span",{class:"button-text",innerHTML:r.text},null,8,ra),i[0]||(i[0]=v("span",{class:"vpi-plus button-icon"},null,-1))],8,aa),v("div",{id:o.value,class:"items"},[(a(!0),u(I,null,C(r.items,d=>(a(),u(I,{key:JSON.stringify(d)},["link"in d?(a(),u("div",ia,[_(Ge,{item:d},null,8,["item"])])):"component"in d?(a(),u("div",ca,[(a(),k(E(d.component),U({ref_for:!0},d.props,{"screen-menu":""}),null,16))])):(a(),u("div",ua,[_(sa,{text:d.text,items:d.items},null,8,["text","items"])]))],64))),128))],8,la)],2))}}),va=g(da,[["__scopeId","data-v-29d942ed"]]),pa={key:0,class:"VPNavScreenMenu"},fa=h({__name:"VPNavScreenMenu",setup(s){const{theme:e}=L();return(t,o)=>l(e).nav?(a(),u("nav",pa,[(a(!0),u(I,null,C(l(e).nav,n=>(a(),u(I,{key:JSON.stringify(n)},["link"in n?(a(),k(Zs,{key:0,item:n},null,8,["item"])):"component"in n?(a(),k(E(n.component),U({key:1,ref_for:!0},n.props,{"screen-menu":""}),null,16)):(a(),k(va,{key:2,text:n.text||"",items:n.items},null,8,["text","items"]))],64))),128))])):m("",!0)}}),ma=h({__name:"VPNavScreenSocialLinks",setup(s){const{theme:e}=L();return(t,o)=>l(e).socialLinks?(a(),k(ye,{key:0,class:"VPNavScreenSocialLinks",links:l(e).socialLinks},null,8,["links"])):m("",!0)}}),ha={class:"list"},_a=h({__name:"VPNavScreenTranslations",setup(s){const{localeLinks:e,currentLang:t}=Y({correspondingLink:!0}),o=T(!1);function n(){o.value=!o.value}return(r,i)=>l(e).length&&l(t).label?(a(),u("div",{key:0,class:N(["VPNavScreenTranslations",{open:o.value}])},[v("button",{class:"title",onClick:n},[i[0]||(i[0]=v("span",{class:"vpi-languages icon lang"},null,-1)),j(" "+M(l(t).label)+" ",1),i[1]||(i[1]=v("span",{class:"vpi-chevron-down icon chevron"},null,-1))]),v("ul",ha,[(a(!0),u(I,null,C(l(e),d=>(a(),u("li",{key:d.link,class:"item"},[_(D,{class:"link",href:d.link},{default:f(()=>[j(M(d.text),1)]),_:2},1032,["href"])]))),128))])],2)):m("",!0)}}),ka=g(_a,[["__scopeId","data-v-d906a767"]]),ba={class:"container"},ga=h({__name:"VPNavScreen",props:{open:{type:Boolean}},setup(s){const e=T(null),t=Be(te?document.body:null);return(o,n)=>(a(),k(pe,{name:"fade",onEnter:n[0]||(n[0]=r=>t.value=!0),onAfterLeave:n[1]||(n[1]=r=>t.value=!1)},{default:f(()=>[o.open?(a(),u("div",{key:0,class:"VPNavScreen",ref_key:"screen",ref:e,id:"VPNavScreen"},[v("div",ba,[c(o.$slots,"nav-screen-content-before",{},void 0,!0),_(fa,{class:"menu"}),_(ka,{class:"translations"}),_(Ys,{class:"appearance"}),_(ma,{class:"social-links"}),c(o.$slots,"nav-screen-content-after",{},void 0,!0)])],512)):m("",!0)]),_:3}))}}),$a=g(ga,[["__scopeId","data-v-852a870e"]]),ya={key:0,class:"VPNav"},Pa=h({__name:"VPNav",setup(s){const{isScreenOpen:e,closeScreen:t,toggleScreen:o}=ko(),{frontmatter:n}=L(),r=y(()=>n.value.navbar!==!1);return Ce("close-screen",t),Z(()=>{te&&document.documentElement.classList.toggle("hide-nav",!r.value)}),(i,d)=>r.value?(a(),u("header",ya,[_(zs,{"is-screen-open":l(e),onToggleScreen:l(o)},{"nav-bar-title-before":f(()=>[c(i.$slots,"nav-bar-title-before",{},void 0,!0)]),"nav-bar-title-after":f(()=>[c(i.$slots,"nav-bar-title-after",{},void 0,!0)]),"nav-bar-content-before":f(()=>[c(i.$slots,"nav-bar-content-before",{},void 0,!0)]),"nav-bar-content-after":f(()=>[c(i.$slots,"nav-bar-content-after",{},void 0,!0)]),_:3},8,["is-screen-open","onToggleScreen"]),_($a,{open:l(e)},{"nav-screen-content-before":f(()=>[c(i.$slots,"nav-screen-content-before",{},void 0,!0)]),"nav-screen-content-after":f(()=>[c(i.$slots,"nav-screen-content-after",{},void 0,!0)]),_:3},8,["open"])])):m("",!0)}}),La=g(Pa,[["__scopeId","data-v-1125fe0e"]]),Va=["role","tabindex"],Sa={key:1,class:"items"},Ta=h({__name:"VPSidebarItem",props:{item:{},depth:{}},setup(s){const e=s,{collapsed:t,collapsible:o,isLink:n,isActiveLink:r,hasActiveLink:i,hasChildren:d,toggle:p}=gt(y(()=>e.item)),$=y(()=>d.value?"section":"div"),V=y(()=>n.value?"a":"div"),b=y(()=>d.value?e.depth+2===7?"p":`h${e.depth+2}`:"p"),P=y(()=>n.value?void 0:"button"),w=y(()=>[[`level-${e.depth}`],{collapsible:o.value},{collapsed:t.value},{"is-link":n.value},{"is-active":r.value},{"has-active":i.value}]);function A(S){"key"in S&&S.key!=="Enter"||!e.item.link&&p()}function B(){e.item.link&&p()}return(S,H)=>{const q=z("VPSidebarItem",!0);return a(),k(E($.value),{class:N(["VPSidebarItem",w.value])},{default:f(()=>[S.item.text?(a(),u("div",U({key:0,class:"item",role:P.value},Ze(S.item.items?{click:A,keydown:A}:{},!0),{tabindex:S.item.items&&0}),[H[1]||(H[1]=v("div",{class:"indicator"},null,-1)),S.item.link?(a(),k(D,{key:0,tag:V.value,class:"link",href:S.item.link,rel:S.item.rel,target:S.item.target},{default:f(()=>[(a(),k(E(b.value),{class:"text",innerHTML:S.item.text},null,8,["innerHTML"]))]),_:1},8,["tag","href","rel","target"])):(a(),k(E(b.value),{key:1,class:"text",innerHTML:S.item.text},null,8,["innerHTML"])),S.item.collapsed!=null&&S.item.items&&S.item.items.length?(a(),u("div",{key:2,class:"caret",role:"button","aria-label":"toggle section",onClick:B,onKeydown:Qe(B,["enter"]),tabindex:"0"},H[0]||(H[0]=[v("span",{class:"vpi-chevron-right caret-icon"},null,-1)]),32)):m("",!0)],16,Va)):m("",!0),S.item.items&&S.item.items.length?(a(),u("div",Sa,[S.depth<5?(a(!0),u(I,{key:0},C(S.item.items,K=>(a(),k(q,{key:K.text,item:K,depth:S.depth+1},null,8,["item","depth"]))),128)):m("",!0)])):m("",!0)]),_:1},8,["class"])}}}),wa=g(Ta,[["__scopeId","data-v-877bfe94"]]),Na=h({__name:"VPSidebarGroup",props:{items:{}},setup(s){const e=T(!0);let t=null;return O(()=>{t=setTimeout(()=>{t=null,e.value=!1},300)}),xe(()=>{t!=null&&(clearTimeout(t),t=null)}),(o,n)=>(a(!0),u(I,null,C(o.items,r=>(a(),u("div",{key:r.text,class:N(["group",{"no-transition":e.value}])},[_(wa,{item:r,depth:0},null,8,["item"])],2))),128))}}),Ma=g(Na,[["__scopeId","data-v-71286ee5"]]),Ia={class:"nav",id:"VPSidebarNav","aria-labelledby":"sidebar-aria-label",tabindex:"-1"},Aa=h({__name:"VPSidebar",props:{open:{type:Boolean}},setup(s){const{sidebarGroups:e,hasSidebar:t}=G(),o=s,n=T(null),r=Be(te?document.body:null);F([o,n],()=>{var d;o.open?(r.value=!0,(d=n.value)==null||d.focus()):r.value=!1},{immediate:!0,flush:"post"});const i=T(0);return F(e,()=>{i.value+=1},{deep:!0}),(d,p)=>l(t)?(a(),u("aside",{key:0,class:N(["VPSidebar",{open:d.open}]),ref_key:"navEl",ref:n,onClick:p[0]||(p[0]=et(()=>{},["stop"]))},[p[2]||(p[2]=v("div",{class:"curtain"},null,-1)),v("nav",Ia,[p[1]||(p[1]=v("span",{class:"visually-hidden",id:"sidebar-aria-label"}," Sidebar Navigation ",-1)),c(d.$slots,"sidebar-nav-before",{},void 0,!0),(a(),k(Ma,{items:l(e),key:i.value},null,8,["items"])),c(d.$slots,"sidebar-nav-after",{},void 0,!0)])],2)):m("",!0)}}),Ba=g(Aa,[["__scopeId","data-v-6b9869d7"]]),Ca=h({__name:"VPSkipLink",setup(s){const e=J(),t=T();F(()=>e.path,()=>t.value.focus());function o({target:n}){const r=document.getElementById(decodeURIComponent(n.hash).slice(1));if(r){const i=()=>{r.removeAttribute("tabindex"),r.removeEventListener("blur",i)};r.setAttribute("tabindex","-1"),r.addEventListener("blur",i),r.focus(),window.scrollTo(0,0)}}return(n,r)=>(a(),u(I,null,[v("span",{ref_key:"backToTop",ref:t,tabindex:"-1"},null,512),v("a",{href:"#VPContent",class:"VPSkipLink visually-hidden",onClick:o}," Skip to content ")],64))}}),Ha=g(Ca,[["__scopeId","data-v-a06310ac"]]),Ea=h({__name:"Layout",setup(s){const{isOpen:e,open:t,close:o}=G(),n=J();F(()=>n.path,o),bt(e,o);const{frontmatter:r}=L(),i=tt(),d=y(()=>!!i["home-hero-image"]);return Ce("hero-image-slot-exists",d),(p,$)=>{const V=z("Content");return l(r).layout!==!1?(a(),u("div",{key:0,class:N(["Layout",l(r).pageClass])},[c(p.$slots,"layout-top",{},void 0,!0),_(Ha),_(rt,{class:"backdrop",show:l(e),onClick:l(o)},null,8,["show","onClick"]),_(La,null,{"nav-bar-title-before":f(()=>[c(p.$slots,"nav-bar-title-before",{},void 0,!0)]),"nav-bar-title-after":f(()=>[c(p.$slots,"nav-bar-title-after",{},void 0,!0)]),"nav-bar-content-before":f(()=>[c(p.$slots,"nav-bar-content-before",{},void 0,!0)]),"nav-bar-content-after":f(()=>[c(p.$slots,"nav-bar-content-after",{},void 0,!0)]),"nav-screen-content-before":f(()=>[c(p.$slots,"nav-screen-content-before",{},void 0,!0)]),"nav-screen-content-after":f(()=>[c(p.$slots,"nav-screen-content-after",{},void 0,!0)]),_:3}),_(_o,{open:l(e),onOpenMenu:l(t)},null,8,["open","onOpenMenu"]),_(Ba,{open:l(e)},{"sidebar-nav-before":f(()=>[c(p.$slots,"sidebar-nav-before",{},void 0,!0)]),"sidebar-nav-after":f(()=>[c(p.$slots,"sidebar-nav-after",{},void 0,!0)]),_:3},8,["open"]),_(eo,null,{"page-top":f(()=>[c(p.$slots,"page-top",{},void 0,!0)]),"page-bottom":f(()=>[c(p.$slots,"page-bottom",{},void 0,!0)]),"not-found":f(()=>[c(p.$slots,"not-found",{},void 0,!0)]),"home-hero-before":f(()=>[c(p.$slots,"home-hero-before",{},void 0,!0)]),"home-hero-info-before":f(()=>[c(p.$slots,"home-hero-info-before",{},void 0,!0)]),"home-hero-info":f(()=>[c(p.$slots,"home-hero-info",{},void 0,!0)]),"home-hero-info-after":f(()=>[c(p.$slots,"home-hero-info-after",{},void 0,!0)]),"home-hero-actions-after":f(()=>[c(p.$slots,"home-hero-actions-after",{},void 0,!0)]),"home-hero-image":f(()=>[c(p.$slots,"home-hero-image",{},void 0,!0)]),"home-hero-after":f(()=>[c(p.$slots,"home-hero-after",{},void 0,!0)]),"home-features-before":f(()=>[c(p.$slots,"home-features-before",{},void 0,!0)]),"home-features-after":f(()=>[c(p.$slots,"home-features-after",{},void 0,!0)]),"doc-footer-before":f(()=>[c(p.$slots,"doc-footer-before",{},void 0,!0)]),"doc-before":f(()=>[c(p.$slots,"doc-before",{},void 0,!0)]),"doc-after":f(()=>[c(p.$slots,"doc-after",{},void 0,!0)]),"doc-top":f(()=>[c(p.$slots,"doc-top",{},void 0,!0)]),"doc-bottom":f(()=>[c(p.$slots,"doc-bottom",{},void 0,!0)]),"aside-top":f(()=>[c(p.$slots,"aside-top",{},void 0,!0)]),"aside-bottom":f(()=>[c(p.$slots,"aside-bottom",{},void 0,!0)]),"aside-outline-before":f(()=>[c(p.$slots,"aside-outline-before",{},void 0,!0)]),"aside-outline-after":f(()=>[c(p.$slots,"aside-outline-after",{},void 0,!0)]),"aside-ads-before":f(()=>[c(p.$slots,"aside-ads-before",{},void 0,!0)]),"aside-ads-after":f(()=>[c(p.$slots,"aside-ads-after",{},void 0,!0)]),_:3}),_(ao),c(p.$slots,"layout-bottom",{},void 0,!0)],2)):(a(),k(V,{key:1}))}}}),Da=g(Ea,[["__scopeId","data-v-39b851b6"]]),Le={Layout:Da,enhanceApp:({app:s})=>{s.component("Badge",ot)}};let ve=null;const Ve=(s,e,t)=>{let o=!0;s.value&&s.value.cbf!==void 0&&(o=s.value.cbf),document.querySelectorAll('.vp-doc [class*="language-"]').forEach((r,i)=>{const d=r;d.offsetHeight!==0&&d.offsetHeight<=t||(Array.isArray(o)?e?o.indexOf(i+1)===-1&&re(d,t):o.indexOf(i+1)!==-1&&re(d,t):e&&o&&re(d,t))}),!ve&&Ga()},Fa=(s,e)=>{new MutationObserver(t=>{t.forEach(o=>{const n=o.target;o.attributeName==="class"&&n.classList.contains("active")&&n.offsetHeight>e&&qe(s,e)})}).observe(s,{attributeFilter:["class"]})},re=(s,e)=>{const t=window.getComputedStyle(s,null).getPropertyValue("display"),o=s.parentElement.classList.contains("details");t==="none"||o?Fa(s,e):qe(s,e)},qe=(s,e)=>{if(s.classList.contains("fold"))return;s.classList.add("fold");const t=s.querySelectorAll("pre");t.forEach(r=>{r.style.height=e+"px",r.style.overflow="hidden"}),s.style.marginBottom="48px",s.style.borderRadius="8px 8px 0 0";const o=document.createElement("div"),n=document.createElement("div");n.style.backgroundImage="linear-gradient(-180deg, rgba(0, 0, 0, 0) 0%, var(--vp-code-block-bg) 100%)",n.className="codeblocks-mask",o.style.backgroundColor="var(--vp-code-block-bg)",o.className="fold-btn",o.insertAdjacentHTML("afterbegin",''),s.appendChild(n),s.appendChild(o),o.onclick=()=>{const r=s.querySelector(".codeblocks-mask"),i=s.querySelector(".fold-btn-icon");t.forEach(d=>{Ue({pre:d,foldBtn:o,iconElement:i,maskElement:r},e)})}},Ue=(s,e)=>{const{pre:t,foldBtn:o,iconElement:n,maskElement:r}=s;if(t.classList.contains("expand")){const i=o.getBoundingClientRect().top;t.style.height=e+"px",t.style.overflow="hidden",t.scrollTo(0,0),t.classList.remove("expand"),r.style.height="48px",n.classList.remove("turn"),window.scrollTo(0,o.getBoundingClientRect().top+window.scrollY-i)}else t.style.height="auto",t.style.overflow="auto",t.classList.add("expand"),r.style.height="0",n.classList.add("turn")},Se=s=>{document.querySelectorAll('.vp-doc [class*="language-"]').forEach(t=>{const o=t.querySelector(".fold-btn");o&&!o.onclick&&(o.onclick=()=>{const n=t.querySelector("pre"),r=t.querySelector(".codeblocks-mask"),i=t.querySelector(".fold-btn-icon");Ue({pre:n,foldBtn:o,iconElement:i,maskElement:r},s)})})};function Oa(s){return/^rgba\(\s*\d+\s*,\s*\d+\s*,\s*\d+\s*,\s*(0(\.\d+)?|1(\.0+)?)\s*\)$/i.test(s)}const Ga=()=>{Te(),ve=new MutationObserver(s=>{s.forEach(e=>{e.attributeName==="class"&&Te()})}),ve.observe(document.querySelector("html"),{attributeFilter:["class"]})},Te=()=>{document.querySelector('.vp-doc [class*="language-"]')&&(Oa(window.getComputedStyle(document.querySelector('.vp-doc [class*="language-"]'),null).getPropertyValue("background-color"))?W(()=>{document.querySelectorAll(".codeblocks-mask").forEach(e=>{e.style.display="none"})}).then():W(()=>{document.querySelectorAll(".codeblocks-mask").forEach(e=>{e.style.display=""})}).then())},qa=(s,e=!0,t=400)=>{const{frontmatter:o,route:n}=s;O(()=>{Ve(o,e,t),Se(t)}),F(()=>n.path,()=>{W(()=>{Ve(s.frontmatter,e,t),Se(t)}).then()})},ja={extends:Le,Layout:()=>nt(Le.Layout,null,{}),enhanceApp({app:s,router:e,siteData:t}){},setup(){const{frontmatter:s}=we(),e=J();qa({route:e,frontmatter:s},!0,400)}};export{ja as R,gs as c,L as u}; diff --git a/.vitepress/dist/assets/configuration_auth-config.md.CWCNki4x.js b/.vitepress/dist/assets/configuration_auth-config.md.CWCNki4x.js new file mode 100644 index 0000000..c91e4fb --- /dev/null +++ b/.vitepress/dist/assets/configuration_auth-config.md.CWCNki4x.js @@ -0,0 +1,1325 @@ +import{_ as i,c as a,a3 as n,o as l}from"./chunks/framework.DtMx7FFi.js";const d=JSON.parse('{"title":"Authelia Configuration","description":"","frontmatter":{"title":"Authelia Configuration"},"headers":[],"relativePath":"configuration/auth-config.md","filePath":"configuration/auth-config.md"}'),e={name:"configuration/auth-config.md"};function p(t,s,h,k,r,A){return l(),a("div",null,s[0]||(s[0]=[n(`

Authelia Configuration ​

Authelia, is our version of an SSO , as once you've logged into Authelia, you have access to all protected links. Attached below is the example configuration.yml file for Authelia. You can copy/paste this configuration, and then change all values surrounded in square brackets. Make sure to set passwords/tokens where REDACTED occurs. I recommend strings that are at least a length of 26 characters. This example configuration is perfect for 2FA with Authy out of the box, if you'd like to enable Duo , please see Authy/Duo Configuration for more details.

yaml
# yamllint disable rule:comments-indentation
+---
+###################################################################
+############
+# Authelia Configuration #
+###################################################################
+############
+## Note: the container by default expects to find this file at /config/configuration.yml.
+## Certificates directory specifies where Authelia will load trusted certificates (public portion) from in addition to
+## the system certificates store.
+## They should be in base64 format, and have one of the following extensions: *.cer, *.crt, *.pem.
+# certificates_directory: /config/certificates/
+## The theme to display: light, dark, grey, auto.
+theme: dark
+## The secret used to generate JWT tokens when validating user identity by email confirmation. JWT Secret can
+also be
+## set using a secret: https://www.authelia.com/c/secrets
+jwt_secret: REDACTED
+## Default redirection URL
+##
+## If user tries to authenticate without any referer, Authelia does not know where to redirect the user to at the
+end
+## of the authentication process. This parameter allows you to specify the default redirection URL Authelia will
+use
+## in such a case.
+##
+## Note: this parameter is optional. If not provided, user won't be redirected upon successful authentication.
+default_redirection_url: https://[domain.tld]/
+## Set the default 2FA method for new users and for when a user has a preferred method configured that has
+been
+## disabled. This setting must be a method that is enabled.
+## Options are totp, webauthn, mobile_push.
+default_2fa_method: "totp"
+##
+## Server Configuration
+##
+server:
+ ## The address to listen on.
+ host: 0.0.0.0
+ ## The port to listen on.
+ port: 9091
+ ## Set the single level path Authelia listens on.
+ ## Must be alphanumeric chars and should not contain any slashes.
+ path: "authelia"
+ ## Set the path on disk to Authelia assets.
+ ## Useful to allow overriding of specific static assets.
+ # asset_path: /config/assets/
+ ## Enables the pprof endpoint.
+ enable_pprof: false
+ ## Enables the expvars endpoint.
+ enable_expvars: false
+ ## Disables writing the health check vars to /app/.healthcheck.env which makes healthcheck.sh return exit
+code 0.
+ ## This is disabled by default if either /app/.healthcheck.env or /app/healthcheck.sh do not exist.
+ disable_healthcheck: false
+ ## Authelia by default doesn't accept TLS communication on the server port. This section overrides this
+behaviour.
+ tls:
+ ## The path to the DER base64/PEM format private key.
+ key: ""
+ ## The path to the DER base64/PEM format public certificate.
+ certificate: ""
+ ## The list of certificates for client authentication.
+ client_certificates: []
+ ## Server headers configuration/customization.
+ headers:
+ ## The CSP Template. Read the docs.
+ csp_template: ""
+ ## Server Buffers configuration.
+ # buffers:
+ ## Buffers usually should be configured to be the same value.
+ ## Explanation at https://www.authelia.com/c/server#buffer-sizes
+ ## Read buffer size adjusts the server's max incoming request size in bytes.
+ ## Write buffer size does the same for outgoing responses.
+ ## Read buffer.
+ # read: 4096
+ ## Write buffer.
+ # write: 4096
+ ## Server Timeouts configuration.
+ # timeouts:
+ ## Read timeout.
+ # read: 6s
+ ## Write timeout.
+ # write: 6s
+ ## Idle timeout.
+ # idle: 30s
+##
+## Log Configuration
+##
+log:
+ ## Level of verbosity for logs: info, debug, trace.
+ level: debug
+ ## Format the logs are written as: json, text.
+ # format: json
+ ## File path where the logs will be written. If not set logs are written to stdout.
+ # file_path: /config/authelia.log
+ ## Whether to also log to stdout when a log_file_path is defined.
+ # keep_stdout: false
+##
+## Telemetry Configuration
+##
+telemetry:
+ ##
+ ## Metrics Configuration
+ ##
+ metrics:
+ ## Enable Metrics.
+ enabled: false
+ ## The address to listen on for metrics. This should be on a different port to the main server.port value.
+ address: tcp://0.0.0.0:9959
+ ## Metrics Server Buffers configuration.
+ # buffers:
+ ## Read buffer.
+ # read: 4096
+ ## Write buffer.
+ # write: 4096
+ ## Metrics Server Timeouts configuration.
+ # timeouts:
+ ## Read timeout.
+ # read: 6s
+ ## Write timeout.
+ # write: 6s
+ ## Idle timeout.
+ # idle: 30s
+##
+## TOTP Configuration
+##
+## Parameters used for TOTP generation.
+totp:
+ ## Disable TOTP.
+ disable: false
+ ## The issuer name displayed in the Authenticator application of your choice.
+ issuer: [domain.tld]
+ ## The TOTP algorithm to use.
+ ## It is CRITICAL you read the documentation before changing this option:
+ ## https://www.authelia.com/c/totp#algorithm
+ algorithm: sha1
+ ## The number of digits a user has to input. Must either be 6 or 8.
+ ## Changing this option only affects newly generated TOTP configurations.
+ ## It is CRITICAL you read the documentation before changing this option:
+ ## https://www.authelia.com/c/totp#digits
+ digits: 8
+ ## The period in seconds a one-time password is valid for.
+ ## Changing this option only affects newly generated TOTP configurations.
+ period: 30
+ ## The skew controls number of one-time passwords either side of the current one that are valid.
+ ## Warning: before changing skew read the docs link below.
+ skew: 1
+ ## See: https://www.authelia.com/c/totp#input-validation to read
+ ## the documentation.
+ ## The size of the generated shared secrets. Default is 32 and is sufficient in most use cases, minimum is 20.
+ secret_size: 32
+##
+## WebAuthn Configuration
+##
+## Parameters used for WebAuthn.
+webauthn:
+ ## Disable Webauthn.
+ disable: false
+ ## Adjust the interaction timeout for Webauthn dialogues.
+ timeout: 60s
+ ## The display name the browser should show the user for when using Webauthn to login/register.
+ display_name: Authelia
+ ## Conveyance preference controls if we collect the attestation statement including the AAGUID from the
+device.
+ ## Options are none, indirect, direct.
+ attestation_conveyance_preference: indirect
+ ## User verification controls if the user must make a gesture or action to confirm they are present.
+ ## Options are required, preferred, discouraged.
+ user_verification: preferred
+##
+## Duo Push API Configuration
+##
+## Parameters used to contact the Duo API. Those are generated when you protect an application of type
+## "Partner Auth API" in the management panel.
+# duo_api:
+ # disable: false
+ # hostname: api-123456789.example.com
+ # integration_key: ABCDEF
+ ## Secret can also be set using a secret: https://www.authelia.com/c/secrets
+ # secret_key: 1234567890abcdefghifjkl
+ # enable_self_enrollment: false
+##
+## NTP Configuration
+##
+## This is used to validate the servers time is accurate enough to validate TOTP.
+ntp:
+ ## NTP server address.
+ address: "time.cloudflare.com:123"
+ ## NTP version.
+ version: 4
+ ## Maximum allowed time offset between the host and the NTP server.
+ max_desync: 3s
+ ## Disables the NTP check on startup entirely. This means Authelia will not contact a remote service at all if
+you
+ ## set this to true, and can operate in a truly offline mode.
+ disable_startup_check: false
+ ## The default of false will prevent startup only if we can contact the NTP server and the time is out of sync
+with
+ ## the NTP server more than the configured max_desync. If you set this to true, an error will be logged but
+startup
+ ## will continue regardless of results.
+ disable_failure: false
+##
+## Authentication Backend Provider Configuration
+##
+## Used for verifying user passwords and retrieve information such as email address and groups users belong
+to.
+##
+## The available providers are: \`file\`, \`ldap\`. You must use only one of these providers.
+authentication_backend:
+ ## Password Reset Options.
+ password_reset:
+ ## Disable both the HTML element and the API for reset password functionality.
+ disable: false
+ ## External reset password url that redirects the user to an external reset portal. This disables the internal
+reset
+ ## functionality.
+ custom_url: ""
+ ## The amount of time to wait before we refresh data from the authentication backend. Uses duration
+notation.
+ ## To disable this feature set it to 'disable', this will slightly reduce security because for Authelia, users will
+ ## always belong to groups they belonged to at the time of login even if they have been removed from them
+in LDAP.
+ ## To force update on every request you can set this to '0' or 'always', this will increase processor demand.
+ ## See the below documentation for more information.
+ ## Duration Notation docs: https://www.authelia.com/c/common#duration-notation-format
+ ## Refresh Interval docs: https://www.authelia.com/c/1fa#refresh-interval
+ refresh_interval: 5m
+ ##
+ ## LDAP (Authentication Provider)
+ ##
+ ## This is the recommended Authentication Provider in production
+ ## because it allows Authelia to offload the stateful operations
+ ## onto the LDAP service.
+ ldap:
+ ## The LDAP implementation, this affects elements like the attribute utilised for resetting a password.
+ ## Acceptable options are as follows:
+ ## - 'activedirectory' - For Microsoft Active Directory.
+ ## - 'custom' - For custom specifications of attributes and filters.
+ ## This currently defaults to 'custom' to maintain existing behaviour.
+ ##
+ ## Depending on the option here certain other values in this section have a default value, notably all of the
+ ## attribute mappings have a default value that this config overrides, you can read more about these default
+values
+ ## at https://www.authelia.com/c/ldap#defaults
+ implementation: custom
+ ## The url to the ldap server. Format: <scheme>://<address>[:<port>].
+ ## Scheme can be ldap or ldaps in the format (port optional).
+ url: ldap://lldap:3890
+ ## The dial timeout for LDAP.
+ timeout: 5s
+ ## Use StartTLS with the LDAP connection.
+ start_tls: false
+ # tls:
+ ## The server subject name to check the servers certificate against during the validation process.
+ ## This option is not required if the certificate has a SAN which matches the host portion of the url option.
+ # server_name: ldap.example.com
+ ## Skip verifying the server certificate entirely. In preference to setting this we strongly recommend you
+add the
+ ## certificate or the certificate of the authority signing the certificate to the certificates directory which is
+ ## defined by the \`certificates_directory\` option at the top of the configuration.
+ ## It's important to note the public key should be added to the directory, not the private key.
+ ## This option is strongly discouraged but may be useful in some self-signed situations where validation is
+not
+ ## important to the administrator.
+ # skip_verify: false
+ ## Minimum TLS version for the connection.
+ # minimum_version: TLS1.2
+ ## Maximum TLS version for the connection.
+ # maximum_version: TLS1.3
+ ## The certificate chain used with the private_key if the server requests TLS Client Authentication
+ ## i.e. Mutual TLS.
+ # certificate_chain: |
+ # -----BEGIN CERTIFICATE-----
+ # MIIC5jCCAc6gAwIBAgIRAK4Sj7FiN6PXo/urPfO4E7owDQYJKoZIhvcNAQELBQAw
+ # EzERMA8GA1UEChMIQXV0aGVsaWEwHhcNNzAwMTAxMDAwMDAwWhcNNzEwMTAxMDAw
+ # MDAwWjATMREwDwYDVQQKEwhBdXRoZWxpYTCCASIwDQYJKoZIhvcNAQEBBQADggEP
+ # ADCCAQoCggEBAPKv3pSyP4ozGEiVLJ14dIWFCEGEgq7WUMI0SZZqQA2ID0L59U/Q
+ # /Usyy7uC9gfMUzODTpANtkOjFQcQAsxlR1FOjVBrX5QgjSvXwbQn3DtwMA7XWSl6
+ # LuYx2rBYSlMSN5UZQm/RxMtXfLK2b51WgEEYDFi+nECSqKzR4R54eOPkBEWRfvuY
+ # 91AMjlhpivg8e4JWkq4LVQUKbmiFYwIdK8XQiN4blY9WwXwJFYs5sQ/UYMwBFi0H
+ # kWOh7GEjfxgoUOPauIueZSMSlQp7zqAH39N0ZSYb6cS0Npj57QoWZSY3ak87ebcR
+ # Nf4rCvZLby7LoN7qYCKxmCaDD3x2+NYpWH8CAwEAAaM1MDMwDgYDVR0PAQH/BAQD
+ # AgWgMBMGA1UdJQQMMAoGCCsGAQUFBwMBMAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcN
+ # AQELBQADggEBAHSITqIQSNzonFl3DzxHPEzr2hp6peo45buAAtu8FZHoA+U7Icfh
+ # /ZXjPg7Xz+hgFwM/DTNGXkMWacQA/PaNWvZspgRJf2AXvNbMSs2UQODr7Tbv+Fb4
+ # lyblmMUNYFMCFVAMU0eIxXAFq2qcwv8UMcQFT0Z/35s6PVOakYnAGGQjTfp5Ljuq
+ # wsdc/xWmM0cHWube6sdRRUD7SY20KU/kWzl8iFO0VbSSrDf1AlEhnLEkp1SPaxXg
+ # OdBnl98MeoramNiJ7NT6Jnyb3zZ578fjaWfThiBpagItI8GZmG4s4Ovh2JbheN8i
+ # ZsjNr9jqHTjhyLVbDRlmJzcqoj4JhbKs6/I^invalid DO NOT USE=
+ # -----END CERTIFICATE-----
+ # -----BEGIN CERTIFICATE-----
+ # MIIDBDCCAeygAwIBAgIRALJsPg21kA0zY4F1wUCIuoMwDQYJKoZIhvcNAQELBQAw
+ # EzERMA8GA1UEChMIQXV0aGVsaWEwHhcNNzAwMTAxMDAwMDAwWhcNNzEwMTAxMDAw
+ # MDAwWjATMREwDwYDVQQKEwhBdXRoZWxpYTCCASIwDQYJKoZIhvcNAQEBBQADggEP
+ # ADCCAQoCggEBAMXHBvVxUzYk0u34/DINMSF+uiOekKOAjOrC6Mi9Ww8ytPVO7t2S
+ # zfTvM+XnEJqkFQFgimERfG/eGhjF9XIEY6LtnXe8ATvOK4nTwdufzBaoeQu3Gd50
+ # 5VXr6OHRo//ErrGvFXwP3g8xLePABsi/fkH3oDN+ztewOBMDzpd+KgTrk8ysv2ou
+ # kNRMKFZZqASvCgv0LD5KWvUCnL6wgf1oTXG7aztduA4oSkUP321GpOmBC5+5ElU7
+ # ysoRzvD12o9QJ/IfEaulIX06w9yVMo60C/h6A3U6GdkT1SiyTIqR7v7KU/IWd/Qi
+ # Lfftcj91VhCmJ73Meff2e2S2PrpjdXbG5FMCAwEAAaNTMFEwDgYDVR0PAQH/BAQD
+ # AgKkMA8GA1UdJQQIMAYGBFUdJQAwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU
+ # Z7AtA3mzFc0InSBA5fiMfeLXA3owDQYJKoZIhvcNAQELBQADggEBAEE5hm1mtlk/
+ # kviCoHH4evbpw7rxPxDftIQlqYTtvMM4eWY/6icFoSZ4fUHEWYyps8SsPu/8f2tf
+ # 71LGgZn0FdHi1QU2H8m0HHK7TFw+5Q6RLrLdSyk0PItJ71s9en7r8pX820nAFEHZ
+ # HkOSfJZ7B5hFgUDkMtVM6bardXAhoqcMk4YCU96e9d4PB4eI+xGc+mNuYvov3RbB
+ # D0s8ICyojeyPVLerz4wHjZu68Z5frAzhZ68YbzNs8j2fIBKKHkHyLG1iQyF+LJVj
+ # 2PjCP+auJsj6fQQpMGoyGtpLcSDh+ptcTngUD8JsWipzTCjmaNqdPHAOYmcgtf4b
+ # qocikt3WAdU^invalid DO NOT USE=
+ # -----END CERTIFICATE-----
+ ## The private key used with the certificate_chain if the server requests TLS Client Authentication
+ ## i.e. Mutual TLS.
+ # private_key: |
+ # -----BEGIN RSA PRIVATE KEY-----
+ # MIIEpAIBAAKCAQEA8q/elLI/ijMYSJUsnXh0hYUIQYSCrtZQwjRJlmpADYgPQvn1
+ # T9D9SzLLu4L2B8xTM4NOkA22Q6MVBxACzGVHUU6NUGtflCCNK9fBtCfcO3AwDtdZ
+ # KXou5jHasFhKUxI3lRlCb9HEy1d8srZvnVaAQRgMWL6cQJKorNHhHnh44+QERZF+
+ # +5j3UAyOWGmK+Dx7glaSrgtVBQpuaIVjAh0rxdCI3huVj1bBfAkVizmxD9RgzAEW
+ # LQeRY6HsYSN/GChQ49q4i55lIxKVCnvOoAff03RlJhvpxLQ2mPntChZlJjdqTzt5
+ # txE1/isK9ktvLsug3upgIrGYJoMPfHb41ilYfwIDAQABAoIBAQDTOdFf2JjHH1um
+ # aPgRAvNf9v7Nj5jytaRKs5nM6iNf46ls4QPreXnMhqSeSwj6lpNgBYxOgzC9Q+cc
+ # Y4ob/paJJPaIJTxmP8K/gyWcOQlNToL1l+eJ20eQoZm23NGr5fIsunSBwLEpTrdB
+ # ENqqtcwhW937K8Pxy/Q1nuLyU2bc6Tn/ivLozc8n27dpQWWKh8537VY7ancIaACr
+ # LJJLYxKqhQpjtBWAyCDvZQirnAOm9KnvIHaGXIswCZ4Xbsu0Y9NL+woARPyRVQvG
+ # jfxy4EmO9s1s6y7OObSukwKDSNihAKHx/VIbvVWx8g2Lv5fGOa+J2Y7o9Qurs8t5
+ # BQwMTt0BAoGBAPUw5Z32EszNepAeV3E2mPFUc5CLiqAxagZJuNDO2pKtyN29ETTR
+ # Ma4O1cWtGb6RqcNNN/Iukfkdk27Q5nC9VJSUUPYelOLc1WYOoUf6oKRzE72dkMQV
+ # R4bf6TkjD+OVR17fAfkswkGahZ5XA7j48KIQ+YC4jbnYKSxZTYyKPjH/AoGBAP1i
+ # tqXt36OVlP+y84wWqZSjMelBIVa9phDVGJmmhz3i1cMni8eLpJzWecA3pfnG6Tm9
+ # ze5M4whASleEt+M00gEvNaU9ND+z0wBfi+/DwJYIbv8PQdGrBiZFrPhTPjGQUldR
+ # lXccV2meeLZv7TagVxSi3DO6dSJfSEHyemd5j9mBAoGAX8Hv+0gOQZQCSOTAq8Nx
+ # 6dZcp9gHlNaXnMsP9eTDckOSzh636JPGvj6m+GPJSSbkURUIQ3oyokMNwFqvlNos
+ # fTaLhAOfjBZI9WnDTTQxpugWjphJ4HqbC67JC/qIiw5S6FdaEvGLEEoD4zoChywZ
+ # 9oGAn+fz2d/0/JAH/FpFPgsCgYEAp/ipZgPzziiZ9ov1wbdAQcWRj7RaWnssPFpX
+ # jXwEiXT3CgEMO4MJ4+KWIWOChrti3qFBg6i6lDyyS6Qyls7sLFbUdC7HlTcrOEMe
+ # rBoTcCI1GqZNlqWOVQ65ZIEiaI7o1vPBZo2GMQEZuq8mDKFsOMThvvTrM5cAep84
+ # n6HJR4ECgYABWcbsSnr0MKvVth/inxjbKapbZnp2HUCuw87Ie5zK2Of/tbC20wwk
+ # yKw3vrGoE3O1t1g2m2tn8UGGASeZ842jZWjIODdSi5+icysQGuULKt86h/woz2SQ
+ # 27GoE2i5mh6Yez6VAYbUuns3FcwIsMyWLq043Tu2DNkx9ijOOAuQzw^invalid..
+ # DO NOT USE==
+ # -----END RSA PRIVATE KEY-----
+ ## The distinguished name of the container searched for objects in the directory information tree.
+ ## See also: additional_users_dn, additional_groups_dn.
+ base_dn: dc=[domain],dc=[tld]
+ ## The attribute holding the username of the user. This attribute is used to populate the username in the
+session
+ ## information. For your information, Microsoft Active Directory usually uses 'sAMAccountName' and
+OpenLDAP usually
+ ## uses 'uid'. Beware that this attribute holds the unique identifiers for the users binding the user and the
+ ## configuration stored in database. Therefore only single value attributes are allowed and the value must
+never be
+ ## changed once attributed to a user otherwise it would break the configuration for that user. Technically,
+ ## non-unique attributes like 'mail' can also be used but we don't recommend using them, we instead advise
+to use
+ ## a filter to perform alternative lookups and the attributes mentioned above (sAMAccountName and uid) to
+ ## follow https://www.ietf.org/rfc/rfc2307.txt.
+ username_attribute: uid
+ ## The additional_users_dn is prefixed to base_dn and delimited by a comma when searching for users.
+ ## i.e. with this set to OU=Users and base_dn set to DC=a,DC=com; OU=Users,DC=a,DC=com is searched
+for users.
+ additional_users_dn: ou=people
+ ## The users filter used in search queries to find the user profile based on input filled in login form.
+ ## Various placeholders are available in the user filter which you can read about in the documentation which
+can
+ ## be found at: https://www.authelia.com/c/ldap#users-filter-replacements
+ ##
+ ## Recommended settings are as follows:
+ ## - Microsoft Active Directory:
+(&({username_attribute}={input})(objectCategory=person)(objectClass=user))
+ ## - OpenLDAP:
+ ## - (&({username_attribute}={input})(objectClass=person))
+ ## - (&({username_attribute}={input})(objectClass=inetOrgPerson))
+ ##
+ ## To allow sign in both with username and email, one can use a filter like
+ ## (&(|({username_attribute}={input})({mail_attribute}={input}))(objectClass=person))
+ users_filter: (&({username_attribute}={input})(objectClass=person))
+ ## The additional_groups_dn is prefixed to base_dn and delimited by a comma when searching for groups.
+ ## i.e. with this set to OU=Groups and base_dn set to DC=a,DC=com; OU=Groups,DC=a,DC=com is
+searched for groups.
+ additional_groups_dn: ou=groups
+ ## The groups filter used in search queries to find the groups based on relevant authenticated user.
+ ## Various placeholders are available in the groups filter which you can read about in the documentation
+which can
+ ## be found at: https://www.authelia.com/c/ldap#groups-filter-replacements
+ ##
+ ## If your groups use the \`groupOfUniqueNames\` structure use this instead:
+ ## (&(uniqueMember={dn})(objectClass=groupOfUniqueNames))
+ groups_filter: (&(member={dn})(objectClass=groupOfUniqueNames))
+ ## The attribute holding the name of the group.
+ group_name_attribute: cn
+ ## The attribute holding the mail address of the user. If multiple email addresses are defined for a user, only
+the
+ ## first one returned by the LDAP server is used.
+ mail_attribute: mail
+ ## The attribute holding the display name of the user. This will be used to greet an authenticated user.
+ display_name_attribute: displayName
+ ## Follow referrals returned by the server.
+ ## This is especially useful for environments where read-only servers exist. Only implemented for write
+operations.
+ # permit_referrals: false
+ ## The username and password of the admin user.
+ user: cn=admin,ou=people,dc=[domain],dc=[tld]
+ ## Password can also be set using a secret: https://www.authelia.com/c/secrets
+ password: "REDACTED"
+ ##
+ ## File (Authentication Provider)
+ ##
+ ## With this backend, the users database is stored in a file which is updated when users reset their passwords.
+ ## Therefore, this backend is meant to be used in a dev environment and not in production since it prevents
+Authelia
+ ## to be scaled to more than one instance. The options under 'password' have sane defaults, and as it has
+security
+ ## implications it is highly recommended you leave the default values. Before considering changing these
+settings
+ ## please read the docs page below:
+ ## https://www.authelia.com/r/passwords#tuning
+ ##
+ ## Important: Kubernetes (or HA) users must read https://www.authelia.com/t/statelessness
+ ##
+ # file:
+ # path: /config/users_database.yml
+ # watch: false
+ # search:
+ # email: false
+ # case_insensitive: false
+ # password:
+ # algorithm: argon2
+ # argon2:
+ # variant: argon2id
+ # iterations: 3
+ # memory: 65536
+ # parallelism: 4
+ # key_length: 32
+ # salt_length: 16
+ # scrypt:
+ # iterations: 16
+ # block_size: 8
+ # parallelism: 1
+ # key_length: 32
+ # salt_length: 16
+ # pbkdf2:
+ # variant: sha512
+ # iterations: 310000
+ # salt_length: 16
+ # sha2crypt:
+ # variant: sha512
+ # iterations: 50000
+ # salt_length: 16
+ # bcrypt:
+ # variant: standard
+ # cost: 12
+##
+## Password Policy Configuration.
+##
+password_policy:
+ ## The standard policy allows you to tune individual settings manually.
+ standard:
+ enabled: true
+ ## Require a minimum length for passwords.
+ min_length: 8
+ ## Require a maximum length for passwords.
+ max_length: 0
+ ## Require uppercase characters.
+ require_uppercase: true
+ ## Require lowercase characters.
+ require_lowercase: true
+ ## Require numeric characters.
+ require_number: true
+ ## Require special characters.
+ require_special: true
+ ## zxcvbn is a well known and used password strength algorithm. It does not have tunable settings.
+ zxcvbn:
+ enabled: false
+ ## Configures the minimum score allowed.
+ min_score: 3
+##
+## Access Control Configuration
+##
+## Access control is a list of rules defining the authorizations applied for one resource to users or group of
+users.
+##
+## If 'access_control' is not defined, ACL rules are disabled and the 'bypass' rule is applied, i.e., access is
+allowed
+## to anyone. Otherwise restrictions follow the rules defined.
+##
+## Note: One can use the wildcard * to match any subdomain.
+## It must stand at the beginning of the pattern. (example: *.example.com)
+##
+## Note: You must put patterns containing wildcards between simple quotes for the YAML to be syntactically
+correct.
+##
+## Definition: A 'rule' is an object with the following keys: 'domain', 'subject', 'policy' and 'resources'.
+##
+## - 'domain' defines which domain or set of domains the rule applies to.
+##
+## - 'subject' defines the subject to apply authorizations to. This parameter is optional and matching any user if
+not
+## provided. If provided, the parameter represents either a user or a group. It should be of the form
+## 'user:<username>' or 'group:<groupname>'.
+##
+## - 'policy' is the policy to apply to resources. It must be either 'bypass', 'one_factor', 'two_factor' or 'deny'.
+##
+## - 'resources' is a list of regular expressions that matches a set of resources to apply the policy to. This
+parameter
+## is optional and matches any resource if not provided.
+##
+## Note: the order of the rules is important. The first policy matching (domain, resource, subject) applies.
+access_control:
+ ## Default policy can either be 'bypass', 'one_factor', 'two_factor' or 'deny'. It is the policy applied to any
+ ## resource if there is no policy to be applied to the user.
+ default_policy: deny
+ # networks:
+ # - name: internal
+ # networks:
+ # - 10.10.0.0/16
+ # - 192.168.2.0/24
+ # - name: VPN
+ # networks: 10.9.0.0/16
+ rules:
+ ## Rules applied to everyone
+ ## This below policy allows for auth to be accessed at all times,
+ ## useful when trying to login without the main page available.
+ - domain:
+ - 'auth.[domain.tld]'
+ policy: bypass
+ ## This below policy example will exclude a user from using 2FA,
+ ## useful if the user has no way of configuring 2FA.
+ - domain:
+ - '[domain.tld]'
+ - '*.[domain.tld]'
+ subject:
+ - "user:[USERNAME/UID]"
+ policy: one_factor
+ ## This below policy example will exclude all users of the people
+ ## group from using 2FA, NOT RECOMMENDED
+ - domain:
+ - '[domain.tld]'
+ - '*.[domain.tld]'
+ subject:
+ - "group:people"
+ policy: one_factor
+ ## This below policy will require all users of the LLDAP_Admin group
+ ## in LLDAP to use 2FA BY DEFAULT, this is the strongest policy available
+ - domain:
+ - '[domain.tld]'
+ - '*.[domain.tld]'
+ subject:
+ - "group:lldap_admin"
+ policy: two_factor
+ ## Domain Regex examples. Generally we recommend just using a standard domain.
+ # - domain_regex: '^(?P<User>\\w+)\\.example\\.com$'
+ # policy: one_factor
+ # - domain_regex: '^(?P<Group>\\w+)\\.example\\.com$'
+ # policy: one_factor
+ # - domain_regex:
+ # - '^appgroup-.*\\.example\\.com$'
+ # - '^appgroup2-.*\\.example\\.com$'
+ # policy: one_factor
+ # - domain_regex: '^.*\\.example\\.com$'
+ # policy: two_factor
+ # - domain: 'secure.example.com'
+ # policy: one_factor
+ ## Network based rule, if not provided any network matches.
+ # networks:
+ # - internal
+ # - VPN
+ # - 192.168.1.0/24
+ # - 10.0.0.1
+ # - domain:
+ # - 'secure.example.com'
+ # - 'private.example.com'
+ # policy: two_factor
+ # - domain: 'singlefactor.example.com'
+ # policy: one_factor
+ ## Rules applied to 'admins' group
+ # - domain: 'mx2.mail.example.com'
+ # subject: 'group:admins'
+ # policy: deny
+ # - domain: '*.example.com'
+ # subject:
+ # - 'group:admins'
+ # - 'group:moderators'
+ # policy: two_factor
+ ## Rules applied to 'dev' group
+ # - domain: 'dev.example.com'
+ # resources:
+ # - '^/groups/dev/.*$'
+ # subject: 'group:dev'
+ # policy: two_factor
+ ## Rules applied to user 'john'
+ # - domain: 'dev.example.com'
+ # resources:
+ # - '^/users/john/.*$'
+ # subject: 'user:john'
+ # policy: two_factor
+ ## Rules applied to user 'harry'
+ # - domain: 'dev.example.com'
+ # resources:
+ # - '^/users/harry/.*$'
+ # subject: 'user:harry'
+ # policy: two_factor
+ ## Rules applied to user 'bob'
+ # - domain: '*.mail.example.com'
+ # subject: 'user:bob'
+ # policy: two_factor
+ # - domain: 'dev.example.com'
+ # resources:
+ # - '^/users/bob/.*$'
+ # subject: 'user:bob'
+ # policy: two_factor
+##
+## Session Provider Configuration
+##
+## The session cookies identify the user once logged in.
+## The available providers are: \`memory\`, \`redis\`. Memory is the provider unless redis is defined.
+session:
+ ## The name of the session cookie.
+ name: authelia_session
+ ## The domain to protect.
+ ## Note: the authenticator must also be in that domain.
+ ## If empty, the cookie is restricted to the subdomain of the issuer.
+ domain: [domain.tld]
+ ## Sets the Cookie SameSite value. Possible options are none, lax, or strict.
+ ## Please read https://www.authelia.com/c/session#same_site
+ same_site: lax
+ ## The secret to encrypt the session data. This is only used with Redis / Redis Sentinel.
+ ## Secret can also be set using a secret: https://www.authelia.com/c/secrets
+ secret: REDACTED
+ ## The value for expiration, inactivity, and remember_me_duration are in seconds or the duration notation
+format.
+ ## See: https://www.authelia.com/c/common#duration-notation-format
+ ## All three of these values affect the cookie/session validity period. Longer periods are considered less secure
+ ## because a stolen cookie will last longer giving attackers more time to spy or attack.
+ ## The time before the cookie expires and the session is destroyed if remember me IS NOT selected.
+ expiration: 1h
+ ## The inactivity time before the session is reset. If expiration is set to 1h, and this is set to 5m, if the user
+ ## does not select the remember me option their session will get destroyed after 1h, or after 5m since the last
+time
+ ## Authelia detected user activity.
+ inactivity: 5m
+ ## The time before the cookie expires and the session is destroyed if remember me IS selected.
+ ## Value of -1 disables remember me.
+ remember_me_duration: 2M
+ ##
+ ## Redis Provider
+ ##
+ ## Important: Kubernetes (or HA) users must read https://www.authelia.com/t/statelessness
+ ##
+ redis:
+ host: redis
+ port: 6379
+ ## Use a unix socket instead
+ # host: /var/run/redis/redis.sock
+ ## Username used for redis authentication. This is optional and a new feature in redis 6.0.
+ # username: authelia
+ ## Password can also be set using a secret: https://www.authelia.com/c/secrets
+ password: REDACTED
+ ## This is the Redis DB Index https://redis.io/commands/select (sometimes referred to as database number,
+DB, etc).
+ database_index: 0
+ ## The maximum number of concurrent active connections to Redis.
+ maximum_active_connections: 10
+ ## The target number of idle connections to have open ready for work. Useful when opening connections is
+slow.
+ minimum_idle_connections: 0
+ ## The Redis TLS configuration. If defined will require a TLS connection to the Redis instance(s).
+ # tls:
+ ## The server subject name to check the servers certificate against during the validation process.
+ ## This option is not required if the certificate has a SAN which matches the host option.
+ # server_name: myredis.example.com
+ ## Skip verifying the server certificate entirely. In preference to setting this we strongly recommend you
+add the
+ ## certificate or the certificate of the authority signing the certificate to the certificates directory which is
+ ## defined by the \`certificates_directory\` option at the top of the configuration.
+ ## It's important to note the public key should be added to the directory, not the private key.
+ ## This option is strongly discouraged but may be useful in some self-signed situations where validation is
+not
+ ## important to the administrator.
+ # skip_verify: false
+ ## Minimum TLS version for the connection.
+ # minimum_version: TLS1.2
+ ## Maximum TLS version for the connection.
+ # maximum_version: TLS1.3
+ ## The certificate chain used with the private_key if the server requests TLS Client Authentication
+ ## i.e. Mutual TLS.
+ # certificate_chain: |
+ # -----BEGIN CERTIFICATE-----
+ # MIIC5jCCAc6gAwIBAgIRAK4Sj7FiN6PXo/urPfO4E7owDQYJKoZIhvcNAQELBQAw
+ # EzERMA8GA1UEChMIQXV0aGVsaWEwHhcNNzAwMTAxMDAwMDAwWhcNNzEwMTAxMDAw
+ # MDAwWjATMREwDwYDVQQKEwhBdXRoZWxpYTCCASIwDQYJKoZIhvcNAQEBBQADggEP
+ # ADCCAQoCggEBAPKv3pSyP4ozGEiVLJ14dIWFCEGEgq7WUMI0SZZqQA2ID0L59U/Q
+ # /Usyy7uC9gfMUzODTpANtkOjFQcQAsxlR1FOjVBrX5QgjSvXwbQn3DtwMA7XWSl6
+ # LuYx2rBYSlMSN5UZQm/RxMtXfLK2b51WgEEYDFi+nECSqKzR4R54eOPkBEWRfvuY
+ # 91AMjlhpivg8e4JWkq4LVQUKbmiFYwIdK8XQiN4blY9WwXwJFYs5sQ/UYMwBFi0H
+ # kWOh7GEjfxgoUOPauIueZSMSlQp7zqAH39N0ZSYb6cS0Npj57QoWZSY3ak87ebcR
+ # Nf4rCvZLby7LoN7qYCKxmCaDD3x2+NYpWH8CAwEAAaM1MDMwDgYDVR0PAQH/BAQD
+ # AgWgMBMGA1UdJQQMMAoGCCsGAQUFBwMBMAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcN
+ # AQELBQADggEBAHSITqIQSNzonFl3DzxHPEzr2hp6peo45buAAtu8FZHoA+U7Icfh
+ # /ZXjPg7Xz+hgFwM/DTNGXkMWacQA/PaNWvZspgRJf2AXvNbMSs2UQODr7Tbv+Fb4
+ # lyblmMUNYFMCFVAMU0eIxXAFq2qcwv8UMcQFT0Z/35s6PVOakYnAGGQjTfp5Ljuq
+ # wsdc/xWmM0cHWube6sdRRUD7SY20KU/kWzl8iFO0VbSSrDf1AlEhnLEkp1SPaxXg
+ # OdBnl98MeoramNiJ7NT6Jnyb3zZ578fjaWfThiBpagItI8GZmG4s4Ovh2JbheN8i
+ # ZsjNr9jqHTjhyLVbDRlmJzcqoj4JhbKs6/I^invalid DO NOT USE=
+ # -----END CERTIFICATE-----
+ # -----BEGIN CERTIFICATE-----
+ # MIIDBDCCAeygAwIBAgIRALJsPg21kA0zY4F1wUCIuoMwDQYJKoZIhvcNAQELBQAw
+ # EzERMA8GA1UEChMIQXV0aGVsaWEwHhcNNzAwMTAxMDAwMDAwWhcNNzEwMTAxMDAw
+ # MDAwWjATMREwDwYDVQQKEwhBdXRoZWxpYTCCASIwDQYJKoZIhvcNAQEBBQADggEP
+ # ADCCAQoCggEBAMXHBvVxUzYk0u34/DINMSF+uiOekKOAjOrC6Mi9Ww8ytPVO7t2S
+ # zfTvM+XnEJqkFQFgimERfG/eGhjF9XIEY6LtnXe8ATvOK4nTwdufzBaoeQu3Gd50
+ # 5VXr6OHRo//ErrGvFXwP3g8xLePABsi/fkH3oDN+ztewOBMDzpd+KgTrk8ysv2ou
+ # kNRMKFZZqASvCgv0LD5KWvUCnL6wgf1oTXG7aztduA4oSkUP321GpOmBC5+5ElU7
+ # ysoRzvD12o9QJ/IfEaulIX06w9yVMo60C/h6A3U6GdkT1SiyTIqR7v7KU/IWd/Qi
+ # Lfftcj91VhCmJ73Meff2e2S2PrpjdXbG5FMCAwEAAaNTMFEwDgYDVR0PAQH/BAQD
+ # AgKkMA8GA1UdJQQIMAYGBFUdJQAwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU
+ # Z7AtA3mzFc0InSBA5fiMfeLXA3owDQYJKoZIhvcNAQELBQADggEBAEE5hm1mtlk/
+ # kviCoHH4evbpw7rxPxDftIQlqYTtvMM4eWY/6icFoSZ4fUHEWYyps8SsPu/8f2tf
+ # 71LGgZn0FdHi1QU2H8m0HHK7TFw+5Q6RLrLdSyk0PItJ71s9en7r8pX820nAFEHZ
+ # HkOSfJZ7B5hFgUDkMtVM6bardXAhoqcMk4YCU96e9d4PB4eI+xGc+mNuYvov3RbB
+ # D0s8ICyojeyPVLerz4wHjZu68Z5frAzhZ68YbzNs8j2fIBKKHkHyLG1iQyF+LJVj
+ # 2PjCP+auJsj6fQQpMGoyGtpLcSDh+ptcTngUD8JsWipzTCjmaNqdPHAOYmcgtf4b
+ # qocikt3WAdU^invalid DO NOT USE=
+ # -----END CERTIFICATE-----
+ ## The private key used with the certificate_chain if the server requests TLS Client Authentication
+ ## i.e. Mutual TLS.
+ # private_key: |
+ # -----BEGIN RSA PRIVATE KEY-----
+ # MIIEpAIBAAKCAQEA8q/elLI/ijMYSJUsnXh0hYUIQYSCrtZQwjRJlmpADYgPQvn1
+ # T9D9SzLLu4L2B8xTM4NOkA22Q6MVBxACzGVHUU6NUGtflCCNK9fBtCfcO3AwDtdZ
+ # KXou5jHasFhKUxI3lRlCb9HEy1d8srZvnVaAQRgMWL6cQJKorNHhHnh44+QERZF+
+ # +5j3UAyOWGmK+Dx7glaSrgtVBQpuaIVjAh0rxdCI3huVj1bBfAkVizmxD9RgzAEW
+ # LQeRY6HsYSN/GChQ49q4i55lIxKVCnvOoAff03RlJhvpxLQ2mPntChZlJjdqTzt5
+ # txE1/isK9ktvLsug3upgIrGYJoMPfHb41ilYfwIDAQABAoIBAQDTOdFf2JjHH1um
+ # aPgRAvNf9v7Nj5jytaRKs5nM6iNf46ls4QPreXnMhqSeSwj6lpNgBYxOgzC9Q+cc
+ # Y4ob/paJJPaIJTxmP8K/gyWcOQlNToL1l+eJ20eQoZm23NGr5fIsunSBwLEpTrdB
+ # ENqqtcwhW937K8Pxy/Q1nuLyU2bc6Tn/ivLozc8n27dpQWWKh8537VY7ancIaACr
+ # LJJLYxKqhQpjtBWAyCDvZQirnAOm9KnvIHaGXIswCZ4Xbsu0Y9NL+woARPyRVQvG
+ # jfxy4EmO9s1s6y7OObSukwKDSNihAKHx/VIbvVWx8g2Lv5fGOa+J2Y7o9Qurs8t5
+ # BQwMTt0BAoGBAPUw5Z32EszNepAeV3E2mPFUc5CLiqAxagZJuNDO2pKtyN29ETTR
+ # Ma4O1cWtGb6RqcNNN/Iukfkdk27Q5nC9VJSUUPYelOLc1WYOoUf6oKRzE72dkMQV
+ # R4bf6TkjD+OVR17fAfkswkGahZ5XA7j48KIQ+YC4jbnYKSxZTYyKPjH/AoGBAP1i
+ # tqXt36OVlP+y84wWqZSjMelBIVa9phDVGJmmhz3i1cMni8eLpJzWecA3pfnG6Tm9
+ # ze5M4whASleEt+M00gEvNaU9ND+z0wBfi+/DwJYIbv8PQdGrBiZFrPhTPjGQUldR
+ # lXccV2meeLZv7TagVxSi3DO6dSJfSEHyemd5j9mBAoGAX8Hv+0gOQZQCSOTAq8Nx
+ # 6dZcp9gHlNaXnMsP9eTDckOSzh636JPGvj6m+GPJSSbkURUIQ3oyokMNwFqvlNos
+ # fTaLhAOfjBZI9WnDTTQxpugWjphJ4HqbC67JC/qIiw5S6FdaEvGLEEoD4zoChywZ
+ # 9oGAn+fz2d/0/JAH/FpFPgsCgYEAp/ipZgPzziiZ9ov1wbdAQcWRj7RaWnssPFpX
+ # jXwEiXT3CgEMO4MJ4+KWIWOChrti3qFBg6i6lDyyS6Qyls7sLFbUdC7HlTcrOEMe
+ # rBoTcCI1GqZNlqWOVQ65ZIEiaI7o1vPBZo2GMQEZuq8mDKFsOMThvvTrM5cAep84
+ # n6HJR4ECgYABWcbsSnr0MKvVth/inxjbKapbZnp2HUCuw87Ie5zK2Of/tbC20wwk
+ # yKw3vrGoE3O1t1g2m2tn8UGGASeZ842jZWjIODdSi5+icysQGuULKt86h/woz2SQ
+ # 27GoE2i5mh6Yez6VAYbUuns3FcwIsMyWLq043Tu2DNkx9ijOOAuQzw^invalid..
+ # DO NOT USE==
+ # -----END RSA PRIVATE KEY-----
+ ## The Redis HA configuration options.
+ ## This provides specific options to Redis Sentinel, sentinel_name must be defined (Master Name).
+ # high_availability:
+ ## Sentinel Name / Master Name.
+ # sentinel_name: mysentinel
+ ## Specific username for Redis Sentinel. The node username and password is configured above.
+ # sentinel_username: sentinel_specific_user
+ ## Specific password for Redis Sentinel. The node username and password is configured above.
+ # sentinel_password: sentinel_specific_pass
+ ## The additional nodes to pre-seed the redis provider with (for sentinel).
+ ## If the host in the above section is defined, it will be combined with this list to connect to sentinel.
+ ## For high availability to be used you must have either defined; the host above or at least one node below.
+ # nodes:
+ # - host: sentinel-node1
+ # port: 6379
+ # - host: sentinel-node2
+ # port: 6379
+ ## Choose the host with the lowest latency.
+ # route_by_latency: false
+ ## Choose the host randomly.
+ # route_randomly: false
+##
+## Regulation Configuration
+##
+## This mechanism prevents attackers from brute forcing the first factor. It bans the user if too many attempts
+are made
+## in a short period of time.
+regulation:
+ ## The number of failed login attempts before user is banned. Set it to 0 to disable regulation.
+ max_retries: 3
+ ## The time range during which the user can attempt login before being banned. The user is banned if the
+ ## authentication failed 'max_retries' times in a 'find_time' seconds window. Find Time accepts duration
+notation.
+ ## See: https://www.authelia.com/c/common#duration-notation-format
+ find_time: 10m
+ ## The length of time before a banned user can login again. Ban Time accepts duration notation.
+ ## See: https://www.authelia.com/c/common#duration-notation-format
+ ban_time: 12h
+##
+## Storage Provider Configuration
+##
+## The available providers are: \`local\`, \`mysql\`, \`postgres\`. You must use one and only one of these providers.
+storage:
+ ## The encryption key that is used to encrypt sensitive information in the database. Must be a string with a
+minimum
+ ## length of 20. Please see the docs if you configure this with an undesirable key and need to change it, you
+MUST use
+ ## the CLI to change this in the database if you want to change it from a previously configured value.
+ encryption_key: REDACTED
+ ##
+ ## Local (Storage Provider)
+ ##
+ ## This stores the data in a SQLite3 Database.
+ ## This is only recommended for lightweight non-stateful installations.
+ ##
+ ## Important: Kubernetes (or HA) users must read https://www.authelia.com/t/statelessness
+ ##
+ # local:
+ ## Path to the SQLite3 Database.
+ # path: /config/db.sqlite3
+ ##
+ ## MySQL / MariaDB (Storage Provider)
+ ##
+ mysql:
+ host: mysql
+ port: 3306
+ database: authelia
+ username: authelia
+ ## Password can also be set using a secret: https://www.authelia.com/c/secrets
+ password: REDACTED
+ timeout: 5s
+ ## MySQL TLS settings. Configuring this requires TLS.
+ # tls:
+ ## The server subject name to check the servers certificate against during the validation process.
+ ## This option is not required if the certificate has a SAN which matches the host option.
+ # server_name: mysql.example.com
+ ## Skip verifying the server certificate entirely. In preference to setting this we strongly recommend you
+add the
+ ## certificate or the certificate of the authority signing the certificate to the certificates directory which is
+ ## defined by the \`certificates_directory\` option at the top of the configuration.
+ ## It's important to note the public key should be added to the directory, not the private key.
+ ## This option is strongly discouraged but may be useful in some self-signed situations where validation is
+not
+ ## important to the administrator.
+ # skip_verify: false
+ ## Minimum TLS version for the connection.
+ # minimum_version: TLS1.2
+ ## Maximum TLS version for the connection.
+ # maximum_version: TLS1.3
+ ## The certificate chain used with the private_key if the server requests TLS Client Authentication
+ ## i.e. Mutual TLS.
+ # certificate_chain: |
+ # -----BEGIN CERTIFICATE-----
+ # MIIC5jCCAc6gAwIBAgIRAK4Sj7FiN6PXo/urPfO4E7owDQYJKoZIhvcNAQELBQAw
+ # EzERMA8GA1UEChMIQXV0aGVsaWEwHhcNNzAwMTAxMDAwMDAwWhcNNzEwMTAxMDAw
+ # MDAwWjATMREwDwYDVQQKEwhBdXRoZWxpYTCCASIwDQYJKoZIhvcNAQEBBQADggEP
+ # ADCCAQoCggEBAPKv3pSyP4ozGEiVLJ14dIWFCEGEgq7WUMI0SZZqQA2ID0L59U/Q
+ # /Usyy7uC9gfMUzODTpANtkOjFQcQAsxlR1FOjVBrX5QgjSvXwbQn3DtwMA7XWSl6
+ # LuYx2rBYSlMSN5UZQm/RxMtXfLK2b51WgEEYDFi+nECSqKzR4R54eOPkBEWRfvuY
+ # 91AMjlhpivg8e4JWkq4LVQUKbmiFYwIdK8XQiN4blY9WwXwJFYs5sQ/UYMwBFi0H
+ # kWOh7GEjfxgoUOPauIueZSMSlQp7zqAH39N0ZSYb6cS0Npj57QoWZSY3ak87ebcR
+ # Nf4rCvZLby7LoN7qYCKxmCaDD3x2+NYpWH8CAwEAAaM1MDMwDgYDVR0PAQH/BAQD
+ # AgWgMBMGA1UdJQQMMAoGCCsGAQUFBwMBMAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcN
+ # AQELBQADggEBAHSITqIQSNzonFl3DzxHPEzr2hp6peo45buAAtu8FZHoA+U7Icfh
+ # /ZXjPg7Xz+hgFwM/DTNGXkMWacQA/PaNWvZspgRJf2AXvNbMSs2UQODr7Tbv+Fb4
+ # lyblmMUNYFMCFVAMU0eIxXAFq2qcwv8UMcQFT0Z/35s6PVOakYnAGGQjTfp5Ljuq
+ # wsdc/xWmM0cHWube6sdRRUD7SY20KU/kWzl8iFO0VbSSrDf1AlEhnLEkp1SPaxXg
+ # OdBnl98MeoramNiJ7NT6Jnyb3zZ578fjaWfThiBpagItI8GZmG4s4Ovh2JbheN8i
+ # ZsjNr9jqHTjhyLVbDRlmJzcqoj4JhbKs6/I^invalid DO NOT USE=
+ # -----END CERTIFICATE-----
+ # -----BEGIN CERTIFICATE-----
+ # MIIDBDCCAeygAwIBAgIRALJsPg21kA0zY4F1wUCIuoMwDQYJKoZIhvcNAQELBQAw
+ # EzERMA8GA1UEChMIQXV0aGVsaWEwHhcNNzAwMTAxMDAwMDAwWhcNNzEwMTAxMDAw
+ # MDAwWjATMREwDwYDVQQKEwhBdXRoZWxpYTCCASIwDQYJKoZIhvcNAQEBBQADggEP
+ # ADCCAQoCggEBAMXHBvVxUzYk0u34/DINMSF+uiOekKOAjOrC6Mi9Ww8ytPVO7t2S
+ # zfTvM+XnEJqkFQFgimERfG/eGhjF9XIEY6LtnXe8ATvOK4nTwdufzBaoeQu3Gd50
+ # 5VXr6OHRo//ErrGvFXwP3g8xLePABsi/fkH3oDN+ztewOBMDzpd+KgTrk8ysv2ou
+ # kNRMKFZZqASvCgv0LD5KWvUCnL6wgf1oTXG7aztduA4oSkUP321GpOmBC5+5ElU7
+ # ysoRzvD12o9QJ/IfEaulIX06w9yVMo60C/h6A3U6GdkT1SiyTIqR7v7KU/IWd/Qi
+ # Lfftcj91VhCmJ73Meff2e2S2PrpjdXbG5FMCAwEAAaNTMFEwDgYDVR0PAQH/BAQD
+ # AgKkMA8GA1UdJQQIMAYGBFUdJQAwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU
+ # Z7AtA3mzFc0InSBA5fiMfeLXA3owDQYJKoZIhvcNAQELBQADggEBAEE5hm1mtlk/
+ # kviCoHH4evbpw7rxPxDftIQlqYTtvMM4eWY/6icFoSZ4fUHEWYyps8SsPu/8f2tf
+ # 71LGgZn0FdHi1QU2H8m0HHK7TFw+5Q6RLrLdSyk0PItJ71s9en7r8pX820nAFEHZ
+ # HkOSfJZ7B5hFgUDkMtVM6bardXAhoqcMk4YCU96e9d4PB4eI+xGc+mNuYvov3RbB
+ # D0s8ICyojeyPVLerz4wHjZu68Z5frAzhZ68YbzNs8j2fIBKKHkHyLG1iQyF+LJVj
+ # 2PjCP+auJsj6fQQpMGoyGtpLcSDh+ptcTngUD8JsWipzTCjmaNqdPHAOYmcgtf4b
+ # qocikt3WAdU^invalid DO NOT USE=
+ # -----END CERTIFICATE-----
+ ## The private key used with the certificate_chain if the server requests TLS Client Authentication
+ ## i.e. Mutual TLS.
+ # private_key: |
+ # -----BEGIN RSA PRIVATE KEY-----
+ # MIIEpAIBAAKCAQEA8q/elLI/ijMYSJUsnXh0hYUIQYSCrtZQwjRJlmpADYgPQvn1
+ # T9D9SzLLu4L2B8xTM4NOkA22Q6MVBxACzGVHUU6NUGtflCCNK9fBtCfcO3AwDtdZ
+ # KXou5jHasFhKUxI3lRlCb9HEy1d8srZvnVaAQRgMWL6cQJKorNHhHnh44+QERZF+
+ # +5j3UAyOWGmK+Dx7glaSrgtVBQpuaIVjAh0rxdCI3huVj1bBfAkVizmxD9RgzAEW
+ # LQeRY6HsYSN/GChQ49q4i55lIxKVCnvOoAff03RlJhvpxLQ2mPntChZlJjdqTzt5
+ # txE1/isK9ktvLsug3upgIrGYJoMPfHb41ilYfwIDAQABAoIBAQDTOdFf2JjHH1um
+ # aPgRAvNf9v7Nj5jytaRKs5nM6iNf46ls4QPreXnMhqSeSwj6lpNgBYxOgzC9Q+cc
+ # Y4ob/paJJPaIJTxmP8K/gyWcOQlNToL1l+eJ20eQoZm23NGr5fIsunSBwLEpTrdB
+ # ENqqtcwhW937K8Pxy/Q1nuLyU2bc6Tn/ivLozc8n27dpQWWKh8537VY7ancIaACr
+ # LJJLYxKqhQpjtBWAyCDvZQirnAOm9KnvIHaGXIswCZ4Xbsu0Y9NL+woARPyRVQvG
+ # jfxy4EmO9s1s6y7OObSukwKDSNihAKHx/VIbvVWx8g2Lv5fGOa+J2Y7o9Qurs8t5
+ # BQwMTt0BAoGBAPUw5Z32EszNepAeV3E2mPFUc5CLiqAxagZJuNDO2pKtyN29ETTR
+ # Ma4O1cWtGb6RqcNNN/Iukfkdk27Q5nC9VJSUUPYelOLc1WYOoUf6oKRzE72dkMQV
+ # R4bf6TkjD+OVR17fAfkswkGahZ5XA7j48KIQ+YC4jbnYKSxZTYyKPjH/AoGBAP1i
+ # tqXt36OVlP+y84wWqZSjMelBIVa9phDVGJmmhz3i1cMni8eLpJzWecA3pfnG6Tm9
+ # ze5M4whASleEt+M00gEvNaU9ND+z0wBfi+/DwJYIbv8PQdGrBiZFrPhTPjGQUldR
+ # lXccV2meeLZv7TagVxSi3DO6dSJfSEHyemd5j9mBAoGAX8Hv+0gOQZQCSOTAq8Nx
+ # 6dZcp9gHlNaXnMsP9eTDckOSzh636JPGvj6m+GPJSSbkURUIQ3oyokMNwFqvlNos
+ # fTaLhAOfjBZI9WnDTTQxpugWjphJ4HqbC67JC/qIiw5S6FdaEvGLEEoD4zoChywZ
+ # 9oGAn+fz2d/0/JAH/FpFPgsCgYEAp/ipZgPzziiZ9ov1wbdAQcWRj7RaWnssPFpX
+ # jXwEiXT3CgEMO4MJ4+KWIWOChrti3qFBg6i6lDyyS6Qyls7sLFbUdC7HlTcrOEMe
+ # rBoTcCI1GqZNlqWOVQ65ZIEiaI7o1vPBZo2GMQEZuq8mDKFsOMThvvTrM5cAep84
+ # n6HJR4ECgYABWcbsSnr0MKvVth/inxjbKapbZnp2HUCuw87Ie5zK2Of/tbC20wwk
+ # yKw3vrGoE3O1t1g2m2tn8UGGASeZ842jZWjIODdSi5+icysQGuULKt86h/woz2SQ
+ # 27GoE2i5mh6Yez6VAYbUuns3FcwIsMyWLq043Tu2DNkx9ijOOAuQzw^invalid..
+ # DO NOT USE==
+ # -----END RSA PRIVATE KEY-----
+ ##
+ ## PostgreSQL (Storage Provider)
+ ##
+ # postgres:
+ # host: 127.0.0.1
+ # port: 5432
+ # database: authelia
+ # schema: public
+ # username: authelia
+ ## Password can also be set using a secret: https://www.authelia.com/c/secrets
+ # password: mypassword
+ # timeout: 5s
+ ## PostgreSQL TLS settings. Configuring this requires TLS.
+ # tls:
+ ## The server subject name to check the servers certificate against during the validation process.
+ ## This option is not required if the certificate has a SAN which matches the host option.
+ # server_name: postgres.example.com
+ ## Skip verifying the server certificate entirely. In preference to setting this we strongly recommend you
+add the
+ ## certificate or the certificate of the authority signing the certificate to the certificates directory which is
+ ## defined by the \`certificates_directory\` option at the top of the configuration.
+ ## It's important to note the public key should be added to the directory, not the private key.
+ ## This option is strongly discouraged but may be useful in some self-signed situations where validation is
+not
+ ## important to the administrator.
+ # skip_verify: false
+ ## Minimum TLS version for the connection.
+ # minimum_version: TLS1.2
+ ## Maximum TLS version for the connection.
+ # maximum_version: TLS1.3
+ ## The certificate chain used with the private_key if the server requests TLS Client Authentication
+ ## i.e. Mutual TLS.
+ # certificate_chain: |
+ # -----BEGIN CERTIFICATE-----
+ # MIIC5jCCAc6gAwIBAgIRAK4Sj7FiN6PXo/urPfO4E7owDQYJKoZIhvcNAQELBQAw
+ # EzERMA8GA1UEChMIQXV0aGVsaWEwHhcNNzAwMTAxMDAwMDAwWhcNNzEwMTAxMDAw
+ # MDAwWjATMREwDwYDVQQKEwhBdXRoZWxpYTCCASIwDQYJKoZIhvcNAQEBBQADggEP
+ # ADCCAQoCggEBAPKv3pSyP4ozGEiVLJ14dIWFCEGEgq7WUMI0SZZqQA2ID0L59U/Q
+ # /Usyy7uC9gfMUzODTpANtkOjFQcQAsxlR1FOjVBrX5QgjSvXwbQn3DtwMA7XWSl6
+ # LuYx2rBYSlMSN5UZQm/RxMtXfLK2b51WgEEYDFi+nECSqKzR4R54eOPkBEWRfvuY
+ # 91AMjlhpivg8e4JWkq4LVQUKbmiFYwIdK8XQiN4blY9WwXwJFYs5sQ/UYMwBFi0H
+ # kWOh7GEjfxgoUOPauIueZSMSlQp7zqAH39N0ZSYb6cS0Npj57QoWZSY3ak87ebcR
+ # Nf4rCvZLby7LoN7qYCKxmCaDD3x2+NYpWH8CAwEAAaM1MDMwDgYDVR0PAQH/BAQD
+ # AgWgMBMGA1UdJQQMMAoGCCsGAQUFBwMBMAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcN
+ # AQELBQADggEBAHSITqIQSNzonFl3DzxHPEzr2hp6peo45buAAtu8FZHoA+U7Icfh
+ # /ZXjPg7Xz+hgFwM/DTNGXkMWacQA/PaNWvZspgRJf2AXvNbMSs2UQODr7Tbv+Fb4
+ # lyblmMUNYFMCFVAMU0eIxXAFq2qcwv8UMcQFT0Z/35s6PVOakYnAGGQjTfp5Ljuq
+ # wsdc/xWmM0cHWube6sdRRUD7SY20KU/kWzl8iFO0VbSSrDf1AlEhnLEkp1SPaxXg
+ # OdBnl98MeoramNiJ7NT6Jnyb3zZ578fjaWfThiBpagItI8GZmG4s4Ovh2JbheN8i
+ # ZsjNr9jqHTjhyLVbDRlmJzcqoj4JhbKs6/I^invalid DO NOT USE=
+ # -----END CERTIFICATE-----
+ # -----BEGIN CERTIFICATE-----
+ # MIIDBDCCAeygAwIBAgIRALJsPg21kA0zY4F1wUCIuoMwDQYJKoZIhvcNAQELBQAw
+ # EzERMA8GA1UEChMIQXV0aGVsaWEwHhcNNzAwMTAxMDAwMDAwWhcNNzEwMTAxMDAw
+ # MDAwWjATMREwDwYDVQQKEwhBdXRoZWxpYTCCASIwDQYJKoZIhvcNAQEBBQADggEP
+ # ADCCAQoCggEBAMXHBvVxUzYk0u34/DINMSF+uiOekKOAjOrC6Mi9Ww8ytPVO7t2S
+ # zfTvM+XnEJqkFQFgimERfG/eGhjF9XIEY6LtnXe8ATvOK4nTwdufzBaoeQu3Gd50
+ # 5VXr6OHRo//ErrGvFXwP3g8xLePABsi/fkH3oDN+ztewOBMDzpd+KgTrk8ysv2ou
+ # kNRMKFZZqASvCgv0LD5KWvUCnL6wgf1oTXG7aztduA4oSkUP321GpOmBC5+5ElU7
+ # ysoRzvD12o9QJ/IfEaulIX06w9yVMo60C/h6A3U6GdkT1SiyTIqR7v7KU/IWd/Qi
+ # Lfftcj91VhCmJ73Meff2e2S2PrpjdXbG5FMCAwEAAaNTMFEwDgYDVR0PAQH/BAQD
+ # AgKkMA8GA1UdJQQIMAYGBFUdJQAwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU
+ # Z7AtA3mzFc0InSBA5fiMfeLXA3owDQYJKoZIhvcNAQELBQADggEBAEE5hm1mtlk/
+ # kviCoHH4evbpw7rxPxDftIQlqYTtvMM4eWY/6icFoSZ4fUHEWYyps8SsPu/8f2tf
+ # 71LGgZn0FdHi1QU2H8m0HHK7TFw+5Q6RLrLdSyk0PItJ71s9en7r8pX820nAFEHZ
+ # HkOSfJZ7B5hFgUDkMtVM6bardXAhoqcMk4YCU96e9d4PB4eI+xGc+mNuYvov3RbB
+ # D0s8ICyojeyPVLerz4wHjZu68Z5frAzhZ68YbzNs8j2fIBKKHkHyLG1iQyF+LJVj
+ # 2PjCP+auJsj6fQQpMGoyGtpLcSDh+ptcTngUD8JsWipzTCjmaNqdPHAOYmcgtf4b
+ # qocikt3WAdU^invalid DO NOT USE=
+ # -----END CERTIFICATE-----
+ ## The private key used with the certificate_chain if the server requests TLS Client Authentication
+ ## i.e. Mutual TLS.
+ # private_key: |
+ # -----BEGIN RSA PRIVATE KEY-----
+ # MIIEpAIBAAKCAQEA8q/elLI/ijMYSJUsnXh0hYUIQYSCrtZQwjRJlmpADYgPQvn1
+ # T9D9SzLLu4L2B8xTM4NOkA22Q6MVBxACzGVHUU6NUGtflCCNK9fBtCfcO3AwDtdZ
+ # KXou5jHasFhKUxI3lRlCb9HEy1d8srZvnVaAQRgMWL6cQJKorNHhHnh44+QERZF+
+ # +5j3UAyOWGmK+Dx7glaSrgtVBQpuaIVjAh0rxdCI3huVj1bBfAkVizmxD9RgzAEW
+ # LQeRY6HsYSN/GChQ49q4i55lIxKVCnvOoAff03RlJhvpxLQ2mPntChZlJjdqTzt5
+ # txE1/isK9ktvLsug3upgIrGYJoMPfHb41ilYfwIDAQABAoIBAQDTOdFf2JjHH1um
+ # aPgRAvNf9v7Nj5jytaRKs5nM6iNf46ls4QPreXnMhqSeSwj6lpNgBYxOgzC9Q+cc
+ # Y4ob/paJJPaIJTxmP8K/gyWcOQlNToL1l+eJ20eQoZm23NGr5fIsunSBwLEpTrdB
+ # ENqqtcwhW937K8Pxy/Q1nuLyU2bc6Tn/ivLozc8n27dpQWWKh8537VY7ancIaACr
+ # LJJLYxKqhQpjtBWAyCDvZQirnAOm9KnvIHaGXIswCZ4Xbsu0Y9NL+woARPyRVQvG
+ # jfxy4EmO9s1s6y7OObSukwKDSNihAKHx/VIbvVWx8g2Lv5fGOa+J2Y7o9Qurs8t5
+ # BQwMTt0BAoGBAPUw5Z32EszNepAeV3E2mPFUc5CLiqAxagZJuNDO2pKtyN29ETTR
+ # Ma4O1cWtGb6RqcNNN/Iukfkdk27Q5nC9VJSUUPYelOLc1WYOoUf6oKRzE72dkMQV
+ # R4bf6TkjD+OVR17fAfkswkGahZ5XA7j48KIQ+YC4jbnYKSxZTYyKPjH/AoGBAP1i
+ # tqXt36OVlP+y84wWqZSjMelBIVa9phDVGJmmhz3i1cMni8eLpJzWecA3pfnG6Tm9
+ # ze5M4whASleEt+M00gEvNaU9ND+z0wBfi+/DwJYIbv8PQdGrBiZFrPhTPjGQUldR
+ # lXccV2meeLZv7TagVxSi3DO6dSJfSEHyemd5j9mBAoGAX8Hv+0gOQZQCSOTAq8Nx
+ # 6dZcp9gHlNaXnMsP9eTDckOSzh636JPGvj6m+GPJSSbkURUIQ3oyokMNwFqvlNos
+ # fTaLhAOfjBZI9WnDTTQxpugWjphJ4HqbC67JC/qIiw5S6FdaEvGLEEoD4zoChywZ
+ # 9oGAn+fz2d/0/JAH/FpFPgsCgYEAp/ipZgPzziiZ9ov1wbdAQcWRj7RaWnssPFpX
+ # jXwEiXT3CgEMO4MJ4+KWIWOChrti3qFBg6i6lDyyS6Qyls7sLFbUdC7HlTcrOEMe
+ # rBoTcCI1GqZNlqWOVQ65ZIEiaI7o1vPBZo2GMQEZuq8mDKFsOMThvvTrM5cAep84
+ # n6HJR4ECgYABWcbsSnr0MKvVth/inxjbKapbZnp2HUCuw87Ie5zK2Of/tbC20wwk
+ # yKw3vrGoE3O1t1g2m2tn8UGGASeZ842jZWjIODdSi5+icysQGuULKt86h/woz2SQ
+ # 27GoE2i5mh6Yez6VAYbUuns3FcwIsMyWLq043Tu2DNkx9ijOOAuQzw^invalid..
+ # DO NOT USE==
+ # -----END RSA PRIVATE KEY-----
+##
+## Notification Provider
+##
+## Notifications are sent to users when they require a password reset, a Webauthn registration or a TOTP
+registration.
+## The available providers are: filesystem, smtp. You must use only one of these providers.
+notifier:
+ ## You can disable the notifier startup check by setting this to true.
+ disable_startup_check: false
+ ##
+ ## File System (Notification Provider)
+ ##
+ ## Important: Kubernetes (or HA) users must read https://www.authelia.com/t/statelessness
+ ##
+# filesystem:
+# filename: /config/notification.txt
+ ##
+ ## SMTP (Notification Provider)
+ ##
+ ## Use a SMTP server for sending notifications. Authelia uses the PLAIN or LOGIN methods to authenticate.
+ ## [Security] By default Authelia will:
+ ## - force all SMTP connections over TLS including unauthenticated connections
+ ## - use the disable_require_tls boolean value to disable this requirement
+ ## (only works for unauthenticated connections)
+ ## - validate the SMTP server x509 certificate during the TLS handshake against the hosts trusted certificates
+ ## (configure in tls section)
+ smtp:
+ ## The SMTP host to connect to.
+ host: smtp.gmail.com
+ ## The port to connect to the SMTP host on.
+ port: 587
+ ## The connection timeout.
+ timeout: 5s
+ ## The username used for SMTP authentication.
+ username: [emailaddressrelay]@gmail.com
+ ## The password used for SMTP authentication.
+ ## Can also be set using a secret: https://www.authelia.com/c/secrets
+ password: REDACTED
+ ## The sender is used to is used for the MAIL FROM command and the FROM header.
+ ## If this is not defined and the username is an email, we use the username as this value. This can either be
+just
+ ## an email address or the RFC5322 'Name <email address>' format.
+ sender: "Authelia <admin@[domain.tld]>"
+ ## HELO/EHLO Identifier. Some SMTP Servers may reject the default of localhost.
+ identifier: [domain.tld]
+ ## Subject configuration of the emails sent. {title} is replaced by the text from the notifier.
+ subject: "[Authelia] {title}"
+ ## This address is used during the startup check to verify the email configuration is correct.
+ ## It's not important what it is except if your email server only allows local delivery.
+ startup_check_address: [emailaddressrelay]@gmail.com
+ ## By default we require some form of TLS. This disables this check though is not advised.
+ # disable_require_tls: false
+ ## Disables sending HTML formatted emails.
+ # disable_html_emails: false
+ tls:
+ ## The server subject name to check the servers certificate against during the validation process.
+ ## This option is not required if the certificate has a SAN which matches the host option.
+ server_name: smtp.gmail.com
+ ## Skip verifying the server certificate entirely. In preference to setting this we strongly recommend you
+add the
+ ## certificate or the certificate of the authority signing the certificate to the certificates directory which is
+ ## defined by the \`certificates_directory\` option at the top of the configuration.
+ ## It's important to note the public key should be added to the directory, not the private key.
+ ## This option is strongly discouraged but may be useful in some self-signed situations where validation is
+not
+ ## important to the administrator.
+ # skip_verify: false
+ ## Minimum TLS version for the connection.
+ # minimum_version: TLS1.2
+ ## Maximum TLS version for the connection.
+ # maximum_version: TLS1.3
+ ## The certificate chain used with the private_key if the server requests TLS Client Authentication
+ ## i.e. Mutual TLS.
+ # certificate_chain: |
+ # -----BEGIN CERTIFICATE-----
+ # MIIC5jCCAc6gAwIBAgIRAK4Sj7FiN6PXo/urPfO4E7owDQYJKoZIhvcNAQELBQAw
+ # EzERMA8GA1UEChMIQXV0aGVsaWEwHhcNNzAwMTAxMDAwMDAwWhcNNzEwMTAxMDAw
+ # MDAwWjATMREwDwYDVQQKEwhBdXRoZWxpYTCCASIwDQYJKoZIhvcNAQEBBQADggEP
+ # ADCCAQoCggEBAPKv3pSyP4ozGEiVLJ14dIWFCEGEgq7WUMI0SZZqQA2ID0L59U/Q
+ # /Usyy7uC9gfMUzODTpANtkOjFQcQAsxlR1FOjVBrX5QgjSvXwbQn3DtwMA7XWSl6
+ # LuYx2rBYSlMSN5UZQm/RxMtXfLK2b51WgEEYDFi+nECSqKzR4R54eOPkBEWRfvuY
+ # 91AMjlhpivg8e4JWkq4LVQUKbmiFYwIdK8XQiN4blY9WwXwJFYs5sQ/UYMwBFi0H
+ # kWOh7GEjfxgoUOPauIueZSMSlQp7zqAH39N0ZSYb6cS0Npj57QoWZSY3ak87ebcR
+ # Nf4rCvZLby7LoN7qYCKxmCaDD3x2+NYpWH8CAwEAAaM1MDMwDgYDVR0PAQH/BAQD
+ # AgWgMBMGA1UdJQQMMAoGCCsGAQUFBwMBMAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcN
+ # AQELBQADggEBAHSITqIQSNzonFl3DzxHPEzr2hp6peo45buAAtu8FZHoA+U7Icfh
+ # /ZXjPg7Xz+hgFwM/DTNGXkMWacQA/PaNWvZspgRJf2AXvNbMSs2UQODr7Tbv+Fb4
+ # lyblmMUNYFMCFVAMU0eIxXAFq2qcwv8UMcQFT0Z/35s6PVOakYnAGGQjTfp5Ljuq
+ # wsdc/xWmM0cHWube6sdRRUD7SY20KU/kWzl8iFO0VbSSrDf1AlEhnLEkp1SPaxXg
+ # OdBnl98MeoramNiJ7NT6Jnyb3zZ578fjaWfThiBpagItI8GZmG4s4Ovh2JbheN8i
+ # ZsjNr9jqHTjhyLVbDRlmJzcqoj4JhbKs6/I^invalid DO NOT USE=
+ # -----END CERTIFICATE-----
+ # -----BEGIN CERTIFICATE-----
+ # MIIDBDCCAeygAwIBAgIRALJsPg21kA0zY4F1wUCIuoMwDQYJKoZIhvcNAQELBQAw
+ # EzERMA8GA1UEChMIQXV0aGVsaWEwHhcNNzAwMTAxMDAwMDAwWhcNNzEwMTAxMDAw
+ # MDAwWjATMREwDwYDVQQKEwhBdXRoZWxpYTCCASIwDQYJKoZIhvcNAQEBBQADggEP
+ # ADCCAQoCggEBAMXHBvVxUzYk0u34/DINMSF+uiOekKOAjOrC6Mi9Ww8ytPVO7t2S
+ # zfTvM+XnEJqkFQFgimERfG/eGhjF9XIEY6LtnXe8ATvOK4nTwdufzBaoeQu3Gd50
+ # 5VXr6OHRo//ErrGvFXwP3g8xLePABsi/fkH3oDN+ztewOBMDzpd+KgTrk8ysv2ou
+ # kNRMKFZZqASvCgv0LD5KWvUCnL6wgf1oTXG7aztduA4oSkUP321GpOmBC5+5ElU7
+ # ysoRzvD12o9QJ/IfEaulIX06w9yVMo60C/h6A3U6GdkT1SiyTIqR7v7KU/IWd/Qi
+ # Lfftcj91VhCmJ73Meff2e2S2PrpjdXbG5FMCAwEAAaNTMFEwDgYDVR0PAQH/BAQD
+ # AgKkMA8GA1UdJQQIMAYGBFUdJQAwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU
+ # Z7AtA3mzFc0InSBA5fiMfeLXA3owDQYJKoZIhvcNAQELBQADggEBAEE5hm1mtlk/
+ # kviCoHH4evbpw7rxPxDftIQlqYTtvMM4eWY/6icFoSZ4fUHEWYyps8SsPu/8f2tf
+ # 71LGgZn0FdHi1QU2H8m0HHK7TFw+5Q6RLrLdSyk0PItJ71s9en7r8pX820nAFEHZ
+ # HkOSfJZ7B5hFgUDkMtVM6bardXAhoqcMk4YCU96e9d4PB4eI+xGc+mNuYvov3RbB
+ # D0s8ICyojeyPVLerz4wHjZu68Z5frAzhZ68YbzNs8j2fIBKKHkHyLG1iQyF+LJVj
+ # 2PjCP+auJsj6fQQpMGoyGtpLcSDh+ptcTngUD8JsWipzTCjmaNqdPHAOYmcgtf4b
+ # qocikt3WAdU^invalid DO NOT USE=
+ # -----END CERTIFICATE-----
+ ## The private key used with the certificate_chain if the server requests TLS Client Authentication
+ ## i.e. Mutual TLS.
+ # private_key: |
+ # -----BEGIN RSA PRIVATE KEY-----
+ # MIIEpAIBAAKCAQEA8q/elLI/ijMYSJUsnXh0hYUIQYSCrtZQwjRJlmpADYgPQvn1
+ # T9D9SzLLu4L2B8xTM4NOkA22Q6MVBxACzGVHUU6NUGtflCCNK9fBtCfcO3AwDtdZ
+ # KXou5jHasFhKUxI3lRlCb9HEy1d8srZvnVaAQRgMWL6cQJKorNHhHnh44+QERZF+
+ # +5j3UAyOWGmK+Dx7glaSrgtVBQpuaIVjAh0rxdCI3huVj1bBfAkVizmxD9RgzAEW
+ # LQeRY6HsYSN/GChQ49q4i55lIxKVCnvOoAff03RlJhvpxLQ2mPntChZlJjdqTzt5
+ # txE1/isK9ktvLsug3upgIrGYJoMPfHb41ilYfwIDAQABAoIBAQDTOdFf2JjHH1um
+ # aPgRAvNf9v7Nj5jytaRKs5nM6iNf46ls4QPreXnMhqSeSwj6lpNgBYxOgzC9Q+cc
+ # Y4ob/paJJPaIJTxmP8K/gyWcOQlNToL1l+eJ20eQoZm23NGr5fIsunSBwLEpTrdB
+ # ENqqtcwhW937K8Pxy/Q1nuLyU2bc6Tn/ivLozc8n27dpQWWKh8537VY7ancIaACr
+ # LJJLYxKqhQpjtBWAyCDvZQirnAOm9KnvIHaGXIswCZ4Xbsu0Y9NL+woARPyRVQvG
+ # jfxy4EmO9s1s6y7OObSukwKDSNihAKHx/VIbvVWx8g2Lv5fGOa+J2Y7o9Qurs8t5
+ # BQwMTt0BAoGBAPUw5Z32EszNepAeV3E2mPFUc5CLiqAxagZJuNDO2pKtyN29ETTR
+ # Ma4O1cWtGb6RqcNNN/Iukfkdk27Q5nC9VJSUUPYelOLc1WYOoUf6oKRzE72dkMQV
+ # R4bf6TkjD+OVR17fAfkswkGahZ5XA7j48KIQ+YC4jbnYKSxZTYyKPjH/AoGBAP1i
+ # tqXt36OVlP+y84wWqZSjMelBIVa9phDVGJmmhz3i1cMni8eLpJzWecA3pfnG6Tm9
+ # ze5M4whASleEt+M00gEvNaU9ND+z0wBfi+/DwJYIbv8PQdGrBiZFrPhTPjGQUldR
+ # lXccV2meeLZv7TagVxSi3DO6dSJfSEHyemd5j9mBAoGAX8Hv+0gOQZQCSOTAq8Nx
+ # 6dZcp9gHlNaXnMsP9eTDckOSzh636JPGvj6m+GPJSSbkURUIQ3oyokMNwFqvlNos
+ # fTaLhAOfjBZI9WnDTTQxpugWjphJ4HqbC67JC/qIiw5S6FdaEvGLEEoD4zoChywZ
+ # 9oGAn+fz2d/0/JAH/FpFPgsCgYEAp/ipZgPzziiZ9ov1wbdAQcWRj7RaWnssPFpX
+ # jXwEiXT3CgEMO4MJ4+KWIWOChrti3qFBg6i6lDyyS6Qyls7sLFbUdC7HlTcrOEMe
+ # rBoTcCI1GqZNlqWOVQ65ZIEiaI7o1vPBZo2GMQEZuq8mDKFsOMThvvTrM5cAep84
+ # n6HJR4ECgYABWcbsSnr0MKvVth/inxjbKapbZnp2HUCuw87Ie5zK2Of/tbC20wwk
+ # yKw3vrGoE3O1t1g2m2tn8UGGASeZ842jZWjIODdSi5+icysQGuULKt86h/woz2SQ
+ # 27GoE2i5mh6Yez6VAYbUuns3FcwIsMyWLq043Tu2DNkx9ijOOAuQzw^invalid..
+ # DO NOT USE==
+ # -----END RSA PRIVATE KEY-----
+##
+## Identity Providers
+##
+# identity_providers:
+ ##
+ ## OpenID Connect (Identity Provider)
+ ##
+ ## It's recommended you read the documentation before configuration of this section:
+ ## https://www.authelia.com/c/oidc
+ # oidc:
+ ## The hmac_secret is used to sign OAuth2 tokens (authorization code, access tokens and refresh tokens).
+ ## HMAC Secret can also be set using a secret: https://www.authelia.com/c/secrets
+ # hmac_secret: this_is_a_secret_abc123abc123abc
+ ## The issuer_certificate_chain is an optional PEM encoded certificate chain. It's used in conjunction with the
+ ## issuer_private_key to sign JWT's. All certificates in the chain must be within the validity period, and every
+ ## certificate included must be signed by the certificate immediately after it if provided.
+ # issuer_certificate_chain: |
+ # -----BEGIN CERTIFICATE-----
+ # MIIC5jCCAc6gAwIBAgIRAK4Sj7FiN6PXo/urPfO4E7owDQYJKoZIhvcNAQELBQAw
+ # EzERMA8GA1UEChMIQXV0aGVsaWEwHhcNNzAwMTAxMDAwMDAwWhcNNzEwMTAxMDAw
+ # MDAwWjATMREwDwYDVQQKEwhBdXRoZWxpYTCCASIwDQYJKoZIhvcNAQEBBQADggEP
+ # ADCCAQoCggEBAPKv3pSyP4ozGEiVLJ14dIWFCEGEgq7WUMI0SZZqQA2ID0L59U/Q
+ # /Usyy7uC9gfMUzODTpANtkOjFQcQAsxlR1FOjVBrX5QgjSvXwbQn3DtwMA7XWSl6
+ # LuYx2rBYSlMSN5UZQm/RxMtXfLK2b51WgEEYDFi+nECSqKzR4R54eOPkBEWRfvuY
+ # 91AMjlhpivg8e4JWkq4LVQUKbmiFYwIdK8XQiN4blY9WwXwJFYs5sQ/UYMwBFi0H
+ # kWOh7GEjfxgoUOPauIueZSMSlQp7zqAH39N0ZSYb6cS0Npj57QoWZSY3ak87ebcR
+ # Nf4rCvZLby7LoN7qYCKxmCaDD3x2+NYpWH8CAwEAAaM1MDMwDgYDVR0PAQH/BAQD
+ # AgWgMBMGA1UdJQQMMAoGCCsGAQUFBwMBMAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcN
+ # AQELBQADggEBAHSITqIQSNzonFl3DzxHPEzr2hp6peo45buAAtu8FZHoA+U7Icfh
+ # /ZXjPg7Xz+hgFwM/DTNGXkMWacQA/PaNWvZspgRJf2AXvNbMSs2UQODr7Tbv+Fb4
+ # lyblmMUNYFMCFVAMU0eIxXAFq2qcwv8UMcQFT0Z/35s6PVOakYnAGGQjTfp5Ljuq
+ # wsdc/xWmM0cHWube6sdRRUD7SY20KU/kWzl8iFO0VbSSrDf1AlEhnLEkp1SPaxXg
+ # OdBnl98MeoramNiJ7NT6Jnyb3zZ578fjaWfThiBpagItI8GZmG4s4Ovh2JbheN8i
+ # ZsjNr9jqHTjhyLVbDRlmJzcqoj4JhbKs6/I^invalid DO NOT USE=
+ # -----END CERTIFICATE-----
+ # -----BEGIN CERTIFICATE-----
+ # MIIDBDCCAeygAwIBAgIRALJsPg21kA0zY4F1wUCIuoMwDQYJKoZIhvcNAQELBQAw
+ # EzERMA8GA1UEChMIQXV0aGVsaWEwHhcNNzAwMTAxMDAwMDAwWhcNNzEwMTAxMDAw
+ # MDAwWjATMREwDwYDVQQKEwhBdXRoZWxpYTCCASIwDQYJKoZIhvcNAQEBBQADggEP
+ # ADCCAQoCggEBAMXHBvVxUzYk0u34/DINMSF+uiOekKOAjOrC6Mi9Ww8ytPVO7t2S
+ # zfTvM+XnEJqkFQFgimERfG/eGhjF9XIEY6LtnXe8ATvOK4nTwdufzBaoeQu3Gd50
+ # 5VXr6OHRo//ErrGvFXwP3g8xLePABsi/fkH3oDN+ztewOBMDzpd+KgTrk8ysv2ou
+ # kNRMKFZZqASvCgv0LD5KWvUCnL6wgf1oTXG7aztduA4oSkUP321GpOmBC5+5ElU7
+ # ysoRzvD12o9QJ/IfEaulIX06w9yVMo60C/h6A3U6GdkT1SiyTIqR7v7KU/IWd/Qi
+ # Lfftcj91VhCmJ73Meff2e2S2PrpjdXbG5FMCAwEAAaNTMFEwDgYDVR0PAQH/BAQD
+ # AgKkMA8GA1UdJQQIMAYGBFUdJQAwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU
+ # Z7AtA3mzFc0InSBA5fiMfeLXA3owDQYJKoZIhvcNAQELBQADggEBAEE5hm1mtlk/
+ # kviCoHH4evbpw7rxPxDftIQlqYTtvMM4eWY/6icFoSZ4fUHEWYyps8SsPu/8f2tf
+ # 71LGgZn0FdHi1QU2H8m0HHK7TFw+5Q6RLrLdSyk0PItJ71s9en7r8pX820nAFEHZ
+ # HkOSfJZ7B5hFgUDkMtVM6bardXAhoqcMk4YCU96e9d4PB4eI+xGc+mNuYvov3RbB
+ # D0s8ICyojeyPVLerz4wHjZu68Z5frAzhZ68YbzNs8j2fIBKKHkHyLG1iQyF+LJVj
+ # 2PjCP+auJsj6fQQpMGoyGtpLcSDh+ptcTngUD8JsWipzTCjmaNqdPHAOYmcgtf4b
+ # qocikt3WAdU^invalid DO NOT USE=
+ # -----END CERTIFICATE-----
+ ## The issuer_private_key is used to sign the JWT forged by OpenID Connect.
+ ## Issuer Private Key can also be set using a secret: https://www.authelia.com/c/secrets
+ # issuer_private_key: |
+ # -----BEGIN RSA PRIVATE KEY-----
+ # MIIEpAIBAAKCAQEA8q/elLI/ijMYSJUsnXh0hYUIQYSCrtZQwjRJlmpADYgPQvn1
+ # T9D9SzLLu4L2B8xTM4NOkA22Q6MVBxACzGVHUU6NUGtflCCNK9fBtCfcO3AwDtdZ
+ # KXou5jHasFhKUxI3lRlCb9HEy1d8srZvnVaAQRgMWL6cQJKorNHhHnh44+QERZF+
+ # +5j3UAyOWGmK+Dx7glaSrgtVBQpuaIVjAh0rxdCI3huVj1bBfAkVizmxD9RgzAEW
+ # LQeRY6HsYSN/GChQ49q4i55lIxKVCnvOoAff03RlJhvpxLQ2mPntChZlJjdqTzt5
+ # txE1/isK9ktvLsug3upgIrGYJoMPfHb41ilYfwIDAQABAoIBAQDTOdFf2JjHH1um
+ # aPgRAvNf9v7Nj5jytaRKs5nM6iNf46ls4QPreXnMhqSeSwj6lpNgBYxOgzC9Q+cc
+ # Y4ob/paJJPaIJTxmP8K/gyWcOQlNToL1l+eJ20eQoZm23NGr5fIsunSBwLEpTrdB
+ # ENqqtcwhW937K8Pxy/Q1nuLyU2bc6Tn/ivLozc8n27dpQWWKh8537VY7ancIaACr
+ # LJJLYxKqhQpjtBWAyCDvZQirnAOm9KnvIHaGXIswCZ4Xbsu0Y9NL+woARPyRVQvG
+ # jfxy4EmO9s1s6y7OObSukwKDSNihAKHx/VIbvVWx8g2Lv5fGOa+J2Y7o9Qurs8t5
+ # BQwMTt0BAoGBAPUw5Z32EszNepAeV3E2mPFUc5CLiqAxagZJuNDO2pKtyN29ETTR
+ # Ma4O1cWtGb6RqcNNN/Iukfkdk27Q5nC9VJSUUPYelOLc1WYOoUf6oKRzE72dkMQV
+ # R4bf6TkjD+OVR17fAfkswkGahZ5XA7j48KIQ+YC4jbnYKSxZTYyKPjH/AoGBAP1i
+ # tqXt36OVlP+y84wWqZSjMelBIVa9phDVGJmmhz3i1cMni8eLpJzWecA3pfnG6Tm9
+ # ze5M4whASleEt+M00gEvNaU9ND+z0wBfi+/DwJYIbv8PQdGrBiZFrPhTPjGQUldR
+ # lXccV2meeLZv7TagVxSi3DO6dSJfSEHyemd5j9mBAoGAX8Hv+0gOQZQCSOTAq8Nx
+ # 6dZcp9gHlNaXnMsP9eTDckOSzh636JPGvj6m+GPJSSbkURUIQ3oyokMNwFqvlNos
+ # fTaLhAOfjBZI9WnDTTQxpugWjphJ4HqbC67JC/qIiw5S6FdaEvGLEEoD4zoChywZ
+ # 9oGAn+fz2d/0/JAH/FpFPgsCgYEAp/ipZgPzziiZ9ov1wbdAQcWRj7RaWnssPFpX
+ # jXwEiXT3CgEMO4MJ4+KWIWOChrti3qFBg6i6lDyyS6Qyls7sLFbUdC7HlTcrOEMe
+ # rBoTcCI1GqZNlqWOVQ65ZIEiaI7o1vPBZo2GMQEZuq8mDKFsOMThvvTrM5cAep84
+ # n6HJR4ECgYABWcbsSnr0MKvVth/inxjbKapbZnp2HUCuw87Ie5zK2Of/tbC20wwk
+ # yKw3vrGoE3O1t1g2m2tn8UGGASeZ842jZWjIODdSi5+icysQGuULKt86h/woz2SQ
+ # 27GoE2i5mh6Yez6VAYbUuns3FcwIsMyWLq043Tu2DNkx9ijOOAuQzw^invalid..
+ # DO NOT USE==
+ # -----END RSA PRIVATE KEY-----
+ ## The lifespans configure the expiration for these token types.
+ # access_token_lifespan: 1h
+ # authorize_code_lifespan: 1m
+ # id_token_lifespan: 1h
+ # refresh_token_lifespan: 90m
+ ## Enables additional debug messages.
+ # enable_client_debug_messages: false
+ ## SECURITY NOTICE: It's not recommended changing this option and values below 8 are strongly
+discouraged.
+ # minimum_parameter_entropy: 8
+ ## SECURITY NOTICE: It's not recommended changing this option, and highly discouraged to have it set to
+'never'
+ ## for security reasons.
+ # enforce_pkce: public_clients_only
+ ## Cross-Origin Resource Sharing (CORS) settings.
+ # cors:
+ ## List of endpoints in addition to the metadata endpoints to permit cross-origin requests on.
+ # endpoints:
+ # - authorization
+ # - token
+ # - revocation
+ # - introspection
+ # - userinfo
+ ## List of allowed origins.
+ ## Any origin with https is permitted unless this option is configured or the
+ ## allowed_origins_from_client_redirect_uris option is enabled.
+ # allowed_origins:
+ # - https://example.com
+ ## Automatically adds the origin portion of all redirect URI's on all clients to the list of allowed_origins,
+ ## provided they have the scheme http or https and do not have the hostname of localhost.
+ # allowed_origins_from_client_redirect_uris: false
+ ## Clients is a list of known clients and their configuration.
+ # clients:
+ # -
+ ## The ID is the OpenID Connect ClientID which is used to link an application to a configuration.
+ # id: myapp
+ ## The description to show to users when they end up on the consent screen. Defaults to the ID above.
+ # description: My Application
+ ## The client secret is a shared secret between Authelia and the consumer of this client.
+ # secret: this_is_a_secret
+ ## Sector Identifiers are occasionally used to generate pairwise subject identifiers. In most cases this is not
+ ## necessary. Read the documentation for more information.
+ ## The subject identifier must be the host component of a URL, which is a domain name with an optional
+port.
+ # sector_identifier: example.com
+ ## Sets the client to public. This should typically not be set, please see the documentation for usage.
+ # public: false
+ ## The policy to require for this client; one_factor or two_factor.
+ # authorization_policy: two_factor
+ ## The consent mode controls how consent is obtained.
+ # consent_mode: auto
+ ## This value controls the duration a consent on this client remains remembered when the consent mode
+is
+ ## configured as 'auto' or 'pre-configured'.
+ # pre_configured_consent_duration: 1w
+ ## Audience this client is allowed to request.
+ # audience: []
+ ## Scopes this client is allowed to request.
+ # scopes:
+ # - openid
+ # - groups
+ # - email
+ # - profile
+ ## Redirect URI's specifies a list of valid case-sensitive callbacks for this client.
+ # redirect_uris:
+ # - https://oidc.example.com:8080/oauth2/callback
+ ## Grant Types configures which grants this client can obtain.
+ ## It's not recommended to define this unless you know what you're doing.
+ # grant_types:
+ # - refresh_token
+ # - authorization_code
+ ## Response Types configures which responses this client can be sent.
+ ## It's not recommended to define this unless you know what you're doing.
+ # response_types:
+ # - code
+ ## Response Modes configures which response modes this client supports.
+ # response_modes:
+ # - form_post
+ # - query
+ # - fragment
+ ## The algorithm used to sign userinfo endpoint responses for this client, either none or RS256.
+ # userinfo_signing_algorithm: none
`,3)]))}const c=i(e,[["render",p]]);export{d as __pageData,c as default}; diff --git a/.vitepress/dist/assets/configuration_auth-config.md.CWCNki4x.lean.js b/.vitepress/dist/assets/configuration_auth-config.md.CWCNki4x.lean.js new file mode 100644 index 0000000..c91e4fb --- /dev/null +++ b/.vitepress/dist/assets/configuration_auth-config.md.CWCNki4x.lean.js @@ -0,0 +1,1325 @@ +import{_ as i,c as a,a3 as n,o as l}from"./chunks/framework.DtMx7FFi.js";const d=JSON.parse('{"title":"Authelia Configuration","description":"","frontmatter":{"title":"Authelia Configuration"},"headers":[],"relativePath":"configuration/auth-config.md","filePath":"configuration/auth-config.md"}'),e={name:"configuration/auth-config.md"};function p(t,s,h,k,r,A){return l(),a("div",null,s[0]||(s[0]=[n(`

Authelia Configuration ​

Authelia, is our version of an SSO , as once you've logged into Authelia, you have access to all protected links. Attached below is the example configuration.yml file for Authelia. You can copy/paste this configuration, and then change all values surrounded in square brackets. Make sure to set passwords/tokens where REDACTED occurs. I recommend strings that are at least a length of 26 characters. This example configuration is perfect for 2FA with Authy out of the box, if you'd like to enable Duo , please see Authy/Duo Configuration for more details.

yaml
# yamllint disable rule:comments-indentation
+---
+###################################################################
+############
+# Authelia Configuration #
+###################################################################
+############
+## Note: the container by default expects to find this file at /config/configuration.yml.
+## Certificates directory specifies where Authelia will load trusted certificates (public portion) from in addition to
+## the system certificates store.
+## They should be in base64 format, and have one of the following extensions: *.cer, *.crt, *.pem.
+# certificates_directory: /config/certificates/
+## The theme to display: light, dark, grey, auto.
+theme: dark
+## The secret used to generate JWT tokens when validating user identity by email confirmation. JWT Secret can
+also be
+## set using a secret: https://www.authelia.com/c/secrets
+jwt_secret: REDACTED
+## Default redirection URL
+##
+## If user tries to authenticate without any referer, Authelia does not know where to redirect the user to at the
+end
+## of the authentication process. This parameter allows you to specify the default redirection URL Authelia will
+use
+## in such a case.
+##
+## Note: this parameter is optional. If not provided, user won't be redirected upon successful authentication.
+default_redirection_url: https://[domain.tld]/
+## Set the default 2FA method for new users and for when a user has a preferred method configured that has
+been
+## disabled. This setting must be a method that is enabled.
+## Options are totp, webauthn, mobile_push.
+default_2fa_method: "totp"
+##
+## Server Configuration
+##
+server:
+ ## The address to listen on.
+ host: 0.0.0.0
+ ## The port to listen on.
+ port: 9091
+ ## Set the single level path Authelia listens on.
+ ## Must be alphanumeric chars and should not contain any slashes.
+ path: "authelia"
+ ## Set the path on disk to Authelia assets.
+ ## Useful to allow overriding of specific static assets.
+ # asset_path: /config/assets/
+ ## Enables the pprof endpoint.
+ enable_pprof: false
+ ## Enables the expvars endpoint.
+ enable_expvars: false
+ ## Disables writing the health check vars to /app/.healthcheck.env which makes healthcheck.sh return exit
+code 0.
+ ## This is disabled by default if either /app/.healthcheck.env or /app/healthcheck.sh do not exist.
+ disable_healthcheck: false
+ ## Authelia by default doesn't accept TLS communication on the server port. This section overrides this
+behaviour.
+ tls:
+ ## The path to the DER base64/PEM format private key.
+ key: ""
+ ## The path to the DER base64/PEM format public certificate.
+ certificate: ""
+ ## The list of certificates for client authentication.
+ client_certificates: []
+ ## Server headers configuration/customization.
+ headers:
+ ## The CSP Template. Read the docs.
+ csp_template: ""
+ ## Server Buffers configuration.
+ # buffers:
+ ## Buffers usually should be configured to be the same value.
+ ## Explanation at https://www.authelia.com/c/server#buffer-sizes
+ ## Read buffer size adjusts the server's max incoming request size in bytes.
+ ## Write buffer size does the same for outgoing responses.
+ ## Read buffer.
+ # read: 4096
+ ## Write buffer.
+ # write: 4096
+ ## Server Timeouts configuration.
+ # timeouts:
+ ## Read timeout.
+ # read: 6s
+ ## Write timeout.
+ # write: 6s
+ ## Idle timeout.
+ # idle: 30s
+##
+## Log Configuration
+##
+log:
+ ## Level of verbosity for logs: info, debug, trace.
+ level: debug
+ ## Format the logs are written as: json, text.
+ # format: json
+ ## File path where the logs will be written. If not set logs are written to stdout.
+ # file_path: /config/authelia.log
+ ## Whether to also log to stdout when a log_file_path is defined.
+ # keep_stdout: false
+##
+## Telemetry Configuration
+##
+telemetry:
+ ##
+ ## Metrics Configuration
+ ##
+ metrics:
+ ## Enable Metrics.
+ enabled: false
+ ## The address to listen on for metrics. This should be on a different port to the main server.port value.
+ address: tcp://0.0.0.0:9959
+ ## Metrics Server Buffers configuration.
+ # buffers:
+ ## Read buffer.
+ # read: 4096
+ ## Write buffer.
+ # write: 4096
+ ## Metrics Server Timeouts configuration.
+ # timeouts:
+ ## Read timeout.
+ # read: 6s
+ ## Write timeout.
+ # write: 6s
+ ## Idle timeout.
+ # idle: 30s
+##
+## TOTP Configuration
+##
+## Parameters used for TOTP generation.
+totp:
+ ## Disable TOTP.
+ disable: false
+ ## The issuer name displayed in the Authenticator application of your choice.
+ issuer: [domain.tld]
+ ## The TOTP algorithm to use.
+ ## It is CRITICAL you read the documentation before changing this option:
+ ## https://www.authelia.com/c/totp#algorithm
+ algorithm: sha1
+ ## The number of digits a user has to input. Must either be 6 or 8.
+ ## Changing this option only affects newly generated TOTP configurations.
+ ## It is CRITICAL you read the documentation before changing this option:
+ ## https://www.authelia.com/c/totp#digits
+ digits: 8
+ ## The period in seconds a one-time password is valid for.
+ ## Changing this option only affects newly generated TOTP configurations.
+ period: 30
+ ## The skew controls number of one-time passwords either side of the current one that are valid.
+ ## Warning: before changing skew read the docs link below.
+ skew: 1
+ ## See: https://www.authelia.com/c/totp#input-validation to read
+ ## the documentation.
+ ## The size of the generated shared secrets. Default is 32 and is sufficient in most use cases, minimum is 20.
+ secret_size: 32
+##
+## WebAuthn Configuration
+##
+## Parameters used for WebAuthn.
+webauthn:
+ ## Disable Webauthn.
+ disable: false
+ ## Adjust the interaction timeout for Webauthn dialogues.
+ timeout: 60s
+ ## The display name the browser should show the user for when using Webauthn to login/register.
+ display_name: Authelia
+ ## Conveyance preference controls if we collect the attestation statement including the AAGUID from the
+device.
+ ## Options are none, indirect, direct.
+ attestation_conveyance_preference: indirect
+ ## User verification controls if the user must make a gesture or action to confirm they are present.
+ ## Options are required, preferred, discouraged.
+ user_verification: preferred
+##
+## Duo Push API Configuration
+##
+## Parameters used to contact the Duo API. Those are generated when you protect an application of type
+## "Partner Auth API" in the management panel.
+# duo_api:
+ # disable: false
+ # hostname: api-123456789.example.com
+ # integration_key: ABCDEF
+ ## Secret can also be set using a secret: https://www.authelia.com/c/secrets
+ # secret_key: 1234567890abcdefghifjkl
+ # enable_self_enrollment: false
+##
+## NTP Configuration
+##
+## This is used to validate the servers time is accurate enough to validate TOTP.
+ntp:
+ ## NTP server address.
+ address: "time.cloudflare.com:123"
+ ## NTP version.
+ version: 4
+ ## Maximum allowed time offset between the host and the NTP server.
+ max_desync: 3s
+ ## Disables the NTP check on startup entirely. This means Authelia will not contact a remote service at all if
+you
+ ## set this to true, and can operate in a truly offline mode.
+ disable_startup_check: false
+ ## The default of false will prevent startup only if we can contact the NTP server and the time is out of sync
+with
+ ## the NTP server more than the configured max_desync. If you set this to true, an error will be logged but
+startup
+ ## will continue regardless of results.
+ disable_failure: false
+##
+## Authentication Backend Provider Configuration
+##
+## Used for verifying user passwords and retrieve information such as email address and groups users belong
+to.
+##
+## The available providers are: \`file\`, \`ldap\`. You must use only one of these providers.
+authentication_backend:
+ ## Password Reset Options.
+ password_reset:
+ ## Disable both the HTML element and the API for reset password functionality.
+ disable: false
+ ## External reset password url that redirects the user to an external reset portal. This disables the internal
+reset
+ ## functionality.
+ custom_url: ""
+ ## The amount of time to wait before we refresh data from the authentication backend. Uses duration
+notation.
+ ## To disable this feature set it to 'disable', this will slightly reduce security because for Authelia, users will
+ ## always belong to groups they belonged to at the time of login even if they have been removed from them
+in LDAP.
+ ## To force update on every request you can set this to '0' or 'always', this will increase processor demand.
+ ## See the below documentation for more information.
+ ## Duration Notation docs: https://www.authelia.com/c/common#duration-notation-format
+ ## Refresh Interval docs: https://www.authelia.com/c/1fa#refresh-interval
+ refresh_interval: 5m
+ ##
+ ## LDAP (Authentication Provider)
+ ##
+ ## This is the recommended Authentication Provider in production
+ ## because it allows Authelia to offload the stateful operations
+ ## onto the LDAP service.
+ ldap:
+ ## The LDAP implementation, this affects elements like the attribute utilised for resetting a password.
+ ## Acceptable options are as follows:
+ ## - 'activedirectory' - For Microsoft Active Directory.
+ ## - 'custom' - For custom specifications of attributes and filters.
+ ## This currently defaults to 'custom' to maintain existing behaviour.
+ ##
+ ## Depending on the option here certain other values in this section have a default value, notably all of the
+ ## attribute mappings have a default value that this config overrides, you can read more about these default
+values
+ ## at https://www.authelia.com/c/ldap#defaults
+ implementation: custom
+ ## The url to the ldap server. Format: <scheme>://<address>[:<port>].
+ ## Scheme can be ldap or ldaps in the format (port optional).
+ url: ldap://lldap:3890
+ ## The dial timeout for LDAP.
+ timeout: 5s
+ ## Use StartTLS with the LDAP connection.
+ start_tls: false
+ # tls:
+ ## The server subject name to check the servers certificate against during the validation process.
+ ## This option is not required if the certificate has a SAN which matches the host portion of the url option.
+ # server_name: ldap.example.com
+ ## Skip verifying the server certificate entirely. In preference to setting this we strongly recommend you
+add the
+ ## certificate or the certificate of the authority signing the certificate to the certificates directory which is
+ ## defined by the \`certificates_directory\` option at the top of the configuration.
+ ## It's important to note the public key should be added to the directory, not the private key.
+ ## This option is strongly discouraged but may be useful in some self-signed situations where validation is
+not
+ ## important to the administrator.
+ # skip_verify: false
+ ## Minimum TLS version for the connection.
+ # minimum_version: TLS1.2
+ ## Maximum TLS version for the connection.
+ # maximum_version: TLS1.3
+ ## The certificate chain used with the private_key if the server requests TLS Client Authentication
+ ## i.e. Mutual TLS.
+ # certificate_chain: |
+ # -----BEGIN CERTIFICATE-----
+ # MIIC5jCCAc6gAwIBAgIRAK4Sj7FiN6PXo/urPfO4E7owDQYJKoZIhvcNAQELBQAw
+ # EzERMA8GA1UEChMIQXV0aGVsaWEwHhcNNzAwMTAxMDAwMDAwWhcNNzEwMTAxMDAw
+ # MDAwWjATMREwDwYDVQQKEwhBdXRoZWxpYTCCASIwDQYJKoZIhvcNAQEBBQADggEP
+ # ADCCAQoCggEBAPKv3pSyP4ozGEiVLJ14dIWFCEGEgq7WUMI0SZZqQA2ID0L59U/Q
+ # /Usyy7uC9gfMUzODTpANtkOjFQcQAsxlR1FOjVBrX5QgjSvXwbQn3DtwMA7XWSl6
+ # LuYx2rBYSlMSN5UZQm/RxMtXfLK2b51WgEEYDFi+nECSqKzR4R54eOPkBEWRfvuY
+ # 91AMjlhpivg8e4JWkq4LVQUKbmiFYwIdK8XQiN4blY9WwXwJFYs5sQ/UYMwBFi0H
+ # kWOh7GEjfxgoUOPauIueZSMSlQp7zqAH39N0ZSYb6cS0Npj57QoWZSY3ak87ebcR
+ # Nf4rCvZLby7LoN7qYCKxmCaDD3x2+NYpWH8CAwEAAaM1MDMwDgYDVR0PAQH/BAQD
+ # AgWgMBMGA1UdJQQMMAoGCCsGAQUFBwMBMAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcN
+ # AQELBQADggEBAHSITqIQSNzonFl3DzxHPEzr2hp6peo45buAAtu8FZHoA+U7Icfh
+ # /ZXjPg7Xz+hgFwM/DTNGXkMWacQA/PaNWvZspgRJf2AXvNbMSs2UQODr7Tbv+Fb4
+ # lyblmMUNYFMCFVAMU0eIxXAFq2qcwv8UMcQFT0Z/35s6PVOakYnAGGQjTfp5Ljuq
+ # wsdc/xWmM0cHWube6sdRRUD7SY20KU/kWzl8iFO0VbSSrDf1AlEhnLEkp1SPaxXg
+ # OdBnl98MeoramNiJ7NT6Jnyb3zZ578fjaWfThiBpagItI8GZmG4s4Ovh2JbheN8i
+ # ZsjNr9jqHTjhyLVbDRlmJzcqoj4JhbKs6/I^invalid DO NOT USE=
+ # -----END CERTIFICATE-----
+ # -----BEGIN CERTIFICATE-----
+ # MIIDBDCCAeygAwIBAgIRALJsPg21kA0zY4F1wUCIuoMwDQYJKoZIhvcNAQELBQAw
+ # EzERMA8GA1UEChMIQXV0aGVsaWEwHhcNNzAwMTAxMDAwMDAwWhcNNzEwMTAxMDAw
+ # MDAwWjATMREwDwYDVQQKEwhBdXRoZWxpYTCCASIwDQYJKoZIhvcNAQEBBQADggEP
+ # ADCCAQoCggEBAMXHBvVxUzYk0u34/DINMSF+uiOekKOAjOrC6Mi9Ww8ytPVO7t2S
+ # zfTvM+XnEJqkFQFgimERfG/eGhjF9XIEY6LtnXe8ATvOK4nTwdufzBaoeQu3Gd50
+ # 5VXr6OHRo//ErrGvFXwP3g8xLePABsi/fkH3oDN+ztewOBMDzpd+KgTrk8ysv2ou
+ # kNRMKFZZqASvCgv0LD5KWvUCnL6wgf1oTXG7aztduA4oSkUP321GpOmBC5+5ElU7
+ # ysoRzvD12o9QJ/IfEaulIX06w9yVMo60C/h6A3U6GdkT1SiyTIqR7v7KU/IWd/Qi
+ # Lfftcj91VhCmJ73Meff2e2S2PrpjdXbG5FMCAwEAAaNTMFEwDgYDVR0PAQH/BAQD
+ # AgKkMA8GA1UdJQQIMAYGBFUdJQAwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU
+ # Z7AtA3mzFc0InSBA5fiMfeLXA3owDQYJKoZIhvcNAQELBQADggEBAEE5hm1mtlk/
+ # kviCoHH4evbpw7rxPxDftIQlqYTtvMM4eWY/6icFoSZ4fUHEWYyps8SsPu/8f2tf
+ # 71LGgZn0FdHi1QU2H8m0HHK7TFw+5Q6RLrLdSyk0PItJ71s9en7r8pX820nAFEHZ
+ # HkOSfJZ7B5hFgUDkMtVM6bardXAhoqcMk4YCU96e9d4PB4eI+xGc+mNuYvov3RbB
+ # D0s8ICyojeyPVLerz4wHjZu68Z5frAzhZ68YbzNs8j2fIBKKHkHyLG1iQyF+LJVj
+ # 2PjCP+auJsj6fQQpMGoyGtpLcSDh+ptcTngUD8JsWipzTCjmaNqdPHAOYmcgtf4b
+ # qocikt3WAdU^invalid DO NOT USE=
+ # -----END CERTIFICATE-----
+ ## The private key used with the certificate_chain if the server requests TLS Client Authentication
+ ## i.e. Mutual TLS.
+ # private_key: |
+ # -----BEGIN RSA PRIVATE KEY-----
+ # MIIEpAIBAAKCAQEA8q/elLI/ijMYSJUsnXh0hYUIQYSCrtZQwjRJlmpADYgPQvn1
+ # T9D9SzLLu4L2B8xTM4NOkA22Q6MVBxACzGVHUU6NUGtflCCNK9fBtCfcO3AwDtdZ
+ # KXou5jHasFhKUxI3lRlCb9HEy1d8srZvnVaAQRgMWL6cQJKorNHhHnh44+QERZF+
+ # +5j3UAyOWGmK+Dx7glaSrgtVBQpuaIVjAh0rxdCI3huVj1bBfAkVizmxD9RgzAEW
+ # LQeRY6HsYSN/GChQ49q4i55lIxKVCnvOoAff03RlJhvpxLQ2mPntChZlJjdqTzt5
+ # txE1/isK9ktvLsug3upgIrGYJoMPfHb41ilYfwIDAQABAoIBAQDTOdFf2JjHH1um
+ # aPgRAvNf9v7Nj5jytaRKs5nM6iNf46ls4QPreXnMhqSeSwj6lpNgBYxOgzC9Q+cc
+ # Y4ob/paJJPaIJTxmP8K/gyWcOQlNToL1l+eJ20eQoZm23NGr5fIsunSBwLEpTrdB
+ # ENqqtcwhW937K8Pxy/Q1nuLyU2bc6Tn/ivLozc8n27dpQWWKh8537VY7ancIaACr
+ # LJJLYxKqhQpjtBWAyCDvZQirnAOm9KnvIHaGXIswCZ4Xbsu0Y9NL+woARPyRVQvG
+ # jfxy4EmO9s1s6y7OObSukwKDSNihAKHx/VIbvVWx8g2Lv5fGOa+J2Y7o9Qurs8t5
+ # BQwMTt0BAoGBAPUw5Z32EszNepAeV3E2mPFUc5CLiqAxagZJuNDO2pKtyN29ETTR
+ # Ma4O1cWtGb6RqcNNN/Iukfkdk27Q5nC9VJSUUPYelOLc1WYOoUf6oKRzE72dkMQV
+ # R4bf6TkjD+OVR17fAfkswkGahZ5XA7j48KIQ+YC4jbnYKSxZTYyKPjH/AoGBAP1i
+ # tqXt36OVlP+y84wWqZSjMelBIVa9phDVGJmmhz3i1cMni8eLpJzWecA3pfnG6Tm9
+ # ze5M4whASleEt+M00gEvNaU9ND+z0wBfi+/DwJYIbv8PQdGrBiZFrPhTPjGQUldR
+ # lXccV2meeLZv7TagVxSi3DO6dSJfSEHyemd5j9mBAoGAX8Hv+0gOQZQCSOTAq8Nx
+ # 6dZcp9gHlNaXnMsP9eTDckOSzh636JPGvj6m+GPJSSbkURUIQ3oyokMNwFqvlNos
+ # fTaLhAOfjBZI9WnDTTQxpugWjphJ4HqbC67JC/qIiw5S6FdaEvGLEEoD4zoChywZ
+ # 9oGAn+fz2d/0/JAH/FpFPgsCgYEAp/ipZgPzziiZ9ov1wbdAQcWRj7RaWnssPFpX
+ # jXwEiXT3CgEMO4MJ4+KWIWOChrti3qFBg6i6lDyyS6Qyls7sLFbUdC7HlTcrOEMe
+ # rBoTcCI1GqZNlqWOVQ65ZIEiaI7o1vPBZo2GMQEZuq8mDKFsOMThvvTrM5cAep84
+ # n6HJR4ECgYABWcbsSnr0MKvVth/inxjbKapbZnp2HUCuw87Ie5zK2Of/tbC20wwk
+ # yKw3vrGoE3O1t1g2m2tn8UGGASeZ842jZWjIODdSi5+icysQGuULKt86h/woz2SQ
+ # 27GoE2i5mh6Yez6VAYbUuns3FcwIsMyWLq043Tu2DNkx9ijOOAuQzw^invalid..
+ # DO NOT USE==
+ # -----END RSA PRIVATE KEY-----
+ ## The distinguished name of the container searched for objects in the directory information tree.
+ ## See also: additional_users_dn, additional_groups_dn.
+ base_dn: dc=[domain],dc=[tld]
+ ## The attribute holding the username of the user. This attribute is used to populate the username in the
+session
+ ## information. For your information, Microsoft Active Directory usually uses 'sAMAccountName' and
+OpenLDAP usually
+ ## uses 'uid'. Beware that this attribute holds the unique identifiers for the users binding the user and the
+ ## configuration stored in database. Therefore only single value attributes are allowed and the value must
+never be
+ ## changed once attributed to a user otherwise it would break the configuration for that user. Technically,
+ ## non-unique attributes like 'mail' can also be used but we don't recommend using them, we instead advise
+to use
+ ## a filter to perform alternative lookups and the attributes mentioned above (sAMAccountName and uid) to
+ ## follow https://www.ietf.org/rfc/rfc2307.txt.
+ username_attribute: uid
+ ## The additional_users_dn is prefixed to base_dn and delimited by a comma when searching for users.
+ ## i.e. with this set to OU=Users and base_dn set to DC=a,DC=com; OU=Users,DC=a,DC=com is searched
+for users.
+ additional_users_dn: ou=people
+ ## The users filter used in search queries to find the user profile based on input filled in login form.
+ ## Various placeholders are available in the user filter which you can read about in the documentation which
+can
+ ## be found at: https://www.authelia.com/c/ldap#users-filter-replacements
+ ##
+ ## Recommended settings are as follows:
+ ## - Microsoft Active Directory:
+(&({username_attribute}={input})(objectCategory=person)(objectClass=user))
+ ## - OpenLDAP:
+ ## - (&({username_attribute}={input})(objectClass=person))
+ ## - (&({username_attribute}={input})(objectClass=inetOrgPerson))
+ ##
+ ## To allow sign in both with username and email, one can use a filter like
+ ## (&(|({username_attribute}={input})({mail_attribute}={input}))(objectClass=person))
+ users_filter: (&({username_attribute}={input})(objectClass=person))
+ ## The additional_groups_dn is prefixed to base_dn and delimited by a comma when searching for groups.
+ ## i.e. with this set to OU=Groups and base_dn set to DC=a,DC=com; OU=Groups,DC=a,DC=com is
+searched for groups.
+ additional_groups_dn: ou=groups
+ ## The groups filter used in search queries to find the groups based on relevant authenticated user.
+ ## Various placeholders are available in the groups filter which you can read about in the documentation
+which can
+ ## be found at: https://www.authelia.com/c/ldap#groups-filter-replacements
+ ##
+ ## If your groups use the \`groupOfUniqueNames\` structure use this instead:
+ ## (&(uniqueMember={dn})(objectClass=groupOfUniqueNames))
+ groups_filter: (&(member={dn})(objectClass=groupOfUniqueNames))
+ ## The attribute holding the name of the group.
+ group_name_attribute: cn
+ ## The attribute holding the mail address of the user. If multiple email addresses are defined for a user, only
+the
+ ## first one returned by the LDAP server is used.
+ mail_attribute: mail
+ ## The attribute holding the display name of the user. This will be used to greet an authenticated user.
+ display_name_attribute: displayName
+ ## Follow referrals returned by the server.
+ ## This is especially useful for environments where read-only servers exist. Only implemented for write
+operations.
+ # permit_referrals: false
+ ## The username and password of the admin user.
+ user: cn=admin,ou=people,dc=[domain],dc=[tld]
+ ## Password can also be set using a secret: https://www.authelia.com/c/secrets
+ password: "REDACTED"
+ ##
+ ## File (Authentication Provider)
+ ##
+ ## With this backend, the users database is stored in a file which is updated when users reset their passwords.
+ ## Therefore, this backend is meant to be used in a dev environment and not in production since it prevents
+Authelia
+ ## to be scaled to more than one instance. The options under 'password' have sane defaults, and as it has
+security
+ ## implications it is highly recommended you leave the default values. Before considering changing these
+settings
+ ## please read the docs page below:
+ ## https://www.authelia.com/r/passwords#tuning
+ ##
+ ## Important: Kubernetes (or HA) users must read https://www.authelia.com/t/statelessness
+ ##
+ # file:
+ # path: /config/users_database.yml
+ # watch: false
+ # search:
+ # email: false
+ # case_insensitive: false
+ # password:
+ # algorithm: argon2
+ # argon2:
+ # variant: argon2id
+ # iterations: 3
+ # memory: 65536
+ # parallelism: 4
+ # key_length: 32
+ # salt_length: 16
+ # scrypt:
+ # iterations: 16
+ # block_size: 8
+ # parallelism: 1
+ # key_length: 32
+ # salt_length: 16
+ # pbkdf2:
+ # variant: sha512
+ # iterations: 310000
+ # salt_length: 16
+ # sha2crypt:
+ # variant: sha512
+ # iterations: 50000
+ # salt_length: 16
+ # bcrypt:
+ # variant: standard
+ # cost: 12
+##
+## Password Policy Configuration.
+##
+password_policy:
+ ## The standard policy allows you to tune individual settings manually.
+ standard:
+ enabled: true
+ ## Require a minimum length for passwords.
+ min_length: 8
+ ## Require a maximum length for passwords.
+ max_length: 0
+ ## Require uppercase characters.
+ require_uppercase: true
+ ## Require lowercase characters.
+ require_lowercase: true
+ ## Require numeric characters.
+ require_number: true
+ ## Require special characters.
+ require_special: true
+ ## zxcvbn is a well known and used password strength algorithm. It does not have tunable settings.
+ zxcvbn:
+ enabled: false
+ ## Configures the minimum score allowed.
+ min_score: 3
+##
+## Access Control Configuration
+##
+## Access control is a list of rules defining the authorizations applied for one resource to users or group of
+users.
+##
+## If 'access_control' is not defined, ACL rules are disabled and the 'bypass' rule is applied, i.e., access is
+allowed
+## to anyone. Otherwise restrictions follow the rules defined.
+##
+## Note: One can use the wildcard * to match any subdomain.
+## It must stand at the beginning of the pattern. (example: *.example.com)
+##
+## Note: You must put patterns containing wildcards between simple quotes for the YAML to be syntactically
+correct.
+##
+## Definition: A 'rule' is an object with the following keys: 'domain', 'subject', 'policy' and 'resources'.
+##
+## - 'domain' defines which domain or set of domains the rule applies to.
+##
+## - 'subject' defines the subject to apply authorizations to. This parameter is optional and matching any user if
+not
+## provided. If provided, the parameter represents either a user or a group. It should be of the form
+## 'user:<username>' or 'group:<groupname>'.
+##
+## - 'policy' is the policy to apply to resources. It must be either 'bypass', 'one_factor', 'two_factor' or 'deny'.
+##
+## - 'resources' is a list of regular expressions that matches a set of resources to apply the policy to. This
+parameter
+## is optional and matches any resource if not provided.
+##
+## Note: the order of the rules is important. The first policy matching (domain, resource, subject) applies.
+access_control:
+ ## Default policy can either be 'bypass', 'one_factor', 'two_factor' or 'deny'. It is the policy applied to any
+ ## resource if there is no policy to be applied to the user.
+ default_policy: deny
+ # networks:
+ # - name: internal
+ # networks:
+ # - 10.10.0.0/16
+ # - 192.168.2.0/24
+ # - name: VPN
+ # networks: 10.9.0.0/16
+ rules:
+ ## Rules applied to everyone
+ ## This below policy allows for auth to be accessed at all times,
+ ## useful when trying to login without the main page available.
+ - domain:
+ - 'auth.[domain.tld]'
+ policy: bypass
+ ## This below policy example will exclude a user from using 2FA,
+ ## useful if the user has no way of configuring 2FA.
+ - domain:
+ - '[domain.tld]'
+ - '*.[domain.tld]'
+ subject:
+ - "user:[USERNAME/UID]"
+ policy: one_factor
+ ## This below policy example will exclude all users of the people
+ ## group from using 2FA, NOT RECOMMENDED
+ - domain:
+ - '[domain.tld]'
+ - '*.[domain.tld]'
+ subject:
+ - "group:people"
+ policy: one_factor
+ ## This below policy will require all users of the LLDAP_Admin group
+ ## in LLDAP to use 2FA BY DEFAULT, this is the strongest policy available
+ - domain:
+ - '[domain.tld]'
+ - '*.[domain.tld]'
+ subject:
+ - "group:lldap_admin"
+ policy: two_factor
+ ## Domain Regex examples. Generally we recommend just using a standard domain.
+ # - domain_regex: '^(?P<User>\\w+)\\.example\\.com$'
+ # policy: one_factor
+ # - domain_regex: '^(?P<Group>\\w+)\\.example\\.com$'
+ # policy: one_factor
+ # - domain_regex:
+ # - '^appgroup-.*\\.example\\.com$'
+ # - '^appgroup2-.*\\.example\\.com$'
+ # policy: one_factor
+ # - domain_regex: '^.*\\.example\\.com$'
+ # policy: two_factor
+ # - domain: 'secure.example.com'
+ # policy: one_factor
+ ## Network based rule, if not provided any network matches.
+ # networks:
+ # - internal
+ # - VPN
+ # - 192.168.1.0/24
+ # - 10.0.0.1
+ # - domain:
+ # - 'secure.example.com'
+ # - 'private.example.com'
+ # policy: two_factor
+ # - domain: 'singlefactor.example.com'
+ # policy: one_factor
+ ## Rules applied to 'admins' group
+ # - domain: 'mx2.mail.example.com'
+ # subject: 'group:admins'
+ # policy: deny
+ # - domain: '*.example.com'
+ # subject:
+ # - 'group:admins'
+ # - 'group:moderators'
+ # policy: two_factor
+ ## Rules applied to 'dev' group
+ # - domain: 'dev.example.com'
+ # resources:
+ # - '^/groups/dev/.*$'
+ # subject: 'group:dev'
+ # policy: two_factor
+ ## Rules applied to user 'john'
+ # - domain: 'dev.example.com'
+ # resources:
+ # - '^/users/john/.*$'
+ # subject: 'user:john'
+ # policy: two_factor
+ ## Rules applied to user 'harry'
+ # - domain: 'dev.example.com'
+ # resources:
+ # - '^/users/harry/.*$'
+ # subject: 'user:harry'
+ # policy: two_factor
+ ## Rules applied to user 'bob'
+ # - domain: '*.mail.example.com'
+ # subject: 'user:bob'
+ # policy: two_factor
+ # - domain: 'dev.example.com'
+ # resources:
+ # - '^/users/bob/.*$'
+ # subject: 'user:bob'
+ # policy: two_factor
+##
+## Session Provider Configuration
+##
+## The session cookies identify the user once logged in.
+## The available providers are: \`memory\`, \`redis\`. Memory is the provider unless redis is defined.
+session:
+ ## The name of the session cookie.
+ name: authelia_session
+ ## The domain to protect.
+ ## Note: the authenticator must also be in that domain.
+ ## If empty, the cookie is restricted to the subdomain of the issuer.
+ domain: [domain.tld]
+ ## Sets the Cookie SameSite value. Possible options are none, lax, or strict.
+ ## Please read https://www.authelia.com/c/session#same_site
+ same_site: lax
+ ## The secret to encrypt the session data. This is only used with Redis / Redis Sentinel.
+ ## Secret can also be set using a secret: https://www.authelia.com/c/secrets
+ secret: REDACTED
+ ## The value for expiration, inactivity, and remember_me_duration are in seconds or the duration notation
+format.
+ ## See: https://www.authelia.com/c/common#duration-notation-format
+ ## All three of these values affect the cookie/session validity period. Longer periods are considered less secure
+ ## because a stolen cookie will last longer giving attackers more time to spy or attack.
+ ## The time before the cookie expires and the session is destroyed if remember me IS NOT selected.
+ expiration: 1h
+ ## The inactivity time before the session is reset. If expiration is set to 1h, and this is set to 5m, if the user
+ ## does not select the remember me option their session will get destroyed after 1h, or after 5m since the last
+time
+ ## Authelia detected user activity.
+ inactivity: 5m
+ ## The time before the cookie expires and the session is destroyed if remember me IS selected.
+ ## Value of -1 disables remember me.
+ remember_me_duration: 2M
+ ##
+ ## Redis Provider
+ ##
+ ## Important: Kubernetes (or HA) users must read https://www.authelia.com/t/statelessness
+ ##
+ redis:
+ host: redis
+ port: 6379
+ ## Use a unix socket instead
+ # host: /var/run/redis/redis.sock
+ ## Username used for redis authentication. This is optional and a new feature in redis 6.0.
+ # username: authelia
+ ## Password can also be set using a secret: https://www.authelia.com/c/secrets
+ password: REDACTED
+ ## This is the Redis DB Index https://redis.io/commands/select (sometimes referred to as database number,
+DB, etc).
+ database_index: 0
+ ## The maximum number of concurrent active connections to Redis.
+ maximum_active_connections: 10
+ ## The target number of idle connections to have open ready for work. Useful when opening connections is
+slow.
+ minimum_idle_connections: 0
+ ## The Redis TLS configuration. If defined will require a TLS connection to the Redis instance(s).
+ # tls:
+ ## The server subject name to check the servers certificate against during the validation process.
+ ## This option is not required if the certificate has a SAN which matches the host option.
+ # server_name: myredis.example.com
+ ## Skip verifying the server certificate entirely. In preference to setting this we strongly recommend you
+add the
+ ## certificate or the certificate of the authority signing the certificate to the certificates directory which is
+ ## defined by the \`certificates_directory\` option at the top of the configuration.
+ ## It's important to note the public key should be added to the directory, not the private key.
+ ## This option is strongly discouraged but may be useful in some self-signed situations where validation is
+not
+ ## important to the administrator.
+ # skip_verify: false
+ ## Minimum TLS version for the connection.
+ # minimum_version: TLS1.2
+ ## Maximum TLS version for the connection.
+ # maximum_version: TLS1.3
+ ## The certificate chain used with the private_key if the server requests TLS Client Authentication
+ ## i.e. Mutual TLS.
+ # certificate_chain: |
+ # -----BEGIN CERTIFICATE-----
+ # MIIC5jCCAc6gAwIBAgIRAK4Sj7FiN6PXo/urPfO4E7owDQYJKoZIhvcNAQELBQAw
+ # EzERMA8GA1UEChMIQXV0aGVsaWEwHhcNNzAwMTAxMDAwMDAwWhcNNzEwMTAxMDAw
+ # MDAwWjATMREwDwYDVQQKEwhBdXRoZWxpYTCCASIwDQYJKoZIhvcNAQEBBQADggEP
+ # ADCCAQoCggEBAPKv3pSyP4ozGEiVLJ14dIWFCEGEgq7WUMI0SZZqQA2ID0L59U/Q
+ # /Usyy7uC9gfMUzODTpANtkOjFQcQAsxlR1FOjVBrX5QgjSvXwbQn3DtwMA7XWSl6
+ # LuYx2rBYSlMSN5UZQm/RxMtXfLK2b51WgEEYDFi+nECSqKzR4R54eOPkBEWRfvuY
+ # 91AMjlhpivg8e4JWkq4LVQUKbmiFYwIdK8XQiN4blY9WwXwJFYs5sQ/UYMwBFi0H
+ # kWOh7GEjfxgoUOPauIueZSMSlQp7zqAH39N0ZSYb6cS0Npj57QoWZSY3ak87ebcR
+ # Nf4rCvZLby7LoN7qYCKxmCaDD3x2+NYpWH8CAwEAAaM1MDMwDgYDVR0PAQH/BAQD
+ # AgWgMBMGA1UdJQQMMAoGCCsGAQUFBwMBMAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcN
+ # AQELBQADggEBAHSITqIQSNzonFl3DzxHPEzr2hp6peo45buAAtu8FZHoA+U7Icfh
+ # /ZXjPg7Xz+hgFwM/DTNGXkMWacQA/PaNWvZspgRJf2AXvNbMSs2UQODr7Tbv+Fb4
+ # lyblmMUNYFMCFVAMU0eIxXAFq2qcwv8UMcQFT0Z/35s6PVOakYnAGGQjTfp5Ljuq
+ # wsdc/xWmM0cHWube6sdRRUD7SY20KU/kWzl8iFO0VbSSrDf1AlEhnLEkp1SPaxXg
+ # OdBnl98MeoramNiJ7NT6Jnyb3zZ578fjaWfThiBpagItI8GZmG4s4Ovh2JbheN8i
+ # ZsjNr9jqHTjhyLVbDRlmJzcqoj4JhbKs6/I^invalid DO NOT USE=
+ # -----END CERTIFICATE-----
+ # -----BEGIN CERTIFICATE-----
+ # MIIDBDCCAeygAwIBAgIRALJsPg21kA0zY4F1wUCIuoMwDQYJKoZIhvcNAQELBQAw
+ # EzERMA8GA1UEChMIQXV0aGVsaWEwHhcNNzAwMTAxMDAwMDAwWhcNNzEwMTAxMDAw
+ # MDAwWjATMREwDwYDVQQKEwhBdXRoZWxpYTCCASIwDQYJKoZIhvcNAQEBBQADggEP
+ # ADCCAQoCggEBAMXHBvVxUzYk0u34/DINMSF+uiOekKOAjOrC6Mi9Ww8ytPVO7t2S
+ # zfTvM+XnEJqkFQFgimERfG/eGhjF9XIEY6LtnXe8ATvOK4nTwdufzBaoeQu3Gd50
+ # 5VXr6OHRo//ErrGvFXwP3g8xLePABsi/fkH3oDN+ztewOBMDzpd+KgTrk8ysv2ou
+ # kNRMKFZZqASvCgv0LD5KWvUCnL6wgf1oTXG7aztduA4oSkUP321GpOmBC5+5ElU7
+ # ysoRzvD12o9QJ/IfEaulIX06w9yVMo60C/h6A3U6GdkT1SiyTIqR7v7KU/IWd/Qi
+ # Lfftcj91VhCmJ73Meff2e2S2PrpjdXbG5FMCAwEAAaNTMFEwDgYDVR0PAQH/BAQD
+ # AgKkMA8GA1UdJQQIMAYGBFUdJQAwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU
+ # Z7AtA3mzFc0InSBA5fiMfeLXA3owDQYJKoZIhvcNAQELBQADggEBAEE5hm1mtlk/
+ # kviCoHH4evbpw7rxPxDftIQlqYTtvMM4eWY/6icFoSZ4fUHEWYyps8SsPu/8f2tf
+ # 71LGgZn0FdHi1QU2H8m0HHK7TFw+5Q6RLrLdSyk0PItJ71s9en7r8pX820nAFEHZ
+ # HkOSfJZ7B5hFgUDkMtVM6bardXAhoqcMk4YCU96e9d4PB4eI+xGc+mNuYvov3RbB
+ # D0s8ICyojeyPVLerz4wHjZu68Z5frAzhZ68YbzNs8j2fIBKKHkHyLG1iQyF+LJVj
+ # 2PjCP+auJsj6fQQpMGoyGtpLcSDh+ptcTngUD8JsWipzTCjmaNqdPHAOYmcgtf4b
+ # qocikt3WAdU^invalid DO NOT USE=
+ # -----END CERTIFICATE-----
+ ## The private key used with the certificate_chain if the server requests TLS Client Authentication
+ ## i.e. Mutual TLS.
+ # private_key: |
+ # -----BEGIN RSA PRIVATE KEY-----
+ # MIIEpAIBAAKCAQEA8q/elLI/ijMYSJUsnXh0hYUIQYSCrtZQwjRJlmpADYgPQvn1
+ # T9D9SzLLu4L2B8xTM4NOkA22Q6MVBxACzGVHUU6NUGtflCCNK9fBtCfcO3AwDtdZ
+ # KXou5jHasFhKUxI3lRlCb9HEy1d8srZvnVaAQRgMWL6cQJKorNHhHnh44+QERZF+
+ # +5j3UAyOWGmK+Dx7glaSrgtVBQpuaIVjAh0rxdCI3huVj1bBfAkVizmxD9RgzAEW
+ # LQeRY6HsYSN/GChQ49q4i55lIxKVCnvOoAff03RlJhvpxLQ2mPntChZlJjdqTzt5
+ # txE1/isK9ktvLsug3upgIrGYJoMPfHb41ilYfwIDAQABAoIBAQDTOdFf2JjHH1um
+ # aPgRAvNf9v7Nj5jytaRKs5nM6iNf46ls4QPreXnMhqSeSwj6lpNgBYxOgzC9Q+cc
+ # Y4ob/paJJPaIJTxmP8K/gyWcOQlNToL1l+eJ20eQoZm23NGr5fIsunSBwLEpTrdB
+ # ENqqtcwhW937K8Pxy/Q1nuLyU2bc6Tn/ivLozc8n27dpQWWKh8537VY7ancIaACr
+ # LJJLYxKqhQpjtBWAyCDvZQirnAOm9KnvIHaGXIswCZ4Xbsu0Y9NL+woARPyRVQvG
+ # jfxy4EmO9s1s6y7OObSukwKDSNihAKHx/VIbvVWx8g2Lv5fGOa+J2Y7o9Qurs8t5
+ # BQwMTt0BAoGBAPUw5Z32EszNepAeV3E2mPFUc5CLiqAxagZJuNDO2pKtyN29ETTR
+ # Ma4O1cWtGb6RqcNNN/Iukfkdk27Q5nC9VJSUUPYelOLc1WYOoUf6oKRzE72dkMQV
+ # R4bf6TkjD+OVR17fAfkswkGahZ5XA7j48KIQ+YC4jbnYKSxZTYyKPjH/AoGBAP1i
+ # tqXt36OVlP+y84wWqZSjMelBIVa9phDVGJmmhz3i1cMni8eLpJzWecA3pfnG6Tm9
+ # ze5M4whASleEt+M00gEvNaU9ND+z0wBfi+/DwJYIbv8PQdGrBiZFrPhTPjGQUldR
+ # lXccV2meeLZv7TagVxSi3DO6dSJfSEHyemd5j9mBAoGAX8Hv+0gOQZQCSOTAq8Nx
+ # 6dZcp9gHlNaXnMsP9eTDckOSzh636JPGvj6m+GPJSSbkURUIQ3oyokMNwFqvlNos
+ # fTaLhAOfjBZI9WnDTTQxpugWjphJ4HqbC67JC/qIiw5S6FdaEvGLEEoD4zoChywZ
+ # 9oGAn+fz2d/0/JAH/FpFPgsCgYEAp/ipZgPzziiZ9ov1wbdAQcWRj7RaWnssPFpX
+ # jXwEiXT3CgEMO4MJ4+KWIWOChrti3qFBg6i6lDyyS6Qyls7sLFbUdC7HlTcrOEMe
+ # rBoTcCI1GqZNlqWOVQ65ZIEiaI7o1vPBZo2GMQEZuq8mDKFsOMThvvTrM5cAep84
+ # n6HJR4ECgYABWcbsSnr0MKvVth/inxjbKapbZnp2HUCuw87Ie5zK2Of/tbC20wwk
+ # yKw3vrGoE3O1t1g2m2tn8UGGASeZ842jZWjIODdSi5+icysQGuULKt86h/woz2SQ
+ # 27GoE2i5mh6Yez6VAYbUuns3FcwIsMyWLq043Tu2DNkx9ijOOAuQzw^invalid..
+ # DO NOT USE==
+ # -----END RSA PRIVATE KEY-----
+ ## The Redis HA configuration options.
+ ## This provides specific options to Redis Sentinel, sentinel_name must be defined (Master Name).
+ # high_availability:
+ ## Sentinel Name / Master Name.
+ # sentinel_name: mysentinel
+ ## Specific username for Redis Sentinel. The node username and password is configured above.
+ # sentinel_username: sentinel_specific_user
+ ## Specific password for Redis Sentinel. The node username and password is configured above.
+ # sentinel_password: sentinel_specific_pass
+ ## The additional nodes to pre-seed the redis provider with (for sentinel).
+ ## If the host in the above section is defined, it will be combined with this list to connect to sentinel.
+ ## For high availability to be used you must have either defined; the host above or at least one node below.
+ # nodes:
+ # - host: sentinel-node1
+ # port: 6379
+ # - host: sentinel-node2
+ # port: 6379
+ ## Choose the host with the lowest latency.
+ # route_by_latency: false
+ ## Choose the host randomly.
+ # route_randomly: false
+##
+## Regulation Configuration
+##
+## This mechanism prevents attackers from brute forcing the first factor. It bans the user if too many attempts
+are made
+## in a short period of time.
+regulation:
+ ## The number of failed login attempts before user is banned. Set it to 0 to disable regulation.
+ max_retries: 3
+ ## The time range during which the user can attempt login before being banned. The user is banned if the
+ ## authentication failed 'max_retries' times in a 'find_time' seconds window. Find Time accepts duration
+notation.
+ ## See: https://www.authelia.com/c/common#duration-notation-format
+ find_time: 10m
+ ## The length of time before a banned user can login again. Ban Time accepts duration notation.
+ ## See: https://www.authelia.com/c/common#duration-notation-format
+ ban_time: 12h
+##
+## Storage Provider Configuration
+##
+## The available providers are: \`local\`, \`mysql\`, \`postgres\`. You must use one and only one of these providers.
+storage:
+ ## The encryption key that is used to encrypt sensitive information in the database. Must be a string with a
+minimum
+ ## length of 20. Please see the docs if you configure this with an undesirable key and need to change it, you
+MUST use
+ ## the CLI to change this in the database if you want to change it from a previously configured value.
+ encryption_key: REDACTED
+ ##
+ ## Local (Storage Provider)
+ ##
+ ## This stores the data in a SQLite3 Database.
+ ## This is only recommended for lightweight non-stateful installations.
+ ##
+ ## Important: Kubernetes (or HA) users must read https://www.authelia.com/t/statelessness
+ ##
+ # local:
+ ## Path to the SQLite3 Database.
+ # path: /config/db.sqlite3
+ ##
+ ## MySQL / MariaDB (Storage Provider)
+ ##
+ mysql:
+ host: mysql
+ port: 3306
+ database: authelia
+ username: authelia
+ ## Password can also be set using a secret: https://www.authelia.com/c/secrets
+ password: REDACTED
+ timeout: 5s
+ ## MySQL TLS settings. Configuring this requires TLS.
+ # tls:
+ ## The server subject name to check the servers certificate against during the validation process.
+ ## This option is not required if the certificate has a SAN which matches the host option.
+ # server_name: mysql.example.com
+ ## Skip verifying the server certificate entirely. In preference to setting this we strongly recommend you
+add the
+ ## certificate or the certificate of the authority signing the certificate to the certificates directory which is
+ ## defined by the \`certificates_directory\` option at the top of the configuration.
+ ## It's important to note the public key should be added to the directory, not the private key.
+ ## This option is strongly discouraged but may be useful in some self-signed situations where validation is
+not
+ ## important to the administrator.
+ # skip_verify: false
+ ## Minimum TLS version for the connection.
+ # minimum_version: TLS1.2
+ ## Maximum TLS version for the connection.
+ # maximum_version: TLS1.3
+ ## The certificate chain used with the private_key if the server requests TLS Client Authentication
+ ## i.e. Mutual TLS.
+ # certificate_chain: |
+ # -----BEGIN CERTIFICATE-----
+ # MIIC5jCCAc6gAwIBAgIRAK4Sj7FiN6PXo/urPfO4E7owDQYJKoZIhvcNAQELBQAw
+ # EzERMA8GA1UEChMIQXV0aGVsaWEwHhcNNzAwMTAxMDAwMDAwWhcNNzEwMTAxMDAw
+ # MDAwWjATMREwDwYDVQQKEwhBdXRoZWxpYTCCASIwDQYJKoZIhvcNAQEBBQADggEP
+ # ADCCAQoCggEBAPKv3pSyP4ozGEiVLJ14dIWFCEGEgq7WUMI0SZZqQA2ID0L59U/Q
+ # /Usyy7uC9gfMUzODTpANtkOjFQcQAsxlR1FOjVBrX5QgjSvXwbQn3DtwMA7XWSl6
+ # LuYx2rBYSlMSN5UZQm/RxMtXfLK2b51WgEEYDFi+nECSqKzR4R54eOPkBEWRfvuY
+ # 91AMjlhpivg8e4JWkq4LVQUKbmiFYwIdK8XQiN4blY9WwXwJFYs5sQ/UYMwBFi0H
+ # kWOh7GEjfxgoUOPauIueZSMSlQp7zqAH39N0ZSYb6cS0Npj57QoWZSY3ak87ebcR
+ # Nf4rCvZLby7LoN7qYCKxmCaDD3x2+NYpWH8CAwEAAaM1MDMwDgYDVR0PAQH/BAQD
+ # AgWgMBMGA1UdJQQMMAoGCCsGAQUFBwMBMAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcN
+ # AQELBQADggEBAHSITqIQSNzonFl3DzxHPEzr2hp6peo45buAAtu8FZHoA+U7Icfh
+ # /ZXjPg7Xz+hgFwM/DTNGXkMWacQA/PaNWvZspgRJf2AXvNbMSs2UQODr7Tbv+Fb4
+ # lyblmMUNYFMCFVAMU0eIxXAFq2qcwv8UMcQFT0Z/35s6PVOakYnAGGQjTfp5Ljuq
+ # wsdc/xWmM0cHWube6sdRRUD7SY20KU/kWzl8iFO0VbSSrDf1AlEhnLEkp1SPaxXg
+ # OdBnl98MeoramNiJ7NT6Jnyb3zZ578fjaWfThiBpagItI8GZmG4s4Ovh2JbheN8i
+ # ZsjNr9jqHTjhyLVbDRlmJzcqoj4JhbKs6/I^invalid DO NOT USE=
+ # -----END CERTIFICATE-----
+ # -----BEGIN CERTIFICATE-----
+ # MIIDBDCCAeygAwIBAgIRALJsPg21kA0zY4F1wUCIuoMwDQYJKoZIhvcNAQELBQAw
+ # EzERMA8GA1UEChMIQXV0aGVsaWEwHhcNNzAwMTAxMDAwMDAwWhcNNzEwMTAxMDAw
+ # MDAwWjATMREwDwYDVQQKEwhBdXRoZWxpYTCCASIwDQYJKoZIhvcNAQEBBQADggEP
+ # ADCCAQoCggEBAMXHBvVxUzYk0u34/DINMSF+uiOekKOAjOrC6Mi9Ww8ytPVO7t2S
+ # zfTvM+XnEJqkFQFgimERfG/eGhjF9XIEY6LtnXe8ATvOK4nTwdufzBaoeQu3Gd50
+ # 5VXr6OHRo//ErrGvFXwP3g8xLePABsi/fkH3oDN+ztewOBMDzpd+KgTrk8ysv2ou
+ # kNRMKFZZqASvCgv0LD5KWvUCnL6wgf1oTXG7aztduA4oSkUP321GpOmBC5+5ElU7
+ # ysoRzvD12o9QJ/IfEaulIX06w9yVMo60C/h6A3U6GdkT1SiyTIqR7v7KU/IWd/Qi
+ # Lfftcj91VhCmJ73Meff2e2S2PrpjdXbG5FMCAwEAAaNTMFEwDgYDVR0PAQH/BAQD
+ # AgKkMA8GA1UdJQQIMAYGBFUdJQAwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU
+ # Z7AtA3mzFc0InSBA5fiMfeLXA3owDQYJKoZIhvcNAQELBQADggEBAEE5hm1mtlk/
+ # kviCoHH4evbpw7rxPxDftIQlqYTtvMM4eWY/6icFoSZ4fUHEWYyps8SsPu/8f2tf
+ # 71LGgZn0FdHi1QU2H8m0HHK7TFw+5Q6RLrLdSyk0PItJ71s9en7r8pX820nAFEHZ
+ # HkOSfJZ7B5hFgUDkMtVM6bardXAhoqcMk4YCU96e9d4PB4eI+xGc+mNuYvov3RbB
+ # D0s8ICyojeyPVLerz4wHjZu68Z5frAzhZ68YbzNs8j2fIBKKHkHyLG1iQyF+LJVj
+ # 2PjCP+auJsj6fQQpMGoyGtpLcSDh+ptcTngUD8JsWipzTCjmaNqdPHAOYmcgtf4b
+ # qocikt3WAdU^invalid DO NOT USE=
+ # -----END CERTIFICATE-----
+ ## The private key used with the certificate_chain if the server requests TLS Client Authentication
+ ## i.e. Mutual TLS.
+ # private_key: |
+ # -----BEGIN RSA PRIVATE KEY-----
+ # MIIEpAIBAAKCAQEA8q/elLI/ijMYSJUsnXh0hYUIQYSCrtZQwjRJlmpADYgPQvn1
+ # T9D9SzLLu4L2B8xTM4NOkA22Q6MVBxACzGVHUU6NUGtflCCNK9fBtCfcO3AwDtdZ
+ # KXou5jHasFhKUxI3lRlCb9HEy1d8srZvnVaAQRgMWL6cQJKorNHhHnh44+QERZF+
+ # +5j3UAyOWGmK+Dx7glaSrgtVBQpuaIVjAh0rxdCI3huVj1bBfAkVizmxD9RgzAEW
+ # LQeRY6HsYSN/GChQ49q4i55lIxKVCnvOoAff03RlJhvpxLQ2mPntChZlJjdqTzt5
+ # txE1/isK9ktvLsug3upgIrGYJoMPfHb41ilYfwIDAQABAoIBAQDTOdFf2JjHH1um
+ # aPgRAvNf9v7Nj5jytaRKs5nM6iNf46ls4QPreXnMhqSeSwj6lpNgBYxOgzC9Q+cc
+ # Y4ob/paJJPaIJTxmP8K/gyWcOQlNToL1l+eJ20eQoZm23NGr5fIsunSBwLEpTrdB
+ # ENqqtcwhW937K8Pxy/Q1nuLyU2bc6Tn/ivLozc8n27dpQWWKh8537VY7ancIaACr
+ # LJJLYxKqhQpjtBWAyCDvZQirnAOm9KnvIHaGXIswCZ4Xbsu0Y9NL+woARPyRVQvG
+ # jfxy4EmO9s1s6y7OObSukwKDSNihAKHx/VIbvVWx8g2Lv5fGOa+J2Y7o9Qurs8t5
+ # BQwMTt0BAoGBAPUw5Z32EszNepAeV3E2mPFUc5CLiqAxagZJuNDO2pKtyN29ETTR
+ # Ma4O1cWtGb6RqcNNN/Iukfkdk27Q5nC9VJSUUPYelOLc1WYOoUf6oKRzE72dkMQV
+ # R4bf6TkjD+OVR17fAfkswkGahZ5XA7j48KIQ+YC4jbnYKSxZTYyKPjH/AoGBAP1i
+ # tqXt36OVlP+y84wWqZSjMelBIVa9phDVGJmmhz3i1cMni8eLpJzWecA3pfnG6Tm9
+ # ze5M4whASleEt+M00gEvNaU9ND+z0wBfi+/DwJYIbv8PQdGrBiZFrPhTPjGQUldR
+ # lXccV2meeLZv7TagVxSi3DO6dSJfSEHyemd5j9mBAoGAX8Hv+0gOQZQCSOTAq8Nx
+ # 6dZcp9gHlNaXnMsP9eTDckOSzh636JPGvj6m+GPJSSbkURUIQ3oyokMNwFqvlNos
+ # fTaLhAOfjBZI9WnDTTQxpugWjphJ4HqbC67JC/qIiw5S6FdaEvGLEEoD4zoChywZ
+ # 9oGAn+fz2d/0/JAH/FpFPgsCgYEAp/ipZgPzziiZ9ov1wbdAQcWRj7RaWnssPFpX
+ # jXwEiXT3CgEMO4MJ4+KWIWOChrti3qFBg6i6lDyyS6Qyls7sLFbUdC7HlTcrOEMe
+ # rBoTcCI1GqZNlqWOVQ65ZIEiaI7o1vPBZo2GMQEZuq8mDKFsOMThvvTrM5cAep84
+ # n6HJR4ECgYABWcbsSnr0MKvVth/inxjbKapbZnp2HUCuw87Ie5zK2Of/tbC20wwk
+ # yKw3vrGoE3O1t1g2m2tn8UGGASeZ842jZWjIODdSi5+icysQGuULKt86h/woz2SQ
+ # 27GoE2i5mh6Yez6VAYbUuns3FcwIsMyWLq043Tu2DNkx9ijOOAuQzw^invalid..
+ # DO NOT USE==
+ # -----END RSA PRIVATE KEY-----
+ ##
+ ## PostgreSQL (Storage Provider)
+ ##
+ # postgres:
+ # host: 127.0.0.1
+ # port: 5432
+ # database: authelia
+ # schema: public
+ # username: authelia
+ ## Password can also be set using a secret: https://www.authelia.com/c/secrets
+ # password: mypassword
+ # timeout: 5s
+ ## PostgreSQL TLS settings. Configuring this requires TLS.
+ # tls:
+ ## The server subject name to check the servers certificate against during the validation process.
+ ## This option is not required if the certificate has a SAN which matches the host option.
+ # server_name: postgres.example.com
+ ## Skip verifying the server certificate entirely. In preference to setting this we strongly recommend you
+add the
+ ## certificate or the certificate of the authority signing the certificate to the certificates directory which is
+ ## defined by the \`certificates_directory\` option at the top of the configuration.
+ ## It's important to note the public key should be added to the directory, not the private key.
+ ## This option is strongly discouraged but may be useful in some self-signed situations where validation is
+not
+ ## important to the administrator.
+ # skip_verify: false
+ ## Minimum TLS version for the connection.
+ # minimum_version: TLS1.2
+ ## Maximum TLS version for the connection.
+ # maximum_version: TLS1.3
+ ## The certificate chain used with the private_key if the server requests TLS Client Authentication
+ ## i.e. Mutual TLS.
+ # certificate_chain: |
+ # -----BEGIN CERTIFICATE-----
+ # MIIC5jCCAc6gAwIBAgIRAK4Sj7FiN6PXo/urPfO4E7owDQYJKoZIhvcNAQELBQAw
+ # EzERMA8GA1UEChMIQXV0aGVsaWEwHhcNNzAwMTAxMDAwMDAwWhcNNzEwMTAxMDAw
+ # MDAwWjATMREwDwYDVQQKEwhBdXRoZWxpYTCCASIwDQYJKoZIhvcNAQEBBQADggEP
+ # ADCCAQoCggEBAPKv3pSyP4ozGEiVLJ14dIWFCEGEgq7WUMI0SZZqQA2ID0L59U/Q
+ # /Usyy7uC9gfMUzODTpANtkOjFQcQAsxlR1FOjVBrX5QgjSvXwbQn3DtwMA7XWSl6
+ # LuYx2rBYSlMSN5UZQm/RxMtXfLK2b51WgEEYDFi+nECSqKzR4R54eOPkBEWRfvuY
+ # 91AMjlhpivg8e4JWkq4LVQUKbmiFYwIdK8XQiN4blY9WwXwJFYs5sQ/UYMwBFi0H
+ # kWOh7GEjfxgoUOPauIueZSMSlQp7zqAH39N0ZSYb6cS0Npj57QoWZSY3ak87ebcR
+ # Nf4rCvZLby7LoN7qYCKxmCaDD3x2+NYpWH8CAwEAAaM1MDMwDgYDVR0PAQH/BAQD
+ # AgWgMBMGA1UdJQQMMAoGCCsGAQUFBwMBMAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcN
+ # AQELBQADggEBAHSITqIQSNzonFl3DzxHPEzr2hp6peo45buAAtu8FZHoA+U7Icfh
+ # /ZXjPg7Xz+hgFwM/DTNGXkMWacQA/PaNWvZspgRJf2AXvNbMSs2UQODr7Tbv+Fb4
+ # lyblmMUNYFMCFVAMU0eIxXAFq2qcwv8UMcQFT0Z/35s6PVOakYnAGGQjTfp5Ljuq
+ # wsdc/xWmM0cHWube6sdRRUD7SY20KU/kWzl8iFO0VbSSrDf1AlEhnLEkp1SPaxXg
+ # OdBnl98MeoramNiJ7NT6Jnyb3zZ578fjaWfThiBpagItI8GZmG4s4Ovh2JbheN8i
+ # ZsjNr9jqHTjhyLVbDRlmJzcqoj4JhbKs6/I^invalid DO NOT USE=
+ # -----END CERTIFICATE-----
+ # -----BEGIN CERTIFICATE-----
+ # MIIDBDCCAeygAwIBAgIRALJsPg21kA0zY4F1wUCIuoMwDQYJKoZIhvcNAQELBQAw
+ # EzERMA8GA1UEChMIQXV0aGVsaWEwHhcNNzAwMTAxMDAwMDAwWhcNNzEwMTAxMDAw
+ # MDAwWjATMREwDwYDVQQKEwhBdXRoZWxpYTCCASIwDQYJKoZIhvcNAQEBBQADggEP
+ # ADCCAQoCggEBAMXHBvVxUzYk0u34/DINMSF+uiOekKOAjOrC6Mi9Ww8ytPVO7t2S
+ # zfTvM+XnEJqkFQFgimERfG/eGhjF9XIEY6LtnXe8ATvOK4nTwdufzBaoeQu3Gd50
+ # 5VXr6OHRo//ErrGvFXwP3g8xLePABsi/fkH3oDN+ztewOBMDzpd+KgTrk8ysv2ou
+ # kNRMKFZZqASvCgv0LD5KWvUCnL6wgf1oTXG7aztduA4oSkUP321GpOmBC5+5ElU7
+ # ysoRzvD12o9QJ/IfEaulIX06w9yVMo60C/h6A3U6GdkT1SiyTIqR7v7KU/IWd/Qi
+ # Lfftcj91VhCmJ73Meff2e2S2PrpjdXbG5FMCAwEAAaNTMFEwDgYDVR0PAQH/BAQD
+ # AgKkMA8GA1UdJQQIMAYGBFUdJQAwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU
+ # Z7AtA3mzFc0InSBA5fiMfeLXA3owDQYJKoZIhvcNAQELBQADggEBAEE5hm1mtlk/
+ # kviCoHH4evbpw7rxPxDftIQlqYTtvMM4eWY/6icFoSZ4fUHEWYyps8SsPu/8f2tf
+ # 71LGgZn0FdHi1QU2H8m0HHK7TFw+5Q6RLrLdSyk0PItJ71s9en7r8pX820nAFEHZ
+ # HkOSfJZ7B5hFgUDkMtVM6bardXAhoqcMk4YCU96e9d4PB4eI+xGc+mNuYvov3RbB
+ # D0s8ICyojeyPVLerz4wHjZu68Z5frAzhZ68YbzNs8j2fIBKKHkHyLG1iQyF+LJVj
+ # 2PjCP+auJsj6fQQpMGoyGtpLcSDh+ptcTngUD8JsWipzTCjmaNqdPHAOYmcgtf4b
+ # qocikt3WAdU^invalid DO NOT USE=
+ # -----END CERTIFICATE-----
+ ## The private key used with the certificate_chain if the server requests TLS Client Authentication
+ ## i.e. Mutual TLS.
+ # private_key: |
+ # -----BEGIN RSA PRIVATE KEY-----
+ # MIIEpAIBAAKCAQEA8q/elLI/ijMYSJUsnXh0hYUIQYSCrtZQwjRJlmpADYgPQvn1
+ # T9D9SzLLu4L2B8xTM4NOkA22Q6MVBxACzGVHUU6NUGtflCCNK9fBtCfcO3AwDtdZ
+ # KXou5jHasFhKUxI3lRlCb9HEy1d8srZvnVaAQRgMWL6cQJKorNHhHnh44+QERZF+
+ # +5j3UAyOWGmK+Dx7glaSrgtVBQpuaIVjAh0rxdCI3huVj1bBfAkVizmxD9RgzAEW
+ # LQeRY6HsYSN/GChQ49q4i55lIxKVCnvOoAff03RlJhvpxLQ2mPntChZlJjdqTzt5
+ # txE1/isK9ktvLsug3upgIrGYJoMPfHb41ilYfwIDAQABAoIBAQDTOdFf2JjHH1um
+ # aPgRAvNf9v7Nj5jytaRKs5nM6iNf46ls4QPreXnMhqSeSwj6lpNgBYxOgzC9Q+cc
+ # Y4ob/paJJPaIJTxmP8K/gyWcOQlNToL1l+eJ20eQoZm23NGr5fIsunSBwLEpTrdB
+ # ENqqtcwhW937K8Pxy/Q1nuLyU2bc6Tn/ivLozc8n27dpQWWKh8537VY7ancIaACr
+ # LJJLYxKqhQpjtBWAyCDvZQirnAOm9KnvIHaGXIswCZ4Xbsu0Y9NL+woARPyRVQvG
+ # jfxy4EmO9s1s6y7OObSukwKDSNihAKHx/VIbvVWx8g2Lv5fGOa+J2Y7o9Qurs8t5
+ # BQwMTt0BAoGBAPUw5Z32EszNepAeV3E2mPFUc5CLiqAxagZJuNDO2pKtyN29ETTR
+ # Ma4O1cWtGb6RqcNNN/Iukfkdk27Q5nC9VJSUUPYelOLc1WYOoUf6oKRzE72dkMQV
+ # R4bf6TkjD+OVR17fAfkswkGahZ5XA7j48KIQ+YC4jbnYKSxZTYyKPjH/AoGBAP1i
+ # tqXt36OVlP+y84wWqZSjMelBIVa9phDVGJmmhz3i1cMni8eLpJzWecA3pfnG6Tm9
+ # ze5M4whASleEt+M00gEvNaU9ND+z0wBfi+/DwJYIbv8PQdGrBiZFrPhTPjGQUldR
+ # lXccV2meeLZv7TagVxSi3DO6dSJfSEHyemd5j9mBAoGAX8Hv+0gOQZQCSOTAq8Nx
+ # 6dZcp9gHlNaXnMsP9eTDckOSzh636JPGvj6m+GPJSSbkURUIQ3oyokMNwFqvlNos
+ # fTaLhAOfjBZI9WnDTTQxpugWjphJ4HqbC67JC/qIiw5S6FdaEvGLEEoD4zoChywZ
+ # 9oGAn+fz2d/0/JAH/FpFPgsCgYEAp/ipZgPzziiZ9ov1wbdAQcWRj7RaWnssPFpX
+ # jXwEiXT3CgEMO4MJ4+KWIWOChrti3qFBg6i6lDyyS6Qyls7sLFbUdC7HlTcrOEMe
+ # rBoTcCI1GqZNlqWOVQ65ZIEiaI7o1vPBZo2GMQEZuq8mDKFsOMThvvTrM5cAep84
+ # n6HJR4ECgYABWcbsSnr0MKvVth/inxjbKapbZnp2HUCuw87Ie5zK2Of/tbC20wwk
+ # yKw3vrGoE3O1t1g2m2tn8UGGASeZ842jZWjIODdSi5+icysQGuULKt86h/woz2SQ
+ # 27GoE2i5mh6Yez6VAYbUuns3FcwIsMyWLq043Tu2DNkx9ijOOAuQzw^invalid..
+ # DO NOT USE==
+ # -----END RSA PRIVATE KEY-----
+##
+## Notification Provider
+##
+## Notifications are sent to users when they require a password reset, a Webauthn registration or a TOTP
+registration.
+## The available providers are: filesystem, smtp. You must use only one of these providers.
+notifier:
+ ## You can disable the notifier startup check by setting this to true.
+ disable_startup_check: false
+ ##
+ ## File System (Notification Provider)
+ ##
+ ## Important: Kubernetes (or HA) users must read https://www.authelia.com/t/statelessness
+ ##
+# filesystem:
+# filename: /config/notification.txt
+ ##
+ ## SMTP (Notification Provider)
+ ##
+ ## Use a SMTP server for sending notifications. Authelia uses the PLAIN or LOGIN methods to authenticate.
+ ## [Security] By default Authelia will:
+ ## - force all SMTP connections over TLS including unauthenticated connections
+ ## - use the disable_require_tls boolean value to disable this requirement
+ ## (only works for unauthenticated connections)
+ ## - validate the SMTP server x509 certificate during the TLS handshake against the hosts trusted certificates
+ ## (configure in tls section)
+ smtp:
+ ## The SMTP host to connect to.
+ host: smtp.gmail.com
+ ## The port to connect to the SMTP host on.
+ port: 587
+ ## The connection timeout.
+ timeout: 5s
+ ## The username used for SMTP authentication.
+ username: [emailaddressrelay]@gmail.com
+ ## The password used for SMTP authentication.
+ ## Can also be set using a secret: https://www.authelia.com/c/secrets
+ password: REDACTED
+ ## The sender is used to is used for the MAIL FROM command and the FROM header.
+ ## If this is not defined and the username is an email, we use the username as this value. This can either be
+just
+ ## an email address or the RFC5322 'Name <email address>' format.
+ sender: "Authelia <admin@[domain.tld]>"
+ ## HELO/EHLO Identifier. Some SMTP Servers may reject the default of localhost.
+ identifier: [domain.tld]
+ ## Subject configuration of the emails sent. {title} is replaced by the text from the notifier.
+ subject: "[Authelia] {title}"
+ ## This address is used during the startup check to verify the email configuration is correct.
+ ## It's not important what it is except if your email server only allows local delivery.
+ startup_check_address: [emailaddressrelay]@gmail.com
+ ## By default we require some form of TLS. This disables this check though is not advised.
+ # disable_require_tls: false
+ ## Disables sending HTML formatted emails.
+ # disable_html_emails: false
+ tls:
+ ## The server subject name to check the servers certificate against during the validation process.
+ ## This option is not required if the certificate has a SAN which matches the host option.
+ server_name: smtp.gmail.com
+ ## Skip verifying the server certificate entirely. In preference to setting this we strongly recommend you
+add the
+ ## certificate or the certificate of the authority signing the certificate to the certificates directory which is
+ ## defined by the \`certificates_directory\` option at the top of the configuration.
+ ## It's important to note the public key should be added to the directory, not the private key.
+ ## This option is strongly discouraged but may be useful in some self-signed situations where validation is
+not
+ ## important to the administrator.
+ # skip_verify: false
+ ## Minimum TLS version for the connection.
+ # minimum_version: TLS1.2
+ ## Maximum TLS version for the connection.
+ # maximum_version: TLS1.3
+ ## The certificate chain used with the private_key if the server requests TLS Client Authentication
+ ## i.e. Mutual TLS.
+ # certificate_chain: |
+ # -----BEGIN CERTIFICATE-----
+ # MIIC5jCCAc6gAwIBAgIRAK4Sj7FiN6PXo/urPfO4E7owDQYJKoZIhvcNAQELBQAw
+ # EzERMA8GA1UEChMIQXV0aGVsaWEwHhcNNzAwMTAxMDAwMDAwWhcNNzEwMTAxMDAw
+ # MDAwWjATMREwDwYDVQQKEwhBdXRoZWxpYTCCASIwDQYJKoZIhvcNAQEBBQADggEP
+ # ADCCAQoCggEBAPKv3pSyP4ozGEiVLJ14dIWFCEGEgq7WUMI0SZZqQA2ID0L59U/Q
+ # /Usyy7uC9gfMUzODTpANtkOjFQcQAsxlR1FOjVBrX5QgjSvXwbQn3DtwMA7XWSl6
+ # LuYx2rBYSlMSN5UZQm/RxMtXfLK2b51WgEEYDFi+nECSqKzR4R54eOPkBEWRfvuY
+ # 91AMjlhpivg8e4JWkq4LVQUKbmiFYwIdK8XQiN4blY9WwXwJFYs5sQ/UYMwBFi0H
+ # kWOh7GEjfxgoUOPauIueZSMSlQp7zqAH39N0ZSYb6cS0Npj57QoWZSY3ak87ebcR
+ # Nf4rCvZLby7LoN7qYCKxmCaDD3x2+NYpWH8CAwEAAaM1MDMwDgYDVR0PAQH/BAQD
+ # AgWgMBMGA1UdJQQMMAoGCCsGAQUFBwMBMAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcN
+ # AQELBQADggEBAHSITqIQSNzonFl3DzxHPEzr2hp6peo45buAAtu8FZHoA+U7Icfh
+ # /ZXjPg7Xz+hgFwM/DTNGXkMWacQA/PaNWvZspgRJf2AXvNbMSs2UQODr7Tbv+Fb4
+ # lyblmMUNYFMCFVAMU0eIxXAFq2qcwv8UMcQFT0Z/35s6PVOakYnAGGQjTfp5Ljuq
+ # wsdc/xWmM0cHWube6sdRRUD7SY20KU/kWzl8iFO0VbSSrDf1AlEhnLEkp1SPaxXg
+ # OdBnl98MeoramNiJ7NT6Jnyb3zZ578fjaWfThiBpagItI8GZmG4s4Ovh2JbheN8i
+ # ZsjNr9jqHTjhyLVbDRlmJzcqoj4JhbKs6/I^invalid DO NOT USE=
+ # -----END CERTIFICATE-----
+ # -----BEGIN CERTIFICATE-----
+ # MIIDBDCCAeygAwIBAgIRALJsPg21kA0zY4F1wUCIuoMwDQYJKoZIhvcNAQELBQAw
+ # EzERMA8GA1UEChMIQXV0aGVsaWEwHhcNNzAwMTAxMDAwMDAwWhcNNzEwMTAxMDAw
+ # MDAwWjATMREwDwYDVQQKEwhBdXRoZWxpYTCCASIwDQYJKoZIhvcNAQEBBQADggEP
+ # ADCCAQoCggEBAMXHBvVxUzYk0u34/DINMSF+uiOekKOAjOrC6Mi9Ww8ytPVO7t2S
+ # zfTvM+XnEJqkFQFgimERfG/eGhjF9XIEY6LtnXe8ATvOK4nTwdufzBaoeQu3Gd50
+ # 5VXr6OHRo//ErrGvFXwP3g8xLePABsi/fkH3oDN+ztewOBMDzpd+KgTrk8ysv2ou
+ # kNRMKFZZqASvCgv0LD5KWvUCnL6wgf1oTXG7aztduA4oSkUP321GpOmBC5+5ElU7
+ # ysoRzvD12o9QJ/IfEaulIX06w9yVMo60C/h6A3U6GdkT1SiyTIqR7v7KU/IWd/Qi
+ # Lfftcj91VhCmJ73Meff2e2S2PrpjdXbG5FMCAwEAAaNTMFEwDgYDVR0PAQH/BAQD
+ # AgKkMA8GA1UdJQQIMAYGBFUdJQAwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU
+ # Z7AtA3mzFc0InSBA5fiMfeLXA3owDQYJKoZIhvcNAQELBQADggEBAEE5hm1mtlk/
+ # kviCoHH4evbpw7rxPxDftIQlqYTtvMM4eWY/6icFoSZ4fUHEWYyps8SsPu/8f2tf
+ # 71LGgZn0FdHi1QU2H8m0HHK7TFw+5Q6RLrLdSyk0PItJ71s9en7r8pX820nAFEHZ
+ # HkOSfJZ7B5hFgUDkMtVM6bardXAhoqcMk4YCU96e9d4PB4eI+xGc+mNuYvov3RbB
+ # D0s8ICyojeyPVLerz4wHjZu68Z5frAzhZ68YbzNs8j2fIBKKHkHyLG1iQyF+LJVj
+ # 2PjCP+auJsj6fQQpMGoyGtpLcSDh+ptcTngUD8JsWipzTCjmaNqdPHAOYmcgtf4b
+ # qocikt3WAdU^invalid DO NOT USE=
+ # -----END CERTIFICATE-----
+ ## The private key used with the certificate_chain if the server requests TLS Client Authentication
+ ## i.e. Mutual TLS.
+ # private_key: |
+ # -----BEGIN RSA PRIVATE KEY-----
+ # MIIEpAIBAAKCAQEA8q/elLI/ijMYSJUsnXh0hYUIQYSCrtZQwjRJlmpADYgPQvn1
+ # T9D9SzLLu4L2B8xTM4NOkA22Q6MVBxACzGVHUU6NUGtflCCNK9fBtCfcO3AwDtdZ
+ # KXou5jHasFhKUxI3lRlCb9HEy1d8srZvnVaAQRgMWL6cQJKorNHhHnh44+QERZF+
+ # +5j3UAyOWGmK+Dx7glaSrgtVBQpuaIVjAh0rxdCI3huVj1bBfAkVizmxD9RgzAEW
+ # LQeRY6HsYSN/GChQ49q4i55lIxKVCnvOoAff03RlJhvpxLQ2mPntChZlJjdqTzt5
+ # txE1/isK9ktvLsug3upgIrGYJoMPfHb41ilYfwIDAQABAoIBAQDTOdFf2JjHH1um
+ # aPgRAvNf9v7Nj5jytaRKs5nM6iNf46ls4QPreXnMhqSeSwj6lpNgBYxOgzC9Q+cc
+ # Y4ob/paJJPaIJTxmP8K/gyWcOQlNToL1l+eJ20eQoZm23NGr5fIsunSBwLEpTrdB
+ # ENqqtcwhW937K8Pxy/Q1nuLyU2bc6Tn/ivLozc8n27dpQWWKh8537VY7ancIaACr
+ # LJJLYxKqhQpjtBWAyCDvZQirnAOm9KnvIHaGXIswCZ4Xbsu0Y9NL+woARPyRVQvG
+ # jfxy4EmO9s1s6y7OObSukwKDSNihAKHx/VIbvVWx8g2Lv5fGOa+J2Y7o9Qurs8t5
+ # BQwMTt0BAoGBAPUw5Z32EszNepAeV3E2mPFUc5CLiqAxagZJuNDO2pKtyN29ETTR
+ # Ma4O1cWtGb6RqcNNN/Iukfkdk27Q5nC9VJSUUPYelOLc1WYOoUf6oKRzE72dkMQV
+ # R4bf6TkjD+OVR17fAfkswkGahZ5XA7j48KIQ+YC4jbnYKSxZTYyKPjH/AoGBAP1i
+ # tqXt36OVlP+y84wWqZSjMelBIVa9phDVGJmmhz3i1cMni8eLpJzWecA3pfnG6Tm9
+ # ze5M4whASleEt+M00gEvNaU9ND+z0wBfi+/DwJYIbv8PQdGrBiZFrPhTPjGQUldR
+ # lXccV2meeLZv7TagVxSi3DO6dSJfSEHyemd5j9mBAoGAX8Hv+0gOQZQCSOTAq8Nx
+ # 6dZcp9gHlNaXnMsP9eTDckOSzh636JPGvj6m+GPJSSbkURUIQ3oyokMNwFqvlNos
+ # fTaLhAOfjBZI9WnDTTQxpugWjphJ4HqbC67JC/qIiw5S6FdaEvGLEEoD4zoChywZ
+ # 9oGAn+fz2d/0/JAH/FpFPgsCgYEAp/ipZgPzziiZ9ov1wbdAQcWRj7RaWnssPFpX
+ # jXwEiXT3CgEMO4MJ4+KWIWOChrti3qFBg6i6lDyyS6Qyls7sLFbUdC7HlTcrOEMe
+ # rBoTcCI1GqZNlqWOVQ65ZIEiaI7o1vPBZo2GMQEZuq8mDKFsOMThvvTrM5cAep84
+ # n6HJR4ECgYABWcbsSnr0MKvVth/inxjbKapbZnp2HUCuw87Ie5zK2Of/tbC20wwk
+ # yKw3vrGoE3O1t1g2m2tn8UGGASeZ842jZWjIODdSi5+icysQGuULKt86h/woz2SQ
+ # 27GoE2i5mh6Yez6VAYbUuns3FcwIsMyWLq043Tu2DNkx9ijOOAuQzw^invalid..
+ # DO NOT USE==
+ # -----END RSA PRIVATE KEY-----
+##
+## Identity Providers
+##
+# identity_providers:
+ ##
+ ## OpenID Connect (Identity Provider)
+ ##
+ ## It's recommended you read the documentation before configuration of this section:
+ ## https://www.authelia.com/c/oidc
+ # oidc:
+ ## The hmac_secret is used to sign OAuth2 tokens (authorization code, access tokens and refresh tokens).
+ ## HMAC Secret can also be set using a secret: https://www.authelia.com/c/secrets
+ # hmac_secret: this_is_a_secret_abc123abc123abc
+ ## The issuer_certificate_chain is an optional PEM encoded certificate chain. It's used in conjunction with the
+ ## issuer_private_key to sign JWT's. All certificates in the chain must be within the validity period, and every
+ ## certificate included must be signed by the certificate immediately after it if provided.
+ # issuer_certificate_chain: |
+ # -----BEGIN CERTIFICATE-----
+ # MIIC5jCCAc6gAwIBAgIRAK4Sj7FiN6PXo/urPfO4E7owDQYJKoZIhvcNAQELBQAw
+ # EzERMA8GA1UEChMIQXV0aGVsaWEwHhcNNzAwMTAxMDAwMDAwWhcNNzEwMTAxMDAw
+ # MDAwWjATMREwDwYDVQQKEwhBdXRoZWxpYTCCASIwDQYJKoZIhvcNAQEBBQADggEP
+ # ADCCAQoCggEBAPKv3pSyP4ozGEiVLJ14dIWFCEGEgq7WUMI0SZZqQA2ID0L59U/Q
+ # /Usyy7uC9gfMUzODTpANtkOjFQcQAsxlR1FOjVBrX5QgjSvXwbQn3DtwMA7XWSl6
+ # LuYx2rBYSlMSN5UZQm/RxMtXfLK2b51WgEEYDFi+nECSqKzR4R54eOPkBEWRfvuY
+ # 91AMjlhpivg8e4JWkq4LVQUKbmiFYwIdK8XQiN4blY9WwXwJFYs5sQ/UYMwBFi0H
+ # kWOh7GEjfxgoUOPauIueZSMSlQp7zqAH39N0ZSYb6cS0Npj57QoWZSY3ak87ebcR
+ # Nf4rCvZLby7LoN7qYCKxmCaDD3x2+NYpWH8CAwEAAaM1MDMwDgYDVR0PAQH/BAQD
+ # AgWgMBMGA1UdJQQMMAoGCCsGAQUFBwMBMAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcN
+ # AQELBQADggEBAHSITqIQSNzonFl3DzxHPEzr2hp6peo45buAAtu8FZHoA+U7Icfh
+ # /ZXjPg7Xz+hgFwM/DTNGXkMWacQA/PaNWvZspgRJf2AXvNbMSs2UQODr7Tbv+Fb4
+ # lyblmMUNYFMCFVAMU0eIxXAFq2qcwv8UMcQFT0Z/35s6PVOakYnAGGQjTfp5Ljuq
+ # wsdc/xWmM0cHWube6sdRRUD7SY20KU/kWzl8iFO0VbSSrDf1AlEhnLEkp1SPaxXg
+ # OdBnl98MeoramNiJ7NT6Jnyb3zZ578fjaWfThiBpagItI8GZmG4s4Ovh2JbheN8i
+ # ZsjNr9jqHTjhyLVbDRlmJzcqoj4JhbKs6/I^invalid DO NOT USE=
+ # -----END CERTIFICATE-----
+ # -----BEGIN CERTIFICATE-----
+ # MIIDBDCCAeygAwIBAgIRALJsPg21kA0zY4F1wUCIuoMwDQYJKoZIhvcNAQELBQAw
+ # EzERMA8GA1UEChMIQXV0aGVsaWEwHhcNNzAwMTAxMDAwMDAwWhcNNzEwMTAxMDAw
+ # MDAwWjATMREwDwYDVQQKEwhBdXRoZWxpYTCCASIwDQYJKoZIhvcNAQEBBQADggEP
+ # ADCCAQoCggEBAMXHBvVxUzYk0u34/DINMSF+uiOekKOAjOrC6Mi9Ww8ytPVO7t2S
+ # zfTvM+XnEJqkFQFgimERfG/eGhjF9XIEY6LtnXe8ATvOK4nTwdufzBaoeQu3Gd50
+ # 5VXr6OHRo//ErrGvFXwP3g8xLePABsi/fkH3oDN+ztewOBMDzpd+KgTrk8ysv2ou
+ # kNRMKFZZqASvCgv0LD5KWvUCnL6wgf1oTXG7aztduA4oSkUP321GpOmBC5+5ElU7
+ # ysoRzvD12o9QJ/IfEaulIX06w9yVMo60C/h6A3U6GdkT1SiyTIqR7v7KU/IWd/Qi
+ # Lfftcj91VhCmJ73Meff2e2S2PrpjdXbG5FMCAwEAAaNTMFEwDgYDVR0PAQH/BAQD
+ # AgKkMA8GA1UdJQQIMAYGBFUdJQAwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU
+ # Z7AtA3mzFc0InSBA5fiMfeLXA3owDQYJKoZIhvcNAQELBQADggEBAEE5hm1mtlk/
+ # kviCoHH4evbpw7rxPxDftIQlqYTtvMM4eWY/6icFoSZ4fUHEWYyps8SsPu/8f2tf
+ # 71LGgZn0FdHi1QU2H8m0HHK7TFw+5Q6RLrLdSyk0PItJ71s9en7r8pX820nAFEHZ
+ # HkOSfJZ7B5hFgUDkMtVM6bardXAhoqcMk4YCU96e9d4PB4eI+xGc+mNuYvov3RbB
+ # D0s8ICyojeyPVLerz4wHjZu68Z5frAzhZ68YbzNs8j2fIBKKHkHyLG1iQyF+LJVj
+ # 2PjCP+auJsj6fQQpMGoyGtpLcSDh+ptcTngUD8JsWipzTCjmaNqdPHAOYmcgtf4b
+ # qocikt3WAdU^invalid DO NOT USE=
+ # -----END CERTIFICATE-----
+ ## The issuer_private_key is used to sign the JWT forged by OpenID Connect.
+ ## Issuer Private Key can also be set using a secret: https://www.authelia.com/c/secrets
+ # issuer_private_key: |
+ # -----BEGIN RSA PRIVATE KEY-----
+ # MIIEpAIBAAKCAQEA8q/elLI/ijMYSJUsnXh0hYUIQYSCrtZQwjRJlmpADYgPQvn1
+ # T9D9SzLLu4L2B8xTM4NOkA22Q6MVBxACzGVHUU6NUGtflCCNK9fBtCfcO3AwDtdZ
+ # KXou5jHasFhKUxI3lRlCb9HEy1d8srZvnVaAQRgMWL6cQJKorNHhHnh44+QERZF+
+ # +5j3UAyOWGmK+Dx7glaSrgtVBQpuaIVjAh0rxdCI3huVj1bBfAkVizmxD9RgzAEW
+ # LQeRY6HsYSN/GChQ49q4i55lIxKVCnvOoAff03RlJhvpxLQ2mPntChZlJjdqTzt5
+ # txE1/isK9ktvLsug3upgIrGYJoMPfHb41ilYfwIDAQABAoIBAQDTOdFf2JjHH1um
+ # aPgRAvNf9v7Nj5jytaRKs5nM6iNf46ls4QPreXnMhqSeSwj6lpNgBYxOgzC9Q+cc
+ # Y4ob/paJJPaIJTxmP8K/gyWcOQlNToL1l+eJ20eQoZm23NGr5fIsunSBwLEpTrdB
+ # ENqqtcwhW937K8Pxy/Q1nuLyU2bc6Tn/ivLozc8n27dpQWWKh8537VY7ancIaACr
+ # LJJLYxKqhQpjtBWAyCDvZQirnAOm9KnvIHaGXIswCZ4Xbsu0Y9NL+woARPyRVQvG
+ # jfxy4EmO9s1s6y7OObSukwKDSNihAKHx/VIbvVWx8g2Lv5fGOa+J2Y7o9Qurs8t5
+ # BQwMTt0BAoGBAPUw5Z32EszNepAeV3E2mPFUc5CLiqAxagZJuNDO2pKtyN29ETTR
+ # Ma4O1cWtGb6RqcNNN/Iukfkdk27Q5nC9VJSUUPYelOLc1WYOoUf6oKRzE72dkMQV
+ # R4bf6TkjD+OVR17fAfkswkGahZ5XA7j48KIQ+YC4jbnYKSxZTYyKPjH/AoGBAP1i
+ # tqXt36OVlP+y84wWqZSjMelBIVa9phDVGJmmhz3i1cMni8eLpJzWecA3pfnG6Tm9
+ # ze5M4whASleEt+M00gEvNaU9ND+z0wBfi+/DwJYIbv8PQdGrBiZFrPhTPjGQUldR
+ # lXccV2meeLZv7TagVxSi3DO6dSJfSEHyemd5j9mBAoGAX8Hv+0gOQZQCSOTAq8Nx
+ # 6dZcp9gHlNaXnMsP9eTDckOSzh636JPGvj6m+GPJSSbkURUIQ3oyokMNwFqvlNos
+ # fTaLhAOfjBZI9WnDTTQxpugWjphJ4HqbC67JC/qIiw5S6FdaEvGLEEoD4zoChywZ
+ # 9oGAn+fz2d/0/JAH/FpFPgsCgYEAp/ipZgPzziiZ9ov1wbdAQcWRj7RaWnssPFpX
+ # jXwEiXT3CgEMO4MJ4+KWIWOChrti3qFBg6i6lDyyS6Qyls7sLFbUdC7HlTcrOEMe
+ # rBoTcCI1GqZNlqWOVQ65ZIEiaI7o1vPBZo2GMQEZuq8mDKFsOMThvvTrM5cAep84
+ # n6HJR4ECgYABWcbsSnr0MKvVth/inxjbKapbZnp2HUCuw87Ie5zK2Of/tbC20wwk
+ # yKw3vrGoE3O1t1g2m2tn8UGGASeZ842jZWjIODdSi5+icysQGuULKt86h/woz2SQ
+ # 27GoE2i5mh6Yez6VAYbUuns3FcwIsMyWLq043Tu2DNkx9ijOOAuQzw^invalid..
+ # DO NOT USE==
+ # -----END RSA PRIVATE KEY-----
+ ## The lifespans configure the expiration for these token types.
+ # access_token_lifespan: 1h
+ # authorize_code_lifespan: 1m
+ # id_token_lifespan: 1h
+ # refresh_token_lifespan: 90m
+ ## Enables additional debug messages.
+ # enable_client_debug_messages: false
+ ## SECURITY NOTICE: It's not recommended changing this option and values below 8 are strongly
+discouraged.
+ # minimum_parameter_entropy: 8
+ ## SECURITY NOTICE: It's not recommended changing this option, and highly discouraged to have it set to
+'never'
+ ## for security reasons.
+ # enforce_pkce: public_clients_only
+ ## Cross-Origin Resource Sharing (CORS) settings.
+ # cors:
+ ## List of endpoints in addition to the metadata endpoints to permit cross-origin requests on.
+ # endpoints:
+ # - authorization
+ # - token
+ # - revocation
+ # - introspection
+ # - userinfo
+ ## List of allowed origins.
+ ## Any origin with https is permitted unless this option is configured or the
+ ## allowed_origins_from_client_redirect_uris option is enabled.
+ # allowed_origins:
+ # - https://example.com
+ ## Automatically adds the origin portion of all redirect URI's on all clients to the list of allowed_origins,
+ ## provided they have the scheme http or https and do not have the hostname of localhost.
+ # allowed_origins_from_client_redirect_uris: false
+ ## Clients is a list of known clients and their configuration.
+ # clients:
+ # -
+ ## The ID is the OpenID Connect ClientID which is used to link an application to a configuration.
+ # id: myapp
+ ## The description to show to users when they end up on the consent screen. Defaults to the ID above.
+ # description: My Application
+ ## The client secret is a shared secret between Authelia and the consumer of this client.
+ # secret: this_is_a_secret
+ ## Sector Identifiers are occasionally used to generate pairwise subject identifiers. In most cases this is not
+ ## necessary. Read the documentation for more information.
+ ## The subject identifier must be the host component of a URL, which is a domain name with an optional
+port.
+ # sector_identifier: example.com
+ ## Sets the client to public. This should typically not be set, please see the documentation for usage.
+ # public: false
+ ## The policy to require for this client; one_factor or two_factor.
+ # authorization_policy: two_factor
+ ## The consent mode controls how consent is obtained.
+ # consent_mode: auto
+ ## This value controls the duration a consent on this client remains remembered when the consent mode
+is
+ ## configured as 'auto' or 'pre-configured'.
+ # pre_configured_consent_duration: 1w
+ ## Audience this client is allowed to request.
+ # audience: []
+ ## Scopes this client is allowed to request.
+ # scopes:
+ # - openid
+ # - groups
+ # - email
+ # - profile
+ ## Redirect URI's specifies a list of valid case-sensitive callbacks for this client.
+ # redirect_uris:
+ # - https://oidc.example.com:8080/oauth2/callback
+ ## Grant Types configures which grants this client can obtain.
+ ## It's not recommended to define this unless you know what you're doing.
+ # grant_types:
+ # - refresh_token
+ # - authorization_code
+ ## Response Types configures which responses this client can be sent.
+ ## It's not recommended to define this unless you know what you're doing.
+ # response_types:
+ # - code
+ ## Response Modes configures which response modes this client supports.
+ # response_modes:
+ # - form_post
+ # - query
+ # - fragment
+ ## The algorithm used to sign userinfo endpoint responses for this client, either none or RS256.
+ # userinfo_signing_algorithm: none
`,3)]))}const c=i(e,[["render",p]]);export{d as __pageData,c as default}; diff --git a/.vitepress/dist/assets/configuration_authy-duo-config.md.Czz1BBMP.js b/.vitepress/dist/assets/configuration_authy-duo-config.md.Czz1BBMP.js new file mode 100644 index 0000000..47100c7 --- /dev/null +++ b/.vitepress/dist/assets/configuration_authy-duo-config.md.Czz1BBMP.js @@ -0,0 +1 @@ +import{_ as t,c as o,a3 as a,o as i}from"./chunks/framework.DtMx7FFi.js";const d=JSON.parse('{"title":"DP-Salad Configuration","description":"","frontmatter":{"title":"DP-Salad Configuration"},"headers":[],"relativePath":"configuration/authy-duo-config.md","filePath":"configuration/authy-duo-config.md"}'),n={name:"configuration/authy-duo-config.md"};function s(r,e,u,l,h,c){return i(),o("div",null,e[0]||(e[0]=[a('

Authy/Duo Configuration ​

This is like one of those "Choose Your Own Adventure" books! Pick one, not the other, it may be hard to swap later on. You may be able to give your user a choice too! 2FA is handled by either Authelia using an 8 digit code that generates through Authy or it can be passed off to Duo to handle, and then "reinjected" back into the authentication process later on. I'll outline steps for both, and you can choose the method(s) you want your users to be able to 2FA.


Authy is probably the easiest, and the cheapest way to configure 2FA, especially if you are going to have more than 5 users.

The default for the SALA/D Stack for 2FA for the more technical people is SHA1, 8 Digits

All this means for the user is what applications are supported, list is below:

  • Bitwarden / Vaultwarden (Password Managers, Vaultwarden can be selfhosted!, 2FA is setup in addition to account)
  • Authy (Recommended application, named as the best for the stack)
  • Aegis (Supported, never used. YMMV)

These three options are supported for 2FA for Authelia . It is recommended to actually set this up, as it prevents complete lockouts.


Duo is another way to configure 2FA. If you enable Duo 2FA, you'll need to consult the documentation for Duo setup via Authelia, I've linked some setup links here.

https://www.authelia.com/configuration/second-factor/duo/

https://www.authelia.com/overview/authentication/push-notification/

You'll need to modify the configuration of Authelia to finish the setup of 2FA via Duo.

',13)]))}const f=t(n,[["render",s]]);export{d as __pageData,f as default}; diff --git a/.vitepress/dist/assets/configuration_authy-duo-config.md.Czz1BBMP.lean.js b/.vitepress/dist/assets/configuration_authy-duo-config.md.Czz1BBMP.lean.js new file mode 100644 index 0000000..47100c7 --- /dev/null +++ b/.vitepress/dist/assets/configuration_authy-duo-config.md.Czz1BBMP.lean.js @@ -0,0 +1 @@ +import{_ as t,c as o,a3 as a,o as i}from"./chunks/framework.DtMx7FFi.js";const d=JSON.parse('{"title":"DP-Salad Configuration","description":"","frontmatter":{"title":"DP-Salad Configuration"},"headers":[],"relativePath":"configuration/authy-duo-config.md","filePath":"configuration/authy-duo-config.md"}'),n={name:"configuration/authy-duo-config.md"};function s(r,e,u,l,h,c){return i(),o("div",null,e[0]||(e[0]=[a('

Authy/Duo Configuration ​

This is like one of those "Choose Your Own Adventure" books! Pick one, not the other, it may be hard to swap later on. You may be able to give your user a choice too! 2FA is handled by either Authelia using an 8 digit code that generates through Authy or it can be passed off to Duo to handle, and then "reinjected" back into the authentication process later on. I'll outline steps for both, and you can choose the method(s) you want your users to be able to 2FA.


Authy is probably the easiest, and the cheapest way to configure 2FA, especially if you are going to have more than 5 users.

The default for the SALA/D Stack for 2FA for the more technical people is SHA1, 8 Digits

All this means for the user is what applications are supported, list is below:

  • Bitwarden / Vaultwarden (Password Managers, Vaultwarden can be selfhosted!, 2FA is setup in addition to account)
  • Authy (Recommended application, named as the best for the stack)
  • Aegis (Supported, never used. YMMV)

These three options are supported for 2FA for Authelia . It is recommended to actually set this up, as it prevents complete lockouts.


Duo is another way to configure 2FA. If you enable Duo 2FA, you'll need to consult the documentation for Duo setup via Authelia, I've linked some setup links here.

https://www.authelia.com/configuration/second-factor/duo/

https://www.authelia.com/overview/authentication/push-notification/

You'll need to modify the configuration of Authelia to finish the setup of 2FA via Duo.

',13)]))}const f=t(n,[["render",s]]);export{d as __pageData,f as default}; diff --git a/.vitepress/dist/assets/configuration_lldap-config.md.r20NA1Ia.js b/.vitepress/dist/assets/configuration_lldap-config.md.r20NA1Ia.js new file mode 100644 index 0000000..de8a9c1 --- /dev/null +++ b/.vitepress/dist/assets/configuration_lldap-config.md.r20NA1Ia.js @@ -0,0 +1,131 @@ +import{_ as a,c as i,a3 as n,o as e}from"./chunks/framework.DtMx7FFi.js";const c=JSON.parse('{"title":"LLDAP Configuration","description":"","frontmatter":{"title":"LLDAP Configuration"},"headers":[],"relativePath":"configuration/lldap-config.md","filePath":"configuration/lldap-config.md"}'),t={name:"configuration/lldap-config.md"};function l(p,s,h,o,r,k){return e(),i("div",null,s[0]||(s[0]=[n(`

LLDAP Configuration ​

LLDAP is the Light Lightweight Directory Access Protocol, and for our purposes, it will store all the information that we have on our users, like usernames, emails, and hashed passwords. These are the typical values, and only a few more exist in this light implementation of LDAP. I include a sample config file if you don't want to set values in the Docker Compose file.

As with the Authelia Configuration, please change things in square brackets to your relevant values. This file uses REPLACE_WITH to tell you where to replace other such values like secrets/tokens.

yaml
## Default configuration for Docker.
+## All the values can be overridden through environment variables, prefixed
+## with "LLDAP_". For instance, "ldap_port" can be overridden with the
+## "LLDAP_LDAP_PORT" variable.
+## Tune the logging to be more verbose by setting this to be true.
+## You can set it with the LLDAP_VERBOSE environment variable.
+# verbose=false
+## The host address that the LDAP server will be bound to.
+## To enable IPv6 support, simply switch "ldap_host" to "::":
+## To only allow connections from localhost (if you want to restrict to local self-hosted services),
+## change it to "127.0.0.1" ("::1" in case of IPv6)".
+ldap_host = "0.0.0.0"
+## The port on which to have the LDAP server.
+ldap_port = 3890
+## The host address that the HTTP server will be bound to.
+## To enable IPv6 support, simply switch "http_host" to "::".
+## To only allow connections from localhost (if you want to restrict to local self-hosted services),
+## change it to "127.0.0.1" ("::1" in case of IPv6)".
+http_host = "0.0.0.0"
+## The port on which to have the HTTP server, for user login and
+## administration.
+http_port = 17170
+## The public URL of the server, for password reset links.
+#http_url = "http://localhost"
+## Random secret for JWT signature.
+## This secret should be random, and should be shared with application
+## servers that need to consume the JWTs.
+## Changing this secret will invalidate all user sessions and require
+## them to re-login.
+## You should probably set it through the LLDAP_JWT_SECRET environment
+## variable from a secret ".env" file.
+## This can also be set from a file's contents by specifying the file path
+## in the LLDAP_JWT_SECRET_FILE environment variable
+## You can generate it with (on linux):
+## LC_ALL=C tr -dc 'A-Za-z0-9!#%&'\\''()*+,-./:;<=>?@[\\]^_{|}~' </dev/urandom | head -c 32; echo ''
+jwt_secret = "REPLACE_WITH_RANDOM"
+## Base DN for LDAP.
+## This is usually your domain name, and is used as a
+## namespace for your users. The choice is arbitrary, but will be needed
+## to configure the LDAP integration with other services.
+## The sample value is for "example.com", but you can extend it with as
+## many "dc" as you want, and you don't actually need to own the domain
+## name.
+ldap_base_dn = "dc=[DOMAIN],dc=[TLD]"
+## Admin username.
+## For the LDAP interface, a value of "admin" here will create the LDAP
+## user "cn=admin,ou=people,dc=example,dc=com" (with the base DN above).
+## For the administration interface, this is the username.
+ldap_user_dn = "admin"
+## Admin email.
+## Email for the admin account. It is only used when initially creating
+## the admin user, and can safely be omitted.
+ldap_user_email = "admin@[DOMAIN.TLD]"
+## Admin password.
+## Password for the admin account, both for the LDAP bind and for the
+## administration interface. It is only used when initially creating
+## the admin user.
+## It should be minimum 8 characters long.
+## You can set it with the LLDAP_LDAP_USER_PASS environment variable.
+## This can also be set from a file's contents by specifying the file path
+## in the LLDAP_LDAP_USER_PASS_FILE environment variable
+## Note: you can create another admin user for user administration, this
+## is just the default one.
+ldap_user_pass = "REPLACE_WITH_PASSWORD"
+## Database URL.
+## This encodes the type of database (SQlite, MySQL, or PostgreSQL)
+## , the path, the user, password, and sometimes the mode (when
+## relevant).
+## Note: SQlite should come with "?mode=rwc" to create the DB
+## if not present.
+## Example URLs:
+## - "postgres://postgres-user:password@postgres-server/my-database"
+## - "mysql://mysql-user:password@mysql-server/my-database"
+##
+## This can be overridden with the LLDAP_DATABASE_URL env variable.
+database_url = "sqlite:///data/users.db?mode=rwc"
+## Private key file.
+## Contains the secret private key used to store the passwords safely.
+## Note that even with a database dump and the private key, an attacker
+## would still have to perform an (expensive) brute force attack to find
+## each password.
+## Randomly generated on first run if it doesn't exist.
+## Alternatively, you can use key_seed to override this instead of relying on
+## a file.
+## Env variable: LLDAP_KEY_FILE
+key_file = "/data/private_key"
+## Seed to generate the server private key, see key_file above.
+## This can be any random string, the recommendation is that it's at least 12
+## characters long.
+## Env variable: LLDAP_KEY_SEED
+#key_seed = "RanD0m STR1ng"
+## Ignored attributes.
+## Some services will request attributes that are not present in LLDAP. When it
+## is the case, LLDAP will warn about the attribute being unknown. If you want
+## to ignore the attribute and the service works without, you can add it to this
+## list to silence the warning.
+#ignored_user_attributes = [ "sAMAccountName" ]
+#ignored_group_attributes = [ "mail", "userPrincipalName" ]
+## Options to configure SMTP parameters, to send password reset emails.
+## To set these options from environment variables, use the following format
+## (example with "password"): LLDAP_SMTP_OPTIONS__PASSWORD
+[smtp_options]
+## Whether to enabled password reset via email, from LLDAP.
+#enable_password_reset=true
+## The SMTP server.
+#server="smtp.gmail.com"
+## The SMTP port.
+#port=587
+## How the connection is encrypted, either "NONE" (no encryption), "TLS" or "STARTTLS".
+#smtp_encryption = "TLS"
+## The SMTP user, usually your email address.
+#user="sender@gmail.com"
+## The SMTP password.
+#password="password"
+## The header field, optional: how the sender appears in the email. The first
+## is a free-form name, followed by an email between <>.
+#from="LLDAP Admin <sender@gmail.com>"
+## Same for reply-to, optional.
+#reply_to="Do not reply <noreply@localhost>"
+## Options to configure LDAPS.
+## To set these options from environment variables, use the following format
+## (example with "port"): LLDAP_LDAPS_OPTIONS__PORT
+[ldaps_options]
+## Whether to enable LDAPS.
+#enabled=true
+## Port on which to listen.
+#port=6360
+## Certificate file.
+#cert_file="/data/cert.pem"
+## Certificate key file.
+#key_file="/data/key.pem"
`,4)]))}const A=a(t,[["render",l]]);export{c as __pageData,A as default}; diff --git a/.vitepress/dist/assets/configuration_lldap-config.md.r20NA1Ia.lean.js b/.vitepress/dist/assets/configuration_lldap-config.md.r20NA1Ia.lean.js new file mode 100644 index 0000000..de8a9c1 --- /dev/null +++ b/.vitepress/dist/assets/configuration_lldap-config.md.r20NA1Ia.lean.js @@ -0,0 +1,131 @@ +import{_ as a,c as i,a3 as n,o as e}from"./chunks/framework.DtMx7FFi.js";const c=JSON.parse('{"title":"LLDAP Configuration","description":"","frontmatter":{"title":"LLDAP Configuration"},"headers":[],"relativePath":"configuration/lldap-config.md","filePath":"configuration/lldap-config.md"}'),t={name:"configuration/lldap-config.md"};function l(p,s,h,o,r,k){return e(),i("div",null,s[0]||(s[0]=[n(`

LLDAP Configuration ​

LLDAP is the Light Lightweight Directory Access Protocol, and for our purposes, it will store all the information that we have on our users, like usernames, emails, and hashed passwords. These are the typical values, and only a few more exist in this light implementation of LDAP. I include a sample config file if you don't want to set values in the Docker Compose file.

As with the Authelia Configuration, please change things in square brackets to your relevant values. This file uses REPLACE_WITH to tell you where to replace other such values like secrets/tokens.

yaml
## Default configuration for Docker.
+## All the values can be overridden through environment variables, prefixed
+## with "LLDAP_". For instance, "ldap_port" can be overridden with the
+## "LLDAP_LDAP_PORT" variable.
+## Tune the logging to be more verbose by setting this to be true.
+## You can set it with the LLDAP_VERBOSE environment variable.
+# verbose=false
+## The host address that the LDAP server will be bound to.
+## To enable IPv6 support, simply switch "ldap_host" to "::":
+## To only allow connections from localhost (if you want to restrict to local self-hosted services),
+## change it to "127.0.0.1" ("::1" in case of IPv6)".
+ldap_host = "0.0.0.0"
+## The port on which to have the LDAP server.
+ldap_port = 3890
+## The host address that the HTTP server will be bound to.
+## To enable IPv6 support, simply switch "http_host" to "::".
+## To only allow connections from localhost (if you want to restrict to local self-hosted services),
+## change it to "127.0.0.1" ("::1" in case of IPv6)".
+http_host = "0.0.0.0"
+## The port on which to have the HTTP server, for user login and
+## administration.
+http_port = 17170
+## The public URL of the server, for password reset links.
+#http_url = "http://localhost"
+## Random secret for JWT signature.
+## This secret should be random, and should be shared with application
+## servers that need to consume the JWTs.
+## Changing this secret will invalidate all user sessions and require
+## them to re-login.
+## You should probably set it through the LLDAP_JWT_SECRET environment
+## variable from a secret ".env" file.
+## This can also be set from a file's contents by specifying the file path
+## in the LLDAP_JWT_SECRET_FILE environment variable
+## You can generate it with (on linux):
+## LC_ALL=C tr -dc 'A-Za-z0-9!#%&'\\''()*+,-./:;<=>?@[\\]^_{|}~' </dev/urandom | head -c 32; echo ''
+jwt_secret = "REPLACE_WITH_RANDOM"
+## Base DN for LDAP.
+## This is usually your domain name, and is used as a
+## namespace for your users. The choice is arbitrary, but will be needed
+## to configure the LDAP integration with other services.
+## The sample value is for "example.com", but you can extend it with as
+## many "dc" as you want, and you don't actually need to own the domain
+## name.
+ldap_base_dn = "dc=[DOMAIN],dc=[TLD]"
+## Admin username.
+## For the LDAP interface, a value of "admin" here will create the LDAP
+## user "cn=admin,ou=people,dc=example,dc=com" (with the base DN above).
+## For the administration interface, this is the username.
+ldap_user_dn = "admin"
+## Admin email.
+## Email for the admin account. It is only used when initially creating
+## the admin user, and can safely be omitted.
+ldap_user_email = "admin@[DOMAIN.TLD]"
+## Admin password.
+## Password for the admin account, both for the LDAP bind and for the
+## administration interface. It is only used when initially creating
+## the admin user.
+## It should be minimum 8 characters long.
+## You can set it with the LLDAP_LDAP_USER_PASS environment variable.
+## This can also be set from a file's contents by specifying the file path
+## in the LLDAP_LDAP_USER_PASS_FILE environment variable
+## Note: you can create another admin user for user administration, this
+## is just the default one.
+ldap_user_pass = "REPLACE_WITH_PASSWORD"
+## Database URL.
+## This encodes the type of database (SQlite, MySQL, or PostgreSQL)
+## , the path, the user, password, and sometimes the mode (when
+## relevant).
+## Note: SQlite should come with "?mode=rwc" to create the DB
+## if not present.
+## Example URLs:
+## - "postgres://postgres-user:password@postgres-server/my-database"
+## - "mysql://mysql-user:password@mysql-server/my-database"
+##
+## This can be overridden with the LLDAP_DATABASE_URL env variable.
+database_url = "sqlite:///data/users.db?mode=rwc"
+## Private key file.
+## Contains the secret private key used to store the passwords safely.
+## Note that even with a database dump and the private key, an attacker
+## would still have to perform an (expensive) brute force attack to find
+## each password.
+## Randomly generated on first run if it doesn't exist.
+## Alternatively, you can use key_seed to override this instead of relying on
+## a file.
+## Env variable: LLDAP_KEY_FILE
+key_file = "/data/private_key"
+## Seed to generate the server private key, see key_file above.
+## This can be any random string, the recommendation is that it's at least 12
+## characters long.
+## Env variable: LLDAP_KEY_SEED
+#key_seed = "RanD0m STR1ng"
+## Ignored attributes.
+## Some services will request attributes that are not present in LLDAP. When it
+## is the case, LLDAP will warn about the attribute being unknown. If you want
+## to ignore the attribute and the service works without, you can add it to this
+## list to silence the warning.
+#ignored_user_attributes = [ "sAMAccountName" ]
+#ignored_group_attributes = [ "mail", "userPrincipalName" ]
+## Options to configure SMTP parameters, to send password reset emails.
+## To set these options from environment variables, use the following format
+## (example with "password"): LLDAP_SMTP_OPTIONS__PASSWORD
+[smtp_options]
+## Whether to enabled password reset via email, from LLDAP.
+#enable_password_reset=true
+## The SMTP server.
+#server="smtp.gmail.com"
+## The SMTP port.
+#port=587
+## How the connection is encrypted, either "NONE" (no encryption), "TLS" or "STARTTLS".
+#smtp_encryption = "TLS"
+## The SMTP user, usually your email address.
+#user="sender@gmail.com"
+## The SMTP password.
+#password="password"
+## The header field, optional: how the sender appears in the email. The first
+## is a free-form name, followed by an email between <>.
+#from="LLDAP Admin <sender@gmail.com>"
+## Same for reply-to, optional.
+#reply_to="Do not reply <noreply@localhost>"
+## Options to configure LDAPS.
+## To set these options from environment variables, use the following format
+## (example with "port"): LLDAP_LDAPS_OPTIONS__PORT
+[ldaps_options]
+## Whether to enable LDAPS.
+#enabled=true
+## Port on which to listen.
+#port=6360
+## Certificate file.
+#cert_file="/data/cert.pem"
+## Certificate key file.
+#key_file="/data/key.pem"
`,4)]))}const A=a(t,[["render",l]]);export{c as __pageData,A as default}; diff --git a/.vitepress/dist/assets/configuration_swag-config.md.DsoCqRQq.js b/.vitepress/dist/assets/configuration_swag-config.md.DsoCqRQq.js new file mode 100644 index 0000000..06ece2f --- /dev/null +++ b/.vitepress/dist/assets/configuration_swag-config.md.DsoCqRQq.js @@ -0,0 +1 @@ +import{_ as o,c as a,a3 as i,o as t}from"./chunks/framework.DtMx7FFi.js";const f=JSON.parse('{"title":"Swag Config","description":"","frontmatter":{"title":"Swag Config"},"headers":[],"relativePath":"configuration/swag-config.md","filePath":"configuration/swag-config.md"}'),s={name:"configuration/swag-config.md"};function n(l,e,r,c,p,d){return t(),a("div",null,e[0]||(e[0]=[i('

SWAG Configuration ​

Configuring the Secure Web Application Gateway has a lot of options and potential. It is primarily used to have one gateway for all your services hosted through two ports. Assuming you've used the Docker Compose file, you should be able to view and edit all the configuration files through /home/[USER]/appdata/swag. This location now has multiple places you can go.

  1. /home/[USER]/appdata/swag/nginx - This holds all of the webserver configuration files, this is where you will go when adding a new application/service.
    • /home/[USER]/appdata/swag/nginx/proxy-confs - This is where all the reverse proxy magic happens, and will likely be the most used folder.
    • /home/[USER]/appdata/swag/nginx/site-confs - If you want to host a static site using SWAG, this is the conf file that you will modify to make it function.

TIP

Highly recommend learning how NGINX conf files work.

  • The files in this nginx directory are all usually not touched, but used for the rest of configuration to connect Authelia to SWAG for logins.
  1. /home/[USER]/appdata/swag/etc/letsencrypt - This holds all the relevant data for your SSL certificates using Let's Encrypt . The current certificates are in the "live" folder, under the domain name folder.
  2. /home/[USER]/appdata/swag/dns-conf - This holds the API keys or access information in order for SWAG to setup Let's Encrypt certificates or other DNS information. There are many providers available, however, Cloudflare will most likely be used. In order for a SSL Certificate to be issued, you will have to set this up.
  3. /home/[USER]/appdata/swag/www - This folder holds all of the static site stuff, if you decide to make a static site, you can host it through SWAG's configurations. This does take some patience, as getting the stuff exactly right is a bit tricky.

See How do I add a new application to my stack? for more information as to how to use the SWAG proxy-confs folder to add a new application to your hosting repertoire.

',7)]))}const u=o(s,[["render",n]]);export{f as __pageData,u as default}; diff --git a/.vitepress/dist/assets/configuration_swag-config.md.DsoCqRQq.lean.js b/.vitepress/dist/assets/configuration_swag-config.md.DsoCqRQq.lean.js new file mode 100644 index 0000000..06ece2f --- /dev/null +++ b/.vitepress/dist/assets/configuration_swag-config.md.DsoCqRQq.lean.js @@ -0,0 +1 @@ +import{_ as o,c as a,a3 as i,o as t}from"./chunks/framework.DtMx7FFi.js";const f=JSON.parse('{"title":"Swag Config","description":"","frontmatter":{"title":"Swag Config"},"headers":[],"relativePath":"configuration/swag-config.md","filePath":"configuration/swag-config.md"}'),s={name:"configuration/swag-config.md"};function n(l,e,r,c,p,d){return t(),a("div",null,e[0]||(e[0]=[i('

SWAG Configuration ​

Configuring the Secure Web Application Gateway has a lot of options and potential. It is primarily used to have one gateway for all your services hosted through two ports. Assuming you've used the Docker Compose file, you should be able to view and edit all the configuration files through /home/[USER]/appdata/swag. This location now has multiple places you can go.

  1. /home/[USER]/appdata/swag/nginx - This holds all of the webserver configuration files, this is where you will go when adding a new application/service.
    • /home/[USER]/appdata/swag/nginx/proxy-confs - This is where all the reverse proxy magic happens, and will likely be the most used folder.
    • /home/[USER]/appdata/swag/nginx/site-confs - If you want to host a static site using SWAG, this is the conf file that you will modify to make it function.

TIP

Highly recommend learning how NGINX conf files work.

  • The files in this nginx directory are all usually not touched, but used for the rest of configuration to connect Authelia to SWAG for logins.
  1. /home/[USER]/appdata/swag/etc/letsencrypt - This holds all the relevant data for your SSL certificates using Let's Encrypt . The current certificates are in the "live" folder, under the domain name folder.
  2. /home/[USER]/appdata/swag/dns-conf - This holds the API keys or access information in order for SWAG to setup Let's Encrypt certificates or other DNS information. There are many providers available, however, Cloudflare will most likely be used. In order for a SSL Certificate to be issued, you will have to set this up.
  3. /home/[USER]/appdata/swag/www - This folder holds all of the static site stuff, if you decide to make a static site, you can host it through SWAG's configurations. This does take some patience, as getting the stuff exactly right is a bit tricky.

See How do I add a new application to my stack? for more information as to how to use the SWAG proxy-confs folder to add a new application to your hosting repertoire.

',7)]))}const u=o(s,[["render",n]]);export{f as __pageData,u as default}; diff --git a/.vitepress/dist/assets/docker-compose.md.CiAGvlkZ.js b/.vitepress/dist/assets/docker-compose.md.CiAGvlkZ.js new file mode 100644 index 0000000..44bd70e --- /dev/null +++ b/.vitepress/dist/assets/docker-compose.md.CiAGvlkZ.js @@ -0,0 +1,95 @@ +import{_ as i,c as a,a3 as n,o as l}from"./chunks/framework.DtMx7FFi.js";const g=JSON.parse('{"title":"One File Docker Compose (One File to Rule them all!)","description":"","frontmatter":{"title":"One File Docker Compose (One File to Rule them all!)","sidebar":false},"headers":[],"relativePath":"docker-compose.md","filePath":"docker-compose.md"}'),h={name:"docker-compose.md"};function p(k,s,t,e,E,r){return l(),a("div",null,s[0]||(s[0]=[n(`

One File Docker Compose (One File to Rule them all!) ​

This is the Docker Compose file used for the VM Template, and can be used as a custom template in Portainer. The custom network listed under "Networks" is used for all the applications that you want to connect through the stack. Please replace the ALL_CAPS_PORTIONS and the pieces in square brackets. These are values that you will want to set yourself.

TIP

For things like passwords and such, I'd recommend a 26 character random string, using alphanumeric characters in both upper and lower case. These values are crucial that they remain both secret and lengthy.

These values are crucial that they remain both secret and lengthy. You should not need to change these, and some of them will break the application if you try to change them. I'd recommend that you backup your compose file to the cloud in case you need to redo the setup.

yml
version: "2.1"
+services:
+  swag:
+    image: lscr.io/linuxserver/swag:latest
+    container_name: swag
+    cap_add:
+      - NET_ADMIN
+    environment:
+      - PUID=1000
+      - PGID=1000
+      - TZ=America/Phoenix
+      - URL=[sakura.nt]
+      - VALIDATION=dns
+      - SUBDOMAINS=wildcard
+      - DNSPLUGIN=cloudflare
+      - EMAIL=[sakurant@gmail.com]
+      - ONLY_SUBDOMAINS=false
+      #- EXTRA_DOMAINS= #optional
+      - STAGING=false
+      - DOCKER_MODS=linuxserver/mods:universal-docker|linuxserver/mods:swag-auto-reload|linuxserver/mods:swag-dashboard|linuxserver/mods:swag-dbip
+    volumes:
+      - /home/[INSERT USER FOLDER HERE]/appdata/swag:/config
+    ports:
+      - 443:443
+      - 80:80
+    networks:
+      - [INSERT NETWORK NAME HERE]
+    restart: unless-stopped
+
+  authelia:
+    container_name: authelia
+    image: authelia/authelia:latest
+    expose:
+      - 9091
+    volumes:
+      - /home/[INSERT USER FOLDER HERE]/appdata/authelia:/config
+    networks:
+      - [INSERT NETWORK NAME HERE]
+    restart: unless-stopped
+    depends_on:
+      - redis
+      - mariadb
+
+  lldap:
+    container_name: lldap
+    image: lldap/lldap:stable
+    ports:
+      # For LDAP
+      - "3890:3890"
+      # For the web front-end
+      - "17170:17170"
+    volumes:
+      - /home/[INSERT USER FOLDER HERE]/appdata/lldap:/data
+    networks:
+      - [INSERT NETWORK NAME HERE]
+    environment:
+      - TZ=America/Phoenix
+      - LLDAP_JWT_SECRET=REPLACE_WITH_RANDOM
+      - LLDAP_LDAP_USER_PASS=REPLACE_WITH_PASSWORD
+      - LLDAP_LDAP_BASE_DN=dc=sakura,dc=nt
+
+  redis:
+    container_name: redis
+    image: bitnami/redis:latest
+    expose:
+      - 6379
+    volumes:
+      - /home/[INSERT USER FOLDER HERE]/appdata/redis:/bitnami/
+    environment:
+      REDIS_PASSWORD: "YOUR_REDIS_PASSWORD"
+    networks:
+      - [INSERT NETWORK NAME HERE]
+    restart: unless-stopped
+
+  mariadb:
+    container_name: mysql
+    image: linuxserver/mariadb:latest
+    expose:
+      - 3306
+    volumes:
+      - /home/[INSERT USER FOLDER HERE]/appdata/mariadb:/config
+    environment:
+      MYSQL_ROOT_PASSWORD: "YOUR_MYSQL_ROOT_PASSWORD"
+      MYSQL_ROOT_USER: root
+      MYSQL_DATABASE: authelia
+      MYSQL_USER: authelia
+      MYSQL_PASSWORD: "YOUR_MYSQL_USER_PASSWORD"
+    networks:
+      - [INSERT NETWORK NAME HERE]
+    restart: unless-stopped
+
+networks:
+  [INSERT NETWORK NAME HERE]:
+    driver: bridge
+    external: true
`,5)]))}const y=i(h,[["render",p]]);export{g as __pageData,y as default}; diff --git a/.vitepress/dist/assets/docker-compose.md.CiAGvlkZ.lean.js b/.vitepress/dist/assets/docker-compose.md.CiAGvlkZ.lean.js new file mode 100644 index 0000000..44bd70e --- /dev/null +++ b/.vitepress/dist/assets/docker-compose.md.CiAGvlkZ.lean.js @@ -0,0 +1,95 @@ +import{_ as i,c as a,a3 as n,o as l}from"./chunks/framework.DtMx7FFi.js";const g=JSON.parse('{"title":"One File Docker Compose (One File to Rule them all!)","description":"","frontmatter":{"title":"One File Docker Compose (One File to Rule them all!)","sidebar":false},"headers":[],"relativePath":"docker-compose.md","filePath":"docker-compose.md"}'),h={name:"docker-compose.md"};function p(k,s,t,e,E,r){return l(),a("div",null,s[0]||(s[0]=[n(`

One File Docker Compose (One File to Rule them all!) ​

This is the Docker Compose file used for the VM Template, and can be used as a custom template in Portainer. The custom network listed under "Networks" is used for all the applications that you want to connect through the stack. Please replace the ALL_CAPS_PORTIONS and the pieces in square brackets. These are values that you will want to set yourself.

TIP

For things like passwords and such, I'd recommend a 26 character random string, using alphanumeric characters in both upper and lower case. These values are crucial that they remain both secret and lengthy.

These values are crucial that they remain both secret and lengthy. You should not need to change these, and some of them will break the application if you try to change them. I'd recommend that you backup your compose file to the cloud in case you need to redo the setup.

yml
version: "2.1"
+services:
+  swag:
+    image: lscr.io/linuxserver/swag:latest
+    container_name: swag
+    cap_add:
+      - NET_ADMIN
+    environment:
+      - PUID=1000
+      - PGID=1000
+      - TZ=America/Phoenix
+      - URL=[sakura.nt]
+      - VALIDATION=dns
+      - SUBDOMAINS=wildcard
+      - DNSPLUGIN=cloudflare
+      - EMAIL=[sakurant@gmail.com]
+      - ONLY_SUBDOMAINS=false
+      #- EXTRA_DOMAINS= #optional
+      - STAGING=false
+      - DOCKER_MODS=linuxserver/mods:universal-docker|linuxserver/mods:swag-auto-reload|linuxserver/mods:swag-dashboard|linuxserver/mods:swag-dbip
+    volumes:
+      - /home/[INSERT USER FOLDER HERE]/appdata/swag:/config
+    ports:
+      - 443:443
+      - 80:80
+    networks:
+      - [INSERT NETWORK NAME HERE]
+    restart: unless-stopped
+
+  authelia:
+    container_name: authelia
+    image: authelia/authelia:latest
+    expose:
+      - 9091
+    volumes:
+      - /home/[INSERT USER FOLDER HERE]/appdata/authelia:/config
+    networks:
+      - [INSERT NETWORK NAME HERE]
+    restart: unless-stopped
+    depends_on:
+      - redis
+      - mariadb
+
+  lldap:
+    container_name: lldap
+    image: lldap/lldap:stable
+    ports:
+      # For LDAP
+      - "3890:3890"
+      # For the web front-end
+      - "17170:17170"
+    volumes:
+      - /home/[INSERT USER FOLDER HERE]/appdata/lldap:/data
+    networks:
+      - [INSERT NETWORK NAME HERE]
+    environment:
+      - TZ=America/Phoenix
+      - LLDAP_JWT_SECRET=REPLACE_WITH_RANDOM
+      - LLDAP_LDAP_USER_PASS=REPLACE_WITH_PASSWORD
+      - LLDAP_LDAP_BASE_DN=dc=sakura,dc=nt
+
+  redis:
+    container_name: redis
+    image: bitnami/redis:latest
+    expose:
+      - 6379
+    volumes:
+      - /home/[INSERT USER FOLDER HERE]/appdata/redis:/bitnami/
+    environment:
+      REDIS_PASSWORD: "YOUR_REDIS_PASSWORD"
+    networks:
+      - [INSERT NETWORK NAME HERE]
+    restart: unless-stopped
+
+  mariadb:
+    container_name: mysql
+    image: linuxserver/mariadb:latest
+    expose:
+      - 3306
+    volumes:
+      - /home/[INSERT USER FOLDER HERE]/appdata/mariadb:/config
+    environment:
+      MYSQL_ROOT_PASSWORD: "YOUR_MYSQL_ROOT_PASSWORD"
+      MYSQL_ROOT_USER: root
+      MYSQL_DATABASE: authelia
+      MYSQL_USER: authelia
+      MYSQL_PASSWORD: "YOUR_MYSQL_USER_PASSWORD"
+    networks:
+      - [INSERT NETWORK NAME HERE]
+    restart: unless-stopped
+
+networks:
+  [INSERT NETWORK NAME HERE]:
+    driver: bridge
+    external: true
`,5)]))}const y=i(h,[["render",p]]);export{g as __pageData,y as default}; diff --git a/.vitepress/dist/assets/faq.md.By3ovNs1.js b/.vitepress/dist/assets/faq.md.By3ovNs1.js new file mode 100644 index 0000000..f248eaa --- /dev/null +++ b/.vitepress/dist/assets/faq.md.By3ovNs1.js @@ -0,0 +1,49 @@ +import{_ as a,c as e,a3 as i,o as t}from"./chunks/framework.DtMx7FFi.js";const u=JSON.parse('{"title":"FAQ","description":"","frontmatter":{"title":"FAQ"},"headers":[],"relativePath":"faq.md","filePath":"faq.md"}'),n={name:"faq.md"};function l(o,s,p,h,r,d){return t(),e("div",null,s[0]||(s[0]=[i(`

Frequently Asked Questions ​

How do I [Insert Question Here]? ​

Quick Q&A for common problems/questions about the DP-SALA/D Stack

How do I add a new application to my stack? ​

You have two options:

  1. You can check SWAG's proxy confs folder for the application you are trying to add in it's configuration folder.

    • You will use the following command: mv /home/[USER]/appdata/swag/nginx/proxy-confs/[application].sub[domain/folder].conf.sample /home/[USER]/appdata/swag/nginx/proxy-confs/[application].sub[domain/folder].conf
    • Install the application into your docker network (keep track of the internal port that it uses)
    • Then nano into the .conf nano /home/[USER]/appdata/swag/nginx/proxy-confs/[application].sub[domain/folder].conf
    1. If you are using a subdomain configuration:
      • You can change the server_name directive to the path you want to use as a subdomain (make sure you leave the .*)
      • The $upstream_app should match the docker container name
      • The $upstream_port should match the docker internal port
      • Everything else can be left unchanged
    2. If you are using a subfolder configuration:
      • The $location directive can be changed after the / to the path you want to use as a subfolder (make sure to leave the ^~)
      • The $upstream_app should match the docker container name
      • The $upstream_port should match the docker internal port

TIP

If you have the auto-reload docker mod, SWAG will automatically reload the changes, and display them. Otherwise, SWAG will have to be manually reloaded to see the changes.

  1. If there isn't a premade template, you can DIY your own using the _template.sub[domain/folder].conf.sample.
  • You will use the following command: cp /home/[USER]/appdata/swag/nginx/proxy-confs/_template.sub[domain/folder].conf.sample /home/[USER]/appdata/swag/nginx/proxy-confs/[application].sub[domain/folder].conf

  • Install the application into your docker network (keep track of the internal port that it uses)

  • Then nano into the .conf nano /home/[USER]/appdata/swag/nginx/proxy-confs/[application].sub[domain/folder].conf

    1. If you are using a subdomain template:
      • You'll want to modify anything with <> make sure to remove the <> when you are done.
    2. If you are using a subfolder template:
      • You'll want to modify anything with <> make sure to remove the <> when you are done.
  • Which ever way you decide to do, once you have made the changes, save and exit.

THIS IS IMPORTANT!!!

You'll want to verify that the $upstream_app, $port and $protocal are correct, otherwise you will keep getting 502 errors when trying to visit them. The web path/container_name doesn't really matter, you can name it whatever.

TIP

Most of the time, the template will work out-of-the-box with all of the changes. However, you may run into an application that requrires more configuration to run behind a reverse proxy. You will have to consult the application's documentation to find settings that will let it run behind a reverse proxy. SWAG uses NGINX as it's base, so most NGINX configurations can be used to have it run behind a reverse proxy.

WARNING

If you decide to proxy something externally to docker, this comes with the caveat that the $upstream_app must be an IP address (preferably static), and the $upstream_port must be an external port that the application is listening on. Failing to do so, will result in a 502 Bad Gateway error.

How do I add LLDAP Authentication to [SERVICE]? ​

First, check to see if LDAP authentication is supported by the application that you are trying to add. Some services/applications either don't support LDAP auth out of the box, or there is some plugin/addon to add for LDAP auth to function. Do a quick Google search to see if LDAP auth is supported, and if it requires a secure connection. Canvas in particular requires LDAPS (LDAP over SSL) and will not function unless configured correctly.

Second, if the app supports LDAP Auth, it usually requires a dedicated user to manage the application, usually called a "Bind User" which you will setup in LLDAP. Try to pick a username that will be descriptive for the service it will bind to. The password that is used should be lengthy and mixtures of characters. The next required parts are the "configuration" parts, which are detailed below:

  • User DN/Bind User/User: "cn=[USER],ou=people,dc=[DOMAIN],dc=[TLD]"
  • Base/User Search Base: "ou=people,dc=[DOMAIN],dc=[TLD]"
  • User Filter(no grouping, UID access): (&(uid={username})(objectClass=person)(ou=people,dc=[DOMAIN],dc=[TLD]))
  • User Filter(group access, UID or Email access): (&(objectClass=person)(memberof=cn=[GROUP NAME],ou=groups,dc=[DOMAIN],dc=[TLD])(|(uid={username})(mail={username})))
  • User Filter(group access, UID access): (&(objectClass=person)(memberof=cn=[GROUP NAME],ou=groups,dc=[DOMAIN],dc=[TLD]))
  • Admin Filter(group access): (memberof=cn=[GROUP NAME]_administrator,ou=groups,dc=[DOMAIN],dc=[TLD])

These are some typical settings, however, depending on the service or app, there may be an example configuration out there, for example, Authelia for LLDAP has an example config: https://github.com/lldap/lldap/blob/main/example_configs/authelia_config.yml

yml
###############################################################
+#                   Authelia configuration                    #
+###############################################################
+
+# This is just the LDAP part of the Authelia configuration!
+
+
+authentication_backend:
+  # Password reset through authelia works normally.
+  password_reset:
+    disable: false
+  # How often authelia should check if there is an user update in LDAP
+  refresh_interval: 1m
+  ldap:
+    implementation: custom
+    # Pattern is ldap://HOSTNAME-OR-IP:PORT
+    # Normal ldap port is 389, standard in LLDAP is 3890
+    url: ldap://lldap:3890
+    # The dial timeout for LDAP.
+    timeout: 5s
+    # Use StartTLS with the LDAP connection, TLS not supported right now
+    start_tls: false
+    #tls:
+    #  skip_verify: false
+    #  minimum_version: TLS1.2
+    # Set base dn, like dc=google,dc.com
+    base_dn: dc=example,dc=com
+    username_attribute: uid
+    # You need to set this to ou=people, because all users are stored in this ou!
+    additional_users_dn: ou=people
+    # To allow sign in both with username and email, one can use a filter like
+    # (&(|({username_attribute}={input})({mail_attribute}={input}))(objectClass=person))
+    users_filter: "(&({username_attribute}={input})(objectClass=person))"
+    # Set this to ou=groups, because all groups are stored in this ou
+    additional_groups_dn: ou=groups
+    # The groups are not displayed in the UI, but this filter works.
+    groups_filter: "(member={dn})"
+    # The attribute holding the name of the group.
+    group_name_attribute: cn
+    # Email attribute
+    mail_attribute: mail
+    # The attribute holding the display name of the user. This will be used to greet an authenticated user.
+    display_name_attribute: displayName
+    # The username and password of the bind user.
+    # "bind_user" should be the username you created for authentication with the "lldap_strict_readonly" permission. It is not recommended to use an actual admin account here.
+    # If you are configuring Authelia to change user passwords, then the account used here needs the "lldap_password_manager" permission instead.
+    user: uid=bind_user,ou=people,dc=example,dc=com
+    # Password can also be set using a secret: https://www.authelia.com/docs/configuration/secrets.html
+    password: 'REPLACE_ME'

Here is a list of the attributes that you can use: uid (username), mail (email address), cn (this could be a username, or a full name be careful), and displayName (usually the full name of the user).

Not all of these are good for use cases, however, the most commonly used ones are going to be uid and email.

If this didn't cover what was needed for adding LDAP auth connectivity to your service, consult Google, or the LLDAP GitHub Example Configs, linked here: https://github.com/lldap/lldap/tree/main/example_configs which should give you a good starting point to see how to configure the LDAP authentication for your service.

Here is my recommendation to how user management works:

  1. Setup dedicated groups that match the application/service name, add all users who use that to the group.
  2. Filter the user based on the group, if they are in that group, they have permission to access the application.

How do I handle user creation? ​

Once the stack is all setup, you may want to add users . I outline my way of handling user creation and management, but you may do this anyway you like, I've done it this way given the constraints of how I host, and handle having users access some or all of my services that I host.

User Creation:

  1. Ask for the user's email address, full name, and if they would like something different for their display name.
  2. Using their full name, I create a username. Say if the user was named: Alice Example, their username would be aexa. If I already had a duplicate of the username, I'd append a number, starting at 0.
  3. I would create a temporary password for the user, and then have them go to auth.domain.tld to then "Forgot Password" so that they can setup a password themselves, and have it conform to my password standards I have set.
  4. I then go to the user page, and add them to their respective groups to let them have access to the services.
  5. I'd let the user know that some apps will take a bit to pull their information, while some create their profile on sign in. This is completely normal, and give it up to 24 hours for changes to fully propagate through the system.

This is one way of doing it, but I do have a standard, which I hold to the highest degree. This is important, as it does make finding the user just a little easier when trying to figure out what goes wrong.

`,28)]))}const k=a(n,[["render",l]]);export{u as __pageData,k as default}; diff --git a/.vitepress/dist/assets/faq.md.By3ovNs1.lean.js b/.vitepress/dist/assets/faq.md.By3ovNs1.lean.js new file mode 100644 index 0000000..f248eaa --- /dev/null +++ b/.vitepress/dist/assets/faq.md.By3ovNs1.lean.js @@ -0,0 +1,49 @@ +import{_ as a,c as e,a3 as i,o as t}from"./chunks/framework.DtMx7FFi.js";const u=JSON.parse('{"title":"FAQ","description":"","frontmatter":{"title":"FAQ"},"headers":[],"relativePath":"faq.md","filePath":"faq.md"}'),n={name:"faq.md"};function l(o,s,p,h,r,d){return t(),e("div",null,s[0]||(s[0]=[i(`

Frequently Asked Questions ​

How do I [Insert Question Here]? ​

Quick Q&A for common problems/questions about the DP-SALA/D Stack

How do I add a new application to my stack? ​

You have two options:

  1. You can check SWAG's proxy confs folder for the application you are trying to add in it's configuration folder.

    • You will use the following command: mv /home/[USER]/appdata/swag/nginx/proxy-confs/[application].sub[domain/folder].conf.sample /home/[USER]/appdata/swag/nginx/proxy-confs/[application].sub[domain/folder].conf
    • Install the application into your docker network (keep track of the internal port that it uses)
    • Then nano into the .conf nano /home/[USER]/appdata/swag/nginx/proxy-confs/[application].sub[domain/folder].conf
    1. If you are using a subdomain configuration:
      • You can change the server_name directive to the path you want to use as a subdomain (make sure you leave the .*)
      • The $upstream_app should match the docker container name
      • The $upstream_port should match the docker internal port
      • Everything else can be left unchanged
    2. If you are using a subfolder configuration:
      • The $location directive can be changed after the / to the path you want to use as a subfolder (make sure to leave the ^~)
      • The $upstream_app should match the docker container name
      • The $upstream_port should match the docker internal port

TIP

If you have the auto-reload docker mod, SWAG will automatically reload the changes, and display them. Otherwise, SWAG will have to be manually reloaded to see the changes.

  1. If there isn't a premade template, you can DIY your own using the _template.sub[domain/folder].conf.sample.
  • You will use the following command: cp /home/[USER]/appdata/swag/nginx/proxy-confs/_template.sub[domain/folder].conf.sample /home/[USER]/appdata/swag/nginx/proxy-confs/[application].sub[domain/folder].conf

  • Install the application into your docker network (keep track of the internal port that it uses)

  • Then nano into the .conf nano /home/[USER]/appdata/swag/nginx/proxy-confs/[application].sub[domain/folder].conf

    1. If you are using a subdomain template:
      • You'll want to modify anything with <> make sure to remove the <> when you are done.
    2. If you are using a subfolder template:
      • You'll want to modify anything with <> make sure to remove the <> when you are done.
  • Which ever way you decide to do, once you have made the changes, save and exit.

THIS IS IMPORTANT!!!

You'll want to verify that the $upstream_app, $port and $protocal are correct, otherwise you will keep getting 502 errors when trying to visit them. The web path/container_name doesn't really matter, you can name it whatever.

TIP

Most of the time, the template will work out-of-the-box with all of the changes. However, you may run into an application that requrires more configuration to run behind a reverse proxy. You will have to consult the application's documentation to find settings that will let it run behind a reverse proxy. SWAG uses NGINX as it's base, so most NGINX configurations can be used to have it run behind a reverse proxy.

WARNING

If you decide to proxy something externally to docker, this comes with the caveat that the $upstream_app must be an IP address (preferably static), and the $upstream_port must be an external port that the application is listening on. Failing to do so, will result in a 502 Bad Gateway error.

How do I add LLDAP Authentication to [SERVICE]? ​

First, check to see if LDAP authentication is supported by the application that you are trying to add. Some services/applications either don't support LDAP auth out of the box, or there is some plugin/addon to add for LDAP auth to function. Do a quick Google search to see if LDAP auth is supported, and if it requires a secure connection. Canvas in particular requires LDAPS (LDAP over SSL) and will not function unless configured correctly.

Second, if the app supports LDAP Auth, it usually requires a dedicated user to manage the application, usually called a "Bind User" which you will setup in LLDAP. Try to pick a username that will be descriptive for the service it will bind to. The password that is used should be lengthy and mixtures of characters. The next required parts are the "configuration" parts, which are detailed below:

  • User DN/Bind User/User: "cn=[USER],ou=people,dc=[DOMAIN],dc=[TLD]"
  • Base/User Search Base: "ou=people,dc=[DOMAIN],dc=[TLD]"
  • User Filter(no grouping, UID access): (&(uid={username})(objectClass=person)(ou=people,dc=[DOMAIN],dc=[TLD]))
  • User Filter(group access, UID or Email access): (&(objectClass=person)(memberof=cn=[GROUP NAME],ou=groups,dc=[DOMAIN],dc=[TLD])(|(uid={username})(mail={username})))
  • User Filter(group access, UID access): (&(objectClass=person)(memberof=cn=[GROUP NAME],ou=groups,dc=[DOMAIN],dc=[TLD]))
  • Admin Filter(group access): (memberof=cn=[GROUP NAME]_administrator,ou=groups,dc=[DOMAIN],dc=[TLD])

These are some typical settings, however, depending on the service or app, there may be an example configuration out there, for example, Authelia for LLDAP has an example config: https://github.com/lldap/lldap/blob/main/example_configs/authelia_config.yml

yml
###############################################################
+#                   Authelia configuration                    #
+###############################################################
+
+# This is just the LDAP part of the Authelia configuration!
+
+
+authentication_backend:
+  # Password reset through authelia works normally.
+  password_reset:
+    disable: false
+  # How often authelia should check if there is an user update in LDAP
+  refresh_interval: 1m
+  ldap:
+    implementation: custom
+    # Pattern is ldap://HOSTNAME-OR-IP:PORT
+    # Normal ldap port is 389, standard in LLDAP is 3890
+    url: ldap://lldap:3890
+    # The dial timeout for LDAP.
+    timeout: 5s
+    # Use StartTLS with the LDAP connection, TLS not supported right now
+    start_tls: false
+    #tls:
+    #  skip_verify: false
+    #  minimum_version: TLS1.2
+    # Set base dn, like dc=google,dc.com
+    base_dn: dc=example,dc=com
+    username_attribute: uid
+    # You need to set this to ou=people, because all users are stored in this ou!
+    additional_users_dn: ou=people
+    # To allow sign in both with username and email, one can use a filter like
+    # (&(|({username_attribute}={input})({mail_attribute}={input}))(objectClass=person))
+    users_filter: "(&({username_attribute}={input})(objectClass=person))"
+    # Set this to ou=groups, because all groups are stored in this ou
+    additional_groups_dn: ou=groups
+    # The groups are not displayed in the UI, but this filter works.
+    groups_filter: "(member={dn})"
+    # The attribute holding the name of the group.
+    group_name_attribute: cn
+    # Email attribute
+    mail_attribute: mail
+    # The attribute holding the display name of the user. This will be used to greet an authenticated user.
+    display_name_attribute: displayName
+    # The username and password of the bind user.
+    # "bind_user" should be the username you created for authentication with the "lldap_strict_readonly" permission. It is not recommended to use an actual admin account here.
+    # If you are configuring Authelia to change user passwords, then the account used here needs the "lldap_password_manager" permission instead.
+    user: uid=bind_user,ou=people,dc=example,dc=com
+    # Password can also be set using a secret: https://www.authelia.com/docs/configuration/secrets.html
+    password: 'REPLACE_ME'

Here is a list of the attributes that you can use: uid (username), mail (email address), cn (this could be a username, or a full name be careful), and displayName (usually the full name of the user).

Not all of these are good for use cases, however, the most commonly used ones are going to be uid and email.

If this didn't cover what was needed for adding LDAP auth connectivity to your service, consult Google, or the LLDAP GitHub Example Configs, linked here: https://github.com/lldap/lldap/tree/main/example_configs which should give you a good starting point to see how to configure the LDAP authentication for your service.

Here is my recommendation to how user management works:

  1. Setup dedicated groups that match the application/service name, add all users who use that to the group.
  2. Filter the user based on the group, if they are in that group, they have permission to access the application.

How do I handle user creation? ​

Once the stack is all setup, you may want to add users . I outline my way of handling user creation and management, but you may do this anyway you like, I've done it this way given the constraints of how I host, and handle having users access some or all of my services that I host.

User Creation:

  1. Ask for the user's email address, full name, and if they would like something different for their display name.
  2. Using their full name, I create a username. Say if the user was named: Alice Example, their username would be aexa. If I already had a duplicate of the username, I'd append a number, starting at 0.
  3. I would create a temporary password for the user, and then have them go to auth.domain.tld to then "Forgot Password" so that they can setup a password themselves, and have it conform to my password standards I have set.
  4. I then go to the user page, and add them to their respective groups to let them have access to the services.
  5. I'd let the user know that some apps will take a bit to pull their information, while some create their profile on sign in. This is completely normal, and give it up to 24 hours for changes to fully propagate through the system.

This is one way of doing it, but I do have a standard, which I hold to the highest degree. This is important, as it does make finding the user just a little easier when trying to figure out what goes wrong.

`,28)]))}const k=a(n,[["render",l]]);export{u as __pageData,k as default}; diff --git a/.vitepress/dist/assets/home.md.DWjC1jWa.js b/.vitepress/dist/assets/home.md.DWjC1jWa.js new file mode 100644 index 0000000..364eacf --- /dev/null +++ b/.vitepress/dist/assets/home.md.DWjC1jWa.js @@ -0,0 +1 @@ +import{_ as t,c as o,a3 as a,o as s}from"./chunks/framework.DtMx7FFi.js";const u=JSON.parse('{"title":"Legacy Instructions","description":"","frontmatter":{"title":"Legacy Instructions"},"headers":[],"relativePath":"home.md","filePath":"home.md"}'),n={name:"home.md"};function i(r,e,l,c,p,d){return s(),o("div",null,e[0]||(e[0]=[a('

Welcome! ​

This is page to be when looking to deploy the DP-Salad stack! If you need to see if your system fits the DP-Salad stack requirements, you can find the page you're looking for here: DP-Salad Requirements.

Otherwise, down below are the Legacy Instructions for the DP-Salad stack, they do have bad formatting so we do not suggest using them in a public deployment. You can also find the legacy instructions on this website.

The main instructions can be found on the DP-Setup page, and are the instructions you will use to deploy the stack.

Otherwise, feel free to poke about the documentation!

Legacy Instructions: ​

WARNING

Do not use these instructions as they have poor formatting and will lead to a bad stack deployment

PDF instructions for the DP-SALA/D Stack: DP-SALAD_STACK.pdf (Updated 10/11/2023, 12:03PM)

Docker Compose file for the DP-SALA/D Stack: docker-compose-dpsalad.rtf (Updated 10/13/2023, 11:03PM)

TIP

Download the docker compose file, rename to docker-compose.yml for best results.

OVA/VM Template for DP-SALA/D Stack: DP-SALA/D OVA Template

Authelia Example Configuration File: configuration.yml (Updated 10/12/2023, 8:32PM)

TIP

Remove RTF extension before using in actual deployment

LLDAP Example Configuration File: lldap_config.toml (Updated 10/12/2023, 8:38PM)

TIP

Remove RTF extension before using, however, this file is not always needed.

SWAG Example file locations are detailed in the Guidebook to the DP-SALA/D Stack

',16)]))}const f=t(n,[["render",i]]);export{u as __pageData,f as default}; diff --git a/.vitepress/dist/assets/home.md.DWjC1jWa.lean.js b/.vitepress/dist/assets/home.md.DWjC1jWa.lean.js new file mode 100644 index 0000000..364eacf --- /dev/null +++ b/.vitepress/dist/assets/home.md.DWjC1jWa.lean.js @@ -0,0 +1 @@ +import{_ as t,c as o,a3 as a,o as s}from"./chunks/framework.DtMx7FFi.js";const u=JSON.parse('{"title":"Legacy Instructions","description":"","frontmatter":{"title":"Legacy Instructions"},"headers":[],"relativePath":"home.md","filePath":"home.md"}'),n={name:"home.md"};function i(r,e,l,c,p,d){return s(),o("div",null,e[0]||(e[0]=[a('

Welcome! ​

This is page to be when looking to deploy the DP-Salad stack! If you need to see if your system fits the DP-Salad stack requirements, you can find the page you're looking for here: DP-Salad Requirements.

Otherwise, down below are the Legacy Instructions for the DP-Salad stack, they do have bad formatting so we do not suggest using them in a public deployment. You can also find the legacy instructions on this website.

The main instructions can be found on the DP-Setup page, and are the instructions you will use to deploy the stack.

Otherwise, feel free to poke about the documentation!

Legacy Instructions: ​

WARNING

Do not use these instructions as they have poor formatting and will lead to a bad stack deployment

PDF instructions for the DP-SALA/D Stack: DP-SALAD_STACK.pdf (Updated 10/11/2023, 12:03PM)

Docker Compose file for the DP-SALA/D Stack: docker-compose-dpsalad.rtf (Updated 10/13/2023, 11:03PM)

TIP

Download the docker compose file, rename to docker-compose.yml for best results.

OVA/VM Template for DP-SALA/D Stack: DP-SALA/D OVA Template

Authelia Example Configuration File: configuration.yml (Updated 10/12/2023, 8:32PM)

TIP

Remove RTF extension before using in actual deployment

LLDAP Example Configuration File: lldap_config.toml (Updated 10/12/2023, 8:38PM)

TIP

Remove RTF extension before using, however, this file is not always needed.

SWAG Example file locations are detailed in the Guidebook to the DP-SALA/D Stack

',16)]))}const f=t(n,[["render",i]]);export{u as __pageData,f as default}; diff --git a/.vitepress/dist/assets/index.md.DDpI40D1.js b/.vitepress/dist/assets/index.md.DDpI40D1.js new file mode 100644 index 0000000..10e2938 --- /dev/null +++ b/.vitepress/dist/assets/index.md.DDpI40D1.js @@ -0,0 +1 @@ +import{_ as e,c as t,o as a}from"./chunks/framework.DtMx7FFi.js";const m=JSON.parse('{"title":"","description":"","frontmatter":{"layout":"home","hero":{"name":"DP-Salad","text":"A guide created by Cdez","tagline":"A guide to successfully/fully deploy the DP-Salad Stack","image":"./saladicon.png","actions":[{"theme":"brand","text":"Home","link":"/home"},{"theme":"alt","text":"Minimum Requirements","link":"/install/requirements"},{"theme":"alt","text":"FAQ","link":"/faq"}]},"features":[{"title":"Really easy to setup!","details":"Just a couple of simple steps!","icon":"","link":"/install/dp-setup"},{"title":"Comes with a compose file!","details":"ONE FILE TO RULE THEM ALL","icon":"","link":"/docker-compose"},{"title":"Latest Version","details":"1.1.0","icon":"","link":"/changelog"}]},"headers":[],"relativePath":"index.md","filePath":"index.md"}'),i={name:"index.md"};function o(l,s,n,r,h,d){return a(),t("div")}const p=e(i,[["render",o]]);export{m as __pageData,p as default}; diff --git a/.vitepress/dist/assets/index.md.DDpI40D1.lean.js b/.vitepress/dist/assets/index.md.DDpI40D1.lean.js new file mode 100644 index 0000000..10e2938 --- /dev/null +++ b/.vitepress/dist/assets/index.md.DDpI40D1.lean.js @@ -0,0 +1 @@ +import{_ as e,c as t,o as a}from"./chunks/framework.DtMx7FFi.js";const m=JSON.parse('{"title":"","description":"","frontmatter":{"layout":"home","hero":{"name":"DP-Salad","text":"A guide created by Cdez","tagline":"A guide to successfully/fully deploy the DP-Salad Stack","image":"./saladicon.png","actions":[{"theme":"brand","text":"Home","link":"/home"},{"theme":"alt","text":"Minimum Requirements","link":"/install/requirements"},{"theme":"alt","text":"FAQ","link":"/faq"}]},"features":[{"title":"Really easy to setup!","details":"Just a couple of simple steps!","icon":"","link":"/install/dp-setup"},{"title":"Comes with a compose file!","details":"ONE FILE TO RULE THEM ALL","icon":"","link":"/docker-compose"},{"title":"Latest Version","details":"1.1.0","icon":"","link":"/changelog"}]},"headers":[],"relativePath":"index.md","filePath":"index.md"}'),i={name:"index.md"};function o(l,s,n,r,h,d){return a(),t("div")}const p=e(i,[["render",o]]);export{m as __pageData,p as default}; diff --git a/.vitepress/dist/assets/install_dp-config.md.Cllv2ZYA.js b/.vitepress/dist/assets/install_dp-config.md.Cllv2ZYA.js new file mode 100644 index 0000000..3db018c --- /dev/null +++ b/.vitepress/dist/assets/install_dp-config.md.Cllv2ZYA.js @@ -0,0 +1 @@ +import{_ as a,c as t,a3 as s,o as i}from"./chunks/framework.DtMx7FFi.js";const u=JSON.parse('{"title":"DP-Salad Configuration","description":"","frontmatter":{"title":"DP-Salad Configuration"},"headers":[],"relativePath":"install/dp-config.md","filePath":"install/dp-config.md"}'),o={name:"install/dp-config.md"};function n(r,e,l,p,h,d){return i(),t("div",null,e[0]||(e[0]=[s('

Configuration ​

Debian Configuration ​

Sudo should have been setup after the install, however, nothing much else is required for the setup end in Debian. If you want, here is a list of recommended software to install to make the commandline a little easier to learn:

  1. TLDR
sh
sudo apt-get install tldr, tldr -u
  1. Tmux
sh
sudo apt-get install tmux

Portainer Configuration ​

Portainer is ready right out of the box. There should be nothing you need to do to configure it, unless you are running a "clustered setup" involving more than one computer, which can be done for this stack, but does add a layer of complexity, and allows for scalability for the amount of applications you can offer to either yourself or your users. A "clustered setup" is on the Portainer CE wiki and is out of the scope for this guide.

If you are using the VM Template, Portainer has the custom templates loaded so that if you need to install a newer version, or change something and restart, they are there.

App Templates ​

In Portainer, App Templates enable you to easily deploy services with a predetermined configuration, while allowing you to customize options through the web UI. While Portainer ships with some default templates (see portainer/templates), it's often helpful to have 1-click access to many more apps + stacks, without having to constantly switch template sources.

Under Settings → App Templates in your Portainer GUI, paste this URL:

sh
https://raw.githubusercontent.com/Lissy93/portainer-templates/main/templates.json
',14)]))}const g=a(o,[["render",n]]);export{u as __pageData,g as default}; diff --git a/.vitepress/dist/assets/install_dp-config.md.Cllv2ZYA.lean.js b/.vitepress/dist/assets/install_dp-config.md.Cllv2ZYA.lean.js new file mode 100644 index 0000000..3db018c --- /dev/null +++ b/.vitepress/dist/assets/install_dp-config.md.Cllv2ZYA.lean.js @@ -0,0 +1 @@ +import{_ as a,c as t,a3 as s,o as i}from"./chunks/framework.DtMx7FFi.js";const u=JSON.parse('{"title":"DP-Salad Configuration","description":"","frontmatter":{"title":"DP-Salad Configuration"},"headers":[],"relativePath":"install/dp-config.md","filePath":"install/dp-config.md"}'),o={name:"install/dp-config.md"};function n(r,e,l,p,h,d){return i(),t("div",null,e[0]||(e[0]=[s('

Configuration ​

Debian Configuration ​

Sudo should have been setup after the install, however, nothing much else is required for the setup end in Debian. If you want, here is a list of recommended software to install to make the commandline a little easier to learn:

  1. TLDR
sh
sudo apt-get install tldr, tldr -u
  1. Tmux
sh
sudo apt-get install tmux

Portainer Configuration ​

Portainer is ready right out of the box. There should be nothing you need to do to configure it, unless you are running a "clustered setup" involving more than one computer, which can be done for this stack, but does add a layer of complexity, and allows for scalability for the amount of applications you can offer to either yourself or your users. A "clustered setup" is on the Portainer CE wiki and is out of the scope for this guide.

If you are using the VM Template, Portainer has the custom templates loaded so that if you need to install a newer version, or change something and restart, they are there.

App Templates ​

In Portainer, App Templates enable you to easily deploy services with a predetermined configuration, while allowing you to customize options through the web UI. While Portainer ships with some default templates (see portainer/templates), it's often helpful to have 1-click access to many more apps + stacks, without having to constantly switch template sources.

Under Settings → App Templates in your Portainer GUI, paste this URL:

sh
https://raw.githubusercontent.com/Lissy93/portainer-templates/main/templates.json
',14)]))}const g=a(o,[["render",n]]);export{u as __pageData,g as default}; diff --git a/.vitepress/dist/assets/install_dp-setup.md.Bx00pjFf.js b/.vitepress/dist/assets/install_dp-setup.md.Bx00pjFf.js new file mode 100644 index 0000000..3ecf263 --- /dev/null +++ b/.vitepress/dist/assets/install_dp-setup.md.Bx00pjFf.js @@ -0,0 +1,12 @@ +import{_ as i,c as a,a3 as e,o as t}from"./chunks/framework.DtMx7FFi.js";const c=JSON.parse('{"title":"DP-Salad Setup","description":"","frontmatter":{"title":"DP-Salad Setup"},"headers":[],"relativePath":"install/dp-setup.md","filePath":"install/dp-setup.md"}'),n={name:"install/dp-setup.md"};function l(h,s,p,o,d,r){return t(),a("div",null,s[0]||(s[0]=[e(`

DP-Setup ​

This guide demonstrates the installing of the DP-Salad stack:

Debian 12 Setup ​

Visit Debian's download page to get the latest version of Debian, as of this writing, Debian 12.5.0 is the latest. This is a netinst, meaning that it will require an internet connection to download the OS files.

Load your Debian ISO onto a USB stick, either directly, or using Rufus/Balena Etcher to write the ISO to stick.

Plug it into whatever is becoming your server, and boot to the USB stick in your system's BIOS.

Install Debian using the ISO. Make sure that you are connected to the internet before trying to install Debian.

  1. Select Graphical Installer
  2. Follow the setup process up until hostname, and put in something that you will recognize when port-forwarding or tunneling.
  3. Put in the domain name that you have leased as your domain name, like: "example.com"
  4. Setup a root password. (Template uses DPSALADSTACK)
  5. Setup the name for the first non-admin user. (Template uses dpsalad)
  6. Setup a password for the non-admin user. (Template uses DPSALADSTACKUSER)
  7. Continue the setup, and select "Guided - use entire disk" when Partitioning Disk, continue and use "All files in one partition" as the partitioning scheme.
  8. Allow changes to be written to disk.
  9. Continue with the installer until Software Selection. See the following points for the selections.
    • Debian desktop environment (keep selected)
    • GNOME (deselect)
    • xfce (select)
    • SSH server (select)
    • standard system utilities (keep selected)
  10. Continue with the installer until the reboot.
  11. Once the reboot is complete, you should have a fully working Debian system!
  12. If you used the template, please change the password of both the root and regular user using passwd.

Sudo no worky ​

Debian had you set up a root password, but when you try using sudo, it will not let you do anything. Debian by default does not let the first user have sudo access. See why here: Reason. You will have to temporarily log in as root to fix this. Use the following commands/instructions to add your user to the sudoers file.

markdown
1. su -
+2. nano /etc/sudoers
+3. Add the following to the file(no quotes): "username ALL=(ALL:ALL) ALL"
+4. Exit nano using Ctrl+X and then type 'Y' and enter.
+5. Restart your PC.
+6. systemctl reboot

Once your machine restarts, you should now be able to use the sudo command.

Disabling GUI ​

If you'd like to disable the GUI and work in CLI only (highly recommended, as GUI uses more resources), follow these instructions:

markdown
1. sudo systemctl set-default multi-user.target
+2. sudo reboot

Updating your system ​

Now time to run updates, just to guarantee the system is up-to-date. Debian uses APT as it's package manager of choice. Run these commands:

markdown
1. sudo apt-get update
+2. sudo apt-get upgrade

And now, your system is up-to-date!

Installing the Docker ​

Next, install Docker. Follow the following instructions to install Docker:

sh
sudo apt-get update
sh
sudo apt-get install ca-certificates curl gnupg
sh
sudo install -m 755 -d /etc/apt/keyrings
sh
curl -fsSL https://download.docker.com/linux/debian/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sh
sudo chmod a+r /etc/apt/keyrings/docker.gpg
sh
echo \\
+  "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/debian \\
+  $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \\
+  sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sh
sudo apt-get update
sh
sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin dockercompose-plugin

Once this is done, you are able to move on to the next section of this guide

DANGER

If you use anything other than the netinst for Debian, your apt sources may be invalid. Should this be the case, there is an example of the sources needed in /usr/share/doc/apt/examples/sources.list. Use the following command to copy this list of default sources to restore apt to working order. sudo cp /usr/share/doc/apt/examples/sources.list /etc/apt/sources.list

Portainer CE Setup ​

Time to setup Portainer, which is installed using Docker. Follow the below instructions to install Portainer onto your machine.

sh
sudo docker volume create portainer_data
sh
sudo docker run -d -p 8000:8000 -p 9443:9443 --name portainer --restart=always -v /var/run/docker.sock:/var/run/docker.sock -v portainer_data:/data portainer/portainer-ce:latest
  • Visit https://[ip-address]:9443 to log into Portainer CE.

  • Change the admin username if you wish. (Don't forget it if you change it though!) [Template uses DPSALADSTACK]

  • Use a good secure password (12+ characters) for the administrator password. (Don't forget this either!)

  • Click "Getting Started" to finish setting up Portainer CE.

  • If you are going to use the one-click Compose Install, make sure to create a network using the following command:

sh
sudo docker network create [INSERT NETWORK NAME HERE]

TIP

Make sure to remove the square brackets around the network name.

Some changes need to be made ​

Do note that some changes need to be made before the stack installation is finished. These two commands need to be ran to make sure Redis can be deployed for the stack to function correctly.

sh
mkdir -p /home/[USER]/appdata/redis/redis/ 
+mkdir -p /home/[USER]/appdata/redis/redis/data/

That's it! You have successfully installed Debian and Portainer!

`,42)]))}const g=i(n,[["render",l]]);export{c as __pageData,g as default}; diff --git a/.vitepress/dist/assets/install_dp-setup.md.Bx00pjFf.lean.js b/.vitepress/dist/assets/install_dp-setup.md.Bx00pjFf.lean.js new file mode 100644 index 0000000..3ecf263 --- /dev/null +++ b/.vitepress/dist/assets/install_dp-setup.md.Bx00pjFf.lean.js @@ -0,0 +1,12 @@ +import{_ as i,c as a,a3 as e,o as t}from"./chunks/framework.DtMx7FFi.js";const c=JSON.parse('{"title":"DP-Salad Setup","description":"","frontmatter":{"title":"DP-Salad Setup"},"headers":[],"relativePath":"install/dp-setup.md","filePath":"install/dp-setup.md"}'),n={name:"install/dp-setup.md"};function l(h,s,p,o,d,r){return t(),a("div",null,s[0]||(s[0]=[e(`

DP-Setup ​

This guide demonstrates the installing of the DP-Salad stack:

Debian 12 Setup ​

Visit Debian's download page to get the latest version of Debian, as of this writing, Debian 12.5.0 is the latest. This is a netinst, meaning that it will require an internet connection to download the OS files.

Load your Debian ISO onto a USB stick, either directly, or using Rufus/Balena Etcher to write the ISO to stick.

Plug it into whatever is becoming your server, and boot to the USB stick in your system's BIOS.

Install Debian using the ISO. Make sure that you are connected to the internet before trying to install Debian.

  1. Select Graphical Installer
  2. Follow the setup process up until hostname, and put in something that you will recognize when port-forwarding or tunneling.
  3. Put in the domain name that you have leased as your domain name, like: "example.com"
  4. Setup a root password. (Template uses DPSALADSTACK)
  5. Setup the name for the first non-admin user. (Template uses dpsalad)
  6. Setup a password for the non-admin user. (Template uses DPSALADSTACKUSER)
  7. Continue the setup, and select "Guided - use entire disk" when Partitioning Disk, continue and use "All files in one partition" as the partitioning scheme.
  8. Allow changes to be written to disk.
  9. Continue with the installer until Software Selection. See the following points for the selections.
    • Debian desktop environment (keep selected)
    • GNOME (deselect)
    • xfce (select)
    • SSH server (select)
    • standard system utilities (keep selected)
  10. Continue with the installer until the reboot.
  11. Once the reboot is complete, you should have a fully working Debian system!
  12. If you used the template, please change the password of both the root and regular user using passwd.

Sudo no worky ​

Debian had you set up a root password, but when you try using sudo, it will not let you do anything. Debian by default does not let the first user have sudo access. See why here: Reason. You will have to temporarily log in as root to fix this. Use the following commands/instructions to add your user to the sudoers file.

markdown
1. su -
+2. nano /etc/sudoers
+3. Add the following to the file(no quotes): "username ALL=(ALL:ALL) ALL"
+4. Exit nano using Ctrl+X and then type 'Y' and enter.
+5. Restart your PC.
+6. systemctl reboot

Once your machine restarts, you should now be able to use the sudo command.

Disabling GUI ​

If you'd like to disable the GUI and work in CLI only (highly recommended, as GUI uses more resources), follow these instructions:

markdown
1. sudo systemctl set-default multi-user.target
+2. sudo reboot

Updating your system ​

Now time to run updates, just to guarantee the system is up-to-date. Debian uses APT as it's package manager of choice. Run these commands:

markdown
1. sudo apt-get update
+2. sudo apt-get upgrade

And now, your system is up-to-date!

Installing the Docker ​

Next, install Docker. Follow the following instructions to install Docker:

sh
sudo apt-get update
sh
sudo apt-get install ca-certificates curl gnupg
sh
sudo install -m 755 -d /etc/apt/keyrings
sh
curl -fsSL https://download.docker.com/linux/debian/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sh
sudo chmod a+r /etc/apt/keyrings/docker.gpg
sh
echo \\
+  "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/debian \\
+  $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \\
+  sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sh
sudo apt-get update
sh
sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin dockercompose-plugin

Once this is done, you are able to move on to the next section of this guide

DANGER

If you use anything other than the netinst for Debian, your apt sources may be invalid. Should this be the case, there is an example of the sources needed in /usr/share/doc/apt/examples/sources.list. Use the following command to copy this list of default sources to restore apt to working order. sudo cp /usr/share/doc/apt/examples/sources.list /etc/apt/sources.list

Portainer CE Setup ​

Time to setup Portainer, which is installed using Docker. Follow the below instructions to install Portainer onto your machine.

sh
sudo docker volume create portainer_data
sh
sudo docker run -d -p 8000:8000 -p 9443:9443 --name portainer --restart=always -v /var/run/docker.sock:/var/run/docker.sock -v portainer_data:/data portainer/portainer-ce:latest
  • Visit https://[ip-address]:9443 to log into Portainer CE.

  • Change the admin username if you wish. (Don't forget it if you change it though!) [Template uses DPSALADSTACK]

  • Use a good secure password (12+ characters) for the administrator password. (Don't forget this either!)

  • Click "Getting Started" to finish setting up Portainer CE.

  • If you are going to use the one-click Compose Install, make sure to create a network using the following command:

sh
sudo docker network create [INSERT NETWORK NAME HERE]

TIP

Make sure to remove the square brackets around the network name.

Some changes need to be made ​

Do note that some changes need to be made before the stack installation is finished. These two commands need to be ran to make sure Redis can be deployed for the stack to function correctly.

sh
mkdir -p /home/[USER]/appdata/redis/redis/ 
+mkdir -p /home/[USER]/appdata/redis/redis/data/

That's it! You have successfully installed Debian and Portainer!

`,42)]))}const g=i(n,[["render",l]]);export{c as __pageData,g as default}; diff --git a/.vitepress/dist/assets/install_requirements.md.DnNTxVlB.js b/.vitepress/dist/assets/install_requirements.md.DnNTxVlB.js new file mode 100644 index 0000000..37d2e98 --- /dev/null +++ b/.vitepress/dist/assets/install_requirements.md.DnNTxVlB.js @@ -0,0 +1 @@ +import{_ as e,c as s,a3 as i,o}from"./chunks/framework.DtMx7FFi.js";const c=JSON.parse('{"title":"DP-Salad Minimum Requirements","description":"","frontmatter":{"title":"DP-Salad Minimum Requirements"},"headers":[],"relativePath":"install/requirements.md","filePath":"install/requirements.md"}'),t={name:"install/requirements.md"};function r(l,a,n,u,h,m){return o(),s("div",null,a[0]||(a[0]=[i('

DP-SALA/D Stack (pronounced as DP-Salad but stylized as DP-SALA/D) ​

Where does the acronym originate from? ​

It comes from:

  • Debian 12
  • Portainer
  • SWAG
  • Authelia
  • LLDAP
  • Authy/Duo /

Hence, DP-Salad.

As such, this updates with new configuration and such when needed.

Minimum Requirements for the DP-SALA/D Stack: ​

A DP-SALA/D Stack is rather lightweight in comparison to other stacks out there, like the very similar Unraid-SALA/D stack( + ).

This is a compilation of the minimum specs for each part of the stack.

Debian 12 ​

  • 1GHz Processor from 2010 or later
  • 2 GB RAM
  • 10 GB Storage

Portainer ​

  • 1GHz Processor from 2010 or later
  • 2 GB RAM
  • 20 GB Storage

SWAG ​

  • 1GHz Processor from 2010 or later
  • RAM requirement depends on expected requests, 4 GB recommended.
  • 10 GB Storage

Authelia ​

  • Requires that a REDIS server is setup in addition to whatever else.

Authy/Duo ​

  • Authy:

    • Hooks into Authelia for 2FA aaS, only requires a bit of setup.
  • Duo:

    • Hooks into Authelia for 2FA aaS, however, free tier can have max 10 users, but setup is a little easier on the user/admin.

Overall Minimum: ​

  • Most Processors within the last 5 years should work well enough.
  • 4 GB RAM minimum, although 2 GB can be gotten away with.
  • 30 GB Storage minimum, especially if you plan to reverse proxy some apps.
  • Basic command line knowledge.

What this guide assumes: ​

This guide assumes that you have basic computing knowledge, including how to boot your computer into an OS from a USB stick, having a domain through a registrar, and have a Gmail address for sending email to your potential users.

If you do not have a domain, my recommendation (at the time of writing) is to go through Porkbun or Cloudflare . These are the two most reputable registrars that do not markup pricing for renewing the domain you are leasing.

I also recommend that you set up a Gmail address specifically for the purpose of this stack, as Authelia will require a way to let their users password reset, as well as setup 2FA for themselves.

You may also use iCloud+'s custom domain email, however, this guide will not cover this setup, and you will have to do some research on sending email through iCloud if you choose to go this route, and you will have to find the proper settings before configuring Authelia.

',26)]))}const d=e(t,[["render",r]]);export{c as __pageData,d as default}; diff --git a/.vitepress/dist/assets/install_requirements.md.DnNTxVlB.lean.js b/.vitepress/dist/assets/install_requirements.md.DnNTxVlB.lean.js new file mode 100644 index 0000000..37d2e98 --- /dev/null +++ b/.vitepress/dist/assets/install_requirements.md.DnNTxVlB.lean.js @@ -0,0 +1 @@ +import{_ as e,c as s,a3 as i,o}from"./chunks/framework.DtMx7FFi.js";const c=JSON.parse('{"title":"DP-Salad Minimum Requirements","description":"","frontmatter":{"title":"DP-Salad Minimum Requirements"},"headers":[],"relativePath":"install/requirements.md","filePath":"install/requirements.md"}'),t={name:"install/requirements.md"};function r(l,a,n,u,h,m){return o(),s("div",null,a[0]||(a[0]=[i('

DP-SALA/D Stack (pronounced as DP-Salad but stylized as DP-SALA/D) ​

Where does the acronym originate from? ​

It comes from:

  • Debian 12
  • Portainer
  • SWAG
  • Authelia
  • LLDAP
  • Authy/Duo /

Hence, DP-Salad.

As such, this updates with new configuration and such when needed.

Minimum Requirements for the DP-SALA/D Stack: ​

A DP-SALA/D Stack is rather lightweight in comparison to other stacks out there, like the very similar Unraid-SALA/D stack( + ).

This is a compilation of the minimum specs for each part of the stack.

Debian 12 ​

  • 1GHz Processor from 2010 or later
  • 2 GB RAM
  • 10 GB Storage

Portainer ​

  • 1GHz Processor from 2010 or later
  • 2 GB RAM
  • 20 GB Storage

SWAG ​

  • 1GHz Processor from 2010 or later
  • RAM requirement depends on expected requests, 4 GB recommended.
  • 10 GB Storage

Authelia ​

  • Requires that a REDIS server is setup in addition to whatever else.

Authy/Duo ​

  • Authy:

    • Hooks into Authelia for 2FA aaS, only requires a bit of setup.
  • Duo:

    • Hooks into Authelia for 2FA aaS, however, free tier can have max 10 users, but setup is a little easier on the user/admin.

Overall Minimum: ​

  • Most Processors within the last 5 years should work well enough.
  • 4 GB RAM minimum, although 2 GB can be gotten away with.
  • 30 GB Storage minimum, especially if you plan to reverse proxy some apps.
  • Basic command line knowledge.

What this guide assumes: ​

This guide assumes that you have basic computing knowledge, including how to boot your computer into an OS from a USB stick, having a domain through a registrar, and have a Gmail address for sending email to your potential users.

If you do not have a domain, my recommendation (at the time of writing) is to go through Porkbun or Cloudflare . These are the two most reputable registrars that do not markup pricing for renewing the domain you are leasing.

I also recommend that you set up a Gmail address specifically for the purpose of this stack, as Authelia will require a way to let their users password reset, as well as setup 2FA for themselves.

You may also use iCloud+'s custom domain email, however, this guide will not cover this setup, and you will have to do some research on sending email through iCloud if you choose to go this route, and you will have to find the proper settings before configuring Authelia.

',26)]))}const d=e(t,[["render",r]]);export{c as __pageData,d as default}; diff --git a/.vitepress/dist/assets/install_salad-setup.md.uqD3xfuF.js b/.vitepress/dist/assets/install_salad-setup.md.uqD3xfuF.js new file mode 100644 index 0000000..7e046a0 --- /dev/null +++ b/.vitepress/dist/assets/install_salad-setup.md.uqD3xfuF.js @@ -0,0 +1 @@ +import{_ as a,c as t,a3 as i,o as l}from"./chunks/framework.DtMx7FFi.js";const c=JSON.parse('{"title":"Salad Setup","description":"","frontmatter":{"title":"Salad Setup"},"headers":[],"relativePath":"install/salad-setup.md","filePath":"install/salad-setup.md"}'),s={name:"install/salad-setup.md"};function o(n,e,r,u,h,p){return l(),t("div",null,e[0]||(e[0]=[i('

SALA/D Setup ​

Instructions to set up the SALA/D Part of the stack.

Overview of the SALA/D Stack: ​

The SALA/D stack, or SWAG, Authelia, LLDAP, Authy/Duo stack is a simple way to get a webserver/reverse proxy, an identity and access control management system, as well as 2FA; all working together to host whatever you'd like. Here is what does what:

  • Swag

    • Handles the webserver and reverse proxy.
    • All configuration is handled via .conf files and text
    • This guide also demonstrates how to set up the Docker Mods Auto Reload, GeoIPBlock, and ...
  • Authelia

    • Handles weblogin and the front end of 2FA.
    • This has one configuration file, and hooks into LLDAP.
  • LLDAP

    • Handles the "identity" part of the Authentication solution.
    • Requires that a domain is setup, and has a bit of a learning curve.
    • This has a bit of configuration involved whenever you setup a new application with LDAP integrations, however, LLDAP's GitHub page usually has sample configurations on how to setup LDAP auth for an application.
  • Authy/Duo

    • Pick one between Authy or Duo
      • Authy
        • This allows for 2FA via an 8 digit code. The configuration is handled via Authelia, with the end user setting up 2FA through the Authy App or through Bit/Vaultwarden. The user can self register their 2FA in this way, through email.
      • Duo
        • This allows for 2FA via a push notification on your phone. The configuration is handled via Authelia.
',5)]))}const A=a(s,[["render",o]]);export{c as __pageData,A as default}; diff --git a/.vitepress/dist/assets/install_salad-setup.md.uqD3xfuF.lean.js b/.vitepress/dist/assets/install_salad-setup.md.uqD3xfuF.lean.js new file mode 100644 index 0000000..7e046a0 --- /dev/null +++ b/.vitepress/dist/assets/install_salad-setup.md.uqD3xfuF.lean.js @@ -0,0 +1 @@ +import{_ as a,c as t,a3 as i,o as l}from"./chunks/framework.DtMx7FFi.js";const c=JSON.parse('{"title":"Salad Setup","description":"","frontmatter":{"title":"Salad Setup"},"headers":[],"relativePath":"install/salad-setup.md","filePath":"install/salad-setup.md"}'),s={name:"install/salad-setup.md"};function o(n,e,r,u,h,p){return l(),t("div",null,e[0]||(e[0]=[i('

SALA/D Setup ​

Instructions to set up the SALA/D Part of the stack.

Overview of the SALA/D Stack: ​

The SALA/D stack, or SWAG, Authelia, LLDAP, Authy/Duo stack is a simple way to get a webserver/reverse proxy, an identity and access control management system, as well as 2FA; all working together to host whatever you'd like. Here is what does what:

  • Swag

    • Handles the webserver and reverse proxy.
    • All configuration is handled via .conf files and text
    • This guide also demonstrates how to set up the Docker Mods Auto Reload, GeoIPBlock, and ...
  • Authelia

    • Handles weblogin and the front end of 2FA.
    • This has one configuration file, and hooks into LLDAP.
  • LLDAP

    • Handles the "identity" part of the Authentication solution.
    • Requires that a domain is setup, and has a bit of a learning curve.
    • This has a bit of configuration involved whenever you setup a new application with LDAP integrations, however, LLDAP's GitHub page usually has sample configurations on how to setup LDAP auth for an application.
  • Authy/Duo

    • Pick one between Authy or Duo
      • Authy
        • This allows for 2FA via an 8 digit code. The configuration is handled via Authelia, with the end user setting up 2FA through the Authy App or through Bit/Vaultwarden. The user can self register their 2FA in this way, through email.
      • Duo
        • This allows for 2FA via a push notification on your phone. The configuration is handled via Authelia.
',5)]))}const A=a(s,[["render",o]]);export{c as __pageData,A as default}; diff --git a/.vitepress/dist/assets/inter-italic-cyrillic-ext.r48I6akx.woff2 b/.vitepress/dist/assets/inter-italic-cyrillic-ext.r48I6akx.woff2 new file mode 100644 index 0000000..b6b603d Binary files /dev/null and b/.vitepress/dist/assets/inter-italic-cyrillic-ext.r48I6akx.woff2 differ diff --git a/.vitepress/dist/assets/inter-italic-cyrillic.By2_1cv3.woff2 b/.vitepress/dist/assets/inter-italic-cyrillic.By2_1cv3.woff2 new file mode 100644 index 0000000..def40a4 Binary files /dev/null and b/.vitepress/dist/assets/inter-italic-cyrillic.By2_1cv3.woff2 differ diff --git a/.vitepress/dist/assets/inter-italic-greek-ext.1u6EdAuj.woff2 b/.vitepress/dist/assets/inter-italic-greek-ext.1u6EdAuj.woff2 new file mode 100644 index 0000000..e070c3d Binary files /dev/null and b/.vitepress/dist/assets/inter-italic-greek-ext.1u6EdAuj.woff2 differ diff --git a/.vitepress/dist/assets/inter-italic-greek.DJ8dCoTZ.woff2 b/.vitepress/dist/assets/inter-italic-greek.DJ8dCoTZ.woff2 new file mode 100644 index 0000000..a3c16ca Binary files /dev/null and b/.vitepress/dist/assets/inter-italic-greek.DJ8dCoTZ.woff2 differ diff --git a/.vitepress/dist/assets/inter-italic-latin-ext.CN1xVJS-.woff2 b/.vitepress/dist/assets/inter-italic-latin-ext.CN1xVJS-.woff2 new file mode 100644 index 0000000..2210a89 Binary files /dev/null and b/.vitepress/dist/assets/inter-italic-latin-ext.CN1xVJS-.woff2 differ diff --git a/.vitepress/dist/assets/inter-italic-latin.C2AdPX0b.woff2 b/.vitepress/dist/assets/inter-italic-latin.C2AdPX0b.woff2 new file mode 100644 index 0000000..790d62d Binary files /dev/null and b/.vitepress/dist/assets/inter-italic-latin.C2AdPX0b.woff2 differ diff --git a/.vitepress/dist/assets/inter-italic-vietnamese.BSbpV94h.woff2 b/.vitepress/dist/assets/inter-italic-vietnamese.BSbpV94h.woff2 new file mode 100644 index 0000000..1eec077 Binary files /dev/null and b/.vitepress/dist/assets/inter-italic-vietnamese.BSbpV94h.woff2 differ diff --git a/.vitepress/dist/assets/inter-roman-cyrillic-ext.BBPuwvHQ.woff2 b/.vitepress/dist/assets/inter-roman-cyrillic-ext.BBPuwvHQ.woff2 new file mode 100644 index 0000000..2cfe615 Binary files /dev/null and b/.vitepress/dist/assets/inter-roman-cyrillic-ext.BBPuwvHQ.woff2 differ diff --git a/.vitepress/dist/assets/inter-roman-cyrillic.C5lxZ8CY.woff2 b/.vitepress/dist/assets/inter-roman-cyrillic.C5lxZ8CY.woff2 new file mode 100644 index 0000000..e3886dd Binary files /dev/null and b/.vitepress/dist/assets/inter-roman-cyrillic.C5lxZ8CY.woff2 differ diff --git a/.vitepress/dist/assets/inter-roman-greek-ext.CqjqNYQ-.woff2 b/.vitepress/dist/assets/inter-roman-greek-ext.CqjqNYQ-.woff2 new file mode 100644 index 0000000..36d6748 Binary files /dev/null and b/.vitepress/dist/assets/inter-roman-greek-ext.CqjqNYQ-.woff2 differ diff --git a/.vitepress/dist/assets/inter-roman-greek.BBVDIX6e.woff2 b/.vitepress/dist/assets/inter-roman-greek.BBVDIX6e.woff2 new file mode 100644 index 0000000..2bed1e8 Binary files /dev/null and b/.vitepress/dist/assets/inter-roman-greek.BBVDIX6e.woff2 differ diff --git a/.vitepress/dist/assets/inter-roman-latin-ext.4ZJIpNVo.woff2 b/.vitepress/dist/assets/inter-roman-latin-ext.4ZJIpNVo.woff2 new file mode 100644 index 0000000..9a8d1e2 Binary files /dev/null and b/.vitepress/dist/assets/inter-roman-latin-ext.4ZJIpNVo.woff2 differ diff --git a/.vitepress/dist/assets/inter-roman-latin.Di8DUHzh.woff2 b/.vitepress/dist/assets/inter-roman-latin.Di8DUHzh.woff2 new file mode 100644 index 0000000..07d3c53 Binary files /dev/null and b/.vitepress/dist/assets/inter-roman-latin.Di8DUHzh.woff2 differ diff --git a/.vitepress/dist/assets/inter-roman-vietnamese.BjW4sHH5.woff2 b/.vitepress/dist/assets/inter-roman-vietnamese.BjW4sHH5.woff2 new file mode 100644 index 0000000..57bdc22 Binary files /dev/null and b/.vitepress/dist/assets/inter-roman-vietnamese.BjW4sHH5.woff2 differ diff --git a/.vitepress/dist/assets/maintenance_maintain-guide.md.DC42-hYW.js b/.vitepress/dist/assets/maintenance_maintain-guide.md.DC42-hYW.js new file mode 100644 index 0000000..4ee8f95 --- /dev/null +++ b/.vitepress/dist/assets/maintenance_maintain-guide.md.DC42-hYW.js @@ -0,0 +1 @@ +import{_ as a,c as t,a3 as i,o as n}from"./chunks/framework.DtMx7FFi.js";const h=JSON.parse('{"title":"Maintenance of the DP-SALA/D Stack","description":"","frontmatter":{"title":"Maintenance of the DP-SALA/D Stack"},"headers":[],"relativePath":"maintenance/maintain-guide.md","filePath":"maintenance/maintain-guide.md"}'),s={name:"maintenance/maintain-guide.md"};function o(l,e,r,p,u,c){return n(),t("div",null,e[0]||(e[0]=[i('

Maintenance of the DP-SALA/D Stack ​

Suggested maintenance for the DP-SALA/D Stack

Required Maintenance for the DP-SALA/D Stack ​

Debian 12:

  • At least monthly, run a "sudo apt-get update && sudo apt-get update" to update the base applications for Debian, this applies security and feature upgrades for your OS, which is important.

  • At least bi-weekly, save all the configuration files and important data to a secure, private, personal location. You could even use the Google Drive space of the Gmail address that you setup, and save the previous backups. You could probably keep the last 5 backups just to be safe, but minimum of 3.

Portainer:

  • Update whenever there is an update. If you login and it tells you there is an update available, update right then and there. Portainer is just a docker container that lets you manage other docker containers, but make sure to keep this as up to date as possible.
  • You generally don't have to keep a backup of the Portainer data volume, unless you've made some crazy modification to it's configuration that was different from the standard install.

SWAG:

  • At least monthly, restart the container. This allows it to pull new configurations from the GitHub page, as well as renew your SSL certificates for your webserver.

Authelia:

  • At least monthly, restart the container. This allows it to pull updates for the container.

WARNING

Make sure that your configuration for this is backed up, since multiple sensitive things are within this file, and recovering them will be impossible.

LLDAP:

  • This is probably the lowest maintenance thing out of the stack. Just make sure that it is backed up completely.

Authy/Duo:

  • Set it and forget it. This is typically included in Authelia , so another reason to make sure that config file is completely backed up properly.
',16)]))}const m=a(s,[["render",o]]);export{h as __pageData,m as default}; diff --git a/.vitepress/dist/assets/maintenance_maintain-guide.md.DC42-hYW.lean.js b/.vitepress/dist/assets/maintenance_maintain-guide.md.DC42-hYW.lean.js new file mode 100644 index 0000000..4ee8f95 --- /dev/null +++ b/.vitepress/dist/assets/maintenance_maintain-guide.md.DC42-hYW.lean.js @@ -0,0 +1 @@ +import{_ as a,c as t,a3 as i,o as n}from"./chunks/framework.DtMx7FFi.js";const h=JSON.parse('{"title":"Maintenance of the DP-SALA/D Stack","description":"","frontmatter":{"title":"Maintenance of the DP-SALA/D Stack"},"headers":[],"relativePath":"maintenance/maintain-guide.md","filePath":"maintenance/maintain-guide.md"}'),s={name:"maintenance/maintain-guide.md"};function o(l,e,r,p,u,c){return n(),t("div",null,e[0]||(e[0]=[i('

Maintenance of the DP-SALA/D Stack ​

Suggested maintenance for the DP-SALA/D Stack

Required Maintenance for the DP-SALA/D Stack ​

Debian 12:

  • At least monthly, run a "sudo apt-get update && sudo apt-get update" to update the base applications for Debian, this applies security and feature upgrades for your OS, which is important.

  • At least bi-weekly, save all the configuration files and important data to a secure, private, personal location. You could even use the Google Drive space of the Gmail address that you setup, and save the previous backups. You could probably keep the last 5 backups just to be safe, but minimum of 3.

Portainer:

  • Update whenever there is an update. If you login and it tells you there is an update available, update right then and there. Portainer is just a docker container that lets you manage other docker containers, but make sure to keep this as up to date as possible.
  • You generally don't have to keep a backup of the Portainer data volume, unless you've made some crazy modification to it's configuration that was different from the standard install.

SWAG:

  • At least monthly, restart the container. This allows it to pull new configurations from the GitHub page, as well as renew your SSL certificates for your webserver.

Authelia:

  • At least monthly, restart the container. This allows it to pull updates for the container.

WARNING

Make sure that your configuration for this is backed up, since multiple sensitive things are within this file, and recovering them will be impossible.

LLDAP:

  • This is probably the lowest maintenance thing out of the stack. Just make sure that it is backed up completely.

Authy/Duo:

  • Set it and forget it. This is typically included in Authelia , so another reason to make sure that config file is completely backed up properly.
',16)]))}const m=a(s,[["render",o]]);export{h as __pageData,m as default}; diff --git a/.vitepress/dist/assets/style.CpK5ZA6m.css b/.vitepress/dist/assets/style.CpK5ZA6m.css new file mode 100644 index 0000000..b5e8120 --- /dev/null +++ b/.vitepress/dist/assets/style.CpK5ZA6m.css @@ -0,0 +1 @@ +@font-face{font-family:Inter;font-style:normal;font-weight:100 900;font-display:swap;src:url(/assets/inter-roman-cyrillic-ext.BBPuwvHQ.woff2) format("woff2");unicode-range:U+0460-052F,U+1C80-1C88,U+20B4,U+2DE0-2DFF,U+A640-A69F,U+FE2E-FE2F}@font-face{font-family:Inter;font-style:normal;font-weight:100 900;font-display:swap;src:url(/assets/inter-roman-cyrillic.C5lxZ8CY.woff2) format("woff2");unicode-range:U+0301,U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116}@font-face{font-family:Inter;font-style:normal;font-weight:100 900;font-display:swap;src:url(/assets/inter-roman-greek-ext.CqjqNYQ-.woff2) format("woff2");unicode-range:U+1F00-1FFF}@font-face{font-family:Inter;font-style:normal;font-weight:100 900;font-display:swap;src:url(/assets/inter-roman-greek.BBVDIX6e.woff2) format("woff2");unicode-range:U+0370-0377,U+037A-037F,U+0384-038A,U+038C,U+038E-03A1,U+03A3-03FF}@font-face{font-family:Inter;font-style:normal;font-weight:100 900;font-display:swap;src:url(/assets/inter-roman-vietnamese.BjW4sHH5.woff2) format("woff2");unicode-range:U+0102-0103,U+0110-0111,U+0128-0129,U+0168-0169,U+01A0-01A1,U+01AF-01B0,U+0300-0301,U+0303-0304,U+0308-0309,U+0323,U+0329,U+1EA0-1EF9,U+20AB}@font-face{font-family:Inter;font-style:normal;font-weight:100 900;font-display:swap;src:url(/assets/inter-roman-latin-ext.4ZJIpNVo.woff2) format("woff2");unicode-range:U+0100-02AF,U+0304,U+0308,U+0329,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:Inter;font-style:normal;font-weight:100 900;font-display:swap;src:url(/assets/inter-roman-latin.Di8DUHzh.woff2) format("woff2");unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}@font-face{font-family:Inter;font-style:italic;font-weight:100 900;font-display:swap;src:url(/assets/inter-italic-cyrillic-ext.r48I6akx.woff2) format("woff2");unicode-range:U+0460-052F,U+1C80-1C88,U+20B4,U+2DE0-2DFF,U+A640-A69F,U+FE2E-FE2F}@font-face{font-family:Inter;font-style:italic;font-weight:100 900;font-display:swap;src:url(/assets/inter-italic-cyrillic.By2_1cv3.woff2) format("woff2");unicode-range:U+0301,U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116}@font-face{font-family:Inter;font-style:italic;font-weight:100 900;font-display:swap;src:url(/assets/inter-italic-greek-ext.1u6EdAuj.woff2) format("woff2");unicode-range:U+1F00-1FFF}@font-face{font-family:Inter;font-style:italic;font-weight:100 900;font-display:swap;src:url(/assets/inter-italic-greek.DJ8dCoTZ.woff2) format("woff2");unicode-range:U+0370-0377,U+037A-037F,U+0384-038A,U+038C,U+038E-03A1,U+03A3-03FF}@font-face{font-family:Inter;font-style:italic;font-weight:100 900;font-display:swap;src:url(/assets/inter-italic-vietnamese.BSbpV94h.woff2) format("woff2");unicode-range:U+0102-0103,U+0110-0111,U+0128-0129,U+0168-0169,U+01A0-01A1,U+01AF-01B0,U+0300-0301,U+0303-0304,U+0308-0309,U+0323,U+0329,U+1EA0-1EF9,U+20AB}@font-face{font-family:Inter;font-style:italic;font-weight:100 900;font-display:swap;src:url(/assets/inter-italic-latin-ext.CN1xVJS-.woff2) format("woff2");unicode-range:U+0100-02AF,U+0304,U+0308,U+0329,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:Inter;font-style:italic;font-weight:100 900;font-display:swap;src:url(/assets/inter-italic-latin.C2AdPX0b.woff2) format("woff2");unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}@font-face{font-family:Punctuation SC;font-weight:400;src:local("PingFang SC Regular"),local("Noto Sans CJK SC"),local("Microsoft YaHei");unicode-range:U+201C,U+201D,U+2018,U+2019,U+2E3A,U+2014,U+2013,U+2026,U+00B7,U+007E,U+002F}@font-face{font-family:Punctuation SC;font-weight:500;src:local("PingFang SC Medium"),local("Noto Sans CJK SC"),local("Microsoft YaHei");unicode-range:U+201C,U+201D,U+2018,U+2019,U+2E3A,U+2014,U+2013,U+2026,U+00B7,U+007E,U+002F}@font-face{font-family:Punctuation SC;font-weight:600;src:local("PingFang SC Semibold"),local("Noto Sans CJK SC Bold"),local("Microsoft YaHei Bold");unicode-range:U+201C,U+201D,U+2018,U+2019,U+2E3A,U+2014,U+2013,U+2026,U+00B7,U+007E,U+002F}@font-face{font-family:Punctuation SC;font-weight:700;src:local("PingFang SC Semibold"),local("Noto Sans CJK SC Bold"),local("Microsoft YaHei Bold");unicode-range:U+201C,U+201D,U+2018,U+2019,U+2E3A,U+2014,U+2013,U+2026,U+00B7,U+007E,U+002F}:root{--vp-c-white: #ffffff;--vp-c-black: #000000;--vp-c-neutral: var(--vp-c-black);--vp-c-neutral-inverse: var(--vp-c-white)}.dark{--vp-c-neutral: var(--vp-c-white);--vp-c-neutral-inverse: var(--vp-c-black)}:root{--vp-c-gray-1: #dddde3;--vp-c-gray-2: #e4e4e9;--vp-c-gray-3: #ebebef;--vp-c-gray-soft: rgba(142, 150, 170, .14);--vp-c-indigo-1: #3451b2;--vp-c-indigo-2: #3a5ccc;--vp-c-indigo-3: #5672cd;--vp-c-indigo-soft: rgba(100, 108, 255, .14);--vp-c-purple-1: #6f42c1;--vp-c-purple-2: #7e4cc9;--vp-c-purple-3: #8e5cd9;--vp-c-purple-soft: rgba(159, 122, 234, .14);--vp-c-green-1: #18794e;--vp-c-green-2: #299764;--vp-c-green-3: #30a46c;--vp-c-green-soft: rgba(16, 185, 129, .14);--vp-c-yellow-1: #915930;--vp-c-yellow-2: #946300;--vp-c-yellow-3: #9f6a00;--vp-c-yellow-soft: rgba(234, 179, 8, .14);--vp-c-red-1: #b8272c;--vp-c-red-2: #d5393e;--vp-c-red-3: #e0575b;--vp-c-red-soft: rgba(244, 63, 94, .14);--vp-c-sponsor: #db2777}.dark{--vp-c-gray-1: #515c67;--vp-c-gray-2: #414853;--vp-c-gray-3: #32363f;--vp-c-gray-soft: rgba(101, 117, 133, .16);--vp-c-indigo-1: #a8b1ff;--vp-c-indigo-2: #5c73e7;--vp-c-indigo-3: #3e63dd;--vp-c-indigo-soft: rgba(100, 108, 255, .16);--vp-c-purple-1: #c8abfa;--vp-c-purple-2: #a879e6;--vp-c-purple-3: #8e5cd9;--vp-c-purple-soft: rgba(159, 122, 234, .16);--vp-c-green-1: #3dd68c;--vp-c-green-2: #30a46c;--vp-c-green-3: #298459;--vp-c-green-soft: rgba(16, 185, 129, .16);--vp-c-yellow-1: #f9b44e;--vp-c-yellow-2: #da8b17;--vp-c-yellow-3: #a46a0a;--vp-c-yellow-soft: rgba(234, 179, 8, .16);--vp-c-red-1: #f66f81;--vp-c-red-2: #f14158;--vp-c-red-3: #b62a3c;--vp-c-red-soft: rgba(244, 63, 94, .16)}:root{--vp-c-bg: #ffffff;--vp-c-bg-alt: #f6f6f7;--vp-c-bg-elv: #ffffff;--vp-c-bg-soft: #f6f6f7}.dark{--vp-c-bg: #1b1b1f;--vp-c-bg-alt: #161618;--vp-c-bg-elv: #202127;--vp-c-bg-soft: #202127}:root{--vp-c-border: #c2c2c4;--vp-c-divider: #e2e2e3;--vp-c-gutter: #e2e2e3}.dark{--vp-c-border: #3c3f44;--vp-c-divider: #2e2e32;--vp-c-gutter: #000000}:root{--vp-c-text-1: rgba(60, 60, 67);--vp-c-text-2: rgba(60, 60, 67, .78);--vp-c-text-3: rgba(60, 60, 67, .56)}.dark{--vp-c-text-1: rgba(255, 255, 245, .86);--vp-c-text-2: rgba(235, 235, 245, .6);--vp-c-text-3: rgba(235, 235, 245, .38)}:root{--vp-c-default-1: var(--vp-c-gray-1);--vp-c-default-2: var(--vp-c-gray-2);--vp-c-default-3: var(--vp-c-gray-3);--vp-c-default-soft: var(--vp-c-gray-soft);--vp-c-brand-1: var(--vp-c-indigo-1);--vp-c-brand-2: var(--vp-c-indigo-2);--vp-c-brand-3: var(--vp-c-indigo-3);--vp-c-brand-soft: var(--vp-c-indigo-soft);--vp-c-brand: var(--vp-c-brand-1);--vp-c-tip-1: var(--vp-c-brand-1);--vp-c-tip-2: var(--vp-c-brand-2);--vp-c-tip-3: var(--vp-c-brand-3);--vp-c-tip-soft: var(--vp-c-brand-soft);--vp-c-note-1: var(--vp-c-brand-1);--vp-c-note-2: var(--vp-c-brand-2);--vp-c-note-3: var(--vp-c-brand-3);--vp-c-note-soft: var(--vp-c-brand-soft);--vp-c-success-1: var(--vp-c-green-1);--vp-c-success-2: var(--vp-c-green-2);--vp-c-success-3: var(--vp-c-green-3);--vp-c-success-soft: var(--vp-c-green-soft);--vp-c-important-1: var(--vp-c-purple-1);--vp-c-important-2: var(--vp-c-purple-2);--vp-c-important-3: var(--vp-c-purple-3);--vp-c-important-soft: var(--vp-c-purple-soft);--vp-c-warning-1: var(--vp-c-yellow-1);--vp-c-warning-2: var(--vp-c-yellow-2);--vp-c-warning-3: var(--vp-c-yellow-3);--vp-c-warning-soft: var(--vp-c-yellow-soft);--vp-c-danger-1: var(--vp-c-red-1);--vp-c-danger-2: var(--vp-c-red-2);--vp-c-danger-3: var(--vp-c-red-3);--vp-c-danger-soft: var(--vp-c-red-soft);--vp-c-caution-1: var(--vp-c-red-1);--vp-c-caution-2: var(--vp-c-red-2);--vp-c-caution-3: var(--vp-c-red-3);--vp-c-caution-soft: var(--vp-c-red-soft)}:root{--vp-font-family-base: "Inter", ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";--vp-font-family-mono: ui-monospace, "Menlo", "Monaco", "Consolas", "Liberation Mono", "Courier New", monospace;font-optical-sizing:auto}:root:where(:lang(zh)){--vp-font-family-base: "Punctuation SC", "Inter", ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"}:root{--vp-shadow-1: 0 1px 2px rgba(0, 0, 0, .04), 0 1px 2px rgba(0, 0, 0, .06);--vp-shadow-2: 0 3px 12px rgba(0, 0, 0, .07), 0 1px 4px rgba(0, 0, 0, .07);--vp-shadow-3: 0 12px 32px rgba(0, 0, 0, .1), 0 2px 6px rgba(0, 0, 0, .08);--vp-shadow-4: 0 14px 44px rgba(0, 0, 0, .12), 0 3px 9px rgba(0, 0, 0, .12);--vp-shadow-5: 0 18px 56px rgba(0, 0, 0, .16), 0 4px 12px rgba(0, 0, 0, .16)}:root{--vp-z-index-footer: 10;--vp-z-index-local-nav: 20;--vp-z-index-nav: 30;--vp-z-index-layout-top: 40;--vp-z-index-backdrop: 50;--vp-z-index-sidebar: 60}@media (min-width: 960px){:root{--vp-z-index-sidebar: 25}}:root{--vp-layout-max-width: 1440px}:root{--vp-header-anchor-symbol: "#"}:root{--vp-code-line-height: 1.7;--vp-code-font-size: .875em;--vp-code-color: var(--vp-c-brand-1);--vp-code-link-color: var(--vp-c-brand-1);--vp-code-link-hover-color: var(--vp-c-brand-2);--vp-code-bg: var(--vp-c-default-soft);--vp-code-block-color: var(--vp-c-text-2);--vp-code-block-bg: var(--vp-c-bg-alt);--vp-code-block-divider-color: var(--vp-c-gutter);--vp-code-lang-color: var(--vp-c-text-3);--vp-code-line-highlight-color: var(--vp-c-default-soft);--vp-code-line-number-color: var(--vp-c-text-3);--vp-code-line-diff-add-color: var(--vp-c-success-soft);--vp-code-line-diff-add-symbol-color: var(--vp-c-success-1);--vp-code-line-diff-remove-color: var(--vp-c-danger-soft);--vp-code-line-diff-remove-symbol-color: var(--vp-c-danger-1);--vp-code-line-warning-color: var(--vp-c-warning-soft);--vp-code-line-error-color: var(--vp-c-danger-soft);--vp-code-copy-code-border-color: var(--vp-c-divider);--vp-code-copy-code-bg: var(--vp-c-bg-soft);--vp-code-copy-code-hover-border-color: var(--vp-c-divider);--vp-code-copy-code-hover-bg: var(--vp-c-bg);--vp-code-copy-code-active-text: var(--vp-c-text-2);--vp-code-copy-copied-text-content: "Copied";--vp-code-tab-divider: var(--vp-code-block-divider-color);--vp-code-tab-text-color: var(--vp-c-text-2);--vp-code-tab-bg: var(--vp-code-block-bg);--vp-code-tab-hover-text-color: var(--vp-c-text-1);--vp-code-tab-active-text-color: var(--vp-c-text-1);--vp-code-tab-active-bar-color: var(--vp-c-brand-1)}:root{--vp-button-brand-border: transparent;--vp-button-brand-text: var(--vp-c-white);--vp-button-brand-bg: var(--vp-c-brand-3);--vp-button-brand-hover-border: transparent;--vp-button-brand-hover-text: var(--vp-c-white);--vp-button-brand-hover-bg: var(--vp-c-brand-2);--vp-button-brand-active-border: transparent;--vp-button-brand-active-text: var(--vp-c-white);--vp-button-brand-active-bg: var(--vp-c-brand-1);--vp-button-alt-border: transparent;--vp-button-alt-text: var(--vp-c-text-1);--vp-button-alt-bg: var(--vp-c-default-3);--vp-button-alt-hover-border: transparent;--vp-button-alt-hover-text: var(--vp-c-text-1);--vp-button-alt-hover-bg: var(--vp-c-default-2);--vp-button-alt-active-border: transparent;--vp-button-alt-active-text: var(--vp-c-text-1);--vp-button-alt-active-bg: var(--vp-c-default-1);--vp-button-sponsor-border: var(--vp-c-text-2);--vp-button-sponsor-text: var(--vp-c-text-2);--vp-button-sponsor-bg: transparent;--vp-button-sponsor-hover-border: var(--vp-c-sponsor);--vp-button-sponsor-hover-text: var(--vp-c-sponsor);--vp-button-sponsor-hover-bg: transparent;--vp-button-sponsor-active-border: var(--vp-c-sponsor);--vp-button-sponsor-active-text: var(--vp-c-sponsor);--vp-button-sponsor-active-bg: transparent}:root{--vp-custom-block-font-size: 14px;--vp-custom-block-code-font-size: 13px;--vp-custom-block-info-border: transparent;--vp-custom-block-info-text: var(--vp-c-text-1);--vp-custom-block-info-bg: var(--vp-c-default-soft);--vp-custom-block-info-code-bg: var(--vp-c-default-soft);--vp-custom-block-note-border: transparent;--vp-custom-block-note-text: var(--vp-c-text-1);--vp-custom-block-note-bg: var(--vp-c-default-soft);--vp-custom-block-note-code-bg: var(--vp-c-default-soft);--vp-custom-block-tip-border: transparent;--vp-custom-block-tip-text: var(--vp-c-text-1);--vp-custom-block-tip-bg: var(--vp-c-tip-soft);--vp-custom-block-tip-code-bg: var(--vp-c-tip-soft);--vp-custom-block-important-border: transparent;--vp-custom-block-important-text: var(--vp-c-text-1);--vp-custom-block-important-bg: var(--vp-c-important-soft);--vp-custom-block-important-code-bg: var(--vp-c-important-soft);--vp-custom-block-warning-border: transparent;--vp-custom-block-warning-text: var(--vp-c-text-1);--vp-custom-block-warning-bg: var(--vp-c-warning-soft);--vp-custom-block-warning-code-bg: var(--vp-c-warning-soft);--vp-custom-block-danger-border: transparent;--vp-custom-block-danger-text: var(--vp-c-text-1);--vp-custom-block-danger-bg: var(--vp-c-danger-soft);--vp-custom-block-danger-code-bg: var(--vp-c-danger-soft);--vp-custom-block-caution-border: transparent;--vp-custom-block-caution-text: var(--vp-c-text-1);--vp-custom-block-caution-bg: var(--vp-c-caution-soft);--vp-custom-block-caution-code-bg: var(--vp-c-caution-soft);--vp-custom-block-details-border: var(--vp-custom-block-info-border);--vp-custom-block-details-text: var(--vp-custom-block-info-text);--vp-custom-block-details-bg: var(--vp-custom-block-info-bg);--vp-custom-block-details-code-bg: var(--vp-custom-block-info-code-bg)}:root{--vp-input-border-color: var(--vp-c-border);--vp-input-bg-color: var(--vp-c-bg-alt);--vp-input-switch-bg-color: var(--vp-c-default-soft)}:root{--vp-nav-height: 64px;--vp-nav-bg-color: var(--vp-c-bg);--vp-nav-screen-bg-color: var(--vp-c-bg);--vp-nav-logo-height: 24px}.hide-nav{--vp-nav-height: 0px}.hide-nav .VPSidebar{--vp-nav-height: 22px}:root{--vp-local-nav-bg-color: var(--vp-c-bg)}:root{--vp-sidebar-width: 272px;--vp-sidebar-bg-color: var(--vp-c-bg-alt)}:root{--vp-backdrop-bg-color: rgba(0, 0, 0, .6)}:root{--vp-home-hero-name-color: var(--vp-c-brand-1);--vp-home-hero-name-background: transparent;--vp-home-hero-image-background-image: none;--vp-home-hero-image-filter: none}:root{--vp-badge-info-border: transparent;--vp-badge-info-text: var(--vp-c-text-2);--vp-badge-info-bg: var(--vp-c-default-soft);--vp-badge-tip-border: transparent;--vp-badge-tip-text: var(--vp-c-tip-1);--vp-badge-tip-bg: var(--vp-c-tip-soft);--vp-badge-warning-border: transparent;--vp-badge-warning-text: var(--vp-c-warning-1);--vp-badge-warning-bg: var(--vp-c-warning-soft);--vp-badge-danger-border: transparent;--vp-badge-danger-text: var(--vp-c-danger-1);--vp-badge-danger-bg: var(--vp-c-danger-soft)}:root{--vp-carbon-ads-text-color: var(--vp-c-text-1);--vp-carbon-ads-poweredby-color: var(--vp-c-text-2);--vp-carbon-ads-bg-color: var(--vp-c-bg-soft);--vp-carbon-ads-hover-text-color: var(--vp-c-brand-1);--vp-carbon-ads-hover-poweredby-color: var(--vp-c-text-1)}:root{--vp-local-search-bg: var(--vp-c-bg);--vp-local-search-result-bg: var(--vp-c-bg);--vp-local-search-result-border: var(--vp-c-divider);--vp-local-search-result-selected-bg: var(--vp-c-bg);--vp-local-search-result-selected-border: var(--vp-c-brand-1);--vp-local-search-highlight-bg: var(--vp-c-brand-1);--vp-local-search-highlight-text: var(--vp-c-neutral-inverse)}@media (prefers-reduced-motion: reduce){*,:before,:after{animation-delay:-1ms!important;animation-duration:1ms!important;animation-iteration-count:1!important;background-attachment:initial!important;scroll-behavior:auto!important;transition-duration:0s!important;transition-delay:0s!important}}*,:before,:after{box-sizing:border-box}html{line-height:1.4;font-size:16px;-webkit-text-size-adjust:100%}html.dark{color-scheme:dark}body{margin:0;width:100%;min-width:320px;min-height:100vh;line-height:24px;font-family:var(--vp-font-family-base);font-size:16px;font-weight:400;color:var(--vp-c-text-1);background-color:var(--vp-c-bg);font-synthesis:style;text-rendering:optimizeLegibility;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}main{display:block}h1,h2,h3,h4,h5,h6{margin:0;line-height:24px;font-size:16px;font-weight:400}p{margin:0}strong,b{font-weight:600}a,area,button,[role=button],input,label,select,summary,textarea{touch-action:manipulation}a{color:inherit;text-decoration:inherit}ol,ul{list-style:none;margin:0;padding:0}blockquote{margin:0}pre,code,kbd,samp{font-family:var(--vp-font-family-mono)}img,svg,video,canvas,audio,iframe,embed,object{display:block}figure{margin:0}img,video{max-width:100%;height:auto}button,input,optgroup,select,textarea{border:0;padding:0;line-height:inherit;color:inherit}button{padding:0;font-family:inherit;background-color:transparent;background-image:none}button:enabled,[role=button]:enabled{cursor:pointer}button:focus,button:focus-visible{outline:1px dotted;outline:4px auto -webkit-focus-ring-color}button:focus:not(:focus-visible){outline:none!important}input:focus,textarea:focus,select:focus{outline:none}table{border-collapse:collapse}input{background-color:transparent}input:-ms-input-placeholder,textarea:-ms-input-placeholder{color:var(--vp-c-text-3)}input::-ms-input-placeholder,textarea::-ms-input-placeholder{color:var(--vp-c-text-3)}input::placeholder,textarea::placeholder{color:var(--vp-c-text-3)}input::-webkit-outer-spin-button,input::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}input[type=number]{-moz-appearance:textfield}textarea{resize:vertical}select{-webkit-appearance:none}fieldset{margin:0;padding:0}h1,h2,h3,h4,h5,h6,li,p{overflow-wrap:break-word}vite-error-overlay{z-index:9999}mjx-container{overflow-x:auto}mjx-container>svg{display:inline-block;margin:auto}[class^=vpi-],[class*=" vpi-"],.vp-icon{width:1em;height:1em}[class^=vpi-].bg,[class*=" vpi-"].bg,.vp-icon.bg{background-size:100% 100%;background-color:transparent}[class^=vpi-]:not(.bg),[class*=" vpi-"]:not(.bg),.vp-icon:not(.bg){-webkit-mask:var(--icon) no-repeat;mask:var(--icon) no-repeat;-webkit-mask-size:100% 100%;mask-size:100% 100%;background-color:currentColor;color:inherit}.vpi-align-left{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Cpath d='M21 6H3M15 12H3M17 18H3'/%3E%3C/svg%3E")}.vpi-arrow-right,.vpi-arrow-down,.vpi-arrow-left,.vpi-arrow-up{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Cpath d='M5 12h14M12 5l7 7-7 7'/%3E%3C/svg%3E")}.vpi-chevron-right,.vpi-chevron-down,.vpi-chevron-left,.vpi-chevron-up{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Cpath d='m9 18 6-6-6-6'/%3E%3C/svg%3E")}.vpi-chevron-down,.vpi-arrow-down{transform:rotate(90deg)}.vpi-chevron-left,.vpi-arrow-left{transform:rotate(180deg)}.vpi-chevron-up,.vpi-arrow-up{transform:rotate(-90deg)}.vpi-square-pen{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Cpath d='M12 3H5a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7'/%3E%3Cpath d='M18.375 2.625a2.121 2.121 0 1 1 3 3L12 15l-4 1 1-4Z'/%3E%3C/svg%3E")}.vpi-plus{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Cpath d='M5 12h14M12 5v14'/%3E%3C/svg%3E")}.vpi-sun{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Ccircle cx='12' cy='12' r='4'/%3E%3Cpath d='M12 2v2M12 20v2M4.93 4.93l1.41 1.41M17.66 17.66l1.41 1.41M2 12h2M20 12h2M6.34 17.66l-1.41 1.41M19.07 4.93l-1.41 1.41'/%3E%3C/svg%3E")}.vpi-moon{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Cpath d='M12 3a6 6 0 0 0 9 9 9 9 0 1 1-9-9Z'/%3E%3C/svg%3E")}.vpi-more-horizontal{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Ccircle cx='12' cy='12' r='1'/%3E%3Ccircle cx='19' cy='12' r='1'/%3E%3Ccircle cx='5' cy='12' r='1'/%3E%3C/svg%3E")}.vpi-languages{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Cpath d='m5 8 6 6M4 14l6-6 2-3M2 5h12M7 2h1M22 22l-5-10-5 10M14 18h6'/%3E%3C/svg%3E")}.vpi-heart{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Cpath d='M19 14c1.49-1.46 3-3.21 3-5.5A5.5 5.5 0 0 0 16.5 3c-1.76 0-3 .5-4.5 2-1.5-1.5-2.74-2-4.5-2A5.5 5.5 0 0 0 2 8.5c0 2.3 1.5 4.05 3 5.5l7 7Z'/%3E%3C/svg%3E")}.vpi-search{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Ccircle cx='11' cy='11' r='8'/%3E%3Cpath d='m21 21-4.3-4.3'/%3E%3C/svg%3E")}.vpi-layout-list{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Crect width='7' height='7' x='3' y='3' rx='1'/%3E%3Crect width='7' height='7' x='3' y='14' rx='1'/%3E%3Cpath d='M14 4h7M14 9h7M14 15h7M14 20h7'/%3E%3C/svg%3E")}.vpi-delete{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Cpath d='M20 5H9l-7 7 7 7h11a2 2 0 0 0 2-2V7a2 2 0 0 0-2-2ZM18 9l-6 6M12 9l6 6'/%3E%3C/svg%3E")}.vpi-corner-down-left{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Cpath d='m9 10-5 5 5 5'/%3E%3Cpath d='M20 4v7a4 4 0 0 1-4 4H4'/%3E%3C/svg%3E")}:root{--vp-icon-copy: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='rgba(128,128,128,1)' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Crect width='8' height='4' x='8' y='2' rx='1' ry='1'/%3E%3Cpath d='M16 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2'/%3E%3C/svg%3E");--vp-icon-copied: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='rgba(128,128,128,1)' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' viewBox='0 0 24 24'%3E%3Crect width='8' height='4' x='8' y='2' rx='1' ry='1'/%3E%3Cpath d='M16 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2'/%3E%3Cpath d='m9 14 2 2 4-4'/%3E%3C/svg%3E")}.visually-hidden{position:absolute;width:1px;height:1px;white-space:nowrap;clip:rect(0 0 0 0);clip-path:inset(50%);overflow:hidden}.custom-block{border:1px solid transparent;border-radius:8px;padding:16px 16px 8px;line-height:24px;font-size:var(--vp-custom-block-font-size);color:var(--vp-c-text-2)}.custom-block.info{border-color:var(--vp-custom-block-info-border);color:var(--vp-custom-block-info-text);background-color:var(--vp-custom-block-info-bg)}.custom-block.info a,.custom-block.info code{color:var(--vp-c-brand-1)}.custom-block.info a:hover,.custom-block.info a:hover>code{color:var(--vp-c-brand-2)}.custom-block.info code{background-color:var(--vp-custom-block-info-code-bg)}.custom-block.note{border-color:var(--vp-custom-block-note-border);color:var(--vp-custom-block-note-text);background-color:var(--vp-custom-block-note-bg)}.custom-block.note a,.custom-block.note code{color:var(--vp-c-brand-1)}.custom-block.note a:hover,.custom-block.note a:hover>code{color:var(--vp-c-brand-2)}.custom-block.note code{background-color:var(--vp-custom-block-note-code-bg)}.custom-block.tip{border-color:var(--vp-custom-block-tip-border);color:var(--vp-custom-block-tip-text);background-color:var(--vp-custom-block-tip-bg)}.custom-block.tip a,.custom-block.tip code{color:var(--vp-c-tip-1)}.custom-block.tip a:hover,.custom-block.tip a:hover>code{color:var(--vp-c-tip-2)}.custom-block.tip code{background-color:var(--vp-custom-block-tip-code-bg)}.custom-block.important{border-color:var(--vp-custom-block-important-border);color:var(--vp-custom-block-important-text);background-color:var(--vp-custom-block-important-bg)}.custom-block.important a,.custom-block.important code{color:var(--vp-c-important-1)}.custom-block.important a:hover,.custom-block.important a:hover>code{color:var(--vp-c-important-2)}.custom-block.important code{background-color:var(--vp-custom-block-important-code-bg)}.custom-block.warning{border-color:var(--vp-custom-block-warning-border);color:var(--vp-custom-block-warning-text);background-color:var(--vp-custom-block-warning-bg)}.custom-block.warning a,.custom-block.warning code{color:var(--vp-c-warning-1)}.custom-block.warning a:hover,.custom-block.warning a:hover>code{color:var(--vp-c-warning-2)}.custom-block.warning code{background-color:var(--vp-custom-block-warning-code-bg)}.custom-block.danger{border-color:var(--vp-custom-block-danger-border);color:var(--vp-custom-block-danger-text);background-color:var(--vp-custom-block-danger-bg)}.custom-block.danger a,.custom-block.danger code{color:var(--vp-c-danger-1)}.custom-block.danger a:hover,.custom-block.danger a:hover>code{color:var(--vp-c-danger-2)}.custom-block.danger code{background-color:var(--vp-custom-block-danger-code-bg)}.custom-block.caution{border-color:var(--vp-custom-block-caution-border);color:var(--vp-custom-block-caution-text);background-color:var(--vp-custom-block-caution-bg)}.custom-block.caution a,.custom-block.caution code{color:var(--vp-c-caution-1)}.custom-block.caution a:hover,.custom-block.caution a:hover>code{color:var(--vp-c-caution-2)}.custom-block.caution code{background-color:var(--vp-custom-block-caution-code-bg)}.custom-block.details{border-color:var(--vp-custom-block-details-border);color:var(--vp-custom-block-details-text);background-color:var(--vp-custom-block-details-bg)}.custom-block.details a{color:var(--vp-c-brand-1)}.custom-block.details a:hover,.custom-block.details a:hover>code{color:var(--vp-c-brand-2)}.custom-block.details code{background-color:var(--vp-custom-block-details-code-bg)}.custom-block-title{font-weight:600}.custom-block p+p{margin:8px 0}.custom-block.details summary{margin:0 0 8px;font-weight:700;cursor:pointer;-webkit-user-select:none;user-select:none}.custom-block.details summary+p{margin:8px 0}.custom-block a{color:inherit;font-weight:600;text-decoration:underline;text-underline-offset:2px;transition:opacity .25s}.custom-block a:hover{opacity:.75}.custom-block code{font-size:var(--vp-custom-block-code-font-size)}.custom-block.custom-block th,.custom-block.custom-block blockquote>p{font-size:var(--vp-custom-block-font-size);color:inherit}.dark .vp-code span{color:var(--shiki-dark, inherit)}html:not(.dark) .vp-code span{color:var(--shiki-light, inherit)}.vp-code-group{margin-top:16px}.vp-code-group .tabs{position:relative;display:flex;margin-right:-24px;margin-left:-24px;padding:0 12px;background-color:var(--vp-code-tab-bg);overflow-x:auto;overflow-y:hidden;box-shadow:inset 0 -1px var(--vp-code-tab-divider)}@media (min-width: 640px){.vp-code-group .tabs{margin-right:0;margin-left:0;border-radius:8px 8px 0 0}}.vp-code-group .tabs input{position:fixed;opacity:0;pointer-events:none}.vp-code-group .tabs label{position:relative;display:inline-block;border-bottom:1px solid transparent;padding:0 12px;line-height:48px;font-size:14px;font-weight:500;color:var(--vp-code-tab-text-color);white-space:nowrap;cursor:pointer;transition:color .25s}.vp-code-group .tabs label:after{position:absolute;right:8px;bottom:-1px;left:8px;z-index:1;height:2px;border-radius:2px;content:"";background-color:transparent;transition:background-color .25s}.vp-code-group label:hover{color:var(--vp-code-tab-hover-text-color)}.vp-code-group input:checked+label{color:var(--vp-code-tab-active-text-color)}.vp-code-group input:checked+label:after{background-color:var(--vp-code-tab-active-bar-color)}.vp-code-group div[class*=language-],.vp-block{display:none;margin-top:0!important;border-top-left-radius:0!important;border-top-right-radius:0!important}.vp-code-group div[class*=language-].active,.vp-block.active{display:block}.vp-block{padding:20px 24px}.vp-doc h1,.vp-doc h2,.vp-doc h3,.vp-doc h4,.vp-doc h5,.vp-doc h6{position:relative;font-weight:600;outline:none}.vp-doc h1{letter-spacing:-.02em;line-height:40px;font-size:28px}.vp-doc h2{margin:48px 0 16px;border-top:1px solid var(--vp-c-divider);padding-top:24px;letter-spacing:-.02em;line-height:32px;font-size:24px}.vp-doc h3{margin:32px 0 0;letter-spacing:-.01em;line-height:28px;font-size:20px}.vp-doc h4{margin:24px 0 0;letter-spacing:-.01em;line-height:24px;font-size:18px}.vp-doc .header-anchor{position:absolute;top:0;left:0;margin-left:-.87em;font-weight:500;-webkit-user-select:none;user-select:none;opacity:0;text-decoration:none;transition:color .25s,opacity .25s}.vp-doc .header-anchor:before{content:var(--vp-header-anchor-symbol)}.vp-doc h1:hover .header-anchor,.vp-doc h1 .header-anchor:focus,.vp-doc h2:hover .header-anchor,.vp-doc h2 .header-anchor:focus,.vp-doc h3:hover .header-anchor,.vp-doc h3 .header-anchor:focus,.vp-doc h4:hover .header-anchor,.vp-doc h4 .header-anchor:focus,.vp-doc h5:hover .header-anchor,.vp-doc h5 .header-anchor:focus,.vp-doc h6:hover .header-anchor,.vp-doc h6 .header-anchor:focus{opacity:1}@media (min-width: 768px){.vp-doc h1{letter-spacing:-.02em;line-height:40px;font-size:32px}}.vp-doc h2 .header-anchor{top:24px}.vp-doc p,.vp-doc summary{margin:16px 0}.vp-doc p{line-height:28px}.vp-doc blockquote{margin:16px 0;border-left:2px solid var(--vp-c-divider);padding-left:16px;transition:border-color .5s;color:var(--vp-c-text-2)}.vp-doc blockquote>p{margin:0;font-size:16px;transition:color .5s}.vp-doc a{font-weight:500;color:var(--vp-c-brand-1);text-decoration:underline;text-underline-offset:2px;transition:color .25s,opacity .25s}.vp-doc a:hover{color:var(--vp-c-brand-2)}.vp-doc strong{font-weight:600}.vp-doc ul,.vp-doc ol{padding-left:1.25rem;margin:16px 0}.vp-doc ul{list-style:disc}.vp-doc ol{list-style:decimal}.vp-doc li+li{margin-top:8px}.vp-doc li>ol,.vp-doc li>ul{margin:8px 0 0}.vp-doc table{display:block;border-collapse:collapse;margin:20px 0;overflow-x:auto}.vp-doc tr{background-color:var(--vp-c-bg);border-top:1px solid var(--vp-c-divider);transition:background-color .5s}.vp-doc tr:nth-child(2n){background-color:var(--vp-c-bg-soft)}.vp-doc th,.vp-doc td{border:1px solid var(--vp-c-divider);padding:8px 16px}.vp-doc th{text-align:left;font-size:14px;font-weight:600;color:var(--vp-c-text-2);background-color:var(--vp-c-bg-soft)}.vp-doc td{font-size:14px}.vp-doc hr{margin:16px 0;border:none;border-top:1px solid var(--vp-c-divider)}.vp-doc .custom-block{margin:16px 0}.vp-doc .custom-block p{margin:8px 0;line-height:24px}.vp-doc .custom-block p:first-child{margin:0}.vp-doc .custom-block div[class*=language-]{margin:8px 0;border-radius:8px}.vp-doc .custom-block div[class*=language-] code{font-weight:400;background-color:transparent}.vp-doc .custom-block .vp-code-group .tabs{margin:0;border-radius:8px 8px 0 0}.vp-doc :not(pre,h1,h2,h3,h4,h5,h6)>code{font-size:var(--vp-code-font-size);color:var(--vp-code-color)}.vp-doc :not(pre)>code{border-radius:4px;padding:3px 6px;background-color:var(--vp-code-bg);transition:color .25s,background-color .5s}.vp-doc a>code{color:var(--vp-code-link-color)}.vp-doc a:hover>code{color:var(--vp-code-link-hover-color)}.vp-doc h1>code,.vp-doc h2>code,.vp-doc h3>code,.vp-doc h4>code{font-size:.9em}.vp-doc div[class*=language-],.vp-block{position:relative;margin:16px -24px;background-color:var(--vp-code-block-bg);overflow-x:auto;transition:background-color .5s}@media (min-width: 640px){.vp-doc div[class*=language-],.vp-block{border-radius:8px;margin:16px 0}}@media (max-width: 639px){.vp-doc li div[class*=language-]{border-radius:8px 0 0 8px}}.vp-doc div[class*=language-]+div[class*=language-],.vp-doc div[class$=-api]+div[class*=language-],.vp-doc div[class*=language-]+div[class$=-api]>div[class*=language-]{margin-top:-8px}.vp-doc [class*=language-] pre,.vp-doc [class*=language-] code{direction:ltr;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none}.vp-doc [class*=language-] pre{position:relative;z-index:1;margin:0;padding:20px 0;background:transparent;overflow-x:auto}.vp-doc [class*=language-] code{display:block;padding:0 24px;width:fit-content;min-width:100%;line-height:var(--vp-code-line-height);font-size:var(--vp-code-font-size);color:var(--vp-code-block-color);transition:color .5s}.vp-doc [class*=language-] code .highlighted{background-color:var(--vp-code-line-highlight-color);transition:background-color .5s;margin:0 -24px;padding:0 24px;width:calc(100% + 48px);display:inline-block}.vp-doc [class*=language-] code .highlighted.error{background-color:var(--vp-code-line-error-color)}.vp-doc [class*=language-] code .highlighted.warning{background-color:var(--vp-code-line-warning-color)}.vp-doc [class*=language-] code .diff{transition:background-color .5s;margin:0 -24px;padding:0 24px;width:calc(100% + 48px);display:inline-block}.vp-doc [class*=language-] code .diff:before{position:absolute;left:10px}.vp-doc [class*=language-] .has-focused-lines .line:not(.has-focus){filter:blur(.095rem);opacity:.4;transition:filter .35s,opacity .35s}.vp-doc [class*=language-] .has-focused-lines .line:not(.has-focus){opacity:.7;transition:filter .35s,opacity .35s}.vp-doc [class*=language-]:hover .has-focused-lines .line:not(.has-focus){filter:blur(0);opacity:1}.vp-doc [class*=language-] code .diff.remove{background-color:var(--vp-code-line-diff-remove-color);opacity:.7}.vp-doc [class*=language-] code .diff.remove:before{content:"-";color:var(--vp-code-line-diff-remove-symbol-color)}.vp-doc [class*=language-] code .diff.add{background-color:var(--vp-code-line-diff-add-color)}.vp-doc [class*=language-] code .diff.add:before{content:"+";color:var(--vp-code-line-diff-add-symbol-color)}.vp-doc div[class*=language-].line-numbers-mode{padding-left:32px}.vp-doc .line-numbers-wrapper{position:absolute;top:0;bottom:0;left:0;z-index:3;border-right:1px solid var(--vp-code-block-divider-color);padding-top:20px;width:32px;text-align:center;font-family:var(--vp-font-family-mono);line-height:var(--vp-code-line-height);font-size:var(--vp-code-font-size);color:var(--vp-code-line-number-color);transition:border-color .5s,color .5s}.vp-doc [class*=language-]>button.copy{direction:ltr;position:absolute;top:12px;right:12px;z-index:3;border:1px solid var(--vp-code-copy-code-border-color);border-radius:4px;width:40px;height:40px;background-color:var(--vp-code-copy-code-bg);opacity:0;cursor:pointer;background-image:var(--vp-icon-copy);background-position:50%;background-size:20px;background-repeat:no-repeat;transition:border-color .25s,background-color .25s,opacity .25s}.vp-doc [class*=language-]:hover>button.copy,.vp-doc [class*=language-]>button.copy:focus{opacity:1}.vp-doc [class*=language-]>button.copy:hover,.vp-doc [class*=language-]>button.copy.copied{border-color:var(--vp-code-copy-code-hover-border-color);background-color:var(--vp-code-copy-code-hover-bg)}.vp-doc [class*=language-]>button.copy.copied,.vp-doc [class*=language-]>button.copy:hover.copied{border-radius:0 4px 4px 0;background-color:var(--vp-code-copy-code-hover-bg);background-image:var(--vp-icon-copied)}.vp-doc [class*=language-]>button.copy.copied:before,.vp-doc [class*=language-]>button.copy:hover.copied:before{position:relative;top:-1px;transform:translate(calc(-100% - 1px));display:flex;justify-content:center;align-items:center;border:1px solid var(--vp-code-copy-code-hover-border-color);border-right:0;border-radius:4px 0 0 4px;padding:0 10px;width:fit-content;height:40px;text-align:center;font-size:12px;font-weight:500;color:var(--vp-code-copy-code-active-text);background-color:var(--vp-code-copy-code-hover-bg);white-space:nowrap;content:var(--vp-code-copy-copied-text-content)}.vp-doc [class*=language-]>span.lang{position:absolute;top:2px;right:8px;z-index:2;font-size:12px;font-weight:500;-webkit-user-select:none;user-select:none;color:var(--vp-code-lang-color);transition:color .4s,opacity .4s}.vp-doc [class*=language-]:hover>button.copy+span.lang,.vp-doc [class*=language-]>button.copy:focus+span.lang{opacity:0}.vp-doc .VPTeamMembers{margin-top:24px}.vp-doc .VPTeamMembers.small.count-1 .container{margin:0!important;max-width:calc((100% - 24px)/2)!important}.vp-doc .VPTeamMembers.small.count-2 .container,.vp-doc .VPTeamMembers.small.count-3 .container{max-width:100%!important}.vp-doc .VPTeamMembers.medium.count-1 .container{margin:0!important;max-width:calc((100% - 24px)/2)!important}:is(.vp-external-link-icon,.vp-doc a[href*="://"],.vp-doc a[target=_blank]):not(.no-icon):after{display:inline-block;margin-top:-1px;margin-left:4px;width:11px;height:11px;background:currentColor;color:var(--vp-c-text-3);flex-shrink:0;--icon: url("data:image/svg+xml, %3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' %3E%3Cpath d='M0 0h24v24H0V0z' fill='none' /%3E%3Cpath d='M9 5v2h6.59L4 18.59 5.41 20 17 8.41V15h2V5H9z' /%3E%3C/svg%3E");-webkit-mask-image:var(--icon);mask-image:var(--icon)}.vp-external-link-icon:after{content:""}.external-link-icon-enabled :is(.vp-doc a[href*="://"],.vp-doc a[target=_blank]):after{content:"";color:currentColor}.vp-sponsor{border-radius:16px;overflow:hidden}.vp-sponsor.aside{border-radius:12px}.vp-sponsor-section+.vp-sponsor-section{margin-top:4px}.vp-sponsor-tier{margin:0 0 4px!important;text-align:center;letter-spacing:1px!important;line-height:24px;width:100%;font-weight:600;color:var(--vp-c-text-2);background-color:var(--vp-c-bg-soft)}.vp-sponsor.normal .vp-sponsor-tier{padding:13px 0 11px;font-size:14px}.vp-sponsor.aside .vp-sponsor-tier{padding:9px 0 7px;font-size:12px}.vp-sponsor-grid+.vp-sponsor-tier{margin-top:4px}.vp-sponsor-grid{display:flex;flex-wrap:wrap;gap:4px}.vp-sponsor-grid.xmini .vp-sponsor-grid-link{height:64px}.vp-sponsor-grid.xmini .vp-sponsor-grid-image{max-width:64px;max-height:22px}.vp-sponsor-grid.mini .vp-sponsor-grid-link{height:72px}.vp-sponsor-grid.mini .vp-sponsor-grid-image{max-width:96px;max-height:24px}.vp-sponsor-grid.small .vp-sponsor-grid-link{height:96px}.vp-sponsor-grid.small .vp-sponsor-grid-image{max-width:96px;max-height:24px}.vp-sponsor-grid.medium .vp-sponsor-grid-link{height:112px}.vp-sponsor-grid.medium .vp-sponsor-grid-image{max-width:120px;max-height:36px}.vp-sponsor-grid.big .vp-sponsor-grid-link{height:184px}.vp-sponsor-grid.big .vp-sponsor-grid-image{max-width:192px;max-height:56px}.vp-sponsor-grid[data-vp-grid="2"] .vp-sponsor-grid-item{width:calc((100% - 4px)/2)}.vp-sponsor-grid[data-vp-grid="3"] .vp-sponsor-grid-item{width:calc((100% - 4px * 2) / 3)}.vp-sponsor-grid[data-vp-grid="4"] .vp-sponsor-grid-item{width:calc((100% - 12px)/4)}.vp-sponsor-grid[data-vp-grid="5"] .vp-sponsor-grid-item{width:calc((100% - 16px)/5)}.vp-sponsor-grid[data-vp-grid="6"] .vp-sponsor-grid-item{width:calc((100% - 4px * 5) / 6)}.vp-sponsor-grid-item{flex-shrink:0;width:100%;background-color:var(--vp-c-bg-soft);transition:background-color .25s}.vp-sponsor-grid-item:hover{background-color:var(--vp-c-default-soft)}.vp-sponsor-grid-item:hover .vp-sponsor-grid-image{filter:grayscale(0) invert(0)}.vp-sponsor-grid-item.empty:hover{background-color:var(--vp-c-bg-soft)}.dark .vp-sponsor-grid-item:hover{background-color:var(--vp-c-white)}.dark .vp-sponsor-grid-item.empty:hover{background-color:var(--vp-c-bg-soft)}.vp-sponsor-grid-link{display:flex}.vp-sponsor-grid-box{display:flex;justify-content:center;align-items:center;width:100%}.vp-sponsor-grid-image{max-width:100%;filter:grayscale(1);transition:filter .25s}.dark .vp-sponsor-grid-image{filter:grayscale(1) invert(1)}.VPBadge{display:inline-block;margin-left:2px;border:1px solid transparent;border-radius:12px;padding:0 10px;line-height:22px;font-size:12px;font-weight:500;transform:translateY(-2px)}.VPBadge.small{padding:0 6px;line-height:18px;font-size:10px;transform:translateY(-8px)}.VPDocFooter .VPBadge{display:none}.vp-doc h1>.VPBadge{margin-top:4px;vertical-align:top}.vp-doc h2>.VPBadge{margin-top:3px;padding:0 8px;vertical-align:top}.vp-doc h3>.VPBadge{vertical-align:middle}.vp-doc h4>.VPBadge,.vp-doc h5>.VPBadge,.vp-doc h6>.VPBadge{vertical-align:middle;line-height:18px}.VPBadge.info{border-color:var(--vp-badge-info-border);color:var(--vp-badge-info-text);background-color:var(--vp-badge-info-bg)}.VPBadge.tip{border-color:var(--vp-badge-tip-border);color:var(--vp-badge-tip-text);background-color:var(--vp-badge-tip-bg)}.VPBadge.warning{border-color:var(--vp-badge-warning-border);color:var(--vp-badge-warning-text);background-color:var(--vp-badge-warning-bg)}.VPBadge.danger{border-color:var(--vp-badge-danger-border);color:var(--vp-badge-danger-text);background-color:var(--vp-badge-danger-bg)}.VPBackdrop[data-v-2090a59e]{position:fixed;top:0;right:0;bottom:0;left:0;z-index:var(--vp-z-index-backdrop);background:var(--vp-backdrop-bg-color);transition:opacity .5s}.VPBackdrop.fade-enter-from[data-v-2090a59e],.VPBackdrop.fade-leave-to[data-v-2090a59e]{opacity:0}.VPBackdrop.fade-leave-active[data-v-2090a59e]{transition-duration:.25s}@media (min-width: 1280px){.VPBackdrop[data-v-2090a59e]{display:none}}.NotFound[data-v-51bbc008]{padding:64px 24px 96px;text-align:center}@media (min-width: 768px){.NotFound[data-v-51bbc008]{padding:96px 32px 168px}}.code[data-v-51bbc008]{line-height:64px;font-size:64px;font-weight:600}.title[data-v-51bbc008]{padding-top:12px;letter-spacing:2px;line-height:20px;font-size:20px;font-weight:700}.divider[data-v-51bbc008]{margin:24px auto 18px;width:64px;height:1px;background-color:var(--vp-c-divider)}.quote[data-v-51bbc008]{margin:0 auto;max-width:256px;font-size:14px;font-weight:500;color:var(--vp-c-text-2)}.action[data-v-51bbc008]{padding-top:20px}.link[data-v-51bbc008]{display:inline-block;border:1px solid var(--vp-c-brand-1);border-radius:16px;padding:3px 16px;font-size:14px;font-weight:500;color:var(--vp-c-brand-1);transition:border-color .25s,color .25s}.link[data-v-51bbc008]:hover{border-color:var(--vp-c-brand-2);color:var(--vp-c-brand-2)}.root[data-v-a993366b]{position:relative;z-index:1}.nested[data-v-a993366b]{padding-right:16px;padding-left:16px}.outline-link[data-v-a993366b]{display:block;line-height:32px;font-size:14px;font-weight:400;color:var(--vp-c-text-2);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;transition:color .5s}.outline-link[data-v-a993366b]:hover,.outline-link.active[data-v-a993366b]{color:var(--vp-c-text-1);transition:color .25s}.outline-link.nested[data-v-a993366b]{padding-left:13px}.VPDocAsideOutline[data-v-154faa32]{display:none}.VPDocAsideOutline.has-outline[data-v-154faa32]{display:block}.content[data-v-154faa32]{position:relative;border-left:1px solid var(--vp-c-divider);padding-left:16px;font-size:13px;font-weight:500}.outline-marker[data-v-154faa32]{position:absolute;top:32px;left:-1px;z-index:0;opacity:0;width:2px;border-radius:2px;height:18px;background-color:var(--vp-c-brand-1);transition:top .25s cubic-bezier(0,1,.5,1),background-color .5s,opacity .25s}.outline-title[data-v-154faa32]{line-height:32px;font-size:14px;font-weight:600}.VPDocAside[data-v-c0d770e2]{display:flex;flex-direction:column;flex-grow:1}.spacer[data-v-c0d770e2]{flex-grow:1}.VPDocAside[data-v-c0d770e2] .spacer+.VPDocAsideSponsors,.VPDocAside[data-v-c0d770e2] .spacer+.VPDocAsideCarbonAds{margin-top:24px}.VPDocAside[data-v-c0d770e2] .VPDocAsideSponsors+.VPDocAsideCarbonAds{margin-top:16px}.VPLastUpdated[data-v-acf4bd3a]{line-height:24px;font-size:14px;font-weight:500;color:var(--vp-c-text-2)}@media (min-width: 640px){.VPLastUpdated[data-v-acf4bd3a]{line-height:32px;font-size:14px;font-weight:500}}.VPDocFooter[data-v-a287ad5f]{margin-top:64px}.edit-info[data-v-a287ad5f]{padding-bottom:18px}@media (min-width: 640px){.edit-info[data-v-a287ad5f]{display:flex;justify-content:space-between;align-items:center;padding-bottom:14px}}.edit-link-button[data-v-a287ad5f]{display:flex;align-items:center;border:0;line-height:32px;font-size:14px;font-weight:500;color:var(--vp-c-brand-1);transition:color .25s}.edit-link-button[data-v-a287ad5f]:hover{color:var(--vp-c-brand-2)}.edit-link-icon[data-v-a287ad5f]{margin-right:8px}.prev-next[data-v-a287ad5f]{border-top:1px solid var(--vp-c-divider);padding-top:24px;display:grid;grid-row-gap:8px}@media (min-width: 640px){.prev-next[data-v-a287ad5f]{grid-template-columns:repeat(2,1fr);grid-column-gap:16px}}.pager-link[data-v-a287ad5f]{display:block;border:1px solid var(--vp-c-divider);border-radius:8px;padding:11px 16px 13px;width:100%;height:100%;transition:border-color .25s}.pager-link[data-v-a287ad5f]:hover{border-color:var(--vp-c-brand-1)}.pager-link.next[data-v-a287ad5f]{margin-left:auto;text-align:right}.desc[data-v-a287ad5f]{display:block;line-height:20px;font-size:12px;font-weight:500;color:var(--vp-c-text-2)}.title[data-v-a287ad5f]{display:block;line-height:20px;font-size:14px;font-weight:500;color:var(--vp-c-brand-1);transition:color .25s}.VPDoc[data-v-f87ade32]{padding:32px 24px 96px;width:100%}@media (min-width: 768px){.VPDoc[data-v-f87ade32]{padding:48px 32px 128px}}@media (min-width: 960px){.VPDoc[data-v-f87ade32]{padding:48px 32px 0}.VPDoc:not(.has-sidebar) .container[data-v-f87ade32]{display:flex;justify-content:center;max-width:992px}.VPDoc:not(.has-sidebar) .content[data-v-f87ade32]{max-width:752px}}@media (min-width: 1280px){.VPDoc .container[data-v-f87ade32]{display:flex;justify-content:center}.VPDoc .aside[data-v-f87ade32]{display:block}}@media (min-width: 1440px){.VPDoc:not(.has-sidebar) .content[data-v-f87ade32]{max-width:784px}.VPDoc:not(.has-sidebar) .container[data-v-f87ade32]{max-width:1104px}}.container[data-v-f87ade32]{margin:0 auto;width:100%}.aside[data-v-f87ade32]{position:relative;display:none;order:2;flex-grow:1;padding-left:32px;width:100%;max-width:256px}.left-aside[data-v-f87ade32]{order:1;padding-left:unset;padding-right:32px}.aside-container[data-v-f87ade32]{position:fixed;top:0;padding-top:calc(var(--vp-nav-height) + var(--vp-layout-top-height, 0px) + var(--vp-doc-top-height, 0px) + 48px);width:224px;height:100vh;overflow-x:hidden;overflow-y:auto;scrollbar-width:none}.aside-container[data-v-f87ade32]::-webkit-scrollbar{display:none}.aside-curtain[data-v-f87ade32]{position:fixed;bottom:0;z-index:10;width:224px;height:32px;background:linear-gradient(transparent,var(--vp-c-bg) 70%)}.aside-content[data-v-f87ade32]{display:flex;flex-direction:column;min-height:calc(100vh - (var(--vp-nav-height) + var(--vp-layout-top-height, 0px) + 48px));padding-bottom:32px}.content[data-v-f87ade32]{position:relative;margin:0 auto;width:100%}@media (min-width: 960px){.content[data-v-f87ade32]{padding:0 32px 128px}}@media (min-width: 1280px){.content[data-v-f87ade32]{order:1;margin:0;min-width:640px}}.content-container[data-v-f87ade32]{margin:0 auto}.VPDoc.has-aside .content-container[data-v-f87ade32]{max-width:688px}.VPButton[data-v-913f79e0]{display:inline-block;border:1px solid transparent;text-align:center;font-weight:600;white-space:nowrap;transition:color .25s,border-color .25s,background-color .25s}.VPButton[data-v-913f79e0]:active{transition:color .1s,border-color .1s,background-color .1s}.VPButton.medium[data-v-913f79e0]{border-radius:20px;padding:0 20px;line-height:38px;font-size:14px}.VPButton.big[data-v-913f79e0]{border-radius:24px;padding:0 24px;line-height:46px;font-size:16px}.VPButton.brand[data-v-913f79e0]{border-color:var(--vp-button-brand-border);color:var(--vp-button-brand-text);background-color:var(--vp-button-brand-bg)}.VPButton.brand[data-v-913f79e0]:hover{border-color:var(--vp-button-brand-hover-border);color:var(--vp-button-brand-hover-text);background-color:var(--vp-button-brand-hover-bg)}.VPButton.brand[data-v-913f79e0]:active{border-color:var(--vp-button-brand-active-border);color:var(--vp-button-brand-active-text);background-color:var(--vp-button-brand-active-bg)}.VPButton.alt[data-v-913f79e0]{border-color:var(--vp-button-alt-border);color:var(--vp-button-alt-text);background-color:var(--vp-button-alt-bg)}.VPButton.alt[data-v-913f79e0]:hover{border-color:var(--vp-button-alt-hover-border);color:var(--vp-button-alt-hover-text);background-color:var(--vp-button-alt-hover-bg)}.VPButton.alt[data-v-913f79e0]:active{border-color:var(--vp-button-alt-active-border);color:var(--vp-button-alt-active-text);background-color:var(--vp-button-alt-active-bg)}.VPButton.sponsor[data-v-913f79e0]{border-color:var(--vp-button-sponsor-border);color:var(--vp-button-sponsor-text);background-color:var(--vp-button-sponsor-bg)}.VPButton.sponsor[data-v-913f79e0]:hover{border-color:var(--vp-button-sponsor-hover-border);color:var(--vp-button-sponsor-hover-text);background-color:var(--vp-button-sponsor-hover-bg)}.VPButton.sponsor[data-v-913f79e0]:active{border-color:var(--vp-button-sponsor-active-border);color:var(--vp-button-sponsor-active-text);background-color:var(--vp-button-sponsor-active-bg)}html:not(.dark) .VPImage.dark[data-v-e838cdb3]{display:none}.dark .VPImage.light[data-v-e838cdb3]{display:none}.VPHero[data-v-a8266bd2]{margin-top:calc((var(--vp-nav-height) + var(--vp-layout-top-height, 0px)) * -1);padding:calc(var(--vp-nav-height) + var(--vp-layout-top-height, 0px) + 48px) 24px 48px}@media (min-width: 640px){.VPHero[data-v-a8266bd2]{padding:calc(var(--vp-nav-height) + var(--vp-layout-top-height, 0px) + 80px) 48px 64px}}@media (min-width: 960px){.VPHero[data-v-a8266bd2]{padding:calc(var(--vp-nav-height) + var(--vp-layout-top-height, 0px) + 80px) 64px 64px}}.container[data-v-a8266bd2]{display:flex;flex-direction:column;margin:0 auto;max-width:1152px}@media (min-width: 960px){.container[data-v-a8266bd2]{flex-direction:row}}.main[data-v-a8266bd2]{position:relative;z-index:10;order:2;flex-grow:1;flex-shrink:0}.VPHero.has-image .container[data-v-a8266bd2]{text-align:center}@media (min-width: 960px){.VPHero.has-image .container[data-v-a8266bd2]{text-align:left}}@media (min-width: 960px){.main[data-v-a8266bd2]{order:1;width:calc((100% / 3) * 2)}.VPHero.has-image .main[data-v-a8266bd2]{max-width:592px}}.name[data-v-a8266bd2],.text[data-v-a8266bd2]{max-width:392px;letter-spacing:-.4px;line-height:40px;font-size:32px;font-weight:700;white-space:pre-wrap}.VPHero.has-image .name[data-v-a8266bd2],.VPHero.has-image .text[data-v-a8266bd2]{margin:0 auto}.name[data-v-a8266bd2]{color:var(--vp-home-hero-name-color)}.clip[data-v-a8266bd2]{background:var(--vp-home-hero-name-background);-webkit-background-clip:text;background-clip:text;-webkit-text-fill-color:var(--vp-home-hero-name-color)}@media (min-width: 640px){.name[data-v-a8266bd2],.text[data-v-a8266bd2]{max-width:576px;line-height:56px;font-size:48px}}@media (min-width: 960px){.name[data-v-a8266bd2],.text[data-v-a8266bd2]{line-height:64px;font-size:56px}.VPHero.has-image .name[data-v-a8266bd2],.VPHero.has-image .text[data-v-a8266bd2]{margin:0}}.tagline[data-v-a8266bd2]{padding-top:8px;max-width:392px;line-height:28px;font-size:18px;font-weight:500;white-space:pre-wrap;color:var(--vp-c-text-2)}.VPHero.has-image .tagline[data-v-a8266bd2]{margin:0 auto}@media (min-width: 640px){.tagline[data-v-a8266bd2]{padding-top:12px;max-width:576px;line-height:32px;font-size:20px}}@media (min-width: 960px){.tagline[data-v-a8266bd2]{line-height:36px;font-size:24px}.VPHero.has-image .tagline[data-v-a8266bd2]{margin:0}}.actions[data-v-a8266bd2]{display:flex;flex-wrap:wrap;margin:-6px;padding-top:24px}.VPHero.has-image .actions[data-v-a8266bd2]{justify-content:center}@media (min-width: 640px){.actions[data-v-a8266bd2]{padding-top:32px}}@media (min-width: 960px){.VPHero.has-image .actions[data-v-a8266bd2]{justify-content:flex-start}}.action[data-v-a8266bd2]{flex-shrink:0;padding:6px}.image[data-v-a8266bd2]{order:1;margin:-76px -24px -48px}@media (min-width: 640px){.image[data-v-a8266bd2]{margin:-108px -24px -48px}}@media (min-width: 960px){.image[data-v-a8266bd2]{flex-grow:1;order:2;margin:0;min-height:100%}}.image-container[data-v-a8266bd2]{position:relative;margin:0 auto;width:320px;height:320px}@media (min-width: 640px){.image-container[data-v-a8266bd2]{width:392px;height:392px}}@media (min-width: 960px){.image-container[data-v-a8266bd2]{display:flex;justify-content:center;align-items:center;width:100%;height:100%;transform:translate(-32px,-32px)}}.image-bg[data-v-a8266bd2]{position:absolute;top:50%;left:50%;border-radius:50%;width:192px;height:192px;background-image:var(--vp-home-hero-image-background-image);filter:var(--vp-home-hero-image-filter);transform:translate(-50%,-50%)}@media (min-width: 640px){.image-bg[data-v-a8266bd2]{width:256px;height:256px}}@media (min-width: 960px){.image-bg[data-v-a8266bd2]{width:320px;height:320px}}[data-v-a8266bd2] .image-src{position:absolute;top:50%;left:50%;max-width:192px;max-height:192px;transform:translate(-50%,-50%)}@media (min-width: 640px){[data-v-a8266bd2] .image-src{max-width:256px;max-height:256px}}@media (min-width: 960px){[data-v-a8266bd2] .image-src{max-width:320px;max-height:320px}}.VPFeature[data-v-b2767c9d]{display:block;border:1px solid var(--vp-c-bg-soft);border-radius:12px;height:100%;background-color:var(--vp-c-bg-soft);transition:border-color .25s,background-color .25s}.VPFeature.link[data-v-b2767c9d]:hover{border-color:var(--vp-c-brand-1)}.box[data-v-b2767c9d]{display:flex;flex-direction:column;padding:24px;height:100%}.box[data-v-b2767c9d]>.VPImage{margin-bottom:20px}.icon[data-v-b2767c9d]{display:flex;justify-content:center;align-items:center;margin-bottom:20px;border-radius:6px;background-color:var(--vp-c-default-soft);width:48px;height:48px;font-size:24px;transition:background-color .25s}.title[data-v-b2767c9d]{line-height:24px;font-size:16px;font-weight:600}.details[data-v-b2767c9d]{flex-grow:1;padding-top:8px;line-height:24px;font-size:14px;font-weight:500;color:var(--vp-c-text-2)}.link-text[data-v-b2767c9d]{padding-top:8px}.link-text-value[data-v-b2767c9d]{display:flex;align-items:center;font-size:14px;font-weight:500;color:var(--vp-c-brand-1)}.link-text-icon[data-v-b2767c9d]{margin-left:6px}.VPFeatures[data-v-364f1c1e]{position:relative;padding:0 24px}@media (min-width: 640px){.VPFeatures[data-v-364f1c1e]{padding:0 48px}}@media (min-width: 960px){.VPFeatures[data-v-364f1c1e]{padding:0 64px}}.container[data-v-364f1c1e]{margin:0 auto;max-width:1152px}.items[data-v-364f1c1e]{display:flex;flex-wrap:wrap;margin:-8px}.item[data-v-364f1c1e]{padding:8px;width:100%}@media (min-width: 640px){.item.grid-2[data-v-364f1c1e],.item.grid-4[data-v-364f1c1e],.item.grid-6[data-v-364f1c1e]{width:50%}}@media (min-width: 768px){.item.grid-2[data-v-364f1c1e],.item.grid-4[data-v-364f1c1e]{width:50%}.item.grid-3[data-v-364f1c1e],.item.grid-6[data-v-364f1c1e]{width:calc(100% / 3)}}@media (min-width: 960px){.item.grid-4[data-v-364f1c1e]{width:25%}}.container[data-v-ec979b25]{margin:auto;width:100%;max-width:1280px;padding:0 24px}@media (min-width: 640px){.container[data-v-ec979b25]{padding:0 48px}}@media (min-width: 960px){.container[data-v-ec979b25]{width:100%;padding:0 64px}}.vp-doc[data-v-ec979b25] .VPHomeSponsors,.vp-doc[data-v-ec979b25] .VPTeamPage{margin-left:var(--vp-offset, calc(50% - 50vw) );margin-right:var(--vp-offset, calc(50% - 50vw) )}.vp-doc[data-v-ec979b25] .VPHomeSponsors h2{border-top:none;letter-spacing:normal}.vp-doc[data-v-ec979b25] .VPHomeSponsors a,.vp-doc[data-v-ec979b25] .VPTeamPage a{text-decoration:none}.VPHome[data-v-30316261]{margin-bottom:96px}@media (min-width: 768px){.VPHome[data-v-30316261]{margin-bottom:128px}}.VPContent[data-v-cc09d6e0]{flex-grow:1;flex-shrink:0;margin:var(--vp-layout-top-height, 0px) auto 0;width:100%}.VPContent.is-home[data-v-cc09d6e0]{width:100%;max-width:100%}.VPContent.has-sidebar[data-v-cc09d6e0]{margin:0}@media (min-width: 960px){.VPContent[data-v-cc09d6e0]{padding-top:var(--vp-nav-height)}.VPContent.has-sidebar[data-v-cc09d6e0]{margin:var(--vp-layout-top-height, 0px) 0 0;padding-left:var(--vp-sidebar-width)}}@media (min-width: 1440px){.VPContent.has-sidebar[data-v-cc09d6e0]{padding-right:calc((100vw - var(--vp-layout-max-width)) / 2);padding-left:calc((100vw - var(--vp-layout-max-width)) / 2 + var(--vp-sidebar-width))}}.VPFooter[data-v-ed47955f]{position:relative;z-index:var(--vp-z-index-footer);border-top:1px solid var(--vp-c-gutter);padding:32px 24px;background-color:var(--vp-c-bg)}.VPFooter.has-sidebar[data-v-ed47955f]{display:none}.VPFooter[data-v-ed47955f] a{text-decoration-line:underline;text-underline-offset:2px;transition:color .25s}.VPFooter[data-v-ed47955f] a:hover{color:var(--vp-c-text-1)}@media (min-width: 768px){.VPFooter[data-v-ed47955f]{padding:32px}}.container[data-v-ed47955f]{margin:0 auto;max-width:var(--vp-layout-max-width);text-align:center}.message[data-v-ed47955f],.copyright[data-v-ed47955f]{line-height:24px;font-size:14px;font-weight:500;color:var(--vp-c-text-2)}.VPLocalNavOutlineDropdown[data-v-ebf966df]{padding:12px 20px 11px}@media (min-width: 960px){.VPLocalNavOutlineDropdown[data-v-ebf966df]{padding:12px 36px 11px}}.VPLocalNavOutlineDropdown button[data-v-ebf966df]{display:block;font-size:12px;font-weight:500;line-height:24px;color:var(--vp-c-text-2);transition:color .5s;position:relative}.VPLocalNavOutlineDropdown button[data-v-ebf966df]:hover{color:var(--vp-c-text-1);transition:color .25s}.VPLocalNavOutlineDropdown button.open[data-v-ebf966df]{color:var(--vp-c-text-1)}.icon[data-v-ebf966df]{display:inline-block;vertical-align:middle;margin-left:2px;font-size:14px;transform:rotate(0);transition:transform .25s}@media (min-width: 960px){.VPLocalNavOutlineDropdown button[data-v-ebf966df]{font-size:14px}.icon[data-v-ebf966df]{font-size:16px}}.open>.icon[data-v-ebf966df]{transform:rotate(90deg)}.items[data-v-ebf966df]{position:absolute;top:40px;right:16px;left:16px;display:grid;gap:1px;border:1px solid var(--vp-c-border);border-radius:8px;background-color:var(--vp-c-gutter);max-height:calc(var(--vp-vh, 100vh) - 86px);overflow:hidden auto;box-shadow:var(--vp-shadow-3)}@media (min-width: 960px){.items[data-v-ebf966df]{right:auto;left:calc(var(--vp-sidebar-width) + 32px);width:320px}}.header[data-v-ebf966df]{background-color:var(--vp-c-bg-soft)}.top-link[data-v-ebf966df]{display:block;padding:0 16px;line-height:48px;font-size:14px;font-weight:500;color:var(--vp-c-brand-1)}.outline[data-v-ebf966df]{padding:8px 0;background-color:var(--vp-c-bg-soft)}.flyout-enter-active[data-v-ebf966df]{transition:all .2s ease-out}.flyout-leave-active[data-v-ebf966df]{transition:all .15s ease-in}.flyout-enter-from[data-v-ebf966df],.flyout-leave-to[data-v-ebf966df]{opacity:0;transform:translateY(-16px)}.VPLocalNav[data-v-e758e1b7]{position:sticky;top:0;left:0;z-index:var(--vp-z-index-local-nav);border-bottom:1px solid var(--vp-c-gutter);padding-top:var(--vp-layout-top-height, 0px);width:100%;background-color:var(--vp-local-nav-bg-color)}.VPLocalNav.fixed[data-v-e758e1b7]{position:fixed}@media (min-width: 960px){.VPLocalNav[data-v-e758e1b7]{top:var(--vp-nav-height)}.VPLocalNav.has-sidebar[data-v-e758e1b7]{padding-left:var(--vp-sidebar-width)}.VPLocalNav.empty[data-v-e758e1b7]{display:none}}@media (min-width: 1280px){.VPLocalNav[data-v-e758e1b7]{display:none}}@media (min-width: 1440px){.VPLocalNav.has-sidebar[data-v-e758e1b7]{padding-left:calc((100vw - var(--vp-layout-max-width)) / 2 + var(--vp-sidebar-width))}}.container[data-v-e758e1b7]{display:flex;justify-content:space-between;align-items:center}.menu[data-v-e758e1b7]{display:flex;align-items:center;padding:12px 24px 11px;line-height:24px;font-size:12px;font-weight:500;color:var(--vp-c-text-2);transition:color .5s}.menu[data-v-e758e1b7]:hover{color:var(--vp-c-text-1);transition:color .25s}@media (min-width: 768px){.menu[data-v-e758e1b7]{padding:0 32px}}@media (min-width: 960px){.menu[data-v-e758e1b7]{display:none}}.menu-icon[data-v-e758e1b7]{margin-right:8px;font-size:14px}.VPOutlineDropdown[data-v-e758e1b7]{padding:12px 24px 11px}@media (min-width: 768px){.VPOutlineDropdown[data-v-e758e1b7]{padding:12px 32px 11px}}.VPSwitch[data-v-2ed556eb]{position:relative;border-radius:11px;display:block;width:40px;height:22px;flex-shrink:0;border:1px solid var(--vp-input-border-color);background-color:var(--vp-input-switch-bg-color);transition:border-color .25s!important}.VPSwitch[data-v-2ed556eb]:hover{border-color:var(--vp-c-brand-1)}.check[data-v-2ed556eb]{position:absolute;top:1px;left:1px;width:18px;height:18px;border-radius:50%;background-color:var(--vp-c-neutral-inverse);box-shadow:var(--vp-shadow-1);transition:transform .25s!important}.icon[data-v-2ed556eb]{position:relative;display:block;width:18px;height:18px;border-radius:50%;overflow:hidden}.icon[data-v-2ed556eb] [class^=vpi-]{position:absolute;top:3px;left:3px;width:12px;height:12px;color:var(--vp-c-text-2)}.dark .icon[data-v-2ed556eb] [class^=vpi-]{color:var(--vp-c-text-1);transition:opacity .25s!important}.sun[data-v-2994eab3]{opacity:1}.moon[data-v-2994eab3],.dark .sun[data-v-2994eab3]{opacity:0}.dark .moon[data-v-2994eab3]{opacity:1}.dark .VPSwitchAppearance[data-v-2994eab3] .check{transform:translate(18px)}.VPNavBarAppearance[data-v-407d5c63]{display:none}@media (min-width: 1280px){.VPNavBarAppearance[data-v-407d5c63]{display:flex;align-items:center}}.VPMenuGroup+.VPMenuLink[data-v-15160b25]{margin:12px -12px 0;border-top:1px solid var(--vp-c-divider);padding:12px 12px 0}.link[data-v-15160b25]{display:block;border-radius:6px;padding:0 12px;line-height:32px;font-size:14px;font-weight:500;color:var(--vp-c-text-1);white-space:nowrap;transition:background-color .25s,color .25s}.link[data-v-15160b25]:hover{color:var(--vp-c-brand-1);background-color:var(--vp-c-default-soft)}.link.active[data-v-15160b25]{color:var(--vp-c-brand-1)}.VPMenuGroup[data-v-8e34546a]{margin:12px -12px 0;border-top:1px solid var(--vp-c-divider);padding:12px 12px 0}.VPMenuGroup[data-v-8e34546a]:first-child{margin-top:0;border-top:0;padding-top:0}.VPMenuGroup+.VPMenuGroup[data-v-8e34546a]{margin-top:12px;border-top:1px solid var(--vp-c-divider)}.title[data-v-8e34546a]{padding:0 12px;line-height:32px;font-size:14px;font-weight:600;color:var(--vp-c-text-2);white-space:nowrap;transition:color .25s}.VPMenu[data-v-b71e5dd0]{border-radius:12px;padding:12px;min-width:128px;border:1px solid var(--vp-c-divider);background-color:var(--vp-c-bg-elv);box-shadow:var(--vp-shadow-3);transition:background-color .5s;max-height:calc(100vh - var(--vp-nav-height));overflow-y:auto}.VPMenu[data-v-b71e5dd0] .group{margin:0 -12px;padding:0 12px 12px}.VPMenu[data-v-b71e5dd0] .group+.group{border-top:1px solid var(--vp-c-divider);padding:11px 12px 12px}.VPMenu[data-v-b71e5dd0] .group:last-child{padding-bottom:0}.VPMenu[data-v-b71e5dd0] .group+.item{border-top:1px solid var(--vp-c-divider);padding:11px 16px 0}.VPMenu[data-v-b71e5dd0] .item{padding:0 16px;white-space:nowrap}.VPMenu[data-v-b71e5dd0] .label{flex-grow:1;line-height:28px;font-size:12px;font-weight:500;color:var(--vp-c-text-2);transition:color .5s}.VPMenu[data-v-b71e5dd0] .action{padding-left:24px}.VPFlyout[data-v-f1cced18]{position:relative}.VPFlyout[data-v-f1cced18]:hover{color:var(--vp-c-brand-1);transition:color .25s}.VPFlyout:hover .text[data-v-f1cced18]{color:var(--vp-c-text-2)}.VPFlyout:hover .icon[data-v-f1cced18]{fill:var(--vp-c-text-2)}.VPFlyout.active .text[data-v-f1cced18]{color:var(--vp-c-brand-1)}.VPFlyout.active:hover .text[data-v-f1cced18]{color:var(--vp-c-brand-2)}.button[aria-expanded=false]+.menu[data-v-f1cced18]{opacity:0;visibility:hidden;transform:translateY(0)}.VPFlyout:hover .menu[data-v-f1cced18],.button[aria-expanded=true]+.menu[data-v-f1cced18]{opacity:1;visibility:visible;transform:translateY(0)}.button[data-v-f1cced18]{display:flex;align-items:center;padding:0 12px;height:var(--vp-nav-height);color:var(--vp-c-text-1);transition:color .5s}.text[data-v-f1cced18]{display:flex;align-items:center;line-height:var(--vp-nav-height);font-size:14px;font-weight:500;color:var(--vp-c-text-1);transition:color .25s}.option-icon[data-v-f1cced18]{margin-right:0;font-size:16px}.text-icon[data-v-f1cced18]{margin-left:4px;font-size:14px}.icon[data-v-f1cced18]{font-size:20px;transition:fill .25s}.menu[data-v-f1cced18]{position:absolute;top:calc(var(--vp-nav-height) / 2 + 20px);right:0;opacity:0;visibility:hidden;transition:opacity .25s,visibility .25s,transform .25s}.VPSocialLink[data-v-1dde8092]{display:flex;justify-content:center;align-items:center;width:36px;height:36px;color:var(--vp-c-text-2);transition:color .5s}.VPSocialLink[data-v-1dde8092]:hover{color:var(--vp-c-text-1);transition:color .25s}.VPSocialLink[data-v-1dde8092]>svg,.VPSocialLink[data-v-1dde8092]>[class^=vpi-social-]{width:20px;height:20px;fill:currentColor}.VPSocialLinks[data-v-b299d3ce]{display:flex;justify-content:center}.VPNavBarExtra[data-v-d10923a3]{display:none;margin-right:-12px}@media (min-width: 768px){.VPNavBarExtra[data-v-d10923a3]{display:block}}@media (min-width: 1280px){.VPNavBarExtra[data-v-d10923a3]{display:none}}.trans-title[data-v-d10923a3]{padding:0 24px 0 12px;line-height:32px;font-size:14px;font-weight:700;color:var(--vp-c-text-1)}.item.appearance[data-v-d10923a3],.item.social-links[data-v-d10923a3]{display:flex;align-items:center;padding:0 12px}.item.appearance[data-v-d10923a3]{min-width:176px}.appearance-action[data-v-d10923a3]{margin-right:-2px}.social-links-list[data-v-d10923a3]{margin:-4px -8px}.VPNavBarHamburger[data-v-661d4f1a]{display:flex;justify-content:center;align-items:center;width:48px;height:var(--vp-nav-height)}@media (min-width: 768px){.VPNavBarHamburger[data-v-661d4f1a]{display:none}}.container[data-v-661d4f1a]{position:relative;width:16px;height:14px;overflow:hidden}.VPNavBarHamburger:hover .top[data-v-661d4f1a]{top:0;left:0;transform:translate(4px)}.VPNavBarHamburger:hover .middle[data-v-661d4f1a]{top:6px;left:0;transform:translate(0)}.VPNavBarHamburger:hover .bottom[data-v-661d4f1a]{top:12px;left:0;transform:translate(8px)}.VPNavBarHamburger.active .top[data-v-661d4f1a]{top:6px;transform:translate(0) rotate(225deg)}.VPNavBarHamburger.active .middle[data-v-661d4f1a]{top:6px;transform:translate(16px)}.VPNavBarHamburger.active .bottom[data-v-661d4f1a]{top:6px;transform:translate(0) rotate(135deg)}.VPNavBarHamburger.active:hover .top[data-v-661d4f1a],.VPNavBarHamburger.active:hover .middle[data-v-661d4f1a],.VPNavBarHamburger.active:hover .bottom[data-v-661d4f1a]{background-color:var(--vp-c-text-2);transition:top .25s,background-color .25s,transform .25s}.top[data-v-661d4f1a],.middle[data-v-661d4f1a],.bottom[data-v-661d4f1a]{position:absolute;width:16px;height:2px;background-color:var(--vp-c-text-1);transition:top .25s,background-color .5s,transform .25s}.top[data-v-661d4f1a]{top:0;left:0;transform:translate(0)}.middle[data-v-661d4f1a]{top:6px;left:0;transform:translate(8px)}.bottom[data-v-661d4f1a]{top:12px;left:0;transform:translate(4px)}.VPNavBarMenuLink[data-v-f334ebb6]{display:flex;align-items:center;padding:0 12px;line-height:var(--vp-nav-height);font-size:14px;font-weight:500;color:var(--vp-c-text-1);transition:color .25s}.VPNavBarMenuLink.active[data-v-f334ebb6],.VPNavBarMenuLink[data-v-f334ebb6]:hover{color:var(--vp-c-brand-1)}.VPNavBarMenu[data-v-d62dda7e]{display:none}@media (min-width: 768px){.VPNavBarMenu[data-v-d62dda7e]{display:flex}}/*! @docsearch/css 3.8.0 | MIT License | © Algolia, Inc. and contributors | https://docsearch.algolia.com */:root{--docsearch-primary-color:#5468ff;--docsearch-text-color:#1c1e21;--docsearch-spacing:12px;--docsearch-icon-stroke-width:1.4;--docsearch-highlight-color:var(--docsearch-primary-color);--docsearch-muted-color:#969faf;--docsearch-container-background:rgba(101,108,133,.8);--docsearch-logo-color:#5468ff;--docsearch-modal-width:560px;--docsearch-modal-height:600px;--docsearch-modal-background:#f5f6f7;--docsearch-modal-shadow:inset 1px 1px 0 0 hsla(0,0%,100%,.5),0 3px 8px 0 #555a64;--docsearch-searchbox-height:56px;--docsearch-searchbox-background:#ebedf0;--docsearch-searchbox-focus-background:#fff;--docsearch-searchbox-shadow:inset 0 0 0 2px var(--docsearch-primary-color);--docsearch-hit-height:56px;--docsearch-hit-color:#444950;--docsearch-hit-active-color:#fff;--docsearch-hit-background:#fff;--docsearch-hit-shadow:0 1px 3px 0 #d4d9e1;--docsearch-key-gradient:linear-gradient(-225deg,#d5dbe4,#f8f8f8);--docsearch-key-shadow:inset 0 -2px 0 0 #cdcde6,inset 0 0 1px 1px #fff,0 1px 2px 1px rgba(30,35,90,.4);--docsearch-key-pressed-shadow:inset 0 -2px 0 0 #cdcde6,inset 0 0 1px 1px #fff,0 1px 1px 0 rgba(30,35,90,.4);--docsearch-footer-height:44px;--docsearch-footer-background:#fff;--docsearch-footer-shadow:0 -1px 0 0 #e0e3e8,0 -3px 6px 0 rgba(69,98,155,.12)}html[data-theme=dark]{--docsearch-text-color:#f5f6f7;--docsearch-container-background:rgba(9,10,17,.8);--docsearch-modal-background:#15172a;--docsearch-modal-shadow:inset 1px 1px 0 0 #2c2e40,0 3px 8px 0 #000309;--docsearch-searchbox-background:#090a11;--docsearch-searchbox-focus-background:#000;--docsearch-hit-color:#bec3c9;--docsearch-hit-shadow:none;--docsearch-hit-background:#090a11;--docsearch-key-gradient:linear-gradient(-26.5deg,#565872,#31355b);--docsearch-key-shadow:inset 0 -2px 0 0 #282d55,inset 0 0 1px 1px #51577d,0 2px 2px 0 rgba(3,4,9,.3);--docsearch-key-pressed-shadow:inset 0 -2px 0 0 #282d55,inset 0 0 1px 1px #51577d,0 1px 1px 0 #0304094d;--docsearch-footer-background:#1e2136;--docsearch-footer-shadow:inset 0 1px 0 0 rgba(73,76,106,.5),0 -4px 8px 0 rgba(0,0,0,.2);--docsearch-logo-color:#fff;--docsearch-muted-color:#7f8497}.DocSearch-Button{align-items:center;background:var(--docsearch-searchbox-background);border:0;border-radius:40px;color:var(--docsearch-muted-color);cursor:pointer;display:flex;font-weight:500;height:36px;justify-content:space-between;margin:0 0 0 16px;padding:0 8px;-webkit-user-select:none;user-select:none}.DocSearch-Button:active,.DocSearch-Button:focus,.DocSearch-Button:hover{background:var(--docsearch-searchbox-focus-background);box-shadow:var(--docsearch-searchbox-shadow);color:var(--docsearch-text-color);outline:none}.DocSearch-Button-Container{align-items:center;display:flex}.DocSearch-Search-Icon{stroke-width:1.6}.DocSearch-Button .DocSearch-Search-Icon{color:var(--docsearch-text-color)}.DocSearch-Button-Placeholder{font-size:1rem;padding:0 12px 0 6px}.DocSearch-Button-Keys{display:flex;min-width:calc(40px + .8em)}.DocSearch-Button-Key{align-items:center;background:var(--docsearch-key-gradient);border:0;border-radius:3px;box-shadow:var(--docsearch-key-shadow);color:var(--docsearch-muted-color);display:flex;height:18px;justify-content:center;margin-right:.4em;padding:0 0 2px;position:relative;top:-1px;width:20px}.DocSearch-Button-Key--pressed{box-shadow:var(--docsearch-key-pressed-shadow);transform:translate3d(0,1px,0)}@media (max-width:768px){.DocSearch-Button-Keys,.DocSearch-Button-Placeholder{display:none}}.DocSearch--active{overflow:hidden!important}.DocSearch-Container,.DocSearch-Container *{box-sizing:border-box}.DocSearch-Container{background-color:var(--docsearch-container-background);height:100vh;left:0;position:fixed;top:0;width:100vw;z-index:200}.DocSearch-Container a{text-decoration:none}.DocSearch-Link{-webkit-appearance:none;-moz-appearance:none;appearance:none;background:none;border:0;color:var(--docsearch-highlight-color);cursor:pointer;font:inherit;margin:0;padding:0}.DocSearch-Modal{background:var(--docsearch-modal-background);border-radius:6px;box-shadow:var(--docsearch-modal-shadow);flex-direction:column;margin:60px auto auto;max-width:var(--docsearch-modal-width);position:relative}.DocSearch-SearchBar{display:flex;padding:var(--docsearch-spacing) var(--docsearch-spacing) 0}.DocSearch-Form{align-items:center;background:var(--docsearch-searchbox-focus-background);border-radius:4px;box-shadow:var(--docsearch-searchbox-shadow);display:flex;height:var(--docsearch-searchbox-height);margin:0;padding:0 var(--docsearch-spacing);position:relative;width:100%}.DocSearch-Input{-webkit-appearance:none;-moz-appearance:none;appearance:none;background:transparent;border:0;color:var(--docsearch-text-color);flex:1;font:inherit;font-size:1.2em;height:100%;outline:none;padding:0 0 0 8px;width:80%}.DocSearch-Input::placeholder{color:var(--docsearch-muted-color);opacity:1}.DocSearch-Input::-webkit-search-cancel-button,.DocSearch-Input::-webkit-search-decoration,.DocSearch-Input::-webkit-search-results-button,.DocSearch-Input::-webkit-search-results-decoration{display:none}.DocSearch-LoadingIndicator,.DocSearch-MagnifierLabel,.DocSearch-Reset{margin:0;padding:0}.DocSearch-MagnifierLabel,.DocSearch-Reset{align-items:center;color:var(--docsearch-highlight-color);display:flex;justify-content:center}.DocSearch-Container--Stalled .DocSearch-MagnifierLabel,.DocSearch-LoadingIndicator{display:none}.DocSearch-Container--Stalled .DocSearch-LoadingIndicator{align-items:center;color:var(--docsearch-highlight-color);display:flex;justify-content:center}@media screen and (prefers-reduced-motion:reduce){.DocSearch-Reset{animation:none;-webkit-appearance:none;-moz-appearance:none;appearance:none;background:none;border:0;border-radius:50%;color:var(--docsearch-icon-color);cursor:pointer;right:0;stroke-width:var(--docsearch-icon-stroke-width)}}.DocSearch-Reset{animation:fade-in .1s ease-in forwards;-webkit-appearance:none;-moz-appearance:none;appearance:none;background:none;border:0;border-radius:50%;color:var(--docsearch-icon-color);cursor:pointer;padding:2px;right:0;stroke-width:var(--docsearch-icon-stroke-width)}.DocSearch-Reset[hidden]{display:none}.DocSearch-Reset:hover{color:var(--docsearch-highlight-color)}.DocSearch-LoadingIndicator svg,.DocSearch-MagnifierLabel svg{height:24px;width:24px}.DocSearch-Cancel{display:none}.DocSearch-Dropdown{max-height:calc(var(--docsearch-modal-height) - var(--docsearch-searchbox-height) - var(--docsearch-spacing) - var(--docsearch-footer-height));min-height:var(--docsearch-spacing);overflow-y:auto;overflow-y:overlay;padding:0 var(--docsearch-spacing);scrollbar-color:var(--docsearch-muted-color) var(--docsearch-modal-background);scrollbar-width:thin}.DocSearch-Dropdown::-webkit-scrollbar{width:12px}.DocSearch-Dropdown::-webkit-scrollbar-track{background:transparent}.DocSearch-Dropdown::-webkit-scrollbar-thumb{background-color:var(--docsearch-muted-color);border:3px solid var(--docsearch-modal-background);border-radius:20px}.DocSearch-Dropdown ul{list-style:none;margin:0;padding:0}.DocSearch-Label{font-size:.75em;line-height:1.6em}.DocSearch-Help,.DocSearch-Label{color:var(--docsearch-muted-color)}.DocSearch-Help{font-size:.9em;margin:0;-webkit-user-select:none;user-select:none}.DocSearch-Title{font-size:1.2em}.DocSearch-Logo a{display:flex}.DocSearch-Logo svg{color:var(--docsearch-logo-color);margin-left:8px}.DocSearch-Hits:last-of-type{margin-bottom:24px}.DocSearch-Hits mark{background:none;color:var(--docsearch-highlight-color)}.DocSearch-HitsFooter{color:var(--docsearch-muted-color);display:flex;font-size:.85em;justify-content:center;margin-bottom:var(--docsearch-spacing);padding:var(--docsearch-spacing)}.DocSearch-HitsFooter a{border-bottom:1px solid;color:inherit}.DocSearch-Hit{border-radius:4px;display:flex;padding-bottom:4px;position:relative}@media screen and (prefers-reduced-motion:reduce){.DocSearch-Hit--deleting{transition:none}}.DocSearch-Hit--deleting{opacity:0;transition:all .25s linear}@media screen and (prefers-reduced-motion:reduce){.DocSearch-Hit--favoriting{transition:none}}.DocSearch-Hit--favoriting{transform:scale(0);transform-origin:top center;transition:all .25s linear;transition-delay:.25s}.DocSearch-Hit a{background:var(--docsearch-hit-background);border-radius:4px;box-shadow:var(--docsearch-hit-shadow);display:block;padding-left:var(--docsearch-spacing);width:100%}.DocSearch-Hit-source{background:var(--docsearch-modal-background);color:var(--docsearch-highlight-color);font-size:.85em;font-weight:600;line-height:32px;margin:0 -4px;padding:8px 4px 0;position:sticky;top:0;z-index:10}.DocSearch-Hit-Tree{color:var(--docsearch-muted-color);height:var(--docsearch-hit-height);opacity:.5;stroke-width:var(--docsearch-icon-stroke-width);width:24px}.DocSearch-Hit[aria-selected=true] a{background-color:var(--docsearch-highlight-color)}.DocSearch-Hit[aria-selected=true] mark{text-decoration:underline}.DocSearch-Hit-Container{align-items:center;color:var(--docsearch-hit-color);display:flex;flex-direction:row;height:var(--docsearch-hit-height);padding:0 var(--docsearch-spacing) 0 0}.DocSearch-Hit-icon{height:20px;width:20px}.DocSearch-Hit-action,.DocSearch-Hit-icon{color:var(--docsearch-muted-color);stroke-width:var(--docsearch-icon-stroke-width)}.DocSearch-Hit-action{align-items:center;display:flex;height:22px;width:22px}.DocSearch-Hit-action svg{display:block;height:18px;width:18px}.DocSearch-Hit-action+.DocSearch-Hit-action{margin-left:6px}.DocSearch-Hit-action-button{-webkit-appearance:none;-moz-appearance:none;appearance:none;background:none;border:0;border-radius:50%;color:inherit;cursor:pointer;padding:2px}svg.DocSearch-Hit-Select-Icon{display:none}.DocSearch-Hit[aria-selected=true] .DocSearch-Hit-Select-Icon{display:block}.DocSearch-Hit-action-button:focus,.DocSearch-Hit-action-button:hover{background:#0003;transition:background-color .1s ease-in}@media screen and (prefers-reduced-motion:reduce){.DocSearch-Hit-action-button:focus,.DocSearch-Hit-action-button:hover{transition:none}}.DocSearch-Hit-action-button:focus path,.DocSearch-Hit-action-button:hover path{fill:#fff}.DocSearch-Hit-content-wrapper{display:flex;flex:1 1 auto;flex-direction:column;font-weight:500;justify-content:center;line-height:1.2em;margin:0 8px;overflow-x:hidden;position:relative;text-overflow:ellipsis;white-space:nowrap;width:80%}.DocSearch-Hit-title{font-size:.9em}.DocSearch-Hit-path{color:var(--docsearch-muted-color);font-size:.75em}.DocSearch-Hit[aria-selected=true] .DocSearch-Hit-Tree,.DocSearch-Hit[aria-selected=true] .DocSearch-Hit-action,.DocSearch-Hit[aria-selected=true] .DocSearch-Hit-icon,.DocSearch-Hit[aria-selected=true] .DocSearch-Hit-path,.DocSearch-Hit[aria-selected=true] .DocSearch-Hit-text,.DocSearch-Hit[aria-selected=true] .DocSearch-Hit-title,.DocSearch-Hit[aria-selected=true] mark{color:var(--docsearch-hit-active-color)!important}@media screen and (prefers-reduced-motion:reduce){.DocSearch-Hit-action-button:focus,.DocSearch-Hit-action-button:hover{background:#0003;transition:none}}.DocSearch-ErrorScreen,.DocSearch-NoResults,.DocSearch-StartScreen{font-size:.9em;margin:0 auto;padding:36px 0;text-align:center;width:80%}.DocSearch-Screen-Icon{color:var(--docsearch-muted-color);padding-bottom:12px}.DocSearch-NoResults-Prefill-List{display:inline-block;padding-bottom:24px;text-align:left}.DocSearch-NoResults-Prefill-List ul{display:inline-block;padding:8px 0 0}.DocSearch-NoResults-Prefill-List li{list-style-position:inside;list-style-type:"» "}.DocSearch-Prefill{-webkit-appearance:none;-moz-appearance:none;appearance:none;background:none;border:0;border-radius:1em;color:var(--docsearch-highlight-color);cursor:pointer;display:inline-block;font-size:1em;font-weight:700;padding:0}.DocSearch-Prefill:focus,.DocSearch-Prefill:hover{outline:none;text-decoration:underline}.DocSearch-Footer{align-items:center;background:var(--docsearch-footer-background);border-radius:0 0 8px 8px;box-shadow:var(--docsearch-footer-shadow);display:flex;flex-direction:row-reverse;flex-shrink:0;height:var(--docsearch-footer-height);justify-content:space-between;padding:0 var(--docsearch-spacing);position:relative;-webkit-user-select:none;user-select:none;width:100%;z-index:300}.DocSearch-Commands{color:var(--docsearch-muted-color);display:flex;list-style:none;margin:0;padding:0}.DocSearch-Commands li{align-items:center;display:flex}.DocSearch-Commands li:not(:last-of-type){margin-right:.8em}.DocSearch-Commands-Key{align-items:center;background:var(--docsearch-key-gradient);border:0;border-radius:2px;box-shadow:var(--docsearch-key-shadow);color:var(--docsearch-muted-color);display:flex;height:18px;justify-content:center;margin-right:.4em;padding:0 0 1px;width:20px}.DocSearch-VisuallyHiddenForAccessibility{clip:rect(0 0 0 0);clip-path:inset(50%);height:1px;overflow:hidden;position:absolute;white-space:nowrap;width:1px}@media (max-width:768px){:root{--docsearch-spacing:10px;--docsearch-footer-height:40px}.DocSearch-Dropdown{height:100%}.DocSearch-Container{height:100vh;height:-webkit-fill-available;height:calc(var(--docsearch-vh, 1vh)*100);position:absolute}.DocSearch-Footer{border-radius:0;bottom:0;position:absolute}.DocSearch-Hit-content-wrapper{display:flex;position:relative;width:80%}.DocSearch-Modal{border-radius:0;box-shadow:none;height:100vh;height:-webkit-fill-available;height:calc(var(--docsearch-vh, 1vh)*100);margin:0;max-width:100%;width:100%}.DocSearch-Dropdown{max-height:calc(var(--docsearch-vh, 1vh)*100 - var(--docsearch-searchbox-height) - var(--docsearch-spacing) - var(--docsearch-footer-height))}.DocSearch-Cancel{-webkit-appearance:none;-moz-appearance:none;appearance:none;background:none;border:0;color:var(--docsearch-highlight-color);cursor:pointer;display:inline-block;flex:none;font:inherit;font-size:1em;font-weight:500;margin-left:var(--docsearch-spacing);outline:none;overflow:hidden;padding:0;-webkit-user-select:none;user-select:none;white-space:nowrap}.DocSearch-Commands,.DocSearch-Hit-Tree{display:none}}@keyframes fade-in{0%{opacity:0}to{opacity:1}}[class*=DocSearch]{--docsearch-primary-color: var(--vp-c-brand-1);--docsearch-highlight-color: var(--docsearch-primary-color);--docsearch-text-color: var(--vp-c-text-1);--docsearch-muted-color: var(--vp-c-text-2);--docsearch-searchbox-shadow: none;--docsearch-searchbox-background: transparent;--docsearch-searchbox-focus-background: transparent;--docsearch-key-gradient: transparent;--docsearch-key-shadow: none;--docsearch-modal-background: var(--vp-c-bg-soft);--docsearch-footer-background: var(--vp-c-bg)}.dark [class*=DocSearch]{--docsearch-modal-shadow: none;--docsearch-footer-shadow: none;--docsearch-logo-color: var(--vp-c-text-2);--docsearch-hit-background: var(--vp-c-default-soft);--docsearch-hit-color: var(--vp-c-text-2);--docsearch-hit-shadow: none}.DocSearch-Button{display:flex;justify-content:center;align-items:center;margin:0;padding:0;width:48px;height:55px;background:transparent;transition:border-color .25s}.DocSearch-Button:hover{background:transparent}.DocSearch-Button:focus{outline:1px dotted;outline:5px auto -webkit-focus-ring-color}.DocSearch-Button-Key--pressed{transform:none;box-shadow:none}.DocSearch-Button:focus:not(:focus-visible){outline:none!important}@media (min-width: 768px){.DocSearch-Button{justify-content:flex-start;border:1px solid transparent;border-radius:8px;padding:0 10px 0 12px;width:100%;height:40px;background-color:var(--vp-c-bg-alt)}.DocSearch-Button:hover{border-color:var(--vp-c-brand-1);background:var(--vp-c-bg-alt)}}.DocSearch-Button .DocSearch-Button-Container{display:flex;align-items:center}.DocSearch-Button .DocSearch-Search-Icon{position:relative;width:16px;height:16px;color:var(--vp-c-text-1);fill:currentColor;transition:color .5s}.DocSearch-Button:hover .DocSearch-Search-Icon{color:var(--vp-c-text-1)}@media (min-width: 768px){.DocSearch-Button .DocSearch-Search-Icon{top:1px;margin-right:8px;width:14px;height:14px;color:var(--vp-c-text-2)}}.DocSearch-Button .DocSearch-Button-Placeholder{display:none;margin-top:2px;padding:0 16px 0 0;font-size:13px;font-weight:500;color:var(--vp-c-text-2);transition:color .5s}.DocSearch-Button:hover .DocSearch-Button-Placeholder{color:var(--vp-c-text-1)}@media (min-width: 768px){.DocSearch-Button .DocSearch-Button-Placeholder{display:inline-block}}.DocSearch-Button .DocSearch-Button-Keys{direction:ltr;display:none;min-width:auto}@media (min-width: 768px){.DocSearch-Button .DocSearch-Button-Keys{display:flex;align-items:center}}.DocSearch-Button .DocSearch-Button-Key{display:block;margin:2px 0 0;border:1px solid var(--vp-c-divider);border-right:none;border-radius:4px 0 0 4px;padding-left:6px;min-width:0;width:auto;height:22px;line-height:22px;font-family:var(--vp-font-family-base);font-size:12px;font-weight:500;transition:color .5s,border-color .5s}.DocSearch-Button .DocSearch-Button-Key+.DocSearch-Button-Key{border-right:1px solid var(--vp-c-divider);border-left:none;border-radius:0 4px 4px 0;padding-left:2px;padding-right:6px}.DocSearch-Button .DocSearch-Button-Key:first-child{font-size:0!important}.DocSearch-Button .DocSearch-Button-Key:first-child:after{content:"Ctrl";font-size:12px;letter-spacing:normal;color:var(--docsearch-muted-color)}.mac .DocSearch-Button .DocSearch-Button-Key:first-child:after{content:"⌘"}.DocSearch-Button .DocSearch-Button-Key:first-child>*{display:none}.DocSearch-Search-Icon{--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' stroke-width='1.6' viewBox='0 0 20 20'%3E%3Cpath fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' d='m14.386 14.386 4.088 4.088-4.088-4.088A7.533 7.533 0 1 1 3.733 3.733a7.533 7.533 0 0 1 10.653 10.653z'/%3E%3C/svg%3E")}.VPNavBarSearch{display:flex;align-items:center}@media (min-width: 768px){.VPNavBarSearch{flex-grow:1;padding-left:24px}}@media (min-width: 960px){.VPNavBarSearch{padding-left:32px}}.dark .DocSearch-Footer{border-top:1px solid var(--vp-c-divider)}.DocSearch-Form{border:1px solid var(--vp-c-brand-1);background-color:var(--vp-c-white)}.dark .DocSearch-Form{background-color:var(--vp-c-default-soft)}.DocSearch-Screen-Icon>svg{margin:auto}.VPNavBarSocialLinks[data-v-05a069e5]{display:none}@media (min-width: 1280px){.VPNavBarSocialLinks[data-v-05a069e5]{display:flex;align-items:center}}.title[data-v-91ea8bb2]{display:flex;align-items:center;border-bottom:1px solid transparent;width:100%;height:var(--vp-nav-height);font-size:16px;font-weight:600;color:var(--vp-c-text-1);transition:opacity .25s}@media (min-width: 960px){.title[data-v-91ea8bb2]{flex-shrink:0}.VPNavBarTitle.has-sidebar .title[data-v-91ea8bb2]{border-bottom-color:var(--vp-c-divider)}}[data-v-91ea8bb2] .logo{margin-right:8px;height:var(--vp-nav-logo-height)}.VPNavBarTranslations[data-v-d986342a]{display:none}@media (min-width: 1280px){.VPNavBarTranslations[data-v-d986342a]{display:flex;align-items:center}}.title[data-v-d986342a]{padding:0 24px 0 12px;line-height:32px;font-size:14px;font-weight:700;color:var(--vp-c-text-1)}.VPNavBar[data-v-8c74a6bf]{position:relative;height:var(--vp-nav-height);pointer-events:none;white-space:nowrap;transition:background-color .25s}.VPNavBar.screen-open[data-v-8c74a6bf]{transition:none;background-color:var(--vp-nav-bg-color);border-bottom:1px solid var(--vp-c-divider)}.VPNavBar[data-v-8c74a6bf]:not(.home){background-color:var(--vp-nav-bg-color)}@media (min-width: 960px){.VPNavBar[data-v-8c74a6bf]:not(.home){background-color:transparent}.VPNavBar[data-v-8c74a6bf]:not(.has-sidebar):not(.home.top){background-color:var(--vp-nav-bg-color)}}.wrapper[data-v-8c74a6bf]{padding:0 8px 0 24px}@media (min-width: 768px){.wrapper[data-v-8c74a6bf]{padding:0 32px}}@media (min-width: 960px){.VPNavBar.has-sidebar .wrapper[data-v-8c74a6bf]{padding:0}}.container[data-v-8c74a6bf]{display:flex;justify-content:space-between;margin:0 auto;max-width:calc(var(--vp-layout-max-width) - 64px);height:var(--vp-nav-height);pointer-events:none}.container>.title[data-v-8c74a6bf],.container>.content[data-v-8c74a6bf]{pointer-events:none}.container[data-v-8c74a6bf] *{pointer-events:auto}@media (min-width: 960px){.VPNavBar.has-sidebar .container[data-v-8c74a6bf]{max-width:100%}}.title[data-v-8c74a6bf]{flex-shrink:0;height:calc(var(--vp-nav-height) - 1px);transition:background-color .5s}@media (min-width: 960px){.VPNavBar.has-sidebar .title[data-v-8c74a6bf]{position:absolute;top:0;left:0;z-index:2;padding:0 32px;width:var(--vp-sidebar-width);height:var(--vp-nav-height);background-color:transparent}}@media (min-width: 1440px){.VPNavBar.has-sidebar .title[data-v-8c74a6bf]{padding-left:max(32px,calc((100% - (var(--vp-layout-max-width) - 64px)) / 2));width:calc((100% - (var(--vp-layout-max-width) - 64px)) / 2 + var(--vp-sidebar-width) - 32px)}}.content[data-v-8c74a6bf]{flex-grow:1}@media (min-width: 960px){.VPNavBar.has-sidebar .content[data-v-8c74a6bf]{position:relative;z-index:1;padding-right:32px;padding-left:var(--vp-sidebar-width)}}@media (min-width: 1440px){.VPNavBar.has-sidebar .content[data-v-8c74a6bf]{padding-right:calc((100vw - var(--vp-layout-max-width)) / 2 + 32px);padding-left:calc((100vw - var(--vp-layout-max-width)) / 2 + var(--vp-sidebar-width))}}.content-body[data-v-8c74a6bf]{display:flex;justify-content:flex-end;align-items:center;height:var(--vp-nav-height);transition:background-color .5s}@media (min-width: 960px){.VPNavBar:not(.home.top) .content-body[data-v-8c74a6bf]{position:relative;background-color:var(--vp-nav-bg-color)}.VPNavBar:not(.has-sidebar):not(.home.top) .content-body[data-v-8c74a6bf]{background-color:transparent}}@media (max-width: 767px){.content-body[data-v-8c74a6bf]{column-gap:.5rem}}.menu+.translations[data-v-8c74a6bf]:before,.menu+.appearance[data-v-8c74a6bf]:before,.menu+.social-links[data-v-8c74a6bf]:before,.translations+.appearance[data-v-8c74a6bf]:before,.appearance+.social-links[data-v-8c74a6bf]:before{margin-right:8px;margin-left:8px;width:1px;height:24px;background-color:var(--vp-c-divider);content:""}.menu+.appearance[data-v-8c74a6bf]:before,.translations+.appearance[data-v-8c74a6bf]:before{margin-right:16px}.appearance+.social-links[data-v-8c74a6bf]:before{margin-left:16px}.social-links[data-v-8c74a6bf]{margin-right:-8px}.divider[data-v-8c74a6bf]{width:100%;height:1px}@media (min-width: 960px){.VPNavBar.has-sidebar .divider[data-v-8c74a6bf]{padding-left:var(--vp-sidebar-width)}}@media (min-width: 1440px){.VPNavBar.has-sidebar .divider[data-v-8c74a6bf]{padding-left:calc((100vw - var(--vp-layout-max-width)) / 2 + var(--vp-sidebar-width))}}.divider-line[data-v-8c74a6bf]{width:100%;height:1px;transition:background-color .5s}.VPNavBar:not(.home) .divider-line[data-v-8c74a6bf]{background-color:var(--vp-c-gutter)}@media (min-width: 960px){.VPNavBar:not(.home.top) .divider-line[data-v-8c74a6bf]{background-color:var(--vp-c-gutter)}.VPNavBar:not(.has-sidebar):not(.home.top) .divider[data-v-8c74a6bf]{background-color:var(--vp-c-gutter)}}.VPNavScreenAppearance[data-v-c279db8a]{display:flex;justify-content:space-between;align-items:center;border-radius:8px;padding:12px 14px 12px 16px;background-color:var(--vp-c-bg-soft)}.text[data-v-c279db8a]{line-height:24px;font-size:12px;font-weight:500;color:var(--vp-c-text-2)}.VPNavScreenMenuLink[data-v-9414c9d4]{display:block;border-bottom:1px solid var(--vp-c-divider);padding:12px 0 11px;line-height:24px;font-size:14px;font-weight:500;color:var(--vp-c-text-1);transition:border-color .25s,color .25s}.VPNavScreenMenuLink[data-v-9414c9d4]:hover{color:var(--vp-c-brand-1)}.VPNavScreenMenuGroupLink[data-v-893eacf4]{display:block;margin-left:12px;line-height:32px;font-size:14px;font-weight:400;color:var(--vp-c-text-1);transition:color .25s}.VPNavScreenMenuGroupLink[data-v-893eacf4]:hover{color:var(--vp-c-brand-1)}.VPNavScreenMenuGroupSection[data-v-420cc732]{display:block}.title[data-v-420cc732]{line-height:32px;font-size:13px;font-weight:700;color:var(--vp-c-text-2);transition:color .25s}.VPNavScreenMenuGroup[data-v-29d942ed]{border-bottom:1px solid var(--vp-c-divider);height:48px;overflow:hidden;transition:border-color .5s}.VPNavScreenMenuGroup .items[data-v-29d942ed]{visibility:hidden}.VPNavScreenMenuGroup.open .items[data-v-29d942ed]{visibility:visible}.VPNavScreenMenuGroup.open[data-v-29d942ed]{padding-bottom:10px;height:auto}.VPNavScreenMenuGroup.open .button[data-v-29d942ed]{padding-bottom:6px;color:var(--vp-c-brand-1)}.VPNavScreenMenuGroup.open .button-icon[data-v-29d942ed]{transform:rotate(45deg)}.button[data-v-29d942ed]{display:flex;justify-content:space-between;align-items:center;padding:12px 4px 11px 0;width:100%;line-height:24px;font-size:14px;font-weight:500;color:var(--vp-c-text-1);transition:color .25s}.button[data-v-29d942ed]:hover{color:var(--vp-c-brand-1)}.button-icon[data-v-29d942ed]{transition:transform .25s}.group[data-v-29d942ed]:first-child{padding-top:0}.group+.group[data-v-29d942ed],.group+.item[data-v-29d942ed]{padding-top:4px}.VPNavScreenTranslations[data-v-d906a767]{height:24px;overflow:hidden}.VPNavScreenTranslations.open[data-v-d906a767]{height:auto}.title[data-v-d906a767]{display:flex;align-items:center;font-size:14px;font-weight:500;color:var(--vp-c-text-1)}.icon[data-v-d906a767]{font-size:16px}.icon.lang[data-v-d906a767]{margin-right:8px}.icon.chevron[data-v-d906a767]{margin-left:4px}.list[data-v-d906a767]{padding:4px 0 0 24px}.link[data-v-d906a767]{line-height:32px;font-size:13px;color:var(--vp-c-text-1)}.VPNavScreen[data-v-852a870e]{position:fixed;top:calc(var(--vp-nav-height) + var(--vp-layout-top-height, 0px));right:0;bottom:0;left:0;padding:0 32px;width:100%;background-color:var(--vp-nav-screen-bg-color);overflow-y:auto;transition:background-color .25s;pointer-events:auto}.VPNavScreen.fade-enter-active[data-v-852a870e],.VPNavScreen.fade-leave-active[data-v-852a870e]{transition:opacity .25s}.VPNavScreen.fade-enter-active .container[data-v-852a870e],.VPNavScreen.fade-leave-active .container[data-v-852a870e]{transition:transform .25s ease}.VPNavScreen.fade-enter-from[data-v-852a870e],.VPNavScreen.fade-leave-to[data-v-852a870e]{opacity:0}.VPNavScreen.fade-enter-from .container[data-v-852a870e],.VPNavScreen.fade-leave-to .container[data-v-852a870e]{transform:translateY(-8px)}@media (min-width: 768px){.VPNavScreen[data-v-852a870e]{display:none}}.container[data-v-852a870e]{margin:0 auto;padding:24px 0 96px;max-width:288px}.menu+.translations[data-v-852a870e],.menu+.appearance[data-v-852a870e],.translations+.appearance[data-v-852a870e]{margin-top:24px}.menu+.social-links[data-v-852a870e]{margin-top:16px}.appearance+.social-links[data-v-852a870e]{margin-top:16px}.VPNav[data-v-1125fe0e]{position:relative;top:var(--vp-layout-top-height, 0px);left:0;z-index:var(--vp-z-index-nav);width:100%;pointer-events:none;transition:background-color .5s}@media (min-width: 960px){.VPNav[data-v-1125fe0e]{position:fixed}}.VPSidebarItem.level-0[data-v-877bfe94]{padding-bottom:24px}.VPSidebarItem.collapsed.level-0[data-v-877bfe94]{padding-bottom:10px}.item[data-v-877bfe94]{position:relative;display:flex;width:100%}.VPSidebarItem.collapsible>.item[data-v-877bfe94]{cursor:pointer}.indicator[data-v-877bfe94]{position:absolute;top:6px;bottom:6px;left:-17px;width:2px;border-radius:2px;transition:background-color .25s}.VPSidebarItem.level-2.is-active>.item>.indicator[data-v-877bfe94],.VPSidebarItem.level-3.is-active>.item>.indicator[data-v-877bfe94],.VPSidebarItem.level-4.is-active>.item>.indicator[data-v-877bfe94],.VPSidebarItem.level-5.is-active>.item>.indicator[data-v-877bfe94]{background-color:var(--vp-c-brand-1)}.link[data-v-877bfe94]{display:flex;align-items:center;flex-grow:1}.text[data-v-877bfe94]{flex-grow:1;padding:4px 0;line-height:24px;font-size:14px;transition:color .25s}.VPSidebarItem.level-0 .text[data-v-877bfe94]{font-weight:700;color:var(--vp-c-text-1)}.VPSidebarItem.level-1 .text[data-v-877bfe94],.VPSidebarItem.level-2 .text[data-v-877bfe94],.VPSidebarItem.level-3 .text[data-v-877bfe94],.VPSidebarItem.level-4 .text[data-v-877bfe94],.VPSidebarItem.level-5 .text[data-v-877bfe94]{font-weight:500;color:var(--vp-c-text-2)}.VPSidebarItem.level-0.is-link>.item>.link:hover .text[data-v-877bfe94],.VPSidebarItem.level-1.is-link>.item>.link:hover .text[data-v-877bfe94],.VPSidebarItem.level-2.is-link>.item>.link:hover .text[data-v-877bfe94],.VPSidebarItem.level-3.is-link>.item>.link:hover .text[data-v-877bfe94],.VPSidebarItem.level-4.is-link>.item>.link:hover .text[data-v-877bfe94],.VPSidebarItem.level-5.is-link>.item>.link:hover .text[data-v-877bfe94]{color:var(--vp-c-brand-1)}.VPSidebarItem.level-0.has-active>.item>.text[data-v-877bfe94],.VPSidebarItem.level-1.has-active>.item>.text[data-v-877bfe94],.VPSidebarItem.level-2.has-active>.item>.text[data-v-877bfe94],.VPSidebarItem.level-3.has-active>.item>.text[data-v-877bfe94],.VPSidebarItem.level-4.has-active>.item>.text[data-v-877bfe94],.VPSidebarItem.level-5.has-active>.item>.text[data-v-877bfe94],.VPSidebarItem.level-0.has-active>.item>.link>.text[data-v-877bfe94],.VPSidebarItem.level-1.has-active>.item>.link>.text[data-v-877bfe94],.VPSidebarItem.level-2.has-active>.item>.link>.text[data-v-877bfe94],.VPSidebarItem.level-3.has-active>.item>.link>.text[data-v-877bfe94],.VPSidebarItem.level-4.has-active>.item>.link>.text[data-v-877bfe94],.VPSidebarItem.level-5.has-active>.item>.link>.text[data-v-877bfe94]{color:var(--vp-c-text-1)}.VPSidebarItem.level-0.is-active>.item .link>.text[data-v-877bfe94],.VPSidebarItem.level-1.is-active>.item .link>.text[data-v-877bfe94],.VPSidebarItem.level-2.is-active>.item .link>.text[data-v-877bfe94],.VPSidebarItem.level-3.is-active>.item .link>.text[data-v-877bfe94],.VPSidebarItem.level-4.is-active>.item .link>.text[data-v-877bfe94],.VPSidebarItem.level-5.is-active>.item .link>.text[data-v-877bfe94]{color:var(--vp-c-brand-1)}.caret[data-v-877bfe94]{display:flex;justify-content:center;align-items:center;margin-right:-7px;width:32px;height:32px;color:var(--vp-c-text-3);cursor:pointer;transition:color .25s;flex-shrink:0}.item:hover .caret[data-v-877bfe94]{color:var(--vp-c-text-2)}.item:hover .caret[data-v-877bfe94]:hover{color:var(--vp-c-text-1)}.caret-icon[data-v-877bfe94]{font-size:18px;transform:rotate(90deg);transition:transform .25s}.VPSidebarItem.collapsed .caret-icon[data-v-877bfe94]{transform:rotate(0)}.VPSidebarItem.level-1 .items[data-v-877bfe94],.VPSidebarItem.level-2 .items[data-v-877bfe94],.VPSidebarItem.level-3 .items[data-v-877bfe94],.VPSidebarItem.level-4 .items[data-v-877bfe94],.VPSidebarItem.level-5 .items[data-v-877bfe94]{border-left:1px solid var(--vp-c-divider);padding-left:16px}.VPSidebarItem.collapsed .items[data-v-877bfe94]{display:none}.no-transition[data-v-71286ee5] .caret-icon{transition:none}.group+.group[data-v-71286ee5]{border-top:1px solid var(--vp-c-divider);padding-top:10px}@media (min-width: 960px){.group[data-v-71286ee5]{padding-top:10px;width:calc(var(--vp-sidebar-width) - 64px)}}.VPSidebar[data-v-6b9869d7]{position:fixed;top:var(--vp-layout-top-height, 0px);bottom:0;left:0;z-index:var(--vp-z-index-sidebar);padding:32px 32px 96px;width:calc(100vw - 64px);max-width:320px;background-color:var(--vp-sidebar-bg-color);opacity:0;box-shadow:var(--vp-c-shadow-3);overflow-x:hidden;overflow-y:auto;transform:translate(-100%);transition:opacity .5s,transform .25s ease;overscroll-behavior:contain}.VPSidebar.open[data-v-6b9869d7]{opacity:1;visibility:visible;transform:translate(0);transition:opacity .25s,transform .5s cubic-bezier(.19,1,.22,1)}.dark .VPSidebar[data-v-6b9869d7]{box-shadow:var(--vp-shadow-1)}@media (min-width: 960px){.VPSidebar[data-v-6b9869d7]{padding-top:var(--vp-nav-height);width:var(--vp-sidebar-width);max-width:100%;background-color:var(--vp-sidebar-bg-color);opacity:1;visibility:visible;box-shadow:none;transform:translate(0)}}@media (min-width: 1440px){.VPSidebar[data-v-6b9869d7]{padding-left:max(32px,calc((100% - (var(--vp-layout-max-width) - 64px)) / 2));width:calc((100% - (var(--vp-layout-max-width) - 64px)) / 2 + var(--vp-sidebar-width) - 32px)}}@media (min-width: 960px){.curtain[data-v-6b9869d7]{position:sticky;top:-64px;left:0;z-index:1;margin-top:calc(var(--vp-nav-height) * -1);margin-right:-32px;margin-left:-32px;height:var(--vp-nav-height);background-color:var(--vp-sidebar-bg-color)}}.nav[data-v-6b9869d7]{outline:0}.VPSkipLink[data-v-a06310ac]{top:8px;left:8px;padding:8px 16px;z-index:999;border-radius:8px;font-size:12px;font-weight:700;text-decoration:none;color:var(--vp-c-brand-1);box-shadow:var(--vp-shadow-3);background-color:var(--vp-c-bg)}.VPSkipLink[data-v-a06310ac]:focus{height:auto;width:auto;clip:auto;clip-path:none}@media (min-width: 1280px){.VPSkipLink[data-v-a06310ac]{top:14px;left:16px}}.Layout[data-v-39b851b6]{display:flex;flex-direction:column;min-height:100vh}.VPHomeSponsors[data-v-23565cf2]{border-top:1px solid var(--vp-c-gutter);padding-top:88px!important}.VPHomeSponsors[data-v-23565cf2]{margin:96px 0}@media (min-width: 768px){.VPHomeSponsors[data-v-23565cf2]{margin:128px 0}}.VPHomeSponsors[data-v-23565cf2]{padding:0 24px}@media (min-width: 768px){.VPHomeSponsors[data-v-23565cf2]{padding:0 48px}}@media (min-width: 960px){.VPHomeSponsors[data-v-23565cf2]{padding:0 64px}}.container[data-v-23565cf2]{margin:0 auto;max-width:1152px}.love[data-v-23565cf2]{margin:0 auto;width:fit-content;font-size:28px;color:var(--vp-c-text-3)}.icon[data-v-23565cf2]{display:inline-block}.message[data-v-23565cf2]{margin:0 auto;padding-top:10px;max-width:320px;text-align:center;line-height:24px;font-size:16px;font-weight:500;color:var(--vp-c-text-2)}.sponsors[data-v-23565cf2]{padding-top:32px}.action[data-v-23565cf2]{padding-top:40px;text-align:center}.VPTeamPage[data-v-5b040eb5]{margin:96px 0}@media (min-width: 768px){.VPTeamPage[data-v-5b040eb5]{margin:128px 0}}.VPHome .VPTeamPageTitle[data-v-5b040eb5-s]{border-top:1px solid var(--vp-c-gutter);padding-top:88px!important}.VPTeamPageSection+.VPTeamPageSection[data-v-5b040eb5-s],.VPTeamMembers+.VPTeamPageSection[data-v-5b040eb5-s]{margin-top:64px}.VPTeamMembers+.VPTeamMembers[data-v-5b040eb5-s]{margin-top:24px}@media (min-width: 768px){.VPTeamPageTitle+.VPTeamPageSection[data-v-5b040eb5-s]{margin-top:16px}.VPTeamPageSection+.VPTeamPageSection[data-v-5b040eb5-s],.VPTeamMembers+.VPTeamPageSection[data-v-5b040eb5-s]{margin-top:96px}}.VPTeamMembers[data-v-5b040eb5-s]{padding:0 24px}@media (min-width: 768px){.VPTeamMembers[data-v-5b040eb5-s]{padding:0 48px}}@media (min-width: 960px){.VPTeamMembers[data-v-5b040eb5-s]{padding:0 64px}}.VPTeamPageTitle[data-v-ad23ff56]{padding:48px 32px;text-align:center}@media (min-width: 768px){.VPTeamPageTitle[data-v-ad23ff56]{padding:64px 48px 48px}}@media (min-width: 960px){.VPTeamPageTitle[data-v-ad23ff56]{padding:80px 64px 48px}}.title[data-v-ad23ff56]{letter-spacing:0;line-height:44px;font-size:36px;font-weight:500}@media (min-width: 768px){.title[data-v-ad23ff56]{letter-spacing:-.5px;line-height:56px;font-size:48px}}.lead[data-v-ad23ff56]{margin:0 auto;max-width:512px;padding-top:12px;line-height:24px;font-size:16px;font-weight:500;color:var(--vp-c-text-2)}@media (min-width: 768px){.lead[data-v-ad23ff56]{max-width:592px;letter-spacing:.15px;line-height:28px;font-size:20px}}.VPTeamPageSection[data-v-9218f418]{padding:0 32px}@media (min-width: 768px){.VPTeamPageSection[data-v-9218f418]{padding:0 48px}}@media (min-width: 960px){.VPTeamPageSection[data-v-9218f418]{padding:0 64px}}.title[data-v-9218f418]{position:relative;margin:0 auto;max-width:1152px;text-align:center;color:var(--vp-c-text-2)}.title-line[data-v-9218f418]{position:absolute;top:16px;left:0;width:100%;height:1px;background-color:var(--vp-c-divider)}.title-text[data-v-9218f418]{position:relative;display:inline-block;padding:0 24px;letter-spacing:0;line-height:32px;font-size:20px;font-weight:500;background-color:var(--vp-c-bg)}.lead[data-v-9218f418]{margin:0 auto;max-width:480px;padding-top:12px;text-align:center;line-height:24px;font-size:16px;font-weight:500;color:var(--vp-c-text-2)}.members[data-v-9218f418]{padding-top:40px}.VPTeamMembersItem[data-v-1ec950c8]{display:flex;flex-direction:column;gap:2px;border-radius:12px;width:100%;height:100%;overflow:hidden}.VPTeamMembersItem.small .profile[data-v-1ec950c8]{padding:32px}.VPTeamMembersItem.small .data[data-v-1ec950c8]{padding-top:20px}.VPTeamMembersItem.small .avatar[data-v-1ec950c8]{width:64px;height:64px}.VPTeamMembersItem.small .name[data-v-1ec950c8]{line-height:24px;font-size:16px}.VPTeamMembersItem.small .affiliation[data-v-1ec950c8]{padding-top:4px;line-height:20px;font-size:14px}.VPTeamMembersItem.small .desc[data-v-1ec950c8]{padding-top:12px;line-height:20px;font-size:14px}.VPTeamMembersItem.small .links[data-v-1ec950c8]{margin:0 -16px -20px;padding:10px 0 0}.VPTeamMembersItem.medium .profile[data-v-1ec950c8]{padding:48px 32px}.VPTeamMembersItem.medium .data[data-v-1ec950c8]{padding-top:24px;text-align:center}.VPTeamMembersItem.medium .avatar[data-v-1ec950c8]{width:96px;height:96px}.VPTeamMembersItem.medium .name[data-v-1ec950c8]{letter-spacing:.15px;line-height:28px;font-size:20px}.VPTeamMembersItem.medium .affiliation[data-v-1ec950c8]{padding-top:4px;font-size:16px}.VPTeamMembersItem.medium .desc[data-v-1ec950c8]{padding-top:16px;max-width:288px;font-size:16px}.VPTeamMembersItem.medium .links[data-v-1ec950c8]{margin:0 -16px -12px;padding:16px 12px 0}.profile[data-v-1ec950c8]{flex-grow:1;background-color:var(--vp-c-bg-soft)}.data[data-v-1ec950c8]{text-align:center}.avatar[data-v-1ec950c8]{position:relative;flex-shrink:0;margin:0 auto;border-radius:50%;box-shadow:var(--vp-shadow-3)}.avatar-img[data-v-1ec950c8]{position:absolute;top:0;right:0;bottom:0;left:0;border-radius:50%;object-fit:cover}.name[data-v-1ec950c8]{margin:0;font-weight:600}.affiliation[data-v-1ec950c8]{margin:0;font-weight:500;color:var(--vp-c-text-2)}.org.link[data-v-1ec950c8]{color:var(--vp-c-text-2);transition:color .25s}.org.link[data-v-1ec950c8]:hover{color:var(--vp-c-brand-1)}.desc[data-v-1ec950c8]{margin:0 auto}.desc[data-v-1ec950c8] a{font-weight:500;color:var(--vp-c-brand-1);text-decoration-style:dotted;transition:color .25s}.links[data-v-1ec950c8]{display:flex;justify-content:center;height:56px}.sp-link[data-v-1ec950c8]{display:flex;justify-content:center;align-items:center;text-align:center;padding:16px;font-size:14px;font-weight:500;color:var(--vp-c-sponsor);background-color:var(--vp-c-bg-soft);transition:color .25s,background-color .25s}.sp .sp-link.link[data-v-1ec950c8]:hover,.sp .sp-link.link[data-v-1ec950c8]:focus{outline:none;color:var(--vp-c-white);background-color:var(--vp-c-sponsor)}.sp-icon[data-v-1ec950c8]{margin-right:8px;font-size:16px}.VPTeamMembers.small .container[data-v-73ffef7d]{grid-template-columns:repeat(auto-fit,minmax(224px,1fr))}.VPTeamMembers.small.count-1 .container[data-v-73ffef7d]{max-width:276px}.VPTeamMembers.small.count-2 .container[data-v-73ffef7d]{max-width:576px}.VPTeamMembers.small.count-3 .container[data-v-73ffef7d]{max-width:876px}.VPTeamMembers.medium .container[data-v-73ffef7d]{grid-template-columns:repeat(auto-fit,minmax(256px,1fr))}@media (min-width: 375px){.VPTeamMembers.medium .container[data-v-73ffef7d]{grid-template-columns:repeat(auto-fit,minmax(288px,1fr))}}.VPTeamMembers.medium.count-1 .container[data-v-73ffef7d]{max-width:368px}.VPTeamMembers.medium.count-2 .container[data-v-73ffef7d]{max-width:760px}.container[data-v-73ffef7d]{display:grid;gap:24px;margin:0 auto;max-width:1152px}.vp-doc div.fold[class*=language-]{overflow:unset;margin-bottom:var(--codeblocks-margin-bottom)}.vp-doc div.fold[class*=language-]>.line-numbers-wrapper{overflow:hidden}.vp-doc div.fold[class*=language-]>.codeblocks-mask{display:block;position:absolute;left:0;bottom:0;height:48px;width:100%;z-index:9;pointer-events:none}.vp-doc div.fold[class*=language-]>.fold-btn{display:flex;position:absolute;left:0;bottom:-36px;height:36px;width:100%;z-index:9;border-radius:0 0 8px 8px;cursor:pointer;-webkit-user-select:none;user-select:none;justify-content:center;align-items:center}.vp-doc div.fold[class*=language-]>.fold-btn>svg.fold-btn-icon{animation:float1 infinite .8s}.vp-doc div.fold[class*=language-]>.fold-btn>svg.fold-btn-icon.turn{animation:float2 infinite .8s}@keyframes float1{0%{transform:translateY(0)}50%{transform:translateY(-5px)}to{transform:translateY(0)}}@keyframes float2{0%{transform:translateY(0) rotate(180deg)}50%{transform:translateY(-5px) rotate(180deg)}to{transform:translateY(0) rotate(180deg)}}.vp-doc pre.shiki{scrollbar-width:auto!important;scrollbar-color:rgba(0,0,0,0) rgba(0,0,0,0)!important}.vp-doc pre.shiki::-webkit-scrollbar{width:4px!important;height:4px!important;background-color:#0000}.vp-doc pre.shiki::-webkit-scrollbar-thumb{height:10px!important;outline-offset:0!important;outline:unset!important;border-radius:2px!important;border:1px rgba(0,0,0,0) solid!important;background-color:#0000!important}.vp-doc pre.shiki::-webkit-scrollbar-thumb:hover{height:10px!important;border-radius:2px!important;background-color:#0000!important}.vp-doc pre.shiki::-webkit-scrollbar-track-piece{-webkit-border-radius:0!important;background-color:#0000!important}.vp-doc pre.shiki::-webkit-scrollbar-track{right:0!important;background-color:#0000!important}.vp-doc pre.shiki::-webkit-scrollbar-button{height:4px!important;width:4px!important;background-color:#0000!important}.vp-doc pre.shiki::-webkit-scrollbar-corner{background-color:#0000!important}:root{--vp-c-default-1: var(--vp-c-gray-1);--vp-c-default-2: var(--vp-c-gray-2);--vp-c-default-3: var(--vp-c-gray-3);--vp-c-default-soft: var(--vp-c-gray-soft);--vp-c-brand-1: var(--vp-c-indigo-1);--vp-c-brand-2: var(--vp-c-indigo-2);--vp-c-brand-3: var(--vp-c-indigo-3);--vp-c-brand-soft: var(--vp-c-indigo-soft);--vp-c-tip-1: var(--vp-c-brand-1);--vp-c-tip-2: var(--vp-c-brand-2);--vp-c-tip-3: var(--vp-c-brand-3);--vp-c-tip-soft: var(--vp-c-brand-soft);--vp-c-warning-1: var(--vp-c-yellow-1);--vp-c-warning-2: var(--vp-c-yellow-2);--vp-c-warning-3: var(--vp-c-yellow-3);--vp-c-warning-soft: var(--vp-c-yellow-soft);--vp-c-danger-1: var(--vp-c-red-1);--vp-c-danger-2: var(--vp-c-red-2);--vp-c-danger-3: var(--vp-c-red-3);--vp-c-danger-soft: var(--vp-c-red-soft)}:root{--vp-button-brand-border: transparent;--vp-button-brand-text: var(--vp-c-white);--vp-button-brand-bg: var(--vp-c-brand-3);--vp-button-brand-hover-border: transparent;--vp-button-brand-hover-text: var(--vp-c-white);--vp-button-brand-hover-bg: var(--vp-c-brand-2);--vp-button-brand-active-border: transparent;--vp-button-brand-active-text: var(--vp-c-white);--vp-button-brand-active-bg: var(--vp-c-brand-1)}:root{--vp-home-hero-name-color: transparent;--vp-home-hero-name-background: -webkit-linear-gradient( 120deg, #bd34fe 30%, #41d1ff );--vp-home-hero-image-background-image: linear-gradient( -45deg, #bd34fe 50%, #47caff 50% );--vp-home-hero-image-filter: blur(44px)}@media (min-width: 640px){:root{--vp-home-hero-image-filter: blur(56px)}}@media (min-width: 960px){:root{--vp-home-hero-image-filter: blur(68px)}}:root{--vp-custom-block-tip-border: transparent;--vp-custom-block-tip-text: var(--vp-c-text-1);--vp-custom-block-tip-bg: var(--vp-c-brand-soft);--vp-custom-block-tip-code-bg: var(--vp-c-brand-soft)}.DocSearch{--docsearch-primary-color: var(--vp-c-brand-1) !important}*,:before,:after{--un-rotate:0;--un-rotate-x:0;--un-rotate-y:0;--un-rotate-z:0;--un-scale-x:1;--un-scale-y:1;--un-scale-z:1;--un-skew-x:0;--un-skew-y:0;--un-translate-x:0;--un-translate-y:0;--un-translate-z:0;--un-pan-x: ;--un-pan-y: ;--un-pinch-zoom: ;--un-scroll-snap-strictness:proximity;--un-ordinal: ;--un-slashed-zero: ;--un-numeric-figure: ;--un-numeric-spacing: ;--un-numeric-fraction: ;--un-border-spacing-x:0;--un-border-spacing-y:0;--un-ring-offset-shadow:0 0 rgb(0 0 0 / 0);--un-ring-shadow:0 0 rgb(0 0 0 / 0);--un-shadow-inset: ;--un-shadow:0 0 rgb(0 0 0 / 0);--un-ring-inset: ;--un-ring-offset-width:0px;--un-ring-offset-color:#fff;--un-ring-width:0px;--un-ring-color:rgb(147 197 253 / .5);--un-blur: ;--un-brightness: ;--un-contrast: ;--un-drop-shadow: ;--un-grayscale: ;--un-hue-rotate: ;--un-invert: ;--un-saturate: ;--un-sepia: ;--un-backdrop-blur: ;--un-backdrop-brightness: ;--un-backdrop-contrast: ;--un-backdrop-grayscale: ;--un-backdrop-hue-rotate: ;--un-backdrop-invert: ;--un-backdrop-opacity: ;--un-backdrop-saturate: ;--un-backdrop-sepia: }::backdrop{--un-rotate:0;--un-rotate-x:0;--un-rotate-y:0;--un-rotate-z:0;--un-scale-x:1;--un-scale-y:1;--un-scale-z:1;--un-skew-x:0;--un-skew-y:0;--un-translate-x:0;--un-translate-y:0;--un-translate-z:0;--un-pan-x: ;--un-pan-y: ;--un-pinch-zoom: ;--un-scroll-snap-strictness:proximity;--un-ordinal: ;--un-slashed-zero: ;--un-numeric-figure: ;--un-numeric-spacing: ;--un-numeric-fraction: ;--un-border-spacing-x:0;--un-border-spacing-y:0;--un-ring-offset-shadow:0 0 rgb(0 0 0 / 0);--un-ring-shadow:0 0 rgb(0 0 0 / 0);--un-shadow-inset: ;--un-shadow:0 0 rgb(0 0 0 / 0);--un-ring-inset: ;--un-ring-offset-width:0px;--un-ring-offset-color:#fff;--un-ring-width:0px;--un-ring-color:rgb(147 197 253 / .5);--un-blur: ;--un-brightness: ;--un-contrast: ;--un-drop-shadow: ;--un-grayscale: ;--un-hue-rotate: ;--un-invert: ;--un-saturate: ;--un-sepia: ;--un-backdrop-blur: ;--un-backdrop-brightness: ;--un-backdrop-contrast: ;--un-backdrop-grayscale: ;--un-backdrop-hue-rotate: ;--un-backdrop-invert: ;--un-backdrop-opacity: ;--un-backdrop-saturate: ;--un-backdrop-sepia: }.i-logos-authy{background:url("data:image/svg+xml;utf8,%3Csvg viewBox='0 0 256 256' display='inline-block' vertical-align='middle' width='1.2em' height='1.2em' xmlns='http://www.w3.org/2000/svg' %3E%3Cpath fill='%23F22E46' d='M256 127.998C256 198.696 198.694 256 127.997 256C57.304 256 0 198.696 0 127.998C0 57.305 57.304 0 127.997 0C198.694 0 256 57.305 256 127.998'/%3E%3Cpath fill='%23FFF' d='m117.024 100.89l30.691 30.68c4.43 4.436 11.623 4.436 16.064 0c4.431-4.435 4.441-11.622 0-16.058L133.086 84.82c-21.961-21.966-57.455-22.32-79.882-1.116a10 10 0 0 0-.605.548c-.098.098-.178.202-.275.29c-.1.096-.202.182-.297.278a9 9 0 0 0-.54.597c-21.215 22.437-20.85 57.932 1.113 79.897L83.292 196c4.44 4.433 11.623 4.433 16.062 0c4.442-4.437 4.442-11.633.011-16.06l-30.693-30.691c-13.398-13.393-13.488-35.129-.278-48.637c13.506-13.21 35.23-13.114 48.63.279'/%3E%3Cpath fill='%23F5B1B2' d='M156.636 60.017c-4.435 4.437-4.435 11.623.012 16.059l30.681 30.693c13.39 13.392 13.477 35.125.268 48.636c-13.51 13.2-35.227 13.112-48.623-.282l-30.692-30.689c-4.438-4.437-11.633-4.437-16.066 0c-4.443 4.433-4.443 11.642 0 16.065l30.682 30.694c21.968 21.965 57.458 22.322 79.889 1.116c.208-.184.404-.355.61-.549c.094-.095.182-.192.273-.29c.1-.095.197-.183.29-.289c.197-.183.365-.384.54-.594c21.215-22.428 20.86-57.911-1.102-79.889l-30.692-30.682c-4.436-4.443-11.638-4.443-16.07.001'/%3E%3C/svg%3E") no-repeat;background-size:100% 100%;background-color:transparent;display:inline-block;vertical-align:middle;width:1.2em;height:1.2em}.i-logos-debian{background:url("data:image/svg+xml;utf8,%3Csvg viewBox='0 0 256 317' display='inline-block' vertical-align='middle' width='0.98em' height='1.2em' xmlns='http://www.w3.org/2000/svg' %3E%3Cg fill='%23A80030'%3E%3Cpath d='M152.797 167.425c-5.251.073.993 2.706 7.848 3.761a70 70 0 0 0 5.143-4.43c-4.269 1.046-8.614 1.07-12.991.67m28.183-7.026c3.127-4.315 5.406-9.04 6.21-13.926c-.702 3.483-2.593 6.49-4.372 9.663c-9.815 6.18-.923-3.67-.006-7.413c-10.554 13.284-1.45 7.966-1.832 11.677m10.402-27.071c.635-9.455-1.86-6.466-2.7-2.857c.98.508 1.754 6.665 2.7 2.858M132.886 4.088c2.802.503 6.054.888 5.598 1.557c3.066-.672 3.761-1.291-5.598-1.557m5.598 1.557l-1.98.41l1.843-.164z'/%3E%3Cpath d='M225.866 136.916c.312 8.492-2.484 12.612-5.006 19.905l-4.538 2.268c-3.714 7.211.36 4.579-2.3 10.315c-5.797 5.154-17.593 16.13-21.368 17.132c-2.756-.062 1.867-3.253 2.472-4.503c-7.761 5.33-6.227 8-18.097 11.238l-.347-.771c-29.274 13.771-69.937-13.52-69.402-50.76c-.313 2.364-.889 1.774-1.537 2.73c-1.511-19.16 8.848-38.405 26.319-46.262c17.088-8.46 37.122-4.988 49.362 6.42c-6.724-8.808-20.107-18.144-35.968-17.27c-15.536.245-30.07 10.12-34.921 20.837c-7.96 5.012-8.883 19.318-12.352 21.936c-4.666 34.296 8.778 49.114 31.52 66.544c3.58 2.414 1.009 2.78 1.494 4.617c-7.557-3.539-14.476-8.88-20.165-15.42c3.018 4.419 6.276 8.714 10.487 12.089c-7.124-2.414-16.641-17.264-19.42-17.868c12.281 21.988 49.827 38.562 69.486 30.34c-9.096.335-20.653.186-30.874-3.592c-4.293-2.209-10.13-6.785-9.088-7.641c26.83 10.023 54.546 7.591 77.762-11.02c5.906-4.599 12.358-12.424 14.222-12.532c-2.808 4.222.48 2.03-1.677 5.76c5.885-9.491-2.557-3.864 6.083-16.39l3.191 4.394c-1.186-7.878 9.783-17.444 8.67-29.904c2.516-3.81 2.808 4.1.137 12.866c3.706-9.725.976-11.288 1.929-19.312c1.029 2.697 2.379 5.564 3.071 8.41c-2.414-9.398 2.478-15.826 3.688-21.288c-1.193-.528-3.726 4.156-4.305-6.945c.085-4.822 1.342-2.528 1.827-3.714c-.947-.544-3.43-4.24-4.941-11.33c1.095-1.665 2.927 4.32 4.418 4.565c-.959-5.637-2.61-9.935-2.677-14.26c-4.354-9.099-1.54 1.213-5.073-3.906c-4.634-14.456 3.846-3.355 4.419-9.924c7.024 10.178 11.03 25.951 12.868 32.485c-1.402-7.966-3.67-15.683-6.437-23.149c2.133.897-3.436-16.39 2.773-4.94c-6.633-24.406-28.388-47.21-48.401-57.91c2.449 2.24 5.54 5.055 4.43 5.496c-9.953-5.926-8.202-6.388-9.628-8.892c-8.109-3.299-8.64.266-14.012.006c-15.282-8.106-18.227-7.244-32.291-12.322l.64 2.99c-10.125-3.373-11.797 1.279-22.74.01c-.666-.52 3.507-1.881 6.94-2.38c-9.789 1.29-9.33-1.93-18.909.356c2.361-1.657 4.857-2.753 7.376-4.161c-7.983.485-19.058 4.646-15.64.862c-13.02 5.809-36.145 13.964-49.122 26.132l-.41-2.727c-5.945 7.14-25.93 21.32-27.522 30.565l-1.59.371c-3.094 5.24-5.096 11.177-7.55 16.568c-4.047 6.896-5.932 2.654-5.356 3.735c-7.96 16.138-11.914 29.7-15.33 40.821c2.435 3.638.059 21.9.98 36.517c-3.998 72.187 50.662 142.275 110.41 158.458c8.757 3.132 21.78 3.012 32.858 3.334c-13.07-3.738-14.76-1.981-27.49-6.42c-9.185-4.325-11.198-9.263-17.702-14.908l2.574 4.55c-12.758-4.515-7.42-5.588-17.798-8.875l2.75-3.591c-4.135-.313-10.953-6.97-12.817-10.654l-4.523.178c-5.435-6.706-8.331-11.54-8.12-15.282l-1.462 2.603c-1.657-2.843-19.995-25.15-10.481-19.957c-1.768-1.616-4.117-2.63-6.665-7.259l1.937-2.215c-4.579-5.89-8.427-13.441-8.135-15.957c2.443 3.299 4.138 3.915 5.815 4.48c-11.563-28.69-12.211-1.581-20.969-29.204l1.853-.149c-1.42-2.139-2.282-4.462-3.425-6.74l.807-8.037c-8.325-9.625-2.33-40.926-1.128-58.093c.832-6.98 6.948-14.412 11.6-26.065l-2.834-.488c5.417-9.45 30.933-37.952 42.75-36.485c5.724-7.19-1.137-.026-2.256-1.838c12.573-13.012 16.527-9.193 25.013-11.533c9.151-5.432-7.855 2.118-3.516-2.072c15.82-4.041 11.212-9.187 31.85-11.238c2.178 1.239-5.051 1.914-6.866 3.521c13.181-6.449 41.712-4.982 60.244 3.58c21.504 10.049 45.663 39.754 46.616 67.704l1.084.292c-.55 11.11 1.7 23.958-2.198 35.76z'/%3E%3Cpath d='m95.483 174.634l-.736 3.682c3.45 4.687 6.189 9.765 10.595 13.43c-3.17-6.19-5.525-8.746-9.859-17.112m8.159-.321c-1.827-2.02-2.908-4.45-4.117-6.873c1.157 4.257 3.526 7.916 5.733 11.636zm144.361-31.377l-.771 1.934c-1.414 10.046-4.468 19.987-9.15 29.203c5.173-9.725 8.519-20.36 9.921-31.137M133.923 1.57c3.55-1.301 8.728-.714 12.495-1.57c-4.91.412-9.795.657-14.62 1.28zM9.282 67.847c.819 7.574-5.698 10.514 1.444 5.52c3.828-8.623-1.496-2.381-1.444-5.52M.89 102.9c1.645-5.049 1.943-8.082 2.572-11.004C-1.085 97.708 1.37 98.946.89 102.9'/%3E%3C/g%3E%3C/svg%3E") no-repeat;background-size:100% 100%;background-color:transparent;display:inline-block;vertical-align:middle;width:.98em;height:1.2em}.i-logos-docker-icon{background:url("data:image/svg+xml;utf8,%3Csvg viewBox='0 0 256 185' display='inline-block' vertical-align='middle' width='1.67em' height='1.2em' xmlns='http://www.w3.org/2000/svg' %3E%3Cpath fill='%232396ED' d='M250.716 70.497c-5.765-4-18.976-5.5-29.304-3.5c-1.2-10-6.725-18.749-16.333-26.499l-5.524-4l-3.844 5.75c-4.803 7.5-7.205 18-6.485 28c.24 3.499 1.441 9.749 5.044 15.249c-3.362 2-10.328 4.5-19.455 4.5H1.155l-.48 2c-1.682 9.999-1.682 41.248 18.014 65.247c14.892 18.249 36.99 27.499 66.053 27.499c62.93 0 109.528-30.25 131.386-84.997c8.647.25 27.142 0 36.51-18.75c.24-.5.72-1.5 2.401-5.249l.961-2zM139.986 0h-26.42v24.999h26.42zm0 29.999h-26.42v24.999h26.42zm-31.225 0h-26.42v24.999h26.42zm-31.225 0H51.115v24.999h26.421zM46.311 59.998H19.89v24.999h26.42zm31.225 0H51.115v24.999h26.421zm31.225 0h-26.42v24.999h26.42zm31.226 0h-26.422v24.999h26.422zm31.225 0H144.79v24.999h26.422z'/%3E%3C/svg%3E") no-repeat;background-size:100% 100%;background-color:transparent;display:inline-block;vertical-align:middle;width:1.67em;height:1.2em}.i-logos-nginx{background:url("data:image/svg+xml;utf8,%3Csvg viewBox='0 0 256 291' display='inline-block' vertical-align='middle' width='1.06em' height='1.2em' xmlns='http://www.w3.org/2000/svg' %3E%3Cpath fill='%23009639' d='M2.054 218.187c1.32 2.347 3.227 4.108 5.575 5.428l112.962 65.137c4.695 2.787 10.416 2.787 14.964 0l112.963-65.137c4.695-2.64 7.482-7.629 7.482-13.057V80.284c0-5.428-2.787-10.416-7.482-13.056L135.555 2.09c-4.694-2.788-10.416-2.788-14.964 0L7.63 67.228C2.787 69.868 0 74.856 0 80.284v130.42c0 2.642.587 5.136 2.054 7.483'/%3E%3Cpath fill='%23FFF' d='M91.837 195.154a14.463 14.463 0 0 1-14.524 14.524a14.463 14.463 0 0 1-14.523-14.524V95.542c0-7.776 6.895-14.084 16.43-14.084c6.896 0 14.965 2.787 19.806 8.802l4.4 5.282l60.737 72.618V95.835a14.463 14.463 0 0 1 14.524-14.524a14.463 14.463 0 0 1 14.523 14.524v99.613c0 7.775-6.895 14.083-16.43 14.083c-6.896 0-14.965-2.787-19.806-8.802l-65.137-77.754z'/%3E%3C/svg%3E") no-repeat;background-size:100% 100%;background-color:transparent;display:inline-block;vertical-align:middle;width:1.06em;height:1.2em}.i-logos-redis{background:url("data:image/svg+xml;utf8,%3Csvg viewBox='0 0 256 220' display='inline-block' vertical-align='middle' width='1.41em' height='1.2em' xmlns='http://www.w3.org/2000/svg' %3E%3Cpath fill='%23912626' d='M245.97 168.943c-13.662 7.121-84.434 36.22-99.501 44.075s-23.437 7.78-35.34 2.09c-11.902-5.69-87.216-36.112-100.783-42.597C3.566 169.271 0 166.535 0 163.951v-25.876s98.05-21.345 113.879-27.024c15.828-5.679 21.32-5.884 34.79-.95c13.472 4.936 94.018 19.468 107.331 24.344l-.006 25.51c.002 2.558-3.07 5.364-10.024 8.988'/%3E%3Cpath fill='%23C6302B' d='M245.965 143.22c-13.661 7.118-84.431 36.218-99.498 44.072c-15.066 7.857-23.436 7.78-35.338 2.09c-11.903-5.686-87.214-36.113-100.78-42.594c-13.566-6.485-13.85-10.948-.524-16.166c13.326-5.22 88.224-34.605 104.055-40.284c15.828-5.677 21.319-5.884 34.789-.948c13.471 4.934 83.819 32.935 97.13 37.81c13.316 4.881 13.827 8.9.166 16.02'/%3E%3Cpath fill='%23912626' d='M245.97 127.074c-13.662 7.122-84.434 36.22-99.501 44.078c-15.067 7.853-23.437 7.777-35.34 2.087c-11.903-5.687-87.216-36.112-100.783-42.597C3.566 127.402 0 124.67 0 122.085V96.206s98.05-21.344 113.879-27.023c15.828-5.679 21.32-5.885 34.79-.95C162.142 73.168 242.688 87.697 256 92.574l-.006 25.513c.002 2.557-3.07 5.363-10.024 8.987'/%3E%3Cpath fill='%23C6302B' d='M245.965 101.351c-13.661 7.12-84.431 36.218-99.498 44.075c-15.066 7.854-23.436 7.777-35.338 2.087c-11.903-5.686-87.214-36.112-100.78-42.594c-13.566-6.483-13.85-10.947-.524-16.167C23.151 83.535 98.05 54.148 113.88 48.47c15.828-5.678 21.319-5.884 34.789-.949c13.471 4.934 83.819 32.933 97.13 37.81c13.316 4.88 13.827 8.9.166 16.02'/%3E%3Cpath fill='%23912626' d='M245.97 83.653c-13.662 7.12-84.434 36.22-99.501 44.078c-15.067 7.854-23.437 7.777-35.34 2.087c-11.903-5.687-87.216-36.113-100.783-42.595C3.566 83.98 0 81.247 0 78.665v-25.88s98.05-21.343 113.879-27.021c15.828-5.68 21.32-5.884 34.79-.95C162.142 29.749 242.688 44.278 256 49.155l-.006 25.512c.002 2.555-3.07 5.361-10.024 8.986'/%3E%3Cpath fill='%23C6302B' d='M245.965 57.93c-13.661 7.12-84.431 36.22-99.498 44.074c-15.066 7.854-23.436 7.777-35.338 2.09C99.227 98.404 23.915 67.98 10.35 61.497S-3.5 50.55 9.825 45.331C23.151 40.113 98.05 10.73 113.88 5.05c15.828-5.679 21.319-5.883 34.789-.948s83.819 32.934 97.13 37.811c13.316 4.876 13.827 8.897.166 16.017'/%3E%3Cpath fill='%23FFF' d='m159.283 32.757l-22.01 2.285l-4.927 11.856l-7.958-13.23l-25.415-2.284l18.964-6.839l-5.69-10.498l17.755 6.944l16.738-5.48l-4.524 10.855zm-28.251 57.518L89.955 73.238l58.86-9.035zm-56.95-50.928c17.375 0 31.46 5.46 31.46 12.194c0 6.736-14.085 12.195-31.46 12.195s-31.46-5.46-31.46-12.195c0-6.734 14.085-12.194 31.46-12.194'/%3E%3Cpath fill='%23621B1C' d='m185.295 35.998l34.836 13.766l-34.806 13.753z'/%3E%3Cpath fill='%239A2928' d='m146.755 51.243l38.54-15.245l.03 27.519l-3.779 1.478z'/%3E%3C/svg%3E") no-repeat;background-size:100% 100%;background-color:transparent;display:inline-block;vertical-align:middle;width:1.41em;height:1.2em}.i-material-symbols-account-circle{--un-icon:url("data:image/svg+xml;utf8,%3Csvg viewBox='0 0 24 24' display='inline-block' vertical-align='middle' width='1.2em' height='1.2em' xmlns='http://www.w3.org/2000/svg' %3E%3Cpath fill='currentColor' d='M5.85 17.1q1.275-.975 2.85-1.537T12 15t3.3.563t2.85 1.537q.875-1.025 1.363-2.325T20 12q0-3.325-2.337-5.663T12 4T6.337 6.338T4 12q0 1.475.488 2.775T5.85 17.1M12 13q-1.475 0-2.488-1.012T8.5 9.5t1.013-2.488T12 6t2.488 1.013T15.5 9.5t-1.012 2.488T12 13m0 9q-2.075 0-3.9-.788t-3.175-2.137T2.788 15.9T2 12t.788-3.9t2.137-3.175T8.1 2.788T12 2t3.9.788t3.175 2.137T21.213 8.1T22 12t-.788 3.9t-2.137 3.175t-3.175 2.138T12 22'/%3E%3C/svg%3E");-webkit-mask:var(--un-icon) no-repeat;mask:var(--un-icon) no-repeat;-webkit-mask-size:100% 100%;mask-size:100% 100%;background-color:currentColor;color:inherit;display:inline-block;vertical-align:middle;width:1.2em;height:1.2em}.i-material-symbols-dns-outline{--un-icon:url("data:image/svg+xml;utf8,%3Csvg viewBox='0 0 24 24' display='inline-block' vertical-align='middle' width='1.2em' height='1.2em' xmlns='http://www.w3.org/2000/svg' %3E%3Cpath fill='currentColor' d='M7.5 6q-.625 0-1.062.438T6 7.5t.438 1.063T7.5 9t1.063-.437T9 7.5t-.437-1.062T7.5 6m0 10q-.625 0-1.062.438T6 17.5t.438 1.063T7.5 19t1.063-.437T9 17.5t-.437-1.062T7.5 16M4 3h16q.425 0 .713.288T21 4v7q0 .425-.288.713T20 12H4q-.425 0-.712-.288T3 11V4q0-.425.288-.712T4 3m1 2v5h14V5zm-1 8h16q.425 0 .713.288T21 14v7q0 .425-.288.713T20 22H4q-.425 0-.712-.288T3 21v-7q0-.425.288-.712T4 13m1 2v5h14v-5zM5 5v5zm0 10v5z'/%3E%3C/svg%3E");-webkit-mask:var(--un-icon) no-repeat;mask:var(--un-icon) no-repeat;-webkit-mask-size:100% 100%;mask-size:100% 100%;background-color:currentColor;color:inherit;display:inline-block;vertical-align:middle;width:1.2em;height:1.2em}.i-material-symbols-hard-drive-outline{--un-icon:url("data:image/svg+xml;utf8,%3Csvg viewBox='0 0 24 24' display='inline-block' vertical-align='middle' width='1.2em' height='1.2em' xmlns='http://www.w3.org/2000/svg' %3E%3Cpath fill='currentColor' d='M4 17h16v-6H4zm13-1.5q.625 0 1.063-.437T18.5 14t-.437-1.062T17 12.5t-1.062.438T15.5 14t.438 1.063T17 15.5M22 9h-2.825l-2-2H6.825l-2 2H2l3.425-3.425q.275-.275.638-.425T6.825 5h10.35q.4 0 .763.15t.637.425zM4 19q-.825 0-1.412-.587T2 17V9h20v8q0 .825-.587 1.413T20 19z'/%3E%3C/svg%3E");-webkit-mask:var(--un-icon) no-repeat;mask:var(--un-icon) no-repeat;-webkit-mask-size:100% 100%;mask-size:100% 100%;background-color:currentColor;color:inherit;display:inline-block;vertical-align:middle;width:1.2em;height:1.2em}.i-material-symbols-key-outline{--un-icon:url("data:image/svg+xml;utf8,%3Csvg viewBox='0 0 24 24' display='inline-block' vertical-align='middle' width='1.2em' height='1.2em' xmlns='http://www.w3.org/2000/svg' %3E%3Cpath fill='currentColor' d='M7 14q-.825 0-1.412-.587T5 12t.588-1.412T7 10t1.413.588T9 12t-.587 1.413T7 14m0 4q-2.5 0-4.25-1.75T1 12t1.75-4.25T7 6q1.675 0 3.038.825T12.2 9H21l3 3l-4.5 4.5l-2-1.5l-2 1.5l-2.125-1.5H12.2q-.8 1.35-2.162 2.175T7 18m0-2q1.4 0 2.463-.85T10.875 13H14l1.45 1.025L17.5 12.5l1.775 1.375L21.15 12l-1-1h-9.275q-.35-1.3-1.412-2.15T7 8Q5.35 8 4.175 9.175T3 12t1.175 2.825T7 16'/%3E%3C/svg%3E");-webkit-mask:var(--un-icon) no-repeat;mask:var(--un-icon) no-repeat;-webkit-mask-size:100% 100%;mask-size:100% 100%;background-color:currentColor;color:inherit;display:inline-block;vertical-align:middle;width:1.2em;height:1.2em}.i-material-symbols-lock{--un-icon:url("data:image/svg+xml;utf8,%3Csvg viewBox='0 0 24 24' display='inline-block' vertical-align='middle' width='1.2em' height='1.2em' xmlns='http://www.w3.org/2000/svg' %3E%3Cpath fill='currentColor' d='M6 22q-.825 0-1.412-.587T4 20V10q0-.825.588-1.412T6 8h1V6q0-2.075 1.463-3.537T12 1t3.538 1.463T17 6v2h1q.825 0 1.413.588T20 10v10q0 .825-.587 1.413T18 22zm6-5q.825 0 1.413-.587T14 15t-.587-1.412T12 13t-1.412.588T10 15t.588 1.413T12 17M9 8h6V6q0-1.25-.875-2.125T12 3t-2.125.875T9 6z'/%3E%3C/svg%3E");-webkit-mask:var(--un-icon) no-repeat;mask:var(--un-icon) no-repeat;-webkit-mask-size:100% 100%;mask-size:100% 100%;background-color:currentColor;color:inherit;display:inline-block;vertical-align:middle;width:1.2em;height:1.2em}.i-material-symbols-memory-alt-outline-rounded{--un-icon:url("data:image/svg+xml;utf8,%3Csvg viewBox='0 0 24 24' display='inline-block' vertical-align='middle' width='1.2em' height='1.2em' xmlns='http://www.w3.org/2000/svg' %3E%3Cpath fill='currentColor' d='M7 15q.425 0 .713-.288T8 14v-4q0-.425-.288-.712T7 9t-.712.288T6 10v4q0 .425.288.713T7 15m5 0q.425 0 .713-.288T13 14v-4q0-.425-.288-.712T12 9t-.712.288T11 10v4q0 .425.288.713T12 15m5 0q.425 0 .713-.288T18 14v-4q0-.425-.288-.712T17 9t-.712.288T16 10v4q0 .425.288.713T17 15M4 17h16V7H4zm0 0V7zm0 2q-.825 0-1.412-.587T2 17V7q0-.825.588-1.412T4 5h1V4q0-.425.288-.712T6 3t.713.288T7 4v1h4V4q0-.425.288-.712T12 3t.713.288T13 4v1h4V4q0-.425.288-.712T18 3t.713.288T19 4v1h1q.825 0 1.413.588T22 7v10q0 .825-.587 1.413T20 19h-1v1q0 .425-.288.713T18 21t-.712-.288T17 20v-1h-4v1q0 .425-.288.713T12 21t-.712-.288T11 20v-1H7v1q0 .425-.288.713T6 21t-.712-.288T5 20v-1z'/%3E%3C/svg%3E");-webkit-mask:var(--un-icon) no-repeat;mask:var(--un-icon) no-repeat;-webkit-mask-size:100% 100%;mask-size:100% 100%;background-color:currentColor;color:inherit;display:inline-block;vertical-align:middle;width:1.2em;height:1.2em}.i-material-symbols-terminal{--un-icon:url("data:image/svg+xml;utf8,%3Csvg viewBox='0 0 24 24' display='inline-block' vertical-align='middle' width='1.2em' height='1.2em' xmlns='http://www.w3.org/2000/svg' %3E%3Cpath fill='currentColor' d='M4 20q-.825 0-1.412-.587T2 18V6q0-.825.588-1.412T4 4h16q.825 0 1.413.588T22 6v12q0 .825-.587 1.413T20 20zm0-2h16V8H4zm3.5-1l-1.4-1.4L8.675 13l-2.6-2.6L7.5 9l4 4zm4.5 0v-2h6v2z'/%3E%3C/svg%3E");-webkit-mask:var(--un-icon) no-repeat;mask:var(--un-icon) no-repeat;-webkit-mask-size:100% 100%;mask-size:100% 100%;background-color:currentColor;color:inherit;display:inline-block;vertical-align:middle;width:1.2em;height:1.2em}.i-material-symbols-touch-app{--un-icon:url("data:image/svg+xml;utf8,%3Csvg viewBox='0 0 24 24' display='inline-block' vertical-align='middle' width='1.2em' height='1.2em' xmlns='http://www.w3.org/2000/svg' %3E%3Cpath fill='currentColor' d='M10.475 22q-.7 0-1.312-.3t-1.038-.85l-5.45-6.925l.475-.5q.5-.525 1.2-.625t1.3.275L7.5 14.2V6q0-.425.288-.712T8.5 5t.725.288t.3.712v5H17q1.25 0 2.125.875T20 14v4q0 1.65-1.175 2.825T16 22zm-6.3-13.5q-.325-.55-.5-1.187T3.5 6q0-2.075 1.463-3.537T8.5 1t3.538 1.463T13.5 6q0 .675-.175 1.313t-.5 1.187l-1.725-1q.2-.35.3-.712T11.5 6q0-1.25-.875-2.125T8.5 3t-2.125.875T5.5 6q0 .425.1.788t.3.712z'/%3E%3C/svg%3E");-webkit-mask:var(--un-icon) no-repeat;mask:var(--un-icon) no-repeat;-webkit-mask-size:100% 100%;mask-size:100% 100%;background-color:currentColor;color:inherit;display:inline-block;vertical-align:middle;width:1.2em;height:1.2em}.i-mdi-apple-icloud{--un-icon:url("data:image/svg+xml;utf8,%3Csvg viewBox='0 0 24 24' display='inline-block' vertical-align='middle' width='1.2em' height='1.2em' xmlns='http://www.w3.org/2000/svg' %3E%3Cpath fill='currentColor' d='M22 15.04c0 2.19-1.76 3.96-3.93 3.96H5.93C3.76 19 2 17.23 2 15.04c0-1.97 1.43-3.6 3.31-3.9c-.03-.14-.04-.28-.04-.43c0-1.38 1.11-2.51 2.49-2.51c.61 0 1.18.23 1.61.6c.77-1.75 1.76-3.36 4.54-3.36c3.37 0 4.96 2.62 4.96 5.39c0 .11 0 .23-.01.34A3.95 3.95 0 0 1 22 15.04'/%3E%3C/svg%3E");-webkit-mask:var(--un-icon) no-repeat;mask:var(--un-icon) no-repeat;-webkit-mask-size:100% 100%;mask-size:100% 100%;background-color:currentColor;color:inherit;display:inline-block;vertical-align:middle;width:1.2em;height:1.2em}.i-mdi-github{--un-icon:url("data:image/svg+xml;utf8,%3Csvg viewBox='0 0 24 24' display='inline-block' vertical-align='middle' width='1.2em' height='1.2em' xmlns='http://www.w3.org/2000/svg' %3E%3Cpath fill='currentColor' d='M12 2A10 10 0 0 0 2 12c0 4.42 2.87 8.17 6.84 9.5c.5.08.66-.23.66-.5v-1.69c-2.77.6-3.36-1.34-3.36-1.34c-.46-1.16-1.11-1.47-1.11-1.47c-.91-.62.07-.6.07-.6c1 .07 1.53 1.03 1.53 1.03c.87 1.52 2.34 1.07 2.91.83c.09-.65.35-1.09.63-1.34c-2.22-.25-4.55-1.11-4.55-4.92c0-1.11.38-2 1.03-2.71c-.1-.25-.45-1.29.1-2.64c0 0 .84-.27 2.75 1.02c.79-.22 1.65-.33 2.5-.33s1.71.11 2.5.33c1.91-1.29 2.75-1.02 2.75-1.02c.55 1.35.2 2.39.1 2.64c.65.71 1.03 1.6 1.03 2.71c0 3.82-2.34 4.66-4.57 4.91c.36.31.69.92.69 1.85V21c0 .27.16.59.67.5C19.14 20.16 22 16.42 22 12A10 10 0 0 0 12 2'/%3E%3C/svg%3E");-webkit-mask:var(--un-icon) no-repeat;mask:var(--un-icon) no-repeat;-webkit-mask-size:100% 100%;mask-size:100% 100%;background-color:currentColor;color:inherit;display:inline-block;vertical-align:middle;width:1.2em;height:1.2em}.i-mdi-gmail{--un-icon:url("data:image/svg+xml;utf8,%3Csvg viewBox='0 0 24 24' display='inline-block' vertical-align='middle' width='1.2em' height='1.2em' xmlns='http://www.w3.org/2000/svg' %3E%3Cpath fill='currentColor' d='M20 18h-2V9.25L12 13L6 9.25V18H4V6h1.2l6.8 4.25L18.8 6H20m0-2H4c-1.11 0-2 .89-2 2v12a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2V6a2 2 0 0 0-2-2'/%3E%3C/svg%3E");-webkit-mask:var(--un-icon) no-repeat;mask:var(--un-icon) no-repeat;-webkit-mask-size:100% 100%;mask-size:100% 100%;background-color:currentColor;color:inherit;display:inline-block;vertical-align:middle;width:1.2em;height:1.2em}.i-mdi-google-drive{--un-icon:url("data:image/svg+xml;utf8,%3Csvg viewBox='0 0 24 24' display='inline-block' vertical-align='middle' width='1.2em' height='1.2em' xmlns='http://www.w3.org/2000/svg' %3E%3Cpath fill='currentColor' d='M7.71 3.5L1.15 15l3.43 6l6.55-11.5M9.73 15L6.3 21h13.12l3.43-6m-.57-1L15.42 2H8.57l6.86 12z'/%3E%3C/svg%3E");-webkit-mask:var(--un-icon) no-repeat;mask:var(--un-icon) no-repeat;-webkit-mask-size:100% 100%;mask-size:100% 100%;background-color:currentColor;color:inherit;display:inline-block;vertical-align:middle;width:1.2em;height:1.2em}.i-mdi-monitor{--un-icon:url("data:image/svg+xml;utf8,%3Csvg viewBox='0 0 24 24' display='inline-block' vertical-align='middle' width='1.2em' height='1.2em' xmlns='http://www.w3.org/2000/svg' %3E%3Cpath fill='currentColor' d='M21 16H3V4h18m0-2H3c-1.11 0-2 .89-2 2v12a2 2 0 0 0 2 2h7v2H8v2h8v-2h-2v-2h7a2 2 0 0 0 2-2V4a2 2 0 0 0-2-2'/%3E%3C/svg%3E");-webkit-mask:var(--un-icon) no-repeat;mask:var(--un-icon) no-repeat;-webkit-mask-size:100% 100%;mask-size:100% 100%;background-color:currentColor;color:inherit;display:inline-block;vertical-align:middle;width:1.2em;height:1.2em}.i-mingcute-tunnel-line{--un-icon:url("data:image/svg+xml;utf8,%3Csvg viewBox='0 0 24 24' display='inline-block' vertical-align='middle' width='1.2em' height='1.2em' xmlns='http://www.w3.org/2000/svg' %3E%3Cg fill='none' fill-rule='evenodd'%3E%3Cpath d='m12.594 23.258l-.012.002l-.071.035l-.02.004l-.014-.004l-.071-.036q-.016-.004-.024.006l-.004.01l-.017.428l.005.02l.01.013l.104.074l.015.004l.012-.004l.104-.074l.012-.016l.004-.017l-.017-.427q-.004-.016-.016-.018m.264-.113l-.014.002l-.184.093l-.01.01l-.003.011l.018.43l.005.012l.008.008l.201.092q.019.005.029-.008l.004-.014l-.034-.614q-.005-.019-.02-.022m-.715.002a.02.02 0 0 0-.027.006l-.006.014l-.034.614q.001.018.017.024l.015-.002l.201-.093l.01-.008l.003-.011l.018-.43l-.003-.012l-.01-.01z'/%3E%3Cpath fill='currentColor' d='M12 19.5a1 1 0 0 1 .993.883L13 20.5v.5a1 1 0 0 1-1.993.117L11 21v-.5a1 1 0 0 1 1-1M12 2a8 8 0 0 1 7.996 7.75L20 10v11a1 1 0 0 1-1.696.718l-.085-.093L14.52 17h-1.653q.097.166.125.366L13 17.5v.5a1 1 0 0 1-1.993.117L11 18v-.5q.001-.207.077-.385l.057-.115H9.48l-3.7 4.625a1 1 0 0 1-1.773-.5L4 21V10a8 8 0 0 1 8-8m0 2a6 6 0 0 0-5.996 5.775L6 10v8.15l2-2.5V12a4 4 0 0 1 7.995-.2L16 12v3.65l2 2.5V10a6 6 0 0 0-6-6m0 6a2 2 0 0 0-2 2v3h4v-3a2 2 0 0 0-2-2'/%3E%3C/g%3E%3C/svg%3E");-webkit-mask:var(--un-icon) no-repeat;mask:var(--un-icon) no-repeat;-webkit-mask-size:100% 100%;mask-size:100% 100%;background-color:currentColor;color:inherit;display:inline-block;vertical-align:middle;width:1.2em;height:1.2em}.i-octicon-cpu-24{--un-icon:url("data:image/svg+xml;utf8,%3Csvg viewBox='0 0 24 24' display='inline-block' vertical-align='middle' width='1.2em' height='1.2em' xmlns='http://www.w3.org/2000/svg' %3E%3Cpath fill='currentColor' d='M8.75 8h6.5a.75.75 0 0 1 .75.75v6.5a.75.75 0 0 1-.75.75h-6.5a.75.75 0 0 1-.75-.75v-6.5A.75.75 0 0 1 8.75 8m.75 6.5h5v-5h-5Z'/%3E%3Cpath fill='currentColor' d='M15.25 1a.75.75 0 0 1 .75.75V4h2.25c.966 0 1.75.784 1.75 1.75V8h2.25a.75.75 0 0 1 0 1.5H20v5h2.25a.75.75 0 0 1 0 1.5H20v2.25A1.75 1.75 0 0 1 18.25 20H16v2.25a.75.75 0 0 1-1.5 0V20h-5v2.25a.75.75 0 0 1-1.5 0V20H5.75A1.75 1.75 0 0 1 4 18.25V16H1.75a.75.75 0 0 1 0-1.5H4v-5H1.75a.75.75 0 0 1 0-1.5H4V5.75C4 4.784 4.784 4 5.75 4H8V1.75a.75.75 0 0 1 1.5 0V4h5V1.75a.75.75 0 0 1 .75-.75m3 17.5a.25.25 0 0 0 .25-.25V5.75a.25.25 0 0 0-.25-.25H5.75a.25.25 0 0 0-.25.25v12.5c0 .138.112.25.25.25Z'/%3E%3C/svg%3E");-webkit-mask:var(--un-icon) no-repeat;mask:var(--un-icon) no-repeat;-webkit-mask-size:100% 100%;mask-size:100% 100%;background-color:currentColor;color:inherit;display:inline-block;vertical-align:middle;width:1.2em;height:1.2em}.i-simple-icons-authelia{--un-icon:url("data:image/svg+xml;utf8,%3Csvg viewBox='0 0 24 24' display='inline-block' vertical-align='middle' width='1.2em' height='1.2em' xmlns='http://www.w3.org/2000/svg' %3E%3Cpath fill='currentColor' d='M10.624.191c-.324.023-.655.011-.97.073c-2.883.568-5.244 2.01-7.074 4.3C1.42 6.014.624 7.652.243 9.48c-.25 1.2-.294 2.402-.191 3.627c.237 2.832 1.377 5.233 3.345 7.26c.332.341.775.348 1.1.055c.39-.35.442-.735.124-1.149c-.271-.353-.588-.671-.85-1.03c-1.625-2.208-2.343-4.674-2.04-7.411c.305-2.773 1.6-5.022 3.723-6.795c1.517-1.267 3.288-1.983 5.248-2.24c.272-.037.552-.083.803-.186c.32-.132.478-.564.4-.923c-.085-.384-.355-.483-.702-.477c-.194.004-.387 0-.58 0v-.02zm4.639 3.41c-.312-.008-.582.197-.722.512c-.176.4-.027.854.367 1.096c.123.075.256.134.385.199c1.485.737 2.619 1.834 3.319 3.342c.257.554.423 1.15.636 1.726c.162.441.509.656.92.579c.425-.08.67-.392.668-.952c-.016-.081-.035-.261-.082-.435c-.535-1.97-1.579-3.616-3.21-4.847c-.598-.453-1.28-.812-1.958-1.14a.8.8 0 0 0-.323-.08m-6.939.23a.9.9 0 0 0-.492.144c-.648.388-1.325.764-1.88 1.266c-2.323 2.098-3.262 4.755-2.905 7.84c.55 4.74 4.6 8.021 8.9 7.904l.868-.001a1 1 0 0 0 .109-.007c2.491-.312 4.58-1.387 6.146-3.36c.488-.615.86-1.336 1.2-2.049c.248-.523-.032-.982-.56-1.12c-.38-.1-.72.112-.974.509c-.473.737-.89 1.54-1.491 2.16c-1.479 1.52-3.322 2.28-5.466 2.199c-2.405-.091-4.337-1.127-5.758-3.056c-1.088-1.475-1.49-3.168-1.32-4.984c.184-1.987 1.038-3.644 2.57-4.927c.423-.354.908-.633 1.365-.946c.458-.314.568-.715.314-1.15c-.153-.262-.371-.413-.626-.422m3.417 2.167C8.724 6.056 6.02 8.625 6 12c-.02 3.29 2.712 6.017 6 6.02c3.339.005 6.078-2.618 6.062-6.025c-.014-3.545-2.87-6.084-6.028-5.995a6 6 0 0 0-.293-.002m10.752 1.164a1 1 0 0 0-.137.002c-.404.033-.642.295-.74.646c-.053.187-.01.432.064.62a9.55 9.55 0 0 1 .648 3.753a10 10 0 0 1-1.32 4.76c-1.617 2.84-4.04 4.53-7.243 5.12c-.343.063-.694.095-1.033.174c-.434.103-.688.473-.641.882c.044.38.34.646.769.684c.132.012.265.002.398.002l-.001-.003c.145 0 .29.005.434-.002c.084-.004.167-.028.25-.04c1.847-.282 3.518-.99 5.037-2.068c1.708-1.213 3.001-2.78 3.897-4.665c1.1-2.317 1.375-4.752.906-7.264c-.13-.694-.354-1.376-.584-2.046c-.125-.362-.389-.537-.704-.555m-10.449.862q.195 0 .392.05c.708.18 1.16.787 1.158 1.553c.027.504-.211.888-.588 1.183c-.207.163-.236.32-.176.558q.397 1.578.763 3.164c.13.568-.019.872-.522 1.174c-.675.404-1.666.354-2.29-.13c-.315-.244-.427-.573-.331-.966c.252-1.031.494-2.064.762-3.09c.086-.33.041-.554-.225-.794c-.581-.523-.682-1.253-.317-1.903a1.57 1.57 0 0 1 1.374-.8z'/%3E%3C/svg%3E");-webkit-mask:var(--un-icon) no-repeat;mask:var(--un-icon) no-repeat;-webkit-mask-size:100% 100%;mask-size:100% 100%;background-color:currentColor;color:inherit;display:inline-block;vertical-align:middle;width:1.2em;height:1.2em}.i-simple-icons-bitwarden{--un-icon:url("data:image/svg+xml;utf8,%3Csvg viewBox='0 0 24 24' display='inline-block' vertical-align='middle' width='1.2em' height='1.2em' xmlns='http://www.w3.org/2000/svg' %3E%3Cpath fill='currentColor' d='M3.75 0A3.75 3.75 0 0 0 0 3.75v16.5A3.75 3.75 0 0 0 3.75 24h16.5A3.75 3.75 0 0 0 24 20.25V3.75A3.75 3.75 0 0 0 20.25 0zm1.36 2.92h13.8q.312 0 .54.228a.74.74 0 0 1 .227.539v9.2a5.5 5.5 0 0 1-.401 2.042a7.6 7.6 0 0 1-.995 1.797a11 11 0 0 1-1.413 1.528q-.82.742-1.515 1.234a20 20 0 0 1-1.45.928q-.754.437-1.072.593a13 13 0 0 1-.51.24a.7.7 0 0 1-.31.071a.7.7 0 0 1-.312-.072a14 14 0 0 1-.51-.24a21 21 0 0 1-1.071-.592a19 19 0 0 1-1.45-.928a17 17 0 0 1-1.515-1.234a11 11 0 0 1-1.414-1.528a7.6 7.6 0 0 1-.994-1.797a5.5 5.5 0 0 1-.401-2.042v-9.2q0-.311.227-.54a.74.74 0 0 1 .54-.227zm6.9 2.3v13.62q1.425-.754 2.552-1.64q2.815-2.204 2.815-4.313V5.22Z'/%3E%3C/svg%3E");-webkit-mask:var(--un-icon) no-repeat;mask:var(--un-icon) no-repeat;-webkit-mask-size:100% 100%;mask-size:100% 100%;background-color:currentColor;color:inherit;display:inline-block;vertical-align:middle;width:1.2em;height:1.2em}.i-simple-icons-canvas{--un-icon:url("data:image/svg+xml;utf8,%3Csvg viewBox='0 0 24 24' display='inline-block' vertical-align='middle' width='1.2em' height='1.2em' xmlns='http://www.w3.org/2000/svg' %3E%3Cpath fill='currentColor' d='M.44 15.414a13.7 13.7 0 0 1-.436-3.44a13.7 13.7 0 0 1 .436-3.44a3.47 3.47 0 0 1 3.044 3.44a3.47 3.47 0 0 1-3.044 3.44m3.973-3.44a1.087 1.087 0 1 0 2.175 0a1.087 1.087 0 0 0-2.175 0m19.147-3.44a3.47 3.47 0 0 0-3.044 3.44a3.47 3.47 0 0 0 3.044 3.44a13.7 13.7 0 0 0 .436-3.44c0-1.188-.152-2.341-.436-3.44m-6.148 3.44a1.087 1.087 0 1 0 2.175 0a1.087 1.087 0 0 0-2.175 0m-5.435 8.546a3.47 3.47 0 0 0-3.44 3.044a13.7 13.7 0 0 0 3.441.436c1.189 0 2.34-.151 3.44-.436a3.47 3.47 0 0 0-3.44-3.044m.001-3.104a1.088 1.088 0 1 0 0 2.176a1.088 1.088 0 0 0 0-2.176m0-13.936c1.772 0 3.23-1.33 3.44-3.044A13.7 13.7 0 0 0 11.978 0c-1.189 0-2.341.152-3.44.436a3.47 3.47 0 0 0 3.44 3.044zm0 .929a1.087 1.087 0 1 0 0 2.174a1.087 1.087 0 0 0 0-2.174m6.032 13.596a3.47 3.47 0 0 0-.282 4.582a13.76 13.76 0 0 0 4.863-4.865a3.47 3.47 0 0 0-4.58.283m-.657-2.195a1.09 1.09 0 0 0-1.539 1.539a1.088 1.088 0 1 0 1.54-1.539M5.966 5.96a3.467 3.467 0 0 0 .282-4.581a13.8 13.8 0 0 0-4.864 4.864a3.47 3.47 0 0 0 4.582-.283m.657.658A1.088 1.088 0 1 0 8.16 8.156a1.088 1.088 0 0 0-1.538-1.539m15.962-.386a13.76 13.76 0 0 0-4.864-4.864a3.47 3.47 0 0 0 .283 4.581a3.47 3.47 0 0 0 4.581.283m-5.238 1.912a1.089 1.089 0 1 0-1.539-1.537a1.089 1.089 0 0 0 1.539 1.537M1.377 17.71a13.76 13.76 0 0 0 4.865 4.865a3.468 3.468 0 0 0-4.865-4.865m5.239-1.912a1.088 1.088 0 1 0 1.538 1.538a1.088 1.088 0 0 0-1.538-1.538'/%3E%3C/svg%3E");-webkit-mask:var(--un-icon) no-repeat;mask:var(--un-icon) no-repeat;-webkit-mask-size:100% 100%;mask-size:100% 100%;background-color:currentColor;color:inherit;display:inline-block;vertical-align:middle;width:1.2em;height:1.2em}.i-simple-icons-cisco{--un-icon:url("data:image/svg+xml;utf8,%3Csvg viewBox='0 0 24 24' display='inline-block' vertical-align='middle' width='1.2em' height='1.2em' xmlns='http://www.w3.org/2000/svg' %3E%3Cpath fill='currentColor' d='M16.331 18.171V17.06l-.022.01c-.25.121-.522.19-.801.203a1.2 1.2 0 0 1-.806-.237a1.04 1.04 0 0 1-.352-.498a1.2 1.2 0 0 1-.023-.667c.052-.225.178-.426.357-.569c.16-.134.355-.218.562-.242a1.85 1.85 0 0 1 1.061.198l.024.013v-1.117l-.051-.014a2.9 2.9 0 0 0-1.011-.132a2.3 2.3 0 0 0-.903.206c-.287.132-.54.327-.739.571a2.22 2.22 0 0 0-.04 2.705c.295.378.709.645 1.175.756c.491.12 1.006.102 1.487-.052zm-10.995 0V17.06l-.022.01c-.25.121-.522.19-.801.203a1.18 1.18 0 0 1-.806-.237a1.03 1.03 0 0 1-.351-.498a1.2 1.2 0 0 1-.024-.667c.052-.225.177-.426.357-.569c.16-.134.355-.218.562-.242a1.85 1.85 0 0 1 1.061.198l.024.013v-1.117l-.051-.014a2.9 2.9 0 0 0-1.011-.132a2.3 2.3 0 0 0-.903.206a2.1 2.1 0 0 0-.74.571a2.224 2.224 0 0 0-.041 2.705a2.1 2.1 0 0 0 1.176.756c.491.12 1.005.102 1.487-.052zm3.924-.922l-.004.957l.07.012q.33.061.664.085q.293.028.587.012q.282-.021.551-.104c.21-.06.405-.163.571-.305a1.16 1.16 0 0 0 .333-.478a1.3 1.3 0 0 0-.007-.96a1.1 1.1 0 0 0-.298-.414a1.3 1.3 0 0 0-.438-.255l-.722-.268a.4.4 0 0 1-.197-.188a.25.25 0 0 1 .008-.219a.4.4 0 0 1 .154-.142a.8.8 0 0 1 .257-.074q.23-.034.46.005q.27.03.533.096l.038.008v-.883l-.069-.015a5 5 0 0 0-.543-.097a2.8 2.8 0 0 0-.714-.003c-.3.027-.585.143-.821.33c-.16.126-.281.293-.351.484c-.104.29-.105.608 0 .899q.082.219.252.381q.146.14.327.236q.236.126.497.195q.086.026.17.054l.085.031l.024.01c.084.03.162.078.226.14q.068.064.101.151a.3.3 0 0 1 .001.161a.34.34 0 0 1-.166.198a.9.9 0 0 1-.275.086a2 2 0 0 1-.427.021a5 5 0 0 1-.557-.074a9 9 0 0 1-.287-.067zm-2.475.995h1.05v-4.167h-1.05zm12.162-2.936a1.095 1.095 0 0 1 1.541.158a1.094 1.094 0 0 1-.157 1.541l-.017.014a1.096 1.096 0 0 1-1.367-1.713m-1.525.854a2.193 2.193 0 0 0 2.666 2.107a2.139 2.139 0 0 0 .701-3.937a2.207 2.207 0 0 0-3.367 1.83m5.539-5.434a.52.52 0 0 0 1.039 0V9.573a.52.52 0 0 0-1.039 0zm-2.844 0a.522.522 0 0 0 1.041 0V8.139a.521.521 0 0 0-1.04 0v2.589m-2.887 1.043a.521.521 0 0 0 1.039 0V6.17a.52.52 0 0 0-1.039 0zm-2.838-1.043a.521.521 0 0 0 1.04 0V8.139a.52.52 0 0 0-1.039 0zm-2.9 0a.522.522 0 0 0 1.039 0V9.573a.52.52 0 0 0-1.039 0zm-2.87 0a.52.52 0 0 0 1.039 0V8.139a.52.52 0 0 0-1.039 0zm-2.887 1.043a.52.52 0 0 0 1.039 0V6.17a.52.52 0 0 0-1.039 0zm-2.861-1.043a.522.522 0 0 0 1.04 0V8.139a.52.52 0 0 0-1.039 0zm-2.877 0a.521.521 0 0 0 1.039 0V9.573a.52.52 0 0 0-1.039 0z'/%3E%3C/svg%3E");-webkit-mask:var(--un-icon) no-repeat;mask:var(--un-icon) no-repeat;-webkit-mask-size:100% 100%;mask-size:100% 100%;background-color:currentColor;color:inherit;display:inline-block;vertical-align:middle;width:1.2em;height:1.2em}.i-simple-icons-cloudflare{--un-icon:url("data:image/svg+xml;utf8,%3Csvg viewBox='0 0 24 24' display='inline-block' vertical-align='middle' width='1.2em' height='1.2em' xmlns='http://www.w3.org/2000/svg' %3E%3Cpath fill='currentColor' d='M16.509 16.845c.147-.507.09-.971-.155-1.316c-.225-.316-.605-.499-1.062-.52l-8.66-.113a.16.16 0 0 1-.133-.07a.2.2 0 0 1-.02-.156a.24.24 0 0 1 .203-.156l8.736-.113c1.035-.049 2.16-.886 2.554-1.913l.499-1.302a.27.27 0 0 0 .014-.168a5.689 5.689 0 0 0-10.937-.584a2.58 2.58 0 0 0-1.794-.498a2.56 2.56 0 0 0-2.223 3.18A3.634 3.634 0 0 0 0 16.751q.002.264.035.527a.174.174 0 0 0 .17.148h15.98a.22.22 0 0 0 .204-.155zm2.757-5.564c-.077 0-.161 0-.239.011c-.056 0-.105.042-.127.098l-.337 1.174c-.148.507-.092.971.154 1.317c.225.316.605.498 1.062.52l1.844.113c.056 0 .105.026.133.07a.2.2 0 0 1 .021.156a.24.24 0 0 1-.204.156l-1.92.112c-1.042.049-2.159.887-2.553 1.914l-.141.358c-.028.072.021.142.099.142h6.597a.174.174 0 0 0 .17-.126a5 5 0 0 0 .175-1.28a4.74 4.74 0 0 0-4.734-4.727'/%3E%3C/svg%3E");-webkit-mask:var(--un-icon) no-repeat;mask:var(--un-icon) no-repeat;-webkit-mask-size:100% 100%;mask-size:100% 100%;background-color:currentColor;color:inherit;display:inline-block;vertical-align:middle;width:1.2em;height:1.2em}.i-simple-icons-letsencrypt{--un-icon:url("data:image/svg+xml;utf8,%3Csvg viewBox='0 0 24 24' display='inline-block' vertical-align='middle' width='1.2em' height='1.2em' xmlns='http://www.w3.org/2000/svg' %3E%3Cpath fill='currentColor' d='M11.991 0a.883.883 0 0 0-.871.817v3.02a.883.883 0 0 0 .88.884a.883.883 0 0 0 .88-.88V.816A.883.883 0 0 0 11.991 0m7.705 3.109a.88.88 0 0 0-.521.174L16.8 5.231a.88.88 0 0 0 .559 1.563a.88.88 0 0 0 .56-.2l2.37-1.951a.88.88 0 0 0-.594-1.534M4.32 3.122a.883.883 0 0 0-.611 1.52l2.37 1.951a.88.88 0 0 0 .56.2v-.002a.88.88 0 0 0 .56-1.56L4.828 3.283a.9.9 0 0 0-.508-.16zm7.66 3.228a5.046 5.046 0 0 0-5.026 5.045v1.488H5.787a.967.967 0 0 0-.965.964v9.189a.967.967 0 0 0 .965.964h12.426a.967.967 0 0 0 .964-.964v-9.19a.967.967 0 0 0-.964-.963h-1.168v-1.488A5.046 5.046 0 0 0 11.98 6.35m.012 2.893a2.15 2.15 0 0 1 2.16 2.152v1.488H9.847v-1.488a2.15 2.15 0 0 1 2.145-2.152m7.382.503a.883.883 0 1 0 .07 1.763h3.027a.883.883 0 0 0 0-1.76h-3.027zM1.529 9.75a.883.883 0 0 0 0 1.76h2.999a.883.883 0 0 0 0-1.76zm10.46 6.774a1.28 1.28 0 0 1 .64 2.393v1.245a.63.63 0 0 1-1.259 0v-1.245a1.28 1.28 0 0 1 .619-2.393'/%3E%3C/svg%3E");-webkit-mask:var(--un-icon) no-repeat;mask:var(--un-icon) no-repeat;-webkit-mask-size:100% 100%;mask-size:100% 100%;background-color:currentColor;color:inherit;display:inline-block;vertical-align:middle;width:1.2em;height:1.2em}.i-simple-icons-linuxserver{--un-icon:url("data:image/svg+xml;utf8,%3Csvg viewBox='0 0 24 24' display='inline-block' vertical-align='middle' width='1.2em' height='1.2em' xmlns='http://www.w3.org/2000/svg' %3E%3Cpath fill='currentColor' d='M6.256.719c-5.944 2.988-8.144 11.402-4.44 16.91h.002a12.03 12.03 0 0 0 5.12 4.503v-.002c8.72 4.335 19.309-4.302 16.643-13.793c-.212-.891-1.081-3.824-3.742-6.095c-1.237-1.133-4.163-1.606-6.21-1.152a.5.5 0 0 0-.148.064c-.667.435-1.482.596-2.264.739a.356.356 0 0 0-.29.34c-.011.351.18.76.312 1.037c.33.643.925 1.02 1.629 1.11c2.584.739 4.583 3.083 4.814 5.828c-1.967 1.247-4.603 1.414-6.885-.477q-.054-.043-.107-.09c-.74-.598-1.884.314-1.389 1.21c1.93 2.526 5.008 3.41 7.842 2.907c-3.182.593-7.13 1.05-10.184-.017c-.705-1.455-1.771-2.733-3.08-3.649a7.5 7.5 0 0 1 1-4.498c.604-.926-.796-1.836-1.404-.936c-.769 1.12-1.249 2.415-1.47 3.75l.061-.4C2.548 5.162 3.862 2.42 6.256.72m10.668.719c.047.004.061.011.061.004c.394.032.783.205.816.445c.026.188-.17.372-.435.502a1.9 1.9 0 0 1-.547.168c-.473.066-.036-.247-.078-.553s-.55-.488-.076-.554a1.2 1.2 0 0 1 .26-.012m-2.892.472c.478.032.477.497 0 .53c-.478-.033-.478-.498 0-.53m-3.958 4.477a.636.636 0 0 0-.636.633V9.16c.348-.171.782-.167 1.187-.018a12.3 12.3 0 0 0 2.02.977a.636.636 0 0 0 .535-.63V7.02a.636.636 0 0 0-.637-.633Zm-1.87 3.922a.636.636 0 0 0-.635.637v2.469a.636.636 0 0 0 .634.635h2.47a.635.635 0 0 0 .636-.635v-.15a8.1 8.1 0 0 1-2.406-2.112l-.022-.03l-.017-.032a1.4 1.4 0 0 1-.17-.782Zm5.03 0c.69.2 1.408.313 2.108.26a.64.64 0 0 0-.51-.26zm-1.491 3.19a.636.636 0 0 0 .62.55h.8a8.4 8.4 0 0 1-1.42-.55'/%3E%3C/svg%3E");-webkit-mask:var(--un-icon) no-repeat;mask:var(--un-icon) no-repeat;-webkit-mask-size:100% 100%;mask-size:100% 100%;background-color:currentColor;color:inherit;display:inline-block;vertical-align:middle;width:1.2em;height:1.2em}.i-simple-icons-porkbun{--un-icon:url("data:image/svg+xml;utf8,%3Csvg viewBox='0 0 24 24' display='inline-block' vertical-align='middle' width='1.2em' height='1.2em' xmlns='http://www.w3.org/2000/svg' %3E%3Cpath fill='currentColor' d='M12 0A11.97 11.97 0 0 0 .018 11.982C.018 18.612 5.37 24 12 24s11.982-5.353 11.982-11.982C23.982 5.388 18.63 0 12 0M5.832 5.885c1.064.248 2.092.638 3.014 1.135c-1.1.531-1.987 1.382-2.66 2.375a3.4 3.4 0 0 1-.674-2.057c0-.532.107-.992.32-1.453m12.336 0c.213.425.32.921.32 1.453c0 .78-.248 1.49-.674 2.057c-.673-.993-1.596-1.844-2.66-2.375a10 10 0 0 1 3.014-1.135m-6.072.81a6.39 6.39 0 0 1 6.32 6.457v3.829a1.18 1.18 0 0 1-1.17 1.17a1.18 1.18 0 0 1-1.17-1.17v-.958H7.852v.957a1.18 1.18 0 0 1-1.17 1.17a1.18 1.18 0 0 1-1.17-1.17v-3.65c0-3.51 2.73-6.489 6.24-6.63q.173-.007.344-.005m1.5 3.8a.94.94 0 0 0-.922.921c0 .248.07.424.213.602c.141.212.353.354.566.46c-.142.071-.319.143-.496.143c-.213 0-.39.176-.39.389s.177.39.39.39h.178a1.56 1.56 0 0 0 1.383-.851c.39-.142.709-.39.921-.744c.071-.107.034-.249-.037-.213c-.106-.036-.212-.034-.283.072a1.04 1.04 0 0 1-.426.354v-.143c0-.39-.14-.709-.353-.992a.88.88 0 0 0-.744-.389m0 .53c.212 0 .353.141.388.354v.178c0 .177-.034.354-.105.496a1.06 1.06 0 0 1-.604-.426c-.035-.071-.07-.14-.07-.211c0-.24.206-.39.39-.39'/%3E%3C/svg%3E");-webkit-mask:var(--un-icon) no-repeat;mask:var(--un-icon) no-repeat;-webkit-mask-size:100% 100%;mask-size:100% 100%;background-color:currentColor;color:inherit;display:inline-block;vertical-align:middle;width:1.2em;height:1.2em}.i-simple-icons-portainer{--un-icon:url("data:image/svg+xml;utf8,%3Csvg viewBox='0 0 24 24' display='inline-block' vertical-align='middle' width='1.2em' height='1.2em' xmlns='http://www.w3.org/2000/svg' %3E%3Cpath fill='currentColor' d='M12.504 0v1.023l-.01-.015l-6.106 3.526H3.417v.751h5.359v3.638h1.942V5.284h1.786V15.7c.027 0 .54-.01.751.091V5.285h.531v10.608c.293.147.55.312.751.54V5.286h6.046v-.75h-1.267l-6.061-3.5V0zm0 1.87v2.664H7.889zm.751.031l4.56 2.633h-4.56zM9.142 5.285h1.21v1.686h-1.21zm-4.736 2.73v1.951h1.942v-1.95zm2.19 0v1.951h1.941v-1.95zm-2.19 2.171v1.951h1.942v-1.95zm2.19 0v1.951h1.941v-1.95zm2.18 0v1.951h1.942v-1.95zM4.36 12.43a3.73 3.73 0 0 0-.494 1.851c0 1.227.604 2.308 1.52 2.986c.239-.064.477-.1.724-.11c.1 0 .165.01.266.019c.284-1.191 1.383-1.988 2.665-1.988c.724 0 1.438.201 1.924.668c.229-.476.302-1.007.302-1.575c0-.65-.165-1.292-.494-1.85zm4.828 3.16c-1.21 0-2.226.844-2.492 1.97a1 1 0 0 0-.275-.009a2.56 2.56 0 0 0-2.564 2.556a2.565 2.565 0 0 0 3.096 2.5A2.58 2.58 0 0 0 9.233 24c.862 0 1.622-.43 2.09-1.081a2.557 2.557 0 0 0 4.186-1.97c0-.567-.193-1.099-.504-1.52a2.557 2.557 0 0 0-3.866-2.94a2.57 2.57 0 0 0-1.951-.898z'/%3E%3C/svg%3E");-webkit-mask:var(--un-icon) no-repeat;mask:var(--un-icon) no-repeat;-webkit-mask-size:100% 100%;mask-size:100% 100%;background-color:currentColor;color:inherit;display:inline-block;vertical-align:middle;width:1.2em;height:1.2em}.i-simple-icons-tldraw{--un-icon:url("data:image/svg+xml;utf8,%3Csvg viewBox='0 0 24 24' display='inline-block' vertical-align='middle' width='1.2em' height='1.2em' xmlns='http://www.w3.org/2000/svg' %3E%3Cpath fill='currentColor' d='M21.474 0H2.526C1.131 0 0 1.18 0 2.637v18.726C0 22.819 1.131 24 2.526 24h18.948C22.869 24 24 22.82 24 21.363V2.637C24 1.181 22.869 0 21.474 0m-11.01 5.388q.595-.607 1.474-.607q.854 0 1.448.607q.595.606.595 1.476c0 .87-.198 1.072-.595 1.476a1.95 1.95 0 0 1-1.448.607q-.879 0-1.474-.607q-.594-.606-.594-1.476c0-.87.198-1.072.594-1.476m3.13 11.49a4.9 4.9 0 0 1-2.018 2.136q-.724.422-1.19-.026q-.438-.422.26-1.002q.387-.29.646-.738q.258-.449.336-.923q.026-.21-.181-.21q-.517-.027-1.06-.581t-.543-1.37q0-.87.594-1.477a2.02 2.02 0 0 1 1.5-.633q.828 0 1.448.633q.62.605.724 1.37q.207 1.424-.517 2.822z'/%3E%3C/svg%3E");-webkit-mask:var(--un-icon) no-repeat;mask:var(--un-icon) no-repeat;-webkit-mask-size:100% 100%;mask-size:100% 100%;background-color:currentColor;color:inherit;display:inline-block;vertical-align:middle;width:1.2em;height:1.2em}.i-simple-icons-tmux{--un-icon:url("data:image/svg+xml;utf8,%3Csvg viewBox='0 0 24 24' display='inline-block' vertical-align='middle' width='1.2em' height='1.2em' xmlns='http://www.w3.org/2000/svg' %3E%3Cpath fill='currentColor' d='M24 2.251V10.5H12.45V0h9.3A2.25 2.25 0 0 1 24 2.251M12.45 11.4H24v10.5h-.008A2.25 2.25 0 0 1 21.75 24H2.25a2.247 2.247 0 0 1-2.242-2.1H0V2.251A2.25 2.25 0 0 1 2.25 0h9.3v21.6h.9zm11.242 10.5H.308a1.95 1.95 0 0 0 1.942 1.8h19.5a1.95 1.95 0 0 0 1.942-1.8'/%3E%3C/svg%3E");-webkit-mask:var(--un-icon) no-repeat;mask:var(--un-icon) no-repeat;-webkit-mask-size:100% 100%;mask-size:100% 100%;background-color:currentColor;color:inherit;display:inline-block;vertical-align:middle;width:1.2em;height:1.2em}.i-simple-icons-unraid{--un-icon:url("data:image/svg+xml;utf8,%3Csvg viewBox='0 0 24 24' display='inline-block' vertical-align='middle' width='1.2em' height='1.2em' xmlns='http://www.w3.org/2000/svg' %3E%3Cpath fill='currentColor' d='M11.406 8.528h1.17v6.926h-1.17zM1.17 15.454H0V8.528h1.17zm4.534.828h1.17v2.645h-1.17zm-2.86-2.969h1.169v4.282h-1.17zm5.703 0h1.17v4.282h-1.17zM22.83 8.528H24v6.926h-1.17zm-4.534-.81h-1.17V5.073h1.17zm2.86 2.95h-1.169V6.406h1.17zm-5.72 0h-1.17V6.406h1.17z'/%3E%3C/svg%3E");-webkit-mask:var(--un-icon) no-repeat;mask:var(--un-icon) no-repeat;-webkit-mask-size:100% 100%;mask-size:100% 100%;background-color:currentColor;color:inherit;display:inline-block;vertical-align:middle;width:1.2em;height:1.2em}.i-simple-icons-vaultwarden{--un-icon:url("data:image/svg+xml;utf8,%3Csvg viewBox='0 0 24 24' display='inline-block' vertical-align='middle' width='1.2em' height='1.2em' xmlns='http://www.w3.org/2000/svg' %3E%3Cpath fill='currentColor' d='M11.54.448c-.142.238-.333.524-.438.628c-.171.181-.18.172-.733-.371c-.667-.667-.772-.648-1.086.21c-.133.352-.295.6-.429.676c-.19.095-.285.066-.761-.276c-.8-.562-.943-.477-1.096.619c-.038.276-.114.476-.21.514c-.076.029-.4-.067-.704-.22c-.781-.37-.896-.285-.905.62c0 .371-.048.724-.095.771c-.067.067-.315.048-.781-.066c-.915-.22-.972-.162-.753.752c.114.467.133.715.067.781c-.048.048-.4.095-.772.095c-.914.01-.99.124-.61.905c.372.781.277 1.01-.447 1.105c-1.067.153-1.133.286-.543 1.076c.476.63.448.724-.343 1.01c-.847.324-.867.429-.2 1.095c.543.553.553.562.372.734c-.105.105-.39.295-.629.438c-.59.343-.59.571 0 .914c.238.143.524.334.629.438c.18.172.171.181-.372.734c-.667.667-.647.771.21 1.086c.352.133.6.295.676.428c.095.19.067.286-.276.762c-.562.8-.476.943.619 1.096c.276.038.476.114.514.21c.029.075-.066.4-.219.704c-.371.781-.286.895.62.905c.37 0 .723.048.77.095c.067.067.048.314-.066.781c-.219.915-.162.972.753.753c.466-.115.714-.134.78-.067c.048.048.096.4.096.771c.01.915.124.991.905.61c.78-.371 1.01-.276 1.105.448c.152 1.067.285 1.133 1.076.543c.629-.477.724-.448 1.01.343c.323.847.419.866 1.105.19c.666-.648.609-.657 1.161.276c.343.581.572.581.915 0c.552-.933.495-.924 1.162-.276c.686.676.78.657 1.095-.2c.133-.352.295-.6.429-.676c.19-.096.286-.067.762.276c.8.562.943.476 1.095-.619c.038-.276.114-.476.21-.514c.076-.029.4.066.705.219c.78.371.895.285.905-.62c0-.37.047-.723.095-.771c.066-.067.314-.048.78.067c.915.219.972.162.753-.753c-.114-.467-.133-.714-.067-.78c.048-.048.4-.096.772-.096c.914-.01.99-.124.61-.905c-.372-.78-.277-1.01.447-1.105c1.067-.152 1.134-.286.543-1.076c-.476-.629-.448-.724.343-1.01c.848-.324.867-.419.19-1.105c-.647-.666-.657-.61.277-1.162c.295-.18.438-.324.438-.457s-.143-.276-.438-.457c-.934-.552-.924-.495-.276-1.162c.676-.686.657-.781-.2-1.095c-.353-.134-.6-.296-.677-.429c-.095-.19-.067-.286.276-.762c.562-.8.477-.943-.619-1.095c-.276-.038-.476-.115-.514-.21c-.029-.076.067-.4.219-.705c.372-.78.286-.895-.619-.905c-.371 0-.724-.047-.772-.095c-.066-.066-.047-.314.067-.78c.22-.915.162-.972-.752-.753c-.467.114-.715.133-.781.066c-.048-.047-.096-.4-.096-.771c-.01-.915-.123-.99-.905-.61c-.78.372-1.01.277-1.104-.447c-.153-1.067-.286-1.134-1.077-.543c-.628.476-.724.447-1.01-.343c-.323-.848-.428-.867-1.095-.2c-.552.543-.562.552-.733.371c-.105-.105-.295-.39-.438-.628C12.274.143 12.13 0 11.998 0c-.134 0-.276.143-.457.448m.934 1.933c.105.105.19.315.19.476a.76.76 0 0 1-.19.477c-.41.41-1.143.104-1.143-.477c0-.362.305-.666.667-.666a.76.76 0 0 1 .476.19m-1.467 1.62c.924.895 1.057.895 1.981 0l.686-.667l.667.19c.762.21 1.943.715 1.943.838c0 .038-.895 2.63-1.99 5.744c-1.096 3.114-2.049 5.838-2.106 6.058c-.067.228-.152.41-.19.41s-.115-.163-.162-.353c-.057-.2-1-2.943-2.105-6.106a604 604 0 0 1-2.02-5.79c0-.115 2.115-.934 2.563-.982c.028-.01.352.286.733.657m-3.343 9.6c1.352 3.791 2.429 6.906 2.4 6.934c-.067.077-1.076-.219-1.505-.447c-.343-.172-.352-.19-.476-1c-.076-.524-.19-.905-.305-1.058c-.19-.238-.219-.238-.867-.171c-1.428.162-1.371.18-1.933-.572c-.61-.81-1.181-1.943-1.457-2.905c-.162-.533-.22-1.066-.257-2.095l-.048-1.381l.857-.457c1.153-.6 1.181-.705.59-1.877c-.428-.847-.428-.8.125-1.6c.152-.229.314-.38.352-.333c.038.038 1.171 3.171 2.524 6.962m11.82-6.21l.238.4l-.39.772c-.59 1.18-.562 1.286.58 1.886l.848.447v1.077c0 1.247-.171 2.219-.58 3.257c-.315.79-.944 1.838-1.449 2.429l-.323.38l-.753-.113a9 9 0 0 0-1.01-.115c-.4 0-.6.353-.733 1.286l-.124.829l-.504.219c-.581.257-1.286.467-1.353.39c-.038-.038 4.01-11.524 4.848-13.772l.095-.238l.191.238c.105.123.295.41.419.628M3.76 8.715c.447.438.18 1.095-.448 1.095c-.4 0-.648-.238-.648-.628c0-.629.658-.915 1.096-.467m17.22-.133c.277.152.353.266.353.6c0 .38-.248.628-.638.628c-.638 0-.915-.647-.458-1.095c.258-.267.43-.295.743-.133M7.236 19.154c.343.82-.829 1.324-1.21.515c-.142-.296-.142-.343.01-.572c.324-.495.99-.467 1.2.057m10.563-.257c.238.19.305.524.153.82c-.391.761-1.524.218-1.191-.563c.171-.428.667-.552 1.038-.257'/%3E%3C/svg%3E");-webkit-mask:var(--un-icon) no-repeat;mask:var(--un-icon) no-repeat;-webkit-mask-size:100% 100%;mask-size:100% 100%;background-color:currentColor;color:inherit;display:inline-block;vertical-align:middle;width:1.2em;height:1.2em}.i-twemoji-cold-face{background:url("data:image/svg+xml;utf8,%3Csvg viewBox='0 0 36 36' display='inline-block' vertical-align='middle' width='1.2em' height='1.2em' xmlns='http://www.w3.org/2000/svg' %3E%3Ccircle cx='18' cy='18' r='18' fill='%2350A5E6'/%3E%3Cellipse cx='11.985' cy='15.188' fill='%231C6399' rx='2.5' ry='3.5'/%3E%3Cellipse cx='23.985' cy='15.188' fill='%231C6399' rx='2.5' ry='3.5'/%3E%3Cpath fill='%23FFF' d='M24.985 21.833a4 4 0 0 1 0 8h-14a4 4 0 0 1 0-8z'/%3E%3Cpath fill='%231C6399' d='M24.985 20.812h-14c-2.757 0-5 2.243-5 5s2.243 5 5 5h14c2.757 0 5-2.243 5-5s-2.243-5-5-5m0 2a3 3 0 0 1 2.949 2.5h-3.449v-2.5zm-1.5 0v2.5h-3v-2.5zm-4 0v2.5h-3v-2.5zm-4 0v2.5h-3v-2.5zm-4.5 0h.5v2.5h-3.45a3 3 0 0 1 2.95-2.5m0 6a3 3 0 0 1-2.949-2.5h3.449v2.5zm1.5 0v-2.5h3v2.5zm4 0v-2.5h3v2.5zm4 0v-2.5h3v2.5zm4.5 0h-.5v-2.5h3.449a3 3 0 0 1-2.949 2.5'/%3E%3Cpath fill='%23BBDDF5' d='M35.756 15.188c0-.445-.046 2.24-3.752 3.394c-1.461.455-1.288 2.58-1.265 3.152c.08 1.975.398 3.892.497 4.392c.1.507.507 2.106.602 2.589c.105.532.241 2.406.333 2.873c.111.563.215.968.3 1.398c.184.929.424 1.598.832 1.598c.409 0 .416-1.125.599-2.053c.085-.429.107-.787.218-1.349c.092-.464.363-3.641.465-4.156c.097-.491.636-2.568.734-3.067c.1-.507.399-2.494.479-2.979c.478-2.897-.042-5.791-.042-5.792M.313 21.375c0-.29.613 1.164 1.148 1.488c.69.418 1.23 1.2 2.04 1.887s.808 1.974.776 2.594c-.136 2.656-.486 5.299-.562 5.625c-.076.331-.358 2.823-.73 2.823s-.553-.878-.693-1.484l-.225-.977c-.07-.302-.12-.631-.2-.976c-.072-.314-.421-2.587-.496-2.913c-.076-.331-.406-1.643-.479-1.958c-.08-.347-.114-.684-.19-.987c-.327-1.3-.389-5.121-.389-5.122'/%3E%3Cpath fill='%231C6399' d='M5.986 11.375a1 1 0 0 1-.004-2c.156-.002 3.569-.086 6.205-3.6a1 1 0 0 1 1.6 1.2c-3.263 4.35-7.617 4.4-7.801 4.4m24 0c-.184 0-4.537-.05-7.8-4.4a1 1 0 1 1 1.599-1.2c2.641 3.521 6.062 3.599 6.206 3.6c.55.006.994.456.991 1.005a.996.996 0 0 1-.996.995'/%3E%3Cpath fill='%23BBDDF5' d='M24.266 1.125s-.991-.421-1.317-.521C22.662.516 21.756.328 21.196.22c-.625-.121-1.294-.115-1.294-.115s-.03.402.114 1.025c.116.502.404 1.198.458 1.559c.059.391.068.855.141 1.348c.064.426.128.88.197 1.342c.067.446.182.894.249 1.341c.07.464.102.925.167 1.353c.074.496-.01.978.049 1.371c.121.806.333 1.932.562 1.932s.431-1.019.552-1.828c.059-.391-.027-.695.047-1.188c.064-.426.118-.85.188-1.312c.067-.446.121-.882.188-1.328c.07-.464.061-.916.125-1.344c.074-.496.363-1.107.422-1.5c.119-.806.905-1.751.905-1.751M5.875 9.379s.731-.164 1.427-.309c.453-.094.812-.459 1.553-.729c.771-.281 1.267-.524 1.267-.524s.063 1.305-.109 1.956c-.139.525-.212 1.203-.276 1.58c-.07.408-.109.889-.197 1.404c-.076.445-.216.91-.299 1.394c-.08.467-.144 1.014-.224 1.481c-.083.485-.105.902-.182 1.349c-.089.518-.022.57-.093.98c-.145.843-.165.727-.212 1.186s-.394.516-.544.18s.009-.521-.136-1.367c-.07-.408-.327-1.487-.41-1.97c-.08-.467-.188-1.199-.268-1.666c-.083-.485-.104-1.267-.181-1.715c-.089-.518-.225-.838-.295-1.248c-.145-.841-.821-1.982-.821-1.982'/%3E%3C/svg%3E") no-repeat;background-size:100% 100%;background-color:transparent;display:inline-block;vertical-align:middle;width:1.2em;height:1.2em}.i-twemoji-desktop-computer{background:url("data:image/svg+xml;utf8,%3Csvg viewBox='0 0 36 36' display='inline-block' vertical-align='middle' width='1.2em' height='1.2em' xmlns='http://www.w3.org/2000/svg' %3E%3Cpath fill='%23CCD6DD' d='M36 22a4 4 0 0 1-4 4H4a4 4 0 0 1-4-4V4a4 4 0 0 1 4-4h28a4 4 0 0 1 4 4z'/%3E%3Cpath fill='%235DADEC' d='M4 4h28v18H4z'/%3E%3Cpath fill='%23CCD6DD' d='M13 26h10v6H13z'/%3E%3Cpath fill='%239AAAB4' d='M13 26h10v2H13z'/%3E%3Cpath fill='%23E1E8ED' d='M36 33a3 3 0 0 0-3-3H3a3 3 0 1 0 0 6h30a3 3 0 0 0 3-3'/%3E%3Cpath fill='%23F5F8FA' d='M3 32h2v2H3zm4 0h2v2H7zm4 0h2v2h-2zm4 0h2v2h-2zm4 0h2v2h-2zm4 0h2v2h-2zm4 0h2v2h-2zm4 0h2v2h-2z'/%3E%3C/svg%3E") no-repeat;background-size:100% 100%;background-color:transparent;display:inline-block;vertical-align:middle;width:1.2em;height:1.2em}.i-twemoji-green-salad{background:url("data:image/svg+xml;utf8,%3Csvg viewBox='0 0 36 36' display='inline-block' vertical-align='middle' width='1.2em' height='1.2em' xmlns='http://www.w3.org/2000/svg' %3E%3Cpath fill='%23CCD6DD' d='M18 35C3.042 35 1 21 1 17h34c0 2-1.958 18-17 18'/%3E%3Cpath fill='%2366757F' d='M35 17.056c0 5.216-7.611 9.444-17 9.444S1 22.271 1 17.056s7.611-8.444 17-8.444c9.389-.001 17 3.228 17 8.444'/%3E%3Cpath fill='%2377B255' d='M2.708 18.875c-.808-1.161-2.333-3.5-.708-7c.708-1.833 2.18-3.027 2.375-2.458c.458 1.333 1.375 2.5 2.75 2.375c-.018.473-.669-4.309 1.625-5.584c1.125-.625 2.333.375 3.708 2.583c2.202 3.537 7.811 1.884 9.385.958c1.594-.938 2.99-1.552 2.573-4.062c-.092-.551.743-1.029 1.595-.573c1.431.766 3.498 2.671 3.863 4.761c1.021.271 1.786-.163 2.375-1.354c.292-.59 1.292-.729 1.72.041c.754 1.356 1.992 5.527.239 9.105c-2 4.083-5.042 6.25-11.875 7.125s-15.625-.167-19.625-5.917'/%3E%3Cpath fill='%235C913B' d='M19.417 10.146c0 2.106-1.81 3.812-4.042 3.812s-4.042-1.707-4.042-3.812s1.81-3.812 4.042-3.812c2.232-.001 4.042 1.707 4.042 3.812'/%3E%3Cpath fill='%23C6E5B3' d='M18.417 10.146c0 1.585-1.362 2.869-3.042 2.869s-3.042-1.285-3.042-2.869s1.362-2.87 3.042-2.87c1.68.001 3.042 1.286 3.042 2.87'/%3E%3Cellipse cx='8.167' cy='14.5' fill='%23292F33' rx='2.292' ry='2'/%3E%3Cpath fill='%23DD2E44' d='M17.524 15.182c1.267 2.388-2.104.951-4.614 2.284c-2.511 1.333-3.209 4.929-4.477 2.541s-.26-5.404 2.25-6.737c2.511-1.332 5.574-.476 6.841 1.912'/%3E%3Cellipse cx='24.167' cy='12.5' fill='%23292F33' rx='2.292' ry='2'/%3E%3Cpath fill='%239266CC' d='M29.117 20.129c-1.564 1.48-1.178-1.412-2.734-3.056c-1.558-1.644-4.466-1.415-2.903-2.896s4.094-1.349 5.65.294s1.551 4.177-.013 5.658'/%3E%3Cpath fill='%23E1E8ED' d='M28.117 21.129c-1.564 1.48-1.178-1.412-2.734-3.057c-1.558-1.643-4.466-1.415-2.903-2.896s4.094-1.349 5.65.294s1.551 4.178-.013 5.659'/%3E%3Cpath fill='%23DD2E44' d='M24.013 19.928c.781 2.062-1.798.555-3.966 1.377c-2.166.821-3.1 3.658-3.881 1.597s.343-4.398 2.509-5.219s4.556.185 5.338 2.245'/%3E%3Cpath fill='%23EA596E' d='M8.958 19.084c-.167-1.542 2.833-8.418 8.167-2.417c-1.25.208-4.292.208-5.667 2.125s-2.625.208-2.5.292'/%3E%3Cpath fill='%23A6D388' d='M4.917 19.709c-.728-.971 1.75-3.209 3.625-1.293c.792-.958 4.708-2.874 6.167 1.293c.667-.75 6.125-.917 6.208 3.708c.041.625-6.295.506-9.542-.25c-1.792-.417-5.083-1.625-6.458-3.458M26 22.458c-1.167.315.793-5.125 4.459-4.208c.125-1 .916-4.292 3.208-3.708c.083.958.041 5.832-7.667 7.916'/%3E%3C/svg%3E") no-repeat;background-size:100% 100%;background-color:transparent;display:inline-block;vertical-align:middle;width:1.2em;height:1.2em}.i-twemoji-man-facepalming{background:url("data:image/svg+xml;utf8,%3Csvg viewBox='0 0 36 36' display='inline-block' vertical-align='middle' width='1.2em' height='1.2em' xmlns='http://www.w3.org/2000/svg' %3E%3Cpath fill='%234289C1' d='M27 27H10v9h21v-5a4 4 0 0 0-4-4'/%3E%3Cpath fill='%232A6797' d='M26 32h1v4h-1z'/%3E%3Cpath fill='%23FFDC5D' d='M9 5.938V17c0 4.971 4.029 9 9 9s9-4.029 9-9V6.25z'/%3E%3Cpath fill='%23C1694F' d='M19 19.5h-2a.5.5 0 0 1 0-1h2a.5.5 0 0 1 0 1'/%3E%3Cpath fill='%23FFDC5D' d='M10.847 13.715c0 1.58-.8 2.861-1.788 2.861s-1.788-1.281-1.788-2.861s.801-2.861 1.788-2.861s1.788 1.281 1.788 2.861m17.882 0c0 1.58-.8 2.861-1.788 2.861s-1.788-1.281-1.788-2.861s.8-2.861 1.788-2.861s1.788 1.281 1.788 2.861'/%3E%3Cpath fill='%23FFAC33' d='M18 .823c-7.019 0-10.139 4.684-10.139 8.588s1.343 4.986 1.56 3.903c.78-3.903 3.12-5.101 3.12-5.101c4.68 3.904 3.9.781 3.9.781c4.679 4.684 2.34 0 2.34 0c1.56 1.562 6.239 1.562 6.239 1.562s.78 1.198 1.559 2.759c.78 1.562 1.56 0 1.56-3.903c0-3.905-3.9-8.589-10.139-8.589'/%3E%3Cpath fill='%23FFDC5D' d='M15 24v4a3 3 0 1 0 6 0v-4z'/%3E%3Cpath fill='%232A6797' d='m18.734 18.386l1.827.691s-6.529 13.746-7.413 15.022s-1.87 2.055-4.57 1.76zM26 32h1v4h-1z'/%3E%3Cpath fill='%23EF9645' d='M13.513 7.846c.945-.291 1.598.508 1.77 1.195l.284 1.14l.756-2.155a2 2 0 0 1 2.549-1.225l3.774 1.324a2 2 0 0 1 1.225 2.549l-2.648 7.549s-.331.944-1.275.613l-5.662-1.986l-.613-1.275l.345-.984l-1.226-4.929c-.17-.688.044-1.607.721-1.816'/%3E%3Cpath fill='%23662113' d='M24.157 16.371c-.026-.058-.596-1.288-1.747-1.529l-.49 1.395c.037-.001.063-.009.101-.009c1.162 0 1.76.422 1.774.432a.24.24 0 0 0 .292-.005a.24.24 0 0 0 .07-.284'/%3E%3Cpath fill='%234F140B' d='M22.021 14.792c-1.417 0-2.107 1.515-2.136 1.58a.24.24 0 0 0 .069.283c.084.068.204.07.292.007c.005-.004.578-.397 1.673-.423l.49-1.395a1.8 1.8 0 0 0-.388-.052'/%3E%3Cpath fill='%23C1694F' d='M20.995 23.364s-.56-1.117-1.678-1.681c-.246.514-.516 1.078-.807 1.681z'/%3E%3Cpath fill='%23EF9645' d='m18.734 18.386l-1.9 3.234l-1.024 1.744l-1.16 1.974L15 28c0 .594.178 1.144.476 1.61c.98-1.986 2.097-4.295 3.035-6.246l.807-1.681c.741-1.547 1.244-2.606 1.244-2.606z'/%3E%3Cpath fill='%23894935' d='M19.317 21.683a2.9 2.9 0 0 0-1.322-.319c-.438 0-.819.107-1.161.256l-1.024 1.744h2.701z'/%3E%3Cpath fill='%23FFDC5D' d='M12.513 7.657a1.284 1.284 0 0 1 1.555.934l.284 1.14l.756-2.155a2 2 0 0 1 2.549-1.225l3.774 1.324a2 2 0 0 1 1.225 2.549l-2.648 7.549s-.331.944-1.275.613L13.072 16.4l-.613-1.275l.345-.984l-1.226-4.929a1.283 1.283 0 0 1 .935-1.555'/%3E%3Cpath fill='%23EF9645' d='m18.743 12.054l1.655-4.718l.944.331l-1.655 4.718zm-2.83-.993l1.656-4.718l.943.331l-1.655 4.718z'/%3E%3Cpath fill='%234289C1' d='M14.278 29.85s-1.719 3.579-2.107 4.416C11.484 35.75 10 36 10 36c-8 0-3.622-8.343-3.622-8.343l6.432-11.846l6.541 2.58z'/%3E%3C/svg%3E") no-repeat;background-size:100% 100%;background-color:transparent;display:inline-block;vertical-align:middle;width:1.2em;height:1.2em}.i-twemoji-party-popper{background:url("data:image/svg+xml;utf8,%3Csvg viewBox='0 0 36 36' display='inline-block' vertical-align='middle' width='1.2em' height='1.2em' xmlns='http://www.w3.org/2000/svg' %3E%3Cpath fill='%23DD2E44' d='M11.626 7.488a1.4 1.4 0 0 0-.268.395l-.008-.008L.134 33.141l.011.011c-.208.403.14 1.223.853 1.937c.713.713 1.533 1.061 1.936.853l.01.01L28.21 24.735l-.008-.009c.147-.07.282-.155.395-.269c1.562-1.562-.971-6.627-5.656-11.313c-4.687-4.686-9.752-7.218-11.315-5.656'/%3E%3Cpath fill='%23EA596E' d='M13 12L.416 32.506l-.282.635l.011.011c-.208.403.14 1.223.853 1.937c.232.232.473.408.709.557L17 17z'/%3E%3Cpath fill='%23A0041E' d='M23.012 13.066c4.67 4.672 7.263 9.652 5.789 11.124c-1.473 1.474-6.453-1.118-11.126-5.788c-4.671-4.672-7.263-9.654-5.79-11.127c1.474-1.473 6.454 1.119 11.127 5.791'/%3E%3Cpath fill='%23AA8DD8' d='M18.59 13.609a1 1 0 0 1-.734.215c-.868-.094-1.598-.396-2.109-.873c-.541-.505-.808-1.183-.735-1.862c.128-1.192 1.324-2.286 3.363-2.066c.793.085 1.147-.17 1.159-.292c.014-.121-.277-.446-1.07-.532c-.868-.094-1.598-.396-2.11-.873c-.541-.505-.809-1.183-.735-1.862c.13-1.192 1.325-2.286 3.362-2.065c.578.062.883-.057 1.012-.134c.103-.063.144-.123.148-.158c.012-.121-.275-.446-1.07-.532a1 1 0 0 1-.886-1.102a.997.997 0 0 1 1.101-.886c2.037.219 2.973 1.542 2.844 2.735c-.13 1.194-1.325 2.286-3.364 2.067c-.578-.063-.88.057-1.01.134c-.103.062-.145.123-.149.157c-.013.122.276.446 1.071.532c2.037.22 2.973 1.542 2.844 2.735s-1.324 2.286-3.362 2.065c-.578-.062-.882.058-1.012.134c-.104.064-.144.124-.148.158c-.013.121.276.446 1.07.532a1 1 0 0 1 .52 1.773'/%3E%3Cpath fill='%2377B255' d='M30.661 22.857c1.973-.557 3.334.323 3.658 1.478c.324 1.154-.378 2.615-2.35 3.17c-.77.216-1.001.584-.97.701c.034.118.425.312 1.193.095c1.972-.555 3.333.325 3.657 1.479c.326 1.155-.378 2.614-2.351 3.17c-.769.216-1.001.585-.967.702s.423.311 1.192.095a1 1 0 1 1 .54 1.925c-1.971.555-3.333-.323-3.659-1.479c-.324-1.154.379-2.613 2.353-3.169c.77-.217 1.001-.584.967-.702c-.032-.117-.422-.312-1.19-.096c-1.974.556-3.334-.322-3.659-1.479c-.325-1.154.378-2.613 2.351-3.17c.768-.215.999-.585.967-.701c-.034-.118-.423-.312-1.192-.096a1 1 0 1 1-.54-1.923'/%3E%3Cpath fill='%23AA8DD8' d='M23.001 20.16a1.001 1.001 0 0 1-.626-1.781c.218-.175 5.418-4.259 12.767-3.208a1 1 0 1 1-.283 1.979c-6.493-.922-11.187 2.754-11.233 2.791a1 1 0 0 1-.625.219'/%3E%3Cpath fill='%2377B255' d='M5.754 16a1 1 0 0 1-.958-1.287c1.133-3.773 2.16-9.794.898-11.364c-.141-.178-.354-.353-.842-.316c-.938.072-.849 2.051-.848 2.071a1 1 0 1 1-1.994.149c-.103-1.379.326-4.035 2.692-4.214c1.056-.08 1.933.287 2.552 1.057c2.371 2.951-.036 11.506-.542 13.192a1 1 0 0 1-.958.712'/%3E%3Ccircle cx='25.5' cy='9.5' r='1.5' fill='%235C913B'/%3E%3Ccircle cx='2' cy='18' r='2' fill='%239266CC'/%3E%3Ccircle cx='32.5' cy='19.5' r='1.5' fill='%235C913B'/%3E%3Ccircle cx='23.5' cy='31.5' r='1.5' fill='%235C913B'/%3E%3Ccircle cx='28' cy='4' r='2' fill='%23FFCC4D'/%3E%3Ccircle cx='32.5' cy='8.5' r='1.5' fill='%23FFCC4D'/%3E%3Ccircle cx='29.5' cy='12.5' r='1.5' fill='%23FFCC4D'/%3E%3Ccircle cx='7.5' cy='23.5' r='1.5' fill='%23FFCC4D'/%3E%3C/svg%3E") no-repeat;background-size:100% 100%;background-color:transparent;display:inline-block;vertical-align:middle;width:1.2em;height:1.2em}.i-twemoji-wrench{background:url("data:image/svg+xml;utf8,%3Csvg viewBox='0 0 36 36' display='inline-block' vertical-align='middle' width='1.2em' height='1.2em' xmlns='http://www.w3.org/2000/svg' %3E%3Cpath fill='%238899A6' d='M27.989 19.977c-.622 0-1.225.078-1.806.213L15.811 9.818a8 8 0 0 0 .212-1.806A8.01 8.01 0 0 0 8.012 0C7.11 0 5.91.916 6.909 1.915l2.997 2.997s.999 1.998-.999 3.995s-3.996.998-3.996.998L1.915 6.909C.916 5.91 0 7.105 0 8.012a8.01 8.01 0 0 0 8.012 8.012a8 8 0 0 0 1.806-.212l10.371 10.371a8 8 0 0 0-.213 1.806A8.01 8.01 0 0 0 27.988 36c.901 0 2.101-.916 1.102-1.915l-2.997-2.997s-.999-1.998.999-3.995s3.995-.999 3.995-.999l2.997 2.997c1 .999 1.916-.196 1.916-1.102a8.01 8.01 0 0 0-8.011-8.012'/%3E%3C/svg%3E") no-repeat;background-size:100% 100%;background-color:transparent;display:inline-block;vertical-align:middle;width:1.2em;height:1.2em}.container{width:100%}@media (min-width: 640px){.container{max-width:640px}}@media (min-width: 768px){.container{max-width:768px}}@media (min-width: 1024px){.container{max-width:1024px}}@media (min-width: 1280px){.container{max-width:1280px}}@media (min-width: 1536px){.container{max-width:1536px}}.visible{visibility:visible}.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.sticky{position:sticky}.static{position:static}[start~="2"]{inset-inline-start:.5rem}.grid{display:grid}.m14\.386{margin:3.5965rem}[m128=""]{margin:32rem}[m8=""]{margin:2rem}.my{margin-top:1rem;margin-bottom:1rem}.me{margin-inline-end:1rem}.block{display:block}.inline-block{display:inline-block}.contents{display:contents}.hidden{display:none}.h1{height:.25rem}.h2{height:.5rem}.h3{height:.75rem}.h4{height:1rem}.h5{height:1.25rem}.h6{height:1.5rem}.flex{display:flex}.flex-shrink{flex-shrink:1}.flex-grow{flex-grow:1}.flex-wrap{flex-wrap:wrap}.transform{transform:translate(var(--un-translate-x)) translateY(var(--un-translate-y)) translateZ(var(--un-translate-z)) rotate(var(--un-rotate)) rotateX(var(--un-rotate-x)) rotateY(var(--un-rotate-y)) rotate(var(--un-rotate-z)) skew(var(--un-skew-x)) skewY(var(--un-skew-y)) scaleX(var(--un-scale-x)) scaleY(var(--un-scale-y)) scaleZ(var(--un-scale-z))}.border{border-width:1px}.px{padding-left:1rem;padding-right:1rem}.uppercase{text-transform:uppercase}.lowercase{text-transform:lowercase}.underline{text-decoration-line:underline}.outline{outline-style:solid}.blur{--un-blur:blur(8px);filter:var(--un-blur) var(--un-brightness) var(--un-contrast) var(--un-drop-shadow) var(--un-grayscale) var(--un-hue-rotate) var(--un-invert) var(--un-saturate) var(--un-sepia)}.filter{filter:var(--un-blur) var(--un-brightness) var(--un-contrast) var(--un-drop-shadow) var(--un-grayscale) var(--un-hue-rotate) var(--un-invert) var(--un-saturate) var(--un-sepia)}.transition{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.ease{transition-timing-function:cubic-bezier(.4,0,.2,1)}.ease-in{transition-timing-function:cubic-bezier(.4,0,1,1)}.ease-out{transition-timing-function:cubic-bezier(0,0,.2,1)}.VPLocalSearchBox[data-v-4278b464]{position:fixed;z-index:100;top:0;right:0;bottom:0;left:0;display:flex}.backdrop[data-v-4278b464]{position:absolute;top:0;right:0;bottom:0;left:0;background:var(--vp-backdrop-bg-color);transition:opacity .5s}.shell[data-v-4278b464]{position:relative;padding:12px;margin:64px auto;display:flex;flex-direction:column;gap:16px;background:var(--vp-local-search-bg);width:min(100vw - 60px,900px);height:min-content;max-height:min(100vh - 128px,900px);border-radius:6px}@media (max-width: 767px){.shell[data-v-4278b464]{margin:0;width:100vw;height:100vh;max-height:none;border-radius:0}}.search-bar[data-v-4278b464]{border:1px solid var(--vp-c-divider);border-radius:4px;display:flex;align-items:center;padding:0 12px;cursor:text}@media (max-width: 767px){.search-bar[data-v-4278b464]{padding:0 8px}}.search-bar[data-v-4278b464]:focus-within{border-color:var(--vp-c-brand-1)}.local-search-icon[data-v-4278b464]{display:block;font-size:18px}.navigate-icon[data-v-4278b464]{display:block;font-size:14px}.search-icon[data-v-4278b464]{margin:8px}@media (max-width: 767px){.search-icon[data-v-4278b464]{display:none}}.search-input[data-v-4278b464]{padding:6px 12px;font-size:inherit;width:100%}@media (max-width: 767px){.search-input[data-v-4278b464]{padding:6px 4px}}.search-actions[data-v-4278b464]{display:flex;gap:4px}@media (any-pointer: coarse){.search-actions[data-v-4278b464]{gap:8px}}@media (min-width: 769px){.search-actions.before[data-v-4278b464]{display:none}}.search-actions button[data-v-4278b464]{padding:8px}.search-actions button[data-v-4278b464]:not([disabled]):hover,.toggle-layout-button.detailed-list[data-v-4278b464]{color:var(--vp-c-brand-1)}.search-actions button.clear-button[data-v-4278b464]:disabled{opacity:.37}.search-keyboard-shortcuts[data-v-4278b464]{font-size:.8rem;opacity:75%;display:flex;flex-wrap:wrap;gap:16px;line-height:14px}.search-keyboard-shortcuts span[data-v-4278b464]{display:flex;align-items:center;gap:4px}@media (max-width: 767px){.search-keyboard-shortcuts[data-v-4278b464]{display:none}}.search-keyboard-shortcuts kbd[data-v-4278b464]{background:#8080801a;border-radius:4px;padding:3px 6px;min-width:24px;display:inline-block;text-align:center;vertical-align:middle;border:1px solid rgba(128,128,128,.15);box-shadow:0 2px 2px #0000001a}.results[data-v-4278b464]{display:flex;flex-direction:column;gap:6px;overflow-x:hidden;overflow-y:auto;overscroll-behavior:contain}.result[data-v-4278b464]{display:flex;align-items:center;gap:8px;border-radius:4px;transition:none;line-height:1rem;border:solid 2px var(--vp-local-search-result-border);outline:none}.result>div[data-v-4278b464]{margin:12px;width:100%;overflow:hidden}@media (max-width: 767px){.result>div[data-v-4278b464]{margin:8px}}.titles[data-v-4278b464]{display:flex;flex-wrap:wrap;gap:4px;position:relative;z-index:1001;padding:2px 0}.title[data-v-4278b464]{display:flex;align-items:center;gap:4px}.title.main[data-v-4278b464]{font-weight:500}.title-icon[data-v-4278b464]{opacity:.5;font-weight:500;color:var(--vp-c-brand-1)}.title svg[data-v-4278b464]{opacity:.5}.result.selected[data-v-4278b464]{--vp-local-search-result-bg: var(--vp-local-search-result-selected-bg);border-color:var(--vp-local-search-result-selected-border)}.excerpt-wrapper[data-v-4278b464]{position:relative}.excerpt[data-v-4278b464]{opacity:50%;pointer-events:none;max-height:140px;overflow:hidden;position:relative;margin-top:4px}.result.selected .excerpt[data-v-4278b464]{opacity:1}.excerpt[data-v-4278b464] *{font-size:.8rem!important;line-height:130%!important}.titles[data-v-4278b464] mark,.excerpt[data-v-4278b464] mark{background-color:var(--vp-local-search-highlight-bg);color:var(--vp-local-search-highlight-text);border-radius:2px;padding:0 2px}.excerpt[data-v-4278b464] .vp-code-group .tabs{display:none}.excerpt[data-v-4278b464] .vp-code-group div[class*=language-]{border-radius:8px!important}.excerpt-gradient-bottom[data-v-4278b464]{position:absolute;bottom:-1px;left:0;width:100%;height:8px;background:linear-gradient(transparent,var(--vp-local-search-result-bg));z-index:1000}.excerpt-gradient-top[data-v-4278b464]{position:absolute;top:-1px;left:0;width:100%;height:8px;background:linear-gradient(var(--vp-local-search-result-bg),transparent);z-index:1000}.result.selected .titles[data-v-4278b464],.result.selected .title-icon[data-v-4278b464]{color:var(--vp-c-brand-1)!important}.no-results[data-v-4278b464]{font-size:.9rem;text-align:center;padding:12px}svg[data-v-4278b464]{flex:none} diff --git a/.vitepress/dist/assets/x11-guide.md.BPhK1sNP.js b/.vitepress/dist/assets/x11-guide.md.BPhK1sNP.js new file mode 100644 index 0000000..91e9dc3 --- /dev/null +++ b/.vitepress/dist/assets/x11-guide.md.BPhK1sNP.js @@ -0,0 +1 @@ +import{_ as t,c as a,a3 as n,o as i}from"./chunks/framework.DtMx7FFi.js";const m=JSON.parse('{"title":"X11-Guide","description":"","frontmatter":{"title":"X11-Guide"},"headers":[],"relativePath":"x11-guide.md","filePath":"x11-guide.md"}'),o={name:"x11-guide.md"};function l(r,e,s,c,h,d){return i(),a("div",null,e[0]||(e[0]=[n('

Windows Setup: ​

Windows X11 Window Manager Client/Server ​

Installation:

  1. Install VCXSRV on your Windows machine.
  2. Follow the install instructions until able to close.

Running the X11 Local Server (aka the client that connects to the real X11 server) ​

  1. Locate the newly installed XLaunch application, open it.
  2. You'll want to modify the display settings as follows:
    • Select Multiple windows for the program displays, hit next
    • Select the Start no client option on the next page, hit next.
    • Options on this page are optional, you DO NOT want the Disable access control selected on this page.
    • Hit next.
    • Click the Save configuration button on this page, save this config somewhere you won't forget about it.
    • Click finish.
    • Allow the access to the network if Windows Defender Firewall asks.
    • Congratulations, you've setup the local X11 server!
  3. Make sure the XLaunch application is in the system tray before running Putty OR Terminal SSH

Connecting to the 'domain.tld' X11 Server ​

  1. First, verify the XLaunch application is running in the System Tray, then follow the instructions below based on your preferred SSH method.

PuTTY Instructions (including setting up a profile for easier management) ​

  1. Highly recommend the use of a profile if you are going to use PuTTY, as you can save/load the config up really quick instead of having to put in these values every time.
  2. Enter in the hostname, (this is optional if making a profile, as the IP address is dynamic)
  3. In the connection category, under the data subcategory, the auto-login username can be set if using a profile.
  4. Expand the SSH subcategory (in connection) and set the credentials if using a profile to the private key (if made)
  5. Now, click on X11 subcategory (in connection) and click the checkbox for 'Enable X11 forwarding'
  6. Set the X Display Location textbox to the value '127.0.0.1:0' (no quotes).
  7. Return to the Session category, and type in a name for the saved session, then hit the save button. Now, all of these changes can be loaded instead of put in each time.
  8. Now, type in the IP address of the 'domain.tld' and hit the 'Open' button.
  9. If you'd like to verify the X11 connectivity, type 'xclock' into the terminal. This will make a little analog clock appear in a separate window.

Windows Powershell Instructions ​

  1. You'll want to set a variable in the command prompt, run $env:DISPLAY="127.0.0.1:0" (exactly as written) to set the X Window Manager as the display output.
  2. Use the command 'ssh -X username@domain.tld' to connect, replacing username with your username, and domain.tld with the current dynIP.
  3. If you'd like to verify the X11 connectivity, type 'xclock' into the terminal. This will make a little analog clock appear in a separate window.

Windows Command Prompt Instructions (a.k.a. CMD) ​

  1. You'll want to set a variable in the command prompt, run set DISPLAY=127.0.0.1:0 to set the X Window Manager as the display output.
  2. Use the command 'ssh -X username@domain.tld' to connect, replacing username with your username, and domain.tld with the current dynIP.
  3. If you'd like to verify the X11 connectivity, type 'xclock' into the terminal. This will make a little analog clock appear in a separate window.

MacOS Setup: ​

MacOS X11 Window Manager Client/Server ​

Installation:

  1. Install XQuartz (https://www.xquartz.org/) using the MacOS pkg file.
  2. Follow the install instructions until able to close (you'll have to logout to complete install).

Running the X11 Local Server on Mac (aka the client that connects to the real X11 server) ​

  1. Locate the newly installed XQuartz application, open it, this opens an xtem window.
  2. You'll want to use this window to connect over SSH.

Connecting to the 'domain.tld' X11 Server on Mac ​

  1. Using the xterm window, run the command set DISPLAY=127.0.0.1:0 to set the X11 forwarder to the correct display set.
  2. Run the command 'ssh -X username@domain.tld' where username is replaced by your username and domain.tld is replaced with the current IP address of the domain.tld server.
  3. Run the 'xclock' command to verify connectivity.
',22)]))}const p=t(o,[["render",l]]);export{m as __pageData,p as default}; diff --git a/.vitepress/dist/assets/x11-guide.md.BPhK1sNP.lean.js b/.vitepress/dist/assets/x11-guide.md.BPhK1sNP.lean.js new file mode 100644 index 0000000..91e9dc3 --- /dev/null +++ b/.vitepress/dist/assets/x11-guide.md.BPhK1sNP.lean.js @@ -0,0 +1 @@ +import{_ as t,c as a,a3 as n,o as i}from"./chunks/framework.DtMx7FFi.js";const m=JSON.parse('{"title":"X11-Guide","description":"","frontmatter":{"title":"X11-Guide"},"headers":[],"relativePath":"x11-guide.md","filePath":"x11-guide.md"}'),o={name:"x11-guide.md"};function l(r,e,s,c,h,d){return i(),a("div",null,e[0]||(e[0]=[n('

Windows Setup: ​

Windows X11 Window Manager Client/Server ​

Installation:

  1. Install VCXSRV on your Windows machine.
  2. Follow the install instructions until able to close.

Running the X11 Local Server (aka the client that connects to the real X11 server) ​

  1. Locate the newly installed XLaunch application, open it.
  2. You'll want to modify the display settings as follows:
    • Select Multiple windows for the program displays, hit next
    • Select the Start no client option on the next page, hit next.
    • Options on this page are optional, you DO NOT want the Disable access control selected on this page.
    • Hit next.
    • Click the Save configuration button on this page, save this config somewhere you won't forget about it.
    • Click finish.
    • Allow the access to the network if Windows Defender Firewall asks.
    • Congratulations, you've setup the local X11 server!
  3. Make sure the XLaunch application is in the system tray before running Putty OR Terminal SSH

Connecting to the 'domain.tld' X11 Server ​

  1. First, verify the XLaunch application is running in the System Tray, then follow the instructions below based on your preferred SSH method.

PuTTY Instructions (including setting up a profile for easier management) ​

  1. Highly recommend the use of a profile if you are going to use PuTTY, as you can save/load the config up really quick instead of having to put in these values every time.
  2. Enter in the hostname, (this is optional if making a profile, as the IP address is dynamic)
  3. In the connection category, under the data subcategory, the auto-login username can be set if using a profile.
  4. Expand the SSH subcategory (in connection) and set the credentials if using a profile to the private key (if made)
  5. Now, click on X11 subcategory (in connection) and click the checkbox for 'Enable X11 forwarding'
  6. Set the X Display Location textbox to the value '127.0.0.1:0' (no quotes).
  7. Return to the Session category, and type in a name for the saved session, then hit the save button. Now, all of these changes can be loaded instead of put in each time.
  8. Now, type in the IP address of the 'domain.tld' and hit the 'Open' button.
  9. If you'd like to verify the X11 connectivity, type 'xclock' into the terminal. This will make a little analog clock appear in a separate window.

Windows Powershell Instructions ​

  1. You'll want to set a variable in the command prompt, run $env:DISPLAY="127.0.0.1:0" (exactly as written) to set the X Window Manager as the display output.
  2. Use the command 'ssh -X username@domain.tld' to connect, replacing username with your username, and domain.tld with the current dynIP.
  3. If you'd like to verify the X11 connectivity, type 'xclock' into the terminal. This will make a little analog clock appear in a separate window.

Windows Command Prompt Instructions (a.k.a. CMD) ​

  1. You'll want to set a variable in the command prompt, run set DISPLAY=127.0.0.1:0 to set the X Window Manager as the display output.
  2. Use the command 'ssh -X username@domain.tld' to connect, replacing username with your username, and domain.tld with the current dynIP.
  3. If you'd like to verify the X11 connectivity, type 'xclock' into the terminal. This will make a little analog clock appear in a separate window.

MacOS Setup: ​

MacOS X11 Window Manager Client/Server ​

Installation:

  1. Install XQuartz (https://www.xquartz.org/) using the MacOS pkg file.
  2. Follow the install instructions until able to close (you'll have to logout to complete install).

Running the X11 Local Server on Mac (aka the client that connects to the real X11 server) ​

  1. Locate the newly installed XQuartz application, open it, this opens an xtem window.
  2. You'll want to use this window to connect over SSH.

Connecting to the 'domain.tld' X11 Server on Mac ​

  1. Using the xterm window, run the command set DISPLAY=127.0.0.1:0 to set the X11 forwarder to the correct display set.
  2. Run the command 'ssh -X username@domain.tld' where username is replaced by your username and domain.tld is replaced with the current IP address of the domain.tld server.
  3. Run the 'xclock' command to verify connectivity.
',22)]))}const p=t(o,[["render",l]]);export{m as __pageData,p as default}; diff --git a/.vitepress/dist/cat-typing.gif b/.vitepress/dist/cat-typing.gif new file mode 100644 index 0000000..be05cfc Binary files /dev/null and b/.vitepress/dist/cat-typing.gif differ diff --git a/.vitepress/dist/cf-tunnel.html b/.vitepress/dist/cf-tunnel.html new file mode 100644 index 0000000..025d8b3 --- /dev/null +++ b/.vitepress/dist/cf-tunnel.html @@ -0,0 +1,95 @@ + + + + + + Cloudflare Tunneling | DP-Salad + + + + + + + + + + + + + + + +
Skip to content

Cloudflare Tunnel Setup: ​

Sometimes, someone might want to deploy the DP-SALAD stack behind NAT or you don't want to open your network's ports exposing them to the outside.

Note:

You do not need to have your domain registered through Cloudflare to use Cloudflare Tunnels

THE SOLUTION? ​

Cloudflare Tunnels

Of course, running the stack this way comes with some extra configuartion on both the Docker side and Cloudflare/domain side.

This is an excerpt from the One-Click Docker Compose file:

In order to make this work with cloudflare tunneling, you must add some more lines to your docker compose. The first being a directive which is highlighted below:

yml
version: "2.1"
+services:
+  swag:
+    image: lscr.io/linuxserver/swag:latest
+    container_name: swag
+    cap_add:
+      - NET_ADMIN
+    environment:
+      - PUID=1000
+      - PGID=1000
+      - TZ=America/Phoenix
+      - URL=[sakura.nt]
+      - VALIDATION=dns
+      - SUBDOMAINS=wildcard
+      - DNSPLUGIN=cloudflare
+      - EMAIL=[sakurant@gmail.com]
+      - ONLY_SUBDOMAINS=false
+      #- EXTRA_DOMAINS= #optional
+      - STAGING=false
+      - DOCKER_MODS=linuxserver/mods:universal-docker|linuxserver/mods:swag-auto-reload|linuxserver/mods:swag-dashboard|linuxserver/mods:swag-dbip|linuxserver/mods:universal-cloudflared
+    extra_hosts:
+        - domain.tld:127.0.0.1
+    volumes:
+      - /home/[INSERT USER FOLDER HERE]/appdata/swag:/config
+    ports:
+      - 443:443
+      - 80:80
+    networks:
+      - [INSERT NETWORK NAME HERE]
+    restart: unless-stopped

Next, you'll want to generate an API key with Cloudflare , go to Overview in your domain, and click "get your api token", click Create Token, use → "Edit zone DNS" template, add a permission, select "Account", → "Cloudflare Tunnel", → "Edit", under account resources, include your account, under zone resources, include your domain. Continue with setup, make sure you keep track of the API key somewhere.

After you have completed these steps, you will need to add these credentials to your Swag configuration in the docker-compose.yml. After the Docker_Mods environment variable, add these lines:

yml
version: "2.1"
+services:
+  swag:
+    image: lscr.io/linuxserver/swag:latest
+    container_name: swag
+    cap_add:
+      - NET_ADMIN
+    environment:
+      - PUID=1000
+      - PGID=1000
+      - TZ=America/Phoenix
+      - URL=[sakura.nt]
+      - VALIDATION=dns
+      - SUBDOMAINS=wildcard
+      - DNSPLUGIN=cloudflare
+      - EMAIL=[sakurant@gmail.com]
+      - ONLY_SUBDOMAINS=false
+      #- EXTRA_DOMAINS= #optional
+      - STAGING=false
+      - DOCKER_MODS=linuxserver/mods:universal-docker|linuxserver/mods:swag-auto-reload|linuxserver/mods:swag-dashboard|linuxserver/mods:swag-dbip|linuxserver/mods:universal-cloudflared
+      - CF_ZONE_ID=zone id from cloudflare domain overview
+      - CF_ACCOUNT_ID=account id from cloudflare domain overview
+      - CF_API_TOKEN=api token generated
+      - CF_TUNNEL_NAME=create a tunnel, name it whatever
+      - CF_TUNNEL_PASSWORD=generate a long password
+      - FILE__CF_TUNNEL_CONFIG=/config/tunnelconfig.yml
+    extra_hosts:
+        - domain.tld:127.0.0.1
+    volumes:
+      - /home/[INSERT USER FOLDER HERE]/appdata/swag:/config
+    ports:
+      - 443:443
+      - 80:80
+    networks:
+      - [INSERT NETWORK NAME HERE]
+    restart: unless-stopped

You're not quite done yet...

You'll need to add more to finish the installation: First, nano /home/[USER]/appdata/swag/tunnelconfig.yml, and add these contents:

yml
ingress:
+  - hostname: domain.tld
+    service: https://domain.tld
+  - hostname: "*.domain.tld"
+    service: https://domain.tld
+  - service: http_status:404

Then, edit the /home/[USER]/appdata/swag/dns-conf/cloudflare.ini, add the API token, you'll comment the top two lines, add the token after uncommenting the bottom line.

insert funni meeme here:

/cat-typing.gif

Docs created by @ldez

+ + + + \ No newline at end of file diff --git a/.vitepress/dist/changelog.html b/.vitepress/dist/changelog.html new file mode 100644 index 0000000..5ead452 --- /dev/null +++ b/.vitepress/dist/changelog.html @@ -0,0 +1,26 @@ + + + + + + Changelog | DP-Salad + + + + + + + + + + + + + + + +
Skip to content

Changelog ​

Version 1.1.0: 11-20-24 ​

  • Updated dependencies to latest version -ldez
  • Added code block closure functionality to minify pages -ldez
  • Added back Cdez's credits -ldez
  • Moved cloudflare tunneling to misc -ldez

Version 1.0.4: 10-11-24 ​

  • Updated dependencies to latest version -ldez
  • Added miscellaneous section -ldez

Version 1.0.3: 07-07-24 ​

  • Updated dependencies to latest version -ldez
  • Removed Google Domains as they have moved to shitspace -ldez
  • Added a Cisco Duo logo -ldez

Version 1.0.2: 06-22-24 ​

  • Redo the homepage -ldez
  • Added some icons to pages -ldez
  • Changed "mini-req" to just "requirements" -ldez
  • Fixed the formatting issues on dp-setup -ldez

Version 1.0.1: 06-19-24 ​

  • Fixed some documentation -ldez
  • Added section about cloudflare tunneling -ldez
  • Added more commands to successfully deploy dp-stack -ldez
  • Added an explanation for Debian's sudo -ldez
  • Added the FAQ expanlanation to add an application -ldez

Docs created by @ldez

+ + + + \ No newline at end of file diff --git a/.vitepress/dist/configuration.yml.rtf b/.vitepress/dist/configuration.yml.rtf new file mode 100644 index 0000000..d76c247 --- /dev/null +++ b/.vitepress/dist/configuration.yml.rtf @@ -0,0 +1,1465 @@ +# yamllint disable rule:comments-indentation +--- +############################################################################### +# Authelia Configuration # +############################################################################### + +## Note: the container by default expects to find this file at /config/configuration.yml. + +## Certificates directory specifies where Authelia will load trusted certificates (public portion) from in addition to +## the system certificates store. +## They should be in base64 format, and have one of the following extensions: *.cer, *.crt, *.pem. +# certificates_directory: /config/certificates/ + +## The theme to display: light, dark, grey, auto. +theme: dark + +## The secret used to generate JWT tokens when validating user identity by email confirmation. JWT Secret can also be +## set using a secret: https://www.authelia.com/c/secrets +jwt_secret: REDACTED + +## Default redirection URL +## +## If user tries to authenticate without any referer, Authelia does not know where to redirect the user to at the end +## of the authentication process. This parameter allows you to specify the default redirection URL Authelia will use +## in such a case. +## +## Note: this parameter is optional. If not provided, user won't be redirected upon successful authentication. +default_redirection_url: https://[domain.tld]/ + +## Set the default 2FA method for new users and for when a user has a preferred method configured that has been +## disabled. This setting must be a method that is enabled. +## Options are totp, webauthn, mobile_push. +default_2fa_method: "totp" + +## +## Server Configuration +## +server: + + ## The address to listen on. + host: 0.0.0.0 + + ## The port to listen on. + port: 9091 + + ## Set the single level path Authelia listens on. + ## Must be alphanumeric chars and should not contain any slashes. + path: "authelia" + + ## Set the path on disk to Authelia assets. + ## Useful to allow overriding of specific static assets. + # asset_path: /config/assets/ + + ## Enables the pprof endpoint. + enable_pprof: false + + ## Enables the expvars endpoint. + enable_expvars: false + + ## Disables writing the health check vars to /app/.healthcheck.env which makes healthcheck.sh return exit code 0. + ## This is disabled by default if either /app/.healthcheck.env or /app/healthcheck.sh do not exist. + disable_healthcheck: false + + ## Authelia by default doesn't accept TLS communication on the server port. This section overrides this behaviour. + tls: + ## The path to the DER base64/PEM format private key. + key: "" + + ## The path to the DER base64/PEM format public certificate. + certificate: "" + + ## The list of certificates for client authentication. + client_certificates: [] + + ## Server headers configuration/customization. + headers: + + ## The CSP Template. Read the docs. + csp_template: "" + + ## Server Buffers configuration. + # buffers: + + ## Buffers usually should be configured to be the same value. + ## Explanation at https://www.authelia.com/c/server#buffer-sizes + ## Read buffer size adjusts the server's max incoming request size in bytes. + ## Write buffer size does the same for outgoing responses. + + ## Read buffer. + # read: 4096 + + ## Write buffer. + # write: 4096 + + ## Server Timeouts configuration. + # timeouts: + + ## Read timeout. + # read: 6s + + ## Write timeout. + # write: 6s + + ## Idle timeout. + # idle: 30s + +## +## Log Configuration +## +log: + ## Level of verbosity for logs: info, debug, trace. + level: debug + + ## Format the logs are written as: json, text. + # format: json + + ## File path where the logs will be written. If not set logs are written to stdout. + # file_path: /config/authelia.log + + ## Whether to also log to stdout when a log_file_path is defined. + # keep_stdout: false + +## +## Telemetry Configuration +## +telemetry: + + ## + ## Metrics Configuration + ## + metrics: + ## Enable Metrics. + enabled: false + + ## The address to listen on for metrics. This should be on a different port to the main server.port value. + address: tcp://0.0.0.0:9959 + + ## Metrics Server Buffers configuration. + # buffers: + + ## Read buffer. + # read: 4096 + + ## Write buffer. + # write: 4096 + + ## Metrics Server Timeouts configuration. + # timeouts: + + ## Read timeout. + # read: 6s + + ## Write timeout. + # write: 6s + + ## Idle timeout. + # idle: 30s + +## +## TOTP Configuration +## +## Parameters used for TOTP generation. +totp: + ## Disable TOTP. + disable: false + + ## The issuer name displayed in the Authenticator application of your choice. + issuer: [domain.tld] + + ## The TOTP algorithm to use. + ## It is CRITICAL you read the documentation before changing this option: + ## https://www.authelia.com/c/totp#algorithm + algorithm: sha1 + + ## The number of digits a user has to input. Must either be 6 or 8. + ## Changing this option only affects newly generated TOTP configurations. + ## It is CRITICAL you read the documentation before changing this option: + ## https://www.authelia.com/c/totp#digits + digits: 8 + + ## The period in seconds a one-time password is valid for. + ## Changing this option only affects newly generated TOTP configurations. + period: 30 + + ## The skew controls number of one-time passwords either side of the current one that are valid. + ## Warning: before changing skew read the docs link below. + skew: 1 + ## See: https://www.authelia.com/c/totp#input-validation to read + ## the documentation. + + ## The size of the generated shared secrets. Default is 32 and is sufficient in most use cases, minimum is 20. + secret_size: 32 + +## +## WebAuthn Configuration +## +## Parameters used for WebAuthn. +webauthn: + ## Disable Webauthn. + disable: false + + ## Adjust the interaction timeout for Webauthn dialogues. + timeout: 60s + + ## The display name the browser should show the user for when using Webauthn to login/register. + display_name: Authelia + + ## Conveyance preference controls if we collect the attestation statement including the AAGUID from the device. + ## Options are none, indirect, direct. + attestation_conveyance_preference: indirect + + ## User verification controls if the user must make a gesture or action to confirm they are present. + ## Options are required, preferred, discouraged. + user_verification: preferred + +## +## Duo Push API Configuration +## +## Parameters used to contact the Duo API. Those are generated when you protect an application of type +## "Partner Auth API" in the management panel. +# duo_api: + # disable: false + # hostname: api-123456789.example.com + # integration_key: ABCDEF + ## Secret can also be set using a secret: https://www.authelia.com/c/secrets + # secret_key: 1234567890abcdefghifjkl + # enable_self_enrollment: false + +## +## NTP Configuration +## +## This is used to validate the servers time is accurate enough to validate TOTP. +ntp: + ## NTP server address. + address: "time.cloudflare.com:123" + + ## NTP version. + version: 4 + + ## Maximum allowed time offset between the host and the NTP server. + max_desync: 3s + + ## Disables the NTP check on startup entirely. This means Authelia will not contact a remote service at all if you + ## set this to true, and can operate in a truly offline mode. + disable_startup_check: false + + ## The default of false will prevent startup only if we can contact the NTP server and the time is out of sync with + ## the NTP server more than the configured max_desync. If you set this to true, an error will be logged but startup + ## will continue regardless of results. + disable_failure: false + +## +## Authentication Backend Provider Configuration +## +## Used for verifying user passwords and retrieve information such as email address and groups users belong to. +## +## The available providers are: `file`, `ldap`. You must use only one of these providers. +authentication_backend: + + ## Password Reset Options. + password_reset: + ## Disable both the HTML element and the API for reset password functionality. + disable: false + + ## External reset password url that redirects the user to an external reset portal. This disables the internal reset + ## functionality. + custom_url: "" + + ## The amount of time to wait before we refresh data from the authentication backend. Uses duration notation. + ## To disable this feature set it to 'disable', this will slightly reduce security because for Authelia, users will + ## always belong to groups they belonged to at the time of login even if they have been removed from them in LDAP. + ## To force update on every request you can set this to '0' or 'always', this will increase processor demand. + ## See the below documentation for more information. + ## Duration Notation docs: https://www.authelia.com/c/common#duration-notation-format + ## Refresh Interval docs: https://www.authelia.com/c/1fa#refresh-interval + refresh_interval: 5m + + ## + ## LDAP (Authentication Provider) + ## + ## This is the recommended Authentication Provider in production + ## because it allows Authelia to offload the stateful operations + ## onto the LDAP service. + ldap: + ## The LDAP implementation, this affects elements like the attribute utilised for resetting a password. + ## Acceptable options are as follows: + ## - 'activedirectory' - For Microsoft Active Directory. + ## - 'custom' - For custom specifications of attributes and filters. + ## This currently defaults to 'custom' to maintain existing behaviour. + ## + ## Depending on the option here certain other values in this section have a default value, notably all of the + ## attribute mappings have a default value that this config overrides, you can read more about these default values + ## at https://www.authelia.com/c/ldap#defaults + implementation: custom + + ## The url to the ldap server. Format: ://
[:]. + ## Scheme can be ldap or ldaps in the format (port optional). + url: ldap://lldap:3890 + + ## The dial timeout for LDAP. + timeout: 5s + + ## Use StartTLS with the LDAP connection. + start_tls: false + + # tls: + ## The server subject name to check the servers certificate against during the validation process. + ## This option is not required if the certificate has a SAN which matches the host portion of the url option. + # server_name: ldap.example.com + + ## Skip verifying the server certificate entirely. In preference to setting this we strongly recommend you add the + ## certificate or the certificate of the authority signing the certificate to the certificates directory which is + ## defined by the `certificates_directory` option at the top of the configuration. + ## It's important to note the public key should be added to the directory, not the private key. + ## This option is strongly discouraged but may be useful in some self-signed situations where validation is not + ## important to the administrator. + # skip_verify: false + + ## Minimum TLS version for the connection. + # minimum_version: TLS1.2 + + ## Maximum TLS version for the connection. + # maximum_version: TLS1.3 + + ## The certificate chain used with the private_key if the server requests TLS Client Authentication + ## i.e. Mutual TLS. + # certificate_chain: | + # -----BEGIN CERTIFICATE----- + # MIIC5jCCAc6gAwIBAgIRAK4Sj7FiN6PXo/urPfO4E7owDQYJKoZIhvcNAQELBQAw + # EzERMA8GA1UEChMIQXV0aGVsaWEwHhcNNzAwMTAxMDAwMDAwWhcNNzEwMTAxMDAw + # MDAwWjATMREwDwYDVQQKEwhBdXRoZWxpYTCCASIwDQYJKoZIhvcNAQEBBQADggEP + # ADCCAQoCggEBAPKv3pSyP4ozGEiVLJ14dIWFCEGEgq7WUMI0SZZqQA2ID0L59U/Q + # /Usyy7uC9gfMUzODTpANtkOjFQcQAsxlR1FOjVBrX5QgjSvXwbQn3DtwMA7XWSl6 + # LuYx2rBYSlMSN5UZQm/RxMtXfLK2b51WgEEYDFi+nECSqKzR4R54eOPkBEWRfvuY + # 91AMjlhpivg8e4JWkq4LVQUKbmiFYwIdK8XQiN4blY9WwXwJFYs5sQ/UYMwBFi0H + # kWOh7GEjfxgoUOPauIueZSMSlQp7zqAH39N0ZSYb6cS0Npj57QoWZSY3ak87ebcR + # Nf4rCvZLby7LoN7qYCKxmCaDD3x2+NYpWH8CAwEAAaM1MDMwDgYDVR0PAQH/BAQD + # AgWgMBMGA1UdJQQMMAoGCCsGAQUFBwMBMAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcN + # AQELBQADggEBAHSITqIQSNzonFl3DzxHPEzr2hp6peo45buAAtu8FZHoA+U7Icfh + # /ZXjPg7Xz+hgFwM/DTNGXkMWacQA/PaNWvZspgRJf2AXvNbMSs2UQODr7Tbv+Fb4 + # lyblmMUNYFMCFVAMU0eIxXAFq2qcwv8UMcQFT0Z/35s6PVOakYnAGGQjTfp5Ljuq + # wsdc/xWmM0cHWube6sdRRUD7SY20KU/kWzl8iFO0VbSSrDf1AlEhnLEkp1SPaxXg + # OdBnl98MeoramNiJ7NT6Jnyb3zZ578fjaWfThiBpagItI8GZmG4s4Ovh2JbheN8i + # ZsjNr9jqHTjhyLVbDRlmJzcqoj4JhbKs6/I^invalid DO NOT USE= + # -----END CERTIFICATE----- + # -----BEGIN CERTIFICATE----- + # MIIDBDCCAeygAwIBAgIRALJsPg21kA0zY4F1wUCIuoMwDQYJKoZIhvcNAQELBQAw + # EzERMA8GA1UEChMIQXV0aGVsaWEwHhcNNzAwMTAxMDAwMDAwWhcNNzEwMTAxMDAw + # MDAwWjATMREwDwYDVQQKEwhBdXRoZWxpYTCCASIwDQYJKoZIhvcNAQEBBQADggEP + # ADCCAQoCggEBAMXHBvVxUzYk0u34/DINMSF+uiOekKOAjOrC6Mi9Ww8ytPVO7t2S + # zfTvM+XnEJqkFQFgimERfG/eGhjF9XIEY6LtnXe8ATvOK4nTwdufzBaoeQu3Gd50 + # 5VXr6OHRo//ErrGvFXwP3g8xLePABsi/fkH3oDN+ztewOBMDzpd+KgTrk8ysv2ou + # kNRMKFZZqASvCgv0LD5KWvUCnL6wgf1oTXG7aztduA4oSkUP321GpOmBC5+5ElU7 + # ysoRzvD12o9QJ/IfEaulIX06w9yVMo60C/h6A3U6GdkT1SiyTIqR7v7KU/IWd/Qi + # Lfftcj91VhCmJ73Meff2e2S2PrpjdXbG5FMCAwEAAaNTMFEwDgYDVR0PAQH/BAQD + # AgKkMA8GA1UdJQQIMAYGBFUdJQAwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU + # Z7AtA3mzFc0InSBA5fiMfeLXA3owDQYJKoZIhvcNAQELBQADggEBAEE5hm1mtlk/ + # kviCoHH4evbpw7rxPxDftIQlqYTtvMM4eWY/6icFoSZ4fUHEWYyps8SsPu/8f2tf + # 71LGgZn0FdHi1QU2H8m0HHK7TFw+5Q6RLrLdSyk0PItJ71s9en7r8pX820nAFEHZ + # HkOSfJZ7B5hFgUDkMtVM6bardXAhoqcMk4YCU96e9d4PB4eI+xGc+mNuYvov3RbB + # D0s8ICyojeyPVLerz4wHjZu68Z5frAzhZ68YbzNs8j2fIBKKHkHyLG1iQyF+LJVj + # 2PjCP+auJsj6fQQpMGoyGtpLcSDh+ptcTngUD8JsWipzTCjmaNqdPHAOYmcgtf4b + # qocikt3WAdU^invalid DO NOT USE= + # -----END CERTIFICATE----- + + ## The private key used with the certificate_chain if the server requests TLS Client Authentication + ## i.e. Mutual TLS. + # private_key: | + # -----BEGIN RSA PRIVATE KEY----- + # MIIEpAIBAAKCAQEA8q/elLI/ijMYSJUsnXh0hYUIQYSCrtZQwjRJlmpADYgPQvn1 + # T9D9SzLLu4L2B8xTM4NOkA22Q6MVBxACzGVHUU6NUGtflCCNK9fBtCfcO3AwDtdZ + # KXou5jHasFhKUxI3lRlCb9HEy1d8srZvnVaAQRgMWL6cQJKorNHhHnh44+QERZF+ + # +5j3UAyOWGmK+Dx7glaSrgtVBQpuaIVjAh0rxdCI3huVj1bBfAkVizmxD9RgzAEW + # LQeRY6HsYSN/GChQ49q4i55lIxKVCnvOoAff03RlJhvpxLQ2mPntChZlJjdqTzt5 + # txE1/isK9ktvLsug3upgIrGYJoMPfHb41ilYfwIDAQABAoIBAQDTOdFf2JjHH1um + # aPgRAvNf9v7Nj5jytaRKs5nM6iNf46ls4QPreXnMhqSeSwj6lpNgBYxOgzC9Q+cc + # Y4ob/paJJPaIJTxmP8K/gyWcOQlNToL1l+eJ20eQoZm23NGr5fIsunSBwLEpTrdB + # ENqqtcwhW937K8Pxy/Q1nuLyU2bc6Tn/ivLozc8n27dpQWWKh8537VY7ancIaACr + # LJJLYxKqhQpjtBWAyCDvZQirnAOm9KnvIHaGXIswCZ4Xbsu0Y9NL+woARPyRVQvG + # jfxy4EmO9s1s6y7OObSukwKDSNihAKHx/VIbvVWx8g2Lv5fGOa+J2Y7o9Qurs8t5 + # BQwMTt0BAoGBAPUw5Z32EszNepAeV3E2mPFUc5CLiqAxagZJuNDO2pKtyN29ETTR + # Ma4O1cWtGb6RqcNNN/Iukfkdk27Q5nC9VJSUUPYelOLc1WYOoUf6oKRzE72dkMQV + # R4bf6TkjD+OVR17fAfkswkGahZ5XA7j48KIQ+YC4jbnYKSxZTYyKPjH/AoGBAP1i + # tqXt36OVlP+y84wWqZSjMelBIVa9phDVGJmmhz3i1cMni8eLpJzWecA3pfnG6Tm9 + # ze5M4whASleEt+M00gEvNaU9ND+z0wBfi+/DwJYIbv8PQdGrBiZFrPhTPjGQUldR + # lXccV2meeLZv7TagVxSi3DO6dSJfSEHyemd5j9mBAoGAX8Hv+0gOQZQCSOTAq8Nx + # 6dZcp9gHlNaXnMsP9eTDckOSzh636JPGvj6m+GPJSSbkURUIQ3oyokMNwFqvlNos + # fTaLhAOfjBZI9WnDTTQxpugWjphJ4HqbC67JC/qIiw5S6FdaEvGLEEoD4zoChywZ + # 9oGAn+fz2d/0/JAH/FpFPgsCgYEAp/ipZgPzziiZ9ov1wbdAQcWRj7RaWnssPFpX + # jXwEiXT3CgEMO4MJ4+KWIWOChrti3qFBg6i6lDyyS6Qyls7sLFbUdC7HlTcrOEMe + # rBoTcCI1GqZNlqWOVQ65ZIEiaI7o1vPBZo2GMQEZuq8mDKFsOMThvvTrM5cAep84 + # n6HJR4ECgYABWcbsSnr0MKvVth/inxjbKapbZnp2HUCuw87Ie5zK2Of/tbC20wwk + # yKw3vrGoE3O1t1g2m2tn8UGGASeZ842jZWjIODdSi5+icysQGuULKt86h/woz2SQ + # 27GoE2i5mh6Yez6VAYbUuns3FcwIsMyWLq043Tu2DNkx9ijOOAuQzw^invalid.. + # DO NOT USE== + # -----END RSA PRIVATE KEY----- + + ## The distinguished name of the container searched for objects in the directory information tree. + ## See also: additional_users_dn, additional_groups_dn. + base_dn: dc=[domain],dc=[tld] + + ## The attribute holding the username of the user. This attribute is used to populate the username in the session + ## information. For your information, Microsoft Active Directory usually uses 'sAMAccountName' and OpenLDAP usually + ## uses 'uid'. Beware that this attribute holds the unique identifiers for the users binding the user and the + ## configuration stored in database. Therefore only single value attributes are allowed and the value must never be + ## changed once attributed to a user otherwise it would break the configuration for that user. Technically, + ## non-unique attributes like 'mail' can also be used but we don't recommend using them, we instead advise to use + ## a filter to perform alternative lookups and the attributes mentioned above (sAMAccountName and uid) to + ## follow https://www.ietf.org/rfc/rfc2307.txt. + username_attribute: uid + + ## The additional_users_dn is prefixed to base_dn and delimited by a comma when searching for users. + ## i.e. with this set to OU=Users and base_dn set to DC=a,DC=com; OU=Users,DC=a,DC=com is searched for users. + additional_users_dn: ou=people + + ## The users filter used in search queries to find the user profile based on input filled in login form. + ## Various placeholders are available in the user filter which you can read about in the documentation which can + ## be found at: https://www.authelia.com/c/ldap#users-filter-replacements + ## + ## Recommended settings are as follows: + ## - Microsoft Active Directory: (&({username_attribute}={input})(objectCategory=person)(objectClass=user)) + ## - OpenLDAP: + ## - (&({username_attribute}={input})(objectClass=person)) + ## - (&({username_attribute}={input})(objectClass=inetOrgPerson)) + ## + ## To allow sign in both with username and email, one can use a filter like + ## (&(|({username_attribute}={input})({mail_attribute}={input}))(objectClass=person)) + users_filter: (&({username_attribute}={input})(objectClass=person)) + + ## The additional_groups_dn is prefixed to base_dn and delimited by a comma when searching for groups. + ## i.e. with this set to OU=Groups and base_dn set to DC=a,DC=com; OU=Groups,DC=a,DC=com is searched for groups. + additional_groups_dn: ou=groups + + ## The groups filter used in search queries to find the groups based on relevant authenticated user. + ## Various placeholders are available in the groups filter which you can read about in the documentation which can + ## be found at: https://www.authelia.com/c/ldap#groups-filter-replacements + ## + ## If your groups use the `groupOfUniqueNames` structure use this instead: + ## (&(uniqueMember={dn})(objectClass=groupOfUniqueNames)) + groups_filter: (&(member={dn})(objectClass=groupOfUniqueNames)) + + ## The attribute holding the name of the group. + group_name_attribute: cn + + ## The attribute holding the mail address of the user. If multiple email addresses are defined for a user, only the + ## first one returned by the LDAP server is used. + mail_attribute: mail + + ## The attribute holding the display name of the user. This will be used to greet an authenticated user. + display_name_attribute: displayName + + ## Follow referrals returned by the server. + ## This is especially useful for environments where read-only servers exist. Only implemented for write operations. + # permit_referrals: false + + ## The username and password of the admin user. + user: cn=admin,ou=people,dc=[domain],dc=[tld] + ## Password can also be set using a secret: https://www.authelia.com/c/secrets + password: "REDACTED" + + ## + ## File (Authentication Provider) + ## + ## With this backend, the users database is stored in a file which is updated when users reset their passwords. + ## Therefore, this backend is meant to be used in a dev environment and not in production since it prevents Authelia + ## to be scaled to more than one instance. The options under 'password' have sane defaults, and as it has security + ## implications it is highly recommended you leave the default values. Before considering changing these settings + ## please read the docs page below: + ## https://www.authelia.com/r/passwords#tuning + ## + ## Important: Kubernetes (or HA) users must read https://www.authelia.com/t/statelessness + ## + # file: + # path: /config/users_database.yml + # watch: false + # search: + # email: false + # case_insensitive: false + # password: + # algorithm: argon2 + # argon2: + # variant: argon2id + # iterations: 3 + # memory: 65536 + # parallelism: 4 + # key_length: 32 + # salt_length: 16 + # scrypt: + # iterations: 16 + # block_size: 8 + # parallelism: 1 + # key_length: 32 + # salt_length: 16 + # pbkdf2: + # variant: sha512 + # iterations: 310000 + # salt_length: 16 + # sha2crypt: + # variant: sha512 + # iterations: 50000 + # salt_length: 16 + # bcrypt: + # variant: standard + # cost: 12 + + +## +## Password Policy Configuration. +## +password_policy: + + ## The standard policy allows you to tune individual settings manually. + standard: + enabled: true + + ## Require a minimum length for passwords. + min_length: 8 + + ## Require a maximum length for passwords. + max_length: 0 + + ## Require uppercase characters. + require_uppercase: true + + ## Require lowercase characters. + require_lowercase: true + + ## Require numeric characters. + require_number: true + + ## Require special characters. + require_special: true + + ## zxcvbn is a well known and used password strength algorithm. It does not have tunable settings. + zxcvbn: + enabled: false + + ## Configures the minimum score allowed. + min_score: 3 + +## +## Access Control Configuration +## +## Access control is a list of rules defining the authorizations applied for one resource to users or group of users. +## +## If 'access_control' is not defined, ACL rules are disabled and the 'bypass' rule is applied, i.e., access is allowed +## to anyone. Otherwise restrictions follow the rules defined. +## +## Note: One can use the wildcard * to match any subdomain. +## It must stand at the beginning of the pattern. (example: *.example.com) +## +## Note: You must put patterns containing wildcards between simple quotes for the YAML to be syntactically correct. +## +## Definition: A 'rule' is an object with the following keys: 'domain', 'subject', 'policy' and 'resources'. +## +## - 'domain' defines which domain or set of domains the rule applies to. +## +## - 'subject' defines the subject to apply authorizations to. This parameter is optional and matching any user if not +## provided. If provided, the parameter represents either a user or a group. It should be of the form +## 'user:' or 'group:'. +## +## - 'policy' is the policy to apply to resources. It must be either 'bypass', 'one_factor', 'two_factor' or 'deny'. +## +## - 'resources' is a list of regular expressions that matches a set of resources to apply the policy to. This parameter +## is optional and matches any resource if not provided. +## +## Note: the order of the rules is important. The first policy matching (domain, resource, subject) applies. +access_control: + ## Default policy can either be 'bypass', 'one_factor', 'two_factor' or 'deny'. It is the policy applied to any + ## resource if there is no policy to be applied to the user. + default_policy: deny + + # networks: + # - name: internal + # networks: + # - 10.10.0.0/16 + # - 192.168.2.0/24 + # - name: VPN + # networks: 10.9.0.0/16 + + rules: + ## Rules applied to everyone + ## This below policy allows for auth to be accessed at all times, + ## useful when trying to login without the main page available. + - domain: + - 'auth.[domain.tld]' + policy: bypass + ## This below policy example will exclude a user from using 2FA, + ## useful if the user has no way of configuring 2FA. + - domain: + - '[domain.tld]' + - '*.[domain.tld]' + subject: + - "user:[USERNAME/UID]" + policy: one_factor + ## This below policy example will exclude all users of the people + ## group from using 2FA, NOT RECOMMENDED + - domain: + - '[domain.tld]' + - '*.[domain.tld]' + subject: + - "group:people" + policy: one_factor + ## This below policy will require all users of the LLDAP_Admin group + ## in LLDAP to use 2FA BY DEFAULT, this is the strongest policy available + - domain: + - '[domain.tld]' + - '*.[domain.tld]' + subject: + - "group:lldap_admin" + policy: two_factor + + ## Domain Regex examples. Generally we recommend just using a standard domain. + # - domain_regex: '^(?P\w+)\.example\.com$' + # policy: one_factor + # - domain_regex: '^(?P\w+)\.example\.com$' + # policy: one_factor + # - domain_regex: + # - '^appgroup-.*\.example\.com$' + # - '^appgroup2-.*\.example\.com$' + # policy: one_factor + # - domain_regex: '^.*\.example\.com$' + # policy: two_factor + + # - domain: 'secure.example.com' + # policy: one_factor + ## Network based rule, if not provided any network matches. + # networks: + # - internal + # - VPN + # - 192.168.1.0/24 + # - 10.0.0.1 + + # - domain: + # - 'secure.example.com' + # - 'private.example.com' + # policy: two_factor + + # - domain: 'singlefactor.example.com' + # policy: one_factor + + ## Rules applied to 'admins' group + # - domain: 'mx2.mail.example.com' + # subject: 'group:admins' + # policy: deny + + # - domain: '*.example.com' + # subject: + # - 'group:admins' + # - 'group:moderators' + # policy: two_factor + + ## Rules applied to 'dev' group + # - domain: 'dev.example.com' + # resources: + # - '^/groups/dev/.*$' + # subject: 'group:dev' + # policy: two_factor + + ## Rules applied to user 'john' + # - domain: 'dev.example.com' + # resources: + # - '^/users/john/.*$' + # subject: 'user:john' + # policy: two_factor + + ## Rules applied to user 'harry' + # - domain: 'dev.example.com' + # resources: + # - '^/users/harry/.*$' + # subject: 'user:harry' + # policy: two_factor + + ## Rules applied to user 'bob' + # - domain: '*.mail.example.com' + # subject: 'user:bob' + # policy: two_factor + # - domain: 'dev.example.com' + # resources: + # - '^/users/bob/.*$' + # subject: 'user:bob' + # policy: two_factor + +## +## Session Provider Configuration +## +## The session cookies identify the user once logged in. +## The available providers are: `memory`, `redis`. Memory is the provider unless redis is defined. +session: + ## The name of the session cookie. + name: authelia_session + + ## The domain to protect. + ## Note: the authenticator must also be in that domain. + ## If empty, the cookie is restricted to the subdomain of the issuer. + domain: [domain.tld] + + ## Sets the Cookie SameSite value. Possible options are none, lax, or strict. + ## Please read https://www.authelia.com/c/session#same_site + same_site: lax + + ## The secret to encrypt the session data. This is only used with Redis / Redis Sentinel. + ## Secret can also be set using a secret: https://www.authelia.com/c/secrets + secret: REDACTED + + ## The value for expiration, inactivity, and remember_me_duration are in seconds or the duration notation format. + ## See: https://www.authelia.com/c/common#duration-notation-format + ## All three of these values affect the cookie/session validity period. Longer periods are considered less secure + ## because a stolen cookie will last longer giving attackers more time to spy or attack. + + ## The time before the cookie expires and the session is destroyed if remember me IS NOT selected. + expiration: 1h + + ## The inactivity time before the session is reset. If expiration is set to 1h, and this is set to 5m, if the user + ## does not select the remember me option their session will get destroyed after 1h, or after 5m since the last time + ## Authelia detected user activity. + inactivity: 5m + + ## The time before the cookie expires and the session is destroyed if remember me IS selected. + ## Value of -1 disables remember me. + remember_me_duration: 2M + + ## + ## Redis Provider + ## + ## Important: Kubernetes (or HA) users must read https://www.authelia.com/t/statelessness + ## + redis: + host: redis + port: 6379 + ## Use a unix socket instead + # host: /var/run/redis/redis.sock + + ## Username used for redis authentication. This is optional and a new feature in redis 6.0. + # username: authelia + + ## Password can also be set using a secret: https://www.authelia.com/c/secrets + password: REDACTED + + ## This is the Redis DB Index https://redis.io/commands/select (sometimes referred to as database number, DB, etc). + database_index: 0 + + ## The maximum number of concurrent active connections to Redis. + maximum_active_connections: 10 + + ## The target number of idle connections to have open ready for work. Useful when opening connections is slow. + minimum_idle_connections: 0 + + ## The Redis TLS configuration. If defined will require a TLS connection to the Redis instance(s). + # tls: + ## The server subject name to check the servers certificate against during the validation process. + ## This option is not required if the certificate has a SAN which matches the host option. + # server_name: myredis.example.com + + ## Skip verifying the server certificate entirely. In preference to setting this we strongly recommend you add the + ## certificate or the certificate of the authority signing the certificate to the certificates directory which is + ## defined by the `certificates_directory` option at the top of the configuration. + ## It's important to note the public key should be added to the directory, not the private key. + ## This option is strongly discouraged but may be useful in some self-signed situations where validation is not + ## important to the administrator. + # skip_verify: false + + ## Minimum TLS version for the connection. + # minimum_version: TLS1.2 + + ## Maximum TLS version for the connection. + # maximum_version: TLS1.3 + + ## The certificate chain used with the private_key if the server requests TLS Client Authentication + ## i.e. Mutual TLS. + # certificate_chain: | + # -----BEGIN CERTIFICATE----- + # MIIC5jCCAc6gAwIBAgIRAK4Sj7FiN6PXo/urPfO4E7owDQYJKoZIhvcNAQELBQAw + # EzERMA8GA1UEChMIQXV0aGVsaWEwHhcNNzAwMTAxMDAwMDAwWhcNNzEwMTAxMDAw + # MDAwWjATMREwDwYDVQQKEwhBdXRoZWxpYTCCASIwDQYJKoZIhvcNAQEBBQADggEP + # ADCCAQoCggEBAPKv3pSyP4ozGEiVLJ14dIWFCEGEgq7WUMI0SZZqQA2ID0L59U/Q + # /Usyy7uC9gfMUzODTpANtkOjFQcQAsxlR1FOjVBrX5QgjSvXwbQn3DtwMA7XWSl6 + # LuYx2rBYSlMSN5UZQm/RxMtXfLK2b51WgEEYDFi+nECSqKzR4R54eOPkBEWRfvuY + # 91AMjlhpivg8e4JWkq4LVQUKbmiFYwIdK8XQiN4blY9WwXwJFYs5sQ/UYMwBFi0H + # kWOh7GEjfxgoUOPauIueZSMSlQp7zqAH39N0ZSYb6cS0Npj57QoWZSY3ak87ebcR + # Nf4rCvZLby7LoN7qYCKxmCaDD3x2+NYpWH8CAwEAAaM1MDMwDgYDVR0PAQH/BAQD + # AgWgMBMGA1UdJQQMMAoGCCsGAQUFBwMBMAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcN + # AQELBQADggEBAHSITqIQSNzonFl3DzxHPEzr2hp6peo45buAAtu8FZHoA+U7Icfh + # /ZXjPg7Xz+hgFwM/DTNGXkMWacQA/PaNWvZspgRJf2AXvNbMSs2UQODr7Tbv+Fb4 + # lyblmMUNYFMCFVAMU0eIxXAFq2qcwv8UMcQFT0Z/35s6PVOakYnAGGQjTfp5Ljuq + # wsdc/xWmM0cHWube6sdRRUD7SY20KU/kWzl8iFO0VbSSrDf1AlEhnLEkp1SPaxXg + # OdBnl98MeoramNiJ7NT6Jnyb3zZ578fjaWfThiBpagItI8GZmG4s4Ovh2JbheN8i + # ZsjNr9jqHTjhyLVbDRlmJzcqoj4JhbKs6/I^invalid DO NOT USE= + # -----END CERTIFICATE----- + # -----BEGIN CERTIFICATE----- + # MIIDBDCCAeygAwIBAgIRALJsPg21kA0zY4F1wUCIuoMwDQYJKoZIhvcNAQELBQAw + # EzERMA8GA1UEChMIQXV0aGVsaWEwHhcNNzAwMTAxMDAwMDAwWhcNNzEwMTAxMDAw + # MDAwWjATMREwDwYDVQQKEwhBdXRoZWxpYTCCASIwDQYJKoZIhvcNAQEBBQADggEP + # ADCCAQoCggEBAMXHBvVxUzYk0u34/DINMSF+uiOekKOAjOrC6Mi9Ww8ytPVO7t2S + # zfTvM+XnEJqkFQFgimERfG/eGhjF9XIEY6LtnXe8ATvOK4nTwdufzBaoeQu3Gd50 + # 5VXr6OHRo//ErrGvFXwP3g8xLePABsi/fkH3oDN+ztewOBMDzpd+KgTrk8ysv2ou + # kNRMKFZZqASvCgv0LD5KWvUCnL6wgf1oTXG7aztduA4oSkUP321GpOmBC5+5ElU7 + # ysoRzvD12o9QJ/IfEaulIX06w9yVMo60C/h6A3U6GdkT1SiyTIqR7v7KU/IWd/Qi + # Lfftcj91VhCmJ73Meff2e2S2PrpjdXbG5FMCAwEAAaNTMFEwDgYDVR0PAQH/BAQD + # AgKkMA8GA1UdJQQIMAYGBFUdJQAwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU + # Z7AtA3mzFc0InSBA5fiMfeLXA3owDQYJKoZIhvcNAQELBQADggEBAEE5hm1mtlk/ + # kviCoHH4evbpw7rxPxDftIQlqYTtvMM4eWY/6icFoSZ4fUHEWYyps8SsPu/8f2tf + # 71LGgZn0FdHi1QU2H8m0HHK7TFw+5Q6RLrLdSyk0PItJ71s9en7r8pX820nAFEHZ + # HkOSfJZ7B5hFgUDkMtVM6bardXAhoqcMk4YCU96e9d4PB4eI+xGc+mNuYvov3RbB + # D0s8ICyojeyPVLerz4wHjZu68Z5frAzhZ68YbzNs8j2fIBKKHkHyLG1iQyF+LJVj + # 2PjCP+auJsj6fQQpMGoyGtpLcSDh+ptcTngUD8JsWipzTCjmaNqdPHAOYmcgtf4b + # qocikt3WAdU^invalid DO NOT USE= + # -----END CERTIFICATE----- + + ## The private key used with the certificate_chain if the server requests TLS Client Authentication + ## i.e. Mutual TLS. + # private_key: | + # -----BEGIN RSA PRIVATE KEY----- + # MIIEpAIBAAKCAQEA8q/elLI/ijMYSJUsnXh0hYUIQYSCrtZQwjRJlmpADYgPQvn1 + # T9D9SzLLu4L2B8xTM4NOkA22Q6MVBxACzGVHUU6NUGtflCCNK9fBtCfcO3AwDtdZ + # KXou5jHasFhKUxI3lRlCb9HEy1d8srZvnVaAQRgMWL6cQJKorNHhHnh44+QERZF+ + # +5j3UAyOWGmK+Dx7glaSrgtVBQpuaIVjAh0rxdCI3huVj1bBfAkVizmxD9RgzAEW + # LQeRY6HsYSN/GChQ49q4i55lIxKVCnvOoAff03RlJhvpxLQ2mPntChZlJjdqTzt5 + # txE1/isK9ktvLsug3upgIrGYJoMPfHb41ilYfwIDAQABAoIBAQDTOdFf2JjHH1um + # aPgRAvNf9v7Nj5jytaRKs5nM6iNf46ls4QPreXnMhqSeSwj6lpNgBYxOgzC9Q+cc + # Y4ob/paJJPaIJTxmP8K/gyWcOQlNToL1l+eJ20eQoZm23NGr5fIsunSBwLEpTrdB + # ENqqtcwhW937K8Pxy/Q1nuLyU2bc6Tn/ivLozc8n27dpQWWKh8537VY7ancIaACr + # LJJLYxKqhQpjtBWAyCDvZQirnAOm9KnvIHaGXIswCZ4Xbsu0Y9NL+woARPyRVQvG + # jfxy4EmO9s1s6y7OObSukwKDSNihAKHx/VIbvVWx8g2Lv5fGOa+J2Y7o9Qurs8t5 + # BQwMTt0BAoGBAPUw5Z32EszNepAeV3E2mPFUc5CLiqAxagZJuNDO2pKtyN29ETTR + # Ma4O1cWtGb6RqcNNN/Iukfkdk27Q5nC9VJSUUPYelOLc1WYOoUf6oKRzE72dkMQV + # R4bf6TkjD+OVR17fAfkswkGahZ5XA7j48KIQ+YC4jbnYKSxZTYyKPjH/AoGBAP1i + # tqXt36OVlP+y84wWqZSjMelBIVa9phDVGJmmhz3i1cMni8eLpJzWecA3pfnG6Tm9 + # ze5M4whASleEt+M00gEvNaU9ND+z0wBfi+/DwJYIbv8PQdGrBiZFrPhTPjGQUldR + # lXccV2meeLZv7TagVxSi3DO6dSJfSEHyemd5j9mBAoGAX8Hv+0gOQZQCSOTAq8Nx + # 6dZcp9gHlNaXnMsP9eTDckOSzh636JPGvj6m+GPJSSbkURUIQ3oyokMNwFqvlNos + # fTaLhAOfjBZI9WnDTTQxpugWjphJ4HqbC67JC/qIiw5S6FdaEvGLEEoD4zoChywZ + # 9oGAn+fz2d/0/JAH/FpFPgsCgYEAp/ipZgPzziiZ9ov1wbdAQcWRj7RaWnssPFpX + # jXwEiXT3CgEMO4MJ4+KWIWOChrti3qFBg6i6lDyyS6Qyls7sLFbUdC7HlTcrOEMe + # rBoTcCI1GqZNlqWOVQ65ZIEiaI7o1vPBZo2GMQEZuq8mDKFsOMThvvTrM5cAep84 + # n6HJR4ECgYABWcbsSnr0MKvVth/inxjbKapbZnp2HUCuw87Ie5zK2Of/tbC20wwk + # yKw3vrGoE3O1t1g2m2tn8UGGASeZ842jZWjIODdSi5+icysQGuULKt86h/woz2SQ + # 27GoE2i5mh6Yez6VAYbUuns3FcwIsMyWLq043Tu2DNkx9ijOOAuQzw^invalid.. + # DO NOT USE== + # -----END RSA PRIVATE KEY----- + + ## The Redis HA configuration options. + ## This provides specific options to Redis Sentinel, sentinel_name must be defined (Master Name). + # high_availability: + ## Sentinel Name / Master Name. + # sentinel_name: mysentinel + + ## Specific username for Redis Sentinel. The node username and password is configured above. + # sentinel_username: sentinel_specific_user + + ## Specific password for Redis Sentinel. The node username and password is configured above. + # sentinel_password: sentinel_specific_pass + + ## The additional nodes to pre-seed the redis provider with (for sentinel). + ## If the host in the above section is defined, it will be combined with this list to connect to sentinel. + ## For high availability to be used you must have either defined; the host above or at least one node below. + # nodes: + # - host: sentinel-node1 + # port: 6379 + # - host: sentinel-node2 + # port: 6379 + + ## Choose the host with the lowest latency. + # route_by_latency: false + + ## Choose the host randomly. + # route_randomly: false + +## +## Regulation Configuration +## +## This mechanism prevents attackers from brute forcing the first factor. It bans the user if too many attempts are made +## in a short period of time. +regulation: + ## The number of failed login attempts before user is banned. Set it to 0 to disable regulation. + max_retries: 3 + + ## The time range during which the user can attempt login before being banned. The user is banned if the + ## authentication failed 'max_retries' times in a 'find_time' seconds window. Find Time accepts duration notation. + ## See: https://www.authelia.com/c/common#duration-notation-format + find_time: 10m + + ## The length of time before a banned user can login again. Ban Time accepts duration notation. + ## See: https://www.authelia.com/c/common#duration-notation-format + ban_time: 12h + +## +## Storage Provider Configuration +## +## The available providers are: `local`, `mysql`, `postgres`. You must use one and only one of these providers. +storage: + ## The encryption key that is used to encrypt sensitive information in the database. Must be a string with a minimum + ## length of 20. Please see the docs if you configure this with an undesirable key and need to change it, you MUST use + ## the CLI to change this in the database if you want to change it from a previously configured value. + encryption_key: REDACTED + + ## + ## Local (Storage Provider) + ## + ## This stores the data in a SQLite3 Database. + ## This is only recommended for lightweight non-stateful installations. + ## + ## Important: Kubernetes (or HA) users must read https://www.authelia.com/t/statelessness + ## + # local: + ## Path to the SQLite3 Database. + # path: /config/db.sqlite3 + + ## + ## MySQL / MariaDB (Storage Provider) + ## + mysql: + host: mysql + port: 3306 + database: authelia + username: authelia + ## Password can also be set using a secret: https://www.authelia.com/c/secrets + password: REDACTED + timeout: 5s + + ## MySQL TLS settings. Configuring this requires TLS. + # tls: + ## The server subject name to check the servers certificate against during the validation process. + ## This option is not required if the certificate has a SAN which matches the host option. + # server_name: mysql.example.com + + ## Skip verifying the server certificate entirely. In preference to setting this we strongly recommend you add the + ## certificate or the certificate of the authority signing the certificate to the certificates directory which is + ## defined by the `certificates_directory` option at the top of the configuration. + ## It's important to note the public key should be added to the directory, not the private key. + ## This option is strongly discouraged but may be useful in some self-signed situations where validation is not + ## important to the administrator. + # skip_verify: false + + ## Minimum TLS version for the connection. + # minimum_version: TLS1.2 + + ## Maximum TLS version for the connection. + # maximum_version: TLS1.3 + + ## The certificate chain used with the private_key if the server requests TLS Client Authentication + ## i.e. Mutual TLS. + # certificate_chain: | + # -----BEGIN CERTIFICATE----- + # MIIC5jCCAc6gAwIBAgIRAK4Sj7FiN6PXo/urPfO4E7owDQYJKoZIhvcNAQELBQAw + # EzERMA8GA1UEChMIQXV0aGVsaWEwHhcNNzAwMTAxMDAwMDAwWhcNNzEwMTAxMDAw + # MDAwWjATMREwDwYDVQQKEwhBdXRoZWxpYTCCASIwDQYJKoZIhvcNAQEBBQADggEP + # ADCCAQoCggEBAPKv3pSyP4ozGEiVLJ14dIWFCEGEgq7WUMI0SZZqQA2ID0L59U/Q + # /Usyy7uC9gfMUzODTpANtkOjFQcQAsxlR1FOjVBrX5QgjSvXwbQn3DtwMA7XWSl6 + # LuYx2rBYSlMSN5UZQm/RxMtXfLK2b51WgEEYDFi+nECSqKzR4R54eOPkBEWRfvuY + # 91AMjlhpivg8e4JWkq4LVQUKbmiFYwIdK8XQiN4blY9WwXwJFYs5sQ/UYMwBFi0H + # kWOh7GEjfxgoUOPauIueZSMSlQp7zqAH39N0ZSYb6cS0Npj57QoWZSY3ak87ebcR + # Nf4rCvZLby7LoN7qYCKxmCaDD3x2+NYpWH8CAwEAAaM1MDMwDgYDVR0PAQH/BAQD + # AgWgMBMGA1UdJQQMMAoGCCsGAQUFBwMBMAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcN + # AQELBQADggEBAHSITqIQSNzonFl3DzxHPEzr2hp6peo45buAAtu8FZHoA+U7Icfh + # /ZXjPg7Xz+hgFwM/DTNGXkMWacQA/PaNWvZspgRJf2AXvNbMSs2UQODr7Tbv+Fb4 + # lyblmMUNYFMCFVAMU0eIxXAFq2qcwv8UMcQFT0Z/35s6PVOakYnAGGQjTfp5Ljuq + # wsdc/xWmM0cHWube6sdRRUD7SY20KU/kWzl8iFO0VbSSrDf1AlEhnLEkp1SPaxXg + # OdBnl98MeoramNiJ7NT6Jnyb3zZ578fjaWfThiBpagItI8GZmG4s4Ovh2JbheN8i + # ZsjNr9jqHTjhyLVbDRlmJzcqoj4JhbKs6/I^invalid DO NOT USE= + # -----END CERTIFICATE----- + # -----BEGIN CERTIFICATE----- + # MIIDBDCCAeygAwIBAgIRALJsPg21kA0zY4F1wUCIuoMwDQYJKoZIhvcNAQELBQAw + # EzERMA8GA1UEChMIQXV0aGVsaWEwHhcNNzAwMTAxMDAwMDAwWhcNNzEwMTAxMDAw + # MDAwWjATMREwDwYDVQQKEwhBdXRoZWxpYTCCASIwDQYJKoZIhvcNAQEBBQADggEP + # ADCCAQoCggEBAMXHBvVxUzYk0u34/DINMSF+uiOekKOAjOrC6Mi9Ww8ytPVO7t2S + # zfTvM+XnEJqkFQFgimERfG/eGhjF9XIEY6LtnXe8ATvOK4nTwdufzBaoeQu3Gd50 + # 5VXr6OHRo//ErrGvFXwP3g8xLePABsi/fkH3oDN+ztewOBMDzpd+KgTrk8ysv2ou + # kNRMKFZZqASvCgv0LD5KWvUCnL6wgf1oTXG7aztduA4oSkUP321GpOmBC5+5ElU7 + # ysoRzvD12o9QJ/IfEaulIX06w9yVMo60C/h6A3U6GdkT1SiyTIqR7v7KU/IWd/Qi + # Lfftcj91VhCmJ73Meff2e2S2PrpjdXbG5FMCAwEAAaNTMFEwDgYDVR0PAQH/BAQD + # AgKkMA8GA1UdJQQIMAYGBFUdJQAwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU + # Z7AtA3mzFc0InSBA5fiMfeLXA3owDQYJKoZIhvcNAQELBQADggEBAEE5hm1mtlk/ + # kviCoHH4evbpw7rxPxDftIQlqYTtvMM4eWY/6icFoSZ4fUHEWYyps8SsPu/8f2tf + # 71LGgZn0FdHi1QU2H8m0HHK7TFw+5Q6RLrLdSyk0PItJ71s9en7r8pX820nAFEHZ + # HkOSfJZ7B5hFgUDkMtVM6bardXAhoqcMk4YCU96e9d4PB4eI+xGc+mNuYvov3RbB + # D0s8ICyojeyPVLerz4wHjZu68Z5frAzhZ68YbzNs8j2fIBKKHkHyLG1iQyF+LJVj + # 2PjCP+auJsj6fQQpMGoyGtpLcSDh+ptcTngUD8JsWipzTCjmaNqdPHAOYmcgtf4b + # qocikt3WAdU^invalid DO NOT USE= + # -----END CERTIFICATE----- + + ## The private key used with the certificate_chain if the server requests TLS Client Authentication + ## i.e. Mutual TLS. + # private_key: | + # -----BEGIN RSA PRIVATE KEY----- + # MIIEpAIBAAKCAQEA8q/elLI/ijMYSJUsnXh0hYUIQYSCrtZQwjRJlmpADYgPQvn1 + # T9D9SzLLu4L2B8xTM4NOkA22Q6MVBxACzGVHUU6NUGtflCCNK9fBtCfcO3AwDtdZ + # KXou5jHasFhKUxI3lRlCb9HEy1d8srZvnVaAQRgMWL6cQJKorNHhHnh44+QERZF+ + # +5j3UAyOWGmK+Dx7glaSrgtVBQpuaIVjAh0rxdCI3huVj1bBfAkVizmxD9RgzAEW + # LQeRY6HsYSN/GChQ49q4i55lIxKVCnvOoAff03RlJhvpxLQ2mPntChZlJjdqTzt5 + # txE1/isK9ktvLsug3upgIrGYJoMPfHb41ilYfwIDAQABAoIBAQDTOdFf2JjHH1um + # aPgRAvNf9v7Nj5jytaRKs5nM6iNf46ls4QPreXnMhqSeSwj6lpNgBYxOgzC9Q+cc + # Y4ob/paJJPaIJTxmP8K/gyWcOQlNToL1l+eJ20eQoZm23NGr5fIsunSBwLEpTrdB + # ENqqtcwhW937K8Pxy/Q1nuLyU2bc6Tn/ivLozc8n27dpQWWKh8537VY7ancIaACr + # LJJLYxKqhQpjtBWAyCDvZQirnAOm9KnvIHaGXIswCZ4Xbsu0Y9NL+woARPyRVQvG + # jfxy4EmO9s1s6y7OObSukwKDSNihAKHx/VIbvVWx8g2Lv5fGOa+J2Y7o9Qurs8t5 + # BQwMTt0BAoGBAPUw5Z32EszNepAeV3E2mPFUc5CLiqAxagZJuNDO2pKtyN29ETTR + # Ma4O1cWtGb6RqcNNN/Iukfkdk27Q5nC9VJSUUPYelOLc1WYOoUf6oKRzE72dkMQV + # R4bf6TkjD+OVR17fAfkswkGahZ5XA7j48KIQ+YC4jbnYKSxZTYyKPjH/AoGBAP1i + # tqXt36OVlP+y84wWqZSjMelBIVa9phDVGJmmhz3i1cMni8eLpJzWecA3pfnG6Tm9 + # ze5M4whASleEt+M00gEvNaU9ND+z0wBfi+/DwJYIbv8PQdGrBiZFrPhTPjGQUldR + # lXccV2meeLZv7TagVxSi3DO6dSJfSEHyemd5j9mBAoGAX8Hv+0gOQZQCSOTAq8Nx + # 6dZcp9gHlNaXnMsP9eTDckOSzh636JPGvj6m+GPJSSbkURUIQ3oyokMNwFqvlNos + # fTaLhAOfjBZI9WnDTTQxpugWjphJ4HqbC67JC/qIiw5S6FdaEvGLEEoD4zoChywZ + # 9oGAn+fz2d/0/JAH/FpFPgsCgYEAp/ipZgPzziiZ9ov1wbdAQcWRj7RaWnssPFpX + # jXwEiXT3CgEMO4MJ4+KWIWOChrti3qFBg6i6lDyyS6Qyls7sLFbUdC7HlTcrOEMe + # rBoTcCI1GqZNlqWOVQ65ZIEiaI7o1vPBZo2GMQEZuq8mDKFsOMThvvTrM5cAep84 + # n6HJR4ECgYABWcbsSnr0MKvVth/inxjbKapbZnp2HUCuw87Ie5zK2Of/tbC20wwk + # yKw3vrGoE3O1t1g2m2tn8UGGASeZ842jZWjIODdSi5+icysQGuULKt86h/woz2SQ + # 27GoE2i5mh6Yez6VAYbUuns3FcwIsMyWLq043Tu2DNkx9ijOOAuQzw^invalid.. + # DO NOT USE== + # -----END RSA PRIVATE KEY----- + + ## + ## PostgreSQL (Storage Provider) + ## + # postgres: + # host: 127.0.0.1 + # port: 5432 + # database: authelia + # schema: public + # username: authelia + ## Password can also be set using a secret: https://www.authelia.com/c/secrets + # password: mypassword + # timeout: 5s + + ## PostgreSQL TLS settings. Configuring this requires TLS. + # tls: + ## The server subject name to check the servers certificate against during the validation process. + ## This option is not required if the certificate has a SAN which matches the host option. + # server_name: postgres.example.com + + ## Skip verifying the server certificate entirely. In preference to setting this we strongly recommend you add the + ## certificate or the certificate of the authority signing the certificate to the certificates directory which is + ## defined by the `certificates_directory` option at the top of the configuration. + ## It's important to note the public key should be added to the directory, not the private key. + ## This option is strongly discouraged but may be useful in some self-signed situations where validation is not + ## important to the administrator. + # skip_verify: false + + ## Minimum TLS version for the connection. + # minimum_version: TLS1.2 + + ## Maximum TLS version for the connection. + # maximum_version: TLS1.3 + + ## The certificate chain used with the private_key if the server requests TLS Client Authentication + ## i.e. Mutual TLS. + # certificate_chain: | + # -----BEGIN CERTIFICATE----- + # MIIC5jCCAc6gAwIBAgIRAK4Sj7FiN6PXo/urPfO4E7owDQYJKoZIhvcNAQELBQAw + # EzERMA8GA1UEChMIQXV0aGVsaWEwHhcNNzAwMTAxMDAwMDAwWhcNNzEwMTAxMDAw + # MDAwWjATMREwDwYDVQQKEwhBdXRoZWxpYTCCASIwDQYJKoZIhvcNAQEBBQADggEP + # ADCCAQoCggEBAPKv3pSyP4ozGEiVLJ14dIWFCEGEgq7WUMI0SZZqQA2ID0L59U/Q + # /Usyy7uC9gfMUzODTpANtkOjFQcQAsxlR1FOjVBrX5QgjSvXwbQn3DtwMA7XWSl6 + # LuYx2rBYSlMSN5UZQm/RxMtXfLK2b51WgEEYDFi+nECSqKzR4R54eOPkBEWRfvuY + # 91AMjlhpivg8e4JWkq4LVQUKbmiFYwIdK8XQiN4blY9WwXwJFYs5sQ/UYMwBFi0H + # kWOh7GEjfxgoUOPauIueZSMSlQp7zqAH39N0ZSYb6cS0Npj57QoWZSY3ak87ebcR + # Nf4rCvZLby7LoN7qYCKxmCaDD3x2+NYpWH8CAwEAAaM1MDMwDgYDVR0PAQH/BAQD + # AgWgMBMGA1UdJQQMMAoGCCsGAQUFBwMBMAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcN + # AQELBQADggEBAHSITqIQSNzonFl3DzxHPEzr2hp6peo45buAAtu8FZHoA+U7Icfh + # /ZXjPg7Xz+hgFwM/DTNGXkMWacQA/PaNWvZspgRJf2AXvNbMSs2UQODr7Tbv+Fb4 + # lyblmMUNYFMCFVAMU0eIxXAFq2qcwv8UMcQFT0Z/35s6PVOakYnAGGQjTfp5Ljuq + # wsdc/xWmM0cHWube6sdRRUD7SY20KU/kWzl8iFO0VbSSrDf1AlEhnLEkp1SPaxXg + # OdBnl98MeoramNiJ7NT6Jnyb3zZ578fjaWfThiBpagItI8GZmG4s4Ovh2JbheN8i + # ZsjNr9jqHTjhyLVbDRlmJzcqoj4JhbKs6/I^invalid DO NOT USE= + # -----END CERTIFICATE----- + # -----BEGIN CERTIFICATE----- + # MIIDBDCCAeygAwIBAgIRALJsPg21kA0zY4F1wUCIuoMwDQYJKoZIhvcNAQELBQAw + # EzERMA8GA1UEChMIQXV0aGVsaWEwHhcNNzAwMTAxMDAwMDAwWhcNNzEwMTAxMDAw + # MDAwWjATMREwDwYDVQQKEwhBdXRoZWxpYTCCASIwDQYJKoZIhvcNAQEBBQADggEP + # ADCCAQoCggEBAMXHBvVxUzYk0u34/DINMSF+uiOekKOAjOrC6Mi9Ww8ytPVO7t2S + # zfTvM+XnEJqkFQFgimERfG/eGhjF9XIEY6LtnXe8ATvOK4nTwdufzBaoeQu3Gd50 + # 5VXr6OHRo//ErrGvFXwP3g8xLePABsi/fkH3oDN+ztewOBMDzpd+KgTrk8ysv2ou + # kNRMKFZZqASvCgv0LD5KWvUCnL6wgf1oTXG7aztduA4oSkUP321GpOmBC5+5ElU7 + # ysoRzvD12o9QJ/IfEaulIX06w9yVMo60C/h6A3U6GdkT1SiyTIqR7v7KU/IWd/Qi + # Lfftcj91VhCmJ73Meff2e2S2PrpjdXbG5FMCAwEAAaNTMFEwDgYDVR0PAQH/BAQD + # AgKkMA8GA1UdJQQIMAYGBFUdJQAwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU + # Z7AtA3mzFc0InSBA5fiMfeLXA3owDQYJKoZIhvcNAQELBQADggEBAEE5hm1mtlk/ + # kviCoHH4evbpw7rxPxDftIQlqYTtvMM4eWY/6icFoSZ4fUHEWYyps8SsPu/8f2tf + # 71LGgZn0FdHi1QU2H8m0HHK7TFw+5Q6RLrLdSyk0PItJ71s9en7r8pX820nAFEHZ + # HkOSfJZ7B5hFgUDkMtVM6bardXAhoqcMk4YCU96e9d4PB4eI+xGc+mNuYvov3RbB + # D0s8ICyojeyPVLerz4wHjZu68Z5frAzhZ68YbzNs8j2fIBKKHkHyLG1iQyF+LJVj + # 2PjCP+auJsj6fQQpMGoyGtpLcSDh+ptcTngUD8JsWipzTCjmaNqdPHAOYmcgtf4b + # qocikt3WAdU^invalid DO NOT USE= + # -----END CERTIFICATE----- + + ## The private key used with the certificate_chain if the server requests TLS Client Authentication + ## i.e. Mutual TLS. + # private_key: | + # -----BEGIN RSA PRIVATE KEY----- + # MIIEpAIBAAKCAQEA8q/elLI/ijMYSJUsnXh0hYUIQYSCrtZQwjRJlmpADYgPQvn1 + # T9D9SzLLu4L2B8xTM4NOkA22Q6MVBxACzGVHUU6NUGtflCCNK9fBtCfcO3AwDtdZ + # KXou5jHasFhKUxI3lRlCb9HEy1d8srZvnVaAQRgMWL6cQJKorNHhHnh44+QERZF+ + # +5j3UAyOWGmK+Dx7glaSrgtVBQpuaIVjAh0rxdCI3huVj1bBfAkVizmxD9RgzAEW + # LQeRY6HsYSN/GChQ49q4i55lIxKVCnvOoAff03RlJhvpxLQ2mPntChZlJjdqTzt5 + # txE1/isK9ktvLsug3upgIrGYJoMPfHb41ilYfwIDAQABAoIBAQDTOdFf2JjHH1um + # aPgRAvNf9v7Nj5jytaRKs5nM6iNf46ls4QPreXnMhqSeSwj6lpNgBYxOgzC9Q+cc + # Y4ob/paJJPaIJTxmP8K/gyWcOQlNToL1l+eJ20eQoZm23NGr5fIsunSBwLEpTrdB + # ENqqtcwhW937K8Pxy/Q1nuLyU2bc6Tn/ivLozc8n27dpQWWKh8537VY7ancIaACr + # LJJLYxKqhQpjtBWAyCDvZQirnAOm9KnvIHaGXIswCZ4Xbsu0Y9NL+woARPyRVQvG + # jfxy4EmO9s1s6y7OObSukwKDSNihAKHx/VIbvVWx8g2Lv5fGOa+J2Y7o9Qurs8t5 + # BQwMTt0BAoGBAPUw5Z32EszNepAeV3E2mPFUc5CLiqAxagZJuNDO2pKtyN29ETTR + # Ma4O1cWtGb6RqcNNN/Iukfkdk27Q5nC9VJSUUPYelOLc1WYOoUf6oKRzE72dkMQV + # R4bf6TkjD+OVR17fAfkswkGahZ5XA7j48KIQ+YC4jbnYKSxZTYyKPjH/AoGBAP1i + # tqXt36OVlP+y84wWqZSjMelBIVa9phDVGJmmhz3i1cMni8eLpJzWecA3pfnG6Tm9 + # ze5M4whASleEt+M00gEvNaU9ND+z0wBfi+/DwJYIbv8PQdGrBiZFrPhTPjGQUldR + # lXccV2meeLZv7TagVxSi3DO6dSJfSEHyemd5j9mBAoGAX8Hv+0gOQZQCSOTAq8Nx + # 6dZcp9gHlNaXnMsP9eTDckOSzh636JPGvj6m+GPJSSbkURUIQ3oyokMNwFqvlNos + # fTaLhAOfjBZI9WnDTTQxpugWjphJ4HqbC67JC/qIiw5S6FdaEvGLEEoD4zoChywZ + # 9oGAn+fz2d/0/JAH/FpFPgsCgYEAp/ipZgPzziiZ9ov1wbdAQcWRj7RaWnssPFpX + # jXwEiXT3CgEMO4MJ4+KWIWOChrti3qFBg6i6lDyyS6Qyls7sLFbUdC7HlTcrOEMe + # rBoTcCI1GqZNlqWOVQ65ZIEiaI7o1vPBZo2GMQEZuq8mDKFsOMThvvTrM5cAep84 + # n6HJR4ECgYABWcbsSnr0MKvVth/inxjbKapbZnp2HUCuw87Ie5zK2Of/tbC20wwk + # yKw3vrGoE3O1t1g2m2tn8UGGASeZ842jZWjIODdSi5+icysQGuULKt86h/woz2SQ + # 27GoE2i5mh6Yez6VAYbUuns3FcwIsMyWLq043Tu2DNkx9ijOOAuQzw^invalid.. + # DO NOT USE== + # -----END RSA PRIVATE KEY----- + +## +## Notification Provider +## +## Notifications are sent to users when they require a password reset, a Webauthn registration or a TOTP registration. +## The available providers are: filesystem, smtp. You must use only one of these providers. +notifier: + ## You can disable the notifier startup check by setting this to true. + disable_startup_check: false + + ## + ## File System (Notification Provider) + ## + ## Important: Kubernetes (or HA) users must read https://www.authelia.com/t/statelessness + ## +# filesystem: +# filename: /config/notification.txt + + ## + ## SMTP (Notification Provider) + ## + ## Use a SMTP server for sending notifications. Authelia uses the PLAIN or LOGIN methods to authenticate. + ## [Security] By default Authelia will: + ## - force all SMTP connections over TLS including unauthenticated connections + ## - use the disable_require_tls boolean value to disable this requirement + ## (only works for unauthenticated connections) + ## - validate the SMTP server x509 certificate during the TLS handshake against the hosts trusted certificates + ## (configure in tls section) + smtp: + ## The SMTP host to connect to. + host: smtp.gmail.com + + ## The port to connect to the SMTP host on. + port: 587 + + ## The connection timeout. + timeout: 5s + + ## The username used for SMTP authentication. + username: [emailaddressrelay]@gmail.com + + ## The password used for SMTP authentication. + ## Can also be set using a secret: https://www.authelia.com/c/secrets + password: REDACTED + + ## The sender is used to is used for the MAIL FROM command and the FROM header. + ## If this is not defined and the username is an email, we use the username as this value. This can either be just + ## an email address or the RFC5322 'Name ' format. + sender: "Authelia " + + ## HELO/EHLO Identifier. Some SMTP Servers may reject the default of localhost. + identifier: [domain.tld] + + ## Subject configuration of the emails sent. {title} is replaced by the text from the notifier. + subject: "[Authelia] {title}" + + ## This address is used during the startup check to verify the email configuration is correct. + ## It's not important what it is except if your email server only allows local delivery. + startup_check_address: [emailaddressrelay]@gmail.com + + ## By default we require some form of TLS. This disables this check though is not advised. + # disable_require_tls: false + + ## Disables sending HTML formatted emails. + # disable_html_emails: false + + tls: + ## The server subject name to check the servers certificate against during the validation process. + ## This option is not required if the certificate has a SAN which matches the host option. + server_name: smtp.gmail.com + + ## Skip verifying the server certificate entirely. In preference to setting this we strongly recommend you add the + ## certificate or the certificate of the authority signing the certificate to the certificates directory which is + ## defined by the `certificates_directory` option at the top of the configuration. + ## It's important to note the public key should be added to the directory, not the private key. + ## This option is strongly discouraged but may be useful in some self-signed situations where validation is not + ## important to the administrator. + # skip_verify: false + + ## Minimum TLS version for the connection. + # minimum_version: TLS1.2 + + ## Maximum TLS version for the connection. + # maximum_version: TLS1.3 + + ## The certificate chain used with the private_key if the server requests TLS Client Authentication + ## i.e. Mutual TLS. + # certificate_chain: | + # -----BEGIN CERTIFICATE----- + # MIIC5jCCAc6gAwIBAgIRAK4Sj7FiN6PXo/urPfO4E7owDQYJKoZIhvcNAQELBQAw + # EzERMA8GA1UEChMIQXV0aGVsaWEwHhcNNzAwMTAxMDAwMDAwWhcNNzEwMTAxMDAw + # MDAwWjATMREwDwYDVQQKEwhBdXRoZWxpYTCCASIwDQYJKoZIhvcNAQEBBQADggEP + # ADCCAQoCggEBAPKv3pSyP4ozGEiVLJ14dIWFCEGEgq7WUMI0SZZqQA2ID0L59U/Q + # /Usyy7uC9gfMUzODTpANtkOjFQcQAsxlR1FOjVBrX5QgjSvXwbQn3DtwMA7XWSl6 + # LuYx2rBYSlMSN5UZQm/RxMtXfLK2b51WgEEYDFi+nECSqKzR4R54eOPkBEWRfvuY + # 91AMjlhpivg8e4JWkq4LVQUKbmiFYwIdK8XQiN4blY9WwXwJFYs5sQ/UYMwBFi0H + # kWOh7GEjfxgoUOPauIueZSMSlQp7zqAH39N0ZSYb6cS0Npj57QoWZSY3ak87ebcR + # Nf4rCvZLby7LoN7qYCKxmCaDD3x2+NYpWH8CAwEAAaM1MDMwDgYDVR0PAQH/BAQD + # AgWgMBMGA1UdJQQMMAoGCCsGAQUFBwMBMAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcN + # AQELBQADggEBAHSITqIQSNzonFl3DzxHPEzr2hp6peo45buAAtu8FZHoA+U7Icfh + # /ZXjPg7Xz+hgFwM/DTNGXkMWacQA/PaNWvZspgRJf2AXvNbMSs2UQODr7Tbv+Fb4 + # lyblmMUNYFMCFVAMU0eIxXAFq2qcwv8UMcQFT0Z/35s6PVOakYnAGGQjTfp5Ljuq + # wsdc/xWmM0cHWube6sdRRUD7SY20KU/kWzl8iFO0VbSSrDf1AlEhnLEkp1SPaxXg + # OdBnl98MeoramNiJ7NT6Jnyb3zZ578fjaWfThiBpagItI8GZmG4s4Ovh2JbheN8i + # ZsjNr9jqHTjhyLVbDRlmJzcqoj4JhbKs6/I^invalid DO NOT USE= + # -----END CERTIFICATE----- + # -----BEGIN CERTIFICATE----- + # MIIDBDCCAeygAwIBAgIRALJsPg21kA0zY4F1wUCIuoMwDQYJKoZIhvcNAQELBQAw + # EzERMA8GA1UEChMIQXV0aGVsaWEwHhcNNzAwMTAxMDAwMDAwWhcNNzEwMTAxMDAw + # MDAwWjATMREwDwYDVQQKEwhBdXRoZWxpYTCCASIwDQYJKoZIhvcNAQEBBQADggEP + # ADCCAQoCggEBAMXHBvVxUzYk0u34/DINMSF+uiOekKOAjOrC6Mi9Ww8ytPVO7t2S + # zfTvM+XnEJqkFQFgimERfG/eGhjF9XIEY6LtnXe8ATvOK4nTwdufzBaoeQu3Gd50 + # 5VXr6OHRo//ErrGvFXwP3g8xLePABsi/fkH3oDN+ztewOBMDzpd+KgTrk8ysv2ou + # kNRMKFZZqASvCgv0LD5KWvUCnL6wgf1oTXG7aztduA4oSkUP321GpOmBC5+5ElU7 + # ysoRzvD12o9QJ/IfEaulIX06w9yVMo60C/h6A3U6GdkT1SiyTIqR7v7KU/IWd/Qi + # Lfftcj91VhCmJ73Meff2e2S2PrpjdXbG5FMCAwEAAaNTMFEwDgYDVR0PAQH/BAQD + # AgKkMA8GA1UdJQQIMAYGBFUdJQAwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU + # Z7AtA3mzFc0InSBA5fiMfeLXA3owDQYJKoZIhvcNAQELBQADggEBAEE5hm1mtlk/ + # kviCoHH4evbpw7rxPxDftIQlqYTtvMM4eWY/6icFoSZ4fUHEWYyps8SsPu/8f2tf + # 71LGgZn0FdHi1QU2H8m0HHK7TFw+5Q6RLrLdSyk0PItJ71s9en7r8pX820nAFEHZ + # HkOSfJZ7B5hFgUDkMtVM6bardXAhoqcMk4YCU96e9d4PB4eI+xGc+mNuYvov3RbB + # D0s8ICyojeyPVLerz4wHjZu68Z5frAzhZ68YbzNs8j2fIBKKHkHyLG1iQyF+LJVj + # 2PjCP+auJsj6fQQpMGoyGtpLcSDh+ptcTngUD8JsWipzTCjmaNqdPHAOYmcgtf4b + # qocikt3WAdU^invalid DO NOT USE= + # -----END CERTIFICATE----- + + ## The private key used with the certificate_chain if the server requests TLS Client Authentication + ## i.e. Mutual TLS. + # private_key: | + # -----BEGIN RSA PRIVATE KEY----- + # MIIEpAIBAAKCAQEA8q/elLI/ijMYSJUsnXh0hYUIQYSCrtZQwjRJlmpADYgPQvn1 + # T9D9SzLLu4L2B8xTM4NOkA22Q6MVBxACzGVHUU6NUGtflCCNK9fBtCfcO3AwDtdZ + # KXou5jHasFhKUxI3lRlCb9HEy1d8srZvnVaAQRgMWL6cQJKorNHhHnh44+QERZF+ + # +5j3UAyOWGmK+Dx7glaSrgtVBQpuaIVjAh0rxdCI3huVj1bBfAkVizmxD9RgzAEW + # LQeRY6HsYSN/GChQ49q4i55lIxKVCnvOoAff03RlJhvpxLQ2mPntChZlJjdqTzt5 + # txE1/isK9ktvLsug3upgIrGYJoMPfHb41ilYfwIDAQABAoIBAQDTOdFf2JjHH1um + # aPgRAvNf9v7Nj5jytaRKs5nM6iNf46ls4QPreXnMhqSeSwj6lpNgBYxOgzC9Q+cc + # Y4ob/paJJPaIJTxmP8K/gyWcOQlNToL1l+eJ20eQoZm23NGr5fIsunSBwLEpTrdB + # ENqqtcwhW937K8Pxy/Q1nuLyU2bc6Tn/ivLozc8n27dpQWWKh8537VY7ancIaACr + # LJJLYxKqhQpjtBWAyCDvZQirnAOm9KnvIHaGXIswCZ4Xbsu0Y9NL+woARPyRVQvG + # jfxy4EmO9s1s6y7OObSukwKDSNihAKHx/VIbvVWx8g2Lv5fGOa+J2Y7o9Qurs8t5 + # BQwMTt0BAoGBAPUw5Z32EszNepAeV3E2mPFUc5CLiqAxagZJuNDO2pKtyN29ETTR + # Ma4O1cWtGb6RqcNNN/Iukfkdk27Q5nC9VJSUUPYelOLc1WYOoUf6oKRzE72dkMQV + # R4bf6TkjD+OVR17fAfkswkGahZ5XA7j48KIQ+YC4jbnYKSxZTYyKPjH/AoGBAP1i + # tqXt36OVlP+y84wWqZSjMelBIVa9phDVGJmmhz3i1cMni8eLpJzWecA3pfnG6Tm9 + # ze5M4whASleEt+M00gEvNaU9ND+z0wBfi+/DwJYIbv8PQdGrBiZFrPhTPjGQUldR + # lXccV2meeLZv7TagVxSi3DO6dSJfSEHyemd5j9mBAoGAX8Hv+0gOQZQCSOTAq8Nx + # 6dZcp9gHlNaXnMsP9eTDckOSzh636JPGvj6m+GPJSSbkURUIQ3oyokMNwFqvlNos + # fTaLhAOfjBZI9WnDTTQxpugWjphJ4HqbC67JC/qIiw5S6FdaEvGLEEoD4zoChywZ + # 9oGAn+fz2d/0/JAH/FpFPgsCgYEAp/ipZgPzziiZ9ov1wbdAQcWRj7RaWnssPFpX + # jXwEiXT3CgEMO4MJ4+KWIWOChrti3qFBg6i6lDyyS6Qyls7sLFbUdC7HlTcrOEMe + # rBoTcCI1GqZNlqWOVQ65ZIEiaI7o1vPBZo2GMQEZuq8mDKFsOMThvvTrM5cAep84 + # n6HJR4ECgYABWcbsSnr0MKvVth/inxjbKapbZnp2HUCuw87Ie5zK2Of/tbC20wwk + # yKw3vrGoE3O1t1g2m2tn8UGGASeZ842jZWjIODdSi5+icysQGuULKt86h/woz2SQ + # 27GoE2i5mh6Yez6VAYbUuns3FcwIsMyWLq043Tu2DNkx9ijOOAuQzw^invalid.. + # DO NOT USE== + # -----END RSA PRIVATE KEY----- + +## +## Identity Providers +## +# identity_providers: + + ## + ## OpenID Connect (Identity Provider) + ## + ## It's recommended you read the documentation before configuration of this section: + ## https://www.authelia.com/c/oidc + # oidc: + ## The hmac_secret is used to sign OAuth2 tokens (authorization code, access tokens and refresh tokens). + ## HMAC Secret can also be set using a secret: https://www.authelia.com/c/secrets + # hmac_secret: this_is_a_secret_abc123abc123abc + + ## The issuer_certificate_chain is an optional PEM encoded certificate chain. It's used in conjunction with the + ## issuer_private_key to sign JWT's. All certificates in the chain must be within the validity period, and every + ## certificate included must be signed by the certificate immediately after it if provided. + # issuer_certificate_chain: | + # -----BEGIN CERTIFICATE----- + # MIIC5jCCAc6gAwIBAgIRAK4Sj7FiN6PXo/urPfO4E7owDQYJKoZIhvcNAQELBQAw + # EzERMA8GA1UEChMIQXV0aGVsaWEwHhcNNzAwMTAxMDAwMDAwWhcNNzEwMTAxMDAw + # MDAwWjATMREwDwYDVQQKEwhBdXRoZWxpYTCCASIwDQYJKoZIhvcNAQEBBQADggEP + # ADCCAQoCggEBAPKv3pSyP4ozGEiVLJ14dIWFCEGEgq7WUMI0SZZqQA2ID0L59U/Q + # /Usyy7uC9gfMUzODTpANtkOjFQcQAsxlR1FOjVBrX5QgjSvXwbQn3DtwMA7XWSl6 + # LuYx2rBYSlMSN5UZQm/RxMtXfLK2b51WgEEYDFi+nECSqKzR4R54eOPkBEWRfvuY + # 91AMjlhpivg8e4JWkq4LVQUKbmiFYwIdK8XQiN4blY9WwXwJFYs5sQ/UYMwBFi0H + # kWOh7GEjfxgoUOPauIueZSMSlQp7zqAH39N0ZSYb6cS0Npj57QoWZSY3ak87ebcR + # Nf4rCvZLby7LoN7qYCKxmCaDD3x2+NYpWH8CAwEAAaM1MDMwDgYDVR0PAQH/BAQD + # AgWgMBMGA1UdJQQMMAoGCCsGAQUFBwMBMAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcN + # AQELBQADggEBAHSITqIQSNzonFl3DzxHPEzr2hp6peo45buAAtu8FZHoA+U7Icfh + # /ZXjPg7Xz+hgFwM/DTNGXkMWacQA/PaNWvZspgRJf2AXvNbMSs2UQODr7Tbv+Fb4 + # lyblmMUNYFMCFVAMU0eIxXAFq2qcwv8UMcQFT0Z/35s6PVOakYnAGGQjTfp5Ljuq + # wsdc/xWmM0cHWube6sdRRUD7SY20KU/kWzl8iFO0VbSSrDf1AlEhnLEkp1SPaxXg + # OdBnl98MeoramNiJ7NT6Jnyb3zZ578fjaWfThiBpagItI8GZmG4s4Ovh2JbheN8i + # ZsjNr9jqHTjhyLVbDRlmJzcqoj4JhbKs6/I^invalid DO NOT USE= + # -----END CERTIFICATE----- + # -----BEGIN CERTIFICATE----- + # MIIDBDCCAeygAwIBAgIRALJsPg21kA0zY4F1wUCIuoMwDQYJKoZIhvcNAQELBQAw + # EzERMA8GA1UEChMIQXV0aGVsaWEwHhcNNzAwMTAxMDAwMDAwWhcNNzEwMTAxMDAw + # MDAwWjATMREwDwYDVQQKEwhBdXRoZWxpYTCCASIwDQYJKoZIhvcNAQEBBQADggEP + # ADCCAQoCggEBAMXHBvVxUzYk0u34/DINMSF+uiOekKOAjOrC6Mi9Ww8ytPVO7t2S + # zfTvM+XnEJqkFQFgimERfG/eGhjF9XIEY6LtnXe8ATvOK4nTwdufzBaoeQu3Gd50 + # 5VXr6OHRo//ErrGvFXwP3g8xLePABsi/fkH3oDN+ztewOBMDzpd+KgTrk8ysv2ou + # kNRMKFZZqASvCgv0LD5KWvUCnL6wgf1oTXG7aztduA4oSkUP321GpOmBC5+5ElU7 + # ysoRzvD12o9QJ/IfEaulIX06w9yVMo60C/h6A3U6GdkT1SiyTIqR7v7KU/IWd/Qi + # Lfftcj91VhCmJ73Meff2e2S2PrpjdXbG5FMCAwEAAaNTMFEwDgYDVR0PAQH/BAQD + # AgKkMA8GA1UdJQQIMAYGBFUdJQAwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU + # Z7AtA3mzFc0InSBA5fiMfeLXA3owDQYJKoZIhvcNAQELBQADggEBAEE5hm1mtlk/ + # kviCoHH4evbpw7rxPxDftIQlqYTtvMM4eWY/6icFoSZ4fUHEWYyps8SsPu/8f2tf + # 71LGgZn0FdHi1QU2H8m0HHK7TFw+5Q6RLrLdSyk0PItJ71s9en7r8pX820nAFEHZ + # HkOSfJZ7B5hFgUDkMtVM6bardXAhoqcMk4YCU96e9d4PB4eI+xGc+mNuYvov3RbB + # D0s8ICyojeyPVLerz4wHjZu68Z5frAzhZ68YbzNs8j2fIBKKHkHyLG1iQyF+LJVj + # 2PjCP+auJsj6fQQpMGoyGtpLcSDh+ptcTngUD8JsWipzTCjmaNqdPHAOYmcgtf4b + # qocikt3WAdU^invalid DO NOT USE= + # -----END CERTIFICATE----- + + ## The issuer_private_key is used to sign the JWT forged by OpenID Connect. + ## Issuer Private Key can also be set using a secret: https://www.authelia.com/c/secrets + # issuer_private_key: | + # -----BEGIN RSA PRIVATE KEY----- + # MIIEpAIBAAKCAQEA8q/elLI/ijMYSJUsnXh0hYUIQYSCrtZQwjRJlmpADYgPQvn1 + # T9D9SzLLu4L2B8xTM4NOkA22Q6MVBxACzGVHUU6NUGtflCCNK9fBtCfcO3AwDtdZ + # KXou5jHasFhKUxI3lRlCb9HEy1d8srZvnVaAQRgMWL6cQJKorNHhHnh44+QERZF+ + # +5j3UAyOWGmK+Dx7glaSrgtVBQpuaIVjAh0rxdCI3huVj1bBfAkVizmxD9RgzAEW + # LQeRY6HsYSN/GChQ49q4i55lIxKVCnvOoAff03RlJhvpxLQ2mPntChZlJjdqTzt5 + # txE1/isK9ktvLsug3upgIrGYJoMPfHb41ilYfwIDAQABAoIBAQDTOdFf2JjHH1um + # aPgRAvNf9v7Nj5jytaRKs5nM6iNf46ls4QPreXnMhqSeSwj6lpNgBYxOgzC9Q+cc + # Y4ob/paJJPaIJTxmP8K/gyWcOQlNToL1l+eJ20eQoZm23NGr5fIsunSBwLEpTrdB + # ENqqtcwhW937K8Pxy/Q1nuLyU2bc6Tn/ivLozc8n27dpQWWKh8537VY7ancIaACr + # LJJLYxKqhQpjtBWAyCDvZQirnAOm9KnvIHaGXIswCZ4Xbsu0Y9NL+woARPyRVQvG + # jfxy4EmO9s1s6y7OObSukwKDSNihAKHx/VIbvVWx8g2Lv5fGOa+J2Y7o9Qurs8t5 + # BQwMTt0BAoGBAPUw5Z32EszNepAeV3E2mPFUc5CLiqAxagZJuNDO2pKtyN29ETTR + # Ma4O1cWtGb6RqcNNN/Iukfkdk27Q5nC9VJSUUPYelOLc1WYOoUf6oKRzE72dkMQV + # R4bf6TkjD+OVR17fAfkswkGahZ5XA7j48KIQ+YC4jbnYKSxZTYyKPjH/AoGBAP1i + # tqXt36OVlP+y84wWqZSjMelBIVa9phDVGJmmhz3i1cMni8eLpJzWecA3pfnG6Tm9 + # ze5M4whASleEt+M00gEvNaU9ND+z0wBfi+/DwJYIbv8PQdGrBiZFrPhTPjGQUldR + # lXccV2meeLZv7TagVxSi3DO6dSJfSEHyemd5j9mBAoGAX8Hv+0gOQZQCSOTAq8Nx + # 6dZcp9gHlNaXnMsP9eTDckOSzh636JPGvj6m+GPJSSbkURUIQ3oyokMNwFqvlNos + # fTaLhAOfjBZI9WnDTTQxpugWjphJ4HqbC67JC/qIiw5S6FdaEvGLEEoD4zoChywZ + # 9oGAn+fz2d/0/JAH/FpFPgsCgYEAp/ipZgPzziiZ9ov1wbdAQcWRj7RaWnssPFpX + # jXwEiXT3CgEMO4MJ4+KWIWOChrti3qFBg6i6lDyyS6Qyls7sLFbUdC7HlTcrOEMe + # rBoTcCI1GqZNlqWOVQ65ZIEiaI7o1vPBZo2GMQEZuq8mDKFsOMThvvTrM5cAep84 + # n6HJR4ECgYABWcbsSnr0MKvVth/inxjbKapbZnp2HUCuw87Ie5zK2Of/tbC20wwk + # yKw3vrGoE3O1t1g2m2tn8UGGASeZ842jZWjIODdSi5+icysQGuULKt86h/woz2SQ + # 27GoE2i5mh6Yez6VAYbUuns3FcwIsMyWLq043Tu2DNkx9ijOOAuQzw^invalid.. + # DO NOT USE== + # -----END RSA PRIVATE KEY----- + + ## The lifespans configure the expiration for these token types. + # access_token_lifespan: 1h + # authorize_code_lifespan: 1m + # id_token_lifespan: 1h + # refresh_token_lifespan: 90m + + ## Enables additional debug messages. + # enable_client_debug_messages: false + + ## SECURITY NOTICE: It's not recommended changing this option and values below 8 are strongly discouraged. + # minimum_parameter_entropy: 8 + + ## SECURITY NOTICE: It's not recommended changing this option, and highly discouraged to have it set to 'never' + ## for security reasons. + # enforce_pkce: public_clients_only + + ## Cross-Origin Resource Sharing (CORS) settings. + # cors: + ## List of endpoints in addition to the metadata endpoints to permit cross-origin requests on. + # endpoints: + # - authorization + # - token + # - revocation + # - introspection + # - userinfo + + ## List of allowed origins. + ## Any origin with https is permitted unless this option is configured or the + ## allowed_origins_from_client_redirect_uris option is enabled. + # allowed_origins: + # - https://example.com + + ## Automatically adds the origin portion of all redirect URI's on all clients to the list of allowed_origins, + ## provided they have the scheme http or https and do not have the hostname of localhost. + # allowed_origins_from_client_redirect_uris: false + + ## Clients is a list of known clients and their configuration. + # clients: + # - + ## The ID is the OpenID Connect ClientID which is used to link an application to a configuration. + # id: myapp + + ## The description to show to users when they end up on the consent screen. Defaults to the ID above. + # description: My Application + + ## The client secret is a shared secret between Authelia and the consumer of this client. + # secret: this_is_a_secret + + ## Sector Identifiers are occasionally used to generate pairwise subject identifiers. In most cases this is not + ## necessary. Read the documentation for more information. + ## The subject identifier must be the host component of a URL, which is a domain name with an optional port. + # sector_identifier: example.com + + ## Sets the client to public. This should typically not be set, please see the documentation for usage. + # public: false + + ## The policy to require for this client; one_factor or two_factor. + # authorization_policy: two_factor + + ## The consent mode controls how consent is obtained. + # consent_mode: auto + + ## This value controls the duration a consent on this client remains remembered when the consent mode is + ## configured as 'auto' or 'pre-configured'. + # pre_configured_consent_duration: 1w + + ## Audience this client is allowed to request. + # audience: [] + + ## Scopes this client is allowed to request. + # scopes: + # - openid + # - groups + # - email + # - profile + + ## Redirect URI's specifies a list of valid case-sensitive callbacks for this client. + # redirect_uris: + # - https://oidc.example.com:8080/oauth2/callback + + ## Grant Types configures which grants this client can obtain. + ## It's not recommended to define this unless you know what you're doing. + # grant_types: + # - refresh_token + # - authorization_code + + ## Response Types configures which responses this client can be sent. + ## It's not recommended to define this unless you know what you're doing. + # response_types: + # - code + + ## Response Modes configures which response modes this client supports. + # response_modes: + # - form_post + # - query + # - fragment + + ## The algorithm used to sign userinfo endpoint responses for this client, either none or RS256. + # userinfo_signing_algorithm: none +... diff --git a/.vitepress/dist/configuration/auth-config.html b/.vitepress/dist/configuration/auth-config.html new file mode 100644 index 0000000..a4f80ed --- /dev/null +++ b/.vitepress/dist/configuration/auth-config.html @@ -0,0 +1,1350 @@ + + + + + + Authelia Configuration | DP-Salad + + + + + + + + + + + + + + + +
Skip to content

Authelia Configuration ​

Authelia, is our version of an SSO , as once you've logged into Authelia, you have access to all protected links. Attached below is the example configuration.yml file for Authelia. You can copy/paste this configuration, and then change all values surrounded in square brackets. Make sure to set passwords/tokens where REDACTED occurs. I recommend strings that are at least a length of 26 characters. This example configuration is perfect for 2FA with Authy out of the box, if you'd like to enable Duo , please see Authy/Duo Configuration for more details.

yaml
# yamllint disable rule:comments-indentation
+---
+###################################################################
+############
+# Authelia Configuration #
+###################################################################
+############
+## Note: the container by default expects to find this file at /config/configuration.yml.
+## Certificates directory specifies where Authelia will load trusted certificates (public portion) from in addition to
+## the system certificates store.
+## They should be in base64 format, and have one of the following extensions: *.cer, *.crt, *.pem.
+# certificates_directory: /config/certificates/
+## The theme to display: light, dark, grey, auto.
+theme: dark
+## The secret used to generate JWT tokens when validating user identity by email confirmation. JWT Secret can
+also be
+## set using a secret: https://www.authelia.com/c/secrets
+jwt_secret: REDACTED
+## Default redirection URL
+##
+## If user tries to authenticate without any referer, Authelia does not know where to redirect the user to at the
+end
+## of the authentication process. This parameter allows you to specify the default redirection URL Authelia will
+use
+## in such a case.
+##
+## Note: this parameter is optional. If not provided, user won't be redirected upon successful authentication.
+default_redirection_url: https://[domain.tld]/
+## Set the default 2FA method for new users and for when a user has a preferred method configured that has
+been
+## disabled. This setting must be a method that is enabled.
+## Options are totp, webauthn, mobile_push.
+default_2fa_method: "totp"
+##
+## Server Configuration
+##
+server:
+ ## The address to listen on.
+ host: 0.0.0.0
+ ## The port to listen on.
+ port: 9091
+ ## Set the single level path Authelia listens on.
+ ## Must be alphanumeric chars and should not contain any slashes.
+ path: "authelia"
+ ## Set the path on disk to Authelia assets.
+ ## Useful to allow overriding of specific static assets.
+ # asset_path: /config/assets/
+ ## Enables the pprof endpoint.
+ enable_pprof: false
+ ## Enables the expvars endpoint.
+ enable_expvars: false
+ ## Disables writing the health check vars to /app/.healthcheck.env which makes healthcheck.sh return exit
+code 0.
+ ## This is disabled by default if either /app/.healthcheck.env or /app/healthcheck.sh do not exist.
+ disable_healthcheck: false
+ ## Authelia by default doesn't accept TLS communication on the server port. This section overrides this
+behaviour.
+ tls:
+ ## The path to the DER base64/PEM format private key.
+ key: ""
+ ## The path to the DER base64/PEM format public certificate.
+ certificate: ""
+ ## The list of certificates for client authentication.
+ client_certificates: []
+ ## Server headers configuration/customization.
+ headers:
+ ## The CSP Template. Read the docs.
+ csp_template: ""
+ ## Server Buffers configuration.
+ # buffers:
+ ## Buffers usually should be configured to be the same value.
+ ## Explanation at https://www.authelia.com/c/server#buffer-sizes
+ ## Read buffer size adjusts the server's max incoming request size in bytes.
+ ## Write buffer size does the same for outgoing responses.
+ ## Read buffer.
+ # read: 4096
+ ## Write buffer.
+ # write: 4096
+ ## Server Timeouts configuration.
+ # timeouts:
+ ## Read timeout.
+ # read: 6s
+ ## Write timeout.
+ # write: 6s
+ ## Idle timeout.
+ # idle: 30s
+##
+## Log Configuration
+##
+log:
+ ## Level of verbosity for logs: info, debug, trace.
+ level: debug
+ ## Format the logs are written as: json, text.
+ # format: json
+ ## File path where the logs will be written. If not set logs are written to stdout.
+ # file_path: /config/authelia.log
+ ## Whether to also log to stdout when a log_file_path is defined.
+ # keep_stdout: false
+##
+## Telemetry Configuration
+##
+telemetry:
+ ##
+ ## Metrics Configuration
+ ##
+ metrics:
+ ## Enable Metrics.
+ enabled: false
+ ## The address to listen on for metrics. This should be on a different port to the main server.port value.
+ address: tcp://0.0.0.0:9959
+ ## Metrics Server Buffers configuration.
+ # buffers:
+ ## Read buffer.
+ # read: 4096
+ ## Write buffer.
+ # write: 4096
+ ## Metrics Server Timeouts configuration.
+ # timeouts:
+ ## Read timeout.
+ # read: 6s
+ ## Write timeout.
+ # write: 6s
+ ## Idle timeout.
+ # idle: 30s
+##
+## TOTP Configuration
+##
+## Parameters used for TOTP generation.
+totp:
+ ## Disable TOTP.
+ disable: false
+ ## The issuer name displayed in the Authenticator application of your choice.
+ issuer: [domain.tld]
+ ## The TOTP algorithm to use.
+ ## It is CRITICAL you read the documentation before changing this option:
+ ## https://www.authelia.com/c/totp#algorithm
+ algorithm: sha1
+ ## The number of digits a user has to input. Must either be 6 or 8.
+ ## Changing this option only affects newly generated TOTP configurations.
+ ## It is CRITICAL you read the documentation before changing this option:
+ ## https://www.authelia.com/c/totp#digits
+ digits: 8
+ ## The period in seconds a one-time password is valid for.
+ ## Changing this option only affects newly generated TOTP configurations.
+ period: 30
+ ## The skew controls number of one-time passwords either side of the current one that are valid.
+ ## Warning: before changing skew read the docs link below.
+ skew: 1
+ ## See: https://www.authelia.com/c/totp#input-validation to read
+ ## the documentation.
+ ## The size of the generated shared secrets. Default is 32 and is sufficient in most use cases, minimum is 20.
+ secret_size: 32
+##
+## WebAuthn Configuration
+##
+## Parameters used for WebAuthn.
+webauthn:
+ ## Disable Webauthn.
+ disable: false
+ ## Adjust the interaction timeout for Webauthn dialogues.
+ timeout: 60s
+ ## The display name the browser should show the user for when using Webauthn to login/register.
+ display_name: Authelia
+ ## Conveyance preference controls if we collect the attestation statement including the AAGUID from the
+device.
+ ## Options are none, indirect, direct.
+ attestation_conveyance_preference: indirect
+ ## User verification controls if the user must make a gesture or action to confirm they are present.
+ ## Options are required, preferred, discouraged.
+ user_verification: preferred
+##
+## Duo Push API Configuration
+##
+## Parameters used to contact the Duo API. Those are generated when you protect an application of type
+## "Partner Auth API" in the management panel.
+# duo_api:
+ # disable: false
+ # hostname: api-123456789.example.com
+ # integration_key: ABCDEF
+ ## Secret can also be set using a secret: https://www.authelia.com/c/secrets
+ # secret_key: 1234567890abcdefghifjkl
+ # enable_self_enrollment: false
+##
+## NTP Configuration
+##
+## This is used to validate the servers time is accurate enough to validate TOTP.
+ntp:
+ ## NTP server address.
+ address: "time.cloudflare.com:123"
+ ## NTP version.
+ version: 4
+ ## Maximum allowed time offset between the host and the NTP server.
+ max_desync: 3s
+ ## Disables the NTP check on startup entirely. This means Authelia will not contact a remote service at all if
+you
+ ## set this to true, and can operate in a truly offline mode.
+ disable_startup_check: false
+ ## The default of false will prevent startup only if we can contact the NTP server and the time is out of sync
+with
+ ## the NTP server more than the configured max_desync. If you set this to true, an error will be logged but
+startup
+ ## will continue regardless of results.
+ disable_failure: false
+##
+## Authentication Backend Provider Configuration
+##
+## Used for verifying user passwords and retrieve information such as email address and groups users belong
+to.
+##
+## The available providers are: `file`, `ldap`. You must use only one of these providers.
+authentication_backend:
+ ## Password Reset Options.
+ password_reset:
+ ## Disable both the HTML element and the API for reset password functionality.
+ disable: false
+ ## External reset password url that redirects the user to an external reset portal. This disables the internal
+reset
+ ## functionality.
+ custom_url: ""
+ ## The amount of time to wait before we refresh data from the authentication backend. Uses duration
+notation.
+ ## To disable this feature set it to 'disable', this will slightly reduce security because for Authelia, users will
+ ## always belong to groups they belonged to at the time of login even if they have been removed from them
+in LDAP.
+ ## To force update on every request you can set this to '0' or 'always', this will increase processor demand.
+ ## See the below documentation for more information.
+ ## Duration Notation docs: https://www.authelia.com/c/common#duration-notation-format
+ ## Refresh Interval docs: https://www.authelia.com/c/1fa#refresh-interval
+ refresh_interval: 5m
+ ##
+ ## LDAP (Authentication Provider)
+ ##
+ ## This is the recommended Authentication Provider in production
+ ## because it allows Authelia to offload the stateful operations
+ ## onto the LDAP service.
+ ldap:
+ ## The LDAP implementation, this affects elements like the attribute utilised for resetting a password.
+ ## Acceptable options are as follows:
+ ## - 'activedirectory' - For Microsoft Active Directory.
+ ## - 'custom' - For custom specifications of attributes and filters.
+ ## This currently defaults to 'custom' to maintain existing behaviour.
+ ##
+ ## Depending on the option here certain other values in this section have a default value, notably all of the
+ ## attribute mappings have a default value that this config overrides, you can read more about these default
+values
+ ## at https://www.authelia.com/c/ldap#defaults
+ implementation: custom
+ ## The url to the ldap server. Format: <scheme>://<address>[:<port>].
+ ## Scheme can be ldap or ldaps in the format (port optional).
+ url: ldap://lldap:3890
+ ## The dial timeout for LDAP.
+ timeout: 5s
+ ## Use StartTLS with the LDAP connection.
+ start_tls: false
+ # tls:
+ ## The server subject name to check the servers certificate against during the validation process.
+ ## This option is not required if the certificate has a SAN which matches the host portion of the url option.
+ # server_name: ldap.example.com
+ ## Skip verifying the server certificate entirely. In preference to setting this we strongly recommend you
+add the
+ ## certificate or the certificate of the authority signing the certificate to the certificates directory which is
+ ## defined by the `certificates_directory` option at the top of the configuration.
+ ## It's important to note the public key should be added to the directory, not the private key.
+ ## This option is strongly discouraged but may be useful in some self-signed situations where validation is
+not
+ ## important to the administrator.
+ # skip_verify: false
+ ## Minimum TLS version for the connection.
+ # minimum_version: TLS1.2
+ ## Maximum TLS version for the connection.
+ # maximum_version: TLS1.3
+ ## The certificate chain used with the private_key if the server requests TLS Client Authentication
+ ## i.e. Mutual TLS.
+ # certificate_chain: |
+ # -----BEGIN CERTIFICATE-----
+ # MIIC5jCCAc6gAwIBAgIRAK4Sj7FiN6PXo/urPfO4E7owDQYJKoZIhvcNAQELBQAw
+ # EzERMA8GA1UEChMIQXV0aGVsaWEwHhcNNzAwMTAxMDAwMDAwWhcNNzEwMTAxMDAw
+ # MDAwWjATMREwDwYDVQQKEwhBdXRoZWxpYTCCASIwDQYJKoZIhvcNAQEBBQADggEP
+ # ADCCAQoCggEBAPKv3pSyP4ozGEiVLJ14dIWFCEGEgq7WUMI0SZZqQA2ID0L59U/Q
+ # /Usyy7uC9gfMUzODTpANtkOjFQcQAsxlR1FOjVBrX5QgjSvXwbQn3DtwMA7XWSl6
+ # LuYx2rBYSlMSN5UZQm/RxMtXfLK2b51WgEEYDFi+nECSqKzR4R54eOPkBEWRfvuY
+ # 91AMjlhpivg8e4JWkq4LVQUKbmiFYwIdK8XQiN4blY9WwXwJFYs5sQ/UYMwBFi0H
+ # kWOh7GEjfxgoUOPauIueZSMSlQp7zqAH39N0ZSYb6cS0Npj57QoWZSY3ak87ebcR
+ # Nf4rCvZLby7LoN7qYCKxmCaDD3x2+NYpWH8CAwEAAaM1MDMwDgYDVR0PAQH/BAQD
+ # AgWgMBMGA1UdJQQMMAoGCCsGAQUFBwMBMAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcN
+ # AQELBQADggEBAHSITqIQSNzonFl3DzxHPEzr2hp6peo45buAAtu8FZHoA+U7Icfh
+ # /ZXjPg7Xz+hgFwM/DTNGXkMWacQA/PaNWvZspgRJf2AXvNbMSs2UQODr7Tbv+Fb4
+ # lyblmMUNYFMCFVAMU0eIxXAFq2qcwv8UMcQFT0Z/35s6PVOakYnAGGQjTfp5Ljuq
+ # wsdc/xWmM0cHWube6sdRRUD7SY20KU/kWzl8iFO0VbSSrDf1AlEhnLEkp1SPaxXg
+ # OdBnl98MeoramNiJ7NT6Jnyb3zZ578fjaWfThiBpagItI8GZmG4s4Ovh2JbheN8i
+ # ZsjNr9jqHTjhyLVbDRlmJzcqoj4JhbKs6/I^invalid DO NOT USE=
+ # -----END CERTIFICATE-----
+ # -----BEGIN CERTIFICATE-----
+ # MIIDBDCCAeygAwIBAgIRALJsPg21kA0zY4F1wUCIuoMwDQYJKoZIhvcNAQELBQAw
+ # EzERMA8GA1UEChMIQXV0aGVsaWEwHhcNNzAwMTAxMDAwMDAwWhcNNzEwMTAxMDAw
+ # MDAwWjATMREwDwYDVQQKEwhBdXRoZWxpYTCCASIwDQYJKoZIhvcNAQEBBQADggEP
+ # ADCCAQoCggEBAMXHBvVxUzYk0u34/DINMSF+uiOekKOAjOrC6Mi9Ww8ytPVO7t2S
+ # zfTvM+XnEJqkFQFgimERfG/eGhjF9XIEY6LtnXe8ATvOK4nTwdufzBaoeQu3Gd50
+ # 5VXr6OHRo//ErrGvFXwP3g8xLePABsi/fkH3oDN+ztewOBMDzpd+KgTrk8ysv2ou
+ # kNRMKFZZqASvCgv0LD5KWvUCnL6wgf1oTXG7aztduA4oSkUP321GpOmBC5+5ElU7
+ # ysoRzvD12o9QJ/IfEaulIX06w9yVMo60C/h6A3U6GdkT1SiyTIqR7v7KU/IWd/Qi
+ # Lfftcj91VhCmJ73Meff2e2S2PrpjdXbG5FMCAwEAAaNTMFEwDgYDVR0PAQH/BAQD
+ # AgKkMA8GA1UdJQQIMAYGBFUdJQAwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU
+ # Z7AtA3mzFc0InSBA5fiMfeLXA3owDQYJKoZIhvcNAQELBQADggEBAEE5hm1mtlk/
+ # kviCoHH4evbpw7rxPxDftIQlqYTtvMM4eWY/6icFoSZ4fUHEWYyps8SsPu/8f2tf
+ # 71LGgZn0FdHi1QU2H8m0HHK7TFw+5Q6RLrLdSyk0PItJ71s9en7r8pX820nAFEHZ
+ # HkOSfJZ7B5hFgUDkMtVM6bardXAhoqcMk4YCU96e9d4PB4eI+xGc+mNuYvov3RbB
+ # D0s8ICyojeyPVLerz4wHjZu68Z5frAzhZ68YbzNs8j2fIBKKHkHyLG1iQyF+LJVj
+ # 2PjCP+auJsj6fQQpMGoyGtpLcSDh+ptcTngUD8JsWipzTCjmaNqdPHAOYmcgtf4b
+ # qocikt3WAdU^invalid DO NOT USE=
+ # -----END CERTIFICATE-----
+ ## The private key used with the certificate_chain if the server requests TLS Client Authentication
+ ## i.e. Mutual TLS.
+ # private_key: |
+ # -----BEGIN RSA PRIVATE KEY-----
+ # MIIEpAIBAAKCAQEA8q/elLI/ijMYSJUsnXh0hYUIQYSCrtZQwjRJlmpADYgPQvn1
+ # T9D9SzLLu4L2B8xTM4NOkA22Q6MVBxACzGVHUU6NUGtflCCNK9fBtCfcO3AwDtdZ
+ # KXou5jHasFhKUxI3lRlCb9HEy1d8srZvnVaAQRgMWL6cQJKorNHhHnh44+QERZF+
+ # +5j3UAyOWGmK+Dx7glaSrgtVBQpuaIVjAh0rxdCI3huVj1bBfAkVizmxD9RgzAEW
+ # LQeRY6HsYSN/GChQ49q4i55lIxKVCnvOoAff03RlJhvpxLQ2mPntChZlJjdqTzt5
+ # txE1/isK9ktvLsug3upgIrGYJoMPfHb41ilYfwIDAQABAoIBAQDTOdFf2JjHH1um
+ # aPgRAvNf9v7Nj5jytaRKs5nM6iNf46ls4QPreXnMhqSeSwj6lpNgBYxOgzC9Q+cc
+ # Y4ob/paJJPaIJTxmP8K/gyWcOQlNToL1l+eJ20eQoZm23NGr5fIsunSBwLEpTrdB
+ # ENqqtcwhW937K8Pxy/Q1nuLyU2bc6Tn/ivLozc8n27dpQWWKh8537VY7ancIaACr
+ # LJJLYxKqhQpjtBWAyCDvZQirnAOm9KnvIHaGXIswCZ4Xbsu0Y9NL+woARPyRVQvG
+ # jfxy4EmO9s1s6y7OObSukwKDSNihAKHx/VIbvVWx8g2Lv5fGOa+J2Y7o9Qurs8t5
+ # BQwMTt0BAoGBAPUw5Z32EszNepAeV3E2mPFUc5CLiqAxagZJuNDO2pKtyN29ETTR
+ # Ma4O1cWtGb6RqcNNN/Iukfkdk27Q5nC9VJSUUPYelOLc1WYOoUf6oKRzE72dkMQV
+ # R4bf6TkjD+OVR17fAfkswkGahZ5XA7j48KIQ+YC4jbnYKSxZTYyKPjH/AoGBAP1i
+ # tqXt36OVlP+y84wWqZSjMelBIVa9phDVGJmmhz3i1cMni8eLpJzWecA3pfnG6Tm9
+ # ze5M4whASleEt+M00gEvNaU9ND+z0wBfi+/DwJYIbv8PQdGrBiZFrPhTPjGQUldR
+ # lXccV2meeLZv7TagVxSi3DO6dSJfSEHyemd5j9mBAoGAX8Hv+0gOQZQCSOTAq8Nx
+ # 6dZcp9gHlNaXnMsP9eTDckOSzh636JPGvj6m+GPJSSbkURUIQ3oyokMNwFqvlNos
+ # fTaLhAOfjBZI9WnDTTQxpugWjphJ4HqbC67JC/qIiw5S6FdaEvGLEEoD4zoChywZ
+ # 9oGAn+fz2d/0/JAH/FpFPgsCgYEAp/ipZgPzziiZ9ov1wbdAQcWRj7RaWnssPFpX
+ # jXwEiXT3CgEMO4MJ4+KWIWOChrti3qFBg6i6lDyyS6Qyls7sLFbUdC7HlTcrOEMe
+ # rBoTcCI1GqZNlqWOVQ65ZIEiaI7o1vPBZo2GMQEZuq8mDKFsOMThvvTrM5cAep84
+ # n6HJR4ECgYABWcbsSnr0MKvVth/inxjbKapbZnp2HUCuw87Ie5zK2Of/tbC20wwk
+ # yKw3vrGoE3O1t1g2m2tn8UGGASeZ842jZWjIODdSi5+icysQGuULKt86h/woz2SQ
+ # 27GoE2i5mh6Yez6VAYbUuns3FcwIsMyWLq043Tu2DNkx9ijOOAuQzw^invalid..
+ # DO NOT USE==
+ # -----END RSA PRIVATE KEY-----
+ ## The distinguished name of the container searched for objects in the directory information tree.
+ ## See also: additional_users_dn, additional_groups_dn.
+ base_dn: dc=[domain],dc=[tld]
+ ## The attribute holding the username of the user. This attribute is used to populate the username in the
+session
+ ## information. For your information, Microsoft Active Directory usually uses 'sAMAccountName' and
+OpenLDAP usually
+ ## uses 'uid'. Beware that this attribute holds the unique identifiers for the users binding the user and the
+ ## configuration stored in database. Therefore only single value attributes are allowed and the value must
+never be
+ ## changed once attributed to a user otherwise it would break the configuration for that user. Technically,
+ ## non-unique attributes like 'mail' can also be used but we don't recommend using them, we instead advise
+to use
+ ## a filter to perform alternative lookups and the attributes mentioned above (sAMAccountName and uid) to
+ ## follow https://www.ietf.org/rfc/rfc2307.txt.
+ username_attribute: uid
+ ## The additional_users_dn is prefixed to base_dn and delimited by a comma when searching for users.
+ ## i.e. with this set to OU=Users and base_dn set to DC=a,DC=com; OU=Users,DC=a,DC=com is searched
+for users.
+ additional_users_dn: ou=people
+ ## The users filter used in search queries to find the user profile based on input filled in login form.
+ ## Various placeholders are available in the user filter which you can read about in the documentation which
+can
+ ## be found at: https://www.authelia.com/c/ldap#users-filter-replacements
+ ##
+ ## Recommended settings are as follows:
+ ## - Microsoft Active Directory:
+(&({username_attribute}={input})(objectCategory=person)(objectClass=user))
+ ## - OpenLDAP:
+ ## - (&({username_attribute}={input})(objectClass=person))
+ ## - (&({username_attribute}={input})(objectClass=inetOrgPerson))
+ ##
+ ## To allow sign in both with username and email, one can use a filter like
+ ## (&(|({username_attribute}={input})({mail_attribute}={input}))(objectClass=person))
+ users_filter: (&({username_attribute}={input})(objectClass=person))
+ ## The additional_groups_dn is prefixed to base_dn and delimited by a comma when searching for groups.
+ ## i.e. with this set to OU=Groups and base_dn set to DC=a,DC=com; OU=Groups,DC=a,DC=com is
+searched for groups.
+ additional_groups_dn: ou=groups
+ ## The groups filter used in search queries to find the groups based on relevant authenticated user.
+ ## Various placeholders are available in the groups filter which you can read about in the documentation
+which can
+ ## be found at: https://www.authelia.com/c/ldap#groups-filter-replacements
+ ##
+ ## If your groups use the `groupOfUniqueNames` structure use this instead:
+ ## (&(uniqueMember={dn})(objectClass=groupOfUniqueNames))
+ groups_filter: (&(member={dn})(objectClass=groupOfUniqueNames))
+ ## The attribute holding the name of the group.
+ group_name_attribute: cn
+ ## The attribute holding the mail address of the user. If multiple email addresses are defined for a user, only
+the
+ ## first one returned by the LDAP server is used.
+ mail_attribute: mail
+ ## The attribute holding the display name of the user. This will be used to greet an authenticated user.
+ display_name_attribute: displayName
+ ## Follow referrals returned by the server.
+ ## This is especially useful for environments where read-only servers exist. Only implemented for write
+operations.
+ # permit_referrals: false
+ ## The username and password of the admin user.
+ user: cn=admin,ou=people,dc=[domain],dc=[tld]
+ ## Password can also be set using a secret: https://www.authelia.com/c/secrets
+ password: "REDACTED"
+ ##
+ ## File (Authentication Provider)
+ ##
+ ## With this backend, the users database is stored in a file which is updated when users reset their passwords.
+ ## Therefore, this backend is meant to be used in a dev environment and not in production since it prevents
+Authelia
+ ## to be scaled to more than one instance. The options under 'password' have sane defaults, and as it has
+security
+ ## implications it is highly recommended you leave the default values. Before considering changing these
+settings
+ ## please read the docs page below:
+ ## https://www.authelia.com/r/passwords#tuning
+ ##
+ ## Important: Kubernetes (or HA) users must read https://www.authelia.com/t/statelessness
+ ##
+ # file:
+ # path: /config/users_database.yml
+ # watch: false
+ # search:
+ # email: false
+ # case_insensitive: false
+ # password:
+ # algorithm: argon2
+ # argon2:
+ # variant: argon2id
+ # iterations: 3
+ # memory: 65536
+ # parallelism: 4
+ # key_length: 32
+ # salt_length: 16
+ # scrypt:
+ # iterations: 16
+ # block_size: 8
+ # parallelism: 1
+ # key_length: 32
+ # salt_length: 16
+ # pbkdf2:
+ # variant: sha512
+ # iterations: 310000
+ # salt_length: 16
+ # sha2crypt:
+ # variant: sha512
+ # iterations: 50000
+ # salt_length: 16
+ # bcrypt:
+ # variant: standard
+ # cost: 12
+##
+## Password Policy Configuration.
+##
+password_policy:
+ ## The standard policy allows you to tune individual settings manually.
+ standard:
+ enabled: true
+ ## Require a minimum length for passwords.
+ min_length: 8
+ ## Require a maximum length for passwords.
+ max_length: 0
+ ## Require uppercase characters.
+ require_uppercase: true
+ ## Require lowercase characters.
+ require_lowercase: true
+ ## Require numeric characters.
+ require_number: true
+ ## Require special characters.
+ require_special: true
+ ## zxcvbn is a well known and used password strength algorithm. It does not have tunable settings.
+ zxcvbn:
+ enabled: false
+ ## Configures the minimum score allowed.
+ min_score: 3
+##
+## Access Control Configuration
+##
+## Access control is a list of rules defining the authorizations applied for one resource to users or group of
+users.
+##
+## If 'access_control' is not defined, ACL rules are disabled and the 'bypass' rule is applied, i.e., access is
+allowed
+## to anyone. Otherwise restrictions follow the rules defined.
+##
+## Note: One can use the wildcard * to match any subdomain.
+## It must stand at the beginning of the pattern. (example: *.example.com)
+##
+## Note: You must put patterns containing wildcards between simple quotes for the YAML to be syntactically
+correct.
+##
+## Definition: A 'rule' is an object with the following keys: 'domain', 'subject', 'policy' and 'resources'.
+##
+## - 'domain' defines which domain or set of domains the rule applies to.
+##
+## - 'subject' defines the subject to apply authorizations to. This parameter is optional and matching any user if
+not
+## provided. If provided, the parameter represents either a user or a group. It should be of the form
+## 'user:<username>' or 'group:<groupname>'.
+##
+## - 'policy' is the policy to apply to resources. It must be either 'bypass', 'one_factor', 'two_factor' or 'deny'.
+##
+## - 'resources' is a list of regular expressions that matches a set of resources to apply the policy to. This
+parameter
+## is optional and matches any resource if not provided.
+##
+## Note: the order of the rules is important. The first policy matching (domain, resource, subject) applies.
+access_control:
+ ## Default policy can either be 'bypass', 'one_factor', 'two_factor' or 'deny'. It is the policy applied to any
+ ## resource if there is no policy to be applied to the user.
+ default_policy: deny
+ # networks:
+ # - name: internal
+ # networks:
+ # - 10.10.0.0/16
+ # - 192.168.2.0/24
+ # - name: VPN
+ # networks: 10.9.0.0/16
+ rules:
+ ## Rules applied to everyone
+ ## This below policy allows for auth to be accessed at all times,
+ ## useful when trying to login without the main page available.
+ - domain:
+ - 'auth.[domain.tld]'
+ policy: bypass
+ ## This below policy example will exclude a user from using 2FA,
+ ## useful if the user has no way of configuring 2FA.
+ - domain:
+ - '[domain.tld]'
+ - '*.[domain.tld]'
+ subject:
+ - "user:[USERNAME/UID]"
+ policy: one_factor
+ ## This below policy example will exclude all users of the people
+ ## group from using 2FA, NOT RECOMMENDED
+ - domain:
+ - '[domain.tld]'
+ - '*.[domain.tld]'
+ subject:
+ - "group:people"
+ policy: one_factor
+ ## This below policy will require all users of the LLDAP_Admin group
+ ## in LLDAP to use 2FA BY DEFAULT, this is the strongest policy available
+ - domain:
+ - '[domain.tld]'
+ - '*.[domain.tld]'
+ subject:
+ - "group:lldap_admin"
+ policy: two_factor
+ ## Domain Regex examples. Generally we recommend just using a standard domain.
+ # - domain_regex: '^(?P<User>\w+)\.example\.com$'
+ # policy: one_factor
+ # - domain_regex: '^(?P<Group>\w+)\.example\.com$'
+ # policy: one_factor
+ # - domain_regex:
+ # - '^appgroup-.*\.example\.com$'
+ # - '^appgroup2-.*\.example\.com$'
+ # policy: one_factor
+ # - domain_regex: '^.*\.example\.com$'
+ # policy: two_factor
+ # - domain: 'secure.example.com'
+ # policy: one_factor
+ ## Network based rule, if not provided any network matches.
+ # networks:
+ # - internal
+ # - VPN
+ # - 192.168.1.0/24
+ # - 10.0.0.1
+ # - domain:
+ # - 'secure.example.com'
+ # - 'private.example.com'
+ # policy: two_factor
+ # - domain: 'singlefactor.example.com'
+ # policy: one_factor
+ ## Rules applied to 'admins' group
+ # - domain: 'mx2.mail.example.com'
+ # subject: 'group:admins'
+ # policy: deny
+ # - domain: '*.example.com'
+ # subject:
+ # - 'group:admins'
+ # - 'group:moderators'
+ # policy: two_factor
+ ## Rules applied to 'dev' group
+ # - domain: 'dev.example.com'
+ # resources:
+ # - '^/groups/dev/.*$'
+ # subject: 'group:dev'
+ # policy: two_factor
+ ## Rules applied to user 'john'
+ # - domain: 'dev.example.com'
+ # resources:
+ # - '^/users/john/.*$'
+ # subject: 'user:john'
+ # policy: two_factor
+ ## Rules applied to user 'harry'
+ # - domain: 'dev.example.com'
+ # resources:
+ # - '^/users/harry/.*$'
+ # subject: 'user:harry'
+ # policy: two_factor
+ ## Rules applied to user 'bob'
+ # - domain: '*.mail.example.com'
+ # subject: 'user:bob'
+ # policy: two_factor
+ # - domain: 'dev.example.com'
+ # resources:
+ # - '^/users/bob/.*$'
+ # subject: 'user:bob'
+ # policy: two_factor
+##
+## Session Provider Configuration
+##
+## The session cookies identify the user once logged in.
+## The available providers are: `memory`, `redis`. Memory is the provider unless redis is defined.
+session:
+ ## The name of the session cookie.
+ name: authelia_session
+ ## The domain to protect.
+ ## Note: the authenticator must also be in that domain.
+ ## If empty, the cookie is restricted to the subdomain of the issuer.
+ domain: [domain.tld]
+ ## Sets the Cookie SameSite value. Possible options are none, lax, or strict.
+ ## Please read https://www.authelia.com/c/session#same_site
+ same_site: lax
+ ## The secret to encrypt the session data. This is only used with Redis / Redis Sentinel.
+ ## Secret can also be set using a secret: https://www.authelia.com/c/secrets
+ secret: REDACTED
+ ## The value for expiration, inactivity, and remember_me_duration are in seconds or the duration notation
+format.
+ ## See: https://www.authelia.com/c/common#duration-notation-format
+ ## All three of these values affect the cookie/session validity period. Longer periods are considered less secure
+ ## because a stolen cookie will last longer giving attackers more time to spy or attack.
+ ## The time before the cookie expires and the session is destroyed if remember me IS NOT selected.
+ expiration: 1h
+ ## The inactivity time before the session is reset. If expiration is set to 1h, and this is set to 5m, if the user
+ ## does not select the remember me option their session will get destroyed after 1h, or after 5m since the last
+time
+ ## Authelia detected user activity.
+ inactivity: 5m
+ ## The time before the cookie expires and the session is destroyed if remember me IS selected.
+ ## Value of -1 disables remember me.
+ remember_me_duration: 2M
+ ##
+ ## Redis Provider
+ ##
+ ## Important: Kubernetes (or HA) users must read https://www.authelia.com/t/statelessness
+ ##
+ redis:
+ host: redis
+ port: 6379
+ ## Use a unix socket instead
+ # host: /var/run/redis/redis.sock
+ ## Username used for redis authentication. This is optional and a new feature in redis 6.0.
+ # username: authelia
+ ## Password can also be set using a secret: https://www.authelia.com/c/secrets
+ password: REDACTED
+ ## This is the Redis DB Index https://redis.io/commands/select (sometimes referred to as database number,
+DB, etc).
+ database_index: 0
+ ## The maximum number of concurrent active connections to Redis.
+ maximum_active_connections: 10
+ ## The target number of idle connections to have open ready for work. Useful when opening connections is
+slow.
+ minimum_idle_connections: 0
+ ## The Redis TLS configuration. If defined will require a TLS connection to the Redis instance(s).
+ # tls:
+ ## The server subject name to check the servers certificate against during the validation process.
+ ## This option is not required if the certificate has a SAN which matches the host option.
+ # server_name: myredis.example.com
+ ## Skip verifying the server certificate entirely. In preference to setting this we strongly recommend you
+add the
+ ## certificate or the certificate of the authority signing the certificate to the certificates directory which is
+ ## defined by the `certificates_directory` option at the top of the configuration.
+ ## It's important to note the public key should be added to the directory, not the private key.
+ ## This option is strongly discouraged but may be useful in some self-signed situations where validation is
+not
+ ## important to the administrator.
+ # skip_verify: false
+ ## Minimum TLS version for the connection.
+ # minimum_version: TLS1.2
+ ## Maximum TLS version for the connection.
+ # maximum_version: TLS1.3
+ ## The certificate chain used with the private_key if the server requests TLS Client Authentication
+ ## i.e. Mutual TLS.
+ # certificate_chain: |
+ # -----BEGIN CERTIFICATE-----
+ # MIIC5jCCAc6gAwIBAgIRAK4Sj7FiN6PXo/urPfO4E7owDQYJKoZIhvcNAQELBQAw
+ # EzERMA8GA1UEChMIQXV0aGVsaWEwHhcNNzAwMTAxMDAwMDAwWhcNNzEwMTAxMDAw
+ # MDAwWjATMREwDwYDVQQKEwhBdXRoZWxpYTCCASIwDQYJKoZIhvcNAQEBBQADggEP
+ # ADCCAQoCggEBAPKv3pSyP4ozGEiVLJ14dIWFCEGEgq7WUMI0SZZqQA2ID0L59U/Q
+ # /Usyy7uC9gfMUzODTpANtkOjFQcQAsxlR1FOjVBrX5QgjSvXwbQn3DtwMA7XWSl6
+ # LuYx2rBYSlMSN5UZQm/RxMtXfLK2b51WgEEYDFi+nECSqKzR4R54eOPkBEWRfvuY
+ # 91AMjlhpivg8e4JWkq4LVQUKbmiFYwIdK8XQiN4blY9WwXwJFYs5sQ/UYMwBFi0H
+ # kWOh7GEjfxgoUOPauIueZSMSlQp7zqAH39N0ZSYb6cS0Npj57QoWZSY3ak87ebcR
+ # Nf4rCvZLby7LoN7qYCKxmCaDD3x2+NYpWH8CAwEAAaM1MDMwDgYDVR0PAQH/BAQD
+ # AgWgMBMGA1UdJQQMMAoGCCsGAQUFBwMBMAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcN
+ # AQELBQADggEBAHSITqIQSNzonFl3DzxHPEzr2hp6peo45buAAtu8FZHoA+U7Icfh
+ # /ZXjPg7Xz+hgFwM/DTNGXkMWacQA/PaNWvZspgRJf2AXvNbMSs2UQODr7Tbv+Fb4
+ # lyblmMUNYFMCFVAMU0eIxXAFq2qcwv8UMcQFT0Z/35s6PVOakYnAGGQjTfp5Ljuq
+ # wsdc/xWmM0cHWube6sdRRUD7SY20KU/kWzl8iFO0VbSSrDf1AlEhnLEkp1SPaxXg
+ # OdBnl98MeoramNiJ7NT6Jnyb3zZ578fjaWfThiBpagItI8GZmG4s4Ovh2JbheN8i
+ # ZsjNr9jqHTjhyLVbDRlmJzcqoj4JhbKs6/I^invalid DO NOT USE=
+ # -----END CERTIFICATE-----
+ # -----BEGIN CERTIFICATE-----
+ # MIIDBDCCAeygAwIBAgIRALJsPg21kA0zY4F1wUCIuoMwDQYJKoZIhvcNAQELBQAw
+ # EzERMA8GA1UEChMIQXV0aGVsaWEwHhcNNzAwMTAxMDAwMDAwWhcNNzEwMTAxMDAw
+ # MDAwWjATMREwDwYDVQQKEwhBdXRoZWxpYTCCASIwDQYJKoZIhvcNAQEBBQADggEP
+ # ADCCAQoCggEBAMXHBvVxUzYk0u34/DINMSF+uiOekKOAjOrC6Mi9Ww8ytPVO7t2S
+ # zfTvM+XnEJqkFQFgimERfG/eGhjF9XIEY6LtnXe8ATvOK4nTwdufzBaoeQu3Gd50
+ # 5VXr6OHRo//ErrGvFXwP3g8xLePABsi/fkH3oDN+ztewOBMDzpd+KgTrk8ysv2ou
+ # kNRMKFZZqASvCgv0LD5KWvUCnL6wgf1oTXG7aztduA4oSkUP321GpOmBC5+5ElU7
+ # ysoRzvD12o9QJ/IfEaulIX06w9yVMo60C/h6A3U6GdkT1SiyTIqR7v7KU/IWd/Qi
+ # Lfftcj91VhCmJ73Meff2e2S2PrpjdXbG5FMCAwEAAaNTMFEwDgYDVR0PAQH/BAQD
+ # AgKkMA8GA1UdJQQIMAYGBFUdJQAwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU
+ # Z7AtA3mzFc0InSBA5fiMfeLXA3owDQYJKoZIhvcNAQELBQADggEBAEE5hm1mtlk/
+ # kviCoHH4evbpw7rxPxDftIQlqYTtvMM4eWY/6icFoSZ4fUHEWYyps8SsPu/8f2tf
+ # 71LGgZn0FdHi1QU2H8m0HHK7TFw+5Q6RLrLdSyk0PItJ71s9en7r8pX820nAFEHZ
+ # HkOSfJZ7B5hFgUDkMtVM6bardXAhoqcMk4YCU96e9d4PB4eI+xGc+mNuYvov3RbB
+ # D0s8ICyojeyPVLerz4wHjZu68Z5frAzhZ68YbzNs8j2fIBKKHkHyLG1iQyF+LJVj
+ # 2PjCP+auJsj6fQQpMGoyGtpLcSDh+ptcTngUD8JsWipzTCjmaNqdPHAOYmcgtf4b
+ # qocikt3WAdU^invalid DO NOT USE=
+ # -----END CERTIFICATE-----
+ ## The private key used with the certificate_chain if the server requests TLS Client Authentication
+ ## i.e. Mutual TLS.
+ # private_key: |
+ # -----BEGIN RSA PRIVATE KEY-----
+ # MIIEpAIBAAKCAQEA8q/elLI/ijMYSJUsnXh0hYUIQYSCrtZQwjRJlmpADYgPQvn1
+ # T9D9SzLLu4L2B8xTM4NOkA22Q6MVBxACzGVHUU6NUGtflCCNK9fBtCfcO3AwDtdZ
+ # KXou5jHasFhKUxI3lRlCb9HEy1d8srZvnVaAQRgMWL6cQJKorNHhHnh44+QERZF+
+ # +5j3UAyOWGmK+Dx7glaSrgtVBQpuaIVjAh0rxdCI3huVj1bBfAkVizmxD9RgzAEW
+ # LQeRY6HsYSN/GChQ49q4i55lIxKVCnvOoAff03RlJhvpxLQ2mPntChZlJjdqTzt5
+ # txE1/isK9ktvLsug3upgIrGYJoMPfHb41ilYfwIDAQABAoIBAQDTOdFf2JjHH1um
+ # aPgRAvNf9v7Nj5jytaRKs5nM6iNf46ls4QPreXnMhqSeSwj6lpNgBYxOgzC9Q+cc
+ # Y4ob/paJJPaIJTxmP8K/gyWcOQlNToL1l+eJ20eQoZm23NGr5fIsunSBwLEpTrdB
+ # ENqqtcwhW937K8Pxy/Q1nuLyU2bc6Tn/ivLozc8n27dpQWWKh8537VY7ancIaACr
+ # LJJLYxKqhQpjtBWAyCDvZQirnAOm9KnvIHaGXIswCZ4Xbsu0Y9NL+woARPyRVQvG
+ # jfxy4EmO9s1s6y7OObSukwKDSNihAKHx/VIbvVWx8g2Lv5fGOa+J2Y7o9Qurs8t5
+ # BQwMTt0BAoGBAPUw5Z32EszNepAeV3E2mPFUc5CLiqAxagZJuNDO2pKtyN29ETTR
+ # Ma4O1cWtGb6RqcNNN/Iukfkdk27Q5nC9VJSUUPYelOLc1WYOoUf6oKRzE72dkMQV
+ # R4bf6TkjD+OVR17fAfkswkGahZ5XA7j48KIQ+YC4jbnYKSxZTYyKPjH/AoGBAP1i
+ # tqXt36OVlP+y84wWqZSjMelBIVa9phDVGJmmhz3i1cMni8eLpJzWecA3pfnG6Tm9
+ # ze5M4whASleEt+M00gEvNaU9ND+z0wBfi+/DwJYIbv8PQdGrBiZFrPhTPjGQUldR
+ # lXccV2meeLZv7TagVxSi3DO6dSJfSEHyemd5j9mBAoGAX8Hv+0gOQZQCSOTAq8Nx
+ # 6dZcp9gHlNaXnMsP9eTDckOSzh636JPGvj6m+GPJSSbkURUIQ3oyokMNwFqvlNos
+ # fTaLhAOfjBZI9WnDTTQxpugWjphJ4HqbC67JC/qIiw5S6FdaEvGLEEoD4zoChywZ
+ # 9oGAn+fz2d/0/JAH/FpFPgsCgYEAp/ipZgPzziiZ9ov1wbdAQcWRj7RaWnssPFpX
+ # jXwEiXT3CgEMO4MJ4+KWIWOChrti3qFBg6i6lDyyS6Qyls7sLFbUdC7HlTcrOEMe
+ # rBoTcCI1GqZNlqWOVQ65ZIEiaI7o1vPBZo2GMQEZuq8mDKFsOMThvvTrM5cAep84
+ # n6HJR4ECgYABWcbsSnr0MKvVth/inxjbKapbZnp2HUCuw87Ie5zK2Of/tbC20wwk
+ # yKw3vrGoE3O1t1g2m2tn8UGGASeZ842jZWjIODdSi5+icysQGuULKt86h/woz2SQ
+ # 27GoE2i5mh6Yez6VAYbUuns3FcwIsMyWLq043Tu2DNkx9ijOOAuQzw^invalid..
+ # DO NOT USE==
+ # -----END RSA PRIVATE KEY-----
+ ## The Redis HA configuration options.
+ ## This provides specific options to Redis Sentinel, sentinel_name must be defined (Master Name).
+ # high_availability:
+ ## Sentinel Name / Master Name.
+ # sentinel_name: mysentinel
+ ## Specific username for Redis Sentinel. The node username and password is configured above.
+ # sentinel_username: sentinel_specific_user
+ ## Specific password for Redis Sentinel. The node username and password is configured above.
+ # sentinel_password: sentinel_specific_pass
+ ## The additional nodes to pre-seed the redis provider with (for sentinel).
+ ## If the host in the above section is defined, it will be combined with this list to connect to sentinel.
+ ## For high availability to be used you must have either defined; the host above or at least one node below.
+ # nodes:
+ # - host: sentinel-node1
+ # port: 6379
+ # - host: sentinel-node2
+ # port: 6379
+ ## Choose the host with the lowest latency.
+ # route_by_latency: false
+ ## Choose the host randomly.
+ # route_randomly: false
+##
+## Regulation Configuration
+##
+## This mechanism prevents attackers from brute forcing the first factor. It bans the user if too many attempts
+are made
+## in a short period of time.
+regulation:
+ ## The number of failed login attempts before user is banned. Set it to 0 to disable regulation.
+ max_retries: 3
+ ## The time range during which the user can attempt login before being banned. The user is banned if the
+ ## authentication failed 'max_retries' times in a 'find_time' seconds window. Find Time accepts duration
+notation.
+ ## See: https://www.authelia.com/c/common#duration-notation-format
+ find_time: 10m
+ ## The length of time before a banned user can login again. Ban Time accepts duration notation.
+ ## See: https://www.authelia.com/c/common#duration-notation-format
+ ban_time: 12h
+##
+## Storage Provider Configuration
+##
+## The available providers are: `local`, `mysql`, `postgres`. You must use one and only one of these providers.
+storage:
+ ## The encryption key that is used to encrypt sensitive information in the database. Must be a string with a
+minimum
+ ## length of 20. Please see the docs if you configure this with an undesirable key and need to change it, you
+MUST use
+ ## the CLI to change this in the database if you want to change it from a previously configured value.
+ encryption_key: REDACTED
+ ##
+ ## Local (Storage Provider)
+ ##
+ ## This stores the data in a SQLite3 Database.
+ ## This is only recommended for lightweight non-stateful installations.
+ ##
+ ## Important: Kubernetes (or HA) users must read https://www.authelia.com/t/statelessness
+ ##
+ # local:
+ ## Path to the SQLite3 Database.
+ # path: /config/db.sqlite3
+ ##
+ ## MySQL / MariaDB (Storage Provider)
+ ##
+ mysql:
+ host: mysql
+ port: 3306
+ database: authelia
+ username: authelia
+ ## Password can also be set using a secret: https://www.authelia.com/c/secrets
+ password: REDACTED
+ timeout: 5s
+ ## MySQL TLS settings. Configuring this requires TLS.
+ # tls:
+ ## The server subject name to check the servers certificate against during the validation process.
+ ## This option is not required if the certificate has a SAN which matches the host option.
+ # server_name: mysql.example.com
+ ## Skip verifying the server certificate entirely. In preference to setting this we strongly recommend you
+add the
+ ## certificate or the certificate of the authority signing the certificate to the certificates directory which is
+ ## defined by the `certificates_directory` option at the top of the configuration.
+ ## It's important to note the public key should be added to the directory, not the private key.
+ ## This option is strongly discouraged but may be useful in some self-signed situations where validation is
+not
+ ## important to the administrator.
+ # skip_verify: false
+ ## Minimum TLS version for the connection.
+ # minimum_version: TLS1.2
+ ## Maximum TLS version for the connection.
+ # maximum_version: TLS1.3
+ ## The certificate chain used with the private_key if the server requests TLS Client Authentication
+ ## i.e. Mutual TLS.
+ # certificate_chain: |
+ # -----BEGIN CERTIFICATE-----
+ # MIIC5jCCAc6gAwIBAgIRAK4Sj7FiN6PXo/urPfO4E7owDQYJKoZIhvcNAQELBQAw
+ # EzERMA8GA1UEChMIQXV0aGVsaWEwHhcNNzAwMTAxMDAwMDAwWhcNNzEwMTAxMDAw
+ # MDAwWjATMREwDwYDVQQKEwhBdXRoZWxpYTCCASIwDQYJKoZIhvcNAQEBBQADggEP
+ # ADCCAQoCggEBAPKv3pSyP4ozGEiVLJ14dIWFCEGEgq7WUMI0SZZqQA2ID0L59U/Q
+ # /Usyy7uC9gfMUzODTpANtkOjFQcQAsxlR1FOjVBrX5QgjSvXwbQn3DtwMA7XWSl6
+ # LuYx2rBYSlMSN5UZQm/RxMtXfLK2b51WgEEYDFi+nECSqKzR4R54eOPkBEWRfvuY
+ # 91AMjlhpivg8e4JWkq4LVQUKbmiFYwIdK8XQiN4blY9WwXwJFYs5sQ/UYMwBFi0H
+ # kWOh7GEjfxgoUOPauIueZSMSlQp7zqAH39N0ZSYb6cS0Npj57QoWZSY3ak87ebcR
+ # Nf4rCvZLby7LoN7qYCKxmCaDD3x2+NYpWH8CAwEAAaM1MDMwDgYDVR0PAQH/BAQD
+ # AgWgMBMGA1UdJQQMMAoGCCsGAQUFBwMBMAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcN
+ # AQELBQADggEBAHSITqIQSNzonFl3DzxHPEzr2hp6peo45buAAtu8FZHoA+U7Icfh
+ # /ZXjPg7Xz+hgFwM/DTNGXkMWacQA/PaNWvZspgRJf2AXvNbMSs2UQODr7Tbv+Fb4
+ # lyblmMUNYFMCFVAMU0eIxXAFq2qcwv8UMcQFT0Z/35s6PVOakYnAGGQjTfp5Ljuq
+ # wsdc/xWmM0cHWube6sdRRUD7SY20KU/kWzl8iFO0VbSSrDf1AlEhnLEkp1SPaxXg
+ # OdBnl98MeoramNiJ7NT6Jnyb3zZ578fjaWfThiBpagItI8GZmG4s4Ovh2JbheN8i
+ # ZsjNr9jqHTjhyLVbDRlmJzcqoj4JhbKs6/I^invalid DO NOT USE=
+ # -----END CERTIFICATE-----
+ # -----BEGIN CERTIFICATE-----
+ # MIIDBDCCAeygAwIBAgIRALJsPg21kA0zY4F1wUCIuoMwDQYJKoZIhvcNAQELBQAw
+ # EzERMA8GA1UEChMIQXV0aGVsaWEwHhcNNzAwMTAxMDAwMDAwWhcNNzEwMTAxMDAw
+ # MDAwWjATMREwDwYDVQQKEwhBdXRoZWxpYTCCASIwDQYJKoZIhvcNAQEBBQADggEP
+ # ADCCAQoCggEBAMXHBvVxUzYk0u34/DINMSF+uiOekKOAjOrC6Mi9Ww8ytPVO7t2S
+ # zfTvM+XnEJqkFQFgimERfG/eGhjF9XIEY6LtnXe8ATvOK4nTwdufzBaoeQu3Gd50
+ # 5VXr6OHRo//ErrGvFXwP3g8xLePABsi/fkH3oDN+ztewOBMDzpd+KgTrk8ysv2ou
+ # kNRMKFZZqASvCgv0LD5KWvUCnL6wgf1oTXG7aztduA4oSkUP321GpOmBC5+5ElU7
+ # ysoRzvD12o9QJ/IfEaulIX06w9yVMo60C/h6A3U6GdkT1SiyTIqR7v7KU/IWd/Qi
+ # Lfftcj91VhCmJ73Meff2e2S2PrpjdXbG5FMCAwEAAaNTMFEwDgYDVR0PAQH/BAQD
+ # AgKkMA8GA1UdJQQIMAYGBFUdJQAwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU
+ # Z7AtA3mzFc0InSBA5fiMfeLXA3owDQYJKoZIhvcNAQELBQADggEBAEE5hm1mtlk/
+ # kviCoHH4evbpw7rxPxDftIQlqYTtvMM4eWY/6icFoSZ4fUHEWYyps8SsPu/8f2tf
+ # 71LGgZn0FdHi1QU2H8m0HHK7TFw+5Q6RLrLdSyk0PItJ71s9en7r8pX820nAFEHZ
+ # HkOSfJZ7B5hFgUDkMtVM6bardXAhoqcMk4YCU96e9d4PB4eI+xGc+mNuYvov3RbB
+ # D0s8ICyojeyPVLerz4wHjZu68Z5frAzhZ68YbzNs8j2fIBKKHkHyLG1iQyF+LJVj
+ # 2PjCP+auJsj6fQQpMGoyGtpLcSDh+ptcTngUD8JsWipzTCjmaNqdPHAOYmcgtf4b
+ # qocikt3WAdU^invalid DO NOT USE=
+ # -----END CERTIFICATE-----
+ ## The private key used with the certificate_chain if the server requests TLS Client Authentication
+ ## i.e. Mutual TLS.
+ # private_key: |
+ # -----BEGIN RSA PRIVATE KEY-----
+ # MIIEpAIBAAKCAQEA8q/elLI/ijMYSJUsnXh0hYUIQYSCrtZQwjRJlmpADYgPQvn1
+ # T9D9SzLLu4L2B8xTM4NOkA22Q6MVBxACzGVHUU6NUGtflCCNK9fBtCfcO3AwDtdZ
+ # KXou5jHasFhKUxI3lRlCb9HEy1d8srZvnVaAQRgMWL6cQJKorNHhHnh44+QERZF+
+ # +5j3UAyOWGmK+Dx7glaSrgtVBQpuaIVjAh0rxdCI3huVj1bBfAkVizmxD9RgzAEW
+ # LQeRY6HsYSN/GChQ49q4i55lIxKVCnvOoAff03RlJhvpxLQ2mPntChZlJjdqTzt5
+ # txE1/isK9ktvLsug3upgIrGYJoMPfHb41ilYfwIDAQABAoIBAQDTOdFf2JjHH1um
+ # aPgRAvNf9v7Nj5jytaRKs5nM6iNf46ls4QPreXnMhqSeSwj6lpNgBYxOgzC9Q+cc
+ # Y4ob/paJJPaIJTxmP8K/gyWcOQlNToL1l+eJ20eQoZm23NGr5fIsunSBwLEpTrdB
+ # ENqqtcwhW937K8Pxy/Q1nuLyU2bc6Tn/ivLozc8n27dpQWWKh8537VY7ancIaACr
+ # LJJLYxKqhQpjtBWAyCDvZQirnAOm9KnvIHaGXIswCZ4Xbsu0Y9NL+woARPyRVQvG
+ # jfxy4EmO9s1s6y7OObSukwKDSNihAKHx/VIbvVWx8g2Lv5fGOa+J2Y7o9Qurs8t5
+ # BQwMTt0BAoGBAPUw5Z32EszNepAeV3E2mPFUc5CLiqAxagZJuNDO2pKtyN29ETTR
+ # Ma4O1cWtGb6RqcNNN/Iukfkdk27Q5nC9VJSUUPYelOLc1WYOoUf6oKRzE72dkMQV
+ # R4bf6TkjD+OVR17fAfkswkGahZ5XA7j48KIQ+YC4jbnYKSxZTYyKPjH/AoGBAP1i
+ # tqXt36OVlP+y84wWqZSjMelBIVa9phDVGJmmhz3i1cMni8eLpJzWecA3pfnG6Tm9
+ # ze5M4whASleEt+M00gEvNaU9ND+z0wBfi+/DwJYIbv8PQdGrBiZFrPhTPjGQUldR
+ # lXccV2meeLZv7TagVxSi3DO6dSJfSEHyemd5j9mBAoGAX8Hv+0gOQZQCSOTAq8Nx
+ # 6dZcp9gHlNaXnMsP9eTDckOSzh636JPGvj6m+GPJSSbkURUIQ3oyokMNwFqvlNos
+ # fTaLhAOfjBZI9WnDTTQxpugWjphJ4HqbC67JC/qIiw5S6FdaEvGLEEoD4zoChywZ
+ # 9oGAn+fz2d/0/JAH/FpFPgsCgYEAp/ipZgPzziiZ9ov1wbdAQcWRj7RaWnssPFpX
+ # jXwEiXT3CgEMO4MJ4+KWIWOChrti3qFBg6i6lDyyS6Qyls7sLFbUdC7HlTcrOEMe
+ # rBoTcCI1GqZNlqWOVQ65ZIEiaI7o1vPBZo2GMQEZuq8mDKFsOMThvvTrM5cAep84
+ # n6HJR4ECgYABWcbsSnr0MKvVth/inxjbKapbZnp2HUCuw87Ie5zK2Of/tbC20wwk
+ # yKw3vrGoE3O1t1g2m2tn8UGGASeZ842jZWjIODdSi5+icysQGuULKt86h/woz2SQ
+ # 27GoE2i5mh6Yez6VAYbUuns3FcwIsMyWLq043Tu2DNkx9ijOOAuQzw^invalid..
+ # DO NOT USE==
+ # -----END RSA PRIVATE KEY-----
+ ##
+ ## PostgreSQL (Storage Provider)
+ ##
+ # postgres:
+ # host: 127.0.0.1
+ # port: 5432
+ # database: authelia
+ # schema: public
+ # username: authelia
+ ## Password can also be set using a secret: https://www.authelia.com/c/secrets
+ # password: mypassword
+ # timeout: 5s
+ ## PostgreSQL TLS settings. Configuring this requires TLS.
+ # tls:
+ ## The server subject name to check the servers certificate against during the validation process.
+ ## This option is not required if the certificate has a SAN which matches the host option.
+ # server_name: postgres.example.com
+ ## Skip verifying the server certificate entirely. In preference to setting this we strongly recommend you
+add the
+ ## certificate or the certificate of the authority signing the certificate to the certificates directory which is
+ ## defined by the `certificates_directory` option at the top of the configuration.
+ ## It's important to note the public key should be added to the directory, not the private key.
+ ## This option is strongly discouraged but may be useful in some self-signed situations where validation is
+not
+ ## important to the administrator.
+ # skip_verify: false
+ ## Minimum TLS version for the connection.
+ # minimum_version: TLS1.2
+ ## Maximum TLS version for the connection.
+ # maximum_version: TLS1.3
+ ## The certificate chain used with the private_key if the server requests TLS Client Authentication
+ ## i.e. Mutual TLS.
+ # certificate_chain: |
+ # -----BEGIN CERTIFICATE-----
+ # MIIC5jCCAc6gAwIBAgIRAK4Sj7FiN6PXo/urPfO4E7owDQYJKoZIhvcNAQELBQAw
+ # EzERMA8GA1UEChMIQXV0aGVsaWEwHhcNNzAwMTAxMDAwMDAwWhcNNzEwMTAxMDAw
+ # MDAwWjATMREwDwYDVQQKEwhBdXRoZWxpYTCCASIwDQYJKoZIhvcNAQEBBQADggEP
+ # ADCCAQoCggEBAPKv3pSyP4ozGEiVLJ14dIWFCEGEgq7WUMI0SZZqQA2ID0L59U/Q
+ # /Usyy7uC9gfMUzODTpANtkOjFQcQAsxlR1FOjVBrX5QgjSvXwbQn3DtwMA7XWSl6
+ # LuYx2rBYSlMSN5UZQm/RxMtXfLK2b51WgEEYDFi+nECSqKzR4R54eOPkBEWRfvuY
+ # 91AMjlhpivg8e4JWkq4LVQUKbmiFYwIdK8XQiN4blY9WwXwJFYs5sQ/UYMwBFi0H
+ # kWOh7GEjfxgoUOPauIueZSMSlQp7zqAH39N0ZSYb6cS0Npj57QoWZSY3ak87ebcR
+ # Nf4rCvZLby7LoN7qYCKxmCaDD3x2+NYpWH8CAwEAAaM1MDMwDgYDVR0PAQH/BAQD
+ # AgWgMBMGA1UdJQQMMAoGCCsGAQUFBwMBMAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcN
+ # AQELBQADggEBAHSITqIQSNzonFl3DzxHPEzr2hp6peo45buAAtu8FZHoA+U7Icfh
+ # /ZXjPg7Xz+hgFwM/DTNGXkMWacQA/PaNWvZspgRJf2AXvNbMSs2UQODr7Tbv+Fb4
+ # lyblmMUNYFMCFVAMU0eIxXAFq2qcwv8UMcQFT0Z/35s6PVOakYnAGGQjTfp5Ljuq
+ # wsdc/xWmM0cHWube6sdRRUD7SY20KU/kWzl8iFO0VbSSrDf1AlEhnLEkp1SPaxXg
+ # OdBnl98MeoramNiJ7NT6Jnyb3zZ578fjaWfThiBpagItI8GZmG4s4Ovh2JbheN8i
+ # ZsjNr9jqHTjhyLVbDRlmJzcqoj4JhbKs6/I^invalid DO NOT USE=
+ # -----END CERTIFICATE-----
+ # -----BEGIN CERTIFICATE-----
+ # MIIDBDCCAeygAwIBAgIRALJsPg21kA0zY4F1wUCIuoMwDQYJKoZIhvcNAQELBQAw
+ # EzERMA8GA1UEChMIQXV0aGVsaWEwHhcNNzAwMTAxMDAwMDAwWhcNNzEwMTAxMDAw
+ # MDAwWjATMREwDwYDVQQKEwhBdXRoZWxpYTCCASIwDQYJKoZIhvcNAQEBBQADggEP
+ # ADCCAQoCggEBAMXHBvVxUzYk0u34/DINMSF+uiOekKOAjOrC6Mi9Ww8ytPVO7t2S
+ # zfTvM+XnEJqkFQFgimERfG/eGhjF9XIEY6LtnXe8ATvOK4nTwdufzBaoeQu3Gd50
+ # 5VXr6OHRo//ErrGvFXwP3g8xLePABsi/fkH3oDN+ztewOBMDzpd+KgTrk8ysv2ou
+ # kNRMKFZZqASvCgv0LD5KWvUCnL6wgf1oTXG7aztduA4oSkUP321GpOmBC5+5ElU7
+ # ysoRzvD12o9QJ/IfEaulIX06w9yVMo60C/h6A3U6GdkT1SiyTIqR7v7KU/IWd/Qi
+ # Lfftcj91VhCmJ73Meff2e2S2PrpjdXbG5FMCAwEAAaNTMFEwDgYDVR0PAQH/BAQD
+ # AgKkMA8GA1UdJQQIMAYGBFUdJQAwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU
+ # Z7AtA3mzFc0InSBA5fiMfeLXA3owDQYJKoZIhvcNAQELBQADggEBAEE5hm1mtlk/
+ # kviCoHH4evbpw7rxPxDftIQlqYTtvMM4eWY/6icFoSZ4fUHEWYyps8SsPu/8f2tf
+ # 71LGgZn0FdHi1QU2H8m0HHK7TFw+5Q6RLrLdSyk0PItJ71s9en7r8pX820nAFEHZ
+ # HkOSfJZ7B5hFgUDkMtVM6bardXAhoqcMk4YCU96e9d4PB4eI+xGc+mNuYvov3RbB
+ # D0s8ICyojeyPVLerz4wHjZu68Z5frAzhZ68YbzNs8j2fIBKKHkHyLG1iQyF+LJVj
+ # 2PjCP+auJsj6fQQpMGoyGtpLcSDh+ptcTngUD8JsWipzTCjmaNqdPHAOYmcgtf4b
+ # qocikt3WAdU^invalid DO NOT USE=
+ # -----END CERTIFICATE-----
+ ## The private key used with the certificate_chain if the server requests TLS Client Authentication
+ ## i.e. Mutual TLS.
+ # private_key: |
+ # -----BEGIN RSA PRIVATE KEY-----
+ # MIIEpAIBAAKCAQEA8q/elLI/ijMYSJUsnXh0hYUIQYSCrtZQwjRJlmpADYgPQvn1
+ # T9D9SzLLu4L2B8xTM4NOkA22Q6MVBxACzGVHUU6NUGtflCCNK9fBtCfcO3AwDtdZ
+ # KXou5jHasFhKUxI3lRlCb9HEy1d8srZvnVaAQRgMWL6cQJKorNHhHnh44+QERZF+
+ # +5j3UAyOWGmK+Dx7glaSrgtVBQpuaIVjAh0rxdCI3huVj1bBfAkVizmxD9RgzAEW
+ # LQeRY6HsYSN/GChQ49q4i55lIxKVCnvOoAff03RlJhvpxLQ2mPntChZlJjdqTzt5
+ # txE1/isK9ktvLsug3upgIrGYJoMPfHb41ilYfwIDAQABAoIBAQDTOdFf2JjHH1um
+ # aPgRAvNf9v7Nj5jytaRKs5nM6iNf46ls4QPreXnMhqSeSwj6lpNgBYxOgzC9Q+cc
+ # Y4ob/paJJPaIJTxmP8K/gyWcOQlNToL1l+eJ20eQoZm23NGr5fIsunSBwLEpTrdB
+ # ENqqtcwhW937K8Pxy/Q1nuLyU2bc6Tn/ivLozc8n27dpQWWKh8537VY7ancIaACr
+ # LJJLYxKqhQpjtBWAyCDvZQirnAOm9KnvIHaGXIswCZ4Xbsu0Y9NL+woARPyRVQvG
+ # jfxy4EmO9s1s6y7OObSukwKDSNihAKHx/VIbvVWx8g2Lv5fGOa+J2Y7o9Qurs8t5
+ # BQwMTt0BAoGBAPUw5Z32EszNepAeV3E2mPFUc5CLiqAxagZJuNDO2pKtyN29ETTR
+ # Ma4O1cWtGb6RqcNNN/Iukfkdk27Q5nC9VJSUUPYelOLc1WYOoUf6oKRzE72dkMQV
+ # R4bf6TkjD+OVR17fAfkswkGahZ5XA7j48KIQ+YC4jbnYKSxZTYyKPjH/AoGBAP1i
+ # tqXt36OVlP+y84wWqZSjMelBIVa9phDVGJmmhz3i1cMni8eLpJzWecA3pfnG6Tm9
+ # ze5M4whASleEt+M00gEvNaU9ND+z0wBfi+/DwJYIbv8PQdGrBiZFrPhTPjGQUldR
+ # lXccV2meeLZv7TagVxSi3DO6dSJfSEHyemd5j9mBAoGAX8Hv+0gOQZQCSOTAq8Nx
+ # 6dZcp9gHlNaXnMsP9eTDckOSzh636JPGvj6m+GPJSSbkURUIQ3oyokMNwFqvlNos
+ # fTaLhAOfjBZI9WnDTTQxpugWjphJ4HqbC67JC/qIiw5S6FdaEvGLEEoD4zoChywZ
+ # 9oGAn+fz2d/0/JAH/FpFPgsCgYEAp/ipZgPzziiZ9ov1wbdAQcWRj7RaWnssPFpX
+ # jXwEiXT3CgEMO4MJ4+KWIWOChrti3qFBg6i6lDyyS6Qyls7sLFbUdC7HlTcrOEMe
+ # rBoTcCI1GqZNlqWOVQ65ZIEiaI7o1vPBZo2GMQEZuq8mDKFsOMThvvTrM5cAep84
+ # n6HJR4ECgYABWcbsSnr0MKvVth/inxjbKapbZnp2HUCuw87Ie5zK2Of/tbC20wwk
+ # yKw3vrGoE3O1t1g2m2tn8UGGASeZ842jZWjIODdSi5+icysQGuULKt86h/woz2SQ
+ # 27GoE2i5mh6Yez6VAYbUuns3FcwIsMyWLq043Tu2DNkx9ijOOAuQzw^invalid..
+ # DO NOT USE==
+ # -----END RSA PRIVATE KEY-----
+##
+## Notification Provider
+##
+## Notifications are sent to users when they require a password reset, a Webauthn registration or a TOTP
+registration.
+## The available providers are: filesystem, smtp. You must use only one of these providers.
+notifier:
+ ## You can disable the notifier startup check by setting this to true.
+ disable_startup_check: false
+ ##
+ ## File System (Notification Provider)
+ ##
+ ## Important: Kubernetes (or HA) users must read https://www.authelia.com/t/statelessness
+ ##
+# filesystem:
+# filename: /config/notification.txt
+ ##
+ ## SMTP (Notification Provider)
+ ##
+ ## Use a SMTP server for sending notifications. Authelia uses the PLAIN or LOGIN methods to authenticate.
+ ## [Security] By default Authelia will:
+ ## - force all SMTP connections over TLS including unauthenticated connections
+ ## - use the disable_require_tls boolean value to disable this requirement
+ ## (only works for unauthenticated connections)
+ ## - validate the SMTP server x509 certificate during the TLS handshake against the hosts trusted certificates
+ ## (configure in tls section)
+ smtp:
+ ## The SMTP host to connect to.
+ host: smtp.gmail.com
+ ## The port to connect to the SMTP host on.
+ port: 587
+ ## The connection timeout.
+ timeout: 5s
+ ## The username used for SMTP authentication.
+ username: [emailaddressrelay]@gmail.com
+ ## The password used for SMTP authentication.
+ ## Can also be set using a secret: https://www.authelia.com/c/secrets
+ password: REDACTED
+ ## The sender is used to is used for the MAIL FROM command and the FROM header.
+ ## If this is not defined and the username is an email, we use the username as this value. This can either be
+just
+ ## an email address or the RFC5322 'Name <email address>' format.
+ sender: "Authelia <admin@[domain.tld]>"
+ ## HELO/EHLO Identifier. Some SMTP Servers may reject the default of localhost.
+ identifier: [domain.tld]
+ ## Subject configuration of the emails sent. {title} is replaced by the text from the notifier.
+ subject: "[Authelia] {title}"
+ ## This address is used during the startup check to verify the email configuration is correct.
+ ## It's not important what it is except if your email server only allows local delivery.
+ startup_check_address: [emailaddressrelay]@gmail.com
+ ## By default we require some form of TLS. This disables this check though is not advised.
+ # disable_require_tls: false
+ ## Disables sending HTML formatted emails.
+ # disable_html_emails: false
+ tls:
+ ## The server subject name to check the servers certificate against during the validation process.
+ ## This option is not required if the certificate has a SAN which matches the host option.
+ server_name: smtp.gmail.com
+ ## Skip verifying the server certificate entirely. In preference to setting this we strongly recommend you
+add the
+ ## certificate or the certificate of the authority signing the certificate to the certificates directory which is
+ ## defined by the `certificates_directory` option at the top of the configuration.
+ ## It's important to note the public key should be added to the directory, not the private key.
+ ## This option is strongly discouraged but may be useful in some self-signed situations where validation is
+not
+ ## important to the administrator.
+ # skip_verify: false
+ ## Minimum TLS version for the connection.
+ # minimum_version: TLS1.2
+ ## Maximum TLS version for the connection.
+ # maximum_version: TLS1.3
+ ## The certificate chain used with the private_key if the server requests TLS Client Authentication
+ ## i.e. Mutual TLS.
+ # certificate_chain: |
+ # -----BEGIN CERTIFICATE-----
+ # MIIC5jCCAc6gAwIBAgIRAK4Sj7FiN6PXo/urPfO4E7owDQYJKoZIhvcNAQELBQAw
+ # EzERMA8GA1UEChMIQXV0aGVsaWEwHhcNNzAwMTAxMDAwMDAwWhcNNzEwMTAxMDAw
+ # MDAwWjATMREwDwYDVQQKEwhBdXRoZWxpYTCCASIwDQYJKoZIhvcNAQEBBQADggEP
+ # ADCCAQoCggEBAPKv3pSyP4ozGEiVLJ14dIWFCEGEgq7WUMI0SZZqQA2ID0L59U/Q
+ # /Usyy7uC9gfMUzODTpANtkOjFQcQAsxlR1FOjVBrX5QgjSvXwbQn3DtwMA7XWSl6
+ # LuYx2rBYSlMSN5UZQm/RxMtXfLK2b51WgEEYDFi+nECSqKzR4R54eOPkBEWRfvuY
+ # 91AMjlhpivg8e4JWkq4LVQUKbmiFYwIdK8XQiN4blY9WwXwJFYs5sQ/UYMwBFi0H
+ # kWOh7GEjfxgoUOPauIueZSMSlQp7zqAH39N0ZSYb6cS0Npj57QoWZSY3ak87ebcR
+ # Nf4rCvZLby7LoN7qYCKxmCaDD3x2+NYpWH8CAwEAAaM1MDMwDgYDVR0PAQH/BAQD
+ # AgWgMBMGA1UdJQQMMAoGCCsGAQUFBwMBMAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcN
+ # AQELBQADggEBAHSITqIQSNzonFl3DzxHPEzr2hp6peo45buAAtu8FZHoA+U7Icfh
+ # /ZXjPg7Xz+hgFwM/DTNGXkMWacQA/PaNWvZspgRJf2AXvNbMSs2UQODr7Tbv+Fb4
+ # lyblmMUNYFMCFVAMU0eIxXAFq2qcwv8UMcQFT0Z/35s6PVOakYnAGGQjTfp5Ljuq
+ # wsdc/xWmM0cHWube6sdRRUD7SY20KU/kWzl8iFO0VbSSrDf1AlEhnLEkp1SPaxXg
+ # OdBnl98MeoramNiJ7NT6Jnyb3zZ578fjaWfThiBpagItI8GZmG4s4Ovh2JbheN8i
+ # ZsjNr9jqHTjhyLVbDRlmJzcqoj4JhbKs6/I^invalid DO NOT USE=
+ # -----END CERTIFICATE-----
+ # -----BEGIN CERTIFICATE-----
+ # MIIDBDCCAeygAwIBAgIRALJsPg21kA0zY4F1wUCIuoMwDQYJKoZIhvcNAQELBQAw
+ # EzERMA8GA1UEChMIQXV0aGVsaWEwHhcNNzAwMTAxMDAwMDAwWhcNNzEwMTAxMDAw
+ # MDAwWjATMREwDwYDVQQKEwhBdXRoZWxpYTCCASIwDQYJKoZIhvcNAQEBBQADggEP
+ # ADCCAQoCggEBAMXHBvVxUzYk0u34/DINMSF+uiOekKOAjOrC6Mi9Ww8ytPVO7t2S
+ # zfTvM+XnEJqkFQFgimERfG/eGhjF9XIEY6LtnXe8ATvOK4nTwdufzBaoeQu3Gd50
+ # 5VXr6OHRo//ErrGvFXwP3g8xLePABsi/fkH3oDN+ztewOBMDzpd+KgTrk8ysv2ou
+ # kNRMKFZZqASvCgv0LD5KWvUCnL6wgf1oTXG7aztduA4oSkUP321GpOmBC5+5ElU7
+ # ysoRzvD12o9QJ/IfEaulIX06w9yVMo60C/h6A3U6GdkT1SiyTIqR7v7KU/IWd/Qi
+ # Lfftcj91VhCmJ73Meff2e2S2PrpjdXbG5FMCAwEAAaNTMFEwDgYDVR0PAQH/BAQD
+ # AgKkMA8GA1UdJQQIMAYGBFUdJQAwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU
+ # Z7AtA3mzFc0InSBA5fiMfeLXA3owDQYJKoZIhvcNAQELBQADggEBAEE5hm1mtlk/
+ # kviCoHH4evbpw7rxPxDftIQlqYTtvMM4eWY/6icFoSZ4fUHEWYyps8SsPu/8f2tf
+ # 71LGgZn0FdHi1QU2H8m0HHK7TFw+5Q6RLrLdSyk0PItJ71s9en7r8pX820nAFEHZ
+ # HkOSfJZ7B5hFgUDkMtVM6bardXAhoqcMk4YCU96e9d4PB4eI+xGc+mNuYvov3RbB
+ # D0s8ICyojeyPVLerz4wHjZu68Z5frAzhZ68YbzNs8j2fIBKKHkHyLG1iQyF+LJVj
+ # 2PjCP+auJsj6fQQpMGoyGtpLcSDh+ptcTngUD8JsWipzTCjmaNqdPHAOYmcgtf4b
+ # qocikt3WAdU^invalid DO NOT USE=
+ # -----END CERTIFICATE-----
+ ## The private key used with the certificate_chain if the server requests TLS Client Authentication
+ ## i.e. Mutual TLS.
+ # private_key: |
+ # -----BEGIN RSA PRIVATE KEY-----
+ # MIIEpAIBAAKCAQEA8q/elLI/ijMYSJUsnXh0hYUIQYSCrtZQwjRJlmpADYgPQvn1
+ # T9D9SzLLu4L2B8xTM4NOkA22Q6MVBxACzGVHUU6NUGtflCCNK9fBtCfcO3AwDtdZ
+ # KXou5jHasFhKUxI3lRlCb9HEy1d8srZvnVaAQRgMWL6cQJKorNHhHnh44+QERZF+
+ # +5j3UAyOWGmK+Dx7glaSrgtVBQpuaIVjAh0rxdCI3huVj1bBfAkVizmxD9RgzAEW
+ # LQeRY6HsYSN/GChQ49q4i55lIxKVCnvOoAff03RlJhvpxLQ2mPntChZlJjdqTzt5
+ # txE1/isK9ktvLsug3upgIrGYJoMPfHb41ilYfwIDAQABAoIBAQDTOdFf2JjHH1um
+ # aPgRAvNf9v7Nj5jytaRKs5nM6iNf46ls4QPreXnMhqSeSwj6lpNgBYxOgzC9Q+cc
+ # Y4ob/paJJPaIJTxmP8K/gyWcOQlNToL1l+eJ20eQoZm23NGr5fIsunSBwLEpTrdB
+ # ENqqtcwhW937K8Pxy/Q1nuLyU2bc6Tn/ivLozc8n27dpQWWKh8537VY7ancIaACr
+ # LJJLYxKqhQpjtBWAyCDvZQirnAOm9KnvIHaGXIswCZ4Xbsu0Y9NL+woARPyRVQvG
+ # jfxy4EmO9s1s6y7OObSukwKDSNihAKHx/VIbvVWx8g2Lv5fGOa+J2Y7o9Qurs8t5
+ # BQwMTt0BAoGBAPUw5Z32EszNepAeV3E2mPFUc5CLiqAxagZJuNDO2pKtyN29ETTR
+ # Ma4O1cWtGb6RqcNNN/Iukfkdk27Q5nC9VJSUUPYelOLc1WYOoUf6oKRzE72dkMQV
+ # R4bf6TkjD+OVR17fAfkswkGahZ5XA7j48KIQ+YC4jbnYKSxZTYyKPjH/AoGBAP1i
+ # tqXt36OVlP+y84wWqZSjMelBIVa9phDVGJmmhz3i1cMni8eLpJzWecA3pfnG6Tm9
+ # ze5M4whASleEt+M00gEvNaU9ND+z0wBfi+/DwJYIbv8PQdGrBiZFrPhTPjGQUldR
+ # lXccV2meeLZv7TagVxSi3DO6dSJfSEHyemd5j9mBAoGAX8Hv+0gOQZQCSOTAq8Nx
+ # 6dZcp9gHlNaXnMsP9eTDckOSzh636JPGvj6m+GPJSSbkURUIQ3oyokMNwFqvlNos
+ # fTaLhAOfjBZI9WnDTTQxpugWjphJ4HqbC67JC/qIiw5S6FdaEvGLEEoD4zoChywZ
+ # 9oGAn+fz2d/0/JAH/FpFPgsCgYEAp/ipZgPzziiZ9ov1wbdAQcWRj7RaWnssPFpX
+ # jXwEiXT3CgEMO4MJ4+KWIWOChrti3qFBg6i6lDyyS6Qyls7sLFbUdC7HlTcrOEMe
+ # rBoTcCI1GqZNlqWOVQ65ZIEiaI7o1vPBZo2GMQEZuq8mDKFsOMThvvTrM5cAep84
+ # n6HJR4ECgYABWcbsSnr0MKvVth/inxjbKapbZnp2HUCuw87Ie5zK2Of/tbC20wwk
+ # yKw3vrGoE3O1t1g2m2tn8UGGASeZ842jZWjIODdSi5+icysQGuULKt86h/woz2SQ
+ # 27GoE2i5mh6Yez6VAYbUuns3FcwIsMyWLq043Tu2DNkx9ijOOAuQzw^invalid..
+ # DO NOT USE==
+ # -----END RSA PRIVATE KEY-----
+##
+## Identity Providers
+##
+# identity_providers:
+ ##
+ ## OpenID Connect (Identity Provider)
+ ##
+ ## It's recommended you read the documentation before configuration of this section:
+ ## https://www.authelia.com/c/oidc
+ # oidc:
+ ## The hmac_secret is used to sign OAuth2 tokens (authorization code, access tokens and refresh tokens).
+ ## HMAC Secret can also be set using a secret: https://www.authelia.com/c/secrets
+ # hmac_secret: this_is_a_secret_abc123abc123abc
+ ## The issuer_certificate_chain is an optional PEM encoded certificate chain. It's used in conjunction with the
+ ## issuer_private_key to sign JWT's. All certificates in the chain must be within the validity period, and every
+ ## certificate included must be signed by the certificate immediately after it if provided.
+ # issuer_certificate_chain: |
+ # -----BEGIN CERTIFICATE-----
+ # MIIC5jCCAc6gAwIBAgIRAK4Sj7FiN6PXo/urPfO4E7owDQYJKoZIhvcNAQELBQAw
+ # EzERMA8GA1UEChMIQXV0aGVsaWEwHhcNNzAwMTAxMDAwMDAwWhcNNzEwMTAxMDAw
+ # MDAwWjATMREwDwYDVQQKEwhBdXRoZWxpYTCCASIwDQYJKoZIhvcNAQEBBQADggEP
+ # ADCCAQoCggEBAPKv3pSyP4ozGEiVLJ14dIWFCEGEgq7WUMI0SZZqQA2ID0L59U/Q
+ # /Usyy7uC9gfMUzODTpANtkOjFQcQAsxlR1FOjVBrX5QgjSvXwbQn3DtwMA7XWSl6
+ # LuYx2rBYSlMSN5UZQm/RxMtXfLK2b51WgEEYDFi+nECSqKzR4R54eOPkBEWRfvuY
+ # 91AMjlhpivg8e4JWkq4LVQUKbmiFYwIdK8XQiN4blY9WwXwJFYs5sQ/UYMwBFi0H
+ # kWOh7GEjfxgoUOPauIueZSMSlQp7zqAH39N0ZSYb6cS0Npj57QoWZSY3ak87ebcR
+ # Nf4rCvZLby7LoN7qYCKxmCaDD3x2+NYpWH8CAwEAAaM1MDMwDgYDVR0PAQH/BAQD
+ # AgWgMBMGA1UdJQQMMAoGCCsGAQUFBwMBMAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcN
+ # AQELBQADggEBAHSITqIQSNzonFl3DzxHPEzr2hp6peo45buAAtu8FZHoA+U7Icfh
+ # /ZXjPg7Xz+hgFwM/DTNGXkMWacQA/PaNWvZspgRJf2AXvNbMSs2UQODr7Tbv+Fb4
+ # lyblmMUNYFMCFVAMU0eIxXAFq2qcwv8UMcQFT0Z/35s6PVOakYnAGGQjTfp5Ljuq
+ # wsdc/xWmM0cHWube6sdRRUD7SY20KU/kWzl8iFO0VbSSrDf1AlEhnLEkp1SPaxXg
+ # OdBnl98MeoramNiJ7NT6Jnyb3zZ578fjaWfThiBpagItI8GZmG4s4Ovh2JbheN8i
+ # ZsjNr9jqHTjhyLVbDRlmJzcqoj4JhbKs6/I^invalid DO NOT USE=
+ # -----END CERTIFICATE-----
+ # -----BEGIN CERTIFICATE-----
+ # MIIDBDCCAeygAwIBAgIRALJsPg21kA0zY4F1wUCIuoMwDQYJKoZIhvcNAQELBQAw
+ # EzERMA8GA1UEChMIQXV0aGVsaWEwHhcNNzAwMTAxMDAwMDAwWhcNNzEwMTAxMDAw
+ # MDAwWjATMREwDwYDVQQKEwhBdXRoZWxpYTCCASIwDQYJKoZIhvcNAQEBBQADggEP
+ # ADCCAQoCggEBAMXHBvVxUzYk0u34/DINMSF+uiOekKOAjOrC6Mi9Ww8ytPVO7t2S
+ # zfTvM+XnEJqkFQFgimERfG/eGhjF9XIEY6LtnXe8ATvOK4nTwdufzBaoeQu3Gd50
+ # 5VXr6OHRo//ErrGvFXwP3g8xLePABsi/fkH3oDN+ztewOBMDzpd+KgTrk8ysv2ou
+ # kNRMKFZZqASvCgv0LD5KWvUCnL6wgf1oTXG7aztduA4oSkUP321GpOmBC5+5ElU7
+ # ysoRzvD12o9QJ/IfEaulIX06w9yVMo60C/h6A3U6GdkT1SiyTIqR7v7KU/IWd/Qi
+ # Lfftcj91VhCmJ73Meff2e2S2PrpjdXbG5FMCAwEAAaNTMFEwDgYDVR0PAQH/BAQD
+ # AgKkMA8GA1UdJQQIMAYGBFUdJQAwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU
+ # Z7AtA3mzFc0InSBA5fiMfeLXA3owDQYJKoZIhvcNAQELBQADggEBAEE5hm1mtlk/
+ # kviCoHH4evbpw7rxPxDftIQlqYTtvMM4eWY/6icFoSZ4fUHEWYyps8SsPu/8f2tf
+ # 71LGgZn0FdHi1QU2H8m0HHK7TFw+5Q6RLrLdSyk0PItJ71s9en7r8pX820nAFEHZ
+ # HkOSfJZ7B5hFgUDkMtVM6bardXAhoqcMk4YCU96e9d4PB4eI+xGc+mNuYvov3RbB
+ # D0s8ICyojeyPVLerz4wHjZu68Z5frAzhZ68YbzNs8j2fIBKKHkHyLG1iQyF+LJVj
+ # 2PjCP+auJsj6fQQpMGoyGtpLcSDh+ptcTngUD8JsWipzTCjmaNqdPHAOYmcgtf4b
+ # qocikt3WAdU^invalid DO NOT USE=
+ # -----END CERTIFICATE-----
+ ## The issuer_private_key is used to sign the JWT forged by OpenID Connect.
+ ## Issuer Private Key can also be set using a secret: https://www.authelia.com/c/secrets
+ # issuer_private_key: |
+ # -----BEGIN RSA PRIVATE KEY-----
+ # MIIEpAIBAAKCAQEA8q/elLI/ijMYSJUsnXh0hYUIQYSCrtZQwjRJlmpADYgPQvn1
+ # T9D9SzLLu4L2B8xTM4NOkA22Q6MVBxACzGVHUU6NUGtflCCNK9fBtCfcO3AwDtdZ
+ # KXou5jHasFhKUxI3lRlCb9HEy1d8srZvnVaAQRgMWL6cQJKorNHhHnh44+QERZF+
+ # +5j3UAyOWGmK+Dx7glaSrgtVBQpuaIVjAh0rxdCI3huVj1bBfAkVizmxD9RgzAEW
+ # LQeRY6HsYSN/GChQ49q4i55lIxKVCnvOoAff03RlJhvpxLQ2mPntChZlJjdqTzt5
+ # txE1/isK9ktvLsug3upgIrGYJoMPfHb41ilYfwIDAQABAoIBAQDTOdFf2JjHH1um
+ # aPgRAvNf9v7Nj5jytaRKs5nM6iNf46ls4QPreXnMhqSeSwj6lpNgBYxOgzC9Q+cc
+ # Y4ob/paJJPaIJTxmP8K/gyWcOQlNToL1l+eJ20eQoZm23NGr5fIsunSBwLEpTrdB
+ # ENqqtcwhW937K8Pxy/Q1nuLyU2bc6Tn/ivLozc8n27dpQWWKh8537VY7ancIaACr
+ # LJJLYxKqhQpjtBWAyCDvZQirnAOm9KnvIHaGXIswCZ4Xbsu0Y9NL+woARPyRVQvG
+ # jfxy4EmO9s1s6y7OObSukwKDSNihAKHx/VIbvVWx8g2Lv5fGOa+J2Y7o9Qurs8t5
+ # BQwMTt0BAoGBAPUw5Z32EszNepAeV3E2mPFUc5CLiqAxagZJuNDO2pKtyN29ETTR
+ # Ma4O1cWtGb6RqcNNN/Iukfkdk27Q5nC9VJSUUPYelOLc1WYOoUf6oKRzE72dkMQV
+ # R4bf6TkjD+OVR17fAfkswkGahZ5XA7j48KIQ+YC4jbnYKSxZTYyKPjH/AoGBAP1i
+ # tqXt36OVlP+y84wWqZSjMelBIVa9phDVGJmmhz3i1cMni8eLpJzWecA3pfnG6Tm9
+ # ze5M4whASleEt+M00gEvNaU9ND+z0wBfi+/DwJYIbv8PQdGrBiZFrPhTPjGQUldR
+ # lXccV2meeLZv7TagVxSi3DO6dSJfSEHyemd5j9mBAoGAX8Hv+0gOQZQCSOTAq8Nx
+ # 6dZcp9gHlNaXnMsP9eTDckOSzh636JPGvj6m+GPJSSbkURUIQ3oyokMNwFqvlNos
+ # fTaLhAOfjBZI9WnDTTQxpugWjphJ4HqbC67JC/qIiw5S6FdaEvGLEEoD4zoChywZ
+ # 9oGAn+fz2d/0/JAH/FpFPgsCgYEAp/ipZgPzziiZ9ov1wbdAQcWRj7RaWnssPFpX
+ # jXwEiXT3CgEMO4MJ4+KWIWOChrti3qFBg6i6lDyyS6Qyls7sLFbUdC7HlTcrOEMe
+ # rBoTcCI1GqZNlqWOVQ65ZIEiaI7o1vPBZo2GMQEZuq8mDKFsOMThvvTrM5cAep84
+ # n6HJR4ECgYABWcbsSnr0MKvVth/inxjbKapbZnp2HUCuw87Ie5zK2Of/tbC20wwk
+ # yKw3vrGoE3O1t1g2m2tn8UGGASeZ842jZWjIODdSi5+icysQGuULKt86h/woz2SQ
+ # 27GoE2i5mh6Yez6VAYbUuns3FcwIsMyWLq043Tu2DNkx9ijOOAuQzw^invalid..
+ # DO NOT USE==
+ # -----END RSA PRIVATE KEY-----
+ ## The lifespans configure the expiration for these token types.
+ # access_token_lifespan: 1h
+ # authorize_code_lifespan: 1m
+ # id_token_lifespan: 1h
+ # refresh_token_lifespan: 90m
+ ## Enables additional debug messages.
+ # enable_client_debug_messages: false
+ ## SECURITY NOTICE: It's not recommended changing this option and values below 8 are strongly
+discouraged.
+ # minimum_parameter_entropy: 8
+ ## SECURITY NOTICE: It's not recommended changing this option, and highly discouraged to have it set to
+'never'
+ ## for security reasons.
+ # enforce_pkce: public_clients_only
+ ## Cross-Origin Resource Sharing (CORS) settings.
+ # cors:
+ ## List of endpoints in addition to the metadata endpoints to permit cross-origin requests on.
+ # endpoints:
+ # - authorization
+ # - token
+ # - revocation
+ # - introspection
+ # - userinfo
+ ## List of allowed origins.
+ ## Any origin with https is permitted unless this option is configured or the
+ ## allowed_origins_from_client_redirect_uris option is enabled.
+ # allowed_origins:
+ # - https://example.com
+ ## Automatically adds the origin portion of all redirect URI's on all clients to the list of allowed_origins,
+ ## provided they have the scheme http or https and do not have the hostname of localhost.
+ # allowed_origins_from_client_redirect_uris: false
+ ## Clients is a list of known clients and their configuration.
+ # clients:
+ # -
+ ## The ID is the OpenID Connect ClientID which is used to link an application to a configuration.
+ # id: myapp
+ ## The description to show to users when they end up on the consent screen. Defaults to the ID above.
+ # description: My Application
+ ## The client secret is a shared secret between Authelia and the consumer of this client.
+ # secret: this_is_a_secret
+ ## Sector Identifiers are occasionally used to generate pairwise subject identifiers. In most cases this is not
+ ## necessary. Read the documentation for more information.
+ ## The subject identifier must be the host component of a URL, which is a domain name with an optional
+port.
+ # sector_identifier: example.com
+ ## Sets the client to public. This should typically not be set, please see the documentation for usage.
+ # public: false
+ ## The policy to require for this client; one_factor or two_factor.
+ # authorization_policy: two_factor
+ ## The consent mode controls how consent is obtained.
+ # consent_mode: auto
+ ## This value controls the duration a consent on this client remains remembered when the consent mode
+is
+ ## configured as 'auto' or 'pre-configured'.
+ # pre_configured_consent_duration: 1w
+ ## Audience this client is allowed to request.
+ # audience: []
+ ## Scopes this client is allowed to request.
+ # scopes:
+ # - openid
+ # - groups
+ # - email
+ # - profile
+ ## Redirect URI's specifies a list of valid case-sensitive callbacks for this client.
+ # redirect_uris:
+ # - https://oidc.example.com:8080/oauth2/callback
+ ## Grant Types configures which grants this client can obtain.
+ ## It's not recommended to define this unless you know what you're doing.
+ # grant_types:
+ # - refresh_token
+ # - authorization_code
+ ## Response Types configures which responses this client can be sent.
+ ## It's not recommended to define this unless you know what you're doing.
+ # response_types:
+ # - code
+ ## Response Modes configures which response modes this client supports.
+ # response_modes:
+ # - form_post
+ # - query
+ # - fragment
+ ## The algorithm used to sign userinfo endpoint responses for this client, either none or RS256.
+ # userinfo_signing_algorithm: none

Docs created by @ldez

+ + + + \ No newline at end of file diff --git a/.vitepress/dist/configuration/authy-duo-config.html b/.vitepress/dist/configuration/authy-duo-config.html new file mode 100644 index 0000000..7309b4e --- /dev/null +++ b/.vitepress/dist/configuration/authy-duo-config.html @@ -0,0 +1,26 @@ + + + + + + DP-Salad Configuration | DP-Salad + + + + + + + + + + + + + + + +
Skip to content

Authy/Duo Configuration ​

This is like one of those "Choose Your Own Adventure" books! Pick one, not the other, it may be hard to swap later on. You may be able to give your user a choice too! 2FA is handled by either Authelia using an 8 digit code that generates through Authy or it can be passed off to Duo to handle, and then "reinjected" back into the authentication process later on. I'll outline steps for both, and you can choose the method(s) you want your users to be able to 2FA.


Authy is probably the easiest, and the cheapest way to configure 2FA, especially if you are going to have more than 5 users.

The default for the SALA/D Stack for 2FA for the more technical people is SHA1, 8 Digits

All this means for the user is what applications are supported, list is below:

  • Bitwarden / Vaultwarden (Password Managers, Vaultwarden can be selfhosted!, 2FA is setup in addition to account)
  • Authy (Recommended application, named as the best for the stack)
  • Aegis (Supported, never used. YMMV)

These three options are supported for 2FA for Authelia . It is recommended to actually set this up, as it prevents complete lockouts.


Duo is another way to configure 2FA. If you enable Duo 2FA, you'll need to consult the documentation for Duo setup via Authelia, I've linked some setup links here.

https://www.authelia.com/configuration/second-factor/duo/

https://www.authelia.com/overview/authentication/push-notification/

You'll need to modify the configuration of Authelia to finish the setup of 2FA via Duo.

Docs created by @ldez

+ + + + \ No newline at end of file diff --git a/.vitepress/dist/configuration/lldap-config.html b/.vitepress/dist/configuration/lldap-config.html new file mode 100644 index 0000000..51d6664 --- /dev/null +++ b/.vitepress/dist/configuration/lldap-config.html @@ -0,0 +1,156 @@ + + + + + + LLDAP Configuration | DP-Salad + + + + + + + + + + + + + + + +
Skip to content

LLDAP Configuration ​

LLDAP is the Light Lightweight Directory Access Protocol, and for our purposes, it will store all the information that we have on our users, like usernames, emails, and hashed passwords. These are the typical values, and only a few more exist in this light implementation of LDAP. I include a sample config file if you don't want to set values in the Docker Compose file.

As with the Authelia Configuration, please change things in square brackets to your relevant values. This file uses REPLACE_WITH to tell you where to replace other such values like secrets/tokens.

yaml
## Default configuration for Docker.
+## All the values can be overridden through environment variables, prefixed
+## with "LLDAP_". For instance, "ldap_port" can be overridden with the
+## "LLDAP_LDAP_PORT" variable.
+## Tune the logging to be more verbose by setting this to be true.
+## You can set it with the LLDAP_VERBOSE environment variable.
+# verbose=false
+## The host address that the LDAP server will be bound to.
+## To enable IPv6 support, simply switch "ldap_host" to "::":
+## To only allow connections from localhost (if you want to restrict to local self-hosted services),
+## change it to "127.0.0.1" ("::1" in case of IPv6)".
+ldap_host = "0.0.0.0"
+## The port on which to have the LDAP server.
+ldap_port = 3890
+## The host address that the HTTP server will be bound to.
+## To enable IPv6 support, simply switch "http_host" to "::".
+## To only allow connections from localhost (if you want to restrict to local self-hosted services),
+## change it to "127.0.0.1" ("::1" in case of IPv6)".
+http_host = "0.0.0.0"
+## The port on which to have the HTTP server, for user login and
+## administration.
+http_port = 17170
+## The public URL of the server, for password reset links.
+#http_url = "http://localhost"
+## Random secret for JWT signature.
+## This secret should be random, and should be shared with application
+## servers that need to consume the JWTs.
+## Changing this secret will invalidate all user sessions and require
+## them to re-login.
+## You should probably set it through the LLDAP_JWT_SECRET environment
+## variable from a secret ".env" file.
+## This can also be set from a file's contents by specifying the file path
+## in the LLDAP_JWT_SECRET_FILE environment variable
+## You can generate it with (on linux):
+## LC_ALL=C tr -dc 'A-Za-z0-9!#%&'\''()*+,-./:;<=>?@[\]^_{|}~' </dev/urandom | head -c 32; echo ''
+jwt_secret = "REPLACE_WITH_RANDOM"
+## Base DN for LDAP.
+## This is usually your domain name, and is used as a
+## namespace for your users. The choice is arbitrary, but will be needed
+## to configure the LDAP integration with other services.
+## The sample value is for "example.com", but you can extend it with as
+## many "dc" as you want, and you don't actually need to own the domain
+## name.
+ldap_base_dn = "dc=[DOMAIN],dc=[TLD]"
+## Admin username.
+## For the LDAP interface, a value of "admin" here will create the LDAP
+## user "cn=admin,ou=people,dc=example,dc=com" (with the base DN above).
+## For the administration interface, this is the username.
+ldap_user_dn = "admin"
+## Admin email.
+## Email for the admin account. It is only used when initially creating
+## the admin user, and can safely be omitted.
+ldap_user_email = "admin@[DOMAIN.TLD]"
+## Admin password.
+## Password for the admin account, both for the LDAP bind and for the
+## administration interface. It is only used when initially creating
+## the admin user.
+## It should be minimum 8 characters long.
+## You can set it with the LLDAP_LDAP_USER_PASS environment variable.
+## This can also be set from a file's contents by specifying the file path
+## in the LLDAP_LDAP_USER_PASS_FILE environment variable
+## Note: you can create another admin user for user administration, this
+## is just the default one.
+ldap_user_pass = "REPLACE_WITH_PASSWORD"
+## Database URL.
+## This encodes the type of database (SQlite, MySQL, or PostgreSQL)
+## , the path, the user, password, and sometimes the mode (when
+## relevant).
+## Note: SQlite should come with "?mode=rwc" to create the DB
+## if not present.
+## Example URLs:
+## - "postgres://postgres-user:password@postgres-server/my-database"
+## - "mysql://mysql-user:password@mysql-server/my-database"
+##
+## This can be overridden with the LLDAP_DATABASE_URL env variable.
+database_url = "sqlite:///data/users.db?mode=rwc"
+## Private key file.
+## Contains the secret private key used to store the passwords safely.
+## Note that even with a database dump and the private key, an attacker
+## would still have to perform an (expensive) brute force attack to find
+## each password.
+## Randomly generated on first run if it doesn't exist.
+## Alternatively, you can use key_seed to override this instead of relying on
+## a file.
+## Env variable: LLDAP_KEY_FILE
+key_file = "/data/private_key"
+## Seed to generate the server private key, see key_file above.
+## This can be any random string, the recommendation is that it's at least 12
+## characters long.
+## Env variable: LLDAP_KEY_SEED
+#key_seed = "RanD0m STR1ng"
+## Ignored attributes.
+## Some services will request attributes that are not present in LLDAP. When it
+## is the case, LLDAP will warn about the attribute being unknown. If you want
+## to ignore the attribute and the service works without, you can add it to this
+## list to silence the warning.
+#ignored_user_attributes = [ "sAMAccountName" ]
+#ignored_group_attributes = [ "mail", "userPrincipalName" ]
+## Options to configure SMTP parameters, to send password reset emails.
+## To set these options from environment variables, use the following format
+## (example with "password"): LLDAP_SMTP_OPTIONS__PASSWORD
+[smtp_options]
+## Whether to enabled password reset via email, from LLDAP.
+#enable_password_reset=true
+## The SMTP server.
+#server="smtp.gmail.com"
+## The SMTP port.
+#port=587
+## How the connection is encrypted, either "NONE" (no encryption), "TLS" or "STARTTLS".
+#smtp_encryption = "TLS"
+## The SMTP user, usually your email address.
+#user="sender@gmail.com"
+## The SMTP password.
+#password="password"
+## The header field, optional: how the sender appears in the email. The first
+## is a free-form name, followed by an email between <>.
+#from="LLDAP Admin <sender@gmail.com>"
+## Same for reply-to, optional.
+#reply_to="Do not reply <noreply@localhost>"
+## Options to configure LDAPS.
+## To set these options from environment variables, use the following format
+## (example with "port"): LLDAP_LDAPS_OPTIONS__PORT
+[ldaps_options]
+## Whether to enable LDAPS.
+#enabled=true
+## Port on which to listen.
+#port=6360
+## Certificate file.
+#cert_file="/data/cert.pem"
+## Certificate key file.
+#key_file="/data/key.pem"

Docs created by @ldez

+ + + + \ No newline at end of file diff --git a/.vitepress/dist/configuration/swag-config.html b/.vitepress/dist/configuration/swag-config.html new file mode 100644 index 0000000..85c9a00 --- /dev/null +++ b/.vitepress/dist/configuration/swag-config.html @@ -0,0 +1,26 @@ + + + + + + Swag Config | DP-Salad + + + + + + + + + + + + + + + +
Skip to content

SWAG Configuration ​

Configuring the Secure Web Application Gateway has a lot of options and potential. It is primarily used to have one gateway for all your services hosted through two ports. Assuming you've used the Docker Compose file, you should be able to view and edit all the configuration files through /home/[USER]/appdata/swag. This location now has multiple places you can go.

  1. /home/[USER]/appdata/swag/nginx - This holds all of the webserver configuration files, this is where you will go when adding a new application/service.
    • /home/[USER]/appdata/swag/nginx/proxy-confs - This is where all the reverse proxy magic happens, and will likely be the most used folder.
    • /home/[USER]/appdata/swag/nginx/site-confs - If you want to host a static site using SWAG, this is the conf file that you will modify to make it function.

TIP

Highly recommend learning how NGINX conf files work.

  • The files in this nginx directory are all usually not touched, but used for the rest of configuration to connect Authelia to SWAG for logins.
  1. /home/[USER]/appdata/swag/etc/letsencrypt - This holds all the relevant data for your SSL certificates using Let's Encrypt . The current certificates are in the "live" folder, under the domain name folder.
  2. /home/[USER]/appdata/swag/dns-conf - This holds the API keys or access information in order for SWAG to setup Let's Encrypt certificates or other DNS information. There are many providers available, however, Cloudflare will most likely be used. In order for a SSL Certificate to be issued, you will have to set this up.
  3. /home/[USER]/appdata/swag/www - This folder holds all of the static site stuff, if you decide to make a static site, you can host it through SWAG's configurations. This does take some patience, as getting the stuff exactly right is a bit tricky.

See How do I add a new application to my stack? for more information as to how to use the SWAG proxy-confs folder to add a new application to your hosting repertoire.

Docs created by @ldez

+ + + + \ No newline at end of file diff --git a/.vitepress/dist/docker-compose-dpsalad.rtf b/.vitepress/dist/docker-compose-dpsalad.rtf new file mode 100644 index 0000000..25df609 --- /dev/null +++ b/.vitepress/dist/docker-compose-dpsalad.rtf @@ -0,0 +1,95 @@ +version: "2.1" +services: + swag: + image: lscr.io/linuxserver/swag:latest + container_name: swag + cap_add: + - NET_ADMIN + environment: + - PUID=1000 + - PGID=1000 + - TZ=America/Phoenix + - URL=[sakura.nt] + - VALIDATION=dns + - SUBDOMAINS=wildcard + - DNSPLUGIN=cloudflare + - EMAIL=[sakurant@gmail.com] + - ONLY_SUBDOMAINS=false + #- EXTRA_DOMAINS= #optional + - STAGING=false + - DOCKER_MODS=linuxserver/mods:universal-docker|linuxserver/mods:swag-auto-reload|linuxserver/mods:swag-dashboard|linuxserver/mods:swag-dbip + volumes: + - /home/[INSERT USER FOLDER HERE]/appdata/swag:/config + ports: + - 443:443 + - 80:80 + networks: + - [INSERT NETWORK NAME HERE] + restart: unless-stopped + + authelia: + container_name: authelia + image: authelia/authelia:latest + expose: + - 9091 + volumes: + - /home/[INSERT USER FOLDER HERE]/appdata/authelia:/config + networks: + - [INSERT NETWORK NAME HERE] + restart: unless-stopped + depends_on: + - redis + - mariadb + + lldap: + container_name: lldap + image: lldap/lldap:stable + ports: + # For LDAP + - "3890:3890" + # For the web front-end + - "17170:17170" + volumes: + - /home/[INSERT USER FOLDER HERE]/appdata/lldap:/data + networks: + - [INSERT NETWORK NAME HERE] + environment: + - TZ=America/Phoenix + - LLDAP_JWT_SECRET=REPLACE_WITH_RANDOM + - LLDAP_LDAP_USER_PASS=REPLACE_WITH_PASSWORD + - LLDAP_LDAP_BASE_DN=dc=sakura,dc=nt + + redis: + container_name: redis + image: bitnami/redis:latest + expose: + - 6379 + volumes: + - /home/[INSERT USER FOLDER HERE]/appdata/redis:/bitnami/ + environment: + REDIS_PASSWORD: "YOUR_REDIS_PASSWORD" + networks: + - [INSERT NETWORK NAME HERE] + restart: unless-stopped + + mariadb: + container_name: mariadb + image: linuxserver/mariadb:latest + expose: + - 3306 + volumes: + - /home/[INSERT USER FOLDER HERE]/appdata/mariadb:/config + environment: + MYSQL_ROOT_PASSWORD: "YOUR_MYSQL_ROOT_PASSWORD" + MYSQL_ROOT_USER: root + MYSQL_DATABASE: authelia + MYSQL_USER: authelia + MYSQL_PASSWORD: "YOUR_MYSQL_USER_PASSWORD" + networks: + - [INSERT NETWORK NAME HERE] + restart: unless-stopped + +networks: + [INSERT NETWORK NAME HERE]: + driver: bridge + external: true diff --git a/.vitepress/dist/docker-compose.html b/.vitepress/dist/docker-compose.html new file mode 100644 index 0000000..2a90b75 --- /dev/null +++ b/.vitepress/dist/docker-compose.html @@ -0,0 +1,120 @@ + + + + + + One File Docker Compose (One File to Rule them all!) | DP-Salad + + + + + + + + + + + + + + + +
Skip to content

One File Docker Compose (One File to Rule them all!) ​

This is the Docker Compose file used for the VM Template, and can be used as a custom template in Portainer. The custom network listed under "Networks" is used for all the applications that you want to connect through the stack. Please replace the ALL_CAPS_PORTIONS and the pieces in square brackets. These are values that you will want to set yourself.

TIP

For things like passwords and such, I'd recommend a 26 character random string, using alphanumeric characters in both upper and lower case. These values are crucial that they remain both secret and lengthy.

These values are crucial that they remain both secret and lengthy. You should not need to change these, and some of them will break the application if you try to change them. I'd recommend that you backup your compose file to the cloud in case you need to redo the setup.

yml
version: "2.1"
+services:
+  swag:
+    image: lscr.io/linuxserver/swag:latest
+    container_name: swag
+    cap_add:
+      - NET_ADMIN
+    environment:
+      - PUID=1000
+      - PGID=1000
+      - TZ=America/Phoenix
+      - URL=[sakura.nt]
+      - VALIDATION=dns
+      - SUBDOMAINS=wildcard
+      - DNSPLUGIN=cloudflare
+      - EMAIL=[sakurant@gmail.com]
+      - ONLY_SUBDOMAINS=false
+      #- EXTRA_DOMAINS= #optional
+      - STAGING=false
+      - DOCKER_MODS=linuxserver/mods:universal-docker|linuxserver/mods:swag-auto-reload|linuxserver/mods:swag-dashboard|linuxserver/mods:swag-dbip
+    volumes:
+      - /home/[INSERT USER FOLDER HERE]/appdata/swag:/config
+    ports:
+      - 443:443
+      - 80:80
+    networks:
+      - [INSERT NETWORK NAME HERE]
+    restart: unless-stopped
+
+  authelia:
+    container_name: authelia
+    image: authelia/authelia:latest
+    expose:
+      - 9091
+    volumes:
+      - /home/[INSERT USER FOLDER HERE]/appdata/authelia:/config
+    networks:
+      - [INSERT NETWORK NAME HERE]
+    restart: unless-stopped
+    depends_on:
+      - redis
+      - mariadb
+
+  lldap:
+    container_name: lldap
+    image: lldap/lldap:stable
+    ports:
+      # For LDAP
+      - "3890:3890"
+      # For the web front-end
+      - "17170:17170"
+    volumes:
+      - /home/[INSERT USER FOLDER HERE]/appdata/lldap:/data
+    networks:
+      - [INSERT NETWORK NAME HERE]
+    environment:
+      - TZ=America/Phoenix
+      - LLDAP_JWT_SECRET=REPLACE_WITH_RANDOM
+      - LLDAP_LDAP_USER_PASS=REPLACE_WITH_PASSWORD
+      - LLDAP_LDAP_BASE_DN=dc=sakura,dc=nt
+
+  redis:
+    container_name: redis
+    image: bitnami/redis:latest
+    expose:
+      - 6379
+    volumes:
+      - /home/[INSERT USER FOLDER HERE]/appdata/redis:/bitnami/
+    environment:
+      REDIS_PASSWORD: "YOUR_REDIS_PASSWORD"
+    networks:
+      - [INSERT NETWORK NAME HERE]
+    restart: unless-stopped
+
+  mariadb:
+    container_name: mysql
+    image: linuxserver/mariadb:latest
+    expose:
+      - 3306
+    volumes:
+      - /home/[INSERT USER FOLDER HERE]/appdata/mariadb:/config
+    environment:
+      MYSQL_ROOT_PASSWORD: "YOUR_MYSQL_ROOT_PASSWORD"
+      MYSQL_ROOT_USER: root
+      MYSQL_DATABASE: authelia
+      MYSQL_USER: authelia
+      MYSQL_PASSWORD: "YOUR_MYSQL_USER_PASSWORD"
+    networks:
+      - [INSERT NETWORK NAME HERE]
+    restart: unless-stopped
+
+networks:
+  [INSERT NETWORK NAME HERE]:
+    driver: bridge
+    external: true

Docs created by @ldez

+ + + + \ No newline at end of file diff --git a/.vitepress/dist/dp-salad-stack.pdf b/.vitepress/dist/dp-salad-stack.pdf new file mode 100644 index 0000000..149ec00 Binary files /dev/null and b/.vitepress/dist/dp-salad-stack.pdf differ diff --git a/.vitepress/dist/faq.html b/.vitepress/dist/faq.html new file mode 100644 index 0000000..e69c3ea --- /dev/null +++ b/.vitepress/dist/faq.html @@ -0,0 +1,74 @@ + + + + + + FAQ | DP-Salad + + + + + + + + + + + + + + + +
Skip to content

Frequently Asked Questions ​

How do I [Insert Question Here]? ​

Quick Q&A for common problems/questions about the DP-SALA/D Stack

How do I add a new application to my stack? ​

You have two options:

  1. You can check SWAG's proxy confs folder for the application you are trying to add in it's configuration folder.

    • You will use the following command: mv /home/[USER]/appdata/swag/nginx/proxy-confs/[application].sub[domain/folder].conf.sample /home/[USER]/appdata/swag/nginx/proxy-confs/[application].sub[domain/folder].conf
    • Install the application into your docker network (keep track of the internal port that it uses)
    • Then nano into the .conf nano /home/[USER]/appdata/swag/nginx/proxy-confs/[application].sub[domain/folder].conf
    1. If you are using a subdomain configuration:
      • You can change the server_name directive to the path you want to use as a subdomain (make sure you leave the .*)
      • The $upstream_app should match the docker container name
      • The $upstream_port should match the docker internal port
      • Everything else can be left unchanged
    2. If you are using a subfolder configuration:
      • The $location directive can be changed after the / to the path you want to use as a subfolder (make sure to leave the ^~)
      • The $upstream_app should match the docker container name
      • The $upstream_port should match the docker internal port

TIP

If you have the auto-reload docker mod, SWAG will automatically reload the changes, and display them. Otherwise, SWAG will have to be manually reloaded to see the changes.

  1. If there isn't a premade template, you can DIY your own using the _template.sub[domain/folder].conf.sample.
  • You will use the following command: cp /home/[USER]/appdata/swag/nginx/proxy-confs/_template.sub[domain/folder].conf.sample /home/[USER]/appdata/swag/nginx/proxy-confs/[application].sub[domain/folder].conf

  • Install the application into your docker network (keep track of the internal port that it uses)

  • Then nano into the .conf nano /home/[USER]/appdata/swag/nginx/proxy-confs/[application].sub[domain/folder].conf

    1. If you are using a subdomain template:
      • You'll want to modify anything with <> make sure to remove the <> when you are done.
    2. If you are using a subfolder template:
      • You'll want to modify anything with <> make sure to remove the <> when you are done.
  • Which ever way you decide to do, once you have made the changes, save and exit.

THIS IS IMPORTANT!!!

You'll want to verify that the $upstream_app, $port and $protocal are correct, otherwise you will keep getting 502 errors when trying to visit them. The web path/container_name doesn't really matter, you can name it whatever.

TIP

Most of the time, the template will work out-of-the-box with all of the changes. However, you may run into an application that requrires more configuration to run behind a reverse proxy. You will have to consult the application's documentation to find settings that will let it run behind a reverse proxy. SWAG uses NGINX as it's base, so most NGINX configurations can be used to have it run behind a reverse proxy.

WARNING

If you decide to proxy something externally to docker, this comes with the caveat that the $upstream_app must be an IP address (preferably static), and the $upstream_port must be an external port that the application is listening on. Failing to do so, will result in a 502 Bad Gateway error.

How do I add LLDAP Authentication to [SERVICE]? ​

First, check to see if LDAP authentication is supported by the application that you are trying to add. Some services/applications either don't support LDAP auth out of the box, or there is some plugin/addon to add for LDAP auth to function. Do a quick Google search to see if LDAP auth is supported, and if it requires a secure connection. Canvas in particular requires LDAPS (LDAP over SSL) and will not function unless configured correctly.

Second, if the app supports LDAP Auth, it usually requires a dedicated user to manage the application, usually called a "Bind User" which you will setup in LLDAP. Try to pick a username that will be descriptive for the service it will bind to. The password that is used should be lengthy and mixtures of characters. The next required parts are the "configuration" parts, which are detailed below:

  • User DN/Bind User/User: "cn=[USER],ou=people,dc=[DOMAIN],dc=[TLD]"
  • Base/User Search Base: "ou=people,dc=[DOMAIN],dc=[TLD]"
  • User Filter(no grouping, UID access): (&(uid={username})(objectClass=person)(ou=people,dc=[DOMAIN],dc=[TLD]))
  • User Filter(group access, UID or Email access): (&(objectClass=person)(memberof=cn=[GROUP NAME],ou=groups,dc=[DOMAIN],dc=[TLD])(|(uid={username})(mail={username})))
  • User Filter(group access, UID access): (&(objectClass=person)(memberof=cn=[GROUP NAME],ou=groups,dc=[DOMAIN],dc=[TLD]))
  • Admin Filter(group access): (memberof=cn=[GROUP NAME]_administrator,ou=groups,dc=[DOMAIN],dc=[TLD])

These are some typical settings, however, depending on the service or app, there may be an example configuration out there, for example, Authelia for LLDAP has an example config: https://github.com/lldap/lldap/blob/main/example_configs/authelia_config.yml

yml
###############################################################
+#                   Authelia configuration                    #
+###############################################################
+
+# This is just the LDAP part of the Authelia configuration!
+
+
+authentication_backend:
+  # Password reset through authelia works normally.
+  password_reset:
+    disable: false
+  # How often authelia should check if there is an user update in LDAP
+  refresh_interval: 1m
+  ldap:
+    implementation: custom
+    # Pattern is ldap://HOSTNAME-OR-IP:PORT
+    # Normal ldap port is 389, standard in LLDAP is 3890
+    url: ldap://lldap:3890
+    # The dial timeout for LDAP.
+    timeout: 5s
+    # Use StartTLS with the LDAP connection, TLS not supported right now
+    start_tls: false
+    #tls:
+    #  skip_verify: false
+    #  minimum_version: TLS1.2
+    # Set base dn, like dc=google,dc.com
+    base_dn: dc=example,dc=com
+    username_attribute: uid
+    # You need to set this to ou=people, because all users are stored in this ou!
+    additional_users_dn: ou=people
+    # To allow sign in both with username and email, one can use a filter like
+    # (&(|({username_attribute}={input})({mail_attribute}={input}))(objectClass=person))
+    users_filter: "(&({username_attribute}={input})(objectClass=person))"
+    # Set this to ou=groups, because all groups are stored in this ou
+    additional_groups_dn: ou=groups
+    # The groups are not displayed in the UI, but this filter works.
+    groups_filter: "(member={dn})"
+    # The attribute holding the name of the group.
+    group_name_attribute: cn
+    # Email attribute
+    mail_attribute: mail
+    # The attribute holding the display name of the user. This will be used to greet an authenticated user.
+    display_name_attribute: displayName
+    # The username and password of the bind user.
+    # "bind_user" should be the username you created for authentication with the "lldap_strict_readonly" permission. It is not recommended to use an actual admin account here.
+    # If you are configuring Authelia to change user passwords, then the account used here needs the "lldap_password_manager" permission instead.
+    user: uid=bind_user,ou=people,dc=example,dc=com
+    # Password can also be set using a secret: https://www.authelia.com/docs/configuration/secrets.html
+    password: 'REPLACE_ME'

Here is a list of the attributes that you can use: uid (username), mail (email address), cn (this could be a username, or a full name be careful), and displayName (usually the full name of the user).

Not all of these are good for use cases, however, the most commonly used ones are going to be uid and email.

If this didn't cover what was needed for adding LDAP auth connectivity to your service, consult Google, or the LLDAP GitHub Example Configs, linked here: https://github.com/lldap/lldap/tree/main/example_configs which should give you a good starting point to see how to configure the LDAP authentication for your service.

Here is my recommendation to how user management works:

  1. Setup dedicated groups that match the application/service name, add all users who use that to the group.
  2. Filter the user based on the group, if they are in that group, they have permission to access the application.

How do I handle user creation? ​

Once the stack is all setup, you may want to add users . I outline my way of handling user creation and management, but you may do this anyway you like, I've done it this way given the constraints of how I host, and handle having users access some or all of my services that I host.

User Creation:

  1. Ask for the user's email address, full name, and if they would like something different for their display name.
  2. Using their full name, I create a username. Say if the user was named: Alice Example, their username would be aexa. If I already had a duplicate of the username, I'd append a number, starting at 0.
  3. I would create a temporary password for the user, and then have them go to auth.domain.tld to then "Forgot Password" so that they can setup a password themselves, and have it conform to my password standards I have set.
  4. I then go to the user page, and add them to their respective groups to let them have access to the services.
  5. I'd let the user know that some apps will take a bit to pull their information, while some create their profile on sign in. This is completely normal, and give it up to 24 hours for changes to fully propagate through the system.

This is one way of doing it, but I do have a standard, which I hold to the highest degree. This is important, as it does make finding the user just a little easier when trying to figure out what goes wrong.

Docs created by @ldez

+ + + + \ No newline at end of file diff --git a/.vitepress/dist/hashmap.json b/.vitepress/dist/hashmap.json new file mode 100644 index 0000000..94ea2bb --- /dev/null +++ b/.vitepress/dist/hashmap.json @@ -0,0 +1 @@ +{"cf-tunnel.md":"DCFtN7s5","changelog.md":"DF8BSN3_","configuration_auth-config.md":"CWCNki4x","configuration_authy-duo-config.md":"Czz1BBMP","configuration_lldap-config.md":"r20NA1Ia","configuration_swag-config.md":"DsoCqRQq","docker-compose.md":"CiAGvlkZ","faq.md":"By3ovNs1","home.md":"DWjC1jWa","index.md":"DDpI40D1","install_dp-config.md":"Cllv2ZYA","install_dp-setup.md":"Bx00pjFf","install_requirements.md":"DnNTxVlB","install_salad-setup.md":"uqD3xfuF","maintenance_maintain-guide.md":"DC42-hYW","x11-guide.md":"BPhK1sNP"} diff --git a/.vitepress/dist/home.html b/.vitepress/dist/home.html new file mode 100644 index 0000000..2513f5c --- /dev/null +++ b/.vitepress/dist/home.html @@ -0,0 +1,26 @@ + + + + + + Legacy Instructions | DP-Salad + + + + + + + + + + + + + + + +
Skip to content

Welcome! ​

This is page to be when looking to deploy the DP-Salad stack! If you need to see if your system fits the DP-Salad stack requirements, you can find the page you're looking for here: DP-Salad Requirements.

Otherwise, down below are the Legacy Instructions for the DP-Salad stack, they do have bad formatting so we do not suggest using them in a public deployment. You can also find the legacy instructions on this website.

The main instructions can be found on the DP-Setup page, and are the instructions you will use to deploy the stack.

Otherwise, feel free to poke about the documentation!

Legacy Instructions: ​

WARNING

Do not use these instructions as they have poor formatting and will lead to a bad stack deployment

PDF instructions for the DP-SALA/D Stack: DP-SALAD_STACK.pdf (Updated 10/11/2023, 12:03PM)

Docker Compose file for the DP-SALA/D Stack: docker-compose-dpsalad.rtf (Updated 10/13/2023, 11:03PM)

TIP

Download the docker compose file, rename to docker-compose.yml for best results.

OVA/VM Template for DP-SALA/D Stack: DP-SALA/D OVA Template

Authelia Example Configuration File: configuration.yml (Updated 10/12/2023, 8:32PM)

TIP

Remove RTF extension before using in actual deployment

LLDAP Example Configuration File: lldap_config.toml (Updated 10/12/2023, 8:38PM)

TIP

Remove RTF extension before using, however, this file is not always needed.

SWAG Example file locations are detailed in the Guidebook to the DP-SALA/D Stack

Docs created by @ldez

+ + + + \ No newline at end of file diff --git a/.vitepress/dist/index.html b/.vitepress/dist/index.html new file mode 100644 index 0000000..9d6f86e --- /dev/null +++ b/.vitepress/dist/index.html @@ -0,0 +1,26 @@ + + + + + + DP-Salad + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.vitepress/dist/install/dp-config.html b/.vitepress/dist/install/dp-config.html new file mode 100644 index 0000000..29b1a12 --- /dev/null +++ b/.vitepress/dist/install/dp-config.html @@ -0,0 +1,26 @@ + + + + + + DP-Salad Configuration | DP-Salad + + + + + + + + + + + + + + + +
Skip to content

Configuration ​

Debian Configuration ​

Sudo should have been setup after the install, however, nothing much else is required for the setup end in Debian. If you want, here is a list of recommended software to install to make the commandline a little easier to learn:

  1. TLDR
sh
sudo apt-get install tldr, tldr -u
  1. Tmux
sh
sudo apt-get install tmux

Portainer Configuration ​

Portainer is ready right out of the box. There should be nothing you need to do to configure it, unless you are running a "clustered setup" involving more than one computer, which can be done for this stack, but does add a layer of complexity, and allows for scalability for the amount of applications you can offer to either yourself or your users. A "clustered setup" is on the Portainer CE wiki and is out of the scope for this guide.

If you are using the VM Template, Portainer has the custom templates loaded so that if you need to install a newer version, or change something and restart, they are there.

App Templates ​

In Portainer, App Templates enable you to easily deploy services with a predetermined configuration, while allowing you to customize options through the web UI. While Portainer ships with some default templates (see portainer/templates), it's often helpful to have 1-click access to many more apps + stacks, without having to constantly switch template sources.

Under Settings → App Templates in your Portainer GUI, paste this URL:

sh
https://raw.githubusercontent.com/Lissy93/portainer-templates/main/templates.json

Docs created by @ldez

+ + + + \ No newline at end of file diff --git a/.vitepress/dist/install/dp-setup.html b/.vitepress/dist/install/dp-setup.html new file mode 100644 index 0000000..34f83e3 --- /dev/null +++ b/.vitepress/dist/install/dp-setup.html @@ -0,0 +1,37 @@ + + + + + + DP-Salad Setup | DP-Salad + + + + + + + + + + + + + + + +
Skip to content

DP-Setup ​

This guide demonstrates the installing of the DP-Salad stack:

Debian 12 Setup ​

Visit Debian's download page to get the latest version of Debian, as of this writing, Debian 12.5.0 is the latest. This is a netinst, meaning that it will require an internet connection to download the OS files.

Load your Debian ISO onto a USB stick, either directly, or using Rufus/Balena Etcher to write the ISO to stick.

Plug it into whatever is becoming your server, and boot to the USB stick in your system's BIOS.

Install Debian using the ISO. Make sure that you are connected to the internet before trying to install Debian.

  1. Select Graphical Installer
  2. Follow the setup process up until hostname, and put in something that you will recognize when port-forwarding or tunneling.
  3. Put in the domain name that you have leased as your domain name, like: "example.com"
  4. Setup a root password. (Template uses DPSALADSTACK)
  5. Setup the name for the first non-admin user. (Template uses dpsalad)
  6. Setup a password for the non-admin user. (Template uses DPSALADSTACKUSER)
  7. Continue the setup, and select "Guided - use entire disk" when Partitioning Disk, continue and use "All files in one partition" as the partitioning scheme.
  8. Allow changes to be written to disk.
  9. Continue with the installer until Software Selection. See the following points for the selections.
    • Debian desktop environment (keep selected)
    • GNOME (deselect)
    • xfce (select)
    • SSH server (select)
    • standard system utilities (keep selected)
  10. Continue with the installer until the reboot.
  11. Once the reboot is complete, you should have a fully working Debian system!
  12. If you used the template, please change the password of both the root and regular user using passwd.

Sudo no worky ​

Debian had you set up a root password, but when you try using sudo, it will not let you do anything. Debian by default does not let the first user have sudo access. See why here: Reason. You will have to temporarily log in as root to fix this. Use the following commands/instructions to add your user to the sudoers file.

markdown
1. su -
+2. nano /etc/sudoers
+3. Add the following to the file(no quotes): "username ALL=(ALL:ALL) ALL"
+4. Exit nano using Ctrl+X and then type 'Y' and enter.
+5. Restart your PC.
+6. systemctl reboot

Once your machine restarts, you should now be able to use the sudo command.

Disabling GUI ​

If you'd like to disable the GUI and work in CLI only (highly recommended, as GUI uses more resources), follow these instructions:

markdown
1. sudo systemctl set-default multi-user.target
+2. sudo reboot

Updating your system ​

Now time to run updates, just to guarantee the system is up-to-date. Debian uses APT as it's package manager of choice. Run these commands:

markdown
1. sudo apt-get update
+2. sudo apt-get upgrade

And now, your system is up-to-date!

Installing the Docker ​

Next, install Docker. Follow the following instructions to install Docker:

sh
sudo apt-get update
sh
sudo apt-get install ca-certificates curl gnupg
sh
sudo install -m 755 -d /etc/apt/keyrings
sh
curl -fsSL https://download.docker.com/linux/debian/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sh
sudo chmod a+r /etc/apt/keyrings/docker.gpg
sh
echo \
+  "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/debian \
+  $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
+  sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sh
sudo apt-get update
sh
sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin dockercompose-plugin

Once this is done, you are able to move on to the next section of this guide

DANGER

If you use anything other than the netinst for Debian, your apt sources may be invalid. Should this be the case, there is an example of the sources needed in /usr/share/doc/apt/examples/sources.list. Use the following command to copy this list of default sources to restore apt to working order. sudo cp /usr/share/doc/apt/examples/sources.list /etc/apt/sources.list

Portainer CE Setup ​

Time to setup Portainer, which is installed using Docker. Follow the below instructions to install Portainer onto your machine.

sh
sudo docker volume create portainer_data
sh
sudo docker run -d -p 8000:8000 -p 9443:9443 --name portainer --restart=always -v /var/run/docker.sock:/var/run/docker.sock -v portainer_data:/data portainer/portainer-ce:latest
  • Visit https://[ip-address]:9443 to log into Portainer CE.

  • Change the admin username if you wish. (Don't forget it if you change it though!) [Template uses DPSALADSTACK]

  • Use a good secure password (12+ characters) for the administrator password. (Don't forget this either!)

  • Click "Getting Started" to finish setting up Portainer CE.

  • If you are going to use the one-click Compose Install, make sure to create a network using the following command:

sh
sudo docker network create [INSERT NETWORK NAME HERE]

TIP

Make sure to remove the square brackets around the network name.

Some changes need to be made ​

Do note that some changes need to be made before the stack installation is finished. These two commands need to be ran to make sure Redis can be deployed for the stack to function correctly.

sh
mkdir -p /home/[USER]/appdata/redis/redis/ 
+mkdir -p /home/[USER]/appdata/redis/redis/data/

That's it! You have successfully installed Debian and Portainer!

Docs created by @ldez

+ + + + \ No newline at end of file diff --git a/.vitepress/dist/install/requirements.html b/.vitepress/dist/install/requirements.html new file mode 100644 index 0000000..dd092c6 --- /dev/null +++ b/.vitepress/dist/install/requirements.html @@ -0,0 +1,26 @@ + + + + + + DP-Salad Minimum Requirements | DP-Salad + + + + + + + + + + + + + + + +
Skip to content

DP-SALA/D Stack (pronounced as DP-Salad but stylized as DP-SALA/D) ​

Where does the acronym originate from? ​

It comes from:

  • Debian 12
  • Portainer
  • SWAG
  • Authelia
  • LLDAP
  • Authy/Duo /

Hence, DP-Salad.

As such, this updates with new configuration and such when needed.

Minimum Requirements for the DP-SALA/D Stack: ​

A DP-SALA/D Stack is rather lightweight in comparison to other stacks out there, like the very similar Unraid-SALA/D stack( + ).

This is a compilation of the minimum specs for each part of the stack.

Debian 12 ​

  • 1GHz Processor from 2010 or later
  • 2 GB RAM
  • 10 GB Storage

Portainer ​

  • 1GHz Processor from 2010 or later
  • 2 GB RAM
  • 20 GB Storage

SWAG ​

  • 1GHz Processor from 2010 or later
  • RAM requirement depends on expected requests, 4 GB recommended.
  • 10 GB Storage

Authelia ​

  • Requires that a REDIS server is setup in addition to whatever else.

Authy/Duo ​

  • Authy:

    • Hooks into Authelia for 2FA aaS, only requires a bit of setup.
  • Duo:

    • Hooks into Authelia for 2FA aaS, however, free tier can have max 10 users, but setup is a little easier on the user/admin.

Overall Minimum: ​

  • Most Processors within the last 5 years should work well enough.
  • 4 GB RAM minimum, although 2 GB can be gotten away with.
  • 30 GB Storage minimum, especially if you plan to reverse proxy some apps.
  • Basic command line knowledge.

What this guide assumes: ​

This guide assumes that you have basic computing knowledge, including how to boot your computer into an OS from a USB stick, having a domain through a registrar, and have a Gmail address for sending email to your potential users.

If you do not have a domain, my recommendation (at the time of writing) is to go through Porkbun or Cloudflare . These are the two most reputable registrars that do not markup pricing for renewing the domain you are leasing.

I also recommend that you set up a Gmail address specifically for the purpose of this stack, as Authelia will require a way to let their users password reset, as well as setup 2FA for themselves.

You may also use iCloud+'s custom domain email, however, this guide will not cover this setup, and you will have to do some research on sending email through iCloud if you choose to go this route, and you will have to find the proper settings before configuring Authelia.

Docs created by @ldez

+ + + + \ No newline at end of file diff --git a/.vitepress/dist/install/salad-setup.html b/.vitepress/dist/install/salad-setup.html new file mode 100644 index 0000000..18060c1 --- /dev/null +++ b/.vitepress/dist/install/salad-setup.html @@ -0,0 +1,26 @@ + + + + + + Salad Setup | DP-Salad + + + + + + + + + + + + + + + +
Skip to content

SALA/D Setup ​

Instructions to set up the SALA/D Part of the stack.

Overview of the SALA/D Stack: ​

The SALA/D stack, or SWAG, Authelia, LLDAP, Authy/Duo stack is a simple way to get a webserver/reverse proxy, an identity and access control management system, as well as 2FA; all working together to host whatever you'd like. Here is what does what:

  • Swag

    • Handles the webserver and reverse proxy.
    • All configuration is handled via .conf files and text
    • This guide also demonstrates how to set up the Docker Mods Auto Reload, GeoIPBlock, and ...
  • Authelia

    • Handles weblogin and the front end of 2FA.
    • This has one configuration file, and hooks into LLDAP.
  • LLDAP

    • Handles the "identity" part of the Authentication solution.
    • Requires that a domain is setup, and has a bit of a learning curve.
    • This has a bit of configuration involved whenever you setup a new application with LDAP integrations, however, LLDAP's GitHub page usually has sample configurations on how to setup LDAP auth for an application.
  • Authy/Duo

    • Pick one between Authy or Duo
      • Authy
        • This allows for 2FA via an 8 digit code. The configuration is handled via Authelia, with the end user setting up 2FA through the Authy App or through Bit/Vaultwarden. The user can self register their 2FA in this way, through email.
      • Duo
        • This allows for 2FA via a push notification on your phone. The configuration is handled via Authelia.

Docs created by @ldez

+ + + + \ No newline at end of file diff --git a/.vitepress/dist/lldap_config.toml.rtf b/.vitepress/dist/lldap_config.toml.rtf new file mode 100644 index 0000000..3353033 --- /dev/null +++ b/.vitepress/dist/lldap_config.toml.rtf @@ -0,0 +1,148 @@ +## Default configuration for Docker. +## All the values can be overridden through environment variables, prefixed +## with "LLDAP_". For instance, "ldap_port" can be overridden with the +## "LLDAP_LDAP_PORT" variable. + +## Tune the logging to be more verbose by setting this to be true. +## You can set it with the LLDAP_VERBOSE environment variable. +# verbose=false + +## The host address that the LDAP server will be bound to. +## To enable IPv6 support, simply switch "ldap_host" to "::": +## To only allow connections from localhost (if you want to restrict to local self-hosted services), +## change it to "127.0.0.1" ("::1" in case of IPv6)". +ldap_host = "0.0.0.0" + +## The port on which to have the LDAP server. +ldap_port = 3890 + +## The host address that the HTTP server will be bound to. +## To enable IPv6 support, simply switch "http_host" to "::". +## To only allow connections from localhost (if you want to restrict to local self-hosted services), +## change it to "127.0.0.1" ("::1" in case of IPv6)". +http_host = "0.0.0.0" + +## The port on which to have the HTTP server, for user login and +## administration. +http_port = 17170 + +## The public URL of the server, for password reset links. +#http_url = "http://localhost" + +## Random secret for JWT signature. +## This secret should be random, and should be shared with application +## servers that need to consume the JWTs. +## Changing this secret will invalidate all user sessions and require +## them to re-login. +## You should probably set it through the LLDAP_JWT_SECRET environment +## variable from a secret ".env" file. +## This can also be set from a file's contents by specifying the file path +## in the LLDAP_JWT_SECRET_FILE environment variable +## You can generate it with (on linux): +## LC_ALL=C tr -dc 'A-Za-z0-9!#%&'\''()*+,-./:;<=>?@[\]^_{|}~' . +#from="LLDAP Admin " +## Same for reply-to, optional. +#reply_to="Do not reply " + +## Options to configure LDAPS. +## To set these options from environment variables, use the following format +## (example with "port"): LLDAP_LDAPS_OPTIONS__PORT +[ldaps_options] +## Whether to enable LDAPS. +#enabled=true +## Port on which to listen. +#port=6360 +## Certificate file. +#cert_file="/data/cert.pem" +## Certificate key file. +#key_file="/data/key.pem" diff --git a/.vitepress/dist/maintenance/maintain-guide.html b/.vitepress/dist/maintenance/maintain-guide.html new file mode 100644 index 0000000..a256cec --- /dev/null +++ b/.vitepress/dist/maintenance/maintain-guide.html @@ -0,0 +1,26 @@ + + + + + + Maintenance of the DP-SALA/D Stack | DP-Salad + + + + + + + + + + + + + + + +
Skip to content

Maintenance of the DP-SALA/D Stack ​

Suggested maintenance for the DP-SALA/D Stack

Required Maintenance for the DP-SALA/D Stack ​

Debian 12:

  • At least monthly, run a "sudo apt-get update && sudo apt-get update" to update the base applications for Debian, this applies security and feature upgrades for your OS, which is important.

  • At least bi-weekly, save all the configuration files and important data to a secure, private, personal location. You could even use the Google Drive space of the Gmail address that you setup, and save the previous backups. You could probably keep the last 5 backups just to be safe, but minimum of 3.

Portainer:

  • Update whenever there is an update. If you login and it tells you there is an update available, update right then and there. Portainer is just a docker container that lets you manage other docker containers, but make sure to keep this as up to date as possible.
  • You generally don't have to keep a backup of the Portainer data volume, unless you've made some crazy modification to it's configuration that was different from the standard install.

SWAG:

  • At least monthly, restart the container. This allows it to pull new configurations from the GitHub page, as well as renew your SSL certificates for your webserver.

Authelia:

  • At least monthly, restart the container. This allows it to pull updates for the container.

WARNING

Make sure that your configuration for this is backed up, since multiple sensitive things are within this file, and recovering them will be impossible.

LLDAP:

  • This is probably the lowest maintenance thing out of the stack. Just make sure that it is backed up completely.

Authy/Duo:

  • Set it and forget it. This is typically included in Authelia , so another reason to make sure that config file is completely backed up properly.

Docs created by @ldez

+ + + + \ No newline at end of file diff --git a/.vitepress/dist/robots.txt b/.vitepress/dist/robots.txt new file mode 100644 index 0000000..b3e508a --- /dev/null +++ b/.vitepress/dist/robots.txt @@ -0,0 +1,2 @@ +User-agent: * +Disallow:/ \ No newline at end of file diff --git a/.vitepress/dist/saladicon.png b/.vitepress/dist/saladicon.png new file mode 100644 index 0000000..bbe3793 Binary files /dev/null and b/.vitepress/dist/saladicon.png differ diff --git a/.vitepress/dist/vp-icons.css b/.vitepress/dist/vp-icons.css new file mode 100644 index 0000000..d2e0eeb --- /dev/null +++ b/.vitepress/dist/vp-icons.css @@ -0,0 +1,2 @@ + +/* cannot detect icon mode: not set in options and icon set is missing info, rendering as mask */ diff --git a/.vitepress/dist/x11-guide.html b/.vitepress/dist/x11-guide.html new file mode 100644 index 0000000..918e9d6 --- /dev/null +++ b/.vitepress/dist/x11-guide.html @@ -0,0 +1,26 @@ + + + + + + X11-Guide | DP-Salad + + + + + + + + + + + + + + + +
Skip to content

Windows Setup: ​

Windows X11 Window Manager Client/Server ​

Installation:

  1. Install VCXSRV on your Windows machine.
  2. Follow the install instructions until able to close.

Running the X11 Local Server (aka the client that connects to the real X11 server) ​

  1. Locate the newly installed XLaunch application, open it.
  2. You'll want to modify the display settings as follows:
    • Select Multiple windows for the program displays, hit next
    • Select the Start no client option on the next page, hit next.
    • Options on this page are optional, you DO NOT want the Disable access control selected on this page.
    • Hit next.
    • Click the Save configuration button on this page, save this config somewhere you won't forget about it.
    • Click finish.
    • Allow the access to the network if Windows Defender Firewall asks.
    • Congratulations, you've setup the local X11 server!
  3. Make sure the XLaunch application is in the system tray before running Putty OR Terminal SSH

Connecting to the 'domain.tld' X11 Server ​

  1. First, verify the XLaunch application is running in the System Tray, then follow the instructions below based on your preferred SSH method.

PuTTY Instructions (including setting up a profile for easier management) ​

  1. Highly recommend the use of a profile if you are going to use PuTTY, as you can save/load the config up really quick instead of having to put in these values every time.
  2. Enter in the hostname, (this is optional if making a profile, as the IP address is dynamic)
  3. In the connection category, under the data subcategory, the auto-login username can be set if using a profile.
  4. Expand the SSH subcategory (in connection) and set the credentials if using a profile to the private key (if made)
  5. Now, click on X11 subcategory (in connection) and click the checkbox for 'Enable X11 forwarding'
  6. Set the X Display Location textbox to the value '127.0.0.1:0' (no quotes).
  7. Return to the Session category, and type in a name for the saved session, then hit the save button. Now, all of these changes can be loaded instead of put in each time.
  8. Now, type in the IP address of the 'domain.tld' and hit the 'Open' button.
  9. If you'd like to verify the X11 connectivity, type 'xclock' into the terminal. This will make a little analog clock appear in a separate window.

Windows Powershell Instructions ​

  1. You'll want to set a variable in the command prompt, run $env:DISPLAY="127.0.0.1:0" (exactly as written) to set the X Window Manager as the display output.
  2. Use the command 'ssh -X username@domain.tld' to connect, replacing username with your username, and domain.tld with the current dynIP.
  3. If you'd like to verify the X11 connectivity, type 'xclock' into the terminal. This will make a little analog clock appear in a separate window.

Windows Command Prompt Instructions (a.k.a. CMD) ​

  1. You'll want to set a variable in the command prompt, run set DISPLAY=127.0.0.1:0 to set the X Window Manager as the display output.
  2. Use the command 'ssh -X username@domain.tld' to connect, replacing username with your username, and domain.tld with the current dynIP.
  3. If you'd like to verify the X11 connectivity, type 'xclock' into the terminal. This will make a little analog clock appear in a separate window.

MacOS Setup: ​

MacOS X11 Window Manager Client/Server ​

Installation:

  1. Install XQuartz (https://www.xquartz.org/) using the MacOS pkg file.
  2. Follow the install instructions until able to close (you'll have to logout to complete install).

Running the X11 Local Server on Mac (aka the client that connects to the real X11 server) ​

  1. Locate the newly installed XQuartz application, open it, this opens an xtem window.
  2. You'll want to use this window to connect over SSH.

Connecting to the 'domain.tld' X11 Server on Mac ​

  1. Using the xterm window, run the command set DISPLAY=127.0.0.1:0 to set the X11 forwarder to the correct display set.
  2. Run the command 'ssh -X username@domain.tld' where username is replaced by your username and domain.tld is replaced with the current IP address of the domain.tld server.
  3. Run the 'xclock' command to verify connectivity.

Docs created by @ldez

+ + + + \ No newline at end of file diff --git a/.vitepress/theme/index.ts b/.vitepress/theme/index.ts new file mode 100644 index 0000000..ccbb03b --- /dev/null +++ b/.vitepress/theme/index.ts @@ -0,0 +1,36 @@ +import { h } from "vue"; +import type { Theme } from "vitepress"; +import DefaultTheme from "vitepress/theme"; +import { useData, useRoute } from "vitepress"; +import codeblocksFold from "vitepress-plugin-codeblocks-fold"; +import "vitepress-plugin-codeblocks-fold/style/index.css"; +import "./style.css"; +import "virtual:uno.css"; + +export default { + extends: DefaultTheme, + + Layout: () => { + return h(DefaultTheme.Layout, null, { + // Here you can define custom layout slots or modify the layout. + }); + }, + + enhanceApp({ app, router, siteData }) { + // This is where you can add additional app enhancements or global components + // For example, registering global components or plugins + // DefaultTheme.enhanceApp(ctx) can be called here if needed + // Using the plugin within enhanceApp() is possible if needed, but `setup()` is a cleaner way to do it. + }, + + setup() { + // Get frontmatter and route from VitePress composition API + const { frontmatter } = useData(); + const route = useRoute(); + + // Set up the codeblocks fold plugin with route and frontmatter data + // The second argument enables collapsing by default (true/false) + // The third argument sets the max height of the code block before it collapses (in pixels) + codeblocksFold({ route, frontmatter }, true, 400); + }, +} satisfies Theme; diff --git a/.vitepress/theme/style.css b/.vitepress/theme/style.css new file mode 100644 index 0000000..d63aee8 --- /dev/null +++ b/.vitepress/theme/style.css @@ -0,0 +1,139 @@ +/** + * Customize default theme styling by overriding CSS variables: + * https://github.com/vuejs/vitepress/blob/main/src/client/theme-default/styles/vars.css + */ + +/** + * Colors + * + * Each colors have exact same color scale system with 3 levels of solid + * colors with different brightness, and 1 soft color. + * + * - `XXX-1`: The most solid color used mainly for colored text. It must + * satisfy the contrast ratio against when used on top of `XXX-soft`. + * + * - `XXX-2`: The color used mainly for hover state of the button. + * + * - `XXX-3`: The color for solid background, such as bg color of the button. + * It must satisfy the contrast ratio with pure white (#ffffff) text on + * top of it. + * + * - `XXX-soft`: The color used for subtle background such as custom container + * or badges. It must satisfy the contrast ratio when putting `XXX-1` colors + * on top of it. + * + * The soft color must be semi transparent alpha channel. This is crucial + * because it allows adding multiple "soft" colors on top of each other + * to create a accent, such as when having inline code block inside + * custom containers. + * + * - `default`: The color used purely for subtle indication without any + * special meanings attched to it such as bg color for menu hover state. + * + * - `brand`: Used for primary brand colors, such as link text, button with + * brand theme, etc. + * + * - `tip`: Used to indicate useful information. The default theme uses the + * brand color for this by default. + * + * - `warning`: Used to indicate warning to the users. Used in custom + * container, badges, etc. + * + * - `danger`: Used to show error, or dangerous message to the users. Used + * in custom container, badges, etc. + * -------------------------------------------------------------------------- */ + + :root { + --vp-c-default-1: var(--vp-c-gray-1); + --vp-c-default-2: var(--vp-c-gray-2); + --vp-c-default-3: var(--vp-c-gray-3); + --vp-c-default-soft: var(--vp-c-gray-soft); + + --vp-c-brand-1: var(--vp-c-indigo-1); + --vp-c-brand-2: var(--vp-c-indigo-2); + --vp-c-brand-3: var(--vp-c-indigo-3); + --vp-c-brand-soft: var(--vp-c-indigo-soft); + + --vp-c-tip-1: var(--vp-c-brand-1); + --vp-c-tip-2: var(--vp-c-brand-2); + --vp-c-tip-3: var(--vp-c-brand-3); + --vp-c-tip-soft: var(--vp-c-brand-soft); + + --vp-c-warning-1: var(--vp-c-yellow-1); + --vp-c-warning-2: var(--vp-c-yellow-2); + --vp-c-warning-3: var(--vp-c-yellow-3); + --vp-c-warning-soft: var(--vp-c-yellow-soft); + + --vp-c-danger-1: var(--vp-c-red-1); + --vp-c-danger-2: var(--vp-c-red-2); + --vp-c-danger-3: var(--vp-c-red-3); + --vp-c-danger-soft: var(--vp-c-red-soft); +} + +/** + * Component: Button + * -------------------------------------------------------------------------- */ + +:root { + --vp-button-brand-border: transparent; + --vp-button-brand-text: var(--vp-c-white); + --vp-button-brand-bg: var(--vp-c-brand-3); + --vp-button-brand-hover-border: transparent; + --vp-button-brand-hover-text: var(--vp-c-white); + --vp-button-brand-hover-bg: var(--vp-c-brand-2); + --vp-button-brand-active-border: transparent; + --vp-button-brand-active-text: var(--vp-c-white); + --vp-button-brand-active-bg: var(--vp-c-brand-1); +} + +/** + * Component: Home + * -------------------------------------------------------------------------- */ + +:root { + --vp-home-hero-name-color: transparent; + --vp-home-hero-name-background: -webkit-linear-gradient( + 120deg, + #bd34fe 30%, + #41d1ff + ); + + --vp-home-hero-image-background-image: linear-gradient( + -45deg, + #bd34fe 50%, + #47caff 50% + ); + --vp-home-hero-image-filter: blur(44px); +} + +@media (min-width: 640px) { + :root { + --vp-home-hero-image-filter: blur(56px); + } +} + +@media (min-width: 960px) { + :root { + --vp-home-hero-image-filter: blur(68px); + } +} + +/** + * Component: Custom Block + * -------------------------------------------------------------------------- */ + +:root { + --vp-custom-block-tip-border: transparent; + --vp-custom-block-tip-text: var(--vp-c-text-1); + --vp-custom-block-tip-bg: var(--vp-c-brand-soft); + --vp-custom-block-tip-code-bg: var(--vp-c-brand-soft); +} + +/** + * Component: Algolia + * -------------------------------------------------------------------------- */ + +.DocSearch { + --docsearch-primary-color: var(--vp-c-brand-1) !important; +} + diff --git a/cf-tunnel.md b/cf-tunnel.md new file mode 100644 index 0000000..b5bbd4e --- /dev/null +++ b/cf-tunnel.md @@ -0,0 +1,117 @@ +--- +title: Cloudflare Tunneling +--- + +# Cloudflare Tunnel Setup: :simple-icons-cloudflare: :mingcute-tunnel-line: + +Sometimes, someone might want to deploy the DP-SALAD stack behind *NAT* or you don't want to open your network's ports exposing them to the outside. + +:::tip Note: +You do not need to have your domain registered through Cloudflare :simple-icons-cloudflare: to use Cloudflare Tunnels +::: + +## THE SOLUTION? + +**Cloudflare Tunnels** :party-popper: + +Of course, running the stack this way comes with some extra configuartion on both the Docker side and Cloudflare/domain side. + +This is an excerpt from the [One-Click Docker Compose file](/docker-compose.md): + +In order to make this work with cloudflare tunneling, you must add some more lines to your docker compose. The first being a directive which is highlighted below: + +```yml{21-22} +version: "2.1" +services: + swag: + image: lscr.io/linuxserver/swag:latest + container_name: swag + cap_add: + - NET_ADMIN + environment: + - PUID=1000 + - PGID=1000 + - TZ=America/Phoenix + - URL=[sakura.nt] + - VALIDATION=dns + - SUBDOMAINS=wildcard + - DNSPLUGIN=cloudflare + - EMAIL=[sakurant@gmail.com] + - ONLY_SUBDOMAINS=false + #- EXTRA_DOMAINS= #optional + - STAGING=false + - DOCKER_MODS=linuxserver/mods:universal-docker|linuxserver/mods:swag-auto-reload|linuxserver/mods:swag-dashboard|linuxserver/mods:swag-dbip|linuxserver/mods:universal-cloudflared + extra_hosts: + - domain.tld:127.0.0.1 + volumes: + - /home/[INSERT USER FOLDER HERE]/appdata/swag:/config + ports: + - 443:443 + - 80:80 + networks: + - [INSERT NETWORK NAME HERE] + restart: unless-stopped +``` + +Next, you'll want to generate an API key :material-symbols-key-outline: with Cloudflare :simple-icons-cloudflare:, go to *Overview* in your domain, and click "*get your api token*", click *Create Token*, use → "*Edit zone DNS*" template, add a permission, select "*Account*", → "*Cloudflare Tunnel*", → "*Edit*", under account resources, include your account, under zone resources, include your domain. Continue with setup, **make sure you keep track of the API key somewhere**. + +After you have completed these steps, you will need to add these credentials to your Swag configuration in the **docker-compose.yml**. After the *Docker_Mods* environment variable, add these lines: + +```yml +version: "2.1" +services: + swag: + image: lscr.io/linuxserver/swag:latest + container_name: swag + cap_add: + - NET_ADMIN + environment: + - PUID=1000 + - PGID=1000 + - TZ=America/Phoenix + - URL=[sakura.nt] + - VALIDATION=dns + - SUBDOMAINS=wildcard + - DNSPLUGIN=cloudflare + - EMAIL=[sakurant@gmail.com] + - ONLY_SUBDOMAINS=false + #- EXTRA_DOMAINS= #optional + - STAGING=false + - DOCKER_MODS=linuxserver/mods:universal-docker|linuxserver/mods:swag-auto-reload|linuxserver/mods:swag-dashboard|linuxserver/mods:swag-dbip|linuxserver/mods:universal-cloudflared + - CF_ZONE_ID=zone id from cloudflare domain overview // [!code focus] + - CF_ACCOUNT_ID=account id from cloudflare domain overview // [!code focus] + - CF_API_TOKEN=api token generated // [!code focus] + - CF_TUNNEL_NAME=create a tunnel, name it whatever // [!code focus] + - CF_TUNNEL_PASSWORD=generate a long password // [!code focus] + - FILE__CF_TUNNEL_CONFIG=/config/tunnelconfig.yml // [!code focus] + extra_hosts: + - domain.tld:127.0.0.1 + volumes: + - /home/[INSERT USER FOLDER HERE]/appdata/swag:/config + ports: + - 443:443 + - 80:80 + networks: + - [INSERT NETWORK NAME HERE] + restart: unless-stopped +``` + +You're not quite done yet... :cold-face: + +You'll need to add more to finish the installation: +First, `nano /home/[USER]/appdata/swag/tunnelconfig.yml`, and add these contents: + +```yml +ingress: + - hostname: domain.tld + service: https://domain.tld + - hostname: "*.domain.tld" + service: https://domain.tld + - service: http_status:404 +``` + +Then, edit the `/home/[USER]/appdata/swag/dns-conf/cloudflare.ini`, add the API token, you'll comment the top two lines, add the token after uncommenting the bottom line. + +:::details *insert funni meeme here:* +![/cat-typing.gif](/cat-typing.gif) +::: diff --git a/changelog.md b/changelog.md new file mode 100644 index 0000000..4f4f78f --- /dev/null +++ b/changelog.md @@ -0,0 +1,39 @@ +--- +title: Changelog +sidebar: false +--- + +# Changelog + +## Version 1.1.0: 11-20-24 + +- Updated dependencies to latest version -ldez +- Added code block closure functionality to minify pages -ldez +- Added back Cdez's credits -ldez +- Moved cloudflare tunneling to misc -ldez + +## Version 1.0.4: 10-11-24 + +- Updated dependencies to latest version -ldez +- Added miscellaneous section -ldez + +## Version 1.0.3: 07-07-24 + +- Updated dependencies to latest version -ldez +- Removed Google Domains as they have moved to shitspace -ldez +- Added a Cisco Duo logo -ldez + +## Version 1.0.2: 06-22-24 + +- Redo the homepage -ldez +- Added some icons to pages -ldez +- Changed "mini-req" to just "requirements" -ldez +- Fixed the formatting issues on dp-setup -ldez + +## Version 1.0.1: 06-19-24 + +- Fixed some documentation -ldez +- Added section about cloudflare tunneling -ldez +- Added more commands to successfully deploy dp-stack -ldez +- Added an explanation for Debian's sudo -ldez +- Added the FAQ expanlanation to add an application -ldez diff --git a/configuration/auth-config.md b/configuration/auth-config.md new file mode 100644 index 0000000..2d12775 --- /dev/null +++ b/configuration/auth-config.md @@ -0,0 +1,1335 @@ +--- +title: Authelia Configuration +--- + +# Authelia Configuration :simple-icons-authelia: + +Authelia, is our version of an SSO :material-symbols-key-outline:, as once you've logged into Authelia, you have access to all protected links. Attached below is the example `configuration.yml` file for Authelia. You can copy/paste this configuration, and then change all values surrounded in square brackets. Make sure to set passwords/tokens where **REDACTED** occurs. I recommend strings that are at least a length of 26 characters. This example configuration is perfect for 2FA with Authy :logos-authy: out of the box, if you'd like to enable Duo :simple-icons-cisco:, please see [Authy/Duo Configuration](/configuration/authy-duo-config.md) for more details. + +```yaml +# yamllint disable rule:comments-indentation +--- +################################################################### +############ +# Authelia Configuration # +################################################################### +############ +## Note: the container by default expects to find this file at /config/configuration.yml. +## Certificates directory specifies where Authelia will load trusted certificates (public portion) from in addition to +## the system certificates store. +## They should be in base64 format, and have one of the following extensions: *.cer, *.crt, *.pem. +# certificates_directory: /config/certificates/ +## The theme to display: light, dark, grey, auto. +theme: dark +## The secret used to generate JWT tokens when validating user identity by email confirmation. JWT Secret can +also be +## set using a secret: https://www.authelia.com/c/secrets +jwt_secret: REDACTED +## Default redirection URL +## +## If user tries to authenticate without any referer, Authelia does not know where to redirect the user to at the +end +## of the authentication process. This parameter allows you to specify the default redirection URL Authelia will +use +## in such a case. +## +## Note: this parameter is optional. If not provided, user won't be redirected upon successful authentication. +default_redirection_url: https://[domain.tld]/ +## Set the default 2FA method for new users and for when a user has a preferred method configured that has +been +## disabled. This setting must be a method that is enabled. +## Options are totp, webauthn, mobile_push. +default_2fa_method: "totp" +## +## Server Configuration +## +server: + ## The address to listen on. + host: 0.0.0.0 + ## The port to listen on. + port: 9091 + ## Set the single level path Authelia listens on. + ## Must be alphanumeric chars and should not contain any slashes. + path: "authelia" + ## Set the path on disk to Authelia assets. + ## Useful to allow overriding of specific static assets. + # asset_path: /config/assets/ + ## Enables the pprof endpoint. + enable_pprof: false + ## Enables the expvars endpoint. + enable_expvars: false + ## Disables writing the health check vars to /app/.healthcheck.env which makes healthcheck.sh return exit +code 0. + ## This is disabled by default if either /app/.healthcheck.env or /app/healthcheck.sh do not exist. + disable_healthcheck: false + ## Authelia by default doesn't accept TLS communication on the server port. This section overrides this +behaviour. + tls: + ## The path to the DER base64/PEM format private key. + key: "" + ## The path to the DER base64/PEM format public certificate. + certificate: "" + ## The list of certificates for client authentication. + client_certificates: [] + ## Server headers configuration/customization. + headers: + ## The CSP Template. Read the docs. + csp_template: "" + ## Server Buffers configuration. + # buffers: + ## Buffers usually should be configured to be the same value. + ## Explanation at https://www.authelia.com/c/server#buffer-sizes + ## Read buffer size adjusts the server's max incoming request size in bytes. + ## Write buffer size does the same for outgoing responses. + ## Read buffer. + # read: 4096 + ## Write buffer. + # write: 4096 + ## Server Timeouts configuration. + # timeouts: + ## Read timeout. + # read: 6s + ## Write timeout. + # write: 6s + ## Idle timeout. + # idle: 30s +## +## Log Configuration +## +log: + ## Level of verbosity for logs: info, debug, trace. + level: debug + ## Format the logs are written as: json, text. + # format: json + ## File path where the logs will be written. If not set logs are written to stdout. + # file_path: /config/authelia.log + ## Whether to also log to stdout when a log_file_path is defined. + # keep_stdout: false +## +## Telemetry Configuration +## +telemetry: + ## + ## Metrics Configuration + ## + metrics: + ## Enable Metrics. + enabled: false + ## The address to listen on for metrics. This should be on a different port to the main server.port value. + address: tcp://0.0.0.0:9959 + ## Metrics Server Buffers configuration. + # buffers: + ## Read buffer. + # read: 4096 + ## Write buffer. + # write: 4096 + ## Metrics Server Timeouts configuration. + # timeouts: + ## Read timeout. + # read: 6s + ## Write timeout. + # write: 6s + ## Idle timeout. + # idle: 30s +## +## TOTP Configuration +## +## Parameters used for TOTP generation. +totp: + ## Disable TOTP. + disable: false + ## The issuer name displayed in the Authenticator application of your choice. + issuer: [domain.tld] + ## The TOTP algorithm to use. + ## It is CRITICAL you read the documentation before changing this option: + ## https://www.authelia.com/c/totp#algorithm + algorithm: sha1 + ## The number of digits a user has to input. Must either be 6 or 8. + ## Changing this option only affects newly generated TOTP configurations. + ## It is CRITICAL you read the documentation before changing this option: + ## https://www.authelia.com/c/totp#digits + digits: 8 + ## The period in seconds a one-time password is valid for. + ## Changing this option only affects newly generated TOTP configurations. + period: 30 + ## The skew controls number of one-time passwords either side of the current one that are valid. + ## Warning: before changing skew read the docs link below. + skew: 1 + ## See: https://www.authelia.com/c/totp#input-validation to read + ## the documentation. + ## The size of the generated shared secrets. Default is 32 and is sufficient in most use cases, minimum is 20. + secret_size: 32 +## +## WebAuthn Configuration +## +## Parameters used for WebAuthn. +webauthn: + ## Disable Webauthn. + disable: false + ## Adjust the interaction timeout for Webauthn dialogues. + timeout: 60s + ## The display name the browser should show the user for when using Webauthn to login/register. + display_name: Authelia + ## Conveyance preference controls if we collect the attestation statement including the AAGUID from the +device. + ## Options are none, indirect, direct. + attestation_conveyance_preference: indirect + ## User verification controls if the user must make a gesture or action to confirm they are present. + ## Options are required, preferred, discouraged. + user_verification: preferred +## +## Duo Push API Configuration +## +## Parameters used to contact the Duo API. Those are generated when you protect an application of type +## "Partner Auth API" in the management panel. +# duo_api: + # disable: false + # hostname: api-123456789.example.com + # integration_key: ABCDEF + ## Secret can also be set using a secret: https://www.authelia.com/c/secrets + # secret_key: 1234567890abcdefghifjkl + # enable_self_enrollment: false +## +## NTP Configuration +## +## This is used to validate the servers time is accurate enough to validate TOTP. +ntp: + ## NTP server address. + address: "time.cloudflare.com:123" + ## NTP version. + version: 4 + ## Maximum allowed time offset between the host and the NTP server. + max_desync: 3s + ## Disables the NTP check on startup entirely. This means Authelia will not contact a remote service at all if +you + ## set this to true, and can operate in a truly offline mode. + disable_startup_check: false + ## The default of false will prevent startup only if we can contact the NTP server and the time is out of sync +with + ## the NTP server more than the configured max_desync. If you set this to true, an error will be logged but +startup + ## will continue regardless of results. + disable_failure: false +## +## Authentication Backend Provider Configuration +## +## Used for verifying user passwords and retrieve information such as email address and groups users belong +to. +## +## The available providers are: `file`, `ldap`. You must use only one of these providers. +authentication_backend: + ## Password Reset Options. + password_reset: + ## Disable both the HTML element and the API for reset password functionality. + disable: false + ## External reset password url that redirects the user to an external reset portal. This disables the internal +reset + ## functionality. + custom_url: "" + ## The amount of time to wait before we refresh data from the authentication backend. Uses duration +notation. + ## To disable this feature set it to 'disable', this will slightly reduce security because for Authelia, users will + ## always belong to groups they belonged to at the time of login even if they have been removed from them +in LDAP. + ## To force update on every request you can set this to '0' or 'always', this will increase processor demand. + ## See the below documentation for more information. + ## Duration Notation docs: https://www.authelia.com/c/common#duration-notation-format + ## Refresh Interval docs: https://www.authelia.com/c/1fa#refresh-interval + refresh_interval: 5m + ## + ## LDAP (Authentication Provider) + ## + ## This is the recommended Authentication Provider in production + ## because it allows Authelia to offload the stateful operations + ## onto the LDAP service. + ldap: + ## The LDAP implementation, this affects elements like the attribute utilised for resetting a password. + ## Acceptable options are as follows: + ## - 'activedirectory' - For Microsoft Active Directory. + ## - 'custom' - For custom specifications of attributes and filters. + ## This currently defaults to 'custom' to maintain existing behaviour. + ## + ## Depending on the option here certain other values in this section have a default value, notably all of the + ## attribute mappings have a default value that this config overrides, you can read more about these default +values + ## at https://www.authelia.com/c/ldap#defaults + implementation: custom + ## The url to the ldap server. Format: ://
[:]. + ## Scheme can be ldap or ldaps in the format (port optional). + url: ldap://lldap:3890 + ## The dial timeout for LDAP. + timeout: 5s + ## Use StartTLS with the LDAP connection. + start_tls: false + # tls: + ## The server subject name to check the servers certificate against during the validation process. + ## This option is not required if the certificate has a SAN which matches the host portion of the url option. + # server_name: ldap.example.com + ## Skip verifying the server certificate entirely. In preference to setting this we strongly recommend you +add the + ## certificate or the certificate of the authority signing the certificate to the certificates directory which is + ## defined by the `certificates_directory` option at the top of the configuration. + ## It's important to note the public key should be added to the directory, not the private key. + ## This option is strongly discouraged but may be useful in some self-signed situations where validation is +not + ## important to the administrator. + # skip_verify: false + ## Minimum TLS version for the connection. + # minimum_version: TLS1.2 + ## Maximum TLS version for the connection. + # maximum_version: TLS1.3 + ## The certificate chain used with the private_key if the server requests TLS Client Authentication + ## i.e. Mutual TLS. + # certificate_chain: | + # -----BEGIN CERTIFICATE----- + # MIIC5jCCAc6gAwIBAgIRAK4Sj7FiN6PXo/urPfO4E7owDQYJKoZIhvcNAQELBQAw + # EzERMA8GA1UEChMIQXV0aGVsaWEwHhcNNzAwMTAxMDAwMDAwWhcNNzEwMTAxMDAw + # MDAwWjATMREwDwYDVQQKEwhBdXRoZWxpYTCCASIwDQYJKoZIhvcNAQEBBQADggEP + # ADCCAQoCggEBAPKv3pSyP4ozGEiVLJ14dIWFCEGEgq7WUMI0SZZqQA2ID0L59U/Q + # /Usyy7uC9gfMUzODTpANtkOjFQcQAsxlR1FOjVBrX5QgjSvXwbQn3DtwMA7XWSl6 + # LuYx2rBYSlMSN5UZQm/RxMtXfLK2b51WgEEYDFi+nECSqKzR4R54eOPkBEWRfvuY + # 91AMjlhpivg8e4JWkq4LVQUKbmiFYwIdK8XQiN4blY9WwXwJFYs5sQ/UYMwBFi0H + # kWOh7GEjfxgoUOPauIueZSMSlQp7zqAH39N0ZSYb6cS0Npj57QoWZSY3ak87ebcR + # Nf4rCvZLby7LoN7qYCKxmCaDD3x2+NYpWH8CAwEAAaM1MDMwDgYDVR0PAQH/BAQD + # AgWgMBMGA1UdJQQMMAoGCCsGAQUFBwMBMAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcN + # AQELBQADggEBAHSITqIQSNzonFl3DzxHPEzr2hp6peo45buAAtu8FZHoA+U7Icfh + # /ZXjPg7Xz+hgFwM/DTNGXkMWacQA/PaNWvZspgRJf2AXvNbMSs2UQODr7Tbv+Fb4 + # lyblmMUNYFMCFVAMU0eIxXAFq2qcwv8UMcQFT0Z/35s6PVOakYnAGGQjTfp5Ljuq + # wsdc/xWmM0cHWube6sdRRUD7SY20KU/kWzl8iFO0VbSSrDf1AlEhnLEkp1SPaxXg + # OdBnl98MeoramNiJ7NT6Jnyb3zZ578fjaWfThiBpagItI8GZmG4s4Ovh2JbheN8i + # ZsjNr9jqHTjhyLVbDRlmJzcqoj4JhbKs6/I^invalid DO NOT USE= + # -----END CERTIFICATE----- + # -----BEGIN CERTIFICATE----- + # MIIDBDCCAeygAwIBAgIRALJsPg21kA0zY4F1wUCIuoMwDQYJKoZIhvcNAQELBQAw + # EzERMA8GA1UEChMIQXV0aGVsaWEwHhcNNzAwMTAxMDAwMDAwWhcNNzEwMTAxMDAw + # MDAwWjATMREwDwYDVQQKEwhBdXRoZWxpYTCCASIwDQYJKoZIhvcNAQEBBQADggEP + # ADCCAQoCggEBAMXHBvVxUzYk0u34/DINMSF+uiOekKOAjOrC6Mi9Ww8ytPVO7t2S + # zfTvM+XnEJqkFQFgimERfG/eGhjF9XIEY6LtnXe8ATvOK4nTwdufzBaoeQu3Gd50 + # 5VXr6OHRo//ErrGvFXwP3g8xLePABsi/fkH3oDN+ztewOBMDzpd+KgTrk8ysv2ou + # kNRMKFZZqASvCgv0LD5KWvUCnL6wgf1oTXG7aztduA4oSkUP321GpOmBC5+5ElU7 + # ysoRzvD12o9QJ/IfEaulIX06w9yVMo60C/h6A3U6GdkT1SiyTIqR7v7KU/IWd/Qi + # Lfftcj91VhCmJ73Meff2e2S2PrpjdXbG5FMCAwEAAaNTMFEwDgYDVR0PAQH/BAQD + # AgKkMA8GA1UdJQQIMAYGBFUdJQAwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU + # Z7AtA3mzFc0InSBA5fiMfeLXA3owDQYJKoZIhvcNAQELBQADggEBAEE5hm1mtlk/ + # kviCoHH4evbpw7rxPxDftIQlqYTtvMM4eWY/6icFoSZ4fUHEWYyps8SsPu/8f2tf + # 71LGgZn0FdHi1QU2H8m0HHK7TFw+5Q6RLrLdSyk0PItJ71s9en7r8pX820nAFEHZ + # HkOSfJZ7B5hFgUDkMtVM6bardXAhoqcMk4YCU96e9d4PB4eI+xGc+mNuYvov3RbB + # D0s8ICyojeyPVLerz4wHjZu68Z5frAzhZ68YbzNs8j2fIBKKHkHyLG1iQyF+LJVj + # 2PjCP+auJsj6fQQpMGoyGtpLcSDh+ptcTngUD8JsWipzTCjmaNqdPHAOYmcgtf4b + # qocikt3WAdU^invalid DO NOT USE= + # -----END CERTIFICATE----- + ## The private key used with the certificate_chain if the server requests TLS Client Authentication + ## i.e. Mutual TLS. + # private_key: | + # -----BEGIN RSA PRIVATE KEY----- + # MIIEpAIBAAKCAQEA8q/elLI/ijMYSJUsnXh0hYUIQYSCrtZQwjRJlmpADYgPQvn1 + # T9D9SzLLu4L2B8xTM4NOkA22Q6MVBxACzGVHUU6NUGtflCCNK9fBtCfcO3AwDtdZ + # KXou5jHasFhKUxI3lRlCb9HEy1d8srZvnVaAQRgMWL6cQJKorNHhHnh44+QERZF+ + # +5j3UAyOWGmK+Dx7glaSrgtVBQpuaIVjAh0rxdCI3huVj1bBfAkVizmxD9RgzAEW + # LQeRY6HsYSN/GChQ49q4i55lIxKVCnvOoAff03RlJhvpxLQ2mPntChZlJjdqTzt5 + # txE1/isK9ktvLsug3upgIrGYJoMPfHb41ilYfwIDAQABAoIBAQDTOdFf2JjHH1um + # aPgRAvNf9v7Nj5jytaRKs5nM6iNf46ls4QPreXnMhqSeSwj6lpNgBYxOgzC9Q+cc + # Y4ob/paJJPaIJTxmP8K/gyWcOQlNToL1l+eJ20eQoZm23NGr5fIsunSBwLEpTrdB + # ENqqtcwhW937K8Pxy/Q1nuLyU2bc6Tn/ivLozc8n27dpQWWKh8537VY7ancIaACr + # LJJLYxKqhQpjtBWAyCDvZQirnAOm9KnvIHaGXIswCZ4Xbsu0Y9NL+woARPyRVQvG + # jfxy4EmO9s1s6y7OObSukwKDSNihAKHx/VIbvVWx8g2Lv5fGOa+J2Y7o9Qurs8t5 + # BQwMTt0BAoGBAPUw5Z32EszNepAeV3E2mPFUc5CLiqAxagZJuNDO2pKtyN29ETTR + # Ma4O1cWtGb6RqcNNN/Iukfkdk27Q5nC9VJSUUPYelOLc1WYOoUf6oKRzE72dkMQV + # R4bf6TkjD+OVR17fAfkswkGahZ5XA7j48KIQ+YC4jbnYKSxZTYyKPjH/AoGBAP1i + # tqXt36OVlP+y84wWqZSjMelBIVa9phDVGJmmhz3i1cMni8eLpJzWecA3pfnG6Tm9 + # ze5M4whASleEt+M00gEvNaU9ND+z0wBfi+/DwJYIbv8PQdGrBiZFrPhTPjGQUldR + # lXccV2meeLZv7TagVxSi3DO6dSJfSEHyemd5j9mBAoGAX8Hv+0gOQZQCSOTAq8Nx + # 6dZcp9gHlNaXnMsP9eTDckOSzh636JPGvj6m+GPJSSbkURUIQ3oyokMNwFqvlNos + # fTaLhAOfjBZI9WnDTTQxpugWjphJ4HqbC67JC/qIiw5S6FdaEvGLEEoD4zoChywZ + # 9oGAn+fz2d/0/JAH/FpFPgsCgYEAp/ipZgPzziiZ9ov1wbdAQcWRj7RaWnssPFpX + # jXwEiXT3CgEMO4MJ4+KWIWOChrti3qFBg6i6lDyyS6Qyls7sLFbUdC7HlTcrOEMe + # rBoTcCI1GqZNlqWOVQ65ZIEiaI7o1vPBZo2GMQEZuq8mDKFsOMThvvTrM5cAep84 + # n6HJR4ECgYABWcbsSnr0MKvVth/inxjbKapbZnp2HUCuw87Ie5zK2Of/tbC20wwk + # yKw3vrGoE3O1t1g2m2tn8UGGASeZ842jZWjIODdSi5+icysQGuULKt86h/woz2SQ + # 27GoE2i5mh6Yez6VAYbUuns3FcwIsMyWLq043Tu2DNkx9ijOOAuQzw^invalid.. + # DO NOT USE== + # -----END RSA PRIVATE KEY----- + ## The distinguished name of the container searched for objects in the directory information tree. + ## See also: additional_users_dn, additional_groups_dn. + base_dn: dc=[domain],dc=[tld] + ## The attribute holding the username of the user. This attribute is used to populate the username in the +session + ## information. For your information, Microsoft Active Directory usually uses 'sAMAccountName' and +OpenLDAP usually + ## uses 'uid'. Beware that this attribute holds the unique identifiers for the users binding the user and the + ## configuration stored in database. Therefore only single value attributes are allowed and the value must +never be + ## changed once attributed to a user otherwise it would break the configuration for that user. Technically, + ## non-unique attributes like 'mail' can also be used but we don't recommend using them, we instead advise +to use + ## a filter to perform alternative lookups and the attributes mentioned above (sAMAccountName and uid) to + ## follow https://www.ietf.org/rfc/rfc2307.txt. + username_attribute: uid + ## The additional_users_dn is prefixed to base_dn and delimited by a comma when searching for users. + ## i.e. with this set to OU=Users and base_dn set to DC=a,DC=com; OU=Users,DC=a,DC=com is searched +for users. + additional_users_dn: ou=people + ## The users filter used in search queries to find the user profile based on input filled in login form. + ## Various placeholders are available in the user filter which you can read about in the documentation which +can + ## be found at: https://www.authelia.com/c/ldap#users-filter-replacements + ## + ## Recommended settings are as follows: + ## - Microsoft Active Directory: +(&({username_attribute}={input})(objectCategory=person)(objectClass=user)) + ## - OpenLDAP: + ## - (&({username_attribute}={input})(objectClass=person)) + ## - (&({username_attribute}={input})(objectClass=inetOrgPerson)) + ## + ## To allow sign in both with username and email, one can use a filter like + ## (&(|({username_attribute}={input})({mail_attribute}={input}))(objectClass=person)) + users_filter: (&({username_attribute}={input})(objectClass=person)) + ## The additional_groups_dn is prefixed to base_dn and delimited by a comma when searching for groups. + ## i.e. with this set to OU=Groups and base_dn set to DC=a,DC=com; OU=Groups,DC=a,DC=com is +searched for groups. + additional_groups_dn: ou=groups + ## The groups filter used in search queries to find the groups based on relevant authenticated user. + ## Various placeholders are available in the groups filter which you can read about in the documentation +which can + ## be found at: https://www.authelia.com/c/ldap#groups-filter-replacements + ## + ## If your groups use the `groupOfUniqueNames` structure use this instead: + ## (&(uniqueMember={dn})(objectClass=groupOfUniqueNames)) + groups_filter: (&(member={dn})(objectClass=groupOfUniqueNames)) + ## The attribute holding the name of the group. + group_name_attribute: cn + ## The attribute holding the mail address of the user. If multiple email addresses are defined for a user, only +the + ## first one returned by the LDAP server is used. + mail_attribute: mail + ## The attribute holding the display name of the user. This will be used to greet an authenticated user. + display_name_attribute: displayName + ## Follow referrals returned by the server. + ## This is especially useful for environments where read-only servers exist. Only implemented for write +operations. + # permit_referrals: false + ## The username and password of the admin user. + user: cn=admin,ou=people,dc=[domain],dc=[tld] + ## Password can also be set using a secret: https://www.authelia.com/c/secrets + password: "REDACTED" + ## + ## File (Authentication Provider) + ## + ## With this backend, the users database is stored in a file which is updated when users reset their passwords. + ## Therefore, this backend is meant to be used in a dev environment and not in production since it prevents +Authelia + ## to be scaled to more than one instance. The options under 'password' have sane defaults, and as it has +security + ## implications it is highly recommended you leave the default values. Before considering changing these +settings + ## please read the docs page below: + ## https://www.authelia.com/r/passwords#tuning + ## + ## Important: Kubernetes (or HA) users must read https://www.authelia.com/t/statelessness + ## + # file: + # path: /config/users_database.yml + # watch: false + # search: + # email: false + # case_insensitive: false + # password: + # algorithm: argon2 + # argon2: + # variant: argon2id + # iterations: 3 + # memory: 65536 + # parallelism: 4 + # key_length: 32 + # salt_length: 16 + # scrypt: + # iterations: 16 + # block_size: 8 + # parallelism: 1 + # key_length: 32 + # salt_length: 16 + # pbkdf2: + # variant: sha512 + # iterations: 310000 + # salt_length: 16 + # sha2crypt: + # variant: sha512 + # iterations: 50000 + # salt_length: 16 + # bcrypt: + # variant: standard + # cost: 12 +## +## Password Policy Configuration. +## +password_policy: + ## The standard policy allows you to tune individual settings manually. + standard: + enabled: true + ## Require a minimum length for passwords. + min_length: 8 + ## Require a maximum length for passwords. + max_length: 0 + ## Require uppercase characters. + require_uppercase: true + ## Require lowercase characters. + require_lowercase: true + ## Require numeric characters. + require_number: true + ## Require special characters. + require_special: true + ## zxcvbn is a well known and used password strength algorithm. It does not have tunable settings. + zxcvbn: + enabled: false + ## Configures the minimum score allowed. + min_score: 3 +## +## Access Control Configuration +## +## Access control is a list of rules defining the authorizations applied for one resource to users or group of +users. +## +## If 'access_control' is not defined, ACL rules are disabled and the 'bypass' rule is applied, i.e., access is +allowed +## to anyone. Otherwise restrictions follow the rules defined. +## +## Note: One can use the wildcard * to match any subdomain. +## It must stand at the beginning of the pattern. (example: *.example.com) +## +## Note: You must put patterns containing wildcards between simple quotes for the YAML to be syntactically +correct. +## +## Definition: A 'rule' is an object with the following keys: 'domain', 'subject', 'policy' and 'resources'. +## +## - 'domain' defines which domain or set of domains the rule applies to. +## +## - 'subject' defines the subject to apply authorizations to. This parameter is optional and matching any user if +not +## provided. If provided, the parameter represents either a user or a group. It should be of the form +## 'user:' or 'group:'. +## +## - 'policy' is the policy to apply to resources. It must be either 'bypass', 'one_factor', 'two_factor' or 'deny'. +## +## - 'resources' is a list of regular expressions that matches a set of resources to apply the policy to. This +parameter +## is optional and matches any resource if not provided. +## +## Note: the order of the rules is important. The first policy matching (domain, resource, subject) applies. +access_control: + ## Default policy can either be 'bypass', 'one_factor', 'two_factor' or 'deny'. It is the policy applied to any + ## resource if there is no policy to be applied to the user. + default_policy: deny + # networks: + # - name: internal + # networks: + # - 10.10.0.0/16 + # - 192.168.2.0/24 + # - name: VPN + # networks: 10.9.0.0/16 + rules: + ## Rules applied to everyone + ## This below policy allows for auth to be accessed at all times, + ## useful when trying to login without the main page available. + - domain: + - 'auth.[domain.tld]' + policy: bypass + ## This below policy example will exclude a user from using 2FA, + ## useful if the user has no way of configuring 2FA. + - domain: + - '[domain.tld]' + - '*.[domain.tld]' + subject: + - "user:[USERNAME/UID]" + policy: one_factor + ## This below policy example will exclude all users of the people + ## group from using 2FA, NOT RECOMMENDED + - domain: + - '[domain.tld]' + - '*.[domain.tld]' + subject: + - "group:people" + policy: one_factor + ## This below policy will require all users of the LLDAP_Admin group + ## in LLDAP to use 2FA BY DEFAULT, this is the strongest policy available + - domain: + - '[domain.tld]' + - '*.[domain.tld]' + subject: + - "group:lldap_admin" + policy: two_factor + ## Domain Regex examples. Generally we recommend just using a standard domain. + # - domain_regex: '^(?P\w+)\.example\.com$' + # policy: one_factor + # - domain_regex: '^(?P\w+)\.example\.com$' + # policy: one_factor + # - domain_regex: + # - '^appgroup-.*\.example\.com$' + # - '^appgroup2-.*\.example\.com$' + # policy: one_factor + # - domain_regex: '^.*\.example\.com$' + # policy: two_factor + # - domain: 'secure.example.com' + # policy: one_factor + ## Network based rule, if not provided any network matches. + # networks: + # - internal + # - VPN + # - 192.168.1.0/24 + # - 10.0.0.1 + # - domain: + # - 'secure.example.com' + # - 'private.example.com' + # policy: two_factor + # - domain: 'singlefactor.example.com' + # policy: one_factor + ## Rules applied to 'admins' group + # - domain: 'mx2.mail.example.com' + # subject: 'group:admins' + # policy: deny + # - domain: '*.example.com' + # subject: + # - 'group:admins' + # - 'group:moderators' + # policy: two_factor + ## Rules applied to 'dev' group + # - domain: 'dev.example.com' + # resources: + # - '^/groups/dev/.*$' + # subject: 'group:dev' + # policy: two_factor + ## Rules applied to user 'john' + # - domain: 'dev.example.com' + # resources: + # - '^/users/john/.*$' + # subject: 'user:john' + # policy: two_factor + ## Rules applied to user 'harry' + # - domain: 'dev.example.com' + # resources: + # - '^/users/harry/.*$' + # subject: 'user:harry' + # policy: two_factor + ## Rules applied to user 'bob' + # - domain: '*.mail.example.com' + # subject: 'user:bob' + # policy: two_factor + # - domain: 'dev.example.com' + # resources: + # - '^/users/bob/.*$' + # subject: 'user:bob' + # policy: two_factor +## +## Session Provider Configuration +## +## The session cookies identify the user once logged in. +## The available providers are: `memory`, `redis`. Memory is the provider unless redis is defined. +session: + ## The name of the session cookie. + name: authelia_session + ## The domain to protect. + ## Note: the authenticator must also be in that domain. + ## If empty, the cookie is restricted to the subdomain of the issuer. + domain: [domain.tld] + ## Sets the Cookie SameSite value. Possible options are none, lax, or strict. + ## Please read https://www.authelia.com/c/session#same_site + same_site: lax + ## The secret to encrypt the session data. This is only used with Redis / Redis Sentinel. + ## Secret can also be set using a secret: https://www.authelia.com/c/secrets + secret: REDACTED + ## The value for expiration, inactivity, and remember_me_duration are in seconds or the duration notation +format. + ## See: https://www.authelia.com/c/common#duration-notation-format + ## All three of these values affect the cookie/session validity period. Longer periods are considered less secure + ## because a stolen cookie will last longer giving attackers more time to spy or attack. + ## The time before the cookie expires and the session is destroyed if remember me IS NOT selected. + expiration: 1h + ## The inactivity time before the session is reset. If expiration is set to 1h, and this is set to 5m, if the user + ## does not select the remember me option their session will get destroyed after 1h, or after 5m since the last +time + ## Authelia detected user activity. + inactivity: 5m + ## The time before the cookie expires and the session is destroyed if remember me IS selected. + ## Value of -1 disables remember me. + remember_me_duration: 2M + ## + ## Redis Provider + ## + ## Important: Kubernetes (or HA) users must read https://www.authelia.com/t/statelessness + ## + redis: + host: redis + port: 6379 + ## Use a unix socket instead + # host: /var/run/redis/redis.sock + ## Username used for redis authentication. This is optional and a new feature in redis 6.0. + # username: authelia + ## Password can also be set using a secret: https://www.authelia.com/c/secrets + password: REDACTED + ## This is the Redis DB Index https://redis.io/commands/select (sometimes referred to as database number, +DB, etc). + database_index: 0 + ## The maximum number of concurrent active connections to Redis. + maximum_active_connections: 10 + ## The target number of idle connections to have open ready for work. Useful when opening connections is +slow. + minimum_idle_connections: 0 + ## The Redis TLS configuration. If defined will require a TLS connection to the Redis instance(s). + # tls: + ## The server subject name to check the servers certificate against during the validation process. + ## This option is not required if the certificate has a SAN which matches the host option. + # server_name: myredis.example.com + ## Skip verifying the server certificate entirely. In preference to setting this we strongly recommend you +add the + ## certificate or the certificate of the authority signing the certificate to the certificates directory which is + ## defined by the `certificates_directory` option at the top of the configuration. + ## It's important to note the public key should be added to the directory, not the private key. + ## This option is strongly discouraged but may be useful in some self-signed situations where validation is +not + ## important to the administrator. + # skip_verify: false + ## Minimum TLS version for the connection. + # minimum_version: TLS1.2 + ## Maximum TLS version for the connection. + # maximum_version: TLS1.3 + ## The certificate chain used with the private_key if the server requests TLS Client Authentication + ## i.e. Mutual TLS. + # certificate_chain: | + # -----BEGIN CERTIFICATE----- + # MIIC5jCCAc6gAwIBAgIRAK4Sj7FiN6PXo/urPfO4E7owDQYJKoZIhvcNAQELBQAw + # EzERMA8GA1UEChMIQXV0aGVsaWEwHhcNNzAwMTAxMDAwMDAwWhcNNzEwMTAxMDAw + # MDAwWjATMREwDwYDVQQKEwhBdXRoZWxpYTCCASIwDQYJKoZIhvcNAQEBBQADggEP + # ADCCAQoCggEBAPKv3pSyP4ozGEiVLJ14dIWFCEGEgq7WUMI0SZZqQA2ID0L59U/Q + # /Usyy7uC9gfMUzODTpANtkOjFQcQAsxlR1FOjVBrX5QgjSvXwbQn3DtwMA7XWSl6 + # LuYx2rBYSlMSN5UZQm/RxMtXfLK2b51WgEEYDFi+nECSqKzR4R54eOPkBEWRfvuY + # 91AMjlhpivg8e4JWkq4LVQUKbmiFYwIdK8XQiN4blY9WwXwJFYs5sQ/UYMwBFi0H + # kWOh7GEjfxgoUOPauIueZSMSlQp7zqAH39N0ZSYb6cS0Npj57QoWZSY3ak87ebcR + # Nf4rCvZLby7LoN7qYCKxmCaDD3x2+NYpWH8CAwEAAaM1MDMwDgYDVR0PAQH/BAQD + # AgWgMBMGA1UdJQQMMAoGCCsGAQUFBwMBMAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcN + # AQELBQADggEBAHSITqIQSNzonFl3DzxHPEzr2hp6peo45buAAtu8FZHoA+U7Icfh + # /ZXjPg7Xz+hgFwM/DTNGXkMWacQA/PaNWvZspgRJf2AXvNbMSs2UQODr7Tbv+Fb4 + # lyblmMUNYFMCFVAMU0eIxXAFq2qcwv8UMcQFT0Z/35s6PVOakYnAGGQjTfp5Ljuq + # wsdc/xWmM0cHWube6sdRRUD7SY20KU/kWzl8iFO0VbSSrDf1AlEhnLEkp1SPaxXg + # OdBnl98MeoramNiJ7NT6Jnyb3zZ578fjaWfThiBpagItI8GZmG4s4Ovh2JbheN8i + # ZsjNr9jqHTjhyLVbDRlmJzcqoj4JhbKs6/I^invalid DO NOT USE= + # -----END CERTIFICATE----- + # -----BEGIN CERTIFICATE----- + # MIIDBDCCAeygAwIBAgIRALJsPg21kA0zY4F1wUCIuoMwDQYJKoZIhvcNAQELBQAw + # EzERMA8GA1UEChMIQXV0aGVsaWEwHhcNNzAwMTAxMDAwMDAwWhcNNzEwMTAxMDAw + # MDAwWjATMREwDwYDVQQKEwhBdXRoZWxpYTCCASIwDQYJKoZIhvcNAQEBBQADggEP + # ADCCAQoCggEBAMXHBvVxUzYk0u34/DINMSF+uiOekKOAjOrC6Mi9Ww8ytPVO7t2S + # zfTvM+XnEJqkFQFgimERfG/eGhjF9XIEY6LtnXe8ATvOK4nTwdufzBaoeQu3Gd50 + # 5VXr6OHRo//ErrGvFXwP3g8xLePABsi/fkH3oDN+ztewOBMDzpd+KgTrk8ysv2ou + # kNRMKFZZqASvCgv0LD5KWvUCnL6wgf1oTXG7aztduA4oSkUP321GpOmBC5+5ElU7 + # ysoRzvD12o9QJ/IfEaulIX06w9yVMo60C/h6A3U6GdkT1SiyTIqR7v7KU/IWd/Qi + # Lfftcj91VhCmJ73Meff2e2S2PrpjdXbG5FMCAwEAAaNTMFEwDgYDVR0PAQH/BAQD + # AgKkMA8GA1UdJQQIMAYGBFUdJQAwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU + # Z7AtA3mzFc0InSBA5fiMfeLXA3owDQYJKoZIhvcNAQELBQADggEBAEE5hm1mtlk/ + # kviCoHH4evbpw7rxPxDftIQlqYTtvMM4eWY/6icFoSZ4fUHEWYyps8SsPu/8f2tf + # 71LGgZn0FdHi1QU2H8m0HHK7TFw+5Q6RLrLdSyk0PItJ71s9en7r8pX820nAFEHZ + # HkOSfJZ7B5hFgUDkMtVM6bardXAhoqcMk4YCU96e9d4PB4eI+xGc+mNuYvov3RbB + # D0s8ICyojeyPVLerz4wHjZu68Z5frAzhZ68YbzNs8j2fIBKKHkHyLG1iQyF+LJVj + # 2PjCP+auJsj6fQQpMGoyGtpLcSDh+ptcTngUD8JsWipzTCjmaNqdPHAOYmcgtf4b + # qocikt3WAdU^invalid DO NOT USE= + # -----END CERTIFICATE----- + ## The private key used with the certificate_chain if the server requests TLS Client Authentication + ## i.e. Mutual TLS. + # private_key: | + # -----BEGIN RSA PRIVATE KEY----- + # MIIEpAIBAAKCAQEA8q/elLI/ijMYSJUsnXh0hYUIQYSCrtZQwjRJlmpADYgPQvn1 + # T9D9SzLLu4L2B8xTM4NOkA22Q6MVBxACzGVHUU6NUGtflCCNK9fBtCfcO3AwDtdZ + # KXou5jHasFhKUxI3lRlCb9HEy1d8srZvnVaAQRgMWL6cQJKorNHhHnh44+QERZF+ + # +5j3UAyOWGmK+Dx7glaSrgtVBQpuaIVjAh0rxdCI3huVj1bBfAkVizmxD9RgzAEW + # LQeRY6HsYSN/GChQ49q4i55lIxKVCnvOoAff03RlJhvpxLQ2mPntChZlJjdqTzt5 + # txE1/isK9ktvLsug3upgIrGYJoMPfHb41ilYfwIDAQABAoIBAQDTOdFf2JjHH1um + # aPgRAvNf9v7Nj5jytaRKs5nM6iNf46ls4QPreXnMhqSeSwj6lpNgBYxOgzC9Q+cc + # Y4ob/paJJPaIJTxmP8K/gyWcOQlNToL1l+eJ20eQoZm23NGr5fIsunSBwLEpTrdB + # ENqqtcwhW937K8Pxy/Q1nuLyU2bc6Tn/ivLozc8n27dpQWWKh8537VY7ancIaACr + # LJJLYxKqhQpjtBWAyCDvZQirnAOm9KnvIHaGXIswCZ4Xbsu0Y9NL+woARPyRVQvG + # jfxy4EmO9s1s6y7OObSukwKDSNihAKHx/VIbvVWx8g2Lv5fGOa+J2Y7o9Qurs8t5 + # BQwMTt0BAoGBAPUw5Z32EszNepAeV3E2mPFUc5CLiqAxagZJuNDO2pKtyN29ETTR + # Ma4O1cWtGb6RqcNNN/Iukfkdk27Q5nC9VJSUUPYelOLc1WYOoUf6oKRzE72dkMQV + # R4bf6TkjD+OVR17fAfkswkGahZ5XA7j48KIQ+YC4jbnYKSxZTYyKPjH/AoGBAP1i + # tqXt36OVlP+y84wWqZSjMelBIVa9phDVGJmmhz3i1cMni8eLpJzWecA3pfnG6Tm9 + # ze5M4whASleEt+M00gEvNaU9ND+z0wBfi+/DwJYIbv8PQdGrBiZFrPhTPjGQUldR + # lXccV2meeLZv7TagVxSi3DO6dSJfSEHyemd5j9mBAoGAX8Hv+0gOQZQCSOTAq8Nx + # 6dZcp9gHlNaXnMsP9eTDckOSzh636JPGvj6m+GPJSSbkURUIQ3oyokMNwFqvlNos + # fTaLhAOfjBZI9WnDTTQxpugWjphJ4HqbC67JC/qIiw5S6FdaEvGLEEoD4zoChywZ + # 9oGAn+fz2d/0/JAH/FpFPgsCgYEAp/ipZgPzziiZ9ov1wbdAQcWRj7RaWnssPFpX + # jXwEiXT3CgEMO4MJ4+KWIWOChrti3qFBg6i6lDyyS6Qyls7sLFbUdC7HlTcrOEMe + # rBoTcCI1GqZNlqWOVQ65ZIEiaI7o1vPBZo2GMQEZuq8mDKFsOMThvvTrM5cAep84 + # n6HJR4ECgYABWcbsSnr0MKvVth/inxjbKapbZnp2HUCuw87Ie5zK2Of/tbC20wwk + # yKw3vrGoE3O1t1g2m2tn8UGGASeZ842jZWjIODdSi5+icysQGuULKt86h/woz2SQ + # 27GoE2i5mh6Yez6VAYbUuns3FcwIsMyWLq043Tu2DNkx9ijOOAuQzw^invalid.. + # DO NOT USE== + # -----END RSA PRIVATE KEY----- + ## The Redis HA configuration options. + ## This provides specific options to Redis Sentinel, sentinel_name must be defined (Master Name). + # high_availability: + ## Sentinel Name / Master Name. + # sentinel_name: mysentinel + ## Specific username for Redis Sentinel. The node username and password is configured above. + # sentinel_username: sentinel_specific_user + ## Specific password for Redis Sentinel. The node username and password is configured above. + # sentinel_password: sentinel_specific_pass + ## The additional nodes to pre-seed the redis provider with (for sentinel). + ## If the host in the above section is defined, it will be combined with this list to connect to sentinel. + ## For high availability to be used you must have either defined; the host above or at least one node below. + # nodes: + # - host: sentinel-node1 + # port: 6379 + # - host: sentinel-node2 + # port: 6379 + ## Choose the host with the lowest latency. + # route_by_latency: false + ## Choose the host randomly. + # route_randomly: false +## +## Regulation Configuration +## +## This mechanism prevents attackers from brute forcing the first factor. It bans the user if too many attempts +are made +## in a short period of time. +regulation: + ## The number of failed login attempts before user is banned. Set it to 0 to disable regulation. + max_retries: 3 + ## The time range during which the user can attempt login before being banned. The user is banned if the + ## authentication failed 'max_retries' times in a 'find_time' seconds window. Find Time accepts duration +notation. + ## See: https://www.authelia.com/c/common#duration-notation-format + find_time: 10m + ## The length of time before a banned user can login again. Ban Time accepts duration notation. + ## See: https://www.authelia.com/c/common#duration-notation-format + ban_time: 12h +## +## Storage Provider Configuration +## +## The available providers are: `local`, `mysql`, `postgres`. You must use one and only one of these providers. +storage: + ## The encryption key that is used to encrypt sensitive information in the database. Must be a string with a +minimum + ## length of 20. Please see the docs if you configure this with an undesirable key and need to change it, you +MUST use + ## the CLI to change this in the database if you want to change it from a previously configured value. + encryption_key: REDACTED + ## + ## Local (Storage Provider) + ## + ## This stores the data in a SQLite3 Database. + ## This is only recommended for lightweight non-stateful installations. + ## + ## Important: Kubernetes (or HA) users must read https://www.authelia.com/t/statelessness + ## + # local: + ## Path to the SQLite3 Database. + # path: /config/db.sqlite3 + ## + ## MySQL / MariaDB (Storage Provider) + ## + mysql: + host: mysql + port: 3306 + database: authelia + username: authelia + ## Password can also be set using a secret: https://www.authelia.com/c/secrets + password: REDACTED + timeout: 5s + ## MySQL TLS settings. Configuring this requires TLS. + # tls: + ## The server subject name to check the servers certificate against during the validation process. + ## This option is not required if the certificate has a SAN which matches the host option. + # server_name: mysql.example.com + ## Skip verifying the server certificate entirely. In preference to setting this we strongly recommend you +add the + ## certificate or the certificate of the authority signing the certificate to the certificates directory which is + ## defined by the `certificates_directory` option at the top of the configuration. + ## It's important to note the public key should be added to the directory, not the private key. + ## This option is strongly discouraged but may be useful in some self-signed situations where validation is +not + ## important to the administrator. + # skip_verify: false + ## Minimum TLS version for the connection. + # minimum_version: TLS1.2 + ## Maximum TLS version for the connection. + # maximum_version: TLS1.3 + ## The certificate chain used with the private_key if the server requests TLS Client Authentication + ## i.e. Mutual TLS. + # certificate_chain: | + # -----BEGIN CERTIFICATE----- + # MIIC5jCCAc6gAwIBAgIRAK4Sj7FiN6PXo/urPfO4E7owDQYJKoZIhvcNAQELBQAw + # EzERMA8GA1UEChMIQXV0aGVsaWEwHhcNNzAwMTAxMDAwMDAwWhcNNzEwMTAxMDAw + # MDAwWjATMREwDwYDVQQKEwhBdXRoZWxpYTCCASIwDQYJKoZIhvcNAQEBBQADggEP + # ADCCAQoCggEBAPKv3pSyP4ozGEiVLJ14dIWFCEGEgq7WUMI0SZZqQA2ID0L59U/Q + # /Usyy7uC9gfMUzODTpANtkOjFQcQAsxlR1FOjVBrX5QgjSvXwbQn3DtwMA7XWSl6 + # LuYx2rBYSlMSN5UZQm/RxMtXfLK2b51WgEEYDFi+nECSqKzR4R54eOPkBEWRfvuY + # 91AMjlhpivg8e4JWkq4LVQUKbmiFYwIdK8XQiN4blY9WwXwJFYs5sQ/UYMwBFi0H + # kWOh7GEjfxgoUOPauIueZSMSlQp7zqAH39N0ZSYb6cS0Npj57QoWZSY3ak87ebcR + # Nf4rCvZLby7LoN7qYCKxmCaDD3x2+NYpWH8CAwEAAaM1MDMwDgYDVR0PAQH/BAQD + # AgWgMBMGA1UdJQQMMAoGCCsGAQUFBwMBMAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcN + # AQELBQADggEBAHSITqIQSNzonFl3DzxHPEzr2hp6peo45buAAtu8FZHoA+U7Icfh + # /ZXjPg7Xz+hgFwM/DTNGXkMWacQA/PaNWvZspgRJf2AXvNbMSs2UQODr7Tbv+Fb4 + # lyblmMUNYFMCFVAMU0eIxXAFq2qcwv8UMcQFT0Z/35s6PVOakYnAGGQjTfp5Ljuq + # wsdc/xWmM0cHWube6sdRRUD7SY20KU/kWzl8iFO0VbSSrDf1AlEhnLEkp1SPaxXg + # OdBnl98MeoramNiJ7NT6Jnyb3zZ578fjaWfThiBpagItI8GZmG4s4Ovh2JbheN8i + # ZsjNr9jqHTjhyLVbDRlmJzcqoj4JhbKs6/I^invalid DO NOT USE= + # -----END CERTIFICATE----- + # -----BEGIN CERTIFICATE----- + # MIIDBDCCAeygAwIBAgIRALJsPg21kA0zY4F1wUCIuoMwDQYJKoZIhvcNAQELBQAw + # EzERMA8GA1UEChMIQXV0aGVsaWEwHhcNNzAwMTAxMDAwMDAwWhcNNzEwMTAxMDAw + # MDAwWjATMREwDwYDVQQKEwhBdXRoZWxpYTCCASIwDQYJKoZIhvcNAQEBBQADggEP + # ADCCAQoCggEBAMXHBvVxUzYk0u34/DINMSF+uiOekKOAjOrC6Mi9Ww8ytPVO7t2S + # zfTvM+XnEJqkFQFgimERfG/eGhjF9XIEY6LtnXe8ATvOK4nTwdufzBaoeQu3Gd50 + # 5VXr6OHRo//ErrGvFXwP3g8xLePABsi/fkH3oDN+ztewOBMDzpd+KgTrk8ysv2ou + # kNRMKFZZqASvCgv0LD5KWvUCnL6wgf1oTXG7aztduA4oSkUP321GpOmBC5+5ElU7 + # ysoRzvD12o9QJ/IfEaulIX06w9yVMo60C/h6A3U6GdkT1SiyTIqR7v7KU/IWd/Qi + # Lfftcj91VhCmJ73Meff2e2S2PrpjdXbG5FMCAwEAAaNTMFEwDgYDVR0PAQH/BAQD + # AgKkMA8GA1UdJQQIMAYGBFUdJQAwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU + # Z7AtA3mzFc0InSBA5fiMfeLXA3owDQYJKoZIhvcNAQELBQADggEBAEE5hm1mtlk/ + # kviCoHH4evbpw7rxPxDftIQlqYTtvMM4eWY/6icFoSZ4fUHEWYyps8SsPu/8f2tf + # 71LGgZn0FdHi1QU2H8m0HHK7TFw+5Q6RLrLdSyk0PItJ71s9en7r8pX820nAFEHZ + # HkOSfJZ7B5hFgUDkMtVM6bardXAhoqcMk4YCU96e9d4PB4eI+xGc+mNuYvov3RbB + # D0s8ICyojeyPVLerz4wHjZu68Z5frAzhZ68YbzNs8j2fIBKKHkHyLG1iQyF+LJVj + # 2PjCP+auJsj6fQQpMGoyGtpLcSDh+ptcTngUD8JsWipzTCjmaNqdPHAOYmcgtf4b + # qocikt3WAdU^invalid DO NOT USE= + # -----END CERTIFICATE----- + ## The private key used with the certificate_chain if the server requests TLS Client Authentication + ## i.e. Mutual TLS. + # private_key: | + # -----BEGIN RSA PRIVATE KEY----- + # MIIEpAIBAAKCAQEA8q/elLI/ijMYSJUsnXh0hYUIQYSCrtZQwjRJlmpADYgPQvn1 + # T9D9SzLLu4L2B8xTM4NOkA22Q6MVBxACzGVHUU6NUGtflCCNK9fBtCfcO3AwDtdZ + # KXou5jHasFhKUxI3lRlCb9HEy1d8srZvnVaAQRgMWL6cQJKorNHhHnh44+QERZF+ + # +5j3UAyOWGmK+Dx7glaSrgtVBQpuaIVjAh0rxdCI3huVj1bBfAkVizmxD9RgzAEW + # LQeRY6HsYSN/GChQ49q4i55lIxKVCnvOoAff03RlJhvpxLQ2mPntChZlJjdqTzt5 + # txE1/isK9ktvLsug3upgIrGYJoMPfHb41ilYfwIDAQABAoIBAQDTOdFf2JjHH1um + # aPgRAvNf9v7Nj5jytaRKs5nM6iNf46ls4QPreXnMhqSeSwj6lpNgBYxOgzC9Q+cc + # Y4ob/paJJPaIJTxmP8K/gyWcOQlNToL1l+eJ20eQoZm23NGr5fIsunSBwLEpTrdB + # ENqqtcwhW937K8Pxy/Q1nuLyU2bc6Tn/ivLozc8n27dpQWWKh8537VY7ancIaACr + # LJJLYxKqhQpjtBWAyCDvZQirnAOm9KnvIHaGXIswCZ4Xbsu0Y9NL+woARPyRVQvG + # jfxy4EmO9s1s6y7OObSukwKDSNihAKHx/VIbvVWx8g2Lv5fGOa+J2Y7o9Qurs8t5 + # BQwMTt0BAoGBAPUw5Z32EszNepAeV3E2mPFUc5CLiqAxagZJuNDO2pKtyN29ETTR + # Ma4O1cWtGb6RqcNNN/Iukfkdk27Q5nC9VJSUUPYelOLc1WYOoUf6oKRzE72dkMQV + # R4bf6TkjD+OVR17fAfkswkGahZ5XA7j48KIQ+YC4jbnYKSxZTYyKPjH/AoGBAP1i + # tqXt36OVlP+y84wWqZSjMelBIVa9phDVGJmmhz3i1cMni8eLpJzWecA3pfnG6Tm9 + # ze5M4whASleEt+M00gEvNaU9ND+z0wBfi+/DwJYIbv8PQdGrBiZFrPhTPjGQUldR + # lXccV2meeLZv7TagVxSi3DO6dSJfSEHyemd5j9mBAoGAX8Hv+0gOQZQCSOTAq8Nx + # 6dZcp9gHlNaXnMsP9eTDckOSzh636JPGvj6m+GPJSSbkURUIQ3oyokMNwFqvlNos + # fTaLhAOfjBZI9WnDTTQxpugWjphJ4HqbC67JC/qIiw5S6FdaEvGLEEoD4zoChywZ + # 9oGAn+fz2d/0/JAH/FpFPgsCgYEAp/ipZgPzziiZ9ov1wbdAQcWRj7RaWnssPFpX + # jXwEiXT3CgEMO4MJ4+KWIWOChrti3qFBg6i6lDyyS6Qyls7sLFbUdC7HlTcrOEMe + # rBoTcCI1GqZNlqWOVQ65ZIEiaI7o1vPBZo2GMQEZuq8mDKFsOMThvvTrM5cAep84 + # n6HJR4ECgYABWcbsSnr0MKvVth/inxjbKapbZnp2HUCuw87Ie5zK2Of/tbC20wwk + # yKw3vrGoE3O1t1g2m2tn8UGGASeZ842jZWjIODdSi5+icysQGuULKt86h/woz2SQ + # 27GoE2i5mh6Yez6VAYbUuns3FcwIsMyWLq043Tu2DNkx9ijOOAuQzw^invalid.. + # DO NOT USE== + # -----END RSA PRIVATE KEY----- + ## + ## PostgreSQL (Storage Provider) + ## + # postgres: + # host: 127.0.0.1 + # port: 5432 + # database: authelia + # schema: public + # username: authelia + ## Password can also be set using a secret: https://www.authelia.com/c/secrets + # password: mypassword + # timeout: 5s + ## PostgreSQL TLS settings. Configuring this requires TLS. + # tls: + ## The server subject name to check the servers certificate against during the validation process. + ## This option is not required if the certificate has a SAN which matches the host option. + # server_name: postgres.example.com + ## Skip verifying the server certificate entirely. In preference to setting this we strongly recommend you +add the + ## certificate or the certificate of the authority signing the certificate to the certificates directory which is + ## defined by the `certificates_directory` option at the top of the configuration. + ## It's important to note the public key should be added to the directory, not the private key. + ## This option is strongly discouraged but may be useful in some self-signed situations where validation is +not + ## important to the administrator. + # skip_verify: false + ## Minimum TLS version for the connection. + # minimum_version: TLS1.2 + ## Maximum TLS version for the connection. + # maximum_version: TLS1.3 + ## The certificate chain used with the private_key if the server requests TLS Client Authentication + ## i.e. Mutual TLS. + # certificate_chain: | + # -----BEGIN CERTIFICATE----- + # MIIC5jCCAc6gAwIBAgIRAK4Sj7FiN6PXo/urPfO4E7owDQYJKoZIhvcNAQELBQAw + # EzERMA8GA1UEChMIQXV0aGVsaWEwHhcNNzAwMTAxMDAwMDAwWhcNNzEwMTAxMDAw + # MDAwWjATMREwDwYDVQQKEwhBdXRoZWxpYTCCASIwDQYJKoZIhvcNAQEBBQADggEP + # ADCCAQoCggEBAPKv3pSyP4ozGEiVLJ14dIWFCEGEgq7WUMI0SZZqQA2ID0L59U/Q + # /Usyy7uC9gfMUzODTpANtkOjFQcQAsxlR1FOjVBrX5QgjSvXwbQn3DtwMA7XWSl6 + # LuYx2rBYSlMSN5UZQm/RxMtXfLK2b51WgEEYDFi+nECSqKzR4R54eOPkBEWRfvuY + # 91AMjlhpivg8e4JWkq4LVQUKbmiFYwIdK8XQiN4blY9WwXwJFYs5sQ/UYMwBFi0H + # kWOh7GEjfxgoUOPauIueZSMSlQp7zqAH39N0ZSYb6cS0Npj57QoWZSY3ak87ebcR + # Nf4rCvZLby7LoN7qYCKxmCaDD3x2+NYpWH8CAwEAAaM1MDMwDgYDVR0PAQH/BAQD + # AgWgMBMGA1UdJQQMMAoGCCsGAQUFBwMBMAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcN + # AQELBQADggEBAHSITqIQSNzonFl3DzxHPEzr2hp6peo45buAAtu8FZHoA+U7Icfh + # /ZXjPg7Xz+hgFwM/DTNGXkMWacQA/PaNWvZspgRJf2AXvNbMSs2UQODr7Tbv+Fb4 + # lyblmMUNYFMCFVAMU0eIxXAFq2qcwv8UMcQFT0Z/35s6PVOakYnAGGQjTfp5Ljuq + # wsdc/xWmM0cHWube6sdRRUD7SY20KU/kWzl8iFO0VbSSrDf1AlEhnLEkp1SPaxXg + # OdBnl98MeoramNiJ7NT6Jnyb3zZ578fjaWfThiBpagItI8GZmG4s4Ovh2JbheN8i + # ZsjNr9jqHTjhyLVbDRlmJzcqoj4JhbKs6/I^invalid DO NOT USE= + # -----END CERTIFICATE----- + # -----BEGIN CERTIFICATE----- + # MIIDBDCCAeygAwIBAgIRALJsPg21kA0zY4F1wUCIuoMwDQYJKoZIhvcNAQELBQAw + # EzERMA8GA1UEChMIQXV0aGVsaWEwHhcNNzAwMTAxMDAwMDAwWhcNNzEwMTAxMDAw + # MDAwWjATMREwDwYDVQQKEwhBdXRoZWxpYTCCASIwDQYJKoZIhvcNAQEBBQADggEP + # ADCCAQoCggEBAMXHBvVxUzYk0u34/DINMSF+uiOekKOAjOrC6Mi9Ww8ytPVO7t2S + # zfTvM+XnEJqkFQFgimERfG/eGhjF9XIEY6LtnXe8ATvOK4nTwdufzBaoeQu3Gd50 + # 5VXr6OHRo//ErrGvFXwP3g8xLePABsi/fkH3oDN+ztewOBMDzpd+KgTrk8ysv2ou + # kNRMKFZZqASvCgv0LD5KWvUCnL6wgf1oTXG7aztduA4oSkUP321GpOmBC5+5ElU7 + # ysoRzvD12o9QJ/IfEaulIX06w9yVMo60C/h6A3U6GdkT1SiyTIqR7v7KU/IWd/Qi + # Lfftcj91VhCmJ73Meff2e2S2PrpjdXbG5FMCAwEAAaNTMFEwDgYDVR0PAQH/BAQD + # AgKkMA8GA1UdJQQIMAYGBFUdJQAwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU + # Z7AtA3mzFc0InSBA5fiMfeLXA3owDQYJKoZIhvcNAQELBQADggEBAEE5hm1mtlk/ + # kviCoHH4evbpw7rxPxDftIQlqYTtvMM4eWY/6icFoSZ4fUHEWYyps8SsPu/8f2tf + # 71LGgZn0FdHi1QU2H8m0HHK7TFw+5Q6RLrLdSyk0PItJ71s9en7r8pX820nAFEHZ + # HkOSfJZ7B5hFgUDkMtVM6bardXAhoqcMk4YCU96e9d4PB4eI+xGc+mNuYvov3RbB + # D0s8ICyojeyPVLerz4wHjZu68Z5frAzhZ68YbzNs8j2fIBKKHkHyLG1iQyF+LJVj + # 2PjCP+auJsj6fQQpMGoyGtpLcSDh+ptcTngUD8JsWipzTCjmaNqdPHAOYmcgtf4b + # qocikt3WAdU^invalid DO NOT USE= + # -----END CERTIFICATE----- + ## The private key used with the certificate_chain if the server requests TLS Client Authentication + ## i.e. Mutual TLS. + # private_key: | + # -----BEGIN RSA PRIVATE KEY----- + # MIIEpAIBAAKCAQEA8q/elLI/ijMYSJUsnXh0hYUIQYSCrtZQwjRJlmpADYgPQvn1 + # T9D9SzLLu4L2B8xTM4NOkA22Q6MVBxACzGVHUU6NUGtflCCNK9fBtCfcO3AwDtdZ + # KXou5jHasFhKUxI3lRlCb9HEy1d8srZvnVaAQRgMWL6cQJKorNHhHnh44+QERZF+ + # +5j3UAyOWGmK+Dx7glaSrgtVBQpuaIVjAh0rxdCI3huVj1bBfAkVizmxD9RgzAEW + # LQeRY6HsYSN/GChQ49q4i55lIxKVCnvOoAff03RlJhvpxLQ2mPntChZlJjdqTzt5 + # txE1/isK9ktvLsug3upgIrGYJoMPfHb41ilYfwIDAQABAoIBAQDTOdFf2JjHH1um + # aPgRAvNf9v7Nj5jytaRKs5nM6iNf46ls4QPreXnMhqSeSwj6lpNgBYxOgzC9Q+cc + # Y4ob/paJJPaIJTxmP8K/gyWcOQlNToL1l+eJ20eQoZm23NGr5fIsunSBwLEpTrdB + # ENqqtcwhW937K8Pxy/Q1nuLyU2bc6Tn/ivLozc8n27dpQWWKh8537VY7ancIaACr + # LJJLYxKqhQpjtBWAyCDvZQirnAOm9KnvIHaGXIswCZ4Xbsu0Y9NL+woARPyRVQvG + # jfxy4EmO9s1s6y7OObSukwKDSNihAKHx/VIbvVWx8g2Lv5fGOa+J2Y7o9Qurs8t5 + # BQwMTt0BAoGBAPUw5Z32EszNepAeV3E2mPFUc5CLiqAxagZJuNDO2pKtyN29ETTR + # Ma4O1cWtGb6RqcNNN/Iukfkdk27Q5nC9VJSUUPYelOLc1WYOoUf6oKRzE72dkMQV + # R4bf6TkjD+OVR17fAfkswkGahZ5XA7j48KIQ+YC4jbnYKSxZTYyKPjH/AoGBAP1i + # tqXt36OVlP+y84wWqZSjMelBIVa9phDVGJmmhz3i1cMni8eLpJzWecA3pfnG6Tm9 + # ze5M4whASleEt+M00gEvNaU9ND+z0wBfi+/DwJYIbv8PQdGrBiZFrPhTPjGQUldR + # lXccV2meeLZv7TagVxSi3DO6dSJfSEHyemd5j9mBAoGAX8Hv+0gOQZQCSOTAq8Nx + # 6dZcp9gHlNaXnMsP9eTDckOSzh636JPGvj6m+GPJSSbkURUIQ3oyokMNwFqvlNos + # fTaLhAOfjBZI9WnDTTQxpugWjphJ4HqbC67JC/qIiw5S6FdaEvGLEEoD4zoChywZ + # 9oGAn+fz2d/0/JAH/FpFPgsCgYEAp/ipZgPzziiZ9ov1wbdAQcWRj7RaWnssPFpX + # jXwEiXT3CgEMO4MJ4+KWIWOChrti3qFBg6i6lDyyS6Qyls7sLFbUdC7HlTcrOEMe + # rBoTcCI1GqZNlqWOVQ65ZIEiaI7o1vPBZo2GMQEZuq8mDKFsOMThvvTrM5cAep84 + # n6HJR4ECgYABWcbsSnr0MKvVth/inxjbKapbZnp2HUCuw87Ie5zK2Of/tbC20wwk + # yKw3vrGoE3O1t1g2m2tn8UGGASeZ842jZWjIODdSi5+icysQGuULKt86h/woz2SQ + # 27GoE2i5mh6Yez6VAYbUuns3FcwIsMyWLq043Tu2DNkx9ijOOAuQzw^invalid.. + # DO NOT USE== + # -----END RSA PRIVATE KEY----- +## +## Notification Provider +## +## Notifications are sent to users when they require a password reset, a Webauthn registration or a TOTP +registration. +## The available providers are: filesystem, smtp. You must use only one of these providers. +notifier: + ## You can disable the notifier startup check by setting this to true. + disable_startup_check: false + ## + ## File System (Notification Provider) + ## + ## Important: Kubernetes (or HA) users must read https://www.authelia.com/t/statelessness + ## +# filesystem: +# filename: /config/notification.txt + ## + ## SMTP (Notification Provider) + ## + ## Use a SMTP server for sending notifications. Authelia uses the PLAIN or LOGIN methods to authenticate. + ## [Security] By default Authelia will: + ## - force all SMTP connections over TLS including unauthenticated connections + ## - use the disable_require_tls boolean value to disable this requirement + ## (only works for unauthenticated connections) + ## - validate the SMTP server x509 certificate during the TLS handshake against the hosts trusted certificates + ## (configure in tls section) + smtp: + ## The SMTP host to connect to. + host: smtp.gmail.com + ## The port to connect to the SMTP host on. + port: 587 + ## The connection timeout. + timeout: 5s + ## The username used for SMTP authentication. + username: [emailaddressrelay]@gmail.com + ## The password used for SMTP authentication. + ## Can also be set using a secret: https://www.authelia.com/c/secrets + password: REDACTED + ## The sender is used to is used for the MAIL FROM command and the FROM header. + ## If this is not defined and the username is an email, we use the username as this value. This can either be +just + ## an email address or the RFC5322 'Name ' format. + sender: "Authelia " + ## HELO/EHLO Identifier. Some SMTP Servers may reject the default of localhost. + identifier: [domain.tld] + ## Subject configuration of the emails sent. {title} is replaced by the text from the notifier. + subject: "[Authelia] {title}" + ## This address is used during the startup check to verify the email configuration is correct. + ## It's not important what it is except if your email server only allows local delivery. + startup_check_address: [emailaddressrelay]@gmail.com + ## By default we require some form of TLS. This disables this check though is not advised. + # disable_require_tls: false + ## Disables sending HTML formatted emails. + # disable_html_emails: false + tls: + ## The server subject name to check the servers certificate against during the validation process. + ## This option is not required if the certificate has a SAN which matches the host option. + server_name: smtp.gmail.com + ## Skip verifying the server certificate entirely. In preference to setting this we strongly recommend you +add the + ## certificate or the certificate of the authority signing the certificate to the certificates directory which is + ## defined by the `certificates_directory` option at the top of the configuration. + ## It's important to note the public key should be added to the directory, not the private key. + ## This option is strongly discouraged but may be useful in some self-signed situations where validation is +not + ## important to the administrator. + # skip_verify: false + ## Minimum TLS version for the connection. + # minimum_version: TLS1.2 + ## Maximum TLS version for the connection. + # maximum_version: TLS1.3 + ## The certificate chain used with the private_key if the server requests TLS Client Authentication + ## i.e. Mutual TLS. + # certificate_chain: | + # -----BEGIN CERTIFICATE----- + # MIIC5jCCAc6gAwIBAgIRAK4Sj7FiN6PXo/urPfO4E7owDQYJKoZIhvcNAQELBQAw + # EzERMA8GA1UEChMIQXV0aGVsaWEwHhcNNzAwMTAxMDAwMDAwWhcNNzEwMTAxMDAw + # MDAwWjATMREwDwYDVQQKEwhBdXRoZWxpYTCCASIwDQYJKoZIhvcNAQEBBQADggEP + # ADCCAQoCggEBAPKv3pSyP4ozGEiVLJ14dIWFCEGEgq7WUMI0SZZqQA2ID0L59U/Q + # /Usyy7uC9gfMUzODTpANtkOjFQcQAsxlR1FOjVBrX5QgjSvXwbQn3DtwMA7XWSl6 + # LuYx2rBYSlMSN5UZQm/RxMtXfLK2b51WgEEYDFi+nECSqKzR4R54eOPkBEWRfvuY + # 91AMjlhpivg8e4JWkq4LVQUKbmiFYwIdK8XQiN4blY9WwXwJFYs5sQ/UYMwBFi0H + # kWOh7GEjfxgoUOPauIueZSMSlQp7zqAH39N0ZSYb6cS0Npj57QoWZSY3ak87ebcR + # Nf4rCvZLby7LoN7qYCKxmCaDD3x2+NYpWH8CAwEAAaM1MDMwDgYDVR0PAQH/BAQD + # AgWgMBMGA1UdJQQMMAoGCCsGAQUFBwMBMAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcN + # AQELBQADggEBAHSITqIQSNzonFl3DzxHPEzr2hp6peo45buAAtu8FZHoA+U7Icfh + # /ZXjPg7Xz+hgFwM/DTNGXkMWacQA/PaNWvZspgRJf2AXvNbMSs2UQODr7Tbv+Fb4 + # lyblmMUNYFMCFVAMU0eIxXAFq2qcwv8UMcQFT0Z/35s6PVOakYnAGGQjTfp5Ljuq + # wsdc/xWmM0cHWube6sdRRUD7SY20KU/kWzl8iFO0VbSSrDf1AlEhnLEkp1SPaxXg + # OdBnl98MeoramNiJ7NT6Jnyb3zZ578fjaWfThiBpagItI8GZmG4s4Ovh2JbheN8i + # ZsjNr9jqHTjhyLVbDRlmJzcqoj4JhbKs6/I^invalid DO NOT USE= + # -----END CERTIFICATE----- + # -----BEGIN CERTIFICATE----- + # MIIDBDCCAeygAwIBAgIRALJsPg21kA0zY4F1wUCIuoMwDQYJKoZIhvcNAQELBQAw + # EzERMA8GA1UEChMIQXV0aGVsaWEwHhcNNzAwMTAxMDAwMDAwWhcNNzEwMTAxMDAw + # MDAwWjATMREwDwYDVQQKEwhBdXRoZWxpYTCCASIwDQYJKoZIhvcNAQEBBQADggEP + # ADCCAQoCggEBAMXHBvVxUzYk0u34/DINMSF+uiOekKOAjOrC6Mi9Ww8ytPVO7t2S + # zfTvM+XnEJqkFQFgimERfG/eGhjF9XIEY6LtnXe8ATvOK4nTwdufzBaoeQu3Gd50 + # 5VXr6OHRo//ErrGvFXwP3g8xLePABsi/fkH3oDN+ztewOBMDzpd+KgTrk8ysv2ou + # kNRMKFZZqASvCgv0LD5KWvUCnL6wgf1oTXG7aztduA4oSkUP321GpOmBC5+5ElU7 + # ysoRzvD12o9QJ/IfEaulIX06w9yVMo60C/h6A3U6GdkT1SiyTIqR7v7KU/IWd/Qi + # Lfftcj91VhCmJ73Meff2e2S2PrpjdXbG5FMCAwEAAaNTMFEwDgYDVR0PAQH/BAQD + # AgKkMA8GA1UdJQQIMAYGBFUdJQAwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU + # Z7AtA3mzFc0InSBA5fiMfeLXA3owDQYJKoZIhvcNAQELBQADggEBAEE5hm1mtlk/ + # kviCoHH4evbpw7rxPxDftIQlqYTtvMM4eWY/6icFoSZ4fUHEWYyps8SsPu/8f2tf + # 71LGgZn0FdHi1QU2H8m0HHK7TFw+5Q6RLrLdSyk0PItJ71s9en7r8pX820nAFEHZ + # HkOSfJZ7B5hFgUDkMtVM6bardXAhoqcMk4YCU96e9d4PB4eI+xGc+mNuYvov3RbB + # D0s8ICyojeyPVLerz4wHjZu68Z5frAzhZ68YbzNs8j2fIBKKHkHyLG1iQyF+LJVj + # 2PjCP+auJsj6fQQpMGoyGtpLcSDh+ptcTngUD8JsWipzTCjmaNqdPHAOYmcgtf4b + # qocikt3WAdU^invalid DO NOT USE= + # -----END CERTIFICATE----- + ## The private key used with the certificate_chain if the server requests TLS Client Authentication + ## i.e. Mutual TLS. + # private_key: | + # -----BEGIN RSA PRIVATE KEY----- + # MIIEpAIBAAKCAQEA8q/elLI/ijMYSJUsnXh0hYUIQYSCrtZQwjRJlmpADYgPQvn1 + # T9D9SzLLu4L2B8xTM4NOkA22Q6MVBxACzGVHUU6NUGtflCCNK9fBtCfcO3AwDtdZ + # KXou5jHasFhKUxI3lRlCb9HEy1d8srZvnVaAQRgMWL6cQJKorNHhHnh44+QERZF+ + # +5j3UAyOWGmK+Dx7glaSrgtVBQpuaIVjAh0rxdCI3huVj1bBfAkVizmxD9RgzAEW + # LQeRY6HsYSN/GChQ49q4i55lIxKVCnvOoAff03RlJhvpxLQ2mPntChZlJjdqTzt5 + # txE1/isK9ktvLsug3upgIrGYJoMPfHb41ilYfwIDAQABAoIBAQDTOdFf2JjHH1um + # aPgRAvNf9v7Nj5jytaRKs5nM6iNf46ls4QPreXnMhqSeSwj6lpNgBYxOgzC9Q+cc + # Y4ob/paJJPaIJTxmP8K/gyWcOQlNToL1l+eJ20eQoZm23NGr5fIsunSBwLEpTrdB + # ENqqtcwhW937K8Pxy/Q1nuLyU2bc6Tn/ivLozc8n27dpQWWKh8537VY7ancIaACr + # LJJLYxKqhQpjtBWAyCDvZQirnAOm9KnvIHaGXIswCZ4Xbsu0Y9NL+woARPyRVQvG + # jfxy4EmO9s1s6y7OObSukwKDSNihAKHx/VIbvVWx8g2Lv5fGOa+J2Y7o9Qurs8t5 + # BQwMTt0BAoGBAPUw5Z32EszNepAeV3E2mPFUc5CLiqAxagZJuNDO2pKtyN29ETTR + # Ma4O1cWtGb6RqcNNN/Iukfkdk27Q5nC9VJSUUPYelOLc1WYOoUf6oKRzE72dkMQV + # R4bf6TkjD+OVR17fAfkswkGahZ5XA7j48KIQ+YC4jbnYKSxZTYyKPjH/AoGBAP1i + # tqXt36OVlP+y84wWqZSjMelBIVa9phDVGJmmhz3i1cMni8eLpJzWecA3pfnG6Tm9 + # ze5M4whASleEt+M00gEvNaU9ND+z0wBfi+/DwJYIbv8PQdGrBiZFrPhTPjGQUldR + # lXccV2meeLZv7TagVxSi3DO6dSJfSEHyemd5j9mBAoGAX8Hv+0gOQZQCSOTAq8Nx + # 6dZcp9gHlNaXnMsP9eTDckOSzh636JPGvj6m+GPJSSbkURUIQ3oyokMNwFqvlNos + # fTaLhAOfjBZI9WnDTTQxpugWjphJ4HqbC67JC/qIiw5S6FdaEvGLEEoD4zoChywZ + # 9oGAn+fz2d/0/JAH/FpFPgsCgYEAp/ipZgPzziiZ9ov1wbdAQcWRj7RaWnssPFpX + # jXwEiXT3CgEMO4MJ4+KWIWOChrti3qFBg6i6lDyyS6Qyls7sLFbUdC7HlTcrOEMe + # rBoTcCI1GqZNlqWOVQ65ZIEiaI7o1vPBZo2GMQEZuq8mDKFsOMThvvTrM5cAep84 + # n6HJR4ECgYABWcbsSnr0MKvVth/inxjbKapbZnp2HUCuw87Ie5zK2Of/tbC20wwk + # yKw3vrGoE3O1t1g2m2tn8UGGASeZ842jZWjIODdSi5+icysQGuULKt86h/woz2SQ + # 27GoE2i5mh6Yez6VAYbUuns3FcwIsMyWLq043Tu2DNkx9ijOOAuQzw^invalid.. + # DO NOT USE== + # -----END RSA PRIVATE KEY----- +## +## Identity Providers +## +# identity_providers: + ## + ## OpenID Connect (Identity Provider) + ## + ## It's recommended you read the documentation before configuration of this section: + ## https://www.authelia.com/c/oidc + # oidc: + ## The hmac_secret is used to sign OAuth2 tokens (authorization code, access tokens and refresh tokens). + ## HMAC Secret can also be set using a secret: https://www.authelia.com/c/secrets + # hmac_secret: this_is_a_secret_abc123abc123abc + ## The issuer_certificate_chain is an optional PEM encoded certificate chain. It's used in conjunction with the + ## issuer_private_key to sign JWT's. All certificates in the chain must be within the validity period, and every + ## certificate included must be signed by the certificate immediately after it if provided. + # issuer_certificate_chain: | + # -----BEGIN CERTIFICATE----- + # MIIC5jCCAc6gAwIBAgIRAK4Sj7FiN6PXo/urPfO4E7owDQYJKoZIhvcNAQELBQAw + # EzERMA8GA1UEChMIQXV0aGVsaWEwHhcNNzAwMTAxMDAwMDAwWhcNNzEwMTAxMDAw + # MDAwWjATMREwDwYDVQQKEwhBdXRoZWxpYTCCASIwDQYJKoZIhvcNAQEBBQADggEP + # ADCCAQoCggEBAPKv3pSyP4ozGEiVLJ14dIWFCEGEgq7WUMI0SZZqQA2ID0L59U/Q + # /Usyy7uC9gfMUzODTpANtkOjFQcQAsxlR1FOjVBrX5QgjSvXwbQn3DtwMA7XWSl6 + # LuYx2rBYSlMSN5UZQm/RxMtXfLK2b51WgEEYDFi+nECSqKzR4R54eOPkBEWRfvuY + # 91AMjlhpivg8e4JWkq4LVQUKbmiFYwIdK8XQiN4blY9WwXwJFYs5sQ/UYMwBFi0H + # kWOh7GEjfxgoUOPauIueZSMSlQp7zqAH39N0ZSYb6cS0Npj57QoWZSY3ak87ebcR + # Nf4rCvZLby7LoN7qYCKxmCaDD3x2+NYpWH8CAwEAAaM1MDMwDgYDVR0PAQH/BAQD + # AgWgMBMGA1UdJQQMMAoGCCsGAQUFBwMBMAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcN + # AQELBQADggEBAHSITqIQSNzonFl3DzxHPEzr2hp6peo45buAAtu8FZHoA+U7Icfh + # /ZXjPg7Xz+hgFwM/DTNGXkMWacQA/PaNWvZspgRJf2AXvNbMSs2UQODr7Tbv+Fb4 + # lyblmMUNYFMCFVAMU0eIxXAFq2qcwv8UMcQFT0Z/35s6PVOakYnAGGQjTfp5Ljuq + # wsdc/xWmM0cHWube6sdRRUD7SY20KU/kWzl8iFO0VbSSrDf1AlEhnLEkp1SPaxXg + # OdBnl98MeoramNiJ7NT6Jnyb3zZ578fjaWfThiBpagItI8GZmG4s4Ovh2JbheN8i + # ZsjNr9jqHTjhyLVbDRlmJzcqoj4JhbKs6/I^invalid DO NOT USE= + # -----END CERTIFICATE----- + # -----BEGIN CERTIFICATE----- + # MIIDBDCCAeygAwIBAgIRALJsPg21kA0zY4F1wUCIuoMwDQYJKoZIhvcNAQELBQAw + # EzERMA8GA1UEChMIQXV0aGVsaWEwHhcNNzAwMTAxMDAwMDAwWhcNNzEwMTAxMDAw + # MDAwWjATMREwDwYDVQQKEwhBdXRoZWxpYTCCASIwDQYJKoZIhvcNAQEBBQADggEP + # ADCCAQoCggEBAMXHBvVxUzYk0u34/DINMSF+uiOekKOAjOrC6Mi9Ww8ytPVO7t2S + # zfTvM+XnEJqkFQFgimERfG/eGhjF9XIEY6LtnXe8ATvOK4nTwdufzBaoeQu3Gd50 + # 5VXr6OHRo//ErrGvFXwP3g8xLePABsi/fkH3oDN+ztewOBMDzpd+KgTrk8ysv2ou + # kNRMKFZZqASvCgv0LD5KWvUCnL6wgf1oTXG7aztduA4oSkUP321GpOmBC5+5ElU7 + # ysoRzvD12o9QJ/IfEaulIX06w9yVMo60C/h6A3U6GdkT1SiyTIqR7v7KU/IWd/Qi + # Lfftcj91VhCmJ73Meff2e2S2PrpjdXbG5FMCAwEAAaNTMFEwDgYDVR0PAQH/BAQD + # AgKkMA8GA1UdJQQIMAYGBFUdJQAwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU + # Z7AtA3mzFc0InSBA5fiMfeLXA3owDQYJKoZIhvcNAQELBQADggEBAEE5hm1mtlk/ + # kviCoHH4evbpw7rxPxDftIQlqYTtvMM4eWY/6icFoSZ4fUHEWYyps8SsPu/8f2tf + # 71LGgZn0FdHi1QU2H8m0HHK7TFw+5Q6RLrLdSyk0PItJ71s9en7r8pX820nAFEHZ + # HkOSfJZ7B5hFgUDkMtVM6bardXAhoqcMk4YCU96e9d4PB4eI+xGc+mNuYvov3RbB + # D0s8ICyojeyPVLerz4wHjZu68Z5frAzhZ68YbzNs8j2fIBKKHkHyLG1iQyF+LJVj + # 2PjCP+auJsj6fQQpMGoyGtpLcSDh+ptcTngUD8JsWipzTCjmaNqdPHAOYmcgtf4b + # qocikt3WAdU^invalid DO NOT USE= + # -----END CERTIFICATE----- + ## The issuer_private_key is used to sign the JWT forged by OpenID Connect. + ## Issuer Private Key can also be set using a secret: https://www.authelia.com/c/secrets + # issuer_private_key: | + # -----BEGIN RSA PRIVATE KEY----- + # MIIEpAIBAAKCAQEA8q/elLI/ijMYSJUsnXh0hYUIQYSCrtZQwjRJlmpADYgPQvn1 + # T9D9SzLLu4L2B8xTM4NOkA22Q6MVBxACzGVHUU6NUGtflCCNK9fBtCfcO3AwDtdZ + # KXou5jHasFhKUxI3lRlCb9HEy1d8srZvnVaAQRgMWL6cQJKorNHhHnh44+QERZF+ + # +5j3UAyOWGmK+Dx7glaSrgtVBQpuaIVjAh0rxdCI3huVj1bBfAkVizmxD9RgzAEW + # LQeRY6HsYSN/GChQ49q4i55lIxKVCnvOoAff03RlJhvpxLQ2mPntChZlJjdqTzt5 + # txE1/isK9ktvLsug3upgIrGYJoMPfHb41ilYfwIDAQABAoIBAQDTOdFf2JjHH1um + # aPgRAvNf9v7Nj5jytaRKs5nM6iNf46ls4QPreXnMhqSeSwj6lpNgBYxOgzC9Q+cc + # Y4ob/paJJPaIJTxmP8K/gyWcOQlNToL1l+eJ20eQoZm23NGr5fIsunSBwLEpTrdB + # ENqqtcwhW937K8Pxy/Q1nuLyU2bc6Tn/ivLozc8n27dpQWWKh8537VY7ancIaACr + # LJJLYxKqhQpjtBWAyCDvZQirnAOm9KnvIHaGXIswCZ4Xbsu0Y9NL+woARPyRVQvG + # jfxy4EmO9s1s6y7OObSukwKDSNihAKHx/VIbvVWx8g2Lv5fGOa+J2Y7o9Qurs8t5 + # BQwMTt0BAoGBAPUw5Z32EszNepAeV3E2mPFUc5CLiqAxagZJuNDO2pKtyN29ETTR + # Ma4O1cWtGb6RqcNNN/Iukfkdk27Q5nC9VJSUUPYelOLc1WYOoUf6oKRzE72dkMQV + # R4bf6TkjD+OVR17fAfkswkGahZ5XA7j48KIQ+YC4jbnYKSxZTYyKPjH/AoGBAP1i + # tqXt36OVlP+y84wWqZSjMelBIVa9phDVGJmmhz3i1cMni8eLpJzWecA3pfnG6Tm9 + # ze5M4whASleEt+M00gEvNaU9ND+z0wBfi+/DwJYIbv8PQdGrBiZFrPhTPjGQUldR + # lXccV2meeLZv7TagVxSi3DO6dSJfSEHyemd5j9mBAoGAX8Hv+0gOQZQCSOTAq8Nx + # 6dZcp9gHlNaXnMsP9eTDckOSzh636JPGvj6m+GPJSSbkURUIQ3oyokMNwFqvlNos + # fTaLhAOfjBZI9WnDTTQxpugWjphJ4HqbC67JC/qIiw5S6FdaEvGLEEoD4zoChywZ + # 9oGAn+fz2d/0/JAH/FpFPgsCgYEAp/ipZgPzziiZ9ov1wbdAQcWRj7RaWnssPFpX + # jXwEiXT3CgEMO4MJ4+KWIWOChrti3qFBg6i6lDyyS6Qyls7sLFbUdC7HlTcrOEMe + # rBoTcCI1GqZNlqWOVQ65ZIEiaI7o1vPBZo2GMQEZuq8mDKFsOMThvvTrM5cAep84 + # n6HJR4ECgYABWcbsSnr0MKvVth/inxjbKapbZnp2HUCuw87Ie5zK2Of/tbC20wwk + # yKw3vrGoE3O1t1g2m2tn8UGGASeZ842jZWjIODdSi5+icysQGuULKt86h/woz2SQ + # 27GoE2i5mh6Yez6VAYbUuns3FcwIsMyWLq043Tu2DNkx9ijOOAuQzw^invalid.. + # DO NOT USE== + # -----END RSA PRIVATE KEY----- + ## The lifespans configure the expiration for these token types. + # access_token_lifespan: 1h + # authorize_code_lifespan: 1m + # id_token_lifespan: 1h + # refresh_token_lifespan: 90m + ## Enables additional debug messages. + # enable_client_debug_messages: false + ## SECURITY NOTICE: It's not recommended changing this option and values below 8 are strongly +discouraged. + # minimum_parameter_entropy: 8 + ## SECURITY NOTICE: It's not recommended changing this option, and highly discouraged to have it set to +'never' + ## for security reasons. + # enforce_pkce: public_clients_only + ## Cross-Origin Resource Sharing (CORS) settings. + # cors: + ## List of endpoints in addition to the metadata endpoints to permit cross-origin requests on. + # endpoints: + # - authorization + # - token + # - revocation + # - introspection + # - userinfo + ## List of allowed origins. + ## Any origin with https is permitted unless this option is configured or the + ## allowed_origins_from_client_redirect_uris option is enabled. + # allowed_origins: + # - https://example.com + ## Automatically adds the origin portion of all redirect URI's on all clients to the list of allowed_origins, + ## provided they have the scheme http or https and do not have the hostname of localhost. + # allowed_origins_from_client_redirect_uris: false + ## Clients is a list of known clients and their configuration. + # clients: + # - + ## The ID is the OpenID Connect ClientID which is used to link an application to a configuration. + # id: myapp + ## The description to show to users when they end up on the consent screen. Defaults to the ID above. + # description: My Application + ## The client secret is a shared secret between Authelia and the consumer of this client. + # secret: this_is_a_secret + ## Sector Identifiers are occasionally used to generate pairwise subject identifiers. In most cases this is not + ## necessary. Read the documentation for more information. + ## The subject identifier must be the host component of a URL, which is a domain name with an optional +port. + # sector_identifier: example.com + ## Sets the client to public. This should typically not be set, please see the documentation for usage. + # public: false + ## The policy to require for this client; one_factor or two_factor. + # authorization_policy: two_factor + ## The consent mode controls how consent is obtained. + # consent_mode: auto + ## This value controls the duration a consent on this client remains remembered when the consent mode +is + ## configured as 'auto' or 'pre-configured'. + # pre_configured_consent_duration: 1w + ## Audience this client is allowed to request. + # audience: [] + ## Scopes this client is allowed to request. + # scopes: + # - openid + # - groups + # - email + # - profile + ## Redirect URI's specifies a list of valid case-sensitive callbacks for this client. + # redirect_uris: + # - https://oidc.example.com:8080/oauth2/callback + ## Grant Types configures which grants this client can obtain. + ## It's not recommended to define this unless you know what you're doing. + # grant_types: + # - refresh_token + # - authorization_code + ## Response Types configures which responses this client can be sent. + ## It's not recommended to define this unless you know what you're doing. + # response_types: + # - code + ## Response Modes configures which response modes this client supports. + # response_modes: + # - form_post + # - query + # - fragment + ## The algorithm used to sign userinfo endpoint responses for this client, either none or RS256. + # userinfo_signing_algorithm: none + ``` diff --git a/configuration/authy-duo-config.md b/configuration/authy-duo-config.md new file mode 100644 index 0000000..d6a4320 --- /dev/null +++ b/configuration/authy-duo-config.md @@ -0,0 +1,34 @@ +--- +title: DP-Salad Configuration +--- + +# Authy/Duo Configuration + +This is like one of those "Choose Your Own Adventure" books! Pick one, not the other, it may be hard to swap later on. You may be able to give your user a choice too! 2FA is handled by either Authelia using an 8 digit code that generates through Authy :logos-authy: or it can be passed off to Duo :simple-icons-cisco: to handle, and then "reinjected" back into the authentication process later on. I'll outline steps for both, and you can choose the method(s) you want your users to be able to 2FA. + +--- + +Authy is probably the easiest, and the cheapest way to configure 2FA, especially if you are going to +have more than 5 users. + +The default for the SALA/D Stack for 2FA for the more technical people is SHA1, 8 Digits + +All this means for the user is what applications are supported, list is below: + +- [Bitwarden](https://bitwarden.com) :simple-icons-bitwarden: / [Vaultwarden](https://github.com/dani-garcia/vaultwarden) :simple-icons-vaultwarden: (Password Managers, Vaultwarden can be selfhosted!, 2FA is setup in addition to account) +- Authy :logos-authy: (Recommended application, named as the best for the stack) +- Aegis (Supported, never used. YMMV) + +These three options are supported for 2FA for Authelia :simple-icons-authelia:. It is recommended to actually set this up, +as it prevents complete lockouts. + +--- + +Duo :simple-icons-cisco: is another way to configure 2FA. If you enable Duo 2FA, you'll need to consult the +documentation for Duo setup via Authelia, I've linked some setup links here. + +https://www.authelia.com/configuration/second-factor/duo/ + +https://www.authelia.com/overview/authentication/push-notification/ + +You'll need to modify the configuration of Authelia to finish the setup of 2FA via Duo. diff --git a/configuration/lldap-config.md b/configuration/lldap-config.md new file mode 100644 index 0000000..c3f9719 --- /dev/null +++ b/configuration/lldap-config.md @@ -0,0 +1,143 @@ +--- +title: LLDAP Configuration +--- + +# LLDAP Configuration :material-symbols-lock: + +LLDAP :material-symbols-lock: is the *Light Lightweight Directory Access Protocol*, and for our purposes, it will store all the information that we have on our users, like usernames, emails, and hashed passwords. These are the typical values, and only a few more exist in this light implementation of LDAP. I include a sample config file if you don't want to set values in the Docker Compose file. + +As with the Authelia :simple-icons-authelia: Configuration, please change things in square brackets to your relevant values. This file uses **REPLACE_WITH** to tell you where to replace other such values like secrets/tokens. + +```yaml +## Default configuration for Docker. +## All the values can be overridden through environment variables, prefixed +## with "LLDAP_". For instance, "ldap_port" can be overridden with the +## "LLDAP_LDAP_PORT" variable. +## Tune the logging to be more verbose by setting this to be true. +## You can set it with the LLDAP_VERBOSE environment variable. +# verbose=false +## The host address that the LDAP server will be bound to. +## To enable IPv6 support, simply switch "ldap_host" to "::": +## To only allow connections from localhost (if you want to restrict to local self-hosted services), +## change it to "127.0.0.1" ("::1" in case of IPv6)". +ldap_host = "0.0.0.0" +## The port on which to have the LDAP server. +ldap_port = 3890 +## The host address that the HTTP server will be bound to. +## To enable IPv6 support, simply switch "http_host" to "::". +## To only allow connections from localhost (if you want to restrict to local self-hosted services), +## change it to "127.0.0.1" ("::1" in case of IPv6)". +http_host = "0.0.0.0" +## The port on which to have the HTTP server, for user login and +## administration. +http_port = 17170 +## The public URL of the server, for password reset links. +#http_url = "http://localhost" +## Random secret for JWT signature. +## This secret should be random, and should be shared with application +## servers that need to consume the JWTs. +## Changing this secret will invalidate all user sessions and require +## them to re-login. +## You should probably set it through the LLDAP_JWT_SECRET environment +## variable from a secret ".env" file. +## This can also be set from a file's contents by specifying the file path +## in the LLDAP_JWT_SECRET_FILE environment variable +## You can generate it with (on linux): +## LC_ALL=C tr -dc 'A-Za-z0-9!#%&'\''()*+,-./:;<=>?@[\]^_{|}~' . +#from="LLDAP Admin " +## Same for reply-to, optional. +#reply_to="Do not reply " +## Options to configure LDAPS. +## To set these options from environment variables, use the following format +## (example with "port"): LLDAP_LDAPS_OPTIONS__PORT +[ldaps_options] +## Whether to enable LDAPS. +#enabled=true +## Port on which to listen. +#port=6360 +## Certificate file. +#cert_file="/data/cert.pem" +## Certificate key file. +#key_file="/data/key.pem" +``` diff --git a/configuration/swag-config.md b/configuration/swag-config.md new file mode 100644 index 0000000..7691ec5 --- /dev/null +++ b/configuration/swag-config.md @@ -0,0 +1,20 @@ +--- +title: Swag Config +--- + +# SWAG Configuration :simple-icons-linuxserver: + +Configuring the Secure Web Application Gateway has a lot of options and potential. It is primarily used to have one gateway for all your services hosted through two ports. Assuming you've used the Docker Compose file, you should be able to view and edit all the configuration files through `/home/[USER]/appdata/swag`. This location now has multiple places you can go. + +1. `/home/[USER]/appdata/swag/nginx` - This holds all of the webserver configuration files, this is where you will go when adding a new application/service. + - `/home/[USER]/appdata/swag/nginx/proxy-confs` - This is where all the reverse proxy magic happens, and will likely be the most used folder. + - `/home/[USER]/appdata/swag/nginx/site-confs` - If you want to host a static site using SWAG, this is the conf file that you will modify to make it function. +::: tip +Highly recommend learning how NGINX :logos-nginx: conf files work. +::: + - The files in this nginx directory are all usually not touched, but used for the rest of configuration to connect Authelia :simple-icons-authelia: to SWAG :simple-icons-linuxserver: for logins. +2. `/home/[USER]/appdata/swag/etc/letsencrypt` - This holds all the relevant data for your SSL certificates using Let's Encrypt :simple-icons-letsencrypt:. The current certificates are in the "*live*" folder, under the domain name folder. +3. `/home/[USER]/appdata/swag/dns-conf` - This holds the API keys or access information in order for SWAG to setup Let's Encrypt :simple-icons-letsencrypt: certificates or other DNS :material-symbols-dns-outline: information. There are many providers available, however, Cloudflare will most likely be used. In order for a SSL Certificate to be issued, you will have to set this up. +4. `/home/[USER]/appdata/swag/www` - This folder holds all of the static site stuff, if you decide to make a static site, you can host it through SWAG's configurations. This does take some patience, as getting the stuff exactly right is a bit tricky. + +See [How do I add a new application to my stack?](/faq.md#how-do-i-add-a-new-application-to-my-stack) for more information as to how to use the SWAG proxy-confs folder to add a new application to your hosting repertoire. diff --git a/docker-compose.md b/docker-compose.md new file mode 100644 index 0000000..aa5a13e --- /dev/null +++ b/docker-compose.md @@ -0,0 +1,113 @@ +--- +title: One File Docker Compose (One File to Rule them all!) +sidebar: false +--- + +# One File Docker Compose (One File to Rule them all!) + +This is the Docker Compose file used for the VM Template, and can be used as a custom template in Portainer. +The custom network listed under "*Networks*" is used for all the applications that you want to connect through the stack. Please replace the **ALL_CAPS_PORTIONS** and the pieces in **square brackets**. These are values that you will want to set yourself. + +::: tip +For things like passwords and such, I'd recommend a 26 character random string, using alphanumeric characters in both upper and lower case. These values are crucial that they remain both secret and lengthy. +::: + +These values are crucial that they remain both secret and lengthy. You should not need to change these, and some of them will break the application if you try to change them. I'd recommend that you backup your compose file to the cloud in case you need to redo the setup. + +```yml +version: "2.1" +services: + swag: + image: lscr.io/linuxserver/swag:latest + container_name: swag + cap_add: + - NET_ADMIN + environment: + - PUID=1000 + - PGID=1000 + - TZ=America/Phoenix + - URL=[sakura.nt] + - VALIDATION=dns + - SUBDOMAINS=wildcard + - DNSPLUGIN=cloudflare + - EMAIL=[sakurant@gmail.com] + - ONLY_SUBDOMAINS=false + #- EXTRA_DOMAINS= #optional + - STAGING=false + - DOCKER_MODS=linuxserver/mods:universal-docker|linuxserver/mods:swag-auto-reload|linuxserver/mods:swag-dashboard|linuxserver/mods:swag-dbip + volumes: + - /home/[INSERT USER FOLDER HERE]/appdata/swag:/config + ports: + - 443:443 + - 80:80 + networks: + - [INSERT NETWORK NAME HERE] + restart: unless-stopped + + authelia: + container_name: authelia + image: authelia/authelia:latest + expose: + - 9091 + volumes: + - /home/[INSERT USER FOLDER HERE]/appdata/authelia:/config + networks: + - [INSERT NETWORK NAME HERE] + restart: unless-stopped + depends_on: + - redis + - mariadb + + lldap: + container_name: lldap + image: lldap/lldap:stable + ports: + # For LDAP + - "3890:3890" + # For the web front-end + - "17170:17170" + volumes: + - /home/[INSERT USER FOLDER HERE]/appdata/lldap:/data + networks: + - [INSERT NETWORK NAME HERE] + environment: + - TZ=America/Phoenix + - LLDAP_JWT_SECRET=REPLACE_WITH_RANDOM + - LLDAP_LDAP_USER_PASS=REPLACE_WITH_PASSWORD + - LLDAP_LDAP_BASE_DN=dc=sakura,dc=nt + + redis: + container_name: redis + image: bitnami/redis:latest + expose: + - 6379 + volumes: + - /home/[INSERT USER FOLDER HERE]/appdata/redis:/bitnami/ + environment: + REDIS_PASSWORD: "YOUR_REDIS_PASSWORD" + networks: + - [INSERT NETWORK NAME HERE] + restart: unless-stopped + + mariadb: + container_name: mysql + image: linuxserver/mariadb:latest + expose: + - 3306 + volumes: + - /home/[INSERT USER FOLDER HERE]/appdata/mariadb:/config + environment: + MYSQL_ROOT_PASSWORD: "YOUR_MYSQL_ROOT_PASSWORD" + MYSQL_ROOT_USER: root + MYSQL_DATABASE: authelia + MYSQL_USER: authelia + MYSQL_PASSWORD: "YOUR_MYSQL_USER_PASSWORD" + networks: + - [INSERT NETWORK NAME HERE] + restart: unless-stopped + +networks: + [INSERT NETWORK NAME HERE]: + driver: bridge + external: true +``` diff --git a/faq.md b/faq.md new file mode 100644 index 0000000..c08113c --- /dev/null +++ b/faq.md @@ -0,0 +1,154 @@ +--- +title: FAQ +--- + +# Frequently Asked Questions + +## How do I [Insert Question Here]? + +Quick Q&A for common problems/questions about the DP-SALA/D Stack + +## How do I add a new application to my stack? + +You have two options: + +1. You can check SWAG's *proxy confs* folder for the application you are trying to add in it's configuration folder. + + - You will use the following command: `mv /home/[USER]/appdata/swag/nginx/proxy-confs/[application].sub[domain/folder].conf.sample /home/[USER]/appdata/swag/nginx/proxy-confs/[application].sub[domain/folder].conf` + - Install the application into your docker network (keep track of the internal port that it uses) + - Then nano into the *.conf* `nano /home/[USER]/appdata/swag/nginx/proxy-confs/[application].sub[domain/folder].conf` + 1. If you are using a subdomain configuration: + - You can change the *server_name* directive to the path you want to use as a subdomain (make sure you leave the .*) + - The *$upstream_app* should match the docker container name + - The *$upstream_port* should match the docker internal port + - Everything else can be left unchanged + 2. If you are using a subfolder configuration: + - The *$location* directive can be changed after the */* to the path you want to use as a subfolder (make sure to leave the *^~*) + - The *$upstream_app* should match the docker container name + - The *$upstream_port* should match the docker internal port + +::: tip +If you have the auto-reload docker mod, SWAG :simple-icons-linuxserver: will automatically reload the changes, and display them. Otherwise, SWAG :simple-icons-linuxserver: will have to be manually reloaded to see the changes. +::: + +2. If there isn't a premade template, you can DIY your own using the `_template.sub[domain/folder].conf.sample`. + +- You will use the following command: `cp /home/[USER]/appdata/swag/nginx/proxy-confs/_template.sub[domain/folder].conf.sample /home/[USER]/appdata/swag/nginx/proxy-confs/[application].sub[domain/folder].conf` +- Install the application into your docker network (keep track of the internal port that it uses) +- Then nano into the *.conf* `nano /home/[USER]/appdata/swag/nginx/proxy-confs/[application].sub[domain/folder].conf` + 1. If you are using a subdomain template: + - You'll want to modify anything with *<>* make sure to remove the *<>* when you are done. + 2. If you are using a subfolder template: + - You'll want to modify anything with *<>* make sure to remove the *<>* when you are done. + +- Which ever way you decide to do, once you have made the changes, save and exit. + +::: warning **THIS IS IMPORTANT!!!** +You'll want to verify that the *$upstream_app*, *$port* and *$protocal* are correct, otherwise you will keep getting 502 errors when trying to visit them. The web path/container_name doesn't really matter, you can name it whatever. +::: + +::: tip +Most of the time, the template will work out-of-the-box with all of the changes. However, you may run into an application that requrires more configuration to run behind a reverse proxy. You will have to consult the application's documentation to find settings that will let it run behind a reverse proxy. SWAG :simple-icons-linuxserver: uses NGINX :logos-nginx: as it's base, so most NGINX configurations can be used to have it run behind a reverse proxy. +::: + +::: warning +If you decide to proxy something externally to docker, this comes with the caveat that the *$upstream_app* must be an IP address (preferably static), and the *$upstream_port* must be an external port that the application is listening on. Failing to do so, will result in a **502 Bad Gateway** error. +::: + +## How do I add LLDAP :material-symbols-lock: Authentication to [SERVICE]? + +First, check to see if LDAP authentication is supported by the application that you are trying to add. Some services/applications either don't support LDAP auth out of the box, or there is some plugin/addon to add for LDAP auth to function. Do a quick Google search to see if LDAP auth is supported, and if it requires a secure connection. Canvas :simple-icons-canvas: in particular requires LDAPS (LDAP over SSL) and will not function unless configured correctly. + +Second, if the app supports LDAP Auth, it usually requires a dedicated user to manage the application, usually called a "*Bind User*" which you will setup in LLDAP. Try to pick a username that will be descriptive for the service it will bind to. The password that is used should be lengthy and mixtures of characters. The next required parts are the "configuration" parts, which are detailed below: + +- User DN/Bind User/User: "cn=[USER],ou=people,dc=[DOMAIN],dc=[TLD]" +- Base/User Search Base: "ou=people,dc=[DOMAIN],dc=[TLD]" +- User Filter(no grouping, UID access): +(&(uid={username})(objectClass=person)(ou=people,dc=[DOMAIN],dc=[TLD])) +- User Filter(group access, UID or Email access): +(&(objectClass=person)(memberof=cn=[GROUP +NAME],ou=groups,dc=[DOMAIN],dc=[TLD])(|(uid={username})(mail={username}))) +- User Filter(group access, UID access): (&(objectClass=person)(memberof=cn=[GROUP +NAME],ou=groups,dc=[DOMAIN],dc=[TLD])) +- Admin Filter(group access): (memberof=cn=[GROUP +NAME]_administrator,ou=groups,dc=[DOMAIN],dc=[TLD]) + +These are some typical settings, however, depending on the service or app, there may be an example configuration out there, for example, Authelia for LLDAP has an example config: +https://github.com/lldap/lldap/blob/main/example_configs/authelia_config.yml + +```yml +############################################################### +# Authelia configuration # +############################################################### + +# This is just the LDAP part of the Authelia configuration! + + +authentication_backend: + # Password reset through authelia works normally. + password_reset: + disable: false + # How often authelia should check if there is an user update in LDAP + refresh_interval: 1m + ldap: + implementation: custom + # Pattern is ldap://HOSTNAME-OR-IP:PORT + # Normal ldap port is 389, standard in LLDAP is 3890 + url: ldap://lldap:3890 + # The dial timeout for LDAP. + timeout: 5s + # Use StartTLS with the LDAP connection, TLS not supported right now + start_tls: false + #tls: + # skip_verify: false + # minimum_version: TLS1.2 + # Set base dn, like dc=google,dc.com + base_dn: dc=example,dc=com + username_attribute: uid + # You need to set this to ou=people, because all users are stored in this ou! + additional_users_dn: ou=people + # To allow sign in both with username and email, one can use a filter like + # (&(|({username_attribute}={input})({mail_attribute}={input}))(objectClass=person)) + users_filter: "(&({username_attribute}={input})(objectClass=person))" + # Set this to ou=groups, because all groups are stored in this ou + additional_groups_dn: ou=groups + # The groups are not displayed in the UI, but this filter works. + groups_filter: "(member={dn})" + # The attribute holding the name of the group. + group_name_attribute: cn + # Email attribute + mail_attribute: mail + # The attribute holding the display name of the user. This will be used to greet an authenticated user. + display_name_attribute: displayName + # The username and password of the bind user. + # "bind_user" should be the username you created for authentication with the "lldap_strict_readonly" permission. It is not recommended to use an actual admin account here. + # If you are configuring Authelia to change user passwords, then the account used here needs the "lldap_password_manager" permission instead. + user: uid=bind_user,ou=people,dc=example,dc=com + # Password can also be set using a secret: https://www.authelia.com/docs/configuration/secrets.html + password: 'REPLACE_ME' +``` + +Here is a list of the attributes that you can use: uid (username), mail (email address), cn (this could be a username, or a full name be careful), and displayName (usually the full name of the user). + +Not all of these are good for use cases, however, the most commonly used ones are going to be uid and email. + +If this didn't cover what was needed for adding LDAP auth connectivity to your service, consult Google, or the LLDAP GitHub :mdi-github: Example Configs, linked here: https://github.com/lldap/lldap/tree/main/example_configs which should give you a good starting point to see how to configure the LDAP authentication for your service. + +Here is my recommendation to how user management works: + +1. Setup dedicated groups that match the application/service name, add all users who use that to the group. +2. Filter the user based on the group, if they are in that group, they have permission to access the application. + +## How do I handle user creation? + +Once the stack :green-salad: is all setup, you may want to add users :material-symbols-account-circle:. I outline my way of handling user creation and management, but you may do this anyway you like, I've done it this way given the constraints of how I host, and handle having users access some or all of my services that I host. + +User Creation: + +1. Ask for the user's email address, full name, and if they would like something different for their display name. +2. Using their full name, I create a username. Say if the user was named: Alice Example, their username would be *aexa*. If I already had a duplicate of the username, I'd append a number, starting at 0. +3. I would create a temporary password for the user, and then have them go to auth.domain.tld to then "*Forgot Password*" so that they can setup a password themselves, and have it conform to my password standards I have set. +4. I then go to the user page, and add them to their respective groups to let them have access to the services. +5. I'd let the user know that some apps will take a bit to pull their information, while some create their profile on sign in. This is completely normal, and give it up to 24 hours for changes to fully propagate through the system. + +This is one way of doing it, but I do have a standard, which I hold to the highest degree. This is important, as it does make finding the user just a little easier when trying to figure out what goes wrong. diff --git a/home.md b/home.md new file mode 100644 index 0000000..c0cef3a --- /dev/null +++ b/home.md @@ -0,0 +1,43 @@ +--- +title: Legacy Instructions +--- + +# Welcome! +This is page to be when looking to deploy the DP-Salad stack! +If you need to see if your system fits the DP-Salad stack requirements, you can find the page you're looking for here: [DP-Salad Requirements](/install/requirements.md). + +Otherwise, down below are the Legacy Instructions for the DP-Salad stack, they do have bad formatting so we do not suggest using them in a public deployment. You can also find the legacy instructions on this [website](https://dp-salad-legacy.cdezselfhosted.pw). + +The main instructions can be found on the [DP-Setup](/install/dp-setup.md) page, and are the instructions you will use to deploy the :green-salad: stack. + +Otherwise, feel free to poke about the documentation! + +## Legacy Instructions: + +::: warning +Do not use these instructions as they have poor formatting and will lead to a bad stack deployment +::: + +**PDF instructions for the DP-SALA/D Stack:** [DP-SALAD_STACK.pdf](./dp-salad-stack.pdf) (Updated 10/11/2023, 12:03PM) + +**Docker Compose file for the DP-SALA/D Stack:** [docker-compose-dpsalad.rtf](./docker-compose-dpsalad.rtf) (Updated 10/13/2023, 11:03PM) + +::: tip +Download the docker compose file, rename to docker-compose.yml for best results. +::: + +**OVA/VM Template for DP-SALA/D Stack:** [DP-SALA/D OVA Template](https://drive.google.com/file/d/1z2rR20i1UdySJfolpxUM6MiD0f46gqA_/view?usp=drive_link) + +**Authelia Example Configuration File:** [configuration.yml](./configuration.yml.rtf) (Updated 10/12/2023, 8:32PM) + +::: tip +Remove RTF extension before using in actual deployment +::: + +**LLDAP Example Configuration File:** [lldap_config.toml](./lldap_config.toml.rtf) (Updated 10/12/2023, 8:38PM) + +::: tip +Remove RTF extension before using, however, this file is not always needed. +::: + +SWAG Example file locations are detailed in the Guidebook to the DP-SALA/D Stack diff --git a/index.md b/index.md new file mode 100644 index 0000000..abdfca6 --- /dev/null +++ b/index.md @@ -0,0 +1,35 @@ +--- +# https://vitepress.dev/reference/default-theme-home-page +layout: home + +hero: + name: "DP-Salad" + text: "A guide created by Cdez" + tagline: A guide to successfully/fully deploy the DP-Salad Stack + image: ./saladicon.png + actions: + - theme: brand + text: Home + link: /home + - theme: alt + text: Minimum Requirements + link: /install/requirements + - theme: alt + text: FAQ + link: /faq + +features: + - title: Really easy to setup! + details: Just a couple of simple steps! + icon: + link: /install/dp-setup + - title: Comes with a compose file! + details: ONE FILE TO RULE THEM ALL + icon: + link: /docker-compose + - title: Latest Version + details: 1.1.0 + icon: + link: /changelog +--- + diff --git a/install/dp-config.md b/install/dp-config.md new file mode 100644 index 0000000..40f344f --- /dev/null +++ b/install/dp-config.md @@ -0,0 +1,37 @@ +--- +title: DP-Salad Configuration +--- + +# Configuration + +## Debian Configuration :logos-debian: + +Sudo should have been setup after the install, however, nothing much else is required for the setup end in Debian. If you want, here is a list of recommended software to install to make the commandline a little easier to learn: + +1. **TLDR** **:simple-icons-tldraw:** + +```sh +sudo apt-get install tldr, tldr -u +``` + +2. **Tmux** **:simple-icons-tmux:** + +```sh +sudo apt-get install tmux +``` + +## Portainer Configuration :simple-icons-portainer: + +Portainer is ready right out of the box. There should be nothing you need to do to configure it, unless you are running a "*clustered setup*" involving more than one computer, which can be done for this stack, but does add a layer of complexity, and allows for scalability for the amount of applications you can offer to either yourself or your users. A "*clustered setup*" is on the [Portainer CE wiki](https://docs.portainer.io/) and is out of the scope for this guide. + +If you are using the VM Template, Portainer has the custom templates loaded so that if you need to install a newer version, or change something and restart, they are there. + +## App Templates :material-symbols-touch-app: + +In Portainer, [App Templates](https://docs.portainer.io/user/docker/templates) enable you to easily deploy services with a predetermined configuration, while allowing you to customize options through the web UI. While Portainer ships with some default templates (see [portainer/templates](https://github.com/portainer/templates)), it's often helpful to have 1-click access to many more apps + stacks, without having to constantly switch template sources. + +Under Settings → App Templates in your Portainer GUI, paste this URL: + +```sh +https://raw.githubusercontent.com/Lissy93/portainer-templates/main/templates.json +``` diff --git a/install/dp-setup.md b/install/dp-setup.md new file mode 100644 index 0000000..55bdd3a --- /dev/null +++ b/install/dp-setup.md @@ -0,0 +1,155 @@ +--- +title: DP-Salad Setup +--- + +# DP-Setup + +This guide demonstrates the installing of the DP-Salad stack: + +## Debian 12 Setup :logos-debian: + +Visit [Debian's download page](https://debian.org/download) to get the latest version of Debian, as of this writing, Debian 12.5.0 is the latest. This is a *netinst*, meaning that it will require an internet connection to download the OS files. + +Load your Debian ISO onto a USB stick, either directly, or using Rufus/Balena Etcher to write the ISO to stick. + +Plug it into whatever is becoming your server, and boot to the USB stick in your system's BIOS. + +Install Debian using the ISO. Make sure that you are connected to the internet before trying to install Debian. + +1. Select Graphical Installer +2. Follow the setup process up until hostname, and put in something that you will recognize when port-forwarding or tunneling. +3. Put in the domain name that you have leased as your domain name, like: "*example.com*" +4. Setup a root password. (Template uses DPSALADSTACK) +5. Setup the name for the first non-admin user. (Template uses dpsalad) +6. Setup a password for the non-admin user. (Template uses DPSALADSTACKUSER) +7. Continue the setup, and select "Guided - use entire disk" when Partitioning Disk, continue and use "All files in one partition" as the partitioning scheme. +8. Allow changes to be written to disk. +9. Continue with the installer until Software Selection. See the following points for the selections. + - Debian desktop environment (keep selected) + - GNOME (deselect) + - xfce (select) + - SSH server (select) + - standard system utilities (keep selected) +10. Continue with the installer until the reboot. +11. Once the reboot is complete, you should have a fully working Debian system! +12. If you used the template, please change the password of both the root and regular user using passwd. + +## Sudo no worky :man-facepalming: + +Debian had you set up a root password, but when you try using sudo, it will not let you do anything. Debian by default does not let the first user have sudo access. See why here: [Reason](https://wiki.debian.org/sudo#:~:text=Why%20sudo%3F,root.%20Some%20reasons). You will have to temporarily log in as root to fix this. Use the following commands/instructions to add your user to the sudoers file. + +```markdown +1. su - +2. nano /etc/sudoers +3. Add the following to the file(no quotes): "username ALL=(ALL:ALL) ALL" +4. Exit nano using Ctrl+X and then type 'Y' and enter. +5. Restart your PC. +6. systemctl reboot +``` + +Once your machine restarts, you should now be able to use the sudo command. + +## Disabling GUI :desktop-computer: + +If you'd like to disable the GUI and work in CLI only (highly recommended, as GUI uses more resources), follow these instructions: + +```markdown +1. sudo systemctl set-default multi-user.target +2. sudo reboot +``` + +## Updating your system :mdi-monitor: + +Now time to run updates, just to guarantee the system is up-to-date. Debian uses *APT* as it's package manager of choice. Run these commands: + +```markdown +1. sudo apt-get update +2. sudo apt-get upgrade +``` + +And now, your system is up-to-date! + +## Installing the Docker :logos-docker-icon: + +Next, install Docker. Follow the following instructions to install Docker: + +```sh +sudo apt-get update +``` + +```sh +sudo apt-get install ca-certificates curl gnupg +``` + +```sh +sudo install -m 755 -d /etc/apt/keyrings +``` + +```sh +curl -fsSL https://download.docker.com/linux/debian/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg +``` + +```sh +sudo chmod a+r /etc/apt/keyrings/docker.gpg +``` + +```sh +echo \ + "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/debian \ + $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \ + sudo tee /etc/apt/sources.list.d/docker.list > /dev/null +``` + +```sh +sudo apt-get update +``` + +```sh +sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin dockercompose-plugin +``` + +Once this is done, you are able to move on to the next section of this guide + +::: danger +If you use anything other than the *netinst* for Debian, your apt sources may be invalid. Should this be the case, there is an example of the sources needed in `/usr/share/doc/apt/examples/sources.list`. Use the following command to copy this list of default sources to restore apt to working order. `sudo cp /usr/share/doc/apt/examples/sources.list /etc/apt/sources.list` +::: + +## Portainer CE Setup :simple-icons-portainer: + +Time to setup Portainer, which is installed using Docker. Follow the below instructions to install Portainer onto your machine. + +```sh +sudo docker volume create portainer_data +``` + +```sh +sudo docker run -d -p 8000:8000 -p 9443:9443 --name portainer --restart=always -v /var/run/docker.sock:/var/run/docker.sock -v portainer_data:/data portainer/portainer-ce:latest +``` + +- Visit https://[ip-address]:9443 to log into Portainer CE. + +- Change the admin username if you wish. (Don't forget it if you change it though!) [Template uses DPSALADSTACK] + +- Use a good secure password (12+ characters) for the administrator password. (Don't forget this either!) + +- Click "*Getting Started*" to finish setting up Portainer CE. + +- If you are going to use the one-click Compose Install, make sure to create a network using the following command: + +```sh +sudo docker network create [INSERT NETWORK NAME HERE] +``` + +::: tip +Make sure to remove the square brackets around the network name. +::: + +## Some changes need to be made :wrench: +Do note that some changes need to be made before the stack installation is finished. These two commands need to be ran to make sure Redis can be deployed for the stack to function correctly. + +```sh +mkdir -p /home/[USER]/appdata/redis/redis/ +mkdir -p /home/[USER]/appdata/redis/redis/data/ +``` + +That's it! You have successfully installed Debian and Portainer! :party-popper: diff --git a/install/requirements.md b/install/requirements.md new file mode 100644 index 0000000..1926a44 --- /dev/null +++ b/install/requirements.md @@ -0,0 +1,73 @@ +--- +title: DP-Salad Minimum Requirements +--- + +# DP-SALA/D Stack (*pronounced as DP-Salad but stylized as DP-SALA/D*) + +## Where does the acronym originate from? + +It comes from: + +- **D**ebian 12 :logos-debian: +- **P**ortainer :simple-icons-portainer: +- **S**WAG :simple-icons-linuxserver: +- **A**uthelia :simple-icons-authelia: +- **L**LDAP :material-symbols-lock: +- **A**uthy/**D**uo :logos-authy:/:simple-icons-cisco: + +Hence, **DP-Salad**. + +As such, this updates with new configuration and such when needed. + +## Minimum Requirements for the DP-SALA/D Stack: + +A DP-SALA/D Stack is rather lightweight in comparison to other stacks out there, like the very similar Unraid-SALA/D stack(:simple-icons-unraid: + :green-salad:). + +This is a compilation of the minimum specs for each part of the stack. + +### Debian 12 :logos-debian: + +- 1GHz Processor from 2010 or later +- 2 GB RAM +- 10 GB Storage + +### Portainer :simple-icons-portainer: + +- 1GHz Processor from 2010 or later +- 2 GB RAM +- 20 GB Storage + +### SWAG :simple-icons-linuxserver: + +- 1GHz Processor from 2010 or later +- RAM requirement depends on expected requests, 4 GB recommended. +- 10 GB Storage + +### Authelia :simple-icons-authelia: + +- Requires that a REDIS :logos-redis: server is setup in addition to whatever else. + +### Authy/Duo + +- Authy: :logos-authy: + - Hooks into Authelia for 2FA aaS, only requires a bit of setup. + +- Duo: :simple-icons-cisco: + - Hooks into Authelia for 2FA aaS, however, free tier can have max 10 users, but setup is a little easier on the user/admin. + +### Overall Minimum: + +- Most Processors within the last 5 years should work well enough. :octicon-cpu-24: +- 4 GB RAM minimum, although 2 GB can be gotten away with. :material-symbols-memory-alt-outline-rounded: +- 30 GB Storage minimum, especially if you plan to reverse proxy some apps. :material-symbols-hard-drive-outline: +- Basic command line knowledge. :material-symbols-terminal: + +## What this guide assumes: + +This guide assumes that you have basic computing knowledge, including how to boot your computer into an OS from a USB stick, having a domain through a registrar, and have a Gmail address for sending email to your potential users. + +If you do not have a domain, my recommendation (*at the time of writing*) is to go through [Porkbun](https://porkbun.com/) :simple-icons-porkbun: or [Cloudflare](https://www.cloudflare.com/products/registrar/) :simple-icons-cloudflare:. These are the two most reputable registrars that do not markup pricing for renewing the domain you are leasing. + +I also recommend that you set up a Gmail :mdi-gmail: address specifically for the purpose of this stack, as Authelia will require a way to let their users password reset, as well as setup 2FA for themselves. + +You may also use iCloud+'s :mdi-apple-icloud: custom domain email, however, this guide will not cover this setup, and you will have to do some research on sending email through iCloud if you choose to go this route, and you will have to find the proper settings before configuring Authelia. diff --git a/install/salad-setup.md b/install/salad-setup.md new file mode 100644 index 0000000..74d716d --- /dev/null +++ b/install/salad-setup.md @@ -0,0 +1,31 @@ +--- +title: Salad Setup +--- + +# SALA/D Setup +Instructions to set up the SALA/D Part of the stack. + +## Overview of the SALA/D Stack: + +The SALA/D stack, or SWAG, Authelia, LLDAP, Authy/Duo stack is a simple way to get a webserver/reverse proxy, an identity and access control management system, as well as 2FA; all working together to host whatever you'd like. Here is what does what: + +- Swag :simple-icons-linuxserver: + - Handles the webserver and reverse proxy. + - All configuration is handled via *.conf* files and text + - This guide also demonstrates how to set up the Docker Mods Auto Reload, GeoIPBlock, and ... + +- Authelia :simple-icons-authelia: + - Handles weblogin and the front end of 2FA. + - This has one configuration file, and hooks into LLDAP. + +- LLDAP :material-symbols-lock: + - Handles the "identity" part of the Authentication solution. + - Requires that a domain is setup, and has a bit of a learning curve. + - This has a bit of configuration involved whenever you setup a new application with LDAP integrations, however, [LLDAP's GitHub page](https://github.com/lldap/lldap) usually has sample configurations on how to setup LDAP auth for an application. + +- Authy/Duo + - Pick one between Authy or Duo + - Authy :logos-authy: + - This allows for 2FA via an 8 digit code. The configuration is handled via Authelia, with the end user setting up 2FA through the Authy App or through Bit/Vaultwarden. The user can self register their 2FA in this way, through email. + - Duo + - This allows for 2FA via a push notification on your phone. The configuration is handled via Authelia. diff --git a/maintenance/maintain-guide.md b/maintenance/maintain-guide.md new file mode 100644 index 0000000..198a47f --- /dev/null +++ b/maintenance/maintain-guide.md @@ -0,0 +1,40 @@ +--- +title: Maintenance of the DP-SALA/D Stack +--- + +# Maintenance of the DP-SALA/D Stack + +Suggested maintenance for the DP-SALA/D Stack + +## Required Maintenance for the DP-SALA/D Stack + +**Debian 12:** :logos-debian: + +- At least monthly, run a "`sudo apt-get update && sudo apt-get update`" to update the base applications for Debian, this applies security and feature upgrades for your OS, which is important. + +- At least bi-weekly, save all the configuration files and important data to a secure, private, personal location. You could even use the Google Drive :mdi-google-drive: space of the Gmail address that you setup, and save the previous backups. You could probably keep the last 5 backups just to be safe, but minimum of 3. + +**Portainer:** :simple-icons-portainer: + +- Update whenever there is an update. If you login and it tells you there is an update available, update right then and there. Portainer is just a docker container that lets you manage other docker containers, but make sure to keep this as up to date as possible. +- You generally don't have to keep a backup of the Portainer data volume, unless you've made some crazy modification to it's configuration that was different from the standard install. + +**SWAG:** :simple-icons-linuxserver: + +- At least monthly, restart the container. This allows it to pull new configurations from the GitHub :mdi-github: page, as well as renew your SSL certificates for your webserver. + +**Authelia:** :simple-icons-authelia: + +- At least monthly, restart the container. This allows it to pull updates for the container.  + +::: warning +Make sure that your configuration for this is backed up, since multiple sensitive things are within this file, and recovering them will be impossible. +::: + +**LLDAP:** :material-symbols-lock: + +- This is probably the lowest maintenance thing out of the stack. Just make sure that it is backed up completely. + +**Authy/Duo:** :logos-authy: + +- Set it and forget it. This is typically included in Authelia :simple-icons-authelia:, so another reason to make sure that config file is completely backed up properly. diff --git a/package.json b/package.json new file mode 100644 index 0000000..8f9ff6e --- /dev/null +++ b/package.json @@ -0,0 +1,36 @@ +{ + "type": "module", + "devDependencies": { + "@iconify-json/gg": "^1.2.1", + "@iconify-json/ic": "^1.2.1", + "@iconify-json/logos": "^1.2.3", + "@iconify-json/material-symbols": "^1.2.7", + "@iconify-json/mdi": "^1.2.1", + "@iconify-json/mingcute": "^1.2.1", + "@iconify-json/octicon": "^1.2.1", + "@iconify-json/simple-icons": "^1.2.12", + "@iconify-json/twemoji": "^1.2.1", + "unocss": "^0.64.1", + "vitepress": "^1.5.0", + "vitepress-plugin-codeblocks-fold": "^1.2.28", + "vitepress-plugin-pagefind": "^0.4.11", + "vitepress-sidebar": "^1.29.0" + }, + "scripts": { + "docs:dev": "vitepress dev C:\\Users\\Ldez\\Downloads\\DP-Salad", + "docs:build": "vitepress build C:\\Users\\Ldez\\Downloads\\DP-Salad", + "docs:preview": "vitepress preview C:\\Users\\Ldez\\Downloads\\DP-Salad" + }, + "dependencies": { + "@vitejs/plugin-vue": "^5.2.0", + "vue": "^3.5.13" + }, + "pnpm": { + "peerDependencyRules": { + "ignoreMissing": [ + "@algolia/client-search", + "search-insights" + ] + } + } +} \ No newline at end of file diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml new file mode 100644 index 0000000..3a9bdfe --- /dev/null +++ b/pnpm-lock.yaml @@ -0,0 +1,3129 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + dependencies: + '@vitejs/plugin-vue': + specifier: ^5.2.0 + version: 5.2.0(vite@5.4.11)(vue@3.5.13) + vue: + specifier: ^3.5.13 + version: 3.5.13 + devDependencies: + '@iconify-json/gg': + specifier: ^1.2.1 + version: 1.2.1 + '@iconify-json/ic': + specifier: ^1.2.1 + version: 1.2.1 + '@iconify-json/logos': + specifier: ^1.2.3 + version: 1.2.3 + '@iconify-json/material-symbols': + specifier: ^1.2.7 + version: 1.2.7 + '@iconify-json/mdi': + specifier: ^1.2.1 + version: 1.2.1 + '@iconify-json/mingcute': + specifier: ^1.2.1 + version: 1.2.1 + '@iconify-json/octicon': + specifier: ^1.2.1 + version: 1.2.1 + '@iconify-json/simple-icons': + specifier: ^1.2.12 + version: 1.2.12 + '@iconify-json/twemoji': + specifier: ^1.2.1 + version: 1.2.1 + unocss: + specifier: ^0.64.1 + version: 0.64.1(postcss@8.4.49)(rollup@4.27.3)(vite@5.4.11)(vue@3.5.13) + vitepress: + specifier: ^1.5.0 + version: 1.5.0(@algolia/client-search@5.15.0)(postcss@8.4.49)(search-insights@2.17.3) + vitepress-plugin-codeblocks-fold: + specifier: ^1.2.28 + version: 1.2.28 + vitepress-plugin-pagefind: + specifier: ^0.4.11 + version: 0.4.11(pagefind@1.2.0) + vitepress-sidebar: + specifier: ^1.29.0 + version: 1.29.0 + +packages: + + '@algolia/autocomplete-core@1.17.7': + resolution: {integrity: sha512-BjiPOW6ks90UKl7TwMv7oNQMnzU+t/wk9mgIDi6b1tXpUek7MW0lbNOUHpvam9pe3lVCf4xPFT+lK7s+e+fs7Q==} + + '@algolia/autocomplete-plugin-algolia-insights@1.17.7': + resolution: {integrity: sha512-Jca5Ude6yUOuyzjnz57og7Et3aXjbwCSDf/8onLHSQgw1qW3ALl9mrMWaXb5FmPVkV3EtkD2F/+NkT6VHyPu9A==} + peerDependencies: + search-insights: '>= 1 < 3' + + '@algolia/autocomplete-preset-algolia@1.17.7': + resolution: {integrity: sha512-ggOQ950+nwbWROq2MOCIL71RE0DdQZsceqrg32UqnhDz8FlO9rL8ONHNsI2R1MH0tkgVIDKI/D0sMiUchsFdWA==} + peerDependencies: + '@algolia/client-search': '>= 4.9.1 < 6' + algoliasearch: '>= 4.9.1 < 6' + + '@algolia/autocomplete-shared@1.17.7': + resolution: {integrity: sha512-o/1Vurr42U/qskRSuhBH+VKxMvkkUVTLU6WZQr+L5lGZZLYWyhdzWjW0iGXY7EkwRTjBqvN2EsR81yCTGV/kmg==} + peerDependencies: + '@algolia/client-search': '>= 4.9.1 < 6' + algoliasearch: '>= 4.9.1 < 6' + + '@algolia/client-abtesting@5.15.0': + resolution: {integrity: sha512-FaEM40iuiv1mAipYyiptP4EyxkJ8qHfowCpEeusdHUC4C7spATJYArD2rX3AxkVeREkDIgYEOuXcwKUbDCr7Nw==} + engines: {node: '>= 14.0.0'} + + '@algolia/client-analytics@5.15.0': + resolution: {integrity: sha512-lho0gTFsQDIdCwyUKTtMuf9nCLwq9jOGlLGIeQGKDxXF7HbiAysFIu5QW/iQr1LzMgDyM9NH7K98KY+BiIFriQ==} + engines: {node: '>= 14.0.0'} + + '@algolia/client-common@5.15.0': + resolution: {integrity: sha512-IofrVh213VLsDkPoSKMeM9Dshrv28jhDlBDLRcVJQvlL8pzue7PEB1EZ4UoJFYS3NSn7JOcJ/V+olRQzXlJj1w==} + engines: {node: '>= 14.0.0'} + + '@algolia/client-insights@5.15.0': + resolution: {integrity: sha512-bDDEQGfFidDi0UQUCbxXOCdphbVAgbVmxvaV75cypBTQkJ+ABx/Npw7LkFGw1FsoVrttlrrQbwjvUB6mLVKs/w==} + engines: {node: '>= 14.0.0'} + + '@algolia/client-personalization@5.15.0': + resolution: {integrity: sha512-LfaZqLUWxdYFq44QrasCDED5bSYOswpQjSiIL7Q5fYlefAAUO95PzBPKCfUhSwhb4rKxigHfDkd81AvEicIEoA==} + engines: {node: '>= 14.0.0'} + + '@algolia/client-query-suggestions@5.15.0': + resolution: {integrity: sha512-wu8GVluiZ5+il8WIRsGKu8VxMK9dAlr225h878GGtpTL6VBvwyJvAyLdZsfFIpY0iN++jiNb31q2C1PlPL+n/A==} + engines: {node: '>= 14.0.0'} + + '@algolia/client-search@5.15.0': + resolution: {integrity: sha512-Z32gEMrRRpEta5UqVQA612sLdoqY3AovvUPClDfMxYrbdDAebmGDVPtSogUba1FZ4pP5dx20D3OV3reogLKsRA==} + engines: {node: '>= 14.0.0'} + + '@algolia/ingestion@1.15.0': + resolution: {integrity: sha512-MkqkAxBQxtQ5if/EX2IPqFA7LothghVyvPoRNA/meS2AW2qkHwcxjuiBxv4H6mnAVEPfJlhu9rkdVz9LgCBgJg==} + engines: {node: '>= 14.0.0'} + + '@algolia/monitoring@1.15.0': + resolution: {integrity: sha512-QPrFnnGLMMdRa8t/4bs7XilPYnoUXDY8PMQJ1sf9ZFwhUysYYhQNX34/enoO0LBjpoOY6rLpha39YQEFbzgKyQ==} + engines: {node: '>= 14.0.0'} + + '@algolia/recommend@5.15.0': + resolution: {integrity: sha512-5eupMwSqMLDObgSMF0XG958zR6GJP3f7jHDQ3/WlzCM9/YIJiWIUoJFGsko9GYsA5xbLDHE/PhWtq4chcCdaGQ==} + engines: {node: '>= 14.0.0'} + + '@algolia/requester-browser-xhr@5.15.0': + resolution: {integrity: sha512-Po/GNib6QKruC3XE+WKP1HwVSfCDaZcXu48kD+gwmtDlqHWKc7Bq9lrS0sNZ456rfCKhXksOmMfUs4wRM/Y96w==} + engines: {node: '>= 14.0.0'} + + '@algolia/requester-fetch@5.15.0': + resolution: {integrity: sha512-rOZ+c0P7ajmccAvpeeNrUmEKoliYFL8aOR5qGW5pFq3oj3Iept7Y5mEtEsOBYsRt6qLnaXn4zUKf+N8nvJpcIw==} + engines: {node: '>= 14.0.0'} + + '@algolia/requester-node-http@5.15.0': + resolution: {integrity: sha512-b1jTpbFf9LnQHEJP5ddDJKE2sAlhYd7EVSOWgzo/27n/SfCoHfqD0VWntnWYD83PnOKvfe8auZ2+xCb0TXotrQ==} + engines: {node: '>= 14.0.0'} + + '@ampproject/remapping@2.3.0': + resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==} + engines: {node: '>=6.0.0'} + + '@antfu/install-pkg@0.4.1': + resolution: {integrity: sha512-T7yB5QNG29afhWVkVq7XeIMBa5U/vs9mX69YqayXypPRmYzUmzwnYltplHmPtZ4HPCn+sQKeXW8I47wCbuBOjw==} + + '@antfu/utils@0.7.10': + resolution: {integrity: sha512-+562v9k4aI80m1+VuMHehNJWLOFjBnXn3tdOitzD0il5b7smkSBal4+a3oKiQTbrwMmN/TBUMDvbdoWDehgOww==} + + '@babel/helper-string-parser@7.25.9': + resolution: {integrity: sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-identifier@7.25.9': + resolution: {integrity: sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==} + engines: {node: '>=6.9.0'} + + '@babel/parser@7.26.2': + resolution: {integrity: sha512-DWMCZH9WA4Maitz2q21SRKHo9QXZxkDsbNZoVD62gusNtNBBqDg9i7uOhASfTfIGNzW+O+r7+jAlM8dwphcJKQ==} + engines: {node: '>=6.0.0'} + hasBin: true + + '@babel/types@7.26.0': + resolution: {integrity: sha512-Z/yiTPj+lDVnF7lWeKCIJzaIkI0vYO87dMpZ4bg4TDrFe4XXLFWL1TbXU27gBP3QccxV9mZICCrnjnYlJjXHOA==} + engines: {node: '>=6.9.0'} + + '@docsearch/css@3.8.0': + resolution: {integrity: sha512-pieeipSOW4sQ0+bE5UFC51AOZp9NGxg89wAlZ1BAQFaiRAGK1IKUaPQ0UGZeNctJXyqZ1UvBtOQh2HH+U5GtmA==} + + '@docsearch/js@3.8.0': + resolution: {integrity: sha512-PVuV629f5UcYRtBWqK7ID6vNL5647+2ADJypwTjfeBIrJfwPuHtzLy39hMGMfFK+0xgRyhTR0FZ83EkdEraBlg==} + + '@docsearch/react@3.8.0': + resolution: {integrity: sha512-WnFK720+iwTVt94CxY3u+FgX6exb3BfN5kE9xUY6uuAH/9W/UFboBZFLlrw/zxFRHoHZCOXRtOylsXF+6LHI+Q==} + peerDependencies: + '@types/react': '>= 16.8.0 < 19.0.0' + react: '>= 16.8.0 < 19.0.0' + react-dom: '>= 16.8.0 < 19.0.0' + search-insights: '>= 1 < 3' + peerDependenciesMeta: + '@types/react': + optional: true + react: + optional: true + react-dom: + optional: true + search-insights: + optional: true + + '@esbuild/aix-ppc64@0.21.5': + resolution: {integrity: sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [aix] + + '@esbuild/aix-ppc64@0.23.1': + resolution: {integrity: sha512-6VhYk1diRqrhBAqpJEdjASR/+WVRtfjpqKuNw11cLiaWpAT/Uu+nokB+UJnevzy/P9C/ty6AOe0dwueMrGh/iQ==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [aix] + + '@esbuild/android-arm64@0.21.5': + resolution: {integrity: sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==} + engines: {node: '>=12'} + cpu: [arm64] + os: [android] + + '@esbuild/android-arm64@0.23.1': + resolution: {integrity: sha512-xw50ipykXcLstLeWH7WRdQuysJqejuAGPd30vd1i5zSyKK3WE+ijzHmLKxdiCMtH1pHz78rOg0BKSYOSB/2Khw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [android] + + '@esbuild/android-arm@0.21.5': + resolution: {integrity: sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==} + engines: {node: '>=12'} + cpu: [arm] + os: [android] + + '@esbuild/android-arm@0.23.1': + resolution: {integrity: sha512-uz6/tEy2IFm9RYOyvKl88zdzZfwEfKZmnX9Cj1BHjeSGNuGLuMD1kR8y5bteYmwqKm1tj8m4cb/aKEorr6fHWQ==} + engines: {node: '>=18'} + cpu: [arm] + os: [android] + + '@esbuild/android-x64@0.21.5': + resolution: {integrity: sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==} + engines: {node: '>=12'} + cpu: [x64] + os: [android] + + '@esbuild/android-x64@0.23.1': + resolution: {integrity: sha512-nlN9B69St9BwUoB+jkyU090bru8L0NA3yFvAd7k8dNsVH8bi9a8cUAUSEcEEgTp2z3dbEDGJGfP6VUnkQnlReg==} + engines: {node: '>=18'} + cpu: [x64] + os: [android] + + '@esbuild/darwin-arm64@0.21.5': + resolution: {integrity: sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==} + engines: {node: '>=12'} + cpu: [arm64] + os: [darwin] + + '@esbuild/darwin-arm64@0.23.1': + resolution: {integrity: sha512-YsS2e3Wtgnw7Wq53XXBLcV6JhRsEq8hkfg91ESVadIrzr9wO6jJDMZnCQbHm1Guc5t/CdDiFSSfWP58FNuvT3Q==} + engines: {node: '>=18'} + cpu: [arm64] + os: [darwin] + + '@esbuild/darwin-x64@0.21.5': + resolution: {integrity: sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==} + engines: {node: '>=12'} + cpu: [x64] + os: [darwin] + + '@esbuild/darwin-x64@0.23.1': + resolution: {integrity: sha512-aClqdgTDVPSEGgoCS8QDG37Gu8yc9lTHNAQlsztQ6ENetKEO//b8y31MMu2ZaPbn4kVsIABzVLXYLhCGekGDqw==} + engines: {node: '>=18'} + cpu: [x64] + os: [darwin] + + '@esbuild/freebsd-arm64@0.21.5': + resolution: {integrity: sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==} + engines: {node: '>=12'} + cpu: [arm64] + os: [freebsd] + + '@esbuild/freebsd-arm64@0.23.1': + resolution: {integrity: sha512-h1k6yS8/pN/NHlMl5+v4XPfikhJulk4G+tKGFIOwURBSFzE8bixw1ebjluLOjfwtLqY0kewfjLSrO6tN2MgIhA==} + engines: {node: '>=18'} + cpu: [arm64] + os: [freebsd] + + '@esbuild/freebsd-x64@0.21.5': + resolution: {integrity: sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [freebsd] + + '@esbuild/freebsd-x64@0.23.1': + resolution: {integrity: sha512-lK1eJeyk1ZX8UklqFd/3A60UuZ/6UVfGT2LuGo3Wp4/z7eRTRYY+0xOu2kpClP+vMTi9wKOfXi2vjUpO1Ro76g==} + engines: {node: '>=18'} + cpu: [x64] + os: [freebsd] + + '@esbuild/linux-arm64@0.21.5': + resolution: {integrity: sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==} + engines: {node: '>=12'} + cpu: [arm64] + os: [linux] + + '@esbuild/linux-arm64@0.23.1': + resolution: {integrity: sha512-/93bf2yxencYDnItMYV/v116zff6UyTjo4EtEQjUBeGiVpMmffDNUyD9UN2zV+V3LRV3/on4xdZ26NKzn6754g==} + engines: {node: '>=18'} + cpu: [arm64] + os: [linux] + + '@esbuild/linux-arm@0.21.5': + resolution: {integrity: sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==} + engines: {node: '>=12'} + cpu: [arm] + os: [linux] + + '@esbuild/linux-arm@0.23.1': + resolution: {integrity: sha512-CXXkzgn+dXAPs3WBwE+Kvnrf4WECwBdfjfeYHpMeVxWE0EceB6vhWGShs6wi0IYEqMSIzdOF1XjQ/Mkm5d7ZdQ==} + engines: {node: '>=18'} + cpu: [arm] + os: [linux] + + '@esbuild/linux-ia32@0.21.5': + resolution: {integrity: sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==} + engines: {node: '>=12'} + cpu: [ia32] + os: [linux] + + '@esbuild/linux-ia32@0.23.1': + resolution: {integrity: sha512-VTN4EuOHwXEkXzX5nTvVY4s7E/Krz7COC8xkftbbKRYAl96vPiUssGkeMELQMOnLOJ8k3BY1+ZY52tttZnHcXQ==} + engines: {node: '>=18'} + cpu: [ia32] + os: [linux] + + '@esbuild/linux-loong64@0.21.5': + resolution: {integrity: sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==} + engines: {node: '>=12'} + cpu: [loong64] + os: [linux] + + '@esbuild/linux-loong64@0.23.1': + resolution: {integrity: sha512-Vx09LzEoBa5zDnieH8LSMRToj7ir/Jeq0Gu6qJ/1GcBq9GkfoEAoXvLiW1U9J1qE/Y/Oyaq33w5p2ZWrNNHNEw==} + engines: {node: '>=18'} + cpu: [loong64] + os: [linux] + + '@esbuild/linux-mips64el@0.21.5': + resolution: {integrity: sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==} + engines: {node: '>=12'} + cpu: [mips64el] + os: [linux] + + '@esbuild/linux-mips64el@0.23.1': + resolution: {integrity: sha512-nrFzzMQ7W4WRLNUOU5dlWAqa6yVeI0P78WKGUo7lg2HShq/yx+UYkeNSE0SSfSure0SqgnsxPvmAUu/vu0E+3Q==} + engines: {node: '>=18'} + cpu: [mips64el] + os: [linux] + + '@esbuild/linux-ppc64@0.21.5': + resolution: {integrity: sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [linux] + + '@esbuild/linux-ppc64@0.23.1': + resolution: {integrity: sha512-dKN8fgVqd0vUIjxuJI6P/9SSSe/mB9rvA98CSH2sJnlZ/OCZWO1DJvxj8jvKTfYUdGfcq2dDxoKaC6bHuTlgcw==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [linux] + + '@esbuild/linux-riscv64@0.21.5': + resolution: {integrity: sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==} + engines: {node: '>=12'} + cpu: [riscv64] + os: [linux] + + '@esbuild/linux-riscv64@0.23.1': + resolution: {integrity: sha512-5AV4Pzp80fhHL83JM6LoA6pTQVWgB1HovMBsLQ9OZWLDqVY8MVobBXNSmAJi//Csh6tcY7e7Lny2Hg1tElMjIA==} + engines: {node: '>=18'} + cpu: [riscv64] + os: [linux] + + '@esbuild/linux-s390x@0.21.5': + resolution: {integrity: sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==} + engines: {node: '>=12'} + cpu: [s390x] + os: [linux] + + '@esbuild/linux-s390x@0.23.1': + resolution: {integrity: sha512-9ygs73tuFCe6f6m/Tb+9LtYxWR4c9yg7zjt2cYkjDbDpV/xVn+68cQxMXCjUpYwEkze2RcU/rMnfIXNRFmSoDw==} + engines: {node: '>=18'} + cpu: [s390x] + os: [linux] + + '@esbuild/linux-x64@0.21.5': + resolution: {integrity: sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [linux] + + '@esbuild/linux-x64@0.23.1': + resolution: {integrity: sha512-EV6+ovTsEXCPAp58g2dD68LxoP/wK5pRvgy0J/HxPGB009omFPv3Yet0HiaqvrIrgPTBuC6wCH1LTOY91EO5hQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [linux] + + '@esbuild/netbsd-x64@0.21.5': + resolution: {integrity: sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==} + engines: {node: '>=12'} + cpu: [x64] + os: [netbsd] + + '@esbuild/netbsd-x64@0.23.1': + resolution: {integrity: sha512-aevEkCNu7KlPRpYLjwmdcuNz6bDFiE7Z8XC4CPqExjTvrHugh28QzUXVOZtiYghciKUacNktqxdpymplil1beA==} + engines: {node: '>=18'} + cpu: [x64] + os: [netbsd] + + '@esbuild/openbsd-arm64@0.23.1': + resolution: {integrity: sha512-3x37szhLexNA4bXhLrCC/LImN/YtWis6WXr1VESlfVtVeoFJBRINPJ3f0a/6LV8zpikqoUg4hyXw0sFBt5Cr+Q==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openbsd] + + '@esbuild/openbsd-x64@0.21.5': + resolution: {integrity: sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==} + engines: {node: '>=12'} + cpu: [x64] + os: [openbsd] + + '@esbuild/openbsd-x64@0.23.1': + resolution: {integrity: sha512-aY2gMmKmPhxfU+0EdnN+XNtGbjfQgwZj43k8G3fyrDM/UdZww6xrWxmDkuz2eCZchqVeABjV5BpildOrUbBTqA==} + engines: {node: '>=18'} + cpu: [x64] + os: [openbsd] + + '@esbuild/sunos-x64@0.21.5': + resolution: {integrity: sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==} + engines: {node: '>=12'} + cpu: [x64] + os: [sunos] + + '@esbuild/sunos-x64@0.23.1': + resolution: {integrity: sha512-RBRT2gqEl0IKQABT4XTj78tpk9v7ehp+mazn2HbUeZl1YMdaGAQqhapjGTCe7uw7y0frDi4gS0uHzhvpFuI1sA==} + engines: {node: '>=18'} + cpu: [x64] + os: [sunos] + + '@esbuild/win32-arm64@0.21.5': + resolution: {integrity: sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==} + engines: {node: '>=12'} + cpu: [arm64] + os: [win32] + + '@esbuild/win32-arm64@0.23.1': + resolution: {integrity: sha512-4O+gPR5rEBe2FpKOVyiJ7wNDPA8nGzDuJ6gN4okSA1gEOYZ67N8JPk58tkWtdtPeLz7lBnY6I5L3jdsr3S+A6A==} + engines: {node: '>=18'} + cpu: [arm64] + os: [win32] + + '@esbuild/win32-ia32@0.21.5': + resolution: {integrity: sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==} + engines: {node: '>=12'} + cpu: [ia32] + os: [win32] + + '@esbuild/win32-ia32@0.23.1': + resolution: {integrity: sha512-BcaL0Vn6QwCwre3Y717nVHZbAa4UBEigzFm6VdsVdT/MbZ38xoj1X9HPkZhbmaBGUD1W8vxAfffbDe8bA6AKnQ==} + engines: {node: '>=18'} + cpu: [ia32] + os: [win32] + + '@esbuild/win32-x64@0.21.5': + resolution: {integrity: sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==} + engines: {node: '>=12'} + cpu: [x64] + os: [win32] + + '@esbuild/win32-x64@0.23.1': + resolution: {integrity: sha512-BHpFFeslkWrXWyUPnbKm+xYYVYruCinGcftSBaa8zoF9hZO4BcSCFUvHVTtzpIY6YzUnYtuEhZ+C9iEXjxnasg==} + engines: {node: '>=18'} + cpu: [x64] + os: [win32] + + '@iconify-json/gg@1.2.1': + resolution: {integrity: sha512-ELQiJMsxxz3VREz/LFE68e+qMMyQhZ0rrsAxnMs6ia1A3fA1tZ98yvXNhvgt4wRaiSfnzR4+5QqCVSZuuW8qQQ==} + + '@iconify-json/ic@1.2.1': + resolution: {integrity: sha512-UjL/bjJP/T5EV881+hTzcfTKVo0KEUjhnMiJcLtPzNgPtU2KZZmRx8BSKKR61H4CN/5FTEbyawGyG0aEt3SwGQ==} + + '@iconify-json/logos@1.2.3': + resolution: {integrity: sha512-JLHS5hgZP1b55EONAWNeqBUuriRfRNKWXK4cqYx0PpVaJfIIMiiMxFfvoQiX/bkE9XgkLhcKmDUqL3LXPdXPwQ==} + + '@iconify-json/material-symbols@1.2.7': + resolution: {integrity: sha512-3zJ0vv20YfrmI1sFcWTRXWY23+qqTo/WNHm7k1yqbTneSS7yfQakUQjEB05S9YNzu6KODeJ+xHCgcq6RkGn6jg==} + + '@iconify-json/mdi@1.2.1': + resolution: {integrity: sha512-dSkQU78gsZV6Yxnq78+LuX7jzeFC/5NAmz7O3rh558GimGFcwMVY/OtqRowIzjqJBmMmWZft7wkFV4TrwRXjlg==} + + '@iconify-json/mingcute@1.2.1': + resolution: {integrity: sha512-rv682dBsjKUs1/AVg5tOegAunjCLuqyQufXU0D6Kbmgg5jMoUcl/9K2C+9MAiepBP0Eyb05YwXQvGaXMLPu/YA==} + + '@iconify-json/octicon@1.2.1': + resolution: {integrity: sha512-4w7yMipQtp6s6aCHrSVlVXsf0OCBQ8CRmUTkMQUBexR42SXl4z5GnaUyaOMVoZttfgaBNnj0mlMB5T1cmRDgTg==} + + '@iconify-json/simple-icons@1.2.12': + resolution: {integrity: sha512-lRNORrIdeLStShxAjN6FgXE1iMkaAgiAHZdP0P0GZecX91FVYW58uZnRSlXLlSx5cxMoELulkAAixybPA2g52g==} + + '@iconify-json/twemoji@1.2.1': + resolution: {integrity: sha512-BwYutpZMsBfo9YXXLCosyQXT9qU5xT+FBOqw2Ivks0bL7zZNiQGP/bONoQTZVvmOcEJrndfcvZGfKTDC92klfQ==} + + '@iconify/types@2.0.0': + resolution: {integrity: sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==} + + '@iconify/utils@2.1.33': + resolution: {integrity: sha512-jP9h6v/g0BIZx0p7XGJJVtkVnydtbgTgt9mVNcGDYwaa7UhdHdI9dvoq+gKj9sijMSJKxUPEG2JyjsgXjxL7Kw==} + + '@isaacs/cliui@8.0.2': + resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} + engines: {node: '>=12'} + + '@jridgewell/gen-mapping@0.3.5': + resolution: {integrity: sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==} + engines: {node: '>=6.0.0'} + + '@jridgewell/resolve-uri@3.1.2': + resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} + engines: {node: '>=6.0.0'} + + '@jridgewell/set-array@1.2.1': + resolution: {integrity: sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==} + engines: {node: '>=6.0.0'} + + '@jridgewell/sourcemap-codec@1.5.0': + resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==} + + '@jridgewell/trace-mapping@0.3.25': + resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==} + + '@pagefind/darwin-arm64@1.2.0': + resolution: {integrity: sha512-pHnPL2rm4xbe0LqV376g84hUIsVdy4PK6o2ACveo0DSGoC40eOIwPUPftnUPUinSdDWkkySaL5FT5r9hsXk0ZQ==} + cpu: [arm64] + os: [darwin] + + '@pagefind/darwin-x64@1.2.0': + resolution: {integrity: sha512-q2tcnfvcRyx0GnrJoUQJ5bRpiFNtI8DZWM6a4/k8sNJxm2dbM1BnY5hUeo4MbDfpb64Qc1wRMcvBUSOaMKBjfg==} + cpu: [x64] + os: [darwin] + + '@pagefind/linux-arm64@1.2.0': + resolution: {integrity: sha512-wVtLOlF9AUrwLovP9ZSEKOYnwIVrrxId4I2Mz02Zxm3wbUIJyx8wHf6LyEf7W7mJ6rEjW5jtavKAbngKCAaicg==} + cpu: [arm64] + os: [linux] + + '@pagefind/linux-x64@1.2.0': + resolution: {integrity: sha512-Lo5aO2bA++sQTeEWzK5WKr3KU0yzVH5OnTY88apZfkgL4AVfXckH2mrOU8ouYKCLNPseIYTLFEdj0V5xjHQSwQ==} + cpu: [x64] + os: [linux] + + '@pagefind/windows-x64@1.2.0': + resolution: {integrity: sha512-tGQcwQAb5Ndv7woc7lhH9iAdxOnTNsgCz8sEBbsASPB2A0uI8BWBmVdf2GFLQkYHqnnqYuun63sa+UOzB7Ah3g==} + cpu: [x64] + os: [win32] + + '@pkgjs/parseargs@0.11.0': + resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} + engines: {node: '>=14'} + + '@polka/url@1.0.0-next.28': + resolution: {integrity: sha512-8LduaNlMZGwdZ6qWrKlfa+2M4gahzFkprZiAt2TF8uS0qQgBizKXpXURqvTJ4WtmupWxaLqjRb2UCTe72mu+Aw==} + + '@rollup/pluginutils@5.1.3': + resolution: {integrity: sha512-Pnsb6f32CD2W3uCaLZIzDmeFyQ2b8UWMFI7xtwUezpcGBDVDW6y9XgAWIlARiGAo6eNF5FK5aQTr0LFyNyqq5A==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + + '@rollup/rollup-android-arm-eabi@4.27.3': + resolution: {integrity: sha512-EzxVSkIvCFxUd4Mgm4xR9YXrcp976qVaHnqom/Tgm+vU79k4vV4eYTjmRvGfeoW8m9LVcsAy/lGjcgVegKEhLQ==} + cpu: [arm] + os: [android] + + '@rollup/rollup-android-arm64@4.27.3': + resolution: {integrity: sha512-LJc5pDf1wjlt9o/Giaw9Ofl+k/vLUaYsE2zeQGH85giX2F+wn/Cg8b3c5CDP3qmVmeO5NzwVUzQQxwZvC2eQKw==} + cpu: [arm64] + os: [android] + + '@rollup/rollup-darwin-arm64@4.27.3': + resolution: {integrity: sha512-OuRysZ1Mt7wpWJ+aYKblVbJWtVn3Cy52h8nLuNSzTqSesYw1EuN6wKp5NW/4eSre3mp12gqFRXOKTcN3AI3LqA==} + cpu: [arm64] + os: [darwin] + + '@rollup/rollup-darwin-x64@4.27.3': + resolution: {integrity: sha512-xW//zjJMlJs2sOrCmXdB4d0uiilZsOdlGQIC/jjmMWT47lkLLoB1nsNhPUcnoqyi5YR6I4h+FjBpILxbEy8JRg==} + cpu: [x64] + os: [darwin] + + '@rollup/rollup-freebsd-arm64@4.27.3': + resolution: {integrity: sha512-58E0tIcwZ+12nK1WiLzHOD8I0d0kdrY/+o7yFVPRHuVGY3twBwzwDdTIBGRxLmyjciMYl1B/U515GJy+yn46qw==} + cpu: [arm64] + os: [freebsd] + + '@rollup/rollup-freebsd-x64@4.27.3': + resolution: {integrity: sha512-78fohrpcVwTLxg1ZzBMlwEimoAJmY6B+5TsyAZ3Vok7YabRBUvjYTsRXPTjGEvv/mfgVBepbW28OlMEz4w8wGA==} + cpu: [x64] + os: [freebsd] + + '@rollup/rollup-linux-arm-gnueabihf@4.27.3': + resolution: {integrity: sha512-h2Ay79YFXyQi+QZKo3ISZDyKaVD7uUvukEHTOft7kh00WF9mxAaxZsNs3o/eukbeKuH35jBvQqrT61fzKfAB/Q==} + cpu: [arm] + os: [linux] + + '@rollup/rollup-linux-arm-musleabihf@4.27.3': + resolution: {integrity: sha512-Sv2GWmrJfRY57urktVLQ0VKZjNZGogVtASAgosDZ1aUB+ykPxSi3X1nWORL5Jk0sTIIwQiPH7iE3BMi9zGWfkg==} + cpu: [arm] + os: [linux] + + '@rollup/rollup-linux-arm64-gnu@4.27.3': + resolution: {integrity: sha512-FPoJBLsPW2bDNWjSrwNuTPUt30VnfM8GPGRoLCYKZpPx0xiIEdFip3dH6CqgoT0RnoGXptaNziM0WlKgBc+OWQ==} + cpu: [arm64] + os: [linux] + + '@rollup/rollup-linux-arm64-musl@4.27.3': + resolution: {integrity: sha512-TKxiOvBorYq4sUpA0JT+Fkh+l+G9DScnG5Dqx7wiiqVMiRSkzTclP35pE6eQQYjP4Gc8yEkJGea6rz4qyWhp3g==} + cpu: [arm64] + os: [linux] + + '@rollup/rollup-linux-powerpc64le-gnu@4.27.3': + resolution: {integrity: sha512-v2M/mPvVUKVOKITa0oCFksnQQ/TqGrT+yD0184/cWHIu0LoIuYHwox0Pm3ccXEz8cEQDLk6FPKd1CCm+PlsISw==} + cpu: [ppc64] + os: [linux] + + '@rollup/rollup-linux-riscv64-gnu@4.27.3': + resolution: {integrity: sha512-LdrI4Yocb1a/tFVkzmOE5WyYRgEBOyEhWYJe4gsDWDiwnjYKjNs7PS6SGlTDB7maOHF4kxevsuNBl2iOcj3b4A==} + cpu: [riscv64] + os: [linux] + + '@rollup/rollup-linux-s390x-gnu@4.27.3': + resolution: {integrity: sha512-d4wVu6SXij/jyiwPvI6C4KxdGzuZOvJ6y9VfrcleHTwo68fl8vZC5ZYHsCVPUi4tndCfMlFniWgwonQ5CUpQcA==} + cpu: [s390x] + os: [linux] + + '@rollup/rollup-linux-x64-gnu@4.27.3': + resolution: {integrity: sha512-/6bn6pp1fsCGEY5n3yajmzZQAh+mW4QPItbiWxs69zskBzJuheb3tNynEjL+mKOsUSFK11X4LYF2BwwXnzWleA==} + cpu: [x64] + os: [linux] + + '@rollup/rollup-linux-x64-musl@4.27.3': + resolution: {integrity: sha512-nBXOfJds8OzUT1qUreT/en3eyOXd2EH5b0wr2bVB5999qHdGKkzGzIyKYaKj02lXk6wpN71ltLIaQpu58YFBoQ==} + cpu: [x64] + os: [linux] + + '@rollup/rollup-win32-arm64-msvc@4.27.3': + resolution: {integrity: sha512-ogfbEVQgIZOz5WPWXF2HVb6En+kWzScuxJo/WdQTqEgeyGkaa2ui5sQav9Zkr7bnNCLK48uxmmK0TySm22eiuw==} + cpu: [arm64] + os: [win32] + + '@rollup/rollup-win32-ia32-msvc@4.27.3': + resolution: {integrity: sha512-ecE36ZBMLINqiTtSNQ1vzWc5pXLQHlf/oqGp/bSbi7iedcjcNb6QbCBNG73Euyy2C+l/fn8qKWEwxr+0SSfs3w==} + cpu: [ia32] + os: [win32] + + '@rollup/rollup-win32-x64-msvc@4.27.3': + resolution: {integrity: sha512-vliZLrDmYKyaUoMzEbMTg2JkerfBjn03KmAw9CykO0Zzkzoyd7o3iZNam/TpyWNjNT+Cz2iO3P9Smv2wgrR+Eg==} + cpu: [x64] + os: [win32] + + '@shikijs/core@1.23.1': + resolution: {integrity: sha512-NuOVgwcHgVC6jBVH5V7iblziw6iQbWWHrj5IlZI3Fqu2yx9awH7OIQkXIcsHsUmY19ckwSgUMgrqExEyP5A0TA==} + + '@shikijs/engine-javascript@1.23.1': + resolution: {integrity: sha512-i/LdEwT5k3FVu07SiApRFwRcSJs5QM9+tod5vYCPig1Ywi8GR30zcujbxGQFJHwYD7A5BUqagi8o5KS+LEVgBg==} + + '@shikijs/engine-oniguruma@1.23.1': + resolution: {integrity: sha512-KQ+lgeJJ5m2ISbUZudLR1qHeH3MnSs2mjFg7bnencgs5jDVPeJ2NVDJ3N5ZHbcTsOIh0qIueyAJnwg7lg7kwXQ==} + + '@shikijs/transformers@1.23.1': + resolution: {integrity: sha512-yQ2Cn0M9i46p30KwbyIzLvKDk+dQNU+lj88RGO0XEj54Hn4Cof1bZoDb9xBRWxFE4R8nmK63w7oHnJwvOtt0NQ==} + + '@shikijs/types@1.23.1': + resolution: {integrity: sha512-98A5hGyEhzzAgQh2dAeHKrWW4HfCMeoFER2z16p5eJ+vmPeF6lZ/elEne6/UCU551F/WqkopqRsr1l2Yu6+A0g==} + + '@shikijs/vscode-textmate@9.3.0': + resolution: {integrity: sha512-jn7/7ky30idSkd/O5yDBfAnVt+JJpepofP/POZ1iMOxK59cOfqIgg/Dj0eFsjOTMw+4ycJN0uhZH/Eb0bs/EUA==} + + '@sugarat/theme-shared@0.0.3': + resolution: {integrity: sha512-94Ss05oX/PpAAaVUxjvuXmsr3/ZVLXMeQkPhd1IdvKzRLn9Ong2S1vxCy1e1+TArhY72g3ktsBpaWhn5yUx4ng==} + + '@types/estree@1.0.6': + resolution: {integrity: sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==} + + '@types/hast@3.0.4': + resolution: {integrity: sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==} + + '@types/linkify-it@5.0.0': + resolution: {integrity: sha512-sVDA58zAw4eWAffKOaQH5/5j3XeayukzDk+ewSsnv3p4yJEZHCCzMDiZM8e0OUrRvmpGZ85jf4yDHkHsgBNr9Q==} + + '@types/markdown-it@14.1.2': + resolution: {integrity: sha512-promo4eFwuiW+TfGxhi+0x3czqTYJkG8qB17ZUJiVF10Xm7NLVRSLUsfRTU/6h1e24VvRnXCx+hG7li58lkzog==} + + '@types/mdast@4.0.4': + resolution: {integrity: sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==} + + '@types/mdurl@2.0.0': + resolution: {integrity: sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg==} + + '@types/unist@3.0.3': + resolution: {integrity: sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==} + + '@types/web-bluetooth@0.0.16': + resolution: {integrity: sha512-oh8q2Zc32S6gd/j50GowEjKLoOVOwHP/bWVjKJInBwQqdOYMdPrf1oVlelTlyfFK3CKxL1uahMDAr+vy8T7yMQ==} + + '@types/web-bluetooth@0.0.20': + resolution: {integrity: sha512-g9gZnnXVq7gM7v3tJCWV/qw7w+KeOlSHAhgF9RytFyifW6AF61hdT2ucrYhPq9hLs5JIryeupHV3qGk95dH9ow==} + + '@ungap/structured-clone@1.2.0': + resolution: {integrity: sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==} + + '@unocss/astro@0.64.1': + resolution: {integrity: sha512-UBB2nDc3aqBmdcgJHOsnAQaQnbdch4f3CKfV+LTv77D4tPizagUCODwPVTK3CA3leQzVbbUV06uHfo5hsv2PUw==} + peerDependencies: + vite: ^2.9.0 || ^3.0.0-0 || ^4.0.0 || ^5.0.0-0 + peerDependenciesMeta: + vite: + optional: true + + '@unocss/cli@0.64.1': + resolution: {integrity: sha512-P08Routw1TiCZyvfcveZIQrJi4/agBtWJAMP4NwVgYre7Lgl0jYF4qn9NEpUS4z+Qc5t2U33+4q0xgZpVh4oPw==} + engines: {node: '>=14'} + hasBin: true + + '@unocss/config@0.64.1': + resolution: {integrity: sha512-uhUfVnRhVsqZrRuFGGFfvvSO9gVUSHgfXOF/u8MnQ/lG1MVyXpx5QykVhjSgSehMfQIFsZ2SID1y7Fd5f8kgLw==} + engines: {node: '>=14'} + + '@unocss/core@0.64.1': + resolution: {integrity: sha512-D1ULd70a24/k6kGyHCIijbrrIn9UjFUEBg2R4xKX2/ViQb1k2MIgOs4VS20MkJX6kbZXqqm/zAFHzDhsQGIhBA==} + + '@unocss/extractor-arbitrary-variants@0.64.1': + resolution: {integrity: sha512-tKtaeZYzSCaH1ASE7Uj45rPX4ApQHYE8eZFfaL3N4ZY0LYrTJPBnaLSRfLRwGD6KLHjoL3+sorywJiS/VVBcFQ==} + + '@unocss/inspector@0.64.1': + resolution: {integrity: sha512-IDlSxvczxzQso/9aIneQaQ+jVhi8/Wb6uck1pRZm3q71uF3+mhzqEvQojbe1VaKqwUlCmBy2U+M/e8L5dJavlA==} + + '@unocss/postcss@0.64.1': + resolution: {integrity: sha512-tlc5ZFO6xoLhYukSRtKSBaP1SDmAatmHCbbRiH6ElncEQNpjl70raXMKjQWfIuAo8IniUe69ILZC+M60AGPYmA==} + engines: {node: '>=14'} + peerDependencies: + postcss: ^8.4.21 + + '@unocss/preset-attributify@0.64.1': + resolution: {integrity: sha512-uxq4iiMZN+/Dy/TAQI/b+mWbHqI7ww/vVJC8tvjdXm9C4SditLb1Wd+Y183nhXI3Pa78wEibK5t8RaDc/fgKPg==} + + '@unocss/preset-icons@0.64.1': + resolution: {integrity: sha512-aQ4hN2NFdJo08pzUYc1FpwTkNUByE7FB51KmRwXclsVKeXFGvFO3YUYeg5IDlTxqCfvFVWZ3q8NhnmpKGkbutw==} + + '@unocss/preset-mini@0.64.1': + resolution: {integrity: sha512-tl+ciN0elB9eETEVZQrNaMy4NpbLdWDVW7KlmpRZi4Eomf/Ntz+Wctp5V0aBvszo8arEaDiOwsgMxITvx9Ll6Q==} + + '@unocss/preset-tagify@0.64.1': + resolution: {integrity: sha512-xBGF7usHIDOMmLEgawpgbOAoNZ8qFZ/mpbRG9tdEjOHJ+rXJuJlZHhwIgwjQiFRCzSRtlsN57/iM37bZNRCEAg==} + + '@unocss/preset-typography@0.64.1': + resolution: {integrity: sha512-5L/m0YrtF5P6W4U1DhMfqdKVFbso09TplVHK9udJMvYMaj4HzNNIo6GtpbSm2eCXBzxIYuzAjQ9kLldOXjZS1w==} + + '@unocss/preset-uno@0.64.1': + resolution: {integrity: sha512-9427KmOHsck9mNfOXiCBy43Q9aAI1w15tCBJf2bDMHioJltc6JjW+Mg5DDZWnYelhzpXCYK7zTZtMJ40KxDx+g==} + + '@unocss/preset-web-fonts@0.64.1': + resolution: {integrity: sha512-qhc1976bVDMYG+aG5VKvTsKK7K8hMrNnhkCmfKmvdFH7xSj8MB80YxdmiAAcKh3cVk97bh0ej7ym6Lss7I2Idg==} + + '@unocss/preset-wind@0.64.1': + resolution: {integrity: sha512-IpAfsi2tI4elb2uZzc3BSZgbi0axgwgJLPFW0BtZQe4u1J+zrUIOvjCu/2jmiB7LR05IShCyMKIz9Vi4EJm+gQ==} + + '@unocss/reset@0.64.1': + resolution: {integrity: sha512-xx36rWcrIpyvI1l/v+szQLrxWAgsmk6GH85QQ5iE1qccQbL9IlhWHB1KEd3cRbJ1TFeZ2Mzca/qsjg0LU9ZVnA==} + + '@unocss/rule-utils@0.64.1': + resolution: {integrity: sha512-h+Du0lezKHmdsEsGQGAtGrwrTrU+Av4eij46UzpzuNWFq0mAouBu8m/lgBI1AcY9B0Jg3EJalkOgA06tAKS8jg==} + engines: {node: '>=14'} + + '@unocss/transformer-attributify-jsx@0.64.1': + resolution: {integrity: sha512-Zg7rfNheWxJh2G5C0gCctGc6c8NbmI6wqbYjUxUDXEeT+lrZqKeDpTmgcLis7gLqGELFvIqE5R0EpARvjrj9bw==} + + '@unocss/transformer-compile-class@0.64.1': + resolution: {integrity: sha512-oASb3lJq++Ll6LD3frT0WiEZUJupjrLF+rtkgz3lKPgD8bRpbh+m5FykGAIHj5VcIcYOACD4GkTrSFrQbL0GEw==} + + '@unocss/transformer-directives@0.64.1': + resolution: {integrity: sha512-6yWZh7YxYTaNSdATkGpP+aQ3aTRLNo4URDmLQKB3uaQbF0Ae5dLlxXWHZ26VIpKkQ3+hME4TRxEptTR0/ag7nw==} + + '@unocss/transformer-variant-group@0.64.1': + resolution: {integrity: sha512-wQkD1x69YSiIXvSvNNTN6hTZXHVzbVY+xmfoXL3bi/1cDMzRmE9C2Gk/Rzm/BSQxsLusLfDDL0NuhxWoFmvWPA==} + + '@unocss/vite@0.64.1': + resolution: {integrity: sha512-DIvl7Mofc5Q6kKElMRALbH33xBYb5w3Yf7TQ860lmi3DOwjEcg+OWE1HD+iDf7IxZeqPsdF17NvJJaSdmr0m5Q==} + peerDependencies: + vite: ^2.9.0 || ^3.0.0-0 || ^4.0.0 || ^5.0.0-0 + + '@vitejs/plugin-vue@5.2.0': + resolution: {integrity: sha512-7n7KdUEtx/7Yl7I/WVAMZ1bEb0eVvXF3ummWTeLcs/9gvo9pJhuLdouSXGjdZ/MKD1acf1I272+X0RMua4/R3g==} + engines: {node: ^18.0.0 || >=20.0.0} + peerDependencies: + vite: ^5.0.0 + vue: ^3.2.25 + + '@vue/compiler-core@3.5.13': + resolution: {integrity: sha512-oOdAkwqUfW1WqpwSYJce06wvt6HljgY3fGeM9NcVA1HaYOij3mZG9Rkysn0OHuyUAGMbEbARIpsG+LPVlBJ5/Q==} + + '@vue/compiler-dom@3.5.13': + resolution: {integrity: sha512-ZOJ46sMOKUjO3e94wPdCzQ6P1Lx/vhp2RSvfaab88Ajexs0AHeV0uasYhi99WPaogmBlRHNRuly8xV75cNTMDA==} + + '@vue/compiler-sfc@3.5.13': + resolution: {integrity: sha512-6VdaljMpD82w6c2749Zhf5T9u5uLBWKnVue6XWxprDobftnletJ8+oel7sexFfM3qIxNmVE7LSFGTpv6obNyaQ==} + + '@vue/compiler-ssr@3.5.13': + resolution: {integrity: sha512-wMH6vrYHxQl/IybKJagqbquvxpWCuVYpoUJfCqFZwa/JY1GdATAQ+TgVtgrwwMZ0D07QhA99rs/EAAWfvG6KpA==} + + '@vue/devtools-api@7.6.4': + resolution: {integrity: sha512-5AaJ5ELBIuevmFMZYYLuOO9HUuY/6OlkOELHE7oeDhy4XD/hSODIzktlsvBOsn+bto3aD0psj36LGzwVu5Ip8w==} + + '@vue/devtools-kit@7.6.4': + resolution: {integrity: sha512-Zs86qIXXM9icU0PiGY09PQCle4TI750IPLmAJzW5Kf9n9t5HzSYf6Rz6fyzSwmfMPiR51SUKJh9sXVZu78h2QA==} + + '@vue/devtools-shared@7.6.4': + resolution: {integrity: sha512-nD6CUvBEel+y7zpyorjiUocy0nh77DThZJ0k1GRnJeOmY3ATq2fWijEp7wk37gb023Cb0R396uYh5qMSBQ5WFg==} + + '@vue/reactivity@3.5.13': + resolution: {integrity: sha512-NaCwtw8o48B9I6L1zl2p41OHo/2Z4wqYGGIK1Khu5T7yxrn+ATOixn/Udn2m+6kZKB/J7cuT9DbWWhRxqixACg==} + + '@vue/runtime-core@3.5.13': + resolution: {integrity: sha512-Fj4YRQ3Az0WTZw1sFe+QDb0aXCerigEpw418pw1HBUKFtnQHWzwojaukAs2X/c9DQz4MQ4bsXTGlcpGxU/RCIw==} + + '@vue/runtime-dom@3.5.13': + resolution: {integrity: sha512-dLaj94s93NYLqjLiyFzVs9X6dWhTdAlEAciC3Moq7gzAc13VJUdCnjjRurNM6uTLFATRHexHCTu/Xp3eW6yoog==} + + '@vue/server-renderer@3.5.13': + resolution: {integrity: sha512-wAi4IRJV/2SAW3htkTlB+dHeRmpTiVIK1OGLWV1yeStVSebSQQOwGwIq0D3ZIoBj2C2qpgz5+vX9iEBkTdk5YA==} + peerDependencies: + vue: 3.5.13 + + '@vue/shared@3.5.13': + resolution: {integrity: sha512-/hnE/qP5ZoGpol0a5mDi45bOd7t3tjYJBjsgCsivow7D48cJeV5l05RD82lPqi7gRiphZM37rnhW1l6ZoCNNnQ==} + + '@vueuse/core@11.2.0': + resolution: {integrity: sha512-JIUwRcOqOWzcdu1dGlfW04kaJhW3EXnnjJJfLTtddJanymTL7lF1C0+dVVZ/siLfc73mWn+cGP1PE1PKPruRSA==} + + '@vueuse/core@9.13.0': + resolution: {integrity: sha512-pujnclbeHWxxPRqXWmdkKV5OX4Wk4YeK7wusHqRwU0Q7EFusHoqNA/aPhB6KCh9hEqJkLAJo7bb0Lh9b+OIVzw==} + + '@vueuse/integrations@11.2.0': + resolution: {integrity: sha512-zGXz3dsxNHKwiD9jPMvR3DAxQEOV6VWIEYTGVSB9PNpk4pTWR+pXrHz9gvXWcP2sTk3W2oqqS6KwWDdntUvNVA==} + peerDependencies: + async-validator: ^4 + axios: ^1 + change-case: ^5 + drauu: ^0.4 + focus-trap: ^7 + fuse.js: ^7 + idb-keyval: ^6 + jwt-decode: ^4 + nprogress: ^0.2 + qrcode: ^1.5 + sortablejs: ^1 + universal-cookie: ^7 + peerDependenciesMeta: + async-validator: + optional: true + axios: + optional: true + change-case: + optional: true + drauu: + optional: true + focus-trap: + optional: true + fuse.js: + optional: true + idb-keyval: + optional: true + jwt-decode: + optional: true + nprogress: + optional: true + qrcode: + optional: true + sortablejs: + optional: true + universal-cookie: + optional: true + + '@vueuse/metadata@11.2.0': + resolution: {integrity: sha512-L0ZmtRmNx+ZW95DmrgD6vn484gSpVeRbgpWevFKXwqqQxW9hnSi2Ppuh2BzMjnbv4aJRiIw8tQatXT9uOB23dQ==} + + '@vueuse/metadata@9.13.0': + resolution: {integrity: sha512-gdU7TKNAUVlXXLbaF+ZCfte8BjRJQWPCa2J55+7/h+yDtzw3vOoGQDRXzI6pyKyo6bXFT5/QoPE4hAknExjRLQ==} + + '@vueuse/shared@11.2.0': + resolution: {integrity: sha512-VxFjie0EanOudYSgMErxXfq6fo8vhr5ICI+BuE3I9FnX7ePllEsVrRQ7O6Q1TLgApeLuPKcHQxAXpP+KnlrJsg==} + + '@vueuse/shared@9.13.0': + resolution: {integrity: sha512-UrnhU+Cnufu4S6JLCPZnkWh0WwZGUp72ktOF2DFptMlOs3TOdVv8xJN53zhHGARmVOsz5KqOls09+J1NR6sBKw==} + + acorn@8.14.0: + resolution: {integrity: sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==} + engines: {node: '>=0.4.0'} + hasBin: true + + algoliasearch@5.15.0: + resolution: {integrity: sha512-Yf3Swz1s63hjvBVZ/9f2P1Uu48GjmjCN+Esxb6MAONMGtZB1fRX8/S1AhUTtsuTlcGovbYLxpHgc7wEzstDZBw==} + engines: {node: '>= 14.0.0'} + + ansi-regex@5.0.1: + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} + engines: {node: '>=8'} + + ansi-regex@6.1.0: + resolution: {integrity: sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==} + engines: {node: '>=12'} + + ansi-styles@4.3.0: + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} + engines: {node: '>=8'} + + ansi-styles@6.2.1: + resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} + engines: {node: '>=12'} + + anymatch@3.1.3: + resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} + engines: {node: '>= 8'} + + argparse@1.0.10: + resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==} + + balanced-match@1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + + binary-extensions@2.3.0: + resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} + engines: {node: '>=8'} + + birpc@0.2.19: + resolution: {integrity: sha512-5WeXXAvTmitV1RqJFppT5QtUiz2p1mRSYU000Jkft5ZUCLJIk4uQriYNO50HknxKwM6jd8utNc66K1qGIwwWBQ==} + + brace-expansion@2.0.1: + resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} + + braces@3.0.3: + resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} + engines: {node: '>=8'} + + bundle-require@5.0.0: + resolution: {integrity: sha512-GuziW3fSSmopcx4KRymQEJVbZUfqlCqcq7dvs6TYwKRZiegK/2buMxQTPs6MGlNv50wms1699qYO54R8XfRX4w==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + peerDependencies: + esbuild: '>=0.18' + + cac@6.7.14: + resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==} + engines: {node: '>=8'} + + ccount@2.0.1: + resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==} + + character-entities-html4@2.1.0: + resolution: {integrity: sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==} + + character-entities-legacy@3.0.0: + resolution: {integrity: sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==} + + chokidar@3.6.0: + resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} + engines: {node: '>= 8.10.0'} + + color-convert@2.0.1: + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} + engines: {node: '>=7.0.0'} + + color-name@1.1.4: + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + + colorette@2.0.20: + resolution: {integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==} + + comma-separated-tokens@2.0.3: + resolution: {integrity: sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==} + + confbox@0.1.8: + resolution: {integrity: sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==} + + consola@3.2.3: + resolution: {integrity: sha512-I5qxpzLv+sJhTVEoLYNcTW+bThDCPsit0vLNKShZx6rLtpilNpmmeTPaeqJb9ZE9dV3DGaeby6Vuhrw38WjeyQ==} + engines: {node: ^14.18.0 || >=16.10.0} + + copy-anything@3.0.5: + resolution: {integrity: sha512-yCEafptTtb4bk7GLEQoM8KVJpxAfdBJYaXyzQEgQQQgYrZiDp8SJmGKlYza6CYjEDNstAdNdKA3UuoULlEbS6w==} + engines: {node: '>=12.13'} + + cross-spawn@7.0.6: + resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} + engines: {node: '>= 8'} + + css-tree@3.0.1: + resolution: {integrity: sha512-8Fxxv+tGhORlshCdCwnNJytvlvq46sOLSYEx2ZIGurahWvMucSRnyjPA3AmrMq4VPRYbHVpWj5VkiVasrM2H4Q==} + engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0} + + csstype@3.1.3: + resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==} + + debug@4.3.7: + resolution: {integrity: sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + defu@6.1.4: + resolution: {integrity: sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==} + + dequal@2.0.3: + resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==} + engines: {node: '>=6'} + + destr@2.0.3: + resolution: {integrity: sha512-2N3BOUU4gYMpTP24s5rF5iP7BDr7uNTCs4ozw3kf/eKfvWSIu93GEBi5m427YoyJoeOzQ5smuu4nNAPGb8idSQ==} + + devlop@1.1.0: + resolution: {integrity: sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==} + + duplexer@0.1.2: + resolution: {integrity: sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==} + + eastasianwidth@0.2.0: + resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} + + emoji-regex-xs@1.0.0: + resolution: {integrity: sha512-LRlerrMYoIDrT6jgpeZ2YYl/L8EulRTt5hQcYjy5AInh7HWXKimpqx68aknBFpGL2+/IcogTcaydJEgaTmOpDg==} + + emoji-regex@8.0.0: + resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + + emoji-regex@9.2.2: + resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} + + entities@4.5.0: + resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} + engines: {node: '>=0.12'} + + esbuild@0.21.5: + resolution: {integrity: sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==} + engines: {node: '>=12'} + hasBin: true + + esbuild@0.23.1: + resolution: {integrity: sha512-VVNz/9Sa0bs5SELtn3f7qhJCDPCF5oMEl5cO9/SSinpE9hbPVvxbd572HH5AKiP7WD8INO53GgfDDhRjkylHEg==} + engines: {node: '>=18'} + hasBin: true + + esprima@4.0.1: + resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} + engines: {node: '>=4'} + hasBin: true + + estree-walker@2.0.2: + resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} + + extend-shallow@2.0.1: + resolution: {integrity: sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==} + engines: {node: '>=0.10.0'} + + fdir@6.4.2: + resolution: {integrity: sha512-KnhMXsKSPZlAhp7+IjUkRZKPb4fUyccpDrdFXbi4QL1qkmFh9kVY09Yox+n4MaOb3lHZ1Tv829C3oaaXoMYPDQ==} + peerDependencies: + picomatch: ^3 || ^4 + peerDependenciesMeta: + picomatch: + optional: true + + fill-range@7.1.1: + resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} + engines: {node: '>=8'} + + focus-trap@7.6.2: + resolution: {integrity: sha512-9FhUxK1hVju2+AiQIDJ5Dd//9R2n2RAfJ0qfhF4IHGHgcoEUTMpbTeG/zbEuwaiYXfuAH6XE0/aCyxDdRM+W5w==} + + foreground-child@3.3.0: + resolution: {integrity: sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==} + engines: {node: '>=14'} + + fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + + fuse.js@6.6.2: + resolution: {integrity: sha512-cJaJkxCCxC8qIIcPBF9yGxY0W/tVZS3uEISDxhYIdtk8OL93pe+6Zj7LjCqVV4dzbqcriOZ+kQ/NE4RXZHsIGA==} + engines: {node: '>=10'} + + get-tsconfig@4.8.1: + resolution: {integrity: sha512-k9PN+cFBmaLWtVz29SkUoqU5O0slLuHJXt/2P+tMVFT+phsSGXGkp9t3rQIqdz0e+06EHNGs3oM6ZX1s2zHxRg==} + + glob-parent@5.1.2: + resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} + engines: {node: '>= 6'} + + glob@10.4.5: + resolution: {integrity: sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==} + hasBin: true + + gray-matter@4.0.3: + resolution: {integrity: sha512-5v6yZd4JK3eMI3FqqCouswVqwugaA9r4dNZB1wwcmrD02QkV5H0y7XBQW8QwQqEaZY1pM9aqORSORhJRdNK44Q==} + engines: {node: '>=6.0'} + + gzip-size@6.0.0: + resolution: {integrity: sha512-ax7ZYomf6jqPTQ4+XCpUGyXKHk5WweS+e05MBO4/y3WJ5RkmPXNKvX+bx1behVILVwr6JSQvZAku021CHPXG3Q==} + engines: {node: '>=10'} + + hast-util-to-html@9.0.3: + resolution: {integrity: sha512-M17uBDzMJ9RPCqLMO92gNNUDuBSq10a25SDBI08iCCxmorf4Yy6sYHK57n9WAbRAAaU+DuR4W6GN9K4DFZesYg==} + + hast-util-whitespace@3.0.0: + resolution: {integrity: sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==} + + hookable@5.5.3: + resolution: {integrity: sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ==} + + html-void-elements@3.0.0: + resolution: {integrity: sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==} + + importx@0.4.4: + resolution: {integrity: sha512-Lo1pukzAREqrBnnHC+tj+lreMTAvyxtkKsMxLY8H15M/bvLl54p3YuoTI70Tz7Il0AsgSlD7Lrk/FaApRcBL7w==} + + is-binary-path@2.1.0: + resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} + engines: {node: '>=8'} + + is-extendable@0.1.1: + resolution: {integrity: sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==} + engines: {node: '>=0.10.0'} + + is-extglob@2.1.1: + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} + engines: {node: '>=0.10.0'} + + is-fullwidth-code-point@3.0.0: + resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} + engines: {node: '>=8'} + + is-glob@4.0.3: + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} + engines: {node: '>=0.10.0'} + + is-number@7.0.0: + resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} + engines: {node: '>=0.12.0'} + + is-what@4.1.16: + resolution: {integrity: sha512-ZhMwEosbFJkA0YhFnNDgTM4ZxDRsS6HqTo7qsZM08fehyRYIYa0yHu5R6mgo1n/8MgaPBXiPimPD77baVFYg+A==} + engines: {node: '>=12.13'} + + isexe@2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + + jackspeak@3.4.3: + resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==} + + javascript-stringify@2.1.0: + resolution: {integrity: sha512-JVAfqNPTvNq3sB/VHQJAFxN/sPgKnsKrCwyRt15zwNCdrMMJDdcEOdubuy+DuJYYdm0ox1J4uzEuYKkN+9yhVg==} + + jiti@1.21.6: + resolution: {integrity: sha512-2yTgeWTWzMWkHu6Jp9NKgePDaYHbntiwvYuuJLbbN9vl7DC9DvXKOB2BC3ZZ92D3cvV/aflH0osDfwpHepQ53w==} + hasBin: true + + jiti@2.0.0-beta.3: + resolution: {integrity: sha512-pmfRbVRs/7khFrSAYnSiJ8C0D5GvzkE4Ey2pAvUcJsw1ly/p+7ut27jbJrjY79BpAJQJ4gXYFtK6d1Aub+9baQ==} + hasBin: true + + js-yaml@3.14.1: + resolution: {integrity: sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==} + hasBin: true + + kind-of@6.0.3: + resolution: {integrity: sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==} + engines: {node: '>=0.10.0'} + + kolorist@1.8.0: + resolution: {integrity: sha512-Y+60/zizpJ3HRH8DCss+q95yr6145JXZo46OTpFvDZWLfRCE4qChOyk1b26nMaNpfHHgxagk9dXT5OP0Tfe+dQ==} + + load-tsconfig@0.2.5: + resolution: {integrity: sha512-IXO6OCs9yg8tMKzfPZ1YmheJbZCiEsnBdcB03l0OcfK9prKnJb96siuHCr5Fl37/yo9DnKU+TLpxzTUspw9shg==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + local-pkg@0.5.1: + resolution: {integrity: sha512-9rrA30MRRP3gBD3HTGnC6cDFpaE1kVDWxWgqWJUN0RvDNAo+Nz/9GxB+nHOH0ifbVFy0hSA1V6vFDvnx54lTEQ==} + engines: {node: '>=14'} + + lru-cache@10.4.3: + resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} + + magic-string@0.30.13: + resolution: {integrity: sha512-8rYBO+MsWkgjDSOvLomYnzhdwEG51olQ4zL5KXnNJWV5MNmrb4rTZdrtkhxjnD/QyZUqR/Z/XDsUs/4ej2nx0g==} + + mark.js@8.11.1: + resolution: {integrity: sha512-1I+1qpDt4idfgLQG+BNWmrqku+7/2bi5nLf4YwF8y8zXvmfiTBY3PV3ZibfrjBueCByROpuBjLLFCajqkgYoLQ==} + + mdast-util-to-hast@13.2.0: + resolution: {integrity: sha512-QGYKEuUsYT9ykKBCMOEDLsU5JRObWQusAolFMeko/tYPufNkRffBAQjIE+99jbA87xv6FgmjLtwjh9wBWajwAA==} + + mdn-data@2.12.1: + resolution: {integrity: sha512-rsfnCbOHjqrhWxwt5/wtSLzpoKTzW7OXdT5lLOIH1OTYhWu9rRJveGq0sKvDZODABH7RX+uoR+DYcpFnq4Tf6Q==} + + micromark-util-character@2.1.1: + resolution: {integrity: sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==} + + micromark-util-encode@2.0.1: + resolution: {integrity: sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==} + + micromark-util-sanitize-uri@2.0.1: + resolution: {integrity: sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==} + + micromark-util-symbol@2.0.1: + resolution: {integrity: sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==} + + micromark-util-types@2.0.1: + resolution: {integrity: sha512-534m2WhVTddrcKVepwmVEVnUAmtrx9bfIjNoQHRqfnvdaHQiFytEhJoTgpWJvDEXCO5gLTQh3wYC1PgOJA4NSQ==} + + minimatch@9.0.5: + resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==} + engines: {node: '>=16 || 14 >=14.17'} + + minipass@7.1.2: + resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==} + engines: {node: '>=16 || 14 >=14.17'} + + minisearch@7.1.0: + resolution: {integrity: sha512-tv7c/uefWdEhcu6hvrfTihflgeEi2tN6VV7HJnCjK6VxM75QQJh4t9FwJCsA2EsRS8LCnu3W87CuGPWMocOLCA==} + + mitt@3.0.1: + resolution: {integrity: sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==} + + mlly@1.7.3: + resolution: {integrity: sha512-xUsx5n/mN0uQf4V548PKQ+YShA4/IW0KI1dZhrNrPCLG+xizETbHTkOa1f8/xut9JRPp8kQuMnz0oqwkTiLo/A==} + + mrmime@2.0.0: + resolution: {integrity: sha512-eu38+hdgojoyq63s+yTpN4XMBdt5l8HhMhc4VKLO9KM5caLIBvUm4thi7fFaxyTmCKeNnXZ5pAlBwCUnhA09uw==} + engines: {node: '>=10'} + + ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + + nanoid@3.3.7: + resolution: {integrity: sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + + nanoid@4.0.2: + resolution: {integrity: sha512-7ZtY5KTCNheRGfEFxnedV5zFiORN1+Y1N6zvPTnHQd8ENUvfaDBeuJDZb2bN/oXwXxu3qkTXDzy57W5vAmDTBw==} + engines: {node: ^14 || ^16 || >=18} + hasBin: true + + node-fetch-native@1.6.4: + resolution: {integrity: sha512-IhOigYzAKHd244OC0JIMIUrjzctirCmPkaIfhDeGcEETWof5zKYUW7e7MYvChGWh/4CJeXEgsRyGzuF334rOOQ==} + + normalize-path@3.0.0: + resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} + engines: {node: '>=0.10.0'} + + ofetch@1.4.1: + resolution: {integrity: sha512-QZj2DfGplQAr2oj9KzceK9Hwz6Whxazmn85yYeVuS3u9XTMOGMRx0kO95MQ+vLsj/S/NwBDMMLU5hpxvI6Tklw==} + + oniguruma-to-es@0.4.1: + resolution: {integrity: sha512-rNcEohFz095QKGRovP/yqPIKc+nP+Sjs4YTHMv33nMePGKrq/r2eu9Yh4646M5XluGJsUnmwoXuiXE69KDs+fQ==} + + package-json-from-dist@1.0.1: + resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==} + + package-manager-detector@0.2.4: + resolution: {integrity: sha512-H/OUu9/zUfP89z1APcBf2X8Us0tt8dUK4lUmKqz12QNXif3DxAs1/YqjGtcutZi1zQqeNQRWr9C+EbQnnvSSFA==} + + pagefind@1.2.0: + resolution: {integrity: sha512-sFVv5/x73qCp9KlLHv8/uWDv7rG1tsWcG9MuXc5YTrXIrb8c1Gshm9oc5rMLXNZILXUWai8WczqaK4jjroEzng==} + hasBin: true + + path-key@3.1.1: + resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} + engines: {node: '>=8'} + + path-scurry@1.11.1: + resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==} + engines: {node: '>=16 || 14 >=14.18'} + + pathe@1.1.2: + resolution: {integrity: sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==} + + perfect-debounce@1.0.0: + resolution: {integrity: sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA==} + + picocolors@1.1.1: + resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} + + picomatch@2.3.1: + resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} + engines: {node: '>=8.6'} + + picomatch@4.0.2: + resolution: {integrity: sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==} + engines: {node: '>=12'} + + pkg-types@1.2.1: + resolution: {integrity: sha512-sQoqa8alT3nHjGuTjuKgOnvjo4cljkufdtLMnO2LBP/wRwuDlo1tkaEdMxCRhyGRPacv/ztlZgDPm2b7FAmEvw==} + + postcss@8.4.49: + resolution: {integrity: sha512-OCVPnIObs4N29kxTjzLfUryOkvZEq+pf8jTF0lg8E7uETuWHA+v7j3c/xJmiqpX450191LlmZfUKkXxkTry7nA==} + engines: {node: ^10 || ^12 || >=14} + + preact@10.24.3: + resolution: {integrity: sha512-Z2dPnBnMUfyQfSQ+GBdsGa16hz35YmLmtTLhM169uW944hYL6xzTYkJjC07j+Wosz733pMWx0fgON3JNw1jJQA==} + + property-information@6.5.0: + resolution: {integrity: sha512-PgTgs/BlvHxOu8QuEN7wi5A0OmXaBcHpmCSTehcs6Uuu9IkDIEo13Hy7n898RHfrQ49vKCoGeWZSaAK01nwVig==} + + readdirp@3.6.0: + resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} + engines: {node: '>=8.10.0'} + + regex-recursion@4.2.1: + resolution: {integrity: sha512-QHNZyZAeKdndD1G3bKAbBEKOSSK4KOHQrAJ01N1LJeb0SoH4DJIeFhp0uUpETgONifS4+P3sOgoA1dhzgrQvhA==} + + regex-utilities@2.3.0: + resolution: {integrity: sha512-8VhliFJAWRaUiVvREIiW2NXXTmHs4vMNnSzuJVhscgmGav3g9VDxLrQndI3dZZVVdp0ZO/5v0xmX516/7M9cng==} + + regex@5.0.2: + resolution: {integrity: sha512-/pczGbKIQgfTMRV0XjABvc5RzLqQmwqxLHdQao2RTXPk+pmTXB2P0IaUHYdYyk412YLwUIkaeMd5T+RzVgTqnQ==} + + resolve-pkg-maps@1.0.0: + resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} + + rfdc@1.4.1: + resolution: {integrity: sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==} + + rollup@4.27.3: + resolution: {integrity: sha512-SLsCOnlmGt9VoZ9Ek8yBK8tAdmPHeppkw+Xa7yDlCEhDTvwYei03JlWo1fdc7YTfLZ4tD8riJCUyAgTbszk1fQ==} + engines: {node: '>=18.0.0', npm: '>=8.0.0'} + hasBin: true + + search-insights@2.17.3: + resolution: {integrity: sha512-RQPdCYTa8A68uM2jwxoY842xDhvx3E5LFL1LxvxCNMev4o5mLuokczhzjAgGwUZBAmOKZknArSxLKmXtIi2AxQ==} + + section-matter@1.0.0: + resolution: {integrity: sha512-vfD3pmTzGpufjScBh50YHKzEu2lxBWhVEHsNGoEXmCmn2hKGfeNLYMzCJpe8cD7gqX7TJluOVpBkAequ6dgMmA==} + engines: {node: '>=4'} + + shebang-command@2.0.0: + resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} + engines: {node: '>=8'} + + shebang-regex@3.0.0: + resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} + engines: {node: '>=8'} + + shiki@1.23.1: + resolution: {integrity: sha512-8kxV9TH4pXgdKGxNOkrSMydn1Xf6It8lsle0fiqxf7a1149K1WGtdOu3Zb91T5r1JpvRPxqxU3C2XdZZXQnrig==} + + signal-exit@4.1.0: + resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} + engines: {node: '>=14'} + + sirv@2.0.4: + resolution: {integrity: sha512-94Bdh3cC2PKrbgSOUqTiGPWVZeSiXfKOVZNJniWoqrWrRkB1CJzBU3NEbiTsPcYy1lDsANA/THzS+9WBiy5nfQ==} + engines: {node: '>= 10'} + + source-map-js@1.2.1: + resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} + engines: {node: '>=0.10.0'} + + space-separated-tokens@2.0.2: + resolution: {integrity: sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==} + + speakingurl@14.0.1: + resolution: {integrity: sha512-1POYv7uv2gXoyGFpBCmpDVSNV74IfsWlDW216UPjbWufNf+bSU6GdbDsxdcxtfwb4xlI3yxzOTKClUosxARYrQ==} + engines: {node: '>=0.10.0'} + + sprintf-js@1.0.3: + resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} + + string-width@4.2.3: + resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} + engines: {node: '>=8'} + + string-width@5.1.2: + resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} + engines: {node: '>=12'} + + stringify-entities@4.0.4: + resolution: {integrity: sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==} + + strip-ansi@6.0.1: + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} + engines: {node: '>=8'} + + strip-ansi@7.1.0: + resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==} + engines: {node: '>=12'} + + strip-bom-string@1.0.0: + resolution: {integrity: sha512-uCC2VHvQRYu+lMh4My/sFNmF2klFymLX1wHJeXnbEJERpV/ZsVuonzerjfrGpIGF7LBVa1O7i9kjiWvJiFck8g==} + engines: {node: '>=0.10.0'} + + superjson@2.2.1: + resolution: {integrity: sha512-8iGv75BYOa0xRJHK5vRLEjE2H/i4lulTjzpUXic3Eg8akftYjkmQDa8JARQ42rlczXyFR3IeRoeFCc7RxHsYZA==} + engines: {node: '>=16'} + + tabbable@6.2.0: + resolution: {integrity: sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew==} + + tinyexec@0.3.1: + resolution: {integrity: sha512-WiCJLEECkO18gwqIp6+hJg0//p23HXp4S+gGtAKu3mI2F2/sXC4FvHvXvB0zJVVaTPhx1/tOwdbRsa1sOBIKqQ==} + + tinyglobby@0.2.10: + resolution: {integrity: sha512-Zc+8eJlFMvgatPZTl6A9L/yht8QqdmUNtURHaKZLmKBE12hNPSrqNkUp2cs3M/UKmNVVAMFQYSjYIVHDjW5zew==} + engines: {node: '>=12.0.0'} + + to-regex-range@5.0.1: + resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} + engines: {node: '>=8.0'} + + totalist@3.0.1: + resolution: {integrity: sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==} + engines: {node: '>=6'} + + trim-lines@3.0.1: + resolution: {integrity: sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==} + + tsx@4.19.2: + resolution: {integrity: sha512-pOUl6Vo2LUq/bSa8S5q7b91cgNSjctn9ugq/+Mvow99qW6x/UZYwzxy/3NmqoT66eHYfCVvFvACC58UBPFf28g==} + engines: {node: '>=18.0.0'} + hasBin: true + + ufo@1.5.4: + resolution: {integrity: sha512-UsUk3byDzKd04EyoZ7U4DOlxQaD14JUKQl6/P7wiX4FNvUfm3XL246n9W5AmqwW5RSFJ27NAuM0iLscAOYUiGQ==} + + unconfig@0.5.5: + resolution: {integrity: sha512-VQZ5PT9HDX+qag0XdgQi8tJepPhXiR/yVOkn707gJDKo31lGjRilPREiQJ9Z6zd/Ugpv6ZvO5VxVIcatldYcNQ==} + + unist-util-is@6.0.0: + resolution: {integrity: sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==} + + unist-util-position@5.0.0: + resolution: {integrity: sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==} + + unist-util-stringify-position@4.0.0: + resolution: {integrity: sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==} + + unist-util-visit-parents@6.0.1: + resolution: {integrity: sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw==} + + unist-util-visit@5.0.0: + resolution: {integrity: sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==} + + unocss@0.64.1: + resolution: {integrity: sha512-UTtK9TPneVht5r0cVEADS/N6970AoHhKvJKDkBPnk7OQdguIFPCykGyx4llukItzm0AoffGfwg5zQ+L8QJgupw==} + engines: {node: '>=14'} + peerDependencies: + '@unocss/webpack': 0.64.1 + vite: ^2.9.0 || ^3.0.0-0 || ^4.0.0 || ^5.0.0-0 + peerDependenciesMeta: + '@unocss/webpack': + optional: true + vite: + optional: true + + vfile-message@4.0.2: + resolution: {integrity: sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw==} + + vfile@6.0.3: + resolution: {integrity: sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==} + + vite@5.4.11: + resolution: {integrity: sha512-c7jFQRklXua0mTzneGW9QVyxFjUgwcihC4bXEtujIo2ouWCe1Ajt/amn2PCxYnhYfd5k09JX3SB7OYWFKYqj8Q==} + engines: {node: ^18.0.0 || >=20.0.0} + hasBin: true + peerDependencies: + '@types/node': ^18.0.0 || >=20.0.0 + less: '*' + lightningcss: ^1.21.0 + sass: '*' + sass-embedded: '*' + stylus: '*' + sugarss: '*' + terser: ^5.4.0 + peerDependenciesMeta: + '@types/node': + optional: true + less: + optional: true + lightningcss: + optional: true + sass: + optional: true + sass-embedded: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + + vitepress-plugin-codeblocks-fold@1.2.28: + resolution: {integrity: sha512-ilckzzYmTIv3A9t4xiCSsTcYCfzCFzlsycV9nDtgvRTuk7Fy1lNHMZgPOk6ysB7PLFG/R71HsgQC44AZZKL8cw==} + + vitepress-plugin-pagefind@0.4.11: + resolution: {integrity: sha512-f9JdsIddaF71rDP+Y2A5e9FlnTSR1cdNhY1Cym8yA1lbIm/x+GaXjq7pQrY3g5szsa/s1zYODucXuHbZQ60kKQ==} + peerDependencies: + pagefind: ^1.1.0 + + vitepress-sidebar@1.29.0: + resolution: {integrity: sha512-DKsNYBtqKa9WWaGu+l5iuZjx7dXXmiTjhaK1tnOqsb5CXMySXVUwNSAnG/JhiNH55+UDvwzGxbCPLL+3XNmtog==} + engines: {node: '>=18.0.0'} + + vitepress@1.5.0: + resolution: {integrity: sha512-q4Q/G2zjvynvizdB3/bupdYkCJe2umSAMv9Ju4d92E6/NXJ59z70xB0q5p/4lpRyAwflDsbwy1mLV9Q5+nlB+g==} + hasBin: true + peerDependencies: + markdown-it-mathjax3: ^4 + postcss: ^8 + peerDependenciesMeta: + markdown-it-mathjax3: + optional: true + postcss: + optional: true + + vue-command-palette@0.1.4: + resolution: {integrity: sha512-v9wGV5RG/Qe/GLLP3dJGYEvBOHQAH1kTdfzv7/uDj4v51g9uB0J3dQSaREgsrAvAT7tSj/cSbVrGpaalr8z7tg==} + + vue-demi@0.14.10: + resolution: {integrity: sha512-nMZBOwuzabUO0nLgIcc6rycZEebF6eeUfaiQx9+WSk8e29IbLvPU9feI6tqW4kTo3hvoYAJkMh8n8D0fuISphg==} + engines: {node: '>=12'} + hasBin: true + peerDependencies: + '@vue/composition-api': ^1.0.0-rc.1 + vue: ^3.0.0-0 || ^2.6.0 + peerDependenciesMeta: + '@vue/composition-api': + optional: true + + vue-flow-layout@0.1.1: + resolution: {integrity: sha512-JdgRRUVrN0Y2GosA0M68DEbKlXMqJ7FQgsK8CjQD2vxvNSqAU6PZEpi4cfcTVtfM2GVOMjHo7GKKLbXxOBqDqA==} + peerDependencies: + vue: ^3.4.37 + + vue@3.5.13: + resolution: {integrity: sha512-wmeiSMxkZCSc+PM2w2VRsOYAZC8GdipNFRTsLSfodVqI9mbejKeXEGr8SckuLnrQPGe3oJN5c3K0vpoU9q/wCQ==} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + which@2.0.2: + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} + engines: {node: '>= 8'} + hasBin: true + + wrap-ansi@7.0.0: + resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} + engines: {node: '>=10'} + + wrap-ansi@8.1.0: + resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==} + engines: {node: '>=12'} + + zwitch@2.0.4: + resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==} + +snapshots: + + '@algolia/autocomplete-core@1.17.7(@algolia/client-search@5.15.0)(algoliasearch@5.15.0)(search-insights@2.17.3)': + dependencies: + '@algolia/autocomplete-plugin-algolia-insights': 1.17.7(@algolia/client-search@5.15.0)(algoliasearch@5.15.0)(search-insights@2.17.3) + '@algolia/autocomplete-shared': 1.17.7(@algolia/client-search@5.15.0)(algoliasearch@5.15.0) + transitivePeerDependencies: + - '@algolia/client-search' + - algoliasearch + - search-insights + + '@algolia/autocomplete-plugin-algolia-insights@1.17.7(@algolia/client-search@5.15.0)(algoliasearch@5.15.0)(search-insights@2.17.3)': + dependencies: + '@algolia/autocomplete-shared': 1.17.7(@algolia/client-search@5.15.0)(algoliasearch@5.15.0) + search-insights: 2.17.3 + transitivePeerDependencies: + - '@algolia/client-search' + - algoliasearch + + '@algolia/autocomplete-preset-algolia@1.17.7(@algolia/client-search@5.15.0)(algoliasearch@5.15.0)': + dependencies: + '@algolia/autocomplete-shared': 1.17.7(@algolia/client-search@5.15.0)(algoliasearch@5.15.0) + '@algolia/client-search': 5.15.0 + algoliasearch: 5.15.0 + + '@algolia/autocomplete-shared@1.17.7(@algolia/client-search@5.15.0)(algoliasearch@5.15.0)': + dependencies: + '@algolia/client-search': 5.15.0 + algoliasearch: 5.15.0 + + '@algolia/client-abtesting@5.15.0': + dependencies: + '@algolia/client-common': 5.15.0 + '@algolia/requester-browser-xhr': 5.15.0 + '@algolia/requester-fetch': 5.15.0 + '@algolia/requester-node-http': 5.15.0 + + '@algolia/client-analytics@5.15.0': + dependencies: + '@algolia/client-common': 5.15.0 + '@algolia/requester-browser-xhr': 5.15.0 + '@algolia/requester-fetch': 5.15.0 + '@algolia/requester-node-http': 5.15.0 + + '@algolia/client-common@5.15.0': {} + + '@algolia/client-insights@5.15.0': + dependencies: + '@algolia/client-common': 5.15.0 + '@algolia/requester-browser-xhr': 5.15.0 + '@algolia/requester-fetch': 5.15.0 + '@algolia/requester-node-http': 5.15.0 + + '@algolia/client-personalization@5.15.0': + dependencies: + '@algolia/client-common': 5.15.0 + '@algolia/requester-browser-xhr': 5.15.0 + '@algolia/requester-fetch': 5.15.0 + '@algolia/requester-node-http': 5.15.0 + + '@algolia/client-query-suggestions@5.15.0': + dependencies: + '@algolia/client-common': 5.15.0 + '@algolia/requester-browser-xhr': 5.15.0 + '@algolia/requester-fetch': 5.15.0 + '@algolia/requester-node-http': 5.15.0 + + '@algolia/client-search@5.15.0': + dependencies: + '@algolia/client-common': 5.15.0 + '@algolia/requester-browser-xhr': 5.15.0 + '@algolia/requester-fetch': 5.15.0 + '@algolia/requester-node-http': 5.15.0 + + '@algolia/ingestion@1.15.0': + dependencies: + '@algolia/client-common': 5.15.0 + '@algolia/requester-browser-xhr': 5.15.0 + '@algolia/requester-fetch': 5.15.0 + '@algolia/requester-node-http': 5.15.0 + + '@algolia/monitoring@1.15.0': + dependencies: + '@algolia/client-common': 5.15.0 + '@algolia/requester-browser-xhr': 5.15.0 + '@algolia/requester-fetch': 5.15.0 + '@algolia/requester-node-http': 5.15.0 + + '@algolia/recommend@5.15.0': + dependencies: + '@algolia/client-common': 5.15.0 + '@algolia/requester-browser-xhr': 5.15.0 + '@algolia/requester-fetch': 5.15.0 + '@algolia/requester-node-http': 5.15.0 + + '@algolia/requester-browser-xhr@5.15.0': + dependencies: + '@algolia/client-common': 5.15.0 + + '@algolia/requester-fetch@5.15.0': + dependencies: + '@algolia/client-common': 5.15.0 + + '@algolia/requester-node-http@5.15.0': + dependencies: + '@algolia/client-common': 5.15.0 + + '@ampproject/remapping@2.3.0': + dependencies: + '@jridgewell/gen-mapping': 0.3.5 + '@jridgewell/trace-mapping': 0.3.25 + + '@antfu/install-pkg@0.4.1': + dependencies: + package-manager-detector: 0.2.4 + tinyexec: 0.3.1 + + '@antfu/utils@0.7.10': {} + + '@babel/helper-string-parser@7.25.9': {} + + '@babel/helper-validator-identifier@7.25.9': {} + + '@babel/parser@7.26.2': + dependencies: + '@babel/types': 7.26.0 + + '@babel/types@7.26.0': + dependencies: + '@babel/helper-string-parser': 7.25.9 + '@babel/helper-validator-identifier': 7.25.9 + + '@docsearch/css@3.8.0': {} + + '@docsearch/js@3.8.0(@algolia/client-search@5.15.0)(search-insights@2.17.3)': + dependencies: + '@docsearch/react': 3.8.0(@algolia/client-search@5.15.0)(search-insights@2.17.3) + preact: 10.24.3 + transitivePeerDependencies: + - '@algolia/client-search' + - '@types/react' + - react + - react-dom + - search-insights + + '@docsearch/react@3.8.0(@algolia/client-search@5.15.0)(search-insights@2.17.3)': + dependencies: + '@algolia/autocomplete-core': 1.17.7(@algolia/client-search@5.15.0)(algoliasearch@5.15.0)(search-insights@2.17.3) + '@algolia/autocomplete-preset-algolia': 1.17.7(@algolia/client-search@5.15.0)(algoliasearch@5.15.0) + '@docsearch/css': 3.8.0 + algoliasearch: 5.15.0 + optionalDependencies: + search-insights: 2.17.3 + transitivePeerDependencies: + - '@algolia/client-search' + + '@esbuild/aix-ppc64@0.21.5': + optional: true + + '@esbuild/aix-ppc64@0.23.1': + optional: true + + '@esbuild/android-arm64@0.21.5': + optional: true + + '@esbuild/android-arm64@0.23.1': + optional: true + + '@esbuild/android-arm@0.21.5': + optional: true + + '@esbuild/android-arm@0.23.1': + optional: true + + '@esbuild/android-x64@0.21.5': + optional: true + + '@esbuild/android-x64@0.23.1': + optional: true + + '@esbuild/darwin-arm64@0.21.5': + optional: true + + '@esbuild/darwin-arm64@0.23.1': + optional: true + + '@esbuild/darwin-x64@0.21.5': + optional: true + + '@esbuild/darwin-x64@0.23.1': + optional: true + + '@esbuild/freebsd-arm64@0.21.5': + optional: true + + '@esbuild/freebsd-arm64@0.23.1': + optional: true + + '@esbuild/freebsd-x64@0.21.5': + optional: true + + '@esbuild/freebsd-x64@0.23.1': + optional: true + + '@esbuild/linux-arm64@0.21.5': + optional: true + + '@esbuild/linux-arm64@0.23.1': + optional: true + + '@esbuild/linux-arm@0.21.5': + optional: true + + '@esbuild/linux-arm@0.23.1': + optional: true + + '@esbuild/linux-ia32@0.21.5': + optional: true + + '@esbuild/linux-ia32@0.23.1': + optional: true + + '@esbuild/linux-loong64@0.21.5': + optional: true + + '@esbuild/linux-loong64@0.23.1': + optional: true + + '@esbuild/linux-mips64el@0.21.5': + optional: true + + '@esbuild/linux-mips64el@0.23.1': + optional: true + + '@esbuild/linux-ppc64@0.21.5': + optional: true + + '@esbuild/linux-ppc64@0.23.1': + optional: true + + '@esbuild/linux-riscv64@0.21.5': + optional: true + + '@esbuild/linux-riscv64@0.23.1': + optional: true + + '@esbuild/linux-s390x@0.21.5': + optional: true + + '@esbuild/linux-s390x@0.23.1': + optional: true + + '@esbuild/linux-x64@0.21.5': + optional: true + + '@esbuild/linux-x64@0.23.1': + optional: true + + '@esbuild/netbsd-x64@0.21.5': + optional: true + + '@esbuild/netbsd-x64@0.23.1': + optional: true + + '@esbuild/openbsd-arm64@0.23.1': + optional: true + + '@esbuild/openbsd-x64@0.21.5': + optional: true + + '@esbuild/openbsd-x64@0.23.1': + optional: true + + '@esbuild/sunos-x64@0.21.5': + optional: true + + '@esbuild/sunos-x64@0.23.1': + optional: true + + '@esbuild/win32-arm64@0.21.5': + optional: true + + '@esbuild/win32-arm64@0.23.1': + optional: true + + '@esbuild/win32-ia32@0.21.5': + optional: true + + '@esbuild/win32-ia32@0.23.1': + optional: true + + '@esbuild/win32-x64@0.21.5': + optional: true + + '@esbuild/win32-x64@0.23.1': + optional: true + + '@iconify-json/gg@1.2.1': + dependencies: + '@iconify/types': 2.0.0 + + '@iconify-json/ic@1.2.1': + dependencies: + '@iconify/types': 2.0.0 + + '@iconify-json/logos@1.2.3': + dependencies: + '@iconify/types': 2.0.0 + + '@iconify-json/material-symbols@1.2.7': + dependencies: + '@iconify/types': 2.0.0 + + '@iconify-json/mdi@1.2.1': + dependencies: + '@iconify/types': 2.0.0 + + '@iconify-json/mingcute@1.2.1': + dependencies: + '@iconify/types': 2.0.0 + + '@iconify-json/octicon@1.2.1': + dependencies: + '@iconify/types': 2.0.0 + + '@iconify-json/simple-icons@1.2.12': + dependencies: + '@iconify/types': 2.0.0 + + '@iconify-json/twemoji@1.2.1': + dependencies: + '@iconify/types': 2.0.0 + + '@iconify/types@2.0.0': {} + + '@iconify/utils@2.1.33': + dependencies: + '@antfu/install-pkg': 0.4.1 + '@antfu/utils': 0.7.10 + '@iconify/types': 2.0.0 + debug: 4.3.7 + kolorist: 1.8.0 + local-pkg: 0.5.1 + mlly: 1.7.3 + transitivePeerDependencies: + - supports-color + + '@isaacs/cliui@8.0.2': + dependencies: + string-width: 5.1.2 + string-width-cjs: string-width@4.2.3 + strip-ansi: 7.1.0 + strip-ansi-cjs: strip-ansi@6.0.1 + wrap-ansi: 8.1.0 + wrap-ansi-cjs: wrap-ansi@7.0.0 + + '@jridgewell/gen-mapping@0.3.5': + dependencies: + '@jridgewell/set-array': 1.2.1 + '@jridgewell/sourcemap-codec': 1.5.0 + '@jridgewell/trace-mapping': 0.3.25 + + '@jridgewell/resolve-uri@3.1.2': {} + + '@jridgewell/set-array@1.2.1': {} + + '@jridgewell/sourcemap-codec@1.5.0': {} + + '@jridgewell/trace-mapping@0.3.25': + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.5.0 + + '@pagefind/darwin-arm64@1.2.0': + optional: true + + '@pagefind/darwin-x64@1.2.0': + optional: true + + '@pagefind/linux-arm64@1.2.0': + optional: true + + '@pagefind/linux-x64@1.2.0': + optional: true + + '@pagefind/windows-x64@1.2.0': + optional: true + + '@pkgjs/parseargs@0.11.0': + optional: true + + '@polka/url@1.0.0-next.28': {} + + '@rollup/pluginutils@5.1.3(rollup@4.27.3)': + dependencies: + '@types/estree': 1.0.6 + estree-walker: 2.0.2 + picomatch: 4.0.2 + optionalDependencies: + rollup: 4.27.3 + + '@rollup/rollup-android-arm-eabi@4.27.3': + optional: true + + '@rollup/rollup-android-arm64@4.27.3': + optional: true + + '@rollup/rollup-darwin-arm64@4.27.3': + optional: true + + '@rollup/rollup-darwin-x64@4.27.3': + optional: true + + '@rollup/rollup-freebsd-arm64@4.27.3': + optional: true + + '@rollup/rollup-freebsd-x64@4.27.3': + optional: true + + '@rollup/rollup-linux-arm-gnueabihf@4.27.3': + optional: true + + '@rollup/rollup-linux-arm-musleabihf@4.27.3': + optional: true + + '@rollup/rollup-linux-arm64-gnu@4.27.3': + optional: true + + '@rollup/rollup-linux-arm64-musl@4.27.3': + optional: true + + '@rollup/rollup-linux-powerpc64le-gnu@4.27.3': + optional: true + + '@rollup/rollup-linux-riscv64-gnu@4.27.3': + optional: true + + '@rollup/rollup-linux-s390x-gnu@4.27.3': + optional: true + + '@rollup/rollup-linux-x64-gnu@4.27.3': + optional: true + + '@rollup/rollup-linux-x64-musl@4.27.3': + optional: true + + '@rollup/rollup-win32-arm64-msvc@4.27.3': + optional: true + + '@rollup/rollup-win32-ia32-msvc@4.27.3': + optional: true + + '@rollup/rollup-win32-x64-msvc@4.27.3': + optional: true + + '@shikijs/core@1.23.1': + dependencies: + '@shikijs/engine-javascript': 1.23.1 + '@shikijs/engine-oniguruma': 1.23.1 + '@shikijs/types': 1.23.1 + '@shikijs/vscode-textmate': 9.3.0 + '@types/hast': 3.0.4 + hast-util-to-html: 9.0.3 + + '@shikijs/engine-javascript@1.23.1': + dependencies: + '@shikijs/types': 1.23.1 + '@shikijs/vscode-textmate': 9.3.0 + oniguruma-to-es: 0.4.1 + + '@shikijs/engine-oniguruma@1.23.1': + dependencies: + '@shikijs/types': 1.23.1 + '@shikijs/vscode-textmate': 9.3.0 + + '@shikijs/transformers@1.23.1': + dependencies: + shiki: 1.23.1 + + '@shikijs/types@1.23.1': + dependencies: + '@shikijs/vscode-textmate': 9.3.0 + '@types/hast': 3.0.4 + + '@shikijs/vscode-textmate@9.3.0': {} + + '@sugarat/theme-shared@0.0.3': + dependencies: + cross-spawn: 7.0.6 + gray-matter: 4.0.3 + + '@types/estree@1.0.6': {} + + '@types/hast@3.0.4': + dependencies: + '@types/unist': 3.0.3 + + '@types/linkify-it@5.0.0': {} + + '@types/markdown-it@14.1.2': + dependencies: + '@types/linkify-it': 5.0.0 + '@types/mdurl': 2.0.0 + + '@types/mdast@4.0.4': + dependencies: + '@types/unist': 3.0.3 + + '@types/mdurl@2.0.0': {} + + '@types/unist@3.0.3': {} + + '@types/web-bluetooth@0.0.16': {} + + '@types/web-bluetooth@0.0.20': {} + + '@ungap/structured-clone@1.2.0': {} + + '@unocss/astro@0.64.1(rollup@4.27.3)(vite@5.4.11)(vue@3.5.13)': + dependencies: + '@unocss/core': 0.64.1 + '@unocss/reset': 0.64.1 + '@unocss/vite': 0.64.1(rollup@4.27.3)(vite@5.4.11)(vue@3.5.13) + optionalDependencies: + vite: 5.4.11 + transitivePeerDependencies: + - rollup + - supports-color + - vue + + '@unocss/cli@0.64.1(rollup@4.27.3)': + dependencies: + '@ampproject/remapping': 2.3.0 + '@rollup/pluginutils': 5.1.3(rollup@4.27.3) + '@unocss/config': 0.64.1 + '@unocss/core': 0.64.1 + '@unocss/preset-uno': 0.64.1 + cac: 6.7.14 + chokidar: 3.6.0 + colorette: 2.0.20 + consola: 3.2.3 + magic-string: 0.30.13 + pathe: 1.1.2 + perfect-debounce: 1.0.0 + tinyglobby: 0.2.10 + transitivePeerDependencies: + - rollup + - supports-color + + '@unocss/config@0.64.1': + dependencies: + '@unocss/core': 0.64.1 + unconfig: 0.5.5 + transitivePeerDependencies: + - supports-color + + '@unocss/core@0.64.1': {} + + '@unocss/extractor-arbitrary-variants@0.64.1': + dependencies: + '@unocss/core': 0.64.1 + + '@unocss/inspector@0.64.1(vue@3.5.13)': + dependencies: + '@unocss/core': 0.64.1 + '@unocss/rule-utils': 0.64.1 + gzip-size: 6.0.0 + sirv: 2.0.4 + vue-flow-layout: 0.1.1(vue@3.5.13) + transitivePeerDependencies: + - vue + + '@unocss/postcss@0.64.1(postcss@8.4.49)': + dependencies: + '@unocss/config': 0.64.1 + '@unocss/core': 0.64.1 + '@unocss/rule-utils': 0.64.1 + css-tree: 3.0.1 + postcss: 8.4.49 + tinyglobby: 0.2.10 + transitivePeerDependencies: + - supports-color + + '@unocss/preset-attributify@0.64.1': + dependencies: + '@unocss/core': 0.64.1 + + '@unocss/preset-icons@0.64.1': + dependencies: + '@iconify/utils': 2.1.33 + '@unocss/core': 0.64.1 + ofetch: 1.4.1 + transitivePeerDependencies: + - supports-color + + '@unocss/preset-mini@0.64.1': + dependencies: + '@unocss/core': 0.64.1 + '@unocss/extractor-arbitrary-variants': 0.64.1 + '@unocss/rule-utils': 0.64.1 + + '@unocss/preset-tagify@0.64.1': + dependencies: + '@unocss/core': 0.64.1 + + '@unocss/preset-typography@0.64.1': + dependencies: + '@unocss/core': 0.64.1 + '@unocss/preset-mini': 0.64.1 + + '@unocss/preset-uno@0.64.1': + dependencies: + '@unocss/core': 0.64.1 + '@unocss/preset-mini': 0.64.1 + '@unocss/preset-wind': 0.64.1 + '@unocss/rule-utils': 0.64.1 + + '@unocss/preset-web-fonts@0.64.1': + dependencies: + '@unocss/core': 0.64.1 + ofetch: 1.4.1 + + '@unocss/preset-wind@0.64.1': + dependencies: + '@unocss/core': 0.64.1 + '@unocss/preset-mini': 0.64.1 + '@unocss/rule-utils': 0.64.1 + + '@unocss/reset@0.64.1': {} + + '@unocss/rule-utils@0.64.1': + dependencies: + '@unocss/core': 0.64.1 + magic-string: 0.30.13 + + '@unocss/transformer-attributify-jsx@0.64.1': + dependencies: + '@unocss/core': 0.64.1 + + '@unocss/transformer-compile-class@0.64.1': + dependencies: + '@unocss/core': 0.64.1 + + '@unocss/transformer-directives@0.64.1': + dependencies: + '@unocss/core': 0.64.1 + '@unocss/rule-utils': 0.64.1 + css-tree: 3.0.1 + + '@unocss/transformer-variant-group@0.64.1': + dependencies: + '@unocss/core': 0.64.1 + + '@unocss/vite@0.64.1(rollup@4.27.3)(vite@5.4.11)(vue@3.5.13)': + dependencies: + '@ampproject/remapping': 2.3.0 + '@rollup/pluginutils': 5.1.3(rollup@4.27.3) + '@unocss/config': 0.64.1 + '@unocss/core': 0.64.1 + '@unocss/inspector': 0.64.1(vue@3.5.13) + chokidar: 3.6.0 + magic-string: 0.30.13 + tinyglobby: 0.2.10 + vite: 5.4.11 + transitivePeerDependencies: + - rollup + - supports-color + - vue + + '@vitejs/plugin-vue@5.2.0(vite@5.4.11)(vue@3.5.13)': + dependencies: + vite: 5.4.11 + vue: 3.5.13 + + '@vue/compiler-core@3.5.13': + dependencies: + '@babel/parser': 7.26.2 + '@vue/shared': 3.5.13 + entities: 4.5.0 + estree-walker: 2.0.2 + source-map-js: 1.2.1 + + '@vue/compiler-dom@3.5.13': + dependencies: + '@vue/compiler-core': 3.5.13 + '@vue/shared': 3.5.13 + + '@vue/compiler-sfc@3.5.13': + dependencies: + '@babel/parser': 7.26.2 + '@vue/compiler-core': 3.5.13 + '@vue/compiler-dom': 3.5.13 + '@vue/compiler-ssr': 3.5.13 + '@vue/shared': 3.5.13 + estree-walker: 2.0.2 + magic-string: 0.30.13 + postcss: 8.4.49 + source-map-js: 1.2.1 + + '@vue/compiler-ssr@3.5.13': + dependencies: + '@vue/compiler-dom': 3.5.13 + '@vue/shared': 3.5.13 + + '@vue/devtools-api@7.6.4': + dependencies: + '@vue/devtools-kit': 7.6.4 + + '@vue/devtools-kit@7.6.4': + dependencies: + '@vue/devtools-shared': 7.6.4 + birpc: 0.2.19 + hookable: 5.5.3 + mitt: 3.0.1 + perfect-debounce: 1.0.0 + speakingurl: 14.0.1 + superjson: 2.2.1 + + '@vue/devtools-shared@7.6.4': + dependencies: + rfdc: 1.4.1 + + '@vue/reactivity@3.5.13': + dependencies: + '@vue/shared': 3.5.13 + + '@vue/runtime-core@3.5.13': + dependencies: + '@vue/reactivity': 3.5.13 + '@vue/shared': 3.5.13 + + '@vue/runtime-dom@3.5.13': + dependencies: + '@vue/reactivity': 3.5.13 + '@vue/runtime-core': 3.5.13 + '@vue/shared': 3.5.13 + csstype: 3.1.3 + + '@vue/server-renderer@3.5.13(vue@3.5.13)': + dependencies: + '@vue/compiler-ssr': 3.5.13 + '@vue/shared': 3.5.13 + vue: 3.5.13 + + '@vue/shared@3.5.13': {} + + '@vueuse/core@11.2.0(vue@3.5.13)': + dependencies: + '@types/web-bluetooth': 0.0.20 + '@vueuse/metadata': 11.2.0 + '@vueuse/shared': 11.2.0(vue@3.5.13) + vue-demi: 0.14.10(vue@3.5.13) + transitivePeerDependencies: + - '@vue/composition-api' + - vue + + '@vueuse/core@9.13.0(vue@3.5.13)': + dependencies: + '@types/web-bluetooth': 0.0.16 + '@vueuse/metadata': 9.13.0 + '@vueuse/shared': 9.13.0(vue@3.5.13) + vue-demi: 0.14.10(vue@3.5.13) + transitivePeerDependencies: + - '@vue/composition-api' + - vue + + '@vueuse/integrations@11.2.0(focus-trap@7.6.2)(vue@3.5.13)': + dependencies: + '@vueuse/core': 11.2.0(vue@3.5.13) + '@vueuse/shared': 11.2.0(vue@3.5.13) + vue-demi: 0.14.10(vue@3.5.13) + optionalDependencies: + focus-trap: 7.6.2 + transitivePeerDependencies: + - '@vue/composition-api' + - vue + + '@vueuse/metadata@11.2.0': {} + + '@vueuse/metadata@9.13.0': {} + + '@vueuse/shared@11.2.0(vue@3.5.13)': + dependencies: + vue-demi: 0.14.10(vue@3.5.13) + transitivePeerDependencies: + - '@vue/composition-api' + - vue + + '@vueuse/shared@9.13.0(vue@3.5.13)': + dependencies: + vue-demi: 0.14.10(vue@3.5.13) + transitivePeerDependencies: + - '@vue/composition-api' + - vue + + acorn@8.14.0: {} + + algoliasearch@5.15.0: + dependencies: + '@algolia/client-abtesting': 5.15.0 + '@algolia/client-analytics': 5.15.0 + '@algolia/client-common': 5.15.0 + '@algolia/client-insights': 5.15.0 + '@algolia/client-personalization': 5.15.0 + '@algolia/client-query-suggestions': 5.15.0 + '@algolia/client-search': 5.15.0 + '@algolia/ingestion': 1.15.0 + '@algolia/monitoring': 1.15.0 + '@algolia/recommend': 5.15.0 + '@algolia/requester-browser-xhr': 5.15.0 + '@algolia/requester-fetch': 5.15.0 + '@algolia/requester-node-http': 5.15.0 + + ansi-regex@5.0.1: {} + + ansi-regex@6.1.0: {} + + ansi-styles@4.3.0: + dependencies: + color-convert: 2.0.1 + + ansi-styles@6.2.1: {} + + anymatch@3.1.3: + dependencies: + normalize-path: 3.0.0 + picomatch: 2.3.1 + + argparse@1.0.10: + dependencies: + sprintf-js: 1.0.3 + + balanced-match@1.0.2: {} + + binary-extensions@2.3.0: {} + + birpc@0.2.19: {} + + brace-expansion@2.0.1: + dependencies: + balanced-match: 1.0.2 + + braces@3.0.3: + dependencies: + fill-range: 7.1.1 + + bundle-require@5.0.0(esbuild@0.23.1): + dependencies: + esbuild: 0.23.1 + load-tsconfig: 0.2.5 + + cac@6.7.14: {} + + ccount@2.0.1: {} + + character-entities-html4@2.1.0: {} + + character-entities-legacy@3.0.0: {} + + chokidar@3.6.0: + dependencies: + anymatch: 3.1.3 + braces: 3.0.3 + glob-parent: 5.1.2 + is-binary-path: 2.1.0 + is-glob: 4.0.3 + normalize-path: 3.0.0 + readdirp: 3.6.0 + optionalDependencies: + fsevents: 2.3.3 + + color-convert@2.0.1: + dependencies: + color-name: 1.1.4 + + color-name@1.1.4: {} + + colorette@2.0.20: {} + + comma-separated-tokens@2.0.3: {} + + confbox@0.1.8: {} + + consola@3.2.3: {} + + copy-anything@3.0.5: + dependencies: + is-what: 4.1.16 + + cross-spawn@7.0.6: + dependencies: + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 + + css-tree@3.0.1: + dependencies: + mdn-data: 2.12.1 + source-map-js: 1.2.1 + + csstype@3.1.3: {} + + debug@4.3.7: + dependencies: + ms: 2.1.3 + + defu@6.1.4: {} + + dequal@2.0.3: {} + + destr@2.0.3: {} + + devlop@1.1.0: + dependencies: + dequal: 2.0.3 + + duplexer@0.1.2: {} + + eastasianwidth@0.2.0: {} + + emoji-regex-xs@1.0.0: {} + + emoji-regex@8.0.0: {} + + emoji-regex@9.2.2: {} + + entities@4.5.0: {} + + esbuild@0.21.5: + optionalDependencies: + '@esbuild/aix-ppc64': 0.21.5 + '@esbuild/android-arm': 0.21.5 + '@esbuild/android-arm64': 0.21.5 + '@esbuild/android-x64': 0.21.5 + '@esbuild/darwin-arm64': 0.21.5 + '@esbuild/darwin-x64': 0.21.5 + '@esbuild/freebsd-arm64': 0.21.5 + '@esbuild/freebsd-x64': 0.21.5 + '@esbuild/linux-arm': 0.21.5 + '@esbuild/linux-arm64': 0.21.5 + '@esbuild/linux-ia32': 0.21.5 + '@esbuild/linux-loong64': 0.21.5 + '@esbuild/linux-mips64el': 0.21.5 + '@esbuild/linux-ppc64': 0.21.5 + '@esbuild/linux-riscv64': 0.21.5 + '@esbuild/linux-s390x': 0.21.5 + '@esbuild/linux-x64': 0.21.5 + '@esbuild/netbsd-x64': 0.21.5 + '@esbuild/openbsd-x64': 0.21.5 + '@esbuild/sunos-x64': 0.21.5 + '@esbuild/win32-arm64': 0.21.5 + '@esbuild/win32-ia32': 0.21.5 + '@esbuild/win32-x64': 0.21.5 + + esbuild@0.23.1: + optionalDependencies: + '@esbuild/aix-ppc64': 0.23.1 + '@esbuild/android-arm': 0.23.1 + '@esbuild/android-arm64': 0.23.1 + '@esbuild/android-x64': 0.23.1 + '@esbuild/darwin-arm64': 0.23.1 + '@esbuild/darwin-x64': 0.23.1 + '@esbuild/freebsd-arm64': 0.23.1 + '@esbuild/freebsd-x64': 0.23.1 + '@esbuild/linux-arm': 0.23.1 + '@esbuild/linux-arm64': 0.23.1 + '@esbuild/linux-ia32': 0.23.1 + '@esbuild/linux-loong64': 0.23.1 + '@esbuild/linux-mips64el': 0.23.1 + '@esbuild/linux-ppc64': 0.23.1 + '@esbuild/linux-riscv64': 0.23.1 + '@esbuild/linux-s390x': 0.23.1 + '@esbuild/linux-x64': 0.23.1 + '@esbuild/netbsd-x64': 0.23.1 + '@esbuild/openbsd-arm64': 0.23.1 + '@esbuild/openbsd-x64': 0.23.1 + '@esbuild/sunos-x64': 0.23.1 + '@esbuild/win32-arm64': 0.23.1 + '@esbuild/win32-ia32': 0.23.1 + '@esbuild/win32-x64': 0.23.1 + + esprima@4.0.1: {} + + estree-walker@2.0.2: {} + + extend-shallow@2.0.1: + dependencies: + is-extendable: 0.1.1 + + fdir@6.4.2(picomatch@4.0.2): + optionalDependencies: + picomatch: 4.0.2 + + fill-range@7.1.1: + dependencies: + to-regex-range: 5.0.1 + + focus-trap@7.6.2: + dependencies: + tabbable: 6.2.0 + + foreground-child@3.3.0: + dependencies: + cross-spawn: 7.0.6 + signal-exit: 4.1.0 + + fsevents@2.3.3: + optional: true + + fuse.js@6.6.2: {} + + get-tsconfig@4.8.1: + dependencies: + resolve-pkg-maps: 1.0.0 + + glob-parent@5.1.2: + dependencies: + is-glob: 4.0.3 + + glob@10.4.5: + dependencies: + foreground-child: 3.3.0 + jackspeak: 3.4.3 + minimatch: 9.0.5 + minipass: 7.1.2 + package-json-from-dist: 1.0.1 + path-scurry: 1.11.1 + + gray-matter@4.0.3: + dependencies: + js-yaml: 3.14.1 + kind-of: 6.0.3 + section-matter: 1.0.0 + strip-bom-string: 1.0.0 + + gzip-size@6.0.0: + dependencies: + duplexer: 0.1.2 + + hast-util-to-html@9.0.3: + dependencies: + '@types/hast': 3.0.4 + '@types/unist': 3.0.3 + ccount: 2.0.1 + comma-separated-tokens: 2.0.3 + hast-util-whitespace: 3.0.0 + html-void-elements: 3.0.0 + mdast-util-to-hast: 13.2.0 + property-information: 6.5.0 + space-separated-tokens: 2.0.2 + stringify-entities: 4.0.4 + zwitch: 2.0.4 + + hast-util-whitespace@3.0.0: + dependencies: + '@types/hast': 3.0.4 + + hookable@5.5.3: {} + + html-void-elements@3.0.0: {} + + importx@0.4.4: + dependencies: + bundle-require: 5.0.0(esbuild@0.23.1) + debug: 4.3.7 + esbuild: 0.23.1 + jiti: 2.0.0-beta.3 + jiti-v1: jiti@1.21.6 + pathe: 1.1.2 + tsx: 4.19.2 + transitivePeerDependencies: + - supports-color + + is-binary-path@2.1.0: + dependencies: + binary-extensions: 2.3.0 + + is-extendable@0.1.1: {} + + is-extglob@2.1.1: {} + + is-fullwidth-code-point@3.0.0: {} + + is-glob@4.0.3: + dependencies: + is-extglob: 2.1.1 + + is-number@7.0.0: {} + + is-what@4.1.16: {} + + isexe@2.0.0: {} + + jackspeak@3.4.3: + dependencies: + '@isaacs/cliui': 8.0.2 + optionalDependencies: + '@pkgjs/parseargs': 0.11.0 + + javascript-stringify@2.1.0: {} + + jiti@1.21.6: {} + + jiti@2.0.0-beta.3: {} + + js-yaml@3.14.1: + dependencies: + argparse: 1.0.10 + esprima: 4.0.1 + + kind-of@6.0.3: {} + + kolorist@1.8.0: {} + + load-tsconfig@0.2.5: {} + + local-pkg@0.5.1: + dependencies: + mlly: 1.7.3 + pkg-types: 1.2.1 + + lru-cache@10.4.3: {} + + magic-string@0.30.13: + dependencies: + '@jridgewell/sourcemap-codec': 1.5.0 + + mark.js@8.11.1: {} + + mdast-util-to-hast@13.2.0: + dependencies: + '@types/hast': 3.0.4 + '@types/mdast': 4.0.4 + '@ungap/structured-clone': 1.2.0 + devlop: 1.1.0 + micromark-util-sanitize-uri: 2.0.1 + trim-lines: 3.0.1 + unist-util-position: 5.0.0 + unist-util-visit: 5.0.0 + vfile: 6.0.3 + + mdn-data@2.12.1: {} + + micromark-util-character@2.1.1: + dependencies: + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.1 + + micromark-util-encode@2.0.1: {} + + micromark-util-sanitize-uri@2.0.1: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-encode: 2.0.1 + micromark-util-symbol: 2.0.1 + + micromark-util-symbol@2.0.1: {} + + micromark-util-types@2.0.1: {} + + minimatch@9.0.5: + dependencies: + brace-expansion: 2.0.1 + + minipass@7.1.2: {} + + minisearch@7.1.0: {} + + mitt@3.0.1: {} + + mlly@1.7.3: + dependencies: + acorn: 8.14.0 + pathe: 1.1.2 + pkg-types: 1.2.1 + ufo: 1.5.4 + + mrmime@2.0.0: {} + + ms@2.1.3: {} + + nanoid@3.3.7: {} + + nanoid@4.0.2: {} + + node-fetch-native@1.6.4: {} + + normalize-path@3.0.0: {} + + ofetch@1.4.1: + dependencies: + destr: 2.0.3 + node-fetch-native: 1.6.4 + ufo: 1.5.4 + + oniguruma-to-es@0.4.1: + dependencies: + emoji-regex-xs: 1.0.0 + regex: 5.0.2 + regex-recursion: 4.2.1 + + package-json-from-dist@1.0.1: {} + + package-manager-detector@0.2.4: {} + + pagefind@1.2.0: + optionalDependencies: + '@pagefind/darwin-arm64': 1.2.0 + '@pagefind/darwin-x64': 1.2.0 + '@pagefind/linux-arm64': 1.2.0 + '@pagefind/linux-x64': 1.2.0 + '@pagefind/windows-x64': 1.2.0 + + path-key@3.1.1: {} + + path-scurry@1.11.1: + dependencies: + lru-cache: 10.4.3 + minipass: 7.1.2 + + pathe@1.1.2: {} + + perfect-debounce@1.0.0: {} + + picocolors@1.1.1: {} + + picomatch@2.3.1: {} + + picomatch@4.0.2: {} + + pkg-types@1.2.1: + dependencies: + confbox: 0.1.8 + mlly: 1.7.3 + pathe: 1.1.2 + + postcss@8.4.49: + dependencies: + nanoid: 3.3.7 + picocolors: 1.1.1 + source-map-js: 1.2.1 + + preact@10.24.3: {} + + property-information@6.5.0: {} + + readdirp@3.6.0: + dependencies: + picomatch: 2.3.1 + + regex-recursion@4.2.1: + dependencies: + regex-utilities: 2.3.0 + + regex-utilities@2.3.0: {} + + regex@5.0.2: + dependencies: + regex-utilities: 2.3.0 + + resolve-pkg-maps@1.0.0: {} + + rfdc@1.4.1: {} + + rollup@4.27.3: + dependencies: + '@types/estree': 1.0.6 + optionalDependencies: + '@rollup/rollup-android-arm-eabi': 4.27.3 + '@rollup/rollup-android-arm64': 4.27.3 + '@rollup/rollup-darwin-arm64': 4.27.3 + '@rollup/rollup-darwin-x64': 4.27.3 + '@rollup/rollup-freebsd-arm64': 4.27.3 + '@rollup/rollup-freebsd-x64': 4.27.3 + '@rollup/rollup-linux-arm-gnueabihf': 4.27.3 + '@rollup/rollup-linux-arm-musleabihf': 4.27.3 + '@rollup/rollup-linux-arm64-gnu': 4.27.3 + '@rollup/rollup-linux-arm64-musl': 4.27.3 + '@rollup/rollup-linux-powerpc64le-gnu': 4.27.3 + '@rollup/rollup-linux-riscv64-gnu': 4.27.3 + '@rollup/rollup-linux-s390x-gnu': 4.27.3 + '@rollup/rollup-linux-x64-gnu': 4.27.3 + '@rollup/rollup-linux-x64-musl': 4.27.3 + '@rollup/rollup-win32-arm64-msvc': 4.27.3 + '@rollup/rollup-win32-ia32-msvc': 4.27.3 + '@rollup/rollup-win32-x64-msvc': 4.27.3 + fsevents: 2.3.3 + + search-insights@2.17.3: {} + + section-matter@1.0.0: + dependencies: + extend-shallow: 2.0.1 + kind-of: 6.0.3 + + shebang-command@2.0.0: + dependencies: + shebang-regex: 3.0.0 + + shebang-regex@3.0.0: {} + + shiki@1.23.1: + dependencies: + '@shikijs/core': 1.23.1 + '@shikijs/engine-javascript': 1.23.1 + '@shikijs/engine-oniguruma': 1.23.1 + '@shikijs/types': 1.23.1 + '@shikijs/vscode-textmate': 9.3.0 + '@types/hast': 3.0.4 + + signal-exit@4.1.0: {} + + sirv@2.0.4: + dependencies: + '@polka/url': 1.0.0-next.28 + mrmime: 2.0.0 + totalist: 3.0.1 + + source-map-js@1.2.1: {} + + space-separated-tokens@2.0.2: {} + + speakingurl@14.0.1: {} + + sprintf-js@1.0.3: {} + + string-width@4.2.3: + dependencies: + emoji-regex: 8.0.0 + is-fullwidth-code-point: 3.0.0 + strip-ansi: 6.0.1 + + string-width@5.1.2: + dependencies: + eastasianwidth: 0.2.0 + emoji-regex: 9.2.2 + strip-ansi: 7.1.0 + + stringify-entities@4.0.4: + dependencies: + character-entities-html4: 2.1.0 + character-entities-legacy: 3.0.0 + + strip-ansi@6.0.1: + dependencies: + ansi-regex: 5.0.1 + + strip-ansi@7.1.0: + dependencies: + ansi-regex: 6.1.0 + + strip-bom-string@1.0.0: {} + + superjson@2.2.1: + dependencies: + copy-anything: 3.0.5 + + tabbable@6.2.0: {} + + tinyexec@0.3.1: {} + + tinyglobby@0.2.10: + dependencies: + fdir: 6.4.2(picomatch@4.0.2) + picomatch: 4.0.2 + + to-regex-range@5.0.1: + dependencies: + is-number: 7.0.0 + + totalist@3.0.1: {} + + trim-lines@3.0.1: {} + + tsx@4.19.2: + dependencies: + esbuild: 0.23.1 + get-tsconfig: 4.8.1 + optionalDependencies: + fsevents: 2.3.3 + + ufo@1.5.4: {} + + unconfig@0.5.5: + dependencies: + '@antfu/utils': 0.7.10 + defu: 6.1.4 + importx: 0.4.4 + transitivePeerDependencies: + - supports-color + + unist-util-is@6.0.0: + dependencies: + '@types/unist': 3.0.3 + + unist-util-position@5.0.0: + dependencies: + '@types/unist': 3.0.3 + + unist-util-stringify-position@4.0.0: + dependencies: + '@types/unist': 3.0.3 + + unist-util-visit-parents@6.0.1: + dependencies: + '@types/unist': 3.0.3 + unist-util-is: 6.0.0 + + unist-util-visit@5.0.0: + dependencies: + '@types/unist': 3.0.3 + unist-util-is: 6.0.0 + unist-util-visit-parents: 6.0.1 + + unocss@0.64.1(postcss@8.4.49)(rollup@4.27.3)(vite@5.4.11)(vue@3.5.13): + dependencies: + '@unocss/astro': 0.64.1(rollup@4.27.3)(vite@5.4.11)(vue@3.5.13) + '@unocss/cli': 0.64.1(rollup@4.27.3) + '@unocss/core': 0.64.1 + '@unocss/postcss': 0.64.1(postcss@8.4.49) + '@unocss/preset-attributify': 0.64.1 + '@unocss/preset-icons': 0.64.1 + '@unocss/preset-mini': 0.64.1 + '@unocss/preset-tagify': 0.64.1 + '@unocss/preset-typography': 0.64.1 + '@unocss/preset-uno': 0.64.1 + '@unocss/preset-web-fonts': 0.64.1 + '@unocss/preset-wind': 0.64.1 + '@unocss/transformer-attributify-jsx': 0.64.1 + '@unocss/transformer-compile-class': 0.64.1 + '@unocss/transformer-directives': 0.64.1 + '@unocss/transformer-variant-group': 0.64.1 + '@unocss/vite': 0.64.1(rollup@4.27.3)(vite@5.4.11)(vue@3.5.13) + optionalDependencies: + vite: 5.4.11 + transitivePeerDependencies: + - postcss + - rollup + - supports-color + - vue + + vfile-message@4.0.2: + dependencies: + '@types/unist': 3.0.3 + unist-util-stringify-position: 4.0.0 + + vfile@6.0.3: + dependencies: + '@types/unist': 3.0.3 + vfile-message: 4.0.2 + + vite@5.4.11: + dependencies: + esbuild: 0.21.5 + postcss: 8.4.49 + rollup: 4.27.3 + optionalDependencies: + fsevents: 2.3.3 + + vitepress-plugin-codeblocks-fold@1.2.28: {} + + vitepress-plugin-pagefind@0.4.11(pagefind@1.2.0): + dependencies: + '@sugarat/theme-shared': 0.0.3 + '@vueuse/core': 9.13.0(vue@3.5.13) + javascript-stringify: 2.1.0 + pagefind: 1.2.0 + vue: 3.5.13 + vue-command-palette: 0.1.4 + transitivePeerDependencies: + - '@vue/composition-api' + - typescript + + vitepress-sidebar@1.29.0: + dependencies: + glob: 10.4.5 + gray-matter: 4.0.3 + + vitepress@1.5.0(@algolia/client-search@5.15.0)(postcss@8.4.49)(search-insights@2.17.3): + dependencies: + '@docsearch/css': 3.8.0 + '@docsearch/js': 3.8.0(@algolia/client-search@5.15.0)(search-insights@2.17.3) + '@iconify-json/simple-icons': 1.2.12 + '@shikijs/core': 1.23.1 + '@shikijs/transformers': 1.23.1 + '@shikijs/types': 1.23.1 + '@types/markdown-it': 14.1.2 + '@vitejs/plugin-vue': 5.2.0(vite@5.4.11)(vue@3.5.13) + '@vue/devtools-api': 7.6.4 + '@vue/shared': 3.5.13 + '@vueuse/core': 11.2.0(vue@3.5.13) + '@vueuse/integrations': 11.2.0(focus-trap@7.6.2)(vue@3.5.13) + focus-trap: 7.6.2 + mark.js: 8.11.1 + minisearch: 7.1.0 + shiki: 1.23.1 + vite: 5.4.11 + vue: 3.5.13 + optionalDependencies: + postcss: 8.4.49 + transitivePeerDependencies: + - '@algolia/client-search' + - '@types/node' + - '@types/react' + - '@vue/composition-api' + - async-validator + - axios + - change-case + - drauu + - fuse.js + - idb-keyval + - jwt-decode + - less + - lightningcss + - nprogress + - qrcode + - react + - react-dom + - sass + - sass-embedded + - search-insights + - sortablejs + - stylus + - sugarss + - terser + - typescript + - universal-cookie + + vue-command-palette@0.1.4: + dependencies: + fuse.js: 6.6.2 + mitt: 3.0.1 + nanoid: 4.0.2 + + vue-demi@0.14.10(vue@3.5.13): + dependencies: + vue: 3.5.13 + + vue-flow-layout@0.1.1(vue@3.5.13): + dependencies: + vue: 3.5.13 + + vue@3.5.13: + dependencies: + '@vue/compiler-dom': 3.5.13 + '@vue/compiler-sfc': 3.5.13 + '@vue/runtime-dom': 3.5.13 + '@vue/server-renderer': 3.5.13(vue@3.5.13) + '@vue/shared': 3.5.13 + + which@2.0.2: + dependencies: + isexe: 2.0.0 + + wrap-ansi@7.0.0: + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + + wrap-ansi@8.1.0: + dependencies: + ansi-styles: 6.2.1 + string-width: 5.1.2 + strip-ansi: 7.1.0 + + zwitch@2.0.4: {} diff --git a/public/asset/favicon.ico b/public/asset/favicon.ico new file mode 100644 index 0000000..6a4e41c Binary files /dev/null and b/public/asset/favicon.ico differ diff --git a/public/cat-typing.gif b/public/cat-typing.gif new file mode 100644 index 0000000..be05cfc Binary files /dev/null and b/public/cat-typing.gif differ diff --git a/public/configuration.yml.rtf b/public/configuration.yml.rtf new file mode 100644 index 0000000..d76c247 --- /dev/null +++ b/public/configuration.yml.rtf @@ -0,0 +1,1465 @@ +# yamllint disable rule:comments-indentation +--- +############################################################################### +# Authelia Configuration # +############################################################################### + +## Note: the container by default expects to find this file at /config/configuration.yml. + +## Certificates directory specifies where Authelia will load trusted certificates (public portion) from in addition to +## the system certificates store. +## They should be in base64 format, and have one of the following extensions: *.cer, *.crt, *.pem. +# certificates_directory: /config/certificates/ + +## The theme to display: light, dark, grey, auto. +theme: dark + +## The secret used to generate JWT tokens when validating user identity by email confirmation. JWT Secret can also be +## set using a secret: https://www.authelia.com/c/secrets +jwt_secret: REDACTED + +## Default redirection URL +## +## If user tries to authenticate without any referer, Authelia does not know where to redirect the user to at the end +## of the authentication process. This parameter allows you to specify the default redirection URL Authelia will use +## in such a case. +## +## Note: this parameter is optional. If not provided, user won't be redirected upon successful authentication. +default_redirection_url: https://[domain.tld]/ + +## Set the default 2FA method for new users and for when a user has a preferred method configured that has been +## disabled. This setting must be a method that is enabled. +## Options are totp, webauthn, mobile_push. +default_2fa_method: "totp" + +## +## Server Configuration +## +server: + + ## The address to listen on. + host: 0.0.0.0 + + ## The port to listen on. + port: 9091 + + ## Set the single level path Authelia listens on. + ## Must be alphanumeric chars and should not contain any slashes. + path: "authelia" + + ## Set the path on disk to Authelia assets. + ## Useful to allow overriding of specific static assets. + # asset_path: /config/assets/ + + ## Enables the pprof endpoint. + enable_pprof: false + + ## Enables the expvars endpoint. + enable_expvars: false + + ## Disables writing the health check vars to /app/.healthcheck.env which makes healthcheck.sh return exit code 0. + ## This is disabled by default if either /app/.healthcheck.env or /app/healthcheck.sh do not exist. + disable_healthcheck: false + + ## Authelia by default doesn't accept TLS communication on the server port. This section overrides this behaviour. + tls: + ## The path to the DER base64/PEM format private key. + key: "" + + ## The path to the DER base64/PEM format public certificate. + certificate: "" + + ## The list of certificates for client authentication. + client_certificates: [] + + ## Server headers configuration/customization. + headers: + + ## The CSP Template. Read the docs. + csp_template: "" + + ## Server Buffers configuration. + # buffers: + + ## Buffers usually should be configured to be the same value. + ## Explanation at https://www.authelia.com/c/server#buffer-sizes + ## Read buffer size adjusts the server's max incoming request size in bytes. + ## Write buffer size does the same for outgoing responses. + + ## Read buffer. + # read: 4096 + + ## Write buffer. + # write: 4096 + + ## Server Timeouts configuration. + # timeouts: + + ## Read timeout. + # read: 6s + + ## Write timeout. + # write: 6s + + ## Idle timeout. + # idle: 30s + +## +## Log Configuration +## +log: + ## Level of verbosity for logs: info, debug, trace. + level: debug + + ## Format the logs are written as: json, text. + # format: json + + ## File path where the logs will be written. If not set logs are written to stdout. + # file_path: /config/authelia.log + + ## Whether to also log to stdout when a log_file_path is defined. + # keep_stdout: false + +## +## Telemetry Configuration +## +telemetry: + + ## + ## Metrics Configuration + ## + metrics: + ## Enable Metrics. + enabled: false + + ## The address to listen on for metrics. This should be on a different port to the main server.port value. + address: tcp://0.0.0.0:9959 + + ## Metrics Server Buffers configuration. + # buffers: + + ## Read buffer. + # read: 4096 + + ## Write buffer. + # write: 4096 + + ## Metrics Server Timeouts configuration. + # timeouts: + + ## Read timeout. + # read: 6s + + ## Write timeout. + # write: 6s + + ## Idle timeout. + # idle: 30s + +## +## TOTP Configuration +## +## Parameters used for TOTP generation. +totp: + ## Disable TOTP. + disable: false + + ## The issuer name displayed in the Authenticator application of your choice. + issuer: [domain.tld] + + ## The TOTP algorithm to use. + ## It is CRITICAL you read the documentation before changing this option: + ## https://www.authelia.com/c/totp#algorithm + algorithm: sha1 + + ## The number of digits a user has to input. Must either be 6 or 8. + ## Changing this option only affects newly generated TOTP configurations. + ## It is CRITICAL you read the documentation before changing this option: + ## https://www.authelia.com/c/totp#digits + digits: 8 + + ## The period in seconds a one-time password is valid for. + ## Changing this option only affects newly generated TOTP configurations. + period: 30 + + ## The skew controls number of one-time passwords either side of the current one that are valid. + ## Warning: before changing skew read the docs link below. + skew: 1 + ## See: https://www.authelia.com/c/totp#input-validation to read + ## the documentation. + + ## The size of the generated shared secrets. Default is 32 and is sufficient in most use cases, minimum is 20. + secret_size: 32 + +## +## WebAuthn Configuration +## +## Parameters used for WebAuthn. +webauthn: + ## Disable Webauthn. + disable: false + + ## Adjust the interaction timeout for Webauthn dialogues. + timeout: 60s + + ## The display name the browser should show the user for when using Webauthn to login/register. + display_name: Authelia + + ## Conveyance preference controls if we collect the attestation statement including the AAGUID from the device. + ## Options are none, indirect, direct. + attestation_conveyance_preference: indirect + + ## User verification controls if the user must make a gesture or action to confirm they are present. + ## Options are required, preferred, discouraged. + user_verification: preferred + +## +## Duo Push API Configuration +## +## Parameters used to contact the Duo API. Those are generated when you protect an application of type +## "Partner Auth API" in the management panel. +# duo_api: + # disable: false + # hostname: api-123456789.example.com + # integration_key: ABCDEF + ## Secret can also be set using a secret: https://www.authelia.com/c/secrets + # secret_key: 1234567890abcdefghifjkl + # enable_self_enrollment: false + +## +## NTP Configuration +## +## This is used to validate the servers time is accurate enough to validate TOTP. +ntp: + ## NTP server address. + address: "time.cloudflare.com:123" + + ## NTP version. + version: 4 + + ## Maximum allowed time offset between the host and the NTP server. + max_desync: 3s + + ## Disables the NTP check on startup entirely. This means Authelia will not contact a remote service at all if you + ## set this to true, and can operate in a truly offline mode. + disable_startup_check: false + + ## The default of false will prevent startup only if we can contact the NTP server and the time is out of sync with + ## the NTP server more than the configured max_desync. If you set this to true, an error will be logged but startup + ## will continue regardless of results. + disable_failure: false + +## +## Authentication Backend Provider Configuration +## +## Used for verifying user passwords and retrieve information such as email address and groups users belong to. +## +## The available providers are: `file`, `ldap`. You must use only one of these providers. +authentication_backend: + + ## Password Reset Options. + password_reset: + ## Disable both the HTML element and the API for reset password functionality. + disable: false + + ## External reset password url that redirects the user to an external reset portal. This disables the internal reset + ## functionality. + custom_url: "" + + ## The amount of time to wait before we refresh data from the authentication backend. Uses duration notation. + ## To disable this feature set it to 'disable', this will slightly reduce security because for Authelia, users will + ## always belong to groups they belonged to at the time of login even if they have been removed from them in LDAP. + ## To force update on every request you can set this to '0' or 'always', this will increase processor demand. + ## See the below documentation for more information. + ## Duration Notation docs: https://www.authelia.com/c/common#duration-notation-format + ## Refresh Interval docs: https://www.authelia.com/c/1fa#refresh-interval + refresh_interval: 5m + + ## + ## LDAP (Authentication Provider) + ## + ## This is the recommended Authentication Provider in production + ## because it allows Authelia to offload the stateful operations + ## onto the LDAP service. + ldap: + ## The LDAP implementation, this affects elements like the attribute utilised for resetting a password. + ## Acceptable options are as follows: + ## - 'activedirectory' - For Microsoft Active Directory. + ## - 'custom' - For custom specifications of attributes and filters. + ## This currently defaults to 'custom' to maintain existing behaviour. + ## + ## Depending on the option here certain other values in this section have a default value, notably all of the + ## attribute mappings have a default value that this config overrides, you can read more about these default values + ## at https://www.authelia.com/c/ldap#defaults + implementation: custom + + ## The url to the ldap server. Format: ://
[:]. + ## Scheme can be ldap or ldaps in the format (port optional). + url: ldap://lldap:3890 + + ## The dial timeout for LDAP. + timeout: 5s + + ## Use StartTLS with the LDAP connection. + start_tls: false + + # tls: + ## The server subject name to check the servers certificate against during the validation process. + ## This option is not required if the certificate has a SAN which matches the host portion of the url option. + # server_name: ldap.example.com + + ## Skip verifying the server certificate entirely. In preference to setting this we strongly recommend you add the + ## certificate or the certificate of the authority signing the certificate to the certificates directory which is + ## defined by the `certificates_directory` option at the top of the configuration. + ## It's important to note the public key should be added to the directory, not the private key. + ## This option is strongly discouraged but may be useful in some self-signed situations where validation is not + ## important to the administrator. + # skip_verify: false + + ## Minimum TLS version for the connection. + # minimum_version: TLS1.2 + + ## Maximum TLS version for the connection. + # maximum_version: TLS1.3 + + ## The certificate chain used with the private_key if the server requests TLS Client Authentication + ## i.e. Mutual TLS. + # certificate_chain: | + # -----BEGIN CERTIFICATE----- + # MIIC5jCCAc6gAwIBAgIRAK4Sj7FiN6PXo/urPfO4E7owDQYJKoZIhvcNAQELBQAw + # EzERMA8GA1UEChMIQXV0aGVsaWEwHhcNNzAwMTAxMDAwMDAwWhcNNzEwMTAxMDAw + # MDAwWjATMREwDwYDVQQKEwhBdXRoZWxpYTCCASIwDQYJKoZIhvcNAQEBBQADggEP + # ADCCAQoCggEBAPKv3pSyP4ozGEiVLJ14dIWFCEGEgq7WUMI0SZZqQA2ID0L59U/Q + # /Usyy7uC9gfMUzODTpANtkOjFQcQAsxlR1FOjVBrX5QgjSvXwbQn3DtwMA7XWSl6 + # LuYx2rBYSlMSN5UZQm/RxMtXfLK2b51WgEEYDFi+nECSqKzR4R54eOPkBEWRfvuY + # 91AMjlhpivg8e4JWkq4LVQUKbmiFYwIdK8XQiN4blY9WwXwJFYs5sQ/UYMwBFi0H + # kWOh7GEjfxgoUOPauIueZSMSlQp7zqAH39N0ZSYb6cS0Npj57QoWZSY3ak87ebcR + # Nf4rCvZLby7LoN7qYCKxmCaDD3x2+NYpWH8CAwEAAaM1MDMwDgYDVR0PAQH/BAQD + # AgWgMBMGA1UdJQQMMAoGCCsGAQUFBwMBMAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcN + # AQELBQADggEBAHSITqIQSNzonFl3DzxHPEzr2hp6peo45buAAtu8FZHoA+U7Icfh + # /ZXjPg7Xz+hgFwM/DTNGXkMWacQA/PaNWvZspgRJf2AXvNbMSs2UQODr7Tbv+Fb4 + # lyblmMUNYFMCFVAMU0eIxXAFq2qcwv8UMcQFT0Z/35s6PVOakYnAGGQjTfp5Ljuq + # wsdc/xWmM0cHWube6sdRRUD7SY20KU/kWzl8iFO0VbSSrDf1AlEhnLEkp1SPaxXg + # OdBnl98MeoramNiJ7NT6Jnyb3zZ578fjaWfThiBpagItI8GZmG4s4Ovh2JbheN8i + # ZsjNr9jqHTjhyLVbDRlmJzcqoj4JhbKs6/I^invalid DO NOT USE= + # -----END CERTIFICATE----- + # -----BEGIN CERTIFICATE----- + # MIIDBDCCAeygAwIBAgIRALJsPg21kA0zY4F1wUCIuoMwDQYJKoZIhvcNAQELBQAw + # EzERMA8GA1UEChMIQXV0aGVsaWEwHhcNNzAwMTAxMDAwMDAwWhcNNzEwMTAxMDAw + # MDAwWjATMREwDwYDVQQKEwhBdXRoZWxpYTCCASIwDQYJKoZIhvcNAQEBBQADggEP + # ADCCAQoCggEBAMXHBvVxUzYk0u34/DINMSF+uiOekKOAjOrC6Mi9Ww8ytPVO7t2S + # zfTvM+XnEJqkFQFgimERfG/eGhjF9XIEY6LtnXe8ATvOK4nTwdufzBaoeQu3Gd50 + # 5VXr6OHRo//ErrGvFXwP3g8xLePABsi/fkH3oDN+ztewOBMDzpd+KgTrk8ysv2ou + # kNRMKFZZqASvCgv0LD5KWvUCnL6wgf1oTXG7aztduA4oSkUP321GpOmBC5+5ElU7 + # ysoRzvD12o9QJ/IfEaulIX06w9yVMo60C/h6A3U6GdkT1SiyTIqR7v7KU/IWd/Qi + # Lfftcj91VhCmJ73Meff2e2S2PrpjdXbG5FMCAwEAAaNTMFEwDgYDVR0PAQH/BAQD + # AgKkMA8GA1UdJQQIMAYGBFUdJQAwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU + # Z7AtA3mzFc0InSBA5fiMfeLXA3owDQYJKoZIhvcNAQELBQADggEBAEE5hm1mtlk/ + # kviCoHH4evbpw7rxPxDftIQlqYTtvMM4eWY/6icFoSZ4fUHEWYyps8SsPu/8f2tf + # 71LGgZn0FdHi1QU2H8m0HHK7TFw+5Q6RLrLdSyk0PItJ71s9en7r8pX820nAFEHZ + # HkOSfJZ7B5hFgUDkMtVM6bardXAhoqcMk4YCU96e9d4PB4eI+xGc+mNuYvov3RbB + # D0s8ICyojeyPVLerz4wHjZu68Z5frAzhZ68YbzNs8j2fIBKKHkHyLG1iQyF+LJVj + # 2PjCP+auJsj6fQQpMGoyGtpLcSDh+ptcTngUD8JsWipzTCjmaNqdPHAOYmcgtf4b + # qocikt3WAdU^invalid DO NOT USE= + # -----END CERTIFICATE----- + + ## The private key used with the certificate_chain if the server requests TLS Client Authentication + ## i.e. Mutual TLS. + # private_key: | + # -----BEGIN RSA PRIVATE KEY----- + # MIIEpAIBAAKCAQEA8q/elLI/ijMYSJUsnXh0hYUIQYSCrtZQwjRJlmpADYgPQvn1 + # T9D9SzLLu4L2B8xTM4NOkA22Q6MVBxACzGVHUU6NUGtflCCNK9fBtCfcO3AwDtdZ + # KXou5jHasFhKUxI3lRlCb9HEy1d8srZvnVaAQRgMWL6cQJKorNHhHnh44+QERZF+ + # +5j3UAyOWGmK+Dx7glaSrgtVBQpuaIVjAh0rxdCI3huVj1bBfAkVizmxD9RgzAEW + # LQeRY6HsYSN/GChQ49q4i55lIxKVCnvOoAff03RlJhvpxLQ2mPntChZlJjdqTzt5 + # txE1/isK9ktvLsug3upgIrGYJoMPfHb41ilYfwIDAQABAoIBAQDTOdFf2JjHH1um + # aPgRAvNf9v7Nj5jytaRKs5nM6iNf46ls4QPreXnMhqSeSwj6lpNgBYxOgzC9Q+cc + # Y4ob/paJJPaIJTxmP8K/gyWcOQlNToL1l+eJ20eQoZm23NGr5fIsunSBwLEpTrdB + # ENqqtcwhW937K8Pxy/Q1nuLyU2bc6Tn/ivLozc8n27dpQWWKh8537VY7ancIaACr + # LJJLYxKqhQpjtBWAyCDvZQirnAOm9KnvIHaGXIswCZ4Xbsu0Y9NL+woARPyRVQvG + # jfxy4EmO9s1s6y7OObSukwKDSNihAKHx/VIbvVWx8g2Lv5fGOa+J2Y7o9Qurs8t5 + # BQwMTt0BAoGBAPUw5Z32EszNepAeV3E2mPFUc5CLiqAxagZJuNDO2pKtyN29ETTR + # Ma4O1cWtGb6RqcNNN/Iukfkdk27Q5nC9VJSUUPYelOLc1WYOoUf6oKRzE72dkMQV + # R4bf6TkjD+OVR17fAfkswkGahZ5XA7j48KIQ+YC4jbnYKSxZTYyKPjH/AoGBAP1i + # tqXt36OVlP+y84wWqZSjMelBIVa9phDVGJmmhz3i1cMni8eLpJzWecA3pfnG6Tm9 + # ze5M4whASleEt+M00gEvNaU9ND+z0wBfi+/DwJYIbv8PQdGrBiZFrPhTPjGQUldR + # lXccV2meeLZv7TagVxSi3DO6dSJfSEHyemd5j9mBAoGAX8Hv+0gOQZQCSOTAq8Nx + # 6dZcp9gHlNaXnMsP9eTDckOSzh636JPGvj6m+GPJSSbkURUIQ3oyokMNwFqvlNos + # fTaLhAOfjBZI9WnDTTQxpugWjphJ4HqbC67JC/qIiw5S6FdaEvGLEEoD4zoChywZ + # 9oGAn+fz2d/0/JAH/FpFPgsCgYEAp/ipZgPzziiZ9ov1wbdAQcWRj7RaWnssPFpX + # jXwEiXT3CgEMO4MJ4+KWIWOChrti3qFBg6i6lDyyS6Qyls7sLFbUdC7HlTcrOEMe + # rBoTcCI1GqZNlqWOVQ65ZIEiaI7o1vPBZo2GMQEZuq8mDKFsOMThvvTrM5cAep84 + # n6HJR4ECgYABWcbsSnr0MKvVth/inxjbKapbZnp2HUCuw87Ie5zK2Of/tbC20wwk + # yKw3vrGoE3O1t1g2m2tn8UGGASeZ842jZWjIODdSi5+icysQGuULKt86h/woz2SQ + # 27GoE2i5mh6Yez6VAYbUuns3FcwIsMyWLq043Tu2DNkx9ijOOAuQzw^invalid.. + # DO NOT USE== + # -----END RSA PRIVATE KEY----- + + ## The distinguished name of the container searched for objects in the directory information tree. + ## See also: additional_users_dn, additional_groups_dn. + base_dn: dc=[domain],dc=[tld] + + ## The attribute holding the username of the user. This attribute is used to populate the username in the session + ## information. For your information, Microsoft Active Directory usually uses 'sAMAccountName' and OpenLDAP usually + ## uses 'uid'. Beware that this attribute holds the unique identifiers for the users binding the user and the + ## configuration stored in database. Therefore only single value attributes are allowed and the value must never be + ## changed once attributed to a user otherwise it would break the configuration for that user. Technically, + ## non-unique attributes like 'mail' can also be used but we don't recommend using them, we instead advise to use + ## a filter to perform alternative lookups and the attributes mentioned above (sAMAccountName and uid) to + ## follow https://www.ietf.org/rfc/rfc2307.txt. + username_attribute: uid + + ## The additional_users_dn is prefixed to base_dn and delimited by a comma when searching for users. + ## i.e. with this set to OU=Users and base_dn set to DC=a,DC=com; OU=Users,DC=a,DC=com is searched for users. + additional_users_dn: ou=people + + ## The users filter used in search queries to find the user profile based on input filled in login form. + ## Various placeholders are available in the user filter which you can read about in the documentation which can + ## be found at: https://www.authelia.com/c/ldap#users-filter-replacements + ## + ## Recommended settings are as follows: + ## - Microsoft Active Directory: (&({username_attribute}={input})(objectCategory=person)(objectClass=user)) + ## - OpenLDAP: + ## - (&({username_attribute}={input})(objectClass=person)) + ## - (&({username_attribute}={input})(objectClass=inetOrgPerson)) + ## + ## To allow sign in both with username and email, one can use a filter like + ## (&(|({username_attribute}={input})({mail_attribute}={input}))(objectClass=person)) + users_filter: (&({username_attribute}={input})(objectClass=person)) + + ## The additional_groups_dn is prefixed to base_dn and delimited by a comma when searching for groups. + ## i.e. with this set to OU=Groups and base_dn set to DC=a,DC=com; OU=Groups,DC=a,DC=com is searched for groups. + additional_groups_dn: ou=groups + + ## The groups filter used in search queries to find the groups based on relevant authenticated user. + ## Various placeholders are available in the groups filter which you can read about in the documentation which can + ## be found at: https://www.authelia.com/c/ldap#groups-filter-replacements + ## + ## If your groups use the `groupOfUniqueNames` structure use this instead: + ## (&(uniqueMember={dn})(objectClass=groupOfUniqueNames)) + groups_filter: (&(member={dn})(objectClass=groupOfUniqueNames)) + + ## The attribute holding the name of the group. + group_name_attribute: cn + + ## The attribute holding the mail address of the user. If multiple email addresses are defined for a user, only the + ## first one returned by the LDAP server is used. + mail_attribute: mail + + ## The attribute holding the display name of the user. This will be used to greet an authenticated user. + display_name_attribute: displayName + + ## Follow referrals returned by the server. + ## This is especially useful for environments where read-only servers exist. Only implemented for write operations. + # permit_referrals: false + + ## The username and password of the admin user. + user: cn=admin,ou=people,dc=[domain],dc=[tld] + ## Password can also be set using a secret: https://www.authelia.com/c/secrets + password: "REDACTED" + + ## + ## File (Authentication Provider) + ## + ## With this backend, the users database is stored in a file which is updated when users reset their passwords. + ## Therefore, this backend is meant to be used in a dev environment and not in production since it prevents Authelia + ## to be scaled to more than one instance. The options under 'password' have sane defaults, and as it has security + ## implications it is highly recommended you leave the default values. Before considering changing these settings + ## please read the docs page below: + ## https://www.authelia.com/r/passwords#tuning + ## + ## Important: Kubernetes (or HA) users must read https://www.authelia.com/t/statelessness + ## + # file: + # path: /config/users_database.yml + # watch: false + # search: + # email: false + # case_insensitive: false + # password: + # algorithm: argon2 + # argon2: + # variant: argon2id + # iterations: 3 + # memory: 65536 + # parallelism: 4 + # key_length: 32 + # salt_length: 16 + # scrypt: + # iterations: 16 + # block_size: 8 + # parallelism: 1 + # key_length: 32 + # salt_length: 16 + # pbkdf2: + # variant: sha512 + # iterations: 310000 + # salt_length: 16 + # sha2crypt: + # variant: sha512 + # iterations: 50000 + # salt_length: 16 + # bcrypt: + # variant: standard + # cost: 12 + + +## +## Password Policy Configuration. +## +password_policy: + + ## The standard policy allows you to tune individual settings manually. + standard: + enabled: true + + ## Require a minimum length for passwords. + min_length: 8 + + ## Require a maximum length for passwords. + max_length: 0 + + ## Require uppercase characters. + require_uppercase: true + + ## Require lowercase characters. + require_lowercase: true + + ## Require numeric characters. + require_number: true + + ## Require special characters. + require_special: true + + ## zxcvbn is a well known and used password strength algorithm. It does not have tunable settings. + zxcvbn: + enabled: false + + ## Configures the minimum score allowed. + min_score: 3 + +## +## Access Control Configuration +## +## Access control is a list of rules defining the authorizations applied for one resource to users or group of users. +## +## If 'access_control' is not defined, ACL rules are disabled and the 'bypass' rule is applied, i.e., access is allowed +## to anyone. Otherwise restrictions follow the rules defined. +## +## Note: One can use the wildcard * to match any subdomain. +## It must stand at the beginning of the pattern. (example: *.example.com) +## +## Note: You must put patterns containing wildcards between simple quotes for the YAML to be syntactically correct. +## +## Definition: A 'rule' is an object with the following keys: 'domain', 'subject', 'policy' and 'resources'. +## +## - 'domain' defines which domain or set of domains the rule applies to. +## +## - 'subject' defines the subject to apply authorizations to. This parameter is optional and matching any user if not +## provided. If provided, the parameter represents either a user or a group. It should be of the form +## 'user:' or 'group:'. +## +## - 'policy' is the policy to apply to resources. It must be either 'bypass', 'one_factor', 'two_factor' or 'deny'. +## +## - 'resources' is a list of regular expressions that matches a set of resources to apply the policy to. This parameter +## is optional and matches any resource if not provided. +## +## Note: the order of the rules is important. The first policy matching (domain, resource, subject) applies. +access_control: + ## Default policy can either be 'bypass', 'one_factor', 'two_factor' or 'deny'. It is the policy applied to any + ## resource if there is no policy to be applied to the user. + default_policy: deny + + # networks: + # - name: internal + # networks: + # - 10.10.0.0/16 + # - 192.168.2.0/24 + # - name: VPN + # networks: 10.9.0.0/16 + + rules: + ## Rules applied to everyone + ## This below policy allows for auth to be accessed at all times, + ## useful when trying to login without the main page available. + - domain: + - 'auth.[domain.tld]' + policy: bypass + ## This below policy example will exclude a user from using 2FA, + ## useful if the user has no way of configuring 2FA. + - domain: + - '[domain.tld]' + - '*.[domain.tld]' + subject: + - "user:[USERNAME/UID]" + policy: one_factor + ## This below policy example will exclude all users of the people + ## group from using 2FA, NOT RECOMMENDED + - domain: + - '[domain.tld]' + - '*.[domain.tld]' + subject: + - "group:people" + policy: one_factor + ## This below policy will require all users of the LLDAP_Admin group + ## in LLDAP to use 2FA BY DEFAULT, this is the strongest policy available + - domain: + - '[domain.tld]' + - '*.[domain.tld]' + subject: + - "group:lldap_admin" + policy: two_factor + + ## Domain Regex examples. Generally we recommend just using a standard domain. + # - domain_regex: '^(?P\w+)\.example\.com$' + # policy: one_factor + # - domain_regex: '^(?P\w+)\.example\.com$' + # policy: one_factor + # - domain_regex: + # - '^appgroup-.*\.example\.com$' + # - '^appgroup2-.*\.example\.com$' + # policy: one_factor + # - domain_regex: '^.*\.example\.com$' + # policy: two_factor + + # - domain: 'secure.example.com' + # policy: one_factor + ## Network based rule, if not provided any network matches. + # networks: + # - internal + # - VPN + # - 192.168.1.0/24 + # - 10.0.0.1 + + # - domain: + # - 'secure.example.com' + # - 'private.example.com' + # policy: two_factor + + # - domain: 'singlefactor.example.com' + # policy: one_factor + + ## Rules applied to 'admins' group + # - domain: 'mx2.mail.example.com' + # subject: 'group:admins' + # policy: deny + + # - domain: '*.example.com' + # subject: + # - 'group:admins' + # - 'group:moderators' + # policy: two_factor + + ## Rules applied to 'dev' group + # - domain: 'dev.example.com' + # resources: + # - '^/groups/dev/.*$' + # subject: 'group:dev' + # policy: two_factor + + ## Rules applied to user 'john' + # - domain: 'dev.example.com' + # resources: + # - '^/users/john/.*$' + # subject: 'user:john' + # policy: two_factor + + ## Rules applied to user 'harry' + # - domain: 'dev.example.com' + # resources: + # - '^/users/harry/.*$' + # subject: 'user:harry' + # policy: two_factor + + ## Rules applied to user 'bob' + # - domain: '*.mail.example.com' + # subject: 'user:bob' + # policy: two_factor + # - domain: 'dev.example.com' + # resources: + # - '^/users/bob/.*$' + # subject: 'user:bob' + # policy: two_factor + +## +## Session Provider Configuration +## +## The session cookies identify the user once logged in. +## The available providers are: `memory`, `redis`. Memory is the provider unless redis is defined. +session: + ## The name of the session cookie. + name: authelia_session + + ## The domain to protect. + ## Note: the authenticator must also be in that domain. + ## If empty, the cookie is restricted to the subdomain of the issuer. + domain: [domain.tld] + + ## Sets the Cookie SameSite value. Possible options are none, lax, or strict. + ## Please read https://www.authelia.com/c/session#same_site + same_site: lax + + ## The secret to encrypt the session data. This is only used with Redis / Redis Sentinel. + ## Secret can also be set using a secret: https://www.authelia.com/c/secrets + secret: REDACTED + + ## The value for expiration, inactivity, and remember_me_duration are in seconds or the duration notation format. + ## See: https://www.authelia.com/c/common#duration-notation-format + ## All three of these values affect the cookie/session validity period. Longer periods are considered less secure + ## because a stolen cookie will last longer giving attackers more time to spy or attack. + + ## The time before the cookie expires and the session is destroyed if remember me IS NOT selected. + expiration: 1h + + ## The inactivity time before the session is reset. If expiration is set to 1h, and this is set to 5m, if the user + ## does not select the remember me option their session will get destroyed after 1h, or after 5m since the last time + ## Authelia detected user activity. + inactivity: 5m + + ## The time before the cookie expires and the session is destroyed if remember me IS selected. + ## Value of -1 disables remember me. + remember_me_duration: 2M + + ## + ## Redis Provider + ## + ## Important: Kubernetes (or HA) users must read https://www.authelia.com/t/statelessness + ## + redis: + host: redis + port: 6379 + ## Use a unix socket instead + # host: /var/run/redis/redis.sock + + ## Username used for redis authentication. This is optional and a new feature in redis 6.0. + # username: authelia + + ## Password can also be set using a secret: https://www.authelia.com/c/secrets + password: REDACTED + + ## This is the Redis DB Index https://redis.io/commands/select (sometimes referred to as database number, DB, etc). + database_index: 0 + + ## The maximum number of concurrent active connections to Redis. + maximum_active_connections: 10 + + ## The target number of idle connections to have open ready for work. Useful when opening connections is slow. + minimum_idle_connections: 0 + + ## The Redis TLS configuration. If defined will require a TLS connection to the Redis instance(s). + # tls: + ## The server subject name to check the servers certificate against during the validation process. + ## This option is not required if the certificate has a SAN which matches the host option. + # server_name: myredis.example.com + + ## Skip verifying the server certificate entirely. In preference to setting this we strongly recommend you add the + ## certificate or the certificate of the authority signing the certificate to the certificates directory which is + ## defined by the `certificates_directory` option at the top of the configuration. + ## It's important to note the public key should be added to the directory, not the private key. + ## This option is strongly discouraged but may be useful in some self-signed situations where validation is not + ## important to the administrator. + # skip_verify: false + + ## Minimum TLS version for the connection. + # minimum_version: TLS1.2 + + ## Maximum TLS version for the connection. + # maximum_version: TLS1.3 + + ## The certificate chain used with the private_key if the server requests TLS Client Authentication + ## i.e. Mutual TLS. + # certificate_chain: | + # -----BEGIN CERTIFICATE----- + # MIIC5jCCAc6gAwIBAgIRAK4Sj7FiN6PXo/urPfO4E7owDQYJKoZIhvcNAQELBQAw + # EzERMA8GA1UEChMIQXV0aGVsaWEwHhcNNzAwMTAxMDAwMDAwWhcNNzEwMTAxMDAw + # MDAwWjATMREwDwYDVQQKEwhBdXRoZWxpYTCCASIwDQYJKoZIhvcNAQEBBQADggEP + # ADCCAQoCggEBAPKv3pSyP4ozGEiVLJ14dIWFCEGEgq7WUMI0SZZqQA2ID0L59U/Q + # /Usyy7uC9gfMUzODTpANtkOjFQcQAsxlR1FOjVBrX5QgjSvXwbQn3DtwMA7XWSl6 + # LuYx2rBYSlMSN5UZQm/RxMtXfLK2b51WgEEYDFi+nECSqKzR4R54eOPkBEWRfvuY + # 91AMjlhpivg8e4JWkq4LVQUKbmiFYwIdK8XQiN4blY9WwXwJFYs5sQ/UYMwBFi0H + # kWOh7GEjfxgoUOPauIueZSMSlQp7zqAH39N0ZSYb6cS0Npj57QoWZSY3ak87ebcR + # Nf4rCvZLby7LoN7qYCKxmCaDD3x2+NYpWH8CAwEAAaM1MDMwDgYDVR0PAQH/BAQD + # AgWgMBMGA1UdJQQMMAoGCCsGAQUFBwMBMAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcN + # AQELBQADggEBAHSITqIQSNzonFl3DzxHPEzr2hp6peo45buAAtu8FZHoA+U7Icfh + # /ZXjPg7Xz+hgFwM/DTNGXkMWacQA/PaNWvZspgRJf2AXvNbMSs2UQODr7Tbv+Fb4 + # lyblmMUNYFMCFVAMU0eIxXAFq2qcwv8UMcQFT0Z/35s6PVOakYnAGGQjTfp5Ljuq + # wsdc/xWmM0cHWube6sdRRUD7SY20KU/kWzl8iFO0VbSSrDf1AlEhnLEkp1SPaxXg + # OdBnl98MeoramNiJ7NT6Jnyb3zZ578fjaWfThiBpagItI8GZmG4s4Ovh2JbheN8i + # ZsjNr9jqHTjhyLVbDRlmJzcqoj4JhbKs6/I^invalid DO NOT USE= + # -----END CERTIFICATE----- + # -----BEGIN CERTIFICATE----- + # MIIDBDCCAeygAwIBAgIRALJsPg21kA0zY4F1wUCIuoMwDQYJKoZIhvcNAQELBQAw + # EzERMA8GA1UEChMIQXV0aGVsaWEwHhcNNzAwMTAxMDAwMDAwWhcNNzEwMTAxMDAw + # MDAwWjATMREwDwYDVQQKEwhBdXRoZWxpYTCCASIwDQYJKoZIhvcNAQEBBQADggEP + # ADCCAQoCggEBAMXHBvVxUzYk0u34/DINMSF+uiOekKOAjOrC6Mi9Ww8ytPVO7t2S + # zfTvM+XnEJqkFQFgimERfG/eGhjF9XIEY6LtnXe8ATvOK4nTwdufzBaoeQu3Gd50 + # 5VXr6OHRo//ErrGvFXwP3g8xLePABsi/fkH3oDN+ztewOBMDzpd+KgTrk8ysv2ou + # kNRMKFZZqASvCgv0LD5KWvUCnL6wgf1oTXG7aztduA4oSkUP321GpOmBC5+5ElU7 + # ysoRzvD12o9QJ/IfEaulIX06w9yVMo60C/h6A3U6GdkT1SiyTIqR7v7KU/IWd/Qi + # Lfftcj91VhCmJ73Meff2e2S2PrpjdXbG5FMCAwEAAaNTMFEwDgYDVR0PAQH/BAQD + # AgKkMA8GA1UdJQQIMAYGBFUdJQAwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU + # Z7AtA3mzFc0InSBA5fiMfeLXA3owDQYJKoZIhvcNAQELBQADggEBAEE5hm1mtlk/ + # kviCoHH4evbpw7rxPxDftIQlqYTtvMM4eWY/6icFoSZ4fUHEWYyps8SsPu/8f2tf + # 71LGgZn0FdHi1QU2H8m0HHK7TFw+5Q6RLrLdSyk0PItJ71s9en7r8pX820nAFEHZ + # HkOSfJZ7B5hFgUDkMtVM6bardXAhoqcMk4YCU96e9d4PB4eI+xGc+mNuYvov3RbB + # D0s8ICyojeyPVLerz4wHjZu68Z5frAzhZ68YbzNs8j2fIBKKHkHyLG1iQyF+LJVj + # 2PjCP+auJsj6fQQpMGoyGtpLcSDh+ptcTngUD8JsWipzTCjmaNqdPHAOYmcgtf4b + # qocikt3WAdU^invalid DO NOT USE= + # -----END CERTIFICATE----- + + ## The private key used with the certificate_chain if the server requests TLS Client Authentication + ## i.e. Mutual TLS. + # private_key: | + # -----BEGIN RSA PRIVATE KEY----- + # MIIEpAIBAAKCAQEA8q/elLI/ijMYSJUsnXh0hYUIQYSCrtZQwjRJlmpADYgPQvn1 + # T9D9SzLLu4L2B8xTM4NOkA22Q6MVBxACzGVHUU6NUGtflCCNK9fBtCfcO3AwDtdZ + # KXou5jHasFhKUxI3lRlCb9HEy1d8srZvnVaAQRgMWL6cQJKorNHhHnh44+QERZF+ + # +5j3UAyOWGmK+Dx7glaSrgtVBQpuaIVjAh0rxdCI3huVj1bBfAkVizmxD9RgzAEW + # LQeRY6HsYSN/GChQ49q4i55lIxKVCnvOoAff03RlJhvpxLQ2mPntChZlJjdqTzt5 + # txE1/isK9ktvLsug3upgIrGYJoMPfHb41ilYfwIDAQABAoIBAQDTOdFf2JjHH1um + # aPgRAvNf9v7Nj5jytaRKs5nM6iNf46ls4QPreXnMhqSeSwj6lpNgBYxOgzC9Q+cc + # Y4ob/paJJPaIJTxmP8K/gyWcOQlNToL1l+eJ20eQoZm23NGr5fIsunSBwLEpTrdB + # ENqqtcwhW937K8Pxy/Q1nuLyU2bc6Tn/ivLozc8n27dpQWWKh8537VY7ancIaACr + # LJJLYxKqhQpjtBWAyCDvZQirnAOm9KnvIHaGXIswCZ4Xbsu0Y9NL+woARPyRVQvG + # jfxy4EmO9s1s6y7OObSukwKDSNihAKHx/VIbvVWx8g2Lv5fGOa+J2Y7o9Qurs8t5 + # BQwMTt0BAoGBAPUw5Z32EszNepAeV3E2mPFUc5CLiqAxagZJuNDO2pKtyN29ETTR + # Ma4O1cWtGb6RqcNNN/Iukfkdk27Q5nC9VJSUUPYelOLc1WYOoUf6oKRzE72dkMQV + # R4bf6TkjD+OVR17fAfkswkGahZ5XA7j48KIQ+YC4jbnYKSxZTYyKPjH/AoGBAP1i + # tqXt36OVlP+y84wWqZSjMelBIVa9phDVGJmmhz3i1cMni8eLpJzWecA3pfnG6Tm9 + # ze5M4whASleEt+M00gEvNaU9ND+z0wBfi+/DwJYIbv8PQdGrBiZFrPhTPjGQUldR + # lXccV2meeLZv7TagVxSi3DO6dSJfSEHyemd5j9mBAoGAX8Hv+0gOQZQCSOTAq8Nx + # 6dZcp9gHlNaXnMsP9eTDckOSzh636JPGvj6m+GPJSSbkURUIQ3oyokMNwFqvlNos + # fTaLhAOfjBZI9WnDTTQxpugWjphJ4HqbC67JC/qIiw5S6FdaEvGLEEoD4zoChywZ + # 9oGAn+fz2d/0/JAH/FpFPgsCgYEAp/ipZgPzziiZ9ov1wbdAQcWRj7RaWnssPFpX + # jXwEiXT3CgEMO4MJ4+KWIWOChrti3qFBg6i6lDyyS6Qyls7sLFbUdC7HlTcrOEMe + # rBoTcCI1GqZNlqWOVQ65ZIEiaI7o1vPBZo2GMQEZuq8mDKFsOMThvvTrM5cAep84 + # n6HJR4ECgYABWcbsSnr0MKvVth/inxjbKapbZnp2HUCuw87Ie5zK2Of/tbC20wwk + # yKw3vrGoE3O1t1g2m2tn8UGGASeZ842jZWjIODdSi5+icysQGuULKt86h/woz2SQ + # 27GoE2i5mh6Yez6VAYbUuns3FcwIsMyWLq043Tu2DNkx9ijOOAuQzw^invalid.. + # DO NOT USE== + # -----END RSA PRIVATE KEY----- + + ## The Redis HA configuration options. + ## This provides specific options to Redis Sentinel, sentinel_name must be defined (Master Name). + # high_availability: + ## Sentinel Name / Master Name. + # sentinel_name: mysentinel + + ## Specific username for Redis Sentinel. The node username and password is configured above. + # sentinel_username: sentinel_specific_user + + ## Specific password for Redis Sentinel. The node username and password is configured above. + # sentinel_password: sentinel_specific_pass + + ## The additional nodes to pre-seed the redis provider with (for sentinel). + ## If the host in the above section is defined, it will be combined with this list to connect to sentinel. + ## For high availability to be used you must have either defined; the host above or at least one node below. + # nodes: + # - host: sentinel-node1 + # port: 6379 + # - host: sentinel-node2 + # port: 6379 + + ## Choose the host with the lowest latency. + # route_by_latency: false + + ## Choose the host randomly. + # route_randomly: false + +## +## Regulation Configuration +## +## This mechanism prevents attackers from brute forcing the first factor. It bans the user if too many attempts are made +## in a short period of time. +regulation: + ## The number of failed login attempts before user is banned. Set it to 0 to disable regulation. + max_retries: 3 + + ## The time range during which the user can attempt login before being banned. The user is banned if the + ## authentication failed 'max_retries' times in a 'find_time' seconds window. Find Time accepts duration notation. + ## See: https://www.authelia.com/c/common#duration-notation-format + find_time: 10m + + ## The length of time before a banned user can login again. Ban Time accepts duration notation. + ## See: https://www.authelia.com/c/common#duration-notation-format + ban_time: 12h + +## +## Storage Provider Configuration +## +## The available providers are: `local`, `mysql`, `postgres`. You must use one and only one of these providers. +storage: + ## The encryption key that is used to encrypt sensitive information in the database. Must be a string with a minimum + ## length of 20. Please see the docs if you configure this with an undesirable key and need to change it, you MUST use + ## the CLI to change this in the database if you want to change it from a previously configured value. + encryption_key: REDACTED + + ## + ## Local (Storage Provider) + ## + ## This stores the data in a SQLite3 Database. + ## This is only recommended for lightweight non-stateful installations. + ## + ## Important: Kubernetes (or HA) users must read https://www.authelia.com/t/statelessness + ## + # local: + ## Path to the SQLite3 Database. + # path: /config/db.sqlite3 + + ## + ## MySQL / MariaDB (Storage Provider) + ## + mysql: + host: mysql + port: 3306 + database: authelia + username: authelia + ## Password can also be set using a secret: https://www.authelia.com/c/secrets + password: REDACTED + timeout: 5s + + ## MySQL TLS settings. Configuring this requires TLS. + # tls: + ## The server subject name to check the servers certificate against during the validation process. + ## This option is not required if the certificate has a SAN which matches the host option. + # server_name: mysql.example.com + + ## Skip verifying the server certificate entirely. In preference to setting this we strongly recommend you add the + ## certificate or the certificate of the authority signing the certificate to the certificates directory which is + ## defined by the `certificates_directory` option at the top of the configuration. + ## It's important to note the public key should be added to the directory, not the private key. + ## This option is strongly discouraged but may be useful in some self-signed situations where validation is not + ## important to the administrator. + # skip_verify: false + + ## Minimum TLS version for the connection. + # minimum_version: TLS1.2 + + ## Maximum TLS version for the connection. + # maximum_version: TLS1.3 + + ## The certificate chain used with the private_key if the server requests TLS Client Authentication + ## i.e. Mutual TLS. + # certificate_chain: | + # -----BEGIN CERTIFICATE----- + # MIIC5jCCAc6gAwIBAgIRAK4Sj7FiN6PXo/urPfO4E7owDQYJKoZIhvcNAQELBQAw + # EzERMA8GA1UEChMIQXV0aGVsaWEwHhcNNzAwMTAxMDAwMDAwWhcNNzEwMTAxMDAw + # MDAwWjATMREwDwYDVQQKEwhBdXRoZWxpYTCCASIwDQYJKoZIhvcNAQEBBQADggEP + # ADCCAQoCggEBAPKv3pSyP4ozGEiVLJ14dIWFCEGEgq7WUMI0SZZqQA2ID0L59U/Q + # /Usyy7uC9gfMUzODTpANtkOjFQcQAsxlR1FOjVBrX5QgjSvXwbQn3DtwMA7XWSl6 + # LuYx2rBYSlMSN5UZQm/RxMtXfLK2b51WgEEYDFi+nECSqKzR4R54eOPkBEWRfvuY + # 91AMjlhpivg8e4JWkq4LVQUKbmiFYwIdK8XQiN4blY9WwXwJFYs5sQ/UYMwBFi0H + # kWOh7GEjfxgoUOPauIueZSMSlQp7zqAH39N0ZSYb6cS0Npj57QoWZSY3ak87ebcR + # Nf4rCvZLby7LoN7qYCKxmCaDD3x2+NYpWH8CAwEAAaM1MDMwDgYDVR0PAQH/BAQD + # AgWgMBMGA1UdJQQMMAoGCCsGAQUFBwMBMAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcN + # AQELBQADggEBAHSITqIQSNzonFl3DzxHPEzr2hp6peo45buAAtu8FZHoA+U7Icfh + # /ZXjPg7Xz+hgFwM/DTNGXkMWacQA/PaNWvZspgRJf2AXvNbMSs2UQODr7Tbv+Fb4 + # lyblmMUNYFMCFVAMU0eIxXAFq2qcwv8UMcQFT0Z/35s6PVOakYnAGGQjTfp5Ljuq + # wsdc/xWmM0cHWube6sdRRUD7SY20KU/kWzl8iFO0VbSSrDf1AlEhnLEkp1SPaxXg + # OdBnl98MeoramNiJ7NT6Jnyb3zZ578fjaWfThiBpagItI8GZmG4s4Ovh2JbheN8i + # ZsjNr9jqHTjhyLVbDRlmJzcqoj4JhbKs6/I^invalid DO NOT USE= + # -----END CERTIFICATE----- + # -----BEGIN CERTIFICATE----- + # MIIDBDCCAeygAwIBAgIRALJsPg21kA0zY4F1wUCIuoMwDQYJKoZIhvcNAQELBQAw + # EzERMA8GA1UEChMIQXV0aGVsaWEwHhcNNzAwMTAxMDAwMDAwWhcNNzEwMTAxMDAw + # MDAwWjATMREwDwYDVQQKEwhBdXRoZWxpYTCCASIwDQYJKoZIhvcNAQEBBQADggEP + # ADCCAQoCggEBAMXHBvVxUzYk0u34/DINMSF+uiOekKOAjOrC6Mi9Ww8ytPVO7t2S + # zfTvM+XnEJqkFQFgimERfG/eGhjF9XIEY6LtnXe8ATvOK4nTwdufzBaoeQu3Gd50 + # 5VXr6OHRo//ErrGvFXwP3g8xLePABsi/fkH3oDN+ztewOBMDzpd+KgTrk8ysv2ou + # kNRMKFZZqASvCgv0LD5KWvUCnL6wgf1oTXG7aztduA4oSkUP321GpOmBC5+5ElU7 + # ysoRzvD12o9QJ/IfEaulIX06w9yVMo60C/h6A3U6GdkT1SiyTIqR7v7KU/IWd/Qi + # Lfftcj91VhCmJ73Meff2e2S2PrpjdXbG5FMCAwEAAaNTMFEwDgYDVR0PAQH/BAQD + # AgKkMA8GA1UdJQQIMAYGBFUdJQAwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU + # Z7AtA3mzFc0InSBA5fiMfeLXA3owDQYJKoZIhvcNAQELBQADggEBAEE5hm1mtlk/ + # kviCoHH4evbpw7rxPxDftIQlqYTtvMM4eWY/6icFoSZ4fUHEWYyps8SsPu/8f2tf + # 71LGgZn0FdHi1QU2H8m0HHK7TFw+5Q6RLrLdSyk0PItJ71s9en7r8pX820nAFEHZ + # HkOSfJZ7B5hFgUDkMtVM6bardXAhoqcMk4YCU96e9d4PB4eI+xGc+mNuYvov3RbB + # D0s8ICyojeyPVLerz4wHjZu68Z5frAzhZ68YbzNs8j2fIBKKHkHyLG1iQyF+LJVj + # 2PjCP+auJsj6fQQpMGoyGtpLcSDh+ptcTngUD8JsWipzTCjmaNqdPHAOYmcgtf4b + # qocikt3WAdU^invalid DO NOT USE= + # -----END CERTIFICATE----- + + ## The private key used with the certificate_chain if the server requests TLS Client Authentication + ## i.e. Mutual TLS. + # private_key: | + # -----BEGIN RSA PRIVATE KEY----- + # MIIEpAIBAAKCAQEA8q/elLI/ijMYSJUsnXh0hYUIQYSCrtZQwjRJlmpADYgPQvn1 + # T9D9SzLLu4L2B8xTM4NOkA22Q6MVBxACzGVHUU6NUGtflCCNK9fBtCfcO3AwDtdZ + # KXou5jHasFhKUxI3lRlCb9HEy1d8srZvnVaAQRgMWL6cQJKorNHhHnh44+QERZF+ + # +5j3UAyOWGmK+Dx7glaSrgtVBQpuaIVjAh0rxdCI3huVj1bBfAkVizmxD9RgzAEW + # LQeRY6HsYSN/GChQ49q4i55lIxKVCnvOoAff03RlJhvpxLQ2mPntChZlJjdqTzt5 + # txE1/isK9ktvLsug3upgIrGYJoMPfHb41ilYfwIDAQABAoIBAQDTOdFf2JjHH1um + # aPgRAvNf9v7Nj5jytaRKs5nM6iNf46ls4QPreXnMhqSeSwj6lpNgBYxOgzC9Q+cc + # Y4ob/paJJPaIJTxmP8K/gyWcOQlNToL1l+eJ20eQoZm23NGr5fIsunSBwLEpTrdB + # ENqqtcwhW937K8Pxy/Q1nuLyU2bc6Tn/ivLozc8n27dpQWWKh8537VY7ancIaACr + # LJJLYxKqhQpjtBWAyCDvZQirnAOm9KnvIHaGXIswCZ4Xbsu0Y9NL+woARPyRVQvG + # jfxy4EmO9s1s6y7OObSukwKDSNihAKHx/VIbvVWx8g2Lv5fGOa+J2Y7o9Qurs8t5 + # BQwMTt0BAoGBAPUw5Z32EszNepAeV3E2mPFUc5CLiqAxagZJuNDO2pKtyN29ETTR + # Ma4O1cWtGb6RqcNNN/Iukfkdk27Q5nC9VJSUUPYelOLc1WYOoUf6oKRzE72dkMQV + # R4bf6TkjD+OVR17fAfkswkGahZ5XA7j48KIQ+YC4jbnYKSxZTYyKPjH/AoGBAP1i + # tqXt36OVlP+y84wWqZSjMelBIVa9phDVGJmmhz3i1cMni8eLpJzWecA3pfnG6Tm9 + # ze5M4whASleEt+M00gEvNaU9ND+z0wBfi+/DwJYIbv8PQdGrBiZFrPhTPjGQUldR + # lXccV2meeLZv7TagVxSi3DO6dSJfSEHyemd5j9mBAoGAX8Hv+0gOQZQCSOTAq8Nx + # 6dZcp9gHlNaXnMsP9eTDckOSzh636JPGvj6m+GPJSSbkURUIQ3oyokMNwFqvlNos + # fTaLhAOfjBZI9WnDTTQxpugWjphJ4HqbC67JC/qIiw5S6FdaEvGLEEoD4zoChywZ + # 9oGAn+fz2d/0/JAH/FpFPgsCgYEAp/ipZgPzziiZ9ov1wbdAQcWRj7RaWnssPFpX + # jXwEiXT3CgEMO4MJ4+KWIWOChrti3qFBg6i6lDyyS6Qyls7sLFbUdC7HlTcrOEMe + # rBoTcCI1GqZNlqWOVQ65ZIEiaI7o1vPBZo2GMQEZuq8mDKFsOMThvvTrM5cAep84 + # n6HJR4ECgYABWcbsSnr0MKvVth/inxjbKapbZnp2HUCuw87Ie5zK2Of/tbC20wwk + # yKw3vrGoE3O1t1g2m2tn8UGGASeZ842jZWjIODdSi5+icysQGuULKt86h/woz2SQ + # 27GoE2i5mh6Yez6VAYbUuns3FcwIsMyWLq043Tu2DNkx9ijOOAuQzw^invalid.. + # DO NOT USE== + # -----END RSA PRIVATE KEY----- + + ## + ## PostgreSQL (Storage Provider) + ## + # postgres: + # host: 127.0.0.1 + # port: 5432 + # database: authelia + # schema: public + # username: authelia + ## Password can also be set using a secret: https://www.authelia.com/c/secrets + # password: mypassword + # timeout: 5s + + ## PostgreSQL TLS settings. Configuring this requires TLS. + # tls: + ## The server subject name to check the servers certificate against during the validation process. + ## This option is not required if the certificate has a SAN which matches the host option. + # server_name: postgres.example.com + + ## Skip verifying the server certificate entirely. In preference to setting this we strongly recommend you add the + ## certificate or the certificate of the authority signing the certificate to the certificates directory which is + ## defined by the `certificates_directory` option at the top of the configuration. + ## It's important to note the public key should be added to the directory, not the private key. + ## This option is strongly discouraged but may be useful in some self-signed situations where validation is not + ## important to the administrator. + # skip_verify: false + + ## Minimum TLS version for the connection. + # minimum_version: TLS1.2 + + ## Maximum TLS version for the connection. + # maximum_version: TLS1.3 + + ## The certificate chain used with the private_key if the server requests TLS Client Authentication + ## i.e. Mutual TLS. + # certificate_chain: | + # -----BEGIN CERTIFICATE----- + # MIIC5jCCAc6gAwIBAgIRAK4Sj7FiN6PXo/urPfO4E7owDQYJKoZIhvcNAQELBQAw + # EzERMA8GA1UEChMIQXV0aGVsaWEwHhcNNzAwMTAxMDAwMDAwWhcNNzEwMTAxMDAw + # MDAwWjATMREwDwYDVQQKEwhBdXRoZWxpYTCCASIwDQYJKoZIhvcNAQEBBQADggEP + # ADCCAQoCggEBAPKv3pSyP4ozGEiVLJ14dIWFCEGEgq7WUMI0SZZqQA2ID0L59U/Q + # /Usyy7uC9gfMUzODTpANtkOjFQcQAsxlR1FOjVBrX5QgjSvXwbQn3DtwMA7XWSl6 + # LuYx2rBYSlMSN5UZQm/RxMtXfLK2b51WgEEYDFi+nECSqKzR4R54eOPkBEWRfvuY + # 91AMjlhpivg8e4JWkq4LVQUKbmiFYwIdK8XQiN4blY9WwXwJFYs5sQ/UYMwBFi0H + # kWOh7GEjfxgoUOPauIueZSMSlQp7zqAH39N0ZSYb6cS0Npj57QoWZSY3ak87ebcR + # Nf4rCvZLby7LoN7qYCKxmCaDD3x2+NYpWH8CAwEAAaM1MDMwDgYDVR0PAQH/BAQD + # AgWgMBMGA1UdJQQMMAoGCCsGAQUFBwMBMAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcN + # AQELBQADggEBAHSITqIQSNzonFl3DzxHPEzr2hp6peo45buAAtu8FZHoA+U7Icfh + # /ZXjPg7Xz+hgFwM/DTNGXkMWacQA/PaNWvZspgRJf2AXvNbMSs2UQODr7Tbv+Fb4 + # lyblmMUNYFMCFVAMU0eIxXAFq2qcwv8UMcQFT0Z/35s6PVOakYnAGGQjTfp5Ljuq + # wsdc/xWmM0cHWube6sdRRUD7SY20KU/kWzl8iFO0VbSSrDf1AlEhnLEkp1SPaxXg + # OdBnl98MeoramNiJ7NT6Jnyb3zZ578fjaWfThiBpagItI8GZmG4s4Ovh2JbheN8i + # ZsjNr9jqHTjhyLVbDRlmJzcqoj4JhbKs6/I^invalid DO NOT USE= + # -----END CERTIFICATE----- + # -----BEGIN CERTIFICATE----- + # MIIDBDCCAeygAwIBAgIRALJsPg21kA0zY4F1wUCIuoMwDQYJKoZIhvcNAQELBQAw + # EzERMA8GA1UEChMIQXV0aGVsaWEwHhcNNzAwMTAxMDAwMDAwWhcNNzEwMTAxMDAw + # MDAwWjATMREwDwYDVQQKEwhBdXRoZWxpYTCCASIwDQYJKoZIhvcNAQEBBQADggEP + # ADCCAQoCggEBAMXHBvVxUzYk0u34/DINMSF+uiOekKOAjOrC6Mi9Ww8ytPVO7t2S + # zfTvM+XnEJqkFQFgimERfG/eGhjF9XIEY6LtnXe8ATvOK4nTwdufzBaoeQu3Gd50 + # 5VXr6OHRo//ErrGvFXwP3g8xLePABsi/fkH3oDN+ztewOBMDzpd+KgTrk8ysv2ou + # kNRMKFZZqASvCgv0LD5KWvUCnL6wgf1oTXG7aztduA4oSkUP321GpOmBC5+5ElU7 + # ysoRzvD12o9QJ/IfEaulIX06w9yVMo60C/h6A3U6GdkT1SiyTIqR7v7KU/IWd/Qi + # Lfftcj91VhCmJ73Meff2e2S2PrpjdXbG5FMCAwEAAaNTMFEwDgYDVR0PAQH/BAQD + # AgKkMA8GA1UdJQQIMAYGBFUdJQAwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU + # Z7AtA3mzFc0InSBA5fiMfeLXA3owDQYJKoZIhvcNAQELBQADggEBAEE5hm1mtlk/ + # kviCoHH4evbpw7rxPxDftIQlqYTtvMM4eWY/6icFoSZ4fUHEWYyps8SsPu/8f2tf + # 71LGgZn0FdHi1QU2H8m0HHK7TFw+5Q6RLrLdSyk0PItJ71s9en7r8pX820nAFEHZ + # HkOSfJZ7B5hFgUDkMtVM6bardXAhoqcMk4YCU96e9d4PB4eI+xGc+mNuYvov3RbB + # D0s8ICyojeyPVLerz4wHjZu68Z5frAzhZ68YbzNs8j2fIBKKHkHyLG1iQyF+LJVj + # 2PjCP+auJsj6fQQpMGoyGtpLcSDh+ptcTngUD8JsWipzTCjmaNqdPHAOYmcgtf4b + # qocikt3WAdU^invalid DO NOT USE= + # -----END CERTIFICATE----- + + ## The private key used with the certificate_chain if the server requests TLS Client Authentication + ## i.e. Mutual TLS. + # private_key: | + # -----BEGIN RSA PRIVATE KEY----- + # MIIEpAIBAAKCAQEA8q/elLI/ijMYSJUsnXh0hYUIQYSCrtZQwjRJlmpADYgPQvn1 + # T9D9SzLLu4L2B8xTM4NOkA22Q6MVBxACzGVHUU6NUGtflCCNK9fBtCfcO3AwDtdZ + # KXou5jHasFhKUxI3lRlCb9HEy1d8srZvnVaAQRgMWL6cQJKorNHhHnh44+QERZF+ + # +5j3UAyOWGmK+Dx7glaSrgtVBQpuaIVjAh0rxdCI3huVj1bBfAkVizmxD9RgzAEW + # LQeRY6HsYSN/GChQ49q4i55lIxKVCnvOoAff03RlJhvpxLQ2mPntChZlJjdqTzt5 + # txE1/isK9ktvLsug3upgIrGYJoMPfHb41ilYfwIDAQABAoIBAQDTOdFf2JjHH1um + # aPgRAvNf9v7Nj5jytaRKs5nM6iNf46ls4QPreXnMhqSeSwj6lpNgBYxOgzC9Q+cc + # Y4ob/paJJPaIJTxmP8K/gyWcOQlNToL1l+eJ20eQoZm23NGr5fIsunSBwLEpTrdB + # ENqqtcwhW937K8Pxy/Q1nuLyU2bc6Tn/ivLozc8n27dpQWWKh8537VY7ancIaACr + # LJJLYxKqhQpjtBWAyCDvZQirnAOm9KnvIHaGXIswCZ4Xbsu0Y9NL+woARPyRVQvG + # jfxy4EmO9s1s6y7OObSukwKDSNihAKHx/VIbvVWx8g2Lv5fGOa+J2Y7o9Qurs8t5 + # BQwMTt0BAoGBAPUw5Z32EszNepAeV3E2mPFUc5CLiqAxagZJuNDO2pKtyN29ETTR + # Ma4O1cWtGb6RqcNNN/Iukfkdk27Q5nC9VJSUUPYelOLc1WYOoUf6oKRzE72dkMQV + # R4bf6TkjD+OVR17fAfkswkGahZ5XA7j48KIQ+YC4jbnYKSxZTYyKPjH/AoGBAP1i + # tqXt36OVlP+y84wWqZSjMelBIVa9phDVGJmmhz3i1cMni8eLpJzWecA3pfnG6Tm9 + # ze5M4whASleEt+M00gEvNaU9ND+z0wBfi+/DwJYIbv8PQdGrBiZFrPhTPjGQUldR + # lXccV2meeLZv7TagVxSi3DO6dSJfSEHyemd5j9mBAoGAX8Hv+0gOQZQCSOTAq8Nx + # 6dZcp9gHlNaXnMsP9eTDckOSzh636JPGvj6m+GPJSSbkURUIQ3oyokMNwFqvlNos + # fTaLhAOfjBZI9WnDTTQxpugWjphJ4HqbC67JC/qIiw5S6FdaEvGLEEoD4zoChywZ + # 9oGAn+fz2d/0/JAH/FpFPgsCgYEAp/ipZgPzziiZ9ov1wbdAQcWRj7RaWnssPFpX + # jXwEiXT3CgEMO4MJ4+KWIWOChrti3qFBg6i6lDyyS6Qyls7sLFbUdC7HlTcrOEMe + # rBoTcCI1GqZNlqWOVQ65ZIEiaI7o1vPBZo2GMQEZuq8mDKFsOMThvvTrM5cAep84 + # n6HJR4ECgYABWcbsSnr0MKvVth/inxjbKapbZnp2HUCuw87Ie5zK2Of/tbC20wwk + # yKw3vrGoE3O1t1g2m2tn8UGGASeZ842jZWjIODdSi5+icysQGuULKt86h/woz2SQ + # 27GoE2i5mh6Yez6VAYbUuns3FcwIsMyWLq043Tu2DNkx9ijOOAuQzw^invalid.. + # DO NOT USE== + # -----END RSA PRIVATE KEY----- + +## +## Notification Provider +## +## Notifications are sent to users when they require a password reset, a Webauthn registration or a TOTP registration. +## The available providers are: filesystem, smtp. You must use only one of these providers. +notifier: + ## You can disable the notifier startup check by setting this to true. + disable_startup_check: false + + ## + ## File System (Notification Provider) + ## + ## Important: Kubernetes (or HA) users must read https://www.authelia.com/t/statelessness + ## +# filesystem: +# filename: /config/notification.txt + + ## + ## SMTP (Notification Provider) + ## + ## Use a SMTP server for sending notifications. Authelia uses the PLAIN or LOGIN methods to authenticate. + ## [Security] By default Authelia will: + ## - force all SMTP connections over TLS including unauthenticated connections + ## - use the disable_require_tls boolean value to disable this requirement + ## (only works for unauthenticated connections) + ## - validate the SMTP server x509 certificate during the TLS handshake against the hosts trusted certificates + ## (configure in tls section) + smtp: + ## The SMTP host to connect to. + host: smtp.gmail.com + + ## The port to connect to the SMTP host on. + port: 587 + + ## The connection timeout. + timeout: 5s + + ## The username used for SMTP authentication. + username: [emailaddressrelay]@gmail.com + + ## The password used for SMTP authentication. + ## Can also be set using a secret: https://www.authelia.com/c/secrets + password: REDACTED + + ## The sender is used to is used for the MAIL FROM command and the FROM header. + ## If this is not defined and the username is an email, we use the username as this value. This can either be just + ## an email address or the RFC5322 'Name ' format. + sender: "Authelia " + + ## HELO/EHLO Identifier. Some SMTP Servers may reject the default of localhost. + identifier: [domain.tld] + + ## Subject configuration of the emails sent. {title} is replaced by the text from the notifier. + subject: "[Authelia] {title}" + + ## This address is used during the startup check to verify the email configuration is correct. + ## It's not important what it is except if your email server only allows local delivery. + startup_check_address: [emailaddressrelay]@gmail.com + + ## By default we require some form of TLS. This disables this check though is not advised. + # disable_require_tls: false + + ## Disables sending HTML formatted emails. + # disable_html_emails: false + + tls: + ## The server subject name to check the servers certificate against during the validation process. + ## This option is not required if the certificate has a SAN which matches the host option. + server_name: smtp.gmail.com + + ## Skip verifying the server certificate entirely. In preference to setting this we strongly recommend you add the + ## certificate or the certificate of the authority signing the certificate to the certificates directory which is + ## defined by the `certificates_directory` option at the top of the configuration. + ## It's important to note the public key should be added to the directory, not the private key. + ## This option is strongly discouraged but may be useful in some self-signed situations where validation is not + ## important to the administrator. + # skip_verify: false + + ## Minimum TLS version for the connection. + # minimum_version: TLS1.2 + + ## Maximum TLS version for the connection. + # maximum_version: TLS1.3 + + ## The certificate chain used with the private_key if the server requests TLS Client Authentication + ## i.e. Mutual TLS. + # certificate_chain: | + # -----BEGIN CERTIFICATE----- + # MIIC5jCCAc6gAwIBAgIRAK4Sj7FiN6PXo/urPfO4E7owDQYJKoZIhvcNAQELBQAw + # EzERMA8GA1UEChMIQXV0aGVsaWEwHhcNNzAwMTAxMDAwMDAwWhcNNzEwMTAxMDAw + # MDAwWjATMREwDwYDVQQKEwhBdXRoZWxpYTCCASIwDQYJKoZIhvcNAQEBBQADggEP + # ADCCAQoCggEBAPKv3pSyP4ozGEiVLJ14dIWFCEGEgq7WUMI0SZZqQA2ID0L59U/Q + # /Usyy7uC9gfMUzODTpANtkOjFQcQAsxlR1FOjVBrX5QgjSvXwbQn3DtwMA7XWSl6 + # LuYx2rBYSlMSN5UZQm/RxMtXfLK2b51WgEEYDFi+nECSqKzR4R54eOPkBEWRfvuY + # 91AMjlhpivg8e4JWkq4LVQUKbmiFYwIdK8XQiN4blY9WwXwJFYs5sQ/UYMwBFi0H + # kWOh7GEjfxgoUOPauIueZSMSlQp7zqAH39N0ZSYb6cS0Npj57QoWZSY3ak87ebcR + # Nf4rCvZLby7LoN7qYCKxmCaDD3x2+NYpWH8CAwEAAaM1MDMwDgYDVR0PAQH/BAQD + # AgWgMBMGA1UdJQQMMAoGCCsGAQUFBwMBMAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcN + # AQELBQADggEBAHSITqIQSNzonFl3DzxHPEzr2hp6peo45buAAtu8FZHoA+U7Icfh + # /ZXjPg7Xz+hgFwM/DTNGXkMWacQA/PaNWvZspgRJf2AXvNbMSs2UQODr7Tbv+Fb4 + # lyblmMUNYFMCFVAMU0eIxXAFq2qcwv8UMcQFT0Z/35s6PVOakYnAGGQjTfp5Ljuq + # wsdc/xWmM0cHWube6sdRRUD7SY20KU/kWzl8iFO0VbSSrDf1AlEhnLEkp1SPaxXg + # OdBnl98MeoramNiJ7NT6Jnyb3zZ578fjaWfThiBpagItI8GZmG4s4Ovh2JbheN8i + # ZsjNr9jqHTjhyLVbDRlmJzcqoj4JhbKs6/I^invalid DO NOT USE= + # -----END CERTIFICATE----- + # -----BEGIN CERTIFICATE----- + # MIIDBDCCAeygAwIBAgIRALJsPg21kA0zY4F1wUCIuoMwDQYJKoZIhvcNAQELBQAw + # EzERMA8GA1UEChMIQXV0aGVsaWEwHhcNNzAwMTAxMDAwMDAwWhcNNzEwMTAxMDAw + # MDAwWjATMREwDwYDVQQKEwhBdXRoZWxpYTCCASIwDQYJKoZIhvcNAQEBBQADggEP + # ADCCAQoCggEBAMXHBvVxUzYk0u34/DINMSF+uiOekKOAjOrC6Mi9Ww8ytPVO7t2S + # zfTvM+XnEJqkFQFgimERfG/eGhjF9XIEY6LtnXe8ATvOK4nTwdufzBaoeQu3Gd50 + # 5VXr6OHRo//ErrGvFXwP3g8xLePABsi/fkH3oDN+ztewOBMDzpd+KgTrk8ysv2ou + # kNRMKFZZqASvCgv0LD5KWvUCnL6wgf1oTXG7aztduA4oSkUP321GpOmBC5+5ElU7 + # ysoRzvD12o9QJ/IfEaulIX06w9yVMo60C/h6A3U6GdkT1SiyTIqR7v7KU/IWd/Qi + # Lfftcj91VhCmJ73Meff2e2S2PrpjdXbG5FMCAwEAAaNTMFEwDgYDVR0PAQH/BAQD + # AgKkMA8GA1UdJQQIMAYGBFUdJQAwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU + # Z7AtA3mzFc0InSBA5fiMfeLXA3owDQYJKoZIhvcNAQELBQADggEBAEE5hm1mtlk/ + # kviCoHH4evbpw7rxPxDftIQlqYTtvMM4eWY/6icFoSZ4fUHEWYyps8SsPu/8f2tf + # 71LGgZn0FdHi1QU2H8m0HHK7TFw+5Q6RLrLdSyk0PItJ71s9en7r8pX820nAFEHZ + # HkOSfJZ7B5hFgUDkMtVM6bardXAhoqcMk4YCU96e9d4PB4eI+xGc+mNuYvov3RbB + # D0s8ICyojeyPVLerz4wHjZu68Z5frAzhZ68YbzNs8j2fIBKKHkHyLG1iQyF+LJVj + # 2PjCP+auJsj6fQQpMGoyGtpLcSDh+ptcTngUD8JsWipzTCjmaNqdPHAOYmcgtf4b + # qocikt3WAdU^invalid DO NOT USE= + # -----END CERTIFICATE----- + + ## The private key used with the certificate_chain if the server requests TLS Client Authentication + ## i.e. Mutual TLS. + # private_key: | + # -----BEGIN RSA PRIVATE KEY----- + # MIIEpAIBAAKCAQEA8q/elLI/ijMYSJUsnXh0hYUIQYSCrtZQwjRJlmpADYgPQvn1 + # T9D9SzLLu4L2B8xTM4NOkA22Q6MVBxACzGVHUU6NUGtflCCNK9fBtCfcO3AwDtdZ + # KXou5jHasFhKUxI3lRlCb9HEy1d8srZvnVaAQRgMWL6cQJKorNHhHnh44+QERZF+ + # +5j3UAyOWGmK+Dx7glaSrgtVBQpuaIVjAh0rxdCI3huVj1bBfAkVizmxD9RgzAEW + # LQeRY6HsYSN/GChQ49q4i55lIxKVCnvOoAff03RlJhvpxLQ2mPntChZlJjdqTzt5 + # txE1/isK9ktvLsug3upgIrGYJoMPfHb41ilYfwIDAQABAoIBAQDTOdFf2JjHH1um + # aPgRAvNf9v7Nj5jytaRKs5nM6iNf46ls4QPreXnMhqSeSwj6lpNgBYxOgzC9Q+cc + # Y4ob/paJJPaIJTxmP8K/gyWcOQlNToL1l+eJ20eQoZm23NGr5fIsunSBwLEpTrdB + # ENqqtcwhW937K8Pxy/Q1nuLyU2bc6Tn/ivLozc8n27dpQWWKh8537VY7ancIaACr + # LJJLYxKqhQpjtBWAyCDvZQirnAOm9KnvIHaGXIswCZ4Xbsu0Y9NL+woARPyRVQvG + # jfxy4EmO9s1s6y7OObSukwKDSNihAKHx/VIbvVWx8g2Lv5fGOa+J2Y7o9Qurs8t5 + # BQwMTt0BAoGBAPUw5Z32EszNepAeV3E2mPFUc5CLiqAxagZJuNDO2pKtyN29ETTR + # Ma4O1cWtGb6RqcNNN/Iukfkdk27Q5nC9VJSUUPYelOLc1WYOoUf6oKRzE72dkMQV + # R4bf6TkjD+OVR17fAfkswkGahZ5XA7j48KIQ+YC4jbnYKSxZTYyKPjH/AoGBAP1i + # tqXt36OVlP+y84wWqZSjMelBIVa9phDVGJmmhz3i1cMni8eLpJzWecA3pfnG6Tm9 + # ze5M4whASleEt+M00gEvNaU9ND+z0wBfi+/DwJYIbv8PQdGrBiZFrPhTPjGQUldR + # lXccV2meeLZv7TagVxSi3DO6dSJfSEHyemd5j9mBAoGAX8Hv+0gOQZQCSOTAq8Nx + # 6dZcp9gHlNaXnMsP9eTDckOSzh636JPGvj6m+GPJSSbkURUIQ3oyokMNwFqvlNos + # fTaLhAOfjBZI9WnDTTQxpugWjphJ4HqbC67JC/qIiw5S6FdaEvGLEEoD4zoChywZ + # 9oGAn+fz2d/0/JAH/FpFPgsCgYEAp/ipZgPzziiZ9ov1wbdAQcWRj7RaWnssPFpX + # jXwEiXT3CgEMO4MJ4+KWIWOChrti3qFBg6i6lDyyS6Qyls7sLFbUdC7HlTcrOEMe + # rBoTcCI1GqZNlqWOVQ65ZIEiaI7o1vPBZo2GMQEZuq8mDKFsOMThvvTrM5cAep84 + # n6HJR4ECgYABWcbsSnr0MKvVth/inxjbKapbZnp2HUCuw87Ie5zK2Of/tbC20wwk + # yKw3vrGoE3O1t1g2m2tn8UGGASeZ842jZWjIODdSi5+icysQGuULKt86h/woz2SQ + # 27GoE2i5mh6Yez6VAYbUuns3FcwIsMyWLq043Tu2DNkx9ijOOAuQzw^invalid.. + # DO NOT USE== + # -----END RSA PRIVATE KEY----- + +## +## Identity Providers +## +# identity_providers: + + ## + ## OpenID Connect (Identity Provider) + ## + ## It's recommended you read the documentation before configuration of this section: + ## https://www.authelia.com/c/oidc + # oidc: + ## The hmac_secret is used to sign OAuth2 tokens (authorization code, access tokens and refresh tokens). + ## HMAC Secret can also be set using a secret: https://www.authelia.com/c/secrets + # hmac_secret: this_is_a_secret_abc123abc123abc + + ## The issuer_certificate_chain is an optional PEM encoded certificate chain. It's used in conjunction with the + ## issuer_private_key to sign JWT's. All certificates in the chain must be within the validity period, and every + ## certificate included must be signed by the certificate immediately after it if provided. + # issuer_certificate_chain: | + # -----BEGIN CERTIFICATE----- + # MIIC5jCCAc6gAwIBAgIRAK4Sj7FiN6PXo/urPfO4E7owDQYJKoZIhvcNAQELBQAw + # EzERMA8GA1UEChMIQXV0aGVsaWEwHhcNNzAwMTAxMDAwMDAwWhcNNzEwMTAxMDAw + # MDAwWjATMREwDwYDVQQKEwhBdXRoZWxpYTCCASIwDQYJKoZIhvcNAQEBBQADggEP + # ADCCAQoCggEBAPKv3pSyP4ozGEiVLJ14dIWFCEGEgq7WUMI0SZZqQA2ID0L59U/Q + # /Usyy7uC9gfMUzODTpANtkOjFQcQAsxlR1FOjVBrX5QgjSvXwbQn3DtwMA7XWSl6 + # LuYx2rBYSlMSN5UZQm/RxMtXfLK2b51WgEEYDFi+nECSqKzR4R54eOPkBEWRfvuY + # 91AMjlhpivg8e4JWkq4LVQUKbmiFYwIdK8XQiN4blY9WwXwJFYs5sQ/UYMwBFi0H + # kWOh7GEjfxgoUOPauIueZSMSlQp7zqAH39N0ZSYb6cS0Npj57QoWZSY3ak87ebcR + # Nf4rCvZLby7LoN7qYCKxmCaDD3x2+NYpWH8CAwEAAaM1MDMwDgYDVR0PAQH/BAQD + # AgWgMBMGA1UdJQQMMAoGCCsGAQUFBwMBMAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcN + # AQELBQADggEBAHSITqIQSNzonFl3DzxHPEzr2hp6peo45buAAtu8FZHoA+U7Icfh + # /ZXjPg7Xz+hgFwM/DTNGXkMWacQA/PaNWvZspgRJf2AXvNbMSs2UQODr7Tbv+Fb4 + # lyblmMUNYFMCFVAMU0eIxXAFq2qcwv8UMcQFT0Z/35s6PVOakYnAGGQjTfp5Ljuq + # wsdc/xWmM0cHWube6sdRRUD7SY20KU/kWzl8iFO0VbSSrDf1AlEhnLEkp1SPaxXg + # OdBnl98MeoramNiJ7NT6Jnyb3zZ578fjaWfThiBpagItI8GZmG4s4Ovh2JbheN8i + # ZsjNr9jqHTjhyLVbDRlmJzcqoj4JhbKs6/I^invalid DO NOT USE= + # -----END CERTIFICATE----- + # -----BEGIN CERTIFICATE----- + # MIIDBDCCAeygAwIBAgIRALJsPg21kA0zY4F1wUCIuoMwDQYJKoZIhvcNAQELBQAw + # EzERMA8GA1UEChMIQXV0aGVsaWEwHhcNNzAwMTAxMDAwMDAwWhcNNzEwMTAxMDAw + # MDAwWjATMREwDwYDVQQKEwhBdXRoZWxpYTCCASIwDQYJKoZIhvcNAQEBBQADggEP + # ADCCAQoCggEBAMXHBvVxUzYk0u34/DINMSF+uiOekKOAjOrC6Mi9Ww8ytPVO7t2S + # zfTvM+XnEJqkFQFgimERfG/eGhjF9XIEY6LtnXe8ATvOK4nTwdufzBaoeQu3Gd50 + # 5VXr6OHRo//ErrGvFXwP3g8xLePABsi/fkH3oDN+ztewOBMDzpd+KgTrk8ysv2ou + # kNRMKFZZqASvCgv0LD5KWvUCnL6wgf1oTXG7aztduA4oSkUP321GpOmBC5+5ElU7 + # ysoRzvD12o9QJ/IfEaulIX06w9yVMo60C/h6A3U6GdkT1SiyTIqR7v7KU/IWd/Qi + # Lfftcj91VhCmJ73Meff2e2S2PrpjdXbG5FMCAwEAAaNTMFEwDgYDVR0PAQH/BAQD + # AgKkMA8GA1UdJQQIMAYGBFUdJQAwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU + # Z7AtA3mzFc0InSBA5fiMfeLXA3owDQYJKoZIhvcNAQELBQADggEBAEE5hm1mtlk/ + # kviCoHH4evbpw7rxPxDftIQlqYTtvMM4eWY/6icFoSZ4fUHEWYyps8SsPu/8f2tf + # 71LGgZn0FdHi1QU2H8m0HHK7TFw+5Q6RLrLdSyk0PItJ71s9en7r8pX820nAFEHZ + # HkOSfJZ7B5hFgUDkMtVM6bardXAhoqcMk4YCU96e9d4PB4eI+xGc+mNuYvov3RbB + # D0s8ICyojeyPVLerz4wHjZu68Z5frAzhZ68YbzNs8j2fIBKKHkHyLG1iQyF+LJVj + # 2PjCP+auJsj6fQQpMGoyGtpLcSDh+ptcTngUD8JsWipzTCjmaNqdPHAOYmcgtf4b + # qocikt3WAdU^invalid DO NOT USE= + # -----END CERTIFICATE----- + + ## The issuer_private_key is used to sign the JWT forged by OpenID Connect. + ## Issuer Private Key can also be set using a secret: https://www.authelia.com/c/secrets + # issuer_private_key: | + # -----BEGIN RSA PRIVATE KEY----- + # MIIEpAIBAAKCAQEA8q/elLI/ijMYSJUsnXh0hYUIQYSCrtZQwjRJlmpADYgPQvn1 + # T9D9SzLLu4L2B8xTM4NOkA22Q6MVBxACzGVHUU6NUGtflCCNK9fBtCfcO3AwDtdZ + # KXou5jHasFhKUxI3lRlCb9HEy1d8srZvnVaAQRgMWL6cQJKorNHhHnh44+QERZF+ + # +5j3UAyOWGmK+Dx7glaSrgtVBQpuaIVjAh0rxdCI3huVj1bBfAkVizmxD9RgzAEW + # LQeRY6HsYSN/GChQ49q4i55lIxKVCnvOoAff03RlJhvpxLQ2mPntChZlJjdqTzt5 + # txE1/isK9ktvLsug3upgIrGYJoMPfHb41ilYfwIDAQABAoIBAQDTOdFf2JjHH1um + # aPgRAvNf9v7Nj5jytaRKs5nM6iNf46ls4QPreXnMhqSeSwj6lpNgBYxOgzC9Q+cc + # Y4ob/paJJPaIJTxmP8K/gyWcOQlNToL1l+eJ20eQoZm23NGr5fIsunSBwLEpTrdB + # ENqqtcwhW937K8Pxy/Q1nuLyU2bc6Tn/ivLozc8n27dpQWWKh8537VY7ancIaACr + # LJJLYxKqhQpjtBWAyCDvZQirnAOm9KnvIHaGXIswCZ4Xbsu0Y9NL+woARPyRVQvG + # jfxy4EmO9s1s6y7OObSukwKDSNihAKHx/VIbvVWx8g2Lv5fGOa+J2Y7o9Qurs8t5 + # BQwMTt0BAoGBAPUw5Z32EszNepAeV3E2mPFUc5CLiqAxagZJuNDO2pKtyN29ETTR + # Ma4O1cWtGb6RqcNNN/Iukfkdk27Q5nC9VJSUUPYelOLc1WYOoUf6oKRzE72dkMQV + # R4bf6TkjD+OVR17fAfkswkGahZ5XA7j48KIQ+YC4jbnYKSxZTYyKPjH/AoGBAP1i + # tqXt36OVlP+y84wWqZSjMelBIVa9phDVGJmmhz3i1cMni8eLpJzWecA3pfnG6Tm9 + # ze5M4whASleEt+M00gEvNaU9ND+z0wBfi+/DwJYIbv8PQdGrBiZFrPhTPjGQUldR + # lXccV2meeLZv7TagVxSi3DO6dSJfSEHyemd5j9mBAoGAX8Hv+0gOQZQCSOTAq8Nx + # 6dZcp9gHlNaXnMsP9eTDckOSzh636JPGvj6m+GPJSSbkURUIQ3oyokMNwFqvlNos + # fTaLhAOfjBZI9WnDTTQxpugWjphJ4HqbC67JC/qIiw5S6FdaEvGLEEoD4zoChywZ + # 9oGAn+fz2d/0/JAH/FpFPgsCgYEAp/ipZgPzziiZ9ov1wbdAQcWRj7RaWnssPFpX + # jXwEiXT3CgEMO4MJ4+KWIWOChrti3qFBg6i6lDyyS6Qyls7sLFbUdC7HlTcrOEMe + # rBoTcCI1GqZNlqWOVQ65ZIEiaI7o1vPBZo2GMQEZuq8mDKFsOMThvvTrM5cAep84 + # n6HJR4ECgYABWcbsSnr0MKvVth/inxjbKapbZnp2HUCuw87Ie5zK2Of/tbC20wwk + # yKw3vrGoE3O1t1g2m2tn8UGGASeZ842jZWjIODdSi5+icysQGuULKt86h/woz2SQ + # 27GoE2i5mh6Yez6VAYbUuns3FcwIsMyWLq043Tu2DNkx9ijOOAuQzw^invalid.. + # DO NOT USE== + # -----END RSA PRIVATE KEY----- + + ## The lifespans configure the expiration for these token types. + # access_token_lifespan: 1h + # authorize_code_lifespan: 1m + # id_token_lifespan: 1h + # refresh_token_lifespan: 90m + + ## Enables additional debug messages. + # enable_client_debug_messages: false + + ## SECURITY NOTICE: It's not recommended changing this option and values below 8 are strongly discouraged. + # minimum_parameter_entropy: 8 + + ## SECURITY NOTICE: It's not recommended changing this option, and highly discouraged to have it set to 'never' + ## for security reasons. + # enforce_pkce: public_clients_only + + ## Cross-Origin Resource Sharing (CORS) settings. + # cors: + ## List of endpoints in addition to the metadata endpoints to permit cross-origin requests on. + # endpoints: + # - authorization + # - token + # - revocation + # - introspection + # - userinfo + + ## List of allowed origins. + ## Any origin with https is permitted unless this option is configured or the + ## allowed_origins_from_client_redirect_uris option is enabled. + # allowed_origins: + # - https://example.com + + ## Automatically adds the origin portion of all redirect URI's on all clients to the list of allowed_origins, + ## provided they have the scheme http or https and do not have the hostname of localhost. + # allowed_origins_from_client_redirect_uris: false + + ## Clients is a list of known clients and their configuration. + # clients: + # - + ## The ID is the OpenID Connect ClientID which is used to link an application to a configuration. + # id: myapp + + ## The description to show to users when they end up on the consent screen. Defaults to the ID above. + # description: My Application + + ## The client secret is a shared secret between Authelia and the consumer of this client. + # secret: this_is_a_secret + + ## Sector Identifiers are occasionally used to generate pairwise subject identifiers. In most cases this is not + ## necessary. Read the documentation for more information. + ## The subject identifier must be the host component of a URL, which is a domain name with an optional port. + # sector_identifier: example.com + + ## Sets the client to public. This should typically not be set, please see the documentation for usage. + # public: false + + ## The policy to require for this client; one_factor or two_factor. + # authorization_policy: two_factor + + ## The consent mode controls how consent is obtained. + # consent_mode: auto + + ## This value controls the duration a consent on this client remains remembered when the consent mode is + ## configured as 'auto' or 'pre-configured'. + # pre_configured_consent_duration: 1w + + ## Audience this client is allowed to request. + # audience: [] + + ## Scopes this client is allowed to request. + # scopes: + # - openid + # - groups + # - email + # - profile + + ## Redirect URI's specifies a list of valid case-sensitive callbacks for this client. + # redirect_uris: + # - https://oidc.example.com:8080/oauth2/callback + + ## Grant Types configures which grants this client can obtain. + ## It's not recommended to define this unless you know what you're doing. + # grant_types: + # - refresh_token + # - authorization_code + + ## Response Types configures which responses this client can be sent. + ## It's not recommended to define this unless you know what you're doing. + # response_types: + # - code + + ## Response Modes configures which response modes this client supports. + # response_modes: + # - form_post + # - query + # - fragment + + ## The algorithm used to sign userinfo endpoint responses for this client, either none or RS256. + # userinfo_signing_algorithm: none +... diff --git a/public/docker-compose-dpsalad.rtf b/public/docker-compose-dpsalad.rtf new file mode 100644 index 0000000..25df609 --- /dev/null +++ b/public/docker-compose-dpsalad.rtf @@ -0,0 +1,95 @@ +version: "2.1" +services: + swag: + image: lscr.io/linuxserver/swag:latest + container_name: swag + cap_add: + - NET_ADMIN + environment: + - PUID=1000 + - PGID=1000 + - TZ=America/Phoenix + - URL=[sakura.nt] + - VALIDATION=dns + - SUBDOMAINS=wildcard + - DNSPLUGIN=cloudflare + - EMAIL=[sakurant@gmail.com] + - ONLY_SUBDOMAINS=false + #- EXTRA_DOMAINS= #optional + - STAGING=false + - DOCKER_MODS=linuxserver/mods:universal-docker|linuxserver/mods:swag-auto-reload|linuxserver/mods:swag-dashboard|linuxserver/mods:swag-dbip + volumes: + - /home/[INSERT USER FOLDER HERE]/appdata/swag:/config + ports: + - 443:443 + - 80:80 + networks: + - [INSERT NETWORK NAME HERE] + restart: unless-stopped + + authelia: + container_name: authelia + image: authelia/authelia:latest + expose: + - 9091 + volumes: + - /home/[INSERT USER FOLDER HERE]/appdata/authelia:/config + networks: + - [INSERT NETWORK NAME HERE] + restart: unless-stopped + depends_on: + - redis + - mariadb + + lldap: + container_name: lldap + image: lldap/lldap:stable + ports: + # For LDAP + - "3890:3890" + # For the web front-end + - "17170:17170" + volumes: + - /home/[INSERT USER FOLDER HERE]/appdata/lldap:/data + networks: + - [INSERT NETWORK NAME HERE] + environment: + - TZ=America/Phoenix + - LLDAP_JWT_SECRET=REPLACE_WITH_RANDOM + - LLDAP_LDAP_USER_PASS=REPLACE_WITH_PASSWORD + - LLDAP_LDAP_BASE_DN=dc=sakura,dc=nt + + redis: + container_name: redis + image: bitnami/redis:latest + expose: + - 6379 + volumes: + - /home/[INSERT USER FOLDER HERE]/appdata/redis:/bitnami/ + environment: + REDIS_PASSWORD: "YOUR_REDIS_PASSWORD" + networks: + - [INSERT NETWORK NAME HERE] + restart: unless-stopped + + mariadb: + container_name: mariadb + image: linuxserver/mariadb:latest + expose: + - 3306 + volumes: + - /home/[INSERT USER FOLDER HERE]/appdata/mariadb:/config + environment: + MYSQL_ROOT_PASSWORD: "YOUR_MYSQL_ROOT_PASSWORD" + MYSQL_ROOT_USER: root + MYSQL_DATABASE: authelia + MYSQL_USER: authelia + MYSQL_PASSWORD: "YOUR_MYSQL_USER_PASSWORD" + networks: + - [INSERT NETWORK NAME HERE] + restart: unless-stopped + +networks: + [INSERT NETWORK NAME HERE]: + driver: bridge + external: true diff --git a/public/dp-salad-stack.pdf b/public/dp-salad-stack.pdf new file mode 100644 index 0000000..149ec00 Binary files /dev/null and b/public/dp-salad-stack.pdf differ diff --git a/public/lldap_config.toml.rtf b/public/lldap_config.toml.rtf new file mode 100644 index 0000000..3353033 --- /dev/null +++ b/public/lldap_config.toml.rtf @@ -0,0 +1,148 @@ +## Default configuration for Docker. +## All the values can be overridden through environment variables, prefixed +## with "LLDAP_". For instance, "ldap_port" can be overridden with the +## "LLDAP_LDAP_PORT" variable. + +## Tune the logging to be more verbose by setting this to be true. +## You can set it with the LLDAP_VERBOSE environment variable. +# verbose=false + +## The host address that the LDAP server will be bound to. +## To enable IPv6 support, simply switch "ldap_host" to "::": +## To only allow connections from localhost (if you want to restrict to local self-hosted services), +## change it to "127.0.0.1" ("::1" in case of IPv6)". +ldap_host = "0.0.0.0" + +## The port on which to have the LDAP server. +ldap_port = 3890 + +## The host address that the HTTP server will be bound to. +## To enable IPv6 support, simply switch "http_host" to "::". +## To only allow connections from localhost (if you want to restrict to local self-hosted services), +## change it to "127.0.0.1" ("::1" in case of IPv6)". +http_host = "0.0.0.0" + +## The port on which to have the HTTP server, for user login and +## administration. +http_port = 17170 + +## The public URL of the server, for password reset links. +#http_url = "http://localhost" + +## Random secret for JWT signature. +## This secret should be random, and should be shared with application +## servers that need to consume the JWTs. +## Changing this secret will invalidate all user sessions and require +## them to re-login. +## You should probably set it through the LLDAP_JWT_SECRET environment +## variable from a secret ".env" file. +## This can also be set from a file's contents by specifying the file path +## in the LLDAP_JWT_SECRET_FILE environment variable +## You can generate it with (on linux): +## LC_ALL=C tr -dc 'A-Za-z0-9!#%&'\''()*+,-./:;<=>?@[\]^_{|}~' . +#from="LLDAP Admin " +## Same for reply-to, optional. +#reply_to="Do not reply " + +## Options to configure LDAPS. +## To set these options from environment variables, use the following format +## (example with "port"): LLDAP_LDAPS_OPTIONS__PORT +[ldaps_options] +## Whether to enable LDAPS. +#enabled=true +## Port on which to listen. +#port=6360 +## Certificate file. +#cert_file="/data/cert.pem" +## Certificate key file. +#key_file="/data/key.pem" diff --git a/public/robots.txt b/public/robots.txt new file mode 100644 index 0000000..b3e508a --- /dev/null +++ b/public/robots.txt @@ -0,0 +1,2 @@ +User-agent: * +Disallow:/ \ No newline at end of file diff --git a/public/saladicon.png b/public/saladicon.png new file mode 100644 index 0000000..bbe3793 Binary files /dev/null and b/public/saladicon.png differ diff --git a/unocss.config.ts b/unocss.config.ts new file mode 100644 index 0000000..e204f34 --- /dev/null +++ b/unocss.config.ts @@ -0,0 +1,16 @@ +import { defineConfig, presetUno, presetAttributify, presetIcons } from "unocss"; + +export default defineConfig({ + presets: [ + presetUno(), + presetAttributify(), + presetIcons({ + scale: 1.2, + extraProperties: { + display: "inline-block", + "vertical-align": "middle", + }, + warn: true, + }), + ], +}); diff --git a/x11-guide.md b/x11-guide.md new file mode 100644 index 0000000..43abc38 --- /dev/null +++ b/x11-guide.md @@ -0,0 +1,74 @@ +--- +title: X11-Guide +--- + +# Windows Setup: + +## Windows X11 Window Manager Client/Server + +Installation: + +1. Install [VCXSRV](https://sourceforge.net/projects/vcxsrv/) on your Windows machine. +2. Follow the install instructions until able to close. + +### Running the X11 Local Server (aka the client that connects to the real X11 server) + +1. Locate the newly installed XLaunch application, open it. +2. You'll want to modify the display settings as follows: + - Select *Multiple windows* for the program displays, hit next + - Select the *Start no client* option on the next page, hit next. + - Options on this page are optional, you **DO NOT** want the *Disable access control* selected on this page. + - Hit next. + - Click the *Save configuration* button on this page, save this config somewhere you won't forget about it. + - Click finish. + - Allow the access to the network if Windows Defender Firewall asks. + - Congratulations, you've setup the local X11 server! +3. Make sure the XLaunch application is in the system tray before running Putty OR Terminal SSH + +### Connecting to the 'domain.tld' X11 Server + +1. First, verify the XLaunch application is running in the System Tray, then follow the instructions below based on your preferred SSH method. + +### PuTTY Instructions (including setting up a profile for easier management) + +1. Highly recommend the use of a profile if you are going to use PuTTY, as you can save/load the config up really quick instead of having to put in these values every time. +2. Enter in the hostname, (this is optional if making a profile, as the IP address is dynamic) +3. In the connection category, under the data subcategory, the auto-login username can be set if using a profile. +4. Expand the SSH subcategory (in connection) and set the credentials if using a profile to the private key (if made) +5. Now, click on X11 subcategory (in connection) and click the checkbox for 'Enable X11 forwarding' +6. Set the X Display Location textbox to the value '127.0.0.1:0' (no quotes). +7. Return to the Session category, and type in a name for the saved session, then hit the save button. Now, all of these changes can be loaded instead of put in each time. +8. Now, type in the IP address of the 'domain.tld' and hit the 'Open' button. +9. If you'd like to verify the X11 connectivity, type 'xclock' into the terminal. This will make a little analog clock appear in a separate window. + +### Windows Powershell Instructions + +1. You'll want to set a variable in the command prompt, run `$env:DISPLAY="127.0.0.1:0"` (exactly as written) to set the X Window Manager as the display output. +2. Use the command 'ssh -X username@domain.tld' to connect, replacing username with your username, and domain.tld with the current dynIP. +3. If you'd like to verify the X11 connectivity, type 'xclock' into the terminal. This will make a little analog clock appear in a separate window. + +### Windows Command Prompt Instructions (a.k.a. CMD) + +1. You'll want to set a variable in the command prompt, run `set DISPLAY=127.0.0.1:0` to set the X Window Manager as the display output. +2. Use the command 'ssh -X username@domain.tld' to connect, replacing username with your username, and domain.tld with the current dynIP. +3. If you'd like to verify the X11 connectivity, type 'xclock' into the terminal. This will make a little analog clock appear in a separate window. + +# MacOS Setup: + +## MacOS X11 Window Manager Client/Server + +Installation: + +1. Install XQuartz ([https://www.xquartz.org/](https://www.xquartz.org/)) using the MacOS pkg file. +2. Follow the install instructions until able to close (you'll have to logout to complete install). + +### Running the X11 Local Server on Mac (aka the client that connects to the real X11 server) + +1. Locate the newly installed XQuartz application, open it, this opens an xtem window. +2. You'll want to use this window to connect over SSH. + +### Connecting to the 'domain.tld' X11 Server on Mac + +1. Using the xterm window, run the command `set DISPLAY=127.0.0.1:0` to set the X11 forwarder to the correct display set. +2. Run the command 'ssh -X username@domain.tld' where username is replaced by your username and domain.tld is replaced with the current IP address of the domain.tld server. +3. Run the 'xclock' command to verify connectivity.