diff --git a/README.md b/README.md
index 68db3db..1f6d85b 100644
--- a/README.md
+++ b/README.md
@@ -8,6 +8,12 @@
- Optional security UI for quick bootstrapping (Blazor, and components in auto mode).
- **Designed to manage subscriptions and multi-tenants.**
+## News
+
+SvelteKit Frontend added. (not working in Aspire with fnm), so:
+
+`npm install, npm run dev in svelte-link-ui folder`
+
## Goal
This project allows you to choose any OAuth provider and remain independent in terms of your security design. You can add any frontend (Blazor, Next.js, SvelteKit) or backend APIs in front or behind this security layer. For a full SPA, you can modify Yarp to be a full BFF (Backend for Frontend).
diff --git a/UbikLink.AppHost/Program.cs b/UbikLink.AppHost/Program.cs
index 39fce8f..1817345 100644
--- a/UbikLink.AppHost/Program.cs
+++ b/UbikLink.AppHost/Program.cs
@@ -29,7 +29,7 @@
var serviceBus = builder.AddConnectionString("messaging");
//RabbitMQ (local)
-var rabbitmq = builder.AddRabbitMQ("ubiklink-rabbitmq", rabbitUser, rabbitPassword)
+var rabbitmq = builder.AddRabbitMQ("ubiklink-rabbitmq", rabbitUser, rabbitPassword, 58842)
.WithManagementPlugin()
.WithLifetime(ContainerLifetime.Persistent);
@@ -42,7 +42,7 @@
//var cache = builder.AddAzureRedis("cache");
//Redis cache (local)
-var cache = builder.AddRedis("cache")
+var cache = builder.AddRedis("cache", 6379)
.WithLifetime(ContainerLifetime.Persistent);
//Security API
@@ -101,4 +101,11 @@
.WithEnvironment("Messaging__RabbitUser", rabbitUser)
.WithEnvironment("Messaging__RabbitPassword", rabbitPassword);
+//Add npm sevltekit project (not work with fnm.... because of path)
+//builder.AddNpmApp("svelte-ui", "../svelte-link-ui","dev")
+// .WithEnvironment("BROWSER", "none")
+// .WithHttpEndpoint(env: "PORT")
+// .WithExternalHttpEndpoints()
+// .PublishAsDockerFile();
+
await builder.Build().RunAsync();
diff --git a/UbikLink.AppHost/Properties/launchSettings.json b/UbikLink.AppHost/Properties/launchSettings.json
index b456cae..204fadc 100644
--- a/UbikLink.AppHost/Properties/launchSettings.json
+++ b/UbikLink.AppHost/Properties/launchSettings.json
@@ -2,7 +2,7 @@
"profiles": {
"https": {
"commandName": "Project",
- "launchBrowser": false,
+ "launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development",
"DOTNET_ENVIRONMENT": "Development",
diff --git a/UbikLink.AppHost/Realm/ubik-realm.json b/UbikLink.AppHost/Realm/ubik-realm.json
index aa33b1c..9ab2f35 100644
--- a/UbikLink.AppHost/Realm/ubik-realm.json
+++ b/UbikLink.AppHost/Realm/ubik-realm.json
@@ -3,7 +3,7 @@
"realm": "ubik",
"notBefore": 0,
"defaultSignatureAlgorithm": "RS256",
- "revokeRefreshToken": false,
+ "revokeRefreshToken": true,
"refreshTokenMaxReuse": 0,
"accessTokenLifespan": 660,
"accessTokenLifespanForImplicitFlow": 900,
diff --git a/UbikLink.AppHost/UbikLink.AppHost.csproj b/UbikLink.AppHost/UbikLink.AppHost.csproj
index 5db1166..c244f2e 100644
--- a/UbikLink.AppHost/UbikLink.AppHost.csproj
+++ b/UbikLink.AppHost/UbikLink.AppHost.csproj
@@ -16,6 +16,7 @@
+
diff --git a/UbikLink.Security.UI/Properties/launchSettings.json b/UbikLink.Security.UI/Properties/launchSettings.json
index bef62fa..fd98965 100644
--- a/UbikLink.Security.UI/Properties/launchSettings.json
+++ b/UbikLink.Security.UI/Properties/launchSettings.json
@@ -14,7 +14,7 @@
"https": {
"commandName": "Project",
"dotnetRunMessages": true,
- "launchBrowser": true,
+ "launchBrowser": false,
"inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}",
"applicationUrl": "https://localhost:7043;http://localhost:5076",
"environmentVariables": {
diff --git a/best-schema.png b/best-schema.png
index c293376..5125791 100644
Binary files a/best-schema.png and b/best-schema.png differ
diff --git a/svelte-link-ui/.env.local b/svelte-link-ui/.env.local
new file mode 100644
index 0000000..1c69576
--- /dev/null
+++ b/svelte-link-ui/.env.local
@@ -0,0 +1,10 @@
+OIDC_ISSUER=http://localhost:8080/realms/ubik
+OIDC_CLIENT_ID=ubik_app
+OIDC_CLIENT_SECRET=Ye6Y36ocA4SaGqYzd0HgmqMhVaM2jlkE
+OIDC_AUDIENCE=account
+OIDC_REDIRECT_URI=http://localhost:5173/login/auth/callback
+REDIS_PORT=6379
+REDIS_HOST=localhost
+BACKEND_PROXY_URL=http://localhost:5235
+TOKEN_STORE_SECRET=Ye6Y36ocA4SaGqYzd0babaHgmqMhVaM2jlkE
+RABBIT_MQ_CONNECTION=amqp://guest:guest@localhost:58842
\ No newline at end of file
diff --git a/svelte-link-ui/.gitignore b/svelte-link-ui/.gitignore
new file mode 100644
index 0000000..3b462cb
--- /dev/null
+++ b/svelte-link-ui/.gitignore
@@ -0,0 +1,23 @@
+node_modules
+
+# Output
+.output
+.vercel
+.netlify
+.wrangler
+/.svelte-kit
+/build
+
+# OS
+.DS_Store
+Thumbs.db
+
+# Env
+.env
+.env.*
+!.env.example
+!.env.test
+
+# Vite
+vite.config.js.timestamp-*
+vite.config.ts.timestamp-*
diff --git a/svelte-link-ui/.npmrc b/svelte-link-ui/.npmrc
new file mode 100644
index 0000000..b6f27f1
--- /dev/null
+++ b/svelte-link-ui/.npmrc
@@ -0,0 +1 @@
+engine-strict=true
diff --git a/svelte-link-ui/.prettierignore b/svelte-link-ui/.prettierignore
new file mode 100644
index 0000000..ab78a95
--- /dev/null
+++ b/svelte-link-ui/.prettierignore
@@ -0,0 +1,4 @@
+# Package Managers
+package-lock.json
+pnpm-lock.yaml
+yarn.lock
diff --git a/svelte-link-ui/.prettierrc b/svelte-link-ui/.prettierrc
new file mode 100644
index 0000000..e5dfc4a
--- /dev/null
+++ b/svelte-link-ui/.prettierrc
@@ -0,0 +1,16 @@
+{
+ "useTabs": true,
+ "singleQuote": true,
+ "trailingComma": "none",
+ "printWidth": 100,
+ "tailwindStylesheet": "./src/app.css",
+ "plugins": ["prettier-plugin-svelte", "prettier-plugin-tailwindcss"],
+ "overrides": [
+ {
+ "files": "*.svelte",
+ "options": {
+ "parser": "svelte"
+ }
+ }
+ ]
+}
diff --git a/svelte-link-ui/.vscode/settings.json b/svelte-link-ui/.vscode/settings.json
new file mode 100644
index 0000000..0967ef4
--- /dev/null
+++ b/svelte-link-ui/.vscode/settings.json
@@ -0,0 +1 @@
+{}
diff --git a/svelte-link-ui/README.md b/svelte-link-ui/README.md
new file mode 100644
index 0000000..bb4a0b3
--- /dev/null
+++ b/svelte-link-ui/README.md
@@ -0,0 +1,2 @@
+# sv
+
diff --git a/svelte-link-ui/eslint.config.js b/svelte-link-ui/eslint.config.js
new file mode 100644
index 0000000..aa5987f
--- /dev/null
+++ b/svelte-link-ui/eslint.config.js
@@ -0,0 +1,34 @@
+import prettier from 'eslint-config-prettier';
+import js from '@eslint/js';
+import { includeIgnoreFile } from '@eslint/compat';
+import svelte from 'eslint-plugin-svelte';
+import globals from 'globals';
+import { fileURLToPath } from 'node:url';
+import ts from 'typescript-eslint';
+const gitignorePath = fileURLToPath(new URL('./.gitignore', import.meta.url));
+
+export default ts.config(
+ includeIgnoreFile(gitignorePath),
+ js.configs.recommended,
+ ...ts.configs.recommended,
+ ...svelte.configs['flat/recommended'],
+ prettier,
+ ...svelte.configs['flat/prettier'],
+ {
+ languageOptions: {
+ globals: {
+ ...globals.browser,
+ ...globals.node
+ }
+ }
+ },
+ {
+ files: ['**/*.svelte'],
+
+ languageOptions: {
+ parserOptions: {
+ parser: ts.parser
+ }
+ }
+ }
+);
diff --git a/svelte-link-ui/package-lock.json b/svelte-link-ui/package-lock.json
new file mode 100644
index 0000000..668fd59
--- /dev/null
+++ b/svelte-link-ui/package-lock.json
@@ -0,0 +1,4314 @@
+{
+ "name": "svelte-link-ui",
+ "version": "0.0.1",
+ "lockfileVersion": 3,
+ "requires": true,
+ "packages": {
+ "": {
+ "name": "svelte-link-ui",
+ "version": "0.0.1",
+ "dependencies": {
+ "@pilcrowjs/object-parser": "^0.0.4",
+ "@tailwindcss/vite": "^4.0.7",
+ "@types/crypto-js": "^4.2.2",
+ "@types/node": "^22.13.5",
+ "arctic": "^3.3.0",
+ "bits-ui": "^1.3.2",
+ "crypto-js": "^4.2.0",
+ "guid-ts": "^1.1.2",
+ "ioredis": "^5.5.0",
+ "lucide-svelte": "^0.475.0",
+ "mode-watcher": "^0.5.1",
+ "rabbitmq-client": "^5.0.2",
+ "svelte-preprocess": "^6.0.3",
+ "tailwind-merge": "^3.0.1",
+ "tailwind-variants": "^0.3.1",
+ "tailwindcss": "^4.0.7"
+ },
+ "devDependencies": {
+ "@eslint/compat": "^1.2.5",
+ "@eslint/js": "^9.18.0",
+ "@sveltejs/adapter-auto": "^4.0.0",
+ "@sveltejs/kit": "^2.16.0",
+ "@sveltejs/vite-plugin-svelte": "^5.0.0",
+ "eslint": "^9.18.0",
+ "eslint-config-prettier": "^10.0.1",
+ "eslint-plugin-svelte": "^2.46.1",
+ "globals": "^15.14.0",
+ "prettier": "^3.5.1",
+ "prettier-plugin-svelte": "^3.3.3",
+ "prettier-plugin-tailwindcss": "^0.6.11",
+ "svelte": "^5.0.0",
+ "svelte-check": "^4.0.0",
+ "typescript": "^5.0.0",
+ "typescript-eslint": "^8.20.0",
+ "vite": "^6.0.0"
+ }
+ },
+ "node_modules/@ampproject/remapping": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz",
+ "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@jridgewell/gen-mapping": "^0.3.5",
+ "@jridgewell/trace-mapping": "^0.3.24"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@esbuild/aix-ppc64": {
+ "version": "0.24.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.24.2.tgz",
+ "integrity": "sha512-thpVCb/rhxE/BnMLQ7GReQLLN8q9qbHmI55F4489/ByVg2aQaQ6kbcLb6FHkocZzQhxc4gx0sCk0tJkKBFzDhA==",
+ "cpu": [
+ "ppc64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "aix"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/android-arm": {
+ "version": "0.24.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.24.2.tgz",
+ "integrity": "sha512-tmwl4hJkCfNHwFB3nBa8z1Uy3ypZpxqxfTQOcHX+xRByyYgunVbZ9MzUUfb0RxaHIMnbHagwAxuTL+tnNM+1/Q==",
+ "cpu": [
+ "arm"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/android-arm64": {
+ "version": "0.24.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.24.2.tgz",
+ "integrity": "sha512-cNLgeqCqV8WxfcTIOeL4OAtSmL8JjcN6m09XIgro1Wi7cF4t/THaWEa7eL5CMoMBdjoHOTh/vwTO/o2TRXIyzg==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/android-x64": {
+ "version": "0.24.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.24.2.tgz",
+ "integrity": "sha512-B6Q0YQDqMx9D7rvIcsXfmJfvUYLoP722bgfBlO5cGvNVb5V/+Y7nhBE3mHV9OpxBf4eAS2S68KZztiPaWq4XYw==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/darwin-arm64": {
+ "version": "0.24.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.24.2.tgz",
+ "integrity": "sha512-kj3AnYWc+CekmZnS5IPu9D+HWtUI49hbnyqk0FLEJDbzCIQt7hg7ucF1SQAilhtYpIujfaHr6O0UHlzzSPdOeA==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/darwin-x64": {
+ "version": "0.24.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.24.2.tgz",
+ "integrity": "sha512-WeSrmwwHaPkNR5H3yYfowhZcbriGqooyu3zI/3GGpF8AyUdsrrP0X6KumITGA9WOyiJavnGZUwPGvxvwfWPHIA==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/freebsd-arm64": {
+ "version": "0.24.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.24.2.tgz",
+ "integrity": "sha512-UN8HXjtJ0k/Mj6a9+5u6+2eZ2ERD7Edt1Q9IZiB5UZAIdPnVKDoG7mdTVGhHJIeEml60JteamR3qhsr1r8gXvg==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/freebsd-x64": {
+ "version": "0.24.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.24.2.tgz",
+ "integrity": "sha512-TvW7wE/89PYW+IevEJXZ5sF6gJRDY/14hyIGFXdIucxCsbRmLUcjseQu1SyTko+2idmCw94TgyaEZi9HUSOe3Q==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-arm": {
+ "version": "0.24.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.24.2.tgz",
+ "integrity": "sha512-n0WRM/gWIdU29J57hJyUdIsk0WarGd6To0s+Y+LwvlC55wt+GT/OgkwoXCXvIue1i1sSNWblHEig00GBWiJgfA==",
+ "cpu": [
+ "arm"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-arm64": {
+ "version": "0.24.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.24.2.tgz",
+ "integrity": "sha512-7HnAD6074BW43YvvUmE/35Id9/NB7BeX5EoNkK9obndmZBUk8xmJJeU7DwmUeN7tkysslb2eSl6CTrYz6oEMQg==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-ia32": {
+ "version": "0.24.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.24.2.tgz",
+ "integrity": "sha512-sfv0tGPQhcZOgTKO3oBE9xpHuUqguHvSo4jl+wjnKwFpapx+vUDcawbwPNuBIAYdRAvIDBfZVvXprIj3HA+Ugw==",
+ "cpu": [
+ "ia32"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-loong64": {
+ "version": "0.24.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.24.2.tgz",
+ "integrity": "sha512-CN9AZr8kEndGooS35ntToZLTQLHEjtVB5n7dl8ZcTZMonJ7CCfStrYhrzF97eAecqVbVJ7APOEe18RPI4KLhwQ==",
+ "cpu": [
+ "loong64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-mips64el": {
+ "version": "0.24.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.24.2.tgz",
+ "integrity": "sha512-iMkk7qr/wl3exJATwkISxI7kTcmHKE+BlymIAbHO8xanq/TjHaaVThFF6ipWzPHryoFsesNQJPE/3wFJw4+huw==",
+ "cpu": [
+ "mips64el"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-ppc64": {
+ "version": "0.24.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.24.2.tgz",
+ "integrity": "sha512-shsVrgCZ57Vr2L8mm39kO5PPIb+843FStGt7sGGoqiiWYconSxwTiuswC1VJZLCjNiMLAMh34jg4VSEQb+iEbw==",
+ "cpu": [
+ "ppc64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-riscv64": {
+ "version": "0.24.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.24.2.tgz",
+ "integrity": "sha512-4eSFWnU9Hhd68fW16GD0TINewo1L6dRrB+oLNNbYyMUAeOD2yCK5KXGK1GH4qD/kT+bTEXjsyTCiJGHPZ3eM9Q==",
+ "cpu": [
+ "riscv64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-s390x": {
+ "version": "0.24.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.24.2.tgz",
+ "integrity": "sha512-S0Bh0A53b0YHL2XEXC20bHLuGMOhFDO6GN4b3YjRLK//Ep3ql3erpNcPlEFed93hsQAjAQDNsvcK+hV90FubSw==",
+ "cpu": [
+ "s390x"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-x64": {
+ "version": "0.24.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.24.2.tgz",
+ "integrity": "sha512-8Qi4nQcCTbLnK9WoMjdC9NiTG6/E38RNICU6sUNqK0QFxCYgoARqVqxdFmWkdonVsvGqWhmm7MO0jyTqLqwj0Q==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/netbsd-arm64": {
+ "version": "0.24.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.24.2.tgz",
+ "integrity": "sha512-wuLK/VztRRpMt9zyHSazyCVdCXlpHkKm34WUyinD2lzK07FAHTq0KQvZZlXikNWkDGoT6x3TD51jKQ7gMVpopw==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "netbsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/netbsd-x64": {
+ "version": "0.24.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.24.2.tgz",
+ "integrity": "sha512-VefFaQUc4FMmJuAxmIHgUmfNiLXY438XrL4GDNV1Y1H/RW3qow68xTwjZKfj/+Plp9NANmzbH5R40Meudu8mmw==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "netbsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/openbsd-arm64": {
+ "version": "0.24.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.24.2.tgz",
+ "integrity": "sha512-YQbi46SBct6iKnszhSvdluqDmxCJA+Pu280Av9WICNwQmMxV7nLRHZfjQzwbPs3jeWnuAhE9Jy0NrnJ12Oz+0A==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openbsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/openbsd-x64": {
+ "version": "0.24.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.24.2.tgz",
+ "integrity": "sha512-+iDS6zpNM6EnJyWv0bMGLWSWeXGN/HTaF/LXHXHwejGsVi+ooqDfMCCTerNFxEkM3wYVcExkeGXNqshc9iMaOA==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openbsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/sunos-x64": {
+ "version": "0.24.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.24.2.tgz",
+ "integrity": "sha512-hTdsW27jcktEvpwNHJU4ZwWFGkz2zRJUz8pvddmXPtXDzVKTTINmlmga3ZzwcuMpUvLw7JkLy9QLKyGpD2Yxig==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "sunos"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/win32-arm64": {
+ "version": "0.24.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.24.2.tgz",
+ "integrity": "sha512-LihEQ2BBKVFLOC9ZItT9iFprsE9tqjDjnbulhHoFxYQtQfai7qfluVODIYxt1PgdoyQkz23+01rzwNwYfutxUQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/win32-ia32": {
+ "version": "0.24.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.24.2.tgz",
+ "integrity": "sha512-q+iGUwfs8tncmFC9pcnD5IvRHAzmbwQ3GPS5/ceCyHdjXubwQWI12MKWSNSMYLJMq23/IUCvJMS76PDqXe1fxA==",
+ "cpu": [
+ "ia32"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/win32-x64": {
+ "version": "0.24.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.24.2.tgz",
+ "integrity": "sha512-7VTgWzgMGvup6aSqDPLiW5zHaxYJGTO4OokMjIlrCtf+VpEL+cXKtCvg723iguPYI5oaUNdS+/V7OU2gvXVWEg==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@eslint-community/eslint-utils": {
+ "version": "4.4.1",
+ "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.1.tgz",
+ "integrity": "sha512-s3O3waFUrMV8P/XaF/+ZTp1X9XBZW1a4B97ZnjQF2KYWaFD2A8KyFBsrsfSjEmjn3RGWAIuvlneuZm3CUK3jbA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "eslint-visitor-keys": "^3.4.3"
+ },
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ },
+ "peerDependencies": {
+ "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0"
+ }
+ },
+ "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": {
+ "version": "3.4.3",
+ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz",
+ "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/@eslint-community/regexpp": {
+ "version": "4.12.1",
+ "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz",
+ "integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^12.0.0 || ^14.0.0 || >=16.0.0"
+ }
+ },
+ "node_modules/@eslint/compat": {
+ "version": "1.2.6",
+ "resolved": "https://registry.npmjs.org/@eslint/compat/-/compat-1.2.6.tgz",
+ "integrity": "sha512-k7HNCqApoDHM6XzT30zGoETj+D+uUcZUb+IVAJmar3u6bvHf7hhHJcWx09QHj4/a2qrKZMWU0E16tvkiAdv06Q==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "peerDependencies": {
+ "eslint": "^9.10.0"
+ },
+ "peerDependenciesMeta": {
+ "eslint": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@eslint/config-array": {
+ "version": "0.19.2",
+ "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.19.2.tgz",
+ "integrity": "sha512-GNKqxfHG2ySmJOBSHg7LxeUx4xpuCoFjacmlCoYWEbaPXLwvfIjixRI12xCQZeULksQb23uiA8F40w5TojpV7w==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@eslint/object-schema": "^2.1.6",
+ "debug": "^4.3.1",
+ "minimatch": "^3.1.2"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ }
+ },
+ "node_modules/@eslint/core": {
+ "version": "0.11.0",
+ "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.11.0.tgz",
+ "integrity": "sha512-DWUB2pksgNEb6Bz2fggIy1wh6fGgZP4Xyy/Mt0QZPiloKKXerbqq9D3SBQTlCRYOrcRPu4vuz+CGjwdfqxnoWA==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@types/json-schema": "^7.0.15"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ }
+ },
+ "node_modules/@eslint/eslintrc": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.2.0.tgz",
+ "integrity": "sha512-grOjVNN8P3hjJn/eIETF1wwd12DdnwFDoyceUJLYYdkpbwq3nLi+4fqrTAONx7XDALqlL220wC/RHSC/QTI/0w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ajv": "^6.12.4",
+ "debug": "^4.3.2",
+ "espree": "^10.0.1",
+ "globals": "^14.0.0",
+ "ignore": "^5.2.0",
+ "import-fresh": "^3.2.1",
+ "js-yaml": "^4.1.0",
+ "minimatch": "^3.1.2",
+ "strip-json-comments": "^3.1.1"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/@eslint/eslintrc/node_modules/globals": {
+ "version": "14.0.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz",
+ "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/@eslint/js": {
+ "version": "9.20.0",
+ "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.20.0.tgz",
+ "integrity": "sha512-iZA07H9io9Wn836aVTytRaNqh00Sad+EamwOVJT12GTLw1VGMFV/4JaME+JjLtr9fiGaoWgYnS54wrfWsSs4oQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ }
+ },
+ "node_modules/@eslint/object-schema": {
+ "version": "2.1.6",
+ "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.6.tgz",
+ "integrity": "sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ }
+ },
+ "node_modules/@eslint/plugin-kit": {
+ "version": "0.2.6",
+ "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.6.tgz",
+ "integrity": "sha512-+0TjwR1eAUdZtvv/ir1mGX+v0tUoR3VEPB8Up0LLJC+whRW0GgBBtpbOkg/a/U4Dxa6l5a3l9AJ1aWIQVyoWJA==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@eslint/core": "^0.11.0",
+ "levn": "^0.4.1"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ }
+ },
+ "node_modules/@floating-ui/core": {
+ "version": "1.6.9",
+ "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.6.9.tgz",
+ "integrity": "sha512-uMXCuQ3BItDUbAMhIXw7UPXRfAlOAvZzdK9BWpE60MCn+Svt3aLn9jsPTi/WNGlRUu2uI0v5S7JiIUsbsvh3fw==",
+ "license": "MIT",
+ "dependencies": {
+ "@floating-ui/utils": "^0.2.9"
+ }
+ },
+ "node_modules/@floating-ui/dom": {
+ "version": "1.6.13",
+ "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.6.13.tgz",
+ "integrity": "sha512-umqzocjDgNRGTuO7Q8CU32dkHkECqI8ZdMZ5Swb6QAM0t5rnlrN3lGo1hdpscRd3WS8T6DKYK4ephgIH9iRh3w==",
+ "license": "MIT",
+ "dependencies": {
+ "@floating-ui/core": "^1.6.0",
+ "@floating-ui/utils": "^0.2.9"
+ }
+ },
+ "node_modules/@floating-ui/utils": {
+ "version": "0.2.9",
+ "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.9.tgz",
+ "integrity": "sha512-MDWhGtE+eHw5JW7lq4qhc5yRLS11ERl1c7Z6Xd0a58DozHES6EnNNwUWbMiG4J9Cgj053Bhk8zvlhFYKVhULwg==",
+ "license": "MIT"
+ },
+ "node_modules/@humanfs/core": {
+ "version": "0.19.1",
+ "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz",
+ "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=18.18.0"
+ }
+ },
+ "node_modules/@humanfs/node": {
+ "version": "0.16.6",
+ "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.6.tgz",
+ "integrity": "sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@humanfs/core": "^0.19.1",
+ "@humanwhocodes/retry": "^0.3.0"
+ },
+ "engines": {
+ "node": ">=18.18.0"
+ }
+ },
+ "node_modules/@humanfs/node/node_modules/@humanwhocodes/retry": {
+ "version": "0.3.1",
+ "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.1.tgz",
+ "integrity": "sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=18.18"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/nzakas"
+ }
+ },
+ "node_modules/@humanwhocodes/module-importer": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz",
+ "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=12.22"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/nzakas"
+ }
+ },
+ "node_modules/@humanwhocodes/retry": {
+ "version": "0.4.2",
+ "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.2.tgz",
+ "integrity": "sha512-xeO57FpIu4p1Ri3Jq/EXq4ClRm86dVF2z/+kvFnyqVYRavTZmaFaUBbWCOuuTh0o/g7DSsk6kc2vrS4Vl5oPOQ==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=18.18"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/nzakas"
+ }
+ },
+ "node_modules/@internationalized/date": {
+ "version": "3.7.0",
+ "resolved": "https://registry.npmjs.org/@internationalized/date/-/date-3.7.0.tgz",
+ "integrity": "sha512-VJ5WS3fcVx0bejE/YHfbDKR/yawZgKqn/if+oEeLqNwBtPzVB06olkfcnojTmEMX+gTpH+FlQ69SHNitJ8/erQ==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@swc/helpers": "^0.5.0"
+ }
+ },
+ "node_modules/@ioredis/commands": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/@ioredis/commands/-/commands-1.2.0.tgz",
+ "integrity": "sha512-Sx1pU8EM64o2BrqNpEO1CNLtKQwyhuXuqyfH7oGKCk+1a33d2r5saW8zNwm3j6BTExtjrv2BxTgzzkMwts6vGg==",
+ "license": "MIT"
+ },
+ "node_modules/@jridgewell/gen-mapping": {
+ "version": "0.3.8",
+ "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.8.tgz",
+ "integrity": "sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==",
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/set-array": "^1.2.1",
+ "@jridgewell/sourcemap-codec": "^1.4.10",
+ "@jridgewell/trace-mapping": "^0.3.24"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@jridgewell/resolve-uri": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
+ "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@jridgewell/set-array": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz",
+ "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@jridgewell/sourcemap-codec": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz",
+ "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==",
+ "license": "MIT"
+ },
+ "node_modules/@jridgewell/trace-mapping": {
+ "version": "0.3.25",
+ "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz",
+ "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/resolve-uri": "^3.1.0",
+ "@jridgewell/sourcemap-codec": "^1.4.14"
+ }
+ },
+ "node_modules/@nodelib/fs.scandir": {
+ "version": "2.1.5",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
+ "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@nodelib/fs.stat": "2.0.5",
+ "run-parallel": "^1.1.9"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/@nodelib/fs.stat": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz",
+ "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/@nodelib/fs.walk": {
+ "version": "1.2.8",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz",
+ "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@nodelib/fs.scandir": "2.1.5",
+ "fastq": "^1.6.0"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/@oslojs/asn1": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/@oslojs/asn1/-/asn1-1.0.0.tgz",
+ "integrity": "sha512-zw/wn0sj0j0QKbIXfIlnEcTviaCzYOY3V5rAyjR6YtOByFtJiT574+8p9Wlach0lZH9fddD4yb9laEAIl4vXQA==",
+ "license": "MIT",
+ "dependencies": {
+ "@oslojs/binary": "1.0.0"
+ }
+ },
+ "node_modules/@oslojs/binary": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/@oslojs/binary/-/binary-1.0.0.tgz",
+ "integrity": "sha512-9RCU6OwXU6p67H4NODbuxv2S3eenuQ4/WFLrsq+K/k682xrznH5EVWA7N4VFk9VYVcbFtKqur5YQQZc0ySGhsQ==",
+ "license": "MIT"
+ },
+ "node_modules/@oslojs/crypto": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/@oslojs/crypto/-/crypto-1.0.1.tgz",
+ "integrity": "sha512-7n08G8nWjAr/Yu3vu9zzrd0L9XnrJfpMioQcvCMxBIiF5orECHe5/3J0jmXRVvgfqMm/+4oxlQ+Sq39COYLcNQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@oslojs/asn1": "1.0.0",
+ "@oslojs/binary": "1.0.0"
+ }
+ },
+ "node_modules/@oslojs/encoding": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@oslojs/encoding/-/encoding-1.1.0.tgz",
+ "integrity": "sha512-70wQhgYmndg4GCPxPPxPGevRKqTIJ2Nh4OkiMWmDAVYsTQ+Ta7Sq+rPevXyXGdzr30/qZBnyOalCszoMxlyldQ==",
+ "license": "MIT"
+ },
+ "node_modules/@oslojs/jwt": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/@oslojs/jwt/-/jwt-0.2.0.tgz",
+ "integrity": "sha512-bLE7BtHrURedCn4Mco3ma9L4Y1GR2SMBuIvjWr7rmQ4/W/4Jy70TIAgZ+0nIlk0xHz1vNP8x8DCns45Sb2XRbg==",
+ "license": "MIT",
+ "dependencies": {
+ "@oslojs/encoding": "0.4.1"
+ }
+ },
+ "node_modules/@oslojs/jwt/node_modules/@oslojs/encoding": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/@oslojs/encoding/-/encoding-0.4.1.tgz",
+ "integrity": "sha512-hkjo6MuIK/kQR5CrGNdAPZhS01ZCXuWDRJ187zh6qqF2+yMHZpD9fAYpX8q2bOO6Ryhl3XpCT6kUX76N8hhm4Q==",
+ "license": "MIT"
+ },
+ "node_modules/@pilcrowjs/object-parser": {
+ "version": "0.0.4",
+ "resolved": "https://registry.npmjs.org/@pilcrowjs/object-parser/-/object-parser-0.0.4.tgz",
+ "integrity": "sha512-mBy3FMv2lvl/sZX/q03wvl3Km8FWg7kbrqQ/qMxK49uZcBssD76Js5k+o7VuCDJI8SNvsrbIX8y6vclx7bWeSg==",
+ "license": "MIT"
+ },
+ "node_modules/@polka/url": {
+ "version": "1.0.0-next.28",
+ "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.28.tgz",
+ "integrity": "sha512-8LduaNlMZGwdZ6qWrKlfa+2M4gahzFkprZiAt2TF8uS0qQgBizKXpXURqvTJ4WtmupWxaLqjRb2UCTe72mu+Aw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@rollup/rollup-android-arm-eabi": {
+ "version": "4.34.8",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.34.8.tgz",
+ "integrity": "sha512-q217OSE8DTp8AFHuNHXo0Y86e1wtlfVrXiAlwkIvGRQv9zbc6mE3sjIVfwI8sYUyNxwOg0j/Vm1RKM04JcWLJw==",
+ "cpu": [
+ "arm"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ]
+ },
+ "node_modules/@rollup/rollup-android-arm64": {
+ "version": "4.34.8",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.34.8.tgz",
+ "integrity": "sha512-Gigjz7mNWaOL9wCggvoK3jEIUUbGul656opstjaUSGC3eT0BM7PofdAJaBfPFWWkXNVAXbaQtC99OCg4sJv70Q==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ]
+ },
+ "node_modules/@rollup/rollup-darwin-arm64": {
+ "version": "4.34.8",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.34.8.tgz",
+ "integrity": "sha512-02rVdZ5tgdUNRxIUrFdcMBZQoaPMrxtwSb+/hOfBdqkatYHR3lZ2A2EGyHq2sGOd0Owk80oV3snlDASC24He3Q==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ]
+ },
+ "node_modules/@rollup/rollup-darwin-x64": {
+ "version": "4.34.8",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.34.8.tgz",
+ "integrity": "sha512-qIP/elwR/tq/dYRx3lgwK31jkZvMiD6qUtOycLhTzCvrjbZ3LjQnEM9rNhSGpbLXVJYQ3rq39A6Re0h9tU2ynw==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ]
+ },
+ "node_modules/@rollup/rollup-freebsd-arm64": {
+ "version": "4.34.8",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.34.8.tgz",
+ "integrity": "sha512-IQNVXL9iY6NniYbTaOKdrlVP3XIqazBgJOVkddzJlqnCpRi/yAeSOa8PLcECFSQochzqApIOE1GHNu3pCz+BDA==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ]
+ },
+ "node_modules/@rollup/rollup-freebsd-x64": {
+ "version": "4.34.8",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.34.8.tgz",
+ "integrity": "sha512-TYXcHghgnCqYFiE3FT5QwXtOZqDj5GmaFNTNt3jNC+vh22dc/ukG2cG+pi75QO4kACohZzidsq7yKTKwq/Jq7Q==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm-gnueabihf": {
+ "version": "4.34.8",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.34.8.tgz",
+ "integrity": "sha512-A4iphFGNkWRd+5m3VIGuqHnG3MVnqKe7Al57u9mwgbyZ2/xF9Jio72MaY7xxh+Y87VAHmGQr73qoKL9HPbXj1g==",
+ "cpu": [
+ "arm"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm-musleabihf": {
+ "version": "4.34.8",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.34.8.tgz",
+ "integrity": "sha512-S0lqKLfTm5u+QTxlFiAnb2J/2dgQqRy/XvziPtDd1rKZFXHTyYLoVL58M/XFwDI01AQCDIevGLbQrMAtdyanpA==",
+ "cpu": [
+ "arm"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm64-gnu": {
+ "version": "4.34.8",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.34.8.tgz",
+ "integrity": "sha512-jpz9YOuPiSkL4G4pqKrus0pn9aYwpImGkosRKwNi+sJSkz+WU3anZe6hi73StLOQdfXYXC7hUfsQlTnjMd3s1A==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm64-musl": {
+ "version": "4.34.8",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.34.8.tgz",
+ "integrity": "sha512-KdSfaROOUJXgTVxJNAZ3KwkRc5nggDk+06P6lgi1HLv1hskgvxHUKZ4xtwHkVYJ1Rep4GNo+uEfycCRRxht7+Q==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-loongarch64-gnu": {
+ "version": "4.34.8",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.34.8.tgz",
+ "integrity": "sha512-NyF4gcxwkMFRjgXBM6g2lkT58OWztZvw5KkV2K0qqSnUEqCVcqdh2jN4gQrTn/YUpAcNKyFHfoOZEer9nwo6uQ==",
+ "cpu": [
+ "loong64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-powerpc64le-gnu": {
+ "version": "4.34.8",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.34.8.tgz",
+ "integrity": "sha512-LMJc999GkhGvktHU85zNTDImZVUCJ1z/MbAJTnviiWmmjyckP5aQsHtcujMjpNdMZPT2rQEDBlJfubhs3jsMfw==",
+ "cpu": [
+ "ppc64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-riscv64-gnu": {
+ "version": "4.34.8",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.34.8.tgz",
+ "integrity": "sha512-xAQCAHPj8nJq1PI3z8CIZzXuXCstquz7cIOL73HHdXiRcKk8Ywwqtx2wrIy23EcTn4aZ2fLJNBB8d0tQENPCmw==",
+ "cpu": [
+ "riscv64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-s390x-gnu": {
+ "version": "4.34.8",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.34.8.tgz",
+ "integrity": "sha512-DdePVk1NDEuc3fOe3dPPTb+rjMtuFw89gw6gVWxQFAuEqqSdDKnrwzZHrUYdac7A7dXl9Q2Vflxpme15gUWQFA==",
+ "cpu": [
+ "s390x"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-x64-gnu": {
+ "version": "4.34.8",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.34.8.tgz",
+ "integrity": "sha512-8y7ED8gjxITUltTUEJLQdgpbPh1sUQ0kMTmufRF/Ns5tI9TNMNlhWtmPKKHCU0SilX+3MJkZ0zERYYGIVBYHIA==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-x64-musl": {
+ "version": "4.34.8",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.34.8.tgz",
+ "integrity": "sha512-SCXcP0ZpGFIe7Ge+McxY5zKxiEI5ra+GT3QRxL0pMMtxPfpyLAKleZODi1zdRHkz5/BhueUrYtYVgubqe9JBNQ==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-win32-arm64-msvc": {
+ "version": "4.34.8",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.34.8.tgz",
+ "integrity": "sha512-YHYsgzZgFJzTRbth4h7Or0m5O74Yda+hLin0irAIobkLQFRQd1qWmnoVfwmKm9TXIZVAD0nZ+GEb2ICicLyCnQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@rollup/rollup-win32-ia32-msvc": {
+ "version": "4.34.8",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.34.8.tgz",
+ "integrity": "sha512-r3NRQrXkHr4uWy5TOjTpTYojR9XmF0j/RYgKCef+Ag46FWUTltm5ziticv8LdNsDMehjJ543x/+TJAek/xBA2w==",
+ "cpu": [
+ "ia32"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@rollup/rollup-win32-x64-msvc": {
+ "version": "4.34.8",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.34.8.tgz",
+ "integrity": "sha512-U0FaE5O1BCpZSeE6gBl3c5ObhePQSfk9vDRToMmTkbhCOgW4jqvtS5LGyQ76L1fH8sM0keRp4uDTsbjiUyjk0g==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@sveltejs/adapter-auto": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/@sveltejs/adapter-auto/-/adapter-auto-4.0.0.tgz",
+ "integrity": "sha512-kmuYSQdD2AwThymQF0haQhM8rE5rhutQXG4LNbnbShwhMO4qQGnKaaTy+88DuNSuoQDi58+thpq8XpHc1+oEKQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "import-meta-resolve": "^4.1.0"
+ },
+ "peerDependencies": {
+ "@sveltejs/kit": "^2.0.0"
+ }
+ },
+ "node_modules/@sveltejs/kit": {
+ "version": "2.17.2",
+ "resolved": "https://registry.npmjs.org/@sveltejs/kit/-/kit-2.17.2.tgz",
+ "integrity": "sha512-Vypk02baf7qd3SOB1uUwUC/3Oka+srPo2J0a8YN3EfJypRshDkNx9HzNKjSmhOnGWwT+SSO06+N0mAb8iVTmTQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/cookie": "^0.6.0",
+ "cookie": "^0.6.0",
+ "devalue": "^5.1.0",
+ "esm-env": "^1.2.2",
+ "import-meta-resolve": "^4.1.0",
+ "kleur": "^4.1.5",
+ "magic-string": "^0.30.5",
+ "mrmime": "^2.0.0",
+ "sade": "^1.8.1",
+ "set-cookie-parser": "^2.6.0",
+ "sirv": "^3.0.0"
+ },
+ "bin": {
+ "svelte-kit": "svelte-kit.js"
+ },
+ "engines": {
+ "node": ">=18.13"
+ },
+ "peerDependencies": {
+ "@sveltejs/vite-plugin-svelte": "^3.0.0 || ^4.0.0-next.1 || ^5.0.0",
+ "svelte": "^4.0.0 || ^5.0.0-next.0",
+ "vite": "^5.0.3 || ^6.0.0"
+ }
+ },
+ "node_modules/@sveltejs/vite-plugin-svelte": {
+ "version": "5.0.3",
+ "resolved": "https://registry.npmjs.org/@sveltejs/vite-plugin-svelte/-/vite-plugin-svelte-5.0.3.tgz",
+ "integrity": "sha512-MCFS6CrQDu1yGwspm4qtli0e63vaPCehf6V7pIMP15AsWgMKrqDGCPFF/0kn4SP0ii4aySu4Pa62+fIRGFMjgw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@sveltejs/vite-plugin-svelte-inspector": "^4.0.1",
+ "debug": "^4.4.0",
+ "deepmerge": "^4.3.1",
+ "kleur": "^4.1.5",
+ "magic-string": "^0.30.15",
+ "vitefu": "^1.0.4"
+ },
+ "engines": {
+ "node": "^18.0.0 || ^20.0.0 || >=22"
+ },
+ "peerDependencies": {
+ "svelte": "^5.0.0",
+ "vite": "^6.0.0"
+ }
+ },
+ "node_modules/@sveltejs/vite-plugin-svelte-inspector": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/@sveltejs/vite-plugin-svelte-inspector/-/vite-plugin-svelte-inspector-4.0.1.tgz",
+ "integrity": "sha512-J/Nmb2Q2y7mck2hyCX4ckVHcR5tu2J+MtBEQqpDrrgELZ2uvraQcK/ioCV61AqkdXFgriksOKIceDcQmqnGhVw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "debug": "^4.3.7"
+ },
+ "engines": {
+ "node": "^18.0.0 || ^20.0.0 || >=22"
+ },
+ "peerDependencies": {
+ "@sveltejs/vite-plugin-svelte": "^5.0.0",
+ "svelte": "^5.0.0",
+ "vite": "^6.0.0"
+ }
+ },
+ "node_modules/@swc/helpers": {
+ "version": "0.5.15",
+ "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.15.tgz",
+ "integrity": "sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "tslib": "^2.8.0"
+ }
+ },
+ "node_modules/@tailwindcss/node": {
+ "version": "4.0.7",
+ "resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.0.7.tgz",
+ "integrity": "sha512-dkFXufkbRB2mu3FPsW5xLAUWJyexpJA+/VtQj18k3SUiJVLdpgzBd1v1gRRcIpEJj7K5KpxBKfOXlZxT3ZZRuA==",
+ "license": "MIT",
+ "dependencies": {
+ "enhanced-resolve": "^5.18.1",
+ "jiti": "^2.4.2",
+ "tailwindcss": "4.0.7"
+ }
+ },
+ "node_modules/@tailwindcss/oxide": {
+ "version": "4.0.7",
+ "resolved": "https://registry.npmjs.org/@tailwindcss/oxide/-/oxide-4.0.7.tgz",
+ "integrity": "sha512-yr6w5YMgjy+B+zkJiJtIYGXW+HNYOPfRPtSs+aqLnKwdEzNrGv4ZuJh9hYJ3mcA+HMq/K1rtFV+KsEr65S558g==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 10"
+ },
+ "optionalDependencies": {
+ "@tailwindcss/oxide-android-arm64": "4.0.7",
+ "@tailwindcss/oxide-darwin-arm64": "4.0.7",
+ "@tailwindcss/oxide-darwin-x64": "4.0.7",
+ "@tailwindcss/oxide-freebsd-x64": "4.0.7",
+ "@tailwindcss/oxide-linux-arm-gnueabihf": "4.0.7",
+ "@tailwindcss/oxide-linux-arm64-gnu": "4.0.7",
+ "@tailwindcss/oxide-linux-arm64-musl": "4.0.7",
+ "@tailwindcss/oxide-linux-x64-gnu": "4.0.7",
+ "@tailwindcss/oxide-linux-x64-musl": "4.0.7",
+ "@tailwindcss/oxide-win32-arm64-msvc": "4.0.7",
+ "@tailwindcss/oxide-win32-x64-msvc": "4.0.7"
+ }
+ },
+ "node_modules/@tailwindcss/oxide-android-arm64": {
+ "version": "4.0.7",
+ "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.0.7.tgz",
+ "integrity": "sha512-5iQXXcAeOHBZy8ASfHFm1k0O/9wR2E3tKh6+P+ilZZbQiMgu+qrnfpBWYPc3FPuQdWiWb73069WT5D+CAfx/tg==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@tailwindcss/oxide-darwin-arm64": {
+ "version": "4.0.7",
+ "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.0.7.tgz",
+ "integrity": "sha512-7yGZtEc5IgVYylqK/2B0yVqoofk4UAbkn1ygNpIJZyrOhbymsfr8uUFCueTu2fUxmAYIfMZ8waWo2dLg/NgLgg==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@tailwindcss/oxide-darwin-x64": {
+ "version": "4.0.7",
+ "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.0.7.tgz",
+ "integrity": "sha512-tPQDV20fBjb26yWbPqT1ZSoDChomMCiXTKn4jupMSoMCFyU7+OJvIY1ryjqBuY622dEBJ8LnCDDWsnj1lX9nNQ==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@tailwindcss/oxide-freebsd-x64": {
+ "version": "4.0.7",
+ "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.0.7.tgz",
+ "integrity": "sha512-sZqJpTyTZiknU9LLHuByg5GKTW+u3FqM7q7myequAXxKOpAFiOfXpY710FuMY+gjzSapyRbDXJlsTQtCyiTo5w==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@tailwindcss/oxide-linux-arm-gnueabihf": {
+ "version": "4.0.7",
+ "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.0.7.tgz",
+ "integrity": "sha512-PBgvULgeSswjd8cbZ91gdIcIDMdc3TUHV5XemEpxlqt9M8KoydJzkuB/Dt910jYdofOIaTWRL6adG9nJICvU4A==",
+ "cpu": [
+ "arm"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@tailwindcss/oxide-linux-arm64-gnu": {
+ "version": "4.0.7",
+ "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.0.7.tgz",
+ "integrity": "sha512-By/a2yeh+e9b+C67F88ndSwVJl2A3tcUDb29FbedDi+DZ4Mr07Oqw9Y1DrDrtHIDhIZ3bmmiL1dkH2YxrtV+zw==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@tailwindcss/oxide-linux-arm64-musl": {
+ "version": "4.0.7",
+ "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.0.7.tgz",
+ "integrity": "sha512-WHYs3cpPEJb/ccyT20NOzopYQkl7JKncNBUbb77YFlwlXMVJLLV3nrXQKhr7DmZxz2ZXqjyUwsj2rdzd9stYdw==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@tailwindcss/oxide-linux-x64-gnu": {
+ "version": "4.0.7",
+ "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.0.7.tgz",
+ "integrity": "sha512-7bP1UyuX9kFxbOwkeIJhBZNevKYPXB6xZI37v09fqi6rqRJR8elybwjMUHm54GVP+UTtJ14ueB1K54Dy1tIO6w==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@tailwindcss/oxide-linux-x64-musl": {
+ "version": "4.0.7",
+ "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.0.7.tgz",
+ "integrity": "sha512-gBQIV8nL/LuhARNGeroqzXymMzzW5wQzqlteVqOVoqwEfpHOP3GMird5pGFbnpY+NP0fOlsZGrxxOPQ4W/84bQ==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@tailwindcss/oxide-win32-arm64-msvc": {
+ "version": "4.0.7",
+ "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.0.7.tgz",
+ "integrity": "sha512-aH530NFfx0kpQpvYMfWoeG03zGnRCMVlQG8do/5XeahYydz+6SIBxA1tl/cyITSJyWZHyVt6GVNkXeAD30v0Xg==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@tailwindcss/oxide-win32-x64-msvc": {
+ "version": "4.0.7",
+ "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.0.7.tgz",
+ "integrity": "sha512-8Cva6bbJN7ZJx320k7vxGGdU0ewmpfS5A4PudyzUuofdi8MgeINuiiWiPQ0VZCda/GX88K6qp+6UpDZNVr8HMQ==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@tailwindcss/vite": {
+ "version": "4.0.7",
+ "resolved": "https://registry.npmjs.org/@tailwindcss/vite/-/vite-4.0.7.tgz",
+ "integrity": "sha512-GYx5sxArfIMtdZCsxfya3S/efMmf4RvfqdiLUozkhmSFBNUFnYVodatpoO/en4/BsOIGvq/RB6HwcTLn9prFnQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@tailwindcss/node": "4.0.7",
+ "@tailwindcss/oxide": "4.0.7",
+ "lightningcss": "^1.29.1",
+ "tailwindcss": "4.0.7"
+ },
+ "peerDependencies": {
+ "vite": "^5.2.0 || ^6"
+ }
+ },
+ "node_modules/@types/cookie": {
+ "version": "0.6.0",
+ "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.6.0.tgz",
+ "integrity": "sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/crypto-js": {
+ "version": "4.2.2",
+ "resolved": "https://registry.npmjs.org/@types/crypto-js/-/crypto-js-4.2.2.tgz",
+ "integrity": "sha512-sDOLlVbHhXpAUAL0YHDUUwDZf3iN4Bwi4W6a0W0b+QcAezUbRtH4FVb+9J4h+XFPW7l/gQ9F8qC7P+Ec4k8QVQ==",
+ "license": "MIT"
+ },
+ "node_modules/@types/estree": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz",
+ "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==",
+ "license": "MIT"
+ },
+ "node_modules/@types/json-schema": {
+ "version": "7.0.15",
+ "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz",
+ "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/node": {
+ "version": "22.13.5",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-22.13.5.tgz",
+ "integrity": "sha512-+lTU0PxZXn0Dr1NBtC7Y8cR21AJr87dLLU953CWA6pMxxv/UDc7jYAY90upcrie1nRcD6XNG5HOYEDtgW5TxAg==",
+ "license": "MIT",
+ "dependencies": {
+ "undici-types": "~6.20.0"
+ }
+ },
+ "node_modules/@typescript-eslint/eslint-plugin": {
+ "version": "8.24.1",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.24.1.tgz",
+ "integrity": "sha512-ll1StnKtBigWIGqvYDVuDmXJHVH4zLVot1yQ4fJtLpL7qacwkxJc1T0bptqw+miBQ/QfUbhl1TcQ4accW5KUyA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@eslint-community/regexpp": "^4.10.0",
+ "@typescript-eslint/scope-manager": "8.24.1",
+ "@typescript-eslint/type-utils": "8.24.1",
+ "@typescript-eslint/utils": "8.24.1",
+ "@typescript-eslint/visitor-keys": "8.24.1",
+ "graphemer": "^1.4.0",
+ "ignore": "^5.3.1",
+ "natural-compare": "^1.4.0",
+ "ts-api-utils": "^2.0.1"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "@typescript-eslint/parser": "^8.0.0 || ^8.0.0-alpha.0",
+ "eslint": "^8.57.0 || ^9.0.0",
+ "typescript": ">=4.8.4 <5.8.0"
+ }
+ },
+ "node_modules/@typescript-eslint/parser": {
+ "version": "8.24.1",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.24.1.tgz",
+ "integrity": "sha512-Tqoa05bu+t5s8CTZFaGpCH2ub3QeT9YDkXbPd3uQ4SfsLoh1/vv2GEYAioPoxCWJJNsenXlC88tRjwoHNts1oQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@typescript-eslint/scope-manager": "8.24.1",
+ "@typescript-eslint/types": "8.24.1",
+ "@typescript-eslint/typescript-estree": "8.24.1",
+ "@typescript-eslint/visitor-keys": "8.24.1",
+ "debug": "^4.3.4"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "eslint": "^8.57.0 || ^9.0.0",
+ "typescript": ">=4.8.4 <5.8.0"
+ }
+ },
+ "node_modules/@typescript-eslint/scope-manager": {
+ "version": "8.24.1",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.24.1.tgz",
+ "integrity": "sha512-OdQr6BNBzwRjNEXMQyaGyZzgg7wzjYKfX2ZBV3E04hUCBDv3GQCHiz9RpqdUIiVrMgJGkXm3tcEh4vFSHreS2Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@typescript-eslint/types": "8.24.1",
+ "@typescript-eslint/visitor-keys": "8.24.1"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ }
+ },
+ "node_modules/@typescript-eslint/type-utils": {
+ "version": "8.24.1",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.24.1.tgz",
+ "integrity": "sha512-/Do9fmNgCsQ+K4rCz0STI7lYB4phTtEXqqCAs3gZW0pnK7lWNkvWd5iW545GSmApm4AzmQXmSqXPO565B4WVrw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@typescript-eslint/typescript-estree": "8.24.1",
+ "@typescript-eslint/utils": "8.24.1",
+ "debug": "^4.3.4",
+ "ts-api-utils": "^2.0.1"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "eslint": "^8.57.0 || ^9.0.0",
+ "typescript": ">=4.8.4 <5.8.0"
+ }
+ },
+ "node_modules/@typescript-eslint/types": {
+ "version": "8.24.1",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.24.1.tgz",
+ "integrity": "sha512-9kqJ+2DkUXiuhoiYIUvIYjGcwle8pcPpdlfkemGvTObzgmYfJ5d0Qm6jwb4NBXP9W1I5tss0VIAnWFumz3mC5A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ }
+ },
+ "node_modules/@typescript-eslint/typescript-estree": {
+ "version": "8.24.1",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.24.1.tgz",
+ "integrity": "sha512-UPyy4MJ/0RE648DSKQe9g0VDSehPINiejjA6ElqnFaFIhI6ZEiZAkUI0D5MCk0bQcTf/LVqZStvQ6K4lPn/BRg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@typescript-eslint/types": "8.24.1",
+ "@typescript-eslint/visitor-keys": "8.24.1",
+ "debug": "^4.3.4",
+ "fast-glob": "^3.3.2",
+ "is-glob": "^4.0.3",
+ "minimatch": "^9.0.4",
+ "semver": "^7.6.0",
+ "ts-api-utils": "^2.0.1"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "typescript": ">=4.8.4 <5.8.0"
+ }
+ },
+ "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
+ "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "balanced-match": "^1.0.0"
+ }
+ },
+ "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": {
+ "version": "9.0.5",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
+ "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "brace-expansion": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/@typescript-eslint/utils": {
+ "version": "8.24.1",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.24.1.tgz",
+ "integrity": "sha512-OOcg3PMMQx9EXspId5iktsI3eMaXVwlhC8BvNnX6B5w9a4dVgpkQZuU8Hy67TolKcl+iFWq0XX+jbDGN4xWxjQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@eslint-community/eslint-utils": "^4.4.0",
+ "@typescript-eslint/scope-manager": "8.24.1",
+ "@typescript-eslint/types": "8.24.1",
+ "@typescript-eslint/typescript-estree": "8.24.1"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "eslint": "^8.57.0 || ^9.0.0",
+ "typescript": ">=4.8.4 <5.8.0"
+ }
+ },
+ "node_modules/@typescript-eslint/visitor-keys": {
+ "version": "8.24.1",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.24.1.tgz",
+ "integrity": "sha512-EwVHlp5l+2vp8CoqJm9KikPZgi3gbdZAtabKT9KPShGeOcJhsv4Zdo3oc8T8I0uKEmYoU4ItyxbptjF08enaxg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@typescript-eslint/types": "8.24.1",
+ "eslint-visitor-keys": "^4.2.0"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ }
+ },
+ "node_modules/acorn": {
+ "version": "8.14.0",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz",
+ "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==",
+ "license": "MIT",
+ "bin": {
+ "acorn": "bin/acorn"
+ },
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
+ "node_modules/acorn-jsx": {
+ "version": "5.3.2",
+ "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz",
+ "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==",
+ "dev": true,
+ "license": "MIT",
+ "peerDependencies": {
+ "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0"
+ }
+ },
+ "node_modules/acorn-typescript": {
+ "version": "1.4.13",
+ "resolved": "https://registry.npmjs.org/acorn-typescript/-/acorn-typescript-1.4.13.tgz",
+ "integrity": "sha512-xsc9Xv0xlVfwp2o7sQ+GCQ1PgbkdcpWdTzrwXxO3xDMTAywVS3oXVOcOHuRjAPkS4P9b+yc/qNF15460v+jp4Q==",
+ "license": "MIT",
+ "peerDependencies": {
+ "acorn": ">=8.9.0"
+ }
+ },
+ "node_modules/ajv": {
+ "version": "6.12.6",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
+ "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "fast-deep-equal": "^3.1.1",
+ "fast-json-stable-stringify": "^2.0.0",
+ "json-schema-traverse": "^0.4.1",
+ "uri-js": "^4.2.2"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/epoberezkin"
+ }
+ },
+ "node_modules/ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "color-convert": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/arctic": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/arctic/-/arctic-3.3.0.tgz",
+ "integrity": "sha512-kORD8k31tPnbxovMlaTQwknIswAKK2eqQjfyW/sWXTIIZxp7PaFxNogJBFc9ZYdQFL7CXQIhl3XuQI848UX+aw==",
+ "license": "MIT",
+ "dependencies": {
+ "@oslojs/crypto": "1.0.1",
+ "@oslojs/encoding": "1.1.0",
+ "@oslojs/jwt": "0.2.0"
+ }
+ },
+ "node_modules/argparse": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
+ "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
+ "dev": true,
+ "license": "Python-2.0"
+ },
+ "node_modules/aria-query": {
+ "version": "5.3.2",
+ "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.2.tgz",
+ "integrity": "sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==",
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/axobject-query": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-4.1.0.tgz",
+ "integrity": "sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==",
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/balanced-match": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
+ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/bits-ui": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/bits-ui/-/bits-ui-1.3.2.tgz",
+ "integrity": "sha512-27fg/O71yqYmDaDf/opInylQYJjBNlFw3Ari0mXKLA6UrQpRvY62EsAid8s+ci/wYrGZMvHpzNJ69t15ycBHTw==",
+ "license": "MIT",
+ "dependencies": {
+ "@floating-ui/core": "^1.6.4",
+ "@floating-ui/dom": "^1.6.7",
+ "@internationalized/date": "^3.5.6",
+ "esm-env": "^1.1.2",
+ "runed": "^0.23.2",
+ "svelte-toolbelt": "^0.7.1",
+ "tabbable": "^6.2.0"
+ },
+ "engines": {
+ "node": ">=18",
+ "pnpm": ">=8.7.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/huntabyte"
+ },
+ "peerDependencies": {
+ "svelte": "^5.11.0"
+ }
+ },
+ "node_modules/brace-expansion": {
+ "version": "1.1.11",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
+ "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "balanced-match": "^1.0.0",
+ "concat-map": "0.0.1"
+ }
+ },
+ "node_modules/braces": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
+ "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "fill-range": "^7.1.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/callsites": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
+ "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/chalk?sponsor=1"
+ }
+ },
+ "node_modules/chokidar": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz",
+ "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "readdirp": "^4.0.1"
+ },
+ "engines": {
+ "node": ">= 14.16.0"
+ },
+ "funding": {
+ "url": "https://paulmillr.com/funding/"
+ }
+ },
+ "node_modules/clsx": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz",
+ "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/cluster-key-slot": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/cluster-key-slot/-/cluster-key-slot-1.1.2.tgz",
+ "integrity": "sha512-RMr0FhtfXemyinomL4hrWcYJxmX6deFdCxpJzhDttxgO1+bcCnkk+9drydLVDmAMG7NE6aN/fl4F7ucU/90gAA==",
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "color-name": "~1.1.4"
+ },
+ "engines": {
+ "node": ">=7.0.0"
+ }
+ },
+ "node_modules/color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/concat-map": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
+ "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/cookie": {
+ "version": "0.6.0",
+ "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz",
+ "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/cross-spawn": {
+ "version": "7.0.6",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
+ "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "path-key": "^3.1.0",
+ "shebang-command": "^2.0.0",
+ "which": "^2.0.1"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/crypto-js": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-4.2.0.tgz",
+ "integrity": "sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q==",
+ "license": "MIT"
+ },
+ "node_modules/cssesc": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz",
+ "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "cssesc": "bin/cssesc"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/debug": {
+ "version": "4.4.0",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz",
+ "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==",
+ "license": "MIT",
+ "dependencies": {
+ "ms": "^2.1.3"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/deep-is": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz",
+ "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/deepmerge": {
+ "version": "4.3.1",
+ "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz",
+ "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/denque": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/denque/-/denque-2.1.0.tgz",
+ "integrity": "sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw==",
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=0.10"
+ }
+ },
+ "node_modules/detect-libc": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz",
+ "integrity": "sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==",
+ "license": "Apache-2.0",
+ "bin": {
+ "detect-libc": "bin/detect-libc.js"
+ },
+ "engines": {
+ "node": ">=0.10"
+ }
+ },
+ "node_modules/devalue": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/devalue/-/devalue-5.1.1.tgz",
+ "integrity": "sha512-maua5KUiapvEwiEAe+XnlZ3Rh0GD+qI1J/nb9vrJc3muPXvcF/8gXYTWF76+5DAqHyDUtOIImEuo0YKE9mshVw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/enhanced-resolve": {
+ "version": "5.18.1",
+ "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.1.tgz",
+ "integrity": "sha512-ZSW3ma5GkcQBIpwZTSRAI8N71Uuwgs93IezB7mf7R60tC8ZbJideoDNKjHn2O9KIlx6rkGTTEk1xUCK2E1Y2Yg==",
+ "license": "MIT",
+ "dependencies": {
+ "graceful-fs": "^4.2.4",
+ "tapable": "^2.2.0"
+ },
+ "engines": {
+ "node": ">=10.13.0"
+ }
+ },
+ "node_modules/esbuild": {
+ "version": "0.24.2",
+ "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.24.2.tgz",
+ "integrity": "sha512-+9egpBW8I3CD5XPe0n6BfT5fxLzxrlDzqydF3aviG+9ni1lDC/OvMHcxqEFV0+LANZG5R1bFMWfUrjVsdwxJvA==",
+ "hasInstallScript": true,
+ "license": "MIT",
+ "bin": {
+ "esbuild": "bin/esbuild"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "optionalDependencies": {
+ "@esbuild/aix-ppc64": "0.24.2",
+ "@esbuild/android-arm": "0.24.2",
+ "@esbuild/android-arm64": "0.24.2",
+ "@esbuild/android-x64": "0.24.2",
+ "@esbuild/darwin-arm64": "0.24.2",
+ "@esbuild/darwin-x64": "0.24.2",
+ "@esbuild/freebsd-arm64": "0.24.2",
+ "@esbuild/freebsd-x64": "0.24.2",
+ "@esbuild/linux-arm": "0.24.2",
+ "@esbuild/linux-arm64": "0.24.2",
+ "@esbuild/linux-ia32": "0.24.2",
+ "@esbuild/linux-loong64": "0.24.2",
+ "@esbuild/linux-mips64el": "0.24.2",
+ "@esbuild/linux-ppc64": "0.24.2",
+ "@esbuild/linux-riscv64": "0.24.2",
+ "@esbuild/linux-s390x": "0.24.2",
+ "@esbuild/linux-x64": "0.24.2",
+ "@esbuild/netbsd-arm64": "0.24.2",
+ "@esbuild/netbsd-x64": "0.24.2",
+ "@esbuild/openbsd-arm64": "0.24.2",
+ "@esbuild/openbsd-x64": "0.24.2",
+ "@esbuild/sunos-x64": "0.24.2",
+ "@esbuild/win32-arm64": "0.24.2",
+ "@esbuild/win32-ia32": "0.24.2",
+ "@esbuild/win32-x64": "0.24.2"
+ }
+ },
+ "node_modules/escape-string-regexp": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
+ "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/eslint": {
+ "version": "9.20.1",
+ "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.20.1.tgz",
+ "integrity": "sha512-m1mM33o6dBUjxl2qb6wv6nGNwCAsns1eKtaQ4l/NPHeTvhiUPbtdfMyktxN4B3fgHIgsYh1VT3V9txblpQHq+g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@eslint-community/eslint-utils": "^4.2.0",
+ "@eslint-community/regexpp": "^4.12.1",
+ "@eslint/config-array": "^0.19.0",
+ "@eslint/core": "^0.11.0",
+ "@eslint/eslintrc": "^3.2.0",
+ "@eslint/js": "9.20.0",
+ "@eslint/plugin-kit": "^0.2.5",
+ "@humanfs/node": "^0.16.6",
+ "@humanwhocodes/module-importer": "^1.0.1",
+ "@humanwhocodes/retry": "^0.4.1",
+ "@types/estree": "^1.0.6",
+ "@types/json-schema": "^7.0.15",
+ "ajv": "^6.12.4",
+ "chalk": "^4.0.0",
+ "cross-spawn": "^7.0.6",
+ "debug": "^4.3.2",
+ "escape-string-regexp": "^4.0.0",
+ "eslint-scope": "^8.2.0",
+ "eslint-visitor-keys": "^4.2.0",
+ "espree": "^10.3.0",
+ "esquery": "^1.5.0",
+ "esutils": "^2.0.2",
+ "fast-deep-equal": "^3.1.3",
+ "file-entry-cache": "^8.0.0",
+ "find-up": "^5.0.0",
+ "glob-parent": "^6.0.2",
+ "ignore": "^5.2.0",
+ "imurmurhash": "^0.1.4",
+ "is-glob": "^4.0.0",
+ "json-stable-stringify-without-jsonify": "^1.0.1",
+ "lodash.merge": "^4.6.2",
+ "minimatch": "^3.1.2",
+ "natural-compare": "^1.4.0",
+ "optionator": "^0.9.3"
+ },
+ "bin": {
+ "eslint": "bin/eslint.js"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "url": "https://eslint.org/donate"
+ },
+ "peerDependencies": {
+ "jiti": "*"
+ },
+ "peerDependenciesMeta": {
+ "jiti": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/eslint-compat-utils": {
+ "version": "0.5.1",
+ "resolved": "https://registry.npmjs.org/eslint-compat-utils/-/eslint-compat-utils-0.5.1.tgz",
+ "integrity": "sha512-3z3vFexKIEnjHE3zCMRo6fn/e44U7T1khUjg+Hp0ZQMCigh28rALD0nPFBcGZuiLC5rLZa2ubQHDRln09JfU2Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "semver": "^7.5.4"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "peerDependencies": {
+ "eslint": ">=6.0.0"
+ }
+ },
+ "node_modules/eslint-config-prettier": {
+ "version": "10.0.1",
+ "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-10.0.1.tgz",
+ "integrity": "sha512-lZBts941cyJyeaooiKxAtzoPHTN+GbQTJFAIdQbRhA4/8whaAraEh47Whw/ZFfrjNSnlAxqfm9i0XVAEkULjCw==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "eslint-config-prettier": "build/bin/cli.js"
+ },
+ "peerDependencies": {
+ "eslint": ">=7.0.0"
+ }
+ },
+ "node_modules/eslint-plugin-svelte": {
+ "version": "2.46.1",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-svelte/-/eslint-plugin-svelte-2.46.1.tgz",
+ "integrity": "sha512-7xYr2o4NID/f9OEYMqxsEQsCsj4KaMy4q5sANaKkAb6/QeCjYFxRmDm2S3YC3A3pl1kyPZ/syOx/i7LcWYSbIw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@eslint-community/eslint-utils": "^4.4.0",
+ "@jridgewell/sourcemap-codec": "^1.4.15",
+ "eslint-compat-utils": "^0.5.1",
+ "esutils": "^2.0.3",
+ "known-css-properties": "^0.35.0",
+ "postcss": "^8.4.38",
+ "postcss-load-config": "^3.1.4",
+ "postcss-safe-parser": "^6.0.0",
+ "postcss-selector-parser": "^6.1.0",
+ "semver": "^7.6.2",
+ "svelte-eslint-parser": "^0.43.0"
+ },
+ "engines": {
+ "node": "^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ota-meshi"
+ },
+ "peerDependencies": {
+ "eslint": "^7.0.0 || ^8.0.0-0 || ^9.0.0-0",
+ "svelte": "^3.37.0 || ^4.0.0 || ^5.0.0"
+ },
+ "peerDependenciesMeta": {
+ "svelte": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/eslint-scope": {
+ "version": "8.2.0",
+ "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.2.0.tgz",
+ "integrity": "sha512-PHlWUfG6lvPc3yvP5A4PNyBL1W8fkDUccmI21JUu/+GKZBoH/W5u6usENXUrWFRsyoW5ACUjFGgAFQp5gUlb/A==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "esrecurse": "^4.3.0",
+ "estraverse": "^5.2.0"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/eslint-visitor-keys": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz",
+ "integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/esm-env": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/esm-env/-/esm-env-1.2.2.tgz",
+ "integrity": "sha512-Epxrv+Nr/CaL4ZcFGPJIYLWFom+YeV1DqMLHJoEd9SYRxNbaFruBwfEX/kkHUJf55j2+TUbmDcmuilbP1TmXHA==",
+ "license": "MIT"
+ },
+ "node_modules/espree": {
+ "version": "10.3.0",
+ "resolved": "https://registry.npmjs.org/espree/-/espree-10.3.0.tgz",
+ "integrity": "sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "acorn": "^8.14.0",
+ "acorn-jsx": "^5.3.2",
+ "eslint-visitor-keys": "^4.2.0"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/esquery": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz",
+ "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "estraverse": "^5.1.0"
+ },
+ "engines": {
+ "node": ">=0.10"
+ }
+ },
+ "node_modules/esrap": {
+ "version": "1.4.5",
+ "resolved": "https://registry.npmjs.org/esrap/-/esrap-1.4.5.tgz",
+ "integrity": "sha512-CjNMjkBWWZeHn+VX+gS8YvFwJ5+NDhg8aWZBSFJPR8qQduDNjbJodA2WcwCm7uQa5Rjqj+nZvVmceg1RbHFB9g==",
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/sourcemap-codec": "^1.4.15"
+ }
+ },
+ "node_modules/esrecurse": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz",
+ "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "estraverse": "^5.2.0"
+ },
+ "engines": {
+ "node": ">=4.0"
+ }
+ },
+ "node_modules/estraverse": {
+ "version": "5.3.0",
+ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
+ "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=4.0"
+ }
+ },
+ "node_modules/esutils": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
+ "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/fast-deep-equal": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
+ "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/fast-glob": {
+ "version": "3.3.3",
+ "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz",
+ "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@nodelib/fs.stat": "^2.0.2",
+ "@nodelib/fs.walk": "^1.2.3",
+ "glob-parent": "^5.1.2",
+ "merge2": "^1.3.0",
+ "micromatch": "^4.0.8"
+ },
+ "engines": {
+ "node": ">=8.6.0"
+ }
+ },
+ "node_modules/fast-glob/node_modules/glob-parent": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
+ "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "is-glob": "^4.0.1"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/fast-json-stable-stringify": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
+ "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/fast-levenshtein": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
+ "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/fastq": {
+ "version": "1.19.0",
+ "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.0.tgz",
+ "integrity": "sha512-7SFSRCNjBQIZH/xZR3iy5iQYR8aGBE0h3VG6/cwlbrpdciNYBMotQav8c1XI3HjHH+NikUpP53nPdlZSdWmFzA==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "reusify": "^1.0.4"
+ }
+ },
+ "node_modules/fdir": {
+ "version": "6.4.3",
+ "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.3.tgz",
+ "integrity": "sha512-PMXmW2y1hDDfTSRc9gaXIuCCRpuoz3Kaz8cUelp3smouvfT632ozg2vrT6lJsHKKOF59YLbOGfAWGUcKEfRMQw==",
+ "dev": true,
+ "license": "MIT",
+ "peerDependencies": {
+ "picomatch": "^3 || ^4"
+ },
+ "peerDependenciesMeta": {
+ "picomatch": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/file-entry-cache": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz",
+ "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "flat-cache": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=16.0.0"
+ }
+ },
+ "node_modules/fill-range": {
+ "version": "7.1.1",
+ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
+ "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "to-regex-range": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/find-up": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz",
+ "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "locate-path": "^6.0.0",
+ "path-exists": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/flat-cache": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz",
+ "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "flatted": "^3.2.9",
+ "keyv": "^4.5.4"
+ },
+ "engines": {
+ "node": ">=16"
+ }
+ },
+ "node_modules/flatted": {
+ "version": "3.3.3",
+ "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz",
+ "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/fsevents": {
+ "version": "2.3.3",
+ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
+ "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
+ "hasInstallScript": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
+ }
+ },
+ "node_modules/glob-parent": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
+ "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "is-glob": "^4.0.3"
+ },
+ "engines": {
+ "node": ">=10.13.0"
+ }
+ },
+ "node_modules/globals": {
+ "version": "15.15.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-15.15.0.tgz",
+ "integrity": "sha512-7ACyT3wmyp3I61S4fG682L0VA2RGD9otkqGJIwNUMF1SWUombIIk+af1unuDYgMm082aHYwD+mzJvv9Iu8dsgg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/graceful-fs": {
+ "version": "4.2.11",
+ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
+ "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==",
+ "license": "ISC"
+ },
+ "node_modules/graphemer": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz",
+ "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/guid-ts": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/guid-ts/-/guid-ts-1.1.2.tgz",
+ "integrity": "sha512-8LKkTis9udlKO23g+wEEmQxrpaq4cj41IQuAjy+NXyrPKSBLXssTVaBXVs+u8jv1nkjUl9fExgrYoqh3Rsd8Bg==",
+ "license": "MIT"
+ },
+ "node_modules/has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/ignore": {
+ "version": "5.3.2",
+ "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz",
+ "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 4"
+ }
+ },
+ "node_modules/import-fresh": {
+ "version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz",
+ "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "parent-module": "^1.0.0",
+ "resolve-from": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/import-meta-resolve": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/import-meta-resolve/-/import-meta-resolve-4.1.0.tgz",
+ "integrity": "sha512-I6fiaX09Xivtk+THaMfAwnA3MVA5Big1WHF1Dfx9hFuvNIWpXnorlkzhcQf6ehrqQiiZECRt1poOAkPmer3ruw==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/imurmurhash": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
+ "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.8.19"
+ }
+ },
+ "node_modules/inline-style-parser": {
+ "version": "0.2.4",
+ "resolved": "https://registry.npmjs.org/inline-style-parser/-/inline-style-parser-0.2.4.tgz",
+ "integrity": "sha512-0aO8FkhNZlj/ZIbNi7Lxxr12obT7cL1moPfE4tg1LkX7LlLfC6DeX4l2ZEud1ukP9jNQyNnfzQVqwbwmAATY4Q==",
+ "license": "MIT"
+ },
+ "node_modules/ioredis": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/ioredis/-/ioredis-5.5.0.tgz",
+ "integrity": "sha512-7CutT89g23FfSa8MDoIFs2GYYa0PaNiW/OrT+nRyjRXHDZd17HmIgy+reOQ/yhh72NznNjGuS8kbCAcA4Ro4mw==",
+ "license": "MIT",
+ "dependencies": {
+ "@ioredis/commands": "^1.1.1",
+ "cluster-key-slot": "^1.1.0",
+ "debug": "^4.3.4",
+ "denque": "^2.1.0",
+ "lodash.defaults": "^4.2.0",
+ "lodash.isarguments": "^3.1.0",
+ "redis-errors": "^1.2.0",
+ "redis-parser": "^3.0.0",
+ "standard-as-callback": "^2.1.0"
+ },
+ "engines": {
+ "node": ">=12.22.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/ioredis"
+ }
+ },
+ "node_modules/is-extglob": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
+ "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-glob": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
+ "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-extglob": "^2.1.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-number": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
+ "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.12.0"
+ }
+ },
+ "node_modules/is-reference": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-3.0.3.tgz",
+ "integrity": "sha512-ixkJoqQvAP88E6wLydLGGqCJsrFUnqoH6HnaczB8XmDH1oaWU+xxdptvikTgaEhtZ53Ky6YXiBuUI2WXLMCwjw==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/estree": "^1.0.6"
+ }
+ },
+ "node_modules/isexe": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
+ "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/jiti": {
+ "version": "2.4.2",
+ "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.4.2.tgz",
+ "integrity": "sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A==",
+ "license": "MIT",
+ "bin": {
+ "jiti": "lib/jiti-cli.mjs"
+ }
+ },
+ "node_modules/js-yaml": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
+ "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "argparse": "^2.0.1"
+ },
+ "bin": {
+ "js-yaml": "bin/js-yaml.js"
+ }
+ },
+ "node_modules/json-buffer": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz",
+ "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/json-schema-traverse": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
+ "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/json-stable-stringify-without-jsonify": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz",
+ "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/keyv": {
+ "version": "4.5.4",
+ "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz",
+ "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "json-buffer": "3.0.1"
+ }
+ },
+ "node_modules/kleur": {
+ "version": "4.1.5",
+ "resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz",
+ "integrity": "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/known-css-properties": {
+ "version": "0.35.0",
+ "resolved": "https://registry.npmjs.org/known-css-properties/-/known-css-properties-0.35.0.tgz",
+ "integrity": "sha512-a/RAk2BfKk+WFGhhOCAYqSiFLc34k8Mt/6NWRI4joER0EYUzXIcFivjjnoD3+XU1DggLn/tZc3DOAgke7l8a4A==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/levn": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz",
+ "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "prelude-ls": "^1.2.1",
+ "type-check": "~0.4.0"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/lightningcss": {
+ "version": "1.29.1",
+ "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.29.1.tgz",
+ "integrity": "sha512-FmGoeD4S05ewj+AkhTY+D+myDvXI6eL27FjHIjoyUkO/uw7WZD1fBVs0QxeYWa7E17CUHJaYX/RUGISCtcrG4Q==",
+ "license": "MPL-2.0",
+ "dependencies": {
+ "detect-libc": "^1.0.3"
+ },
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ },
+ "optionalDependencies": {
+ "lightningcss-darwin-arm64": "1.29.1",
+ "lightningcss-darwin-x64": "1.29.1",
+ "lightningcss-freebsd-x64": "1.29.1",
+ "lightningcss-linux-arm-gnueabihf": "1.29.1",
+ "lightningcss-linux-arm64-gnu": "1.29.1",
+ "lightningcss-linux-arm64-musl": "1.29.1",
+ "lightningcss-linux-x64-gnu": "1.29.1",
+ "lightningcss-linux-x64-musl": "1.29.1",
+ "lightningcss-win32-arm64-msvc": "1.29.1",
+ "lightningcss-win32-x64-msvc": "1.29.1"
+ }
+ },
+ "node_modules/lightningcss-darwin-arm64": {
+ "version": "1.29.1",
+ "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.29.1.tgz",
+ "integrity": "sha512-HtR5XJ5A0lvCqYAoSv2QdZZyoHNttBpa5EP9aNuzBQeKGfbyH5+UipLWvVzpP4Uml5ej4BYs5I9Lco9u1fECqw==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-darwin-x64": {
+ "version": "1.29.1",
+ "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.29.1.tgz",
+ "integrity": "sha512-k33G9IzKUpHy/J/3+9MCO4e+PzaFblsgBjSGlpAaFikeBFm8B/CkO3cKU9oI4g+fjS2KlkLM/Bza9K/aw8wsNA==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-freebsd-x64": {
+ "version": "1.29.1",
+ "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.29.1.tgz",
+ "integrity": "sha512-0SUW22fv/8kln2LnIdOCmSuXnxgxVC276W5KLTwoehiO0hxkacBxjHOL5EtHD8BAXg2BvuhsJPmVMasvby3LiQ==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-linux-arm-gnueabihf": {
+ "version": "1.29.1",
+ "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.29.1.tgz",
+ "integrity": "sha512-sD32pFvlR0kDlqsOZmYqH/68SqUMPNj+0pucGxToXZi4XZgZmqeX/NkxNKCPsswAXU3UeYgDSpGhu05eAufjDg==",
+ "cpu": [
+ "arm"
+ ],
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-linux-arm64-gnu": {
+ "version": "1.29.1",
+ "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.29.1.tgz",
+ "integrity": "sha512-0+vClRIZ6mmJl/dxGuRsE197o1HDEeeRk6nzycSy2GofC2JsY4ifCRnvUWf/CUBQmlrvMzt6SMQNMSEu22csWQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-linux-arm64-musl": {
+ "version": "1.29.1",
+ "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.29.1.tgz",
+ "integrity": "sha512-UKMFrG4rL/uHNgelBsDwJcBqVpzNJbzsKkbI3Ja5fg00sgQnHw/VrzUTEc4jhZ+AN2BvQYz/tkHu4vt1kLuJyw==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-linux-x64-gnu": {
+ "version": "1.29.1",
+ "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.29.1.tgz",
+ "integrity": "sha512-u1S+xdODy/eEtjADqirA774y3jLcm8RPtYztwReEXoZKdzgsHYPl0s5V52Tst+GKzqjebkULT86XMSxejzfISw==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-linux-x64-musl": {
+ "version": "1.29.1",
+ "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.29.1.tgz",
+ "integrity": "sha512-L0Tx0DtaNUTzXv0lbGCLB/c/qEADanHbu4QdcNOXLIe1i8i22rZRpbT3gpWYsCh9aSL9zFujY/WmEXIatWvXbw==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-win32-arm64-msvc": {
+ "version": "1.29.1",
+ "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.29.1.tgz",
+ "integrity": "sha512-QoOVnkIEFfbW4xPi+dpdft/zAKmgLgsRHfJalEPYuJDOWf7cLQzYg0DEh8/sn737FaeMJxHZRc1oBreiwZCjog==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lightningcss-win32-x64-msvc": {
+ "version": "1.29.1",
+ "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.29.1.tgz",
+ "integrity": "sha512-NygcbThNBe4JElP+olyTI/doBNGJvLs3bFCRPdvuCcxZCcCZ71B858IHpdm7L1btZex0FvCmM17FK98Y9MRy1Q==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MPL-2.0",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">= 12.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/lilconfig": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz",
+ "integrity": "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==",
+ "devOptional": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/locate-character": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/locate-character/-/locate-character-3.0.0.tgz",
+ "integrity": "sha512-SW13ws7BjaeJ6p7Q6CO2nchbYEc3X3J6WrmTTDto7yMPqVSZTUyY5Tjbid+Ab8gLnATtygYtiDIJGQRRn2ZOiA==",
+ "license": "MIT"
+ },
+ "node_modules/locate-path": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
+ "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "p-locate": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/lodash.defaults": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz",
+ "integrity": "sha512-qjxPLHd3r5DnsdGacqOMU6pb/avJzdh9tFX2ymgoZE27BmjXrNy/y4LoaiTeAb+O3gL8AfpJGtqfX/ae2leYYQ==",
+ "license": "MIT"
+ },
+ "node_modules/lodash.isarguments": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz",
+ "integrity": "sha512-chi4NHZlZqZD18a0imDHnZPrDeBbTtVN7GXMwuGdRH9qotxAjYs3aVLKc7zNOG9eddR5Ksd8rvFEBc9SsggPpg==",
+ "license": "MIT"
+ },
+ "node_modules/lodash.merge": {
+ "version": "4.6.2",
+ "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
+ "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/lucide-svelte": {
+ "version": "0.475.0",
+ "resolved": "https://registry.npmjs.org/lucide-svelte/-/lucide-svelte-0.475.0.tgz",
+ "integrity": "sha512-N5+hFTPHaZe9HhqJDxxxODfYuOmI6v+JIowzERcea/uxytN/JZlehVTcINBNp8wMo7l6ov1Jf5srrDbkI/WsJg==",
+ "license": "ISC",
+ "peerDependencies": {
+ "svelte": "^3 || ^4 || ^5.0.0-next.42"
+ }
+ },
+ "node_modules/magic-string": {
+ "version": "0.30.17",
+ "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.17.tgz",
+ "integrity": "sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==",
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/sourcemap-codec": "^1.5.0"
+ }
+ },
+ "node_modules/merge2": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
+ "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/micromatch": {
+ "version": "4.0.8",
+ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz",
+ "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "braces": "^3.0.3",
+ "picomatch": "^2.3.1"
+ },
+ "engines": {
+ "node": ">=8.6"
+ }
+ },
+ "node_modules/micromatch/node_modules/picomatch": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
+ "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8.6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
+ }
+ },
+ "node_modules/minimatch": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
+ "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "brace-expansion": "^1.1.7"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/mode-watcher": {
+ "version": "0.5.1",
+ "resolved": "https://registry.npmjs.org/mode-watcher/-/mode-watcher-0.5.1.tgz",
+ "integrity": "sha512-adEC6T7TMX/kzQlaO/MtiQOSFekZfQu4MC+lXyoceQG+U5sKpJWZ4yKXqw846ExIuWJgedkOIPqAYYRk/xHm+w==",
+ "license": "MIT",
+ "peerDependencies": {
+ "svelte": "^4.0.0 || ^5.0.0-next.1"
+ }
+ },
+ "node_modules/mri": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz",
+ "integrity": "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/mrmime": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.1.tgz",
+ "integrity": "sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/ms": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
+ "license": "MIT"
+ },
+ "node_modules/nanoid": {
+ "version": "3.3.8",
+ "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.8.tgz",
+ "integrity": "sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "bin": {
+ "nanoid": "bin/nanoid.cjs"
+ },
+ "engines": {
+ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
+ }
+ },
+ "node_modules/natural-compare": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
+ "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/optionator": {
+ "version": "0.9.4",
+ "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz",
+ "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "deep-is": "^0.1.3",
+ "fast-levenshtein": "^2.0.6",
+ "levn": "^0.4.1",
+ "prelude-ls": "^1.2.1",
+ "type-check": "^0.4.0",
+ "word-wrap": "^1.2.5"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/p-limit": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
+ "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "yocto-queue": "^0.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/p-locate": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz",
+ "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "p-limit": "^3.0.2"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/parent-module": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
+ "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "callsites": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/path-exists": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
+ "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/path-key": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
+ "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/picocolors": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
+ "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
+ "license": "ISC"
+ },
+ "node_modules/picomatch": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz",
+ "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "peer": true,
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
+ }
+ },
+ "node_modules/postcss": {
+ "version": "8.5.3",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.3.tgz",
+ "integrity": "sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A==",
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/postcss/"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/postcss"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "nanoid": "^3.3.8",
+ "picocolors": "^1.1.1",
+ "source-map-js": "^1.2.1"
+ },
+ "engines": {
+ "node": "^10 || ^12 || >=14"
+ }
+ },
+ "node_modules/postcss-load-config": {
+ "version": "3.1.4",
+ "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-3.1.4.tgz",
+ "integrity": "sha512-6DiM4E7v4coTE4uzA8U//WhtPwyhiim3eyjEMFCnUpzbrkK9wJHgKDT2mR+HbtSrd/NubVaYTOpSpjUl8NQeRg==",
+ "devOptional": true,
+ "license": "MIT",
+ "dependencies": {
+ "lilconfig": "^2.0.5",
+ "yaml": "^1.10.2"
+ },
+ "engines": {
+ "node": ">= 10"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/postcss/"
+ },
+ "peerDependencies": {
+ "postcss": ">=8.0.9",
+ "ts-node": ">=9.0.0"
+ },
+ "peerDependenciesMeta": {
+ "postcss": {
+ "optional": true
+ },
+ "ts-node": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/postcss-load-config/node_modules/yaml": {
+ "version": "1.10.2",
+ "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz",
+ "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==",
+ "devOptional": true,
+ "license": "ISC",
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/postcss-safe-parser": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/postcss-safe-parser/-/postcss-safe-parser-6.0.0.tgz",
+ "integrity": "sha512-FARHN8pwH+WiS2OPCxJI8FuRJpTVnn6ZNFiqAM2aeW2LwTHWWmWgIyKC6cUo0L8aeKiF/14MNvnpls6R2PBeMQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/postcss/"
+ },
+ "peerDependencies": {
+ "postcss": "^8.3.3"
+ }
+ },
+ "node_modules/postcss-scss": {
+ "version": "4.0.9",
+ "resolved": "https://registry.npmjs.org/postcss-scss/-/postcss-scss-4.0.9.tgz",
+ "integrity": "sha512-AjKOeiwAitL/MXxQW2DliT28EKukvvbEWx3LBmJIRN8KfBGZbRTxNYW0kSqi1COiTZ57nZ9NW06S6ux//N1c9A==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/postcss/"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/postcss-scss"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "engines": {
+ "node": ">=12.0"
+ },
+ "peerDependencies": {
+ "postcss": "^8.4.29"
+ }
+ },
+ "node_modules/postcss-selector-parser": {
+ "version": "6.1.2",
+ "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz",
+ "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "cssesc": "^3.0.0",
+ "util-deprecate": "^1.0.2"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/prelude-ls": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz",
+ "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/prettier": {
+ "version": "3.5.1",
+ "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.5.1.tgz",
+ "integrity": "sha512-hPpFQvHwL3Qv5AdRvBFMhnKo4tYxp0ReXiPn2bxkiohEX6mBeBwEpBSQTkD458RaaDKQMYSp4hX4UtfUTA5wDw==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "prettier": "bin/prettier.cjs"
+ },
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "url": "https://github.com/prettier/prettier?sponsor=1"
+ }
+ },
+ "node_modules/prettier-plugin-svelte": {
+ "version": "3.3.3",
+ "resolved": "https://registry.npmjs.org/prettier-plugin-svelte/-/prettier-plugin-svelte-3.3.3.tgz",
+ "integrity": "sha512-yViK9zqQ+H2qZD1w/bH7W8i+bVfKrD8GIFjkFe4Thl6kCT9SlAsXVNmt3jCvQOCsnOhcvYgsoVlRV/Eu6x5nNw==",
+ "dev": true,
+ "license": "MIT",
+ "peerDependencies": {
+ "prettier": "^3.0.0",
+ "svelte": "^3.2.0 || ^4.0.0-next.0 || ^5.0.0-next.0"
+ }
+ },
+ "node_modules/prettier-plugin-tailwindcss": {
+ "version": "0.6.11",
+ "resolved": "https://registry.npmjs.org/prettier-plugin-tailwindcss/-/prettier-plugin-tailwindcss-0.6.11.tgz",
+ "integrity": "sha512-YxaYSIvZPAqhrrEpRtonnrXdghZg1irNg4qrjboCXrpybLWVs55cW2N3juhspVJiO0JBvYJT8SYsJpc8OQSnsA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=14.21.3"
+ },
+ "peerDependencies": {
+ "@ianvs/prettier-plugin-sort-imports": "*",
+ "@prettier/plugin-pug": "*",
+ "@shopify/prettier-plugin-liquid": "*",
+ "@trivago/prettier-plugin-sort-imports": "*",
+ "@zackad/prettier-plugin-twig": "*",
+ "prettier": "^3.0",
+ "prettier-plugin-astro": "*",
+ "prettier-plugin-css-order": "*",
+ "prettier-plugin-import-sort": "*",
+ "prettier-plugin-jsdoc": "*",
+ "prettier-plugin-marko": "*",
+ "prettier-plugin-multiline-arrays": "*",
+ "prettier-plugin-organize-attributes": "*",
+ "prettier-plugin-organize-imports": "*",
+ "prettier-plugin-sort-imports": "*",
+ "prettier-plugin-style-order": "*",
+ "prettier-plugin-svelte": "*"
+ },
+ "peerDependenciesMeta": {
+ "@ianvs/prettier-plugin-sort-imports": {
+ "optional": true
+ },
+ "@prettier/plugin-pug": {
+ "optional": true
+ },
+ "@shopify/prettier-plugin-liquid": {
+ "optional": true
+ },
+ "@trivago/prettier-plugin-sort-imports": {
+ "optional": true
+ },
+ "@zackad/prettier-plugin-twig": {
+ "optional": true
+ },
+ "prettier-plugin-astro": {
+ "optional": true
+ },
+ "prettier-plugin-css-order": {
+ "optional": true
+ },
+ "prettier-plugin-import-sort": {
+ "optional": true
+ },
+ "prettier-plugin-jsdoc": {
+ "optional": true
+ },
+ "prettier-plugin-marko": {
+ "optional": true
+ },
+ "prettier-plugin-multiline-arrays": {
+ "optional": true
+ },
+ "prettier-plugin-organize-attributes": {
+ "optional": true
+ },
+ "prettier-plugin-organize-imports": {
+ "optional": true
+ },
+ "prettier-plugin-sort-imports": {
+ "optional": true
+ },
+ "prettier-plugin-style-order": {
+ "optional": true
+ },
+ "prettier-plugin-svelte": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/punycode": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
+ "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/queue-microtask": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
+ "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "MIT"
+ },
+ "node_modules/rabbitmq-client": {
+ "version": "5.0.2",
+ "resolved": "https://registry.npmjs.org/rabbitmq-client/-/rabbitmq-client-5.0.2.tgz",
+ "integrity": "sha512-rXEcDxBcGAokczKfVsyIhrIXdS4xcOqrMCMlBIMNEIxP43dNwApJWdt2PN3vKtjO/xCVAfOTT5r3rQAdXhuyyA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=16"
+ }
+ },
+ "node_modules/readdirp": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz",
+ "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 14.18.0"
+ },
+ "funding": {
+ "type": "individual",
+ "url": "https://paulmillr.com/funding/"
+ }
+ },
+ "node_modules/redis-errors": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/redis-errors/-/redis-errors-1.2.0.tgz",
+ "integrity": "sha512-1qny3OExCf0UvUV/5wpYKf2YwPcOqXzkwKKSmKHiE6ZMQs5heeE/c8eXK+PNllPvmjgAbfnsbpkGZWy8cBpn9w==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/redis-parser": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/redis-parser/-/redis-parser-3.0.0.tgz",
+ "integrity": "sha512-DJnGAeenTdpMEH6uAJRK/uiyEIH9WVsUmoLwzudwGJUwZPp80PDBWPHXSAGNPwNvIXAbe7MSUB1zQFugFml66A==",
+ "license": "MIT",
+ "dependencies": {
+ "redis-errors": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/resolve-from": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
+ "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/reusify": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz",
+ "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "iojs": ">=1.0.0",
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/rollup": {
+ "version": "4.34.8",
+ "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.34.8.tgz",
+ "integrity": "sha512-489gTVMzAYdiZHFVA/ig/iYFllCcWFHMvUHI1rpFmkoUtRlQxqh6/yiNqnYibjMZ2b/+FUQwldG+aLsEt6bglQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/estree": "1.0.6"
+ },
+ "bin": {
+ "rollup": "dist/bin/rollup"
+ },
+ "engines": {
+ "node": ">=18.0.0",
+ "npm": ">=8.0.0"
+ },
+ "optionalDependencies": {
+ "@rollup/rollup-android-arm-eabi": "4.34.8",
+ "@rollup/rollup-android-arm64": "4.34.8",
+ "@rollup/rollup-darwin-arm64": "4.34.8",
+ "@rollup/rollup-darwin-x64": "4.34.8",
+ "@rollup/rollup-freebsd-arm64": "4.34.8",
+ "@rollup/rollup-freebsd-x64": "4.34.8",
+ "@rollup/rollup-linux-arm-gnueabihf": "4.34.8",
+ "@rollup/rollup-linux-arm-musleabihf": "4.34.8",
+ "@rollup/rollup-linux-arm64-gnu": "4.34.8",
+ "@rollup/rollup-linux-arm64-musl": "4.34.8",
+ "@rollup/rollup-linux-loongarch64-gnu": "4.34.8",
+ "@rollup/rollup-linux-powerpc64le-gnu": "4.34.8",
+ "@rollup/rollup-linux-riscv64-gnu": "4.34.8",
+ "@rollup/rollup-linux-s390x-gnu": "4.34.8",
+ "@rollup/rollup-linux-x64-gnu": "4.34.8",
+ "@rollup/rollup-linux-x64-musl": "4.34.8",
+ "@rollup/rollup-win32-arm64-msvc": "4.34.8",
+ "@rollup/rollup-win32-ia32-msvc": "4.34.8",
+ "@rollup/rollup-win32-x64-msvc": "4.34.8",
+ "fsevents": "~2.3.2"
+ }
+ },
+ "node_modules/run-parallel": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
+ "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "queue-microtask": "^1.2.2"
+ }
+ },
+ "node_modules/runed": {
+ "version": "0.23.4",
+ "resolved": "https://registry.npmjs.org/runed/-/runed-0.23.4.tgz",
+ "integrity": "sha512-9q8oUiBYeXIDLWNK5DfCWlkL0EW3oGbk845VdKlPeia28l751VpfesaB/+7pI6rnbx1I6rqoZ2fZxptOJLxILA==",
+ "funding": [
+ "https://github.com/sponsors/huntabyte",
+ "https://github.com/sponsors/tglide"
+ ],
+ "dependencies": {
+ "esm-env": "^1.0.0"
+ },
+ "peerDependencies": {
+ "svelte": "^5.7.0"
+ }
+ },
+ "node_modules/sade": {
+ "version": "1.8.1",
+ "resolved": "https://registry.npmjs.org/sade/-/sade-1.8.1.tgz",
+ "integrity": "sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "mri": "^1.1.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/semver": {
+ "version": "7.7.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz",
+ "integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==",
+ "dev": true,
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/set-cookie-parser": {
+ "version": "2.7.1",
+ "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.7.1.tgz",
+ "integrity": "sha512-IOc8uWeOZgnb3ptbCURJWNjWUPcO3ZnTTdzsurqERrP6nPyv+paC55vJM0LpOlT2ne+Ix+9+CRG1MNLlyZ4GjQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/shebang-command": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
+ "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "shebang-regex": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/shebang-regex": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
+ "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/sirv": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/sirv/-/sirv-3.0.1.tgz",
+ "integrity": "sha512-FoqMu0NCGBLCcAkS1qA+XJIQTR6/JHfQXl+uGteNCQ76T91DMUjPa9xfmeqMY3z80nLSg9yQmNjK0Px6RWsH/A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@polka/url": "^1.0.0-next.24",
+ "mrmime": "^2.0.0",
+ "totalist": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/source-map-js": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
+ "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
+ "license": "BSD-3-Clause",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/standard-as-callback": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/standard-as-callback/-/standard-as-callback-2.1.0.tgz",
+ "integrity": "sha512-qoRRSyROncaz1z0mvYqIE4lCd9p2R90i6GxW3uZv5ucSu8tU7B5HXUP1gG8pVZsYNVaXjk8ClXHPttLyxAL48A==",
+ "license": "MIT"
+ },
+ "node_modules/strip-json-comments": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
+ "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/style-to-object": {
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/style-to-object/-/style-to-object-1.0.8.tgz",
+ "integrity": "sha512-xT47I/Eo0rwJmaXC4oilDGDWLohVhR6o/xAQcPQN8q6QBuZVL8qMYL85kLmST5cPjAorwvqIA4qXTRQoYHaL6g==",
+ "license": "MIT",
+ "dependencies": {
+ "inline-style-parser": "0.2.4"
+ }
+ },
+ "node_modules/supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "has-flag": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/svelte": {
+ "version": "5.20.2",
+ "resolved": "https://registry.npmjs.org/svelte/-/svelte-5.20.2.tgz",
+ "integrity": "sha512-aYXJreNUiyTob0QOzRZeBXZMGeFZDch6SrSRV8QTncZb6zj0O3BEdUzPpojuHQ1pTvk+KX7I6rZCXPUf8pTPxA==",
+ "license": "MIT",
+ "dependencies": {
+ "@ampproject/remapping": "^2.3.0",
+ "@jridgewell/sourcemap-codec": "^1.5.0",
+ "@types/estree": "^1.0.5",
+ "acorn": "^8.12.1",
+ "acorn-typescript": "^1.4.13",
+ "aria-query": "^5.3.1",
+ "axobject-query": "^4.1.0",
+ "clsx": "^2.1.1",
+ "esm-env": "^1.2.1",
+ "esrap": "^1.4.3",
+ "is-reference": "^3.0.3",
+ "locate-character": "^3.0.0",
+ "magic-string": "^0.30.11",
+ "zimmerframe": "^1.1.2"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/svelte-check": {
+ "version": "4.1.4",
+ "resolved": "https://registry.npmjs.org/svelte-check/-/svelte-check-4.1.4.tgz",
+ "integrity": "sha512-v0j7yLbT29MezzaQJPEDwksybTE2Ups9rUxEXy92T06TiA0cbqcO8wAOwNUVkFW6B0hsYHA+oAX3BS8b/2oHtw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/trace-mapping": "^0.3.25",
+ "chokidar": "^4.0.1",
+ "fdir": "^6.2.0",
+ "picocolors": "^1.0.0",
+ "sade": "^1.7.4"
+ },
+ "bin": {
+ "svelte-check": "bin/svelte-check"
+ },
+ "engines": {
+ "node": ">= 18.0.0"
+ },
+ "peerDependencies": {
+ "svelte": "^4.0.0 || ^5.0.0-next.0",
+ "typescript": ">=5.0.0"
+ }
+ },
+ "node_modules/svelte-eslint-parser": {
+ "version": "0.43.0",
+ "resolved": "https://registry.npmjs.org/svelte-eslint-parser/-/svelte-eslint-parser-0.43.0.tgz",
+ "integrity": "sha512-GpU52uPKKcVnh8tKN5P4UZpJ/fUDndmq7wfsvoVXsyP+aY0anol7Yqo01fyrlaWGMFfm4av5DyrjlaXdLRJvGA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "eslint-scope": "^7.2.2",
+ "eslint-visitor-keys": "^3.4.3",
+ "espree": "^9.6.1",
+ "postcss": "^8.4.39",
+ "postcss-scss": "^4.0.9"
+ },
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ota-meshi"
+ },
+ "peerDependencies": {
+ "svelte": "^3.37.0 || ^4.0.0 || ^5.0.0"
+ },
+ "peerDependenciesMeta": {
+ "svelte": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/svelte-eslint-parser/node_modules/eslint-scope": {
+ "version": "7.2.2",
+ "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz",
+ "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "esrecurse": "^4.3.0",
+ "estraverse": "^5.2.0"
+ },
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/svelte-eslint-parser/node_modules/eslint-visitor-keys": {
+ "version": "3.4.3",
+ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz",
+ "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/svelte-eslint-parser/node_modules/espree": {
+ "version": "9.6.1",
+ "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz",
+ "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "acorn": "^8.9.0",
+ "acorn-jsx": "^5.3.2",
+ "eslint-visitor-keys": "^3.4.1"
+ },
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/svelte-preprocess": {
+ "version": "6.0.3",
+ "resolved": "https://registry.npmjs.org/svelte-preprocess/-/svelte-preprocess-6.0.3.tgz",
+ "integrity": "sha512-PLG2k05qHdhmRG7zR/dyo5qKvakhm8IJ+hD2eFRQmMLHp7X3eJnjeupUtvuRpbNiF31RjVw45W+abDwHEmP5OA==",
+ "hasInstallScript": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 18.0.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.10.2",
+ "coffeescript": "^2.5.1",
+ "less": "^3.11.3 || ^4.0.0",
+ "postcss": "^7 || ^8",
+ "postcss-load-config": ">=3",
+ "pug": "^3.0.0",
+ "sass": "^1.26.8",
+ "stylus": ">=0.55",
+ "sugarss": "^2.0.0 || ^3.0.0 || ^4.0.0",
+ "svelte": "^4.0.0 || ^5.0.0-next.100 || ^5.0.0",
+ "typescript": "^5.0.0"
+ },
+ "peerDependenciesMeta": {
+ "@babel/core": {
+ "optional": true
+ },
+ "coffeescript": {
+ "optional": true
+ },
+ "less": {
+ "optional": true
+ },
+ "postcss": {
+ "optional": true
+ },
+ "postcss-load-config": {
+ "optional": true
+ },
+ "pug": {
+ "optional": true
+ },
+ "sass": {
+ "optional": true
+ },
+ "stylus": {
+ "optional": true
+ },
+ "sugarss": {
+ "optional": true
+ },
+ "typescript": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/svelte-toolbelt": {
+ "version": "0.7.1",
+ "resolved": "https://registry.npmjs.org/svelte-toolbelt/-/svelte-toolbelt-0.7.1.tgz",
+ "integrity": "sha512-HcBOcR17Vx9bjaOceUvxkY3nGmbBmCBBbuWLLEWO6jtmWH8f/QoWmbyUfQZrpDINH39en1b8mptfPQT9VKQ1xQ==",
+ "funding": [
+ "https://github.com/sponsors/huntabyte"
+ ],
+ "dependencies": {
+ "clsx": "^2.1.1",
+ "runed": "^0.23.2",
+ "style-to-object": "^1.0.8"
+ },
+ "engines": {
+ "node": ">=18",
+ "pnpm": ">=8.7.0"
+ },
+ "peerDependencies": {
+ "svelte": "^5.0.0"
+ }
+ },
+ "node_modules/tabbable": {
+ "version": "6.2.0",
+ "resolved": "https://registry.npmjs.org/tabbable/-/tabbable-6.2.0.tgz",
+ "integrity": "sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew==",
+ "license": "MIT"
+ },
+ "node_modules/tailwind-merge": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-3.0.1.tgz",
+ "integrity": "sha512-AvzE8FmSoXC7nC+oU5GlQJbip2UO7tmOhOfQyOmPhrStOGXHU08j8mZEHZ4BmCqY5dWTCo4ClWkNyRNx1wpT0g==",
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/dcastil"
+ }
+ },
+ "node_modules/tailwind-variants": {
+ "version": "0.3.1",
+ "resolved": "https://registry.npmjs.org/tailwind-variants/-/tailwind-variants-0.3.1.tgz",
+ "integrity": "sha512-krn67M3FpPwElg4FsZrOQd0U26o7UDH/QOkK8RNaiCCrr052f6YJPBUfNKnPo/s/xRzNPtv1Mldlxsg8Tb46BQ==",
+ "license": "MIT",
+ "dependencies": {
+ "tailwind-merge": "2.5.4"
+ },
+ "engines": {
+ "node": ">=16.x",
+ "pnpm": ">=7.x"
+ },
+ "peerDependencies": {
+ "tailwindcss": "*"
+ }
+ },
+ "node_modules/tailwind-variants/node_modules/tailwind-merge": {
+ "version": "2.5.4",
+ "resolved": "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-2.5.4.tgz",
+ "integrity": "sha512-0q8cfZHMu9nuYP/b5Shb7Y7Sh1B7Nnl5GqNr1U+n2p6+mybvRtayrQ+0042Z5byvTA8ihjlP8Odo8/VnHbZu4Q==",
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/dcastil"
+ }
+ },
+ "node_modules/tailwindcss": {
+ "version": "4.0.7",
+ "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.0.7.tgz",
+ "integrity": "sha512-yH5bPPyapavo7L+547h3c4jcBXcrKwybQRjwdEIVAd9iXRvy/3T1CC6XSQEgZtRySjKfqvo3Cc0ZF1DTheuIdA==",
+ "license": "MIT"
+ },
+ "node_modules/tapable": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz",
+ "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/to-regex-range": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
+ "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-number": "^7.0.0"
+ },
+ "engines": {
+ "node": ">=8.0"
+ }
+ },
+ "node_modules/totalist": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/totalist/-/totalist-3.0.1.tgz",
+ "integrity": "sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/ts-api-utils": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.0.1.tgz",
+ "integrity": "sha512-dnlgjFSVetynI8nzgJ+qF62efpglpWRk8isUEWZGWlJYySCTD6aKvbUDu+zbPeDakk3bg5H4XpitHukgfL1m9w==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18.12"
+ },
+ "peerDependencies": {
+ "typescript": ">=4.8.4"
+ }
+ },
+ "node_modules/tslib": {
+ "version": "2.8.1",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
+ "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
+ "license": "0BSD"
+ },
+ "node_modules/type-check": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
+ "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "prelude-ls": "^1.2.1"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/typescript": {
+ "version": "5.7.3",
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.3.tgz",
+ "integrity": "sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw==",
+ "devOptional": true,
+ "license": "Apache-2.0",
+ "bin": {
+ "tsc": "bin/tsc",
+ "tsserver": "bin/tsserver"
+ },
+ "engines": {
+ "node": ">=14.17"
+ }
+ },
+ "node_modules/typescript-eslint": {
+ "version": "8.24.1",
+ "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.24.1.tgz",
+ "integrity": "sha512-cw3rEdzDqBs70TIcb0Gdzbt6h11BSs2pS0yaq7hDWDBtCCSei1pPSUXE9qUdQ/Wm9NgFg8mKtMt1b8fTHIl1jA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@typescript-eslint/eslint-plugin": "8.24.1",
+ "@typescript-eslint/parser": "8.24.1",
+ "@typescript-eslint/utils": "8.24.1"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "eslint": "^8.57.0 || ^9.0.0",
+ "typescript": ">=4.8.4 <5.8.0"
+ }
+ },
+ "node_modules/undici-types": {
+ "version": "6.20.0",
+ "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz",
+ "integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==",
+ "license": "MIT"
+ },
+ "node_modules/uri-js": {
+ "version": "4.4.1",
+ "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
+ "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "punycode": "^2.1.0"
+ }
+ },
+ "node_modules/util-deprecate": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
+ "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/vite": {
+ "version": "6.1.1",
+ "resolved": "https://registry.npmjs.org/vite/-/vite-6.1.1.tgz",
+ "integrity": "sha512-4GgM54XrwRfrOp297aIYspIti66k56v16ZnqHvrIM7mG+HjDlAwS7p+Srr7J6fGvEdOJ5JcQ/D9T7HhtdXDTzA==",
+ "license": "MIT",
+ "dependencies": {
+ "esbuild": "^0.24.2",
+ "postcss": "^8.5.2",
+ "rollup": "^4.30.1"
+ },
+ "bin": {
+ "vite": "bin/vite.js"
+ },
+ "engines": {
+ "node": "^18.0.0 || ^20.0.0 || >=22.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/vitejs/vite?sponsor=1"
+ },
+ "optionalDependencies": {
+ "fsevents": "~2.3.3"
+ },
+ "peerDependencies": {
+ "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0",
+ "jiti": ">=1.21.0",
+ "less": "*",
+ "lightningcss": "^1.21.0",
+ "sass": "*",
+ "sass-embedded": "*",
+ "stylus": "*",
+ "sugarss": "*",
+ "terser": "^5.16.0",
+ "tsx": "^4.8.1",
+ "yaml": "^2.4.2"
+ },
+ "peerDependenciesMeta": {
+ "@types/node": {
+ "optional": true
+ },
+ "jiti": {
+ "optional": true
+ },
+ "less": {
+ "optional": true
+ },
+ "lightningcss": {
+ "optional": true
+ },
+ "sass": {
+ "optional": true
+ },
+ "sass-embedded": {
+ "optional": true
+ },
+ "stylus": {
+ "optional": true
+ },
+ "sugarss": {
+ "optional": true
+ },
+ "terser": {
+ "optional": true
+ },
+ "tsx": {
+ "optional": true
+ },
+ "yaml": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/vitefu": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/vitefu/-/vitefu-1.0.5.tgz",
+ "integrity": "sha512-h4Vflt9gxODPFNGPwp4zAMZRpZR7eslzwH2c5hn5kNZ5rhnKyRJ50U+yGCdc2IRaBs8O4haIgLNGrV5CrpMsCA==",
+ "dev": true,
+ "license": "MIT",
+ "workspaces": [
+ "tests/deps/*",
+ "tests/projects/*"
+ ],
+ "peerDependencies": {
+ "vite": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0"
+ },
+ "peerDependenciesMeta": {
+ "vite": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/which": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
+ "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "isexe": "^2.0.0"
+ },
+ "bin": {
+ "node-which": "bin/node-which"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/word-wrap": {
+ "version": "1.2.5",
+ "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz",
+ "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/yaml": {
+ "version": "2.7.0",
+ "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.7.0.tgz",
+ "integrity": "sha512-+hSoy/QHluxmC9kCIJyL/uyFmLmc+e5CFR5Wa+bpIhIj85LVb9ZH2nVnqrHoSvKogwODv0ClqZkmiSSaIH5LTA==",
+ "license": "ISC",
+ "optional": true,
+ "peer": true,
+ "bin": {
+ "yaml": "bin.mjs"
+ },
+ "engines": {
+ "node": ">= 14"
+ }
+ },
+ "node_modules/yocto-queue": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
+ "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/zimmerframe": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/zimmerframe/-/zimmerframe-1.1.2.tgz",
+ "integrity": "sha512-rAbqEGa8ovJy4pyBxZM70hg4pE6gDgaQ0Sl9M3enG3I0d6H4XSAM3GeNGLKnsBpuijUow064sf7ww1nutC5/3w==",
+ "license": "MIT"
+ }
+ }
+}
diff --git a/svelte-link-ui/package.json b/svelte-link-ui/package.json
new file mode 100644
index 0000000..879acde
--- /dev/null
+++ b/svelte-link-ui/package.json
@@ -0,0 +1,53 @@
+{
+ "name": "svelte-link-ui",
+ "private": true,
+ "version": "0.0.1",
+ "type": "module",
+ "scripts": {
+ "dev": "vite dev",
+ "build": "vite build",
+ "preview": "vite preview",
+ "prepare": "svelte-kit sync || echo ''",
+ "check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
+ "check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
+ "format": "prettier --write .",
+ "lint": "prettier --check . && eslint ."
+ },
+ "devDependencies": {
+ "@eslint/compat": "^1.2.5",
+ "@eslint/js": "^9.18.0",
+ "@sveltejs/adapter-auto": "^4.0.0",
+ "@sveltejs/kit": "^2.16.0",
+ "@sveltejs/vite-plugin-svelte": "^5.0.0",
+ "eslint": "^9.18.0",
+ "eslint-config-prettier": "^10.0.1",
+ "eslint-plugin-svelte": "^2.46.1",
+ "globals": "^15.14.0",
+ "prettier": "^3.5.1",
+ "prettier-plugin-svelte": "^3.3.3",
+ "prettier-plugin-tailwindcss": "^0.6.11",
+ "svelte": "^5.0.0",
+ "svelte-check": "^4.0.0",
+ "typescript": "^5.0.0",
+ "typescript-eslint": "^8.20.0",
+ "vite": "^6.0.0"
+ },
+ "dependencies": {
+ "@pilcrowjs/object-parser": "^0.0.4",
+ "@tailwindcss/vite": "^4.0.7",
+ "@types/crypto-js": "^4.2.2",
+ "@types/node": "^22.13.5",
+ "arctic": "^3.3.0",
+ "bits-ui": "^1.3.2",
+ "crypto-js": "^4.2.0",
+ "guid-ts": "^1.1.2",
+ "ioredis": "^5.5.0",
+ "lucide-svelte": "^0.475.0",
+ "mode-watcher": "^0.5.1",
+ "rabbitmq-client": "^5.0.2",
+ "svelte-preprocess": "^6.0.3",
+ "tailwind-merge": "^3.0.1",
+ "tailwind-variants": "^0.3.1",
+ "tailwindcss": "^4.0.7"
+ }
+}
diff --git a/svelte-link-ui/src/app.css b/svelte-link-ui/src/app.css
new file mode 100644
index 0000000..7c6df53
--- /dev/null
+++ b/svelte-link-ui/src/app.css
@@ -0,0 +1,157 @@
+@import 'tailwindcss';
+@import './tailwindcss-animate.css';
+
+@custom-variant dark (&:where(.dark, .dark *));
+
+/*
+ The default border color has changed to `currentColor` in Tailwind CSS v4,
+ so we've added these compatibility styles to make sure everything still
+ looks the same as it did with Tailwind CSS v3.
+
+ If we ever want to remove these styles, we need to add an explicit border
+ color utility to any element that depends on these defaults.
+*/
+@layer base {
+ *,
+ ::after,
+ ::before,
+ ::backdrop,
+ ::file-selector-button {
+ border-color: var(--color-gray-200, currentColor);
+ }
+}
+
+:root {
+ --background: 0 0% 100%;
+ --foreground: 20 14.3% 4.1%;
+ --card: 0 0% 100%;
+ --card-foreground: 20 14.3% 4.1%;
+ --popover: 0 0% 100%;
+ --popover-foreground: 20 14.3% 4.1%;
+ --primary: 24 9.8% 10%;
+ --primary-foreground: 60 9.1% 97.8%;
+ --secondary: 60 4.8% 95.9%;
+ --secondary-foreground: 24 9.8% 10%;
+ --muted: 60 4.8% 95.9%;
+ --muted-foreground: 25 5.3% 44.7%;
+ --accent: 60 4.8% 95.9%;
+ --accent-foreground: 24 9.8% 10%;
+ --destructive: 0 72.22% 50.59%;
+ --destructive-foreground: 60 9.1% 97.8%;
+ --border: 20 5.9% 90%;
+ --input: 20 5.9% 90%;
+ --ring: 20 14.3% 4.1%;
+ --radius: 0.5rem;
+}
+.dark {
+ --background: 20 14.3% 4.1%;
+ --foreground: 60 9.1% 97.8%;
+ --card: 20 14.3% 4.1%;
+ --card-foreground: 60 9.1% 97.8%;
+ --popover: 20 14.3% 4.1%;
+ --popover-foreground: 60 9.1% 97.8%;
+ --primary: 60 9.1% 97.8%;
+ --primary-foreground: 24 9.8% 10%;
+ --secondary: 12 6.5% 15.1%;
+ --secondary-foreground: 60 9.1% 97.8%;
+ --muted: 12 6.5% 15.1%;
+ --muted-foreground: 24 5.4% 63.9%;
+ --accent: 12 6.5% 15.1%;
+ --accent-foreground: 60 9.1% 97.8%;
+ --destructive: 0 62.8% 30.6%;
+ --destructive-foreground: 60 9.1% 97.8%;
+ --border: 12 6.5% 15.1%;
+ --input: 12 6.5% 15.1%;
+ --ring: 24 5.7% 82.9%;
+}
+
+@theme inline {
+ /* Fonts */
+ --font-sans:
+ 'Inter Variable', ui-sans-serif, system-ui, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji',
+ 'Segoe UI Symbol', 'Noto Color Emoji';
+ --font-mono:
+ 'Source Code Pro Variable', ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas,
+ 'Liberation Mono', 'Courier New', monospace;
+
+ /* Colors */
+ --color-border: hsl(var(--border));
+ --color-input: hsl(var(--input));
+ --color-ring: hsl(var(--ring));
+ --color-background: hsl(var(--background));
+ --color-foreground: hsl(var(--foreground));
+ --color-primary: hsl(var(--primary));
+ --color-primary-foreground: hsl(var(--primary-foreground));
+ --color-secondary: hsl(var(--secondary));
+ --color-secondary-foreground: hsl(var(--secondary-foreground));
+ --color-destructive: hsl(var(--destructive));
+ --color-destructive-foreground: hsl(var(--destructive-foreground));
+ --color-caution: var(--color-red-500);
+ --color-warning: var(--color-amber-500);
+ --color-info: var(--color-sky-500);
+ --color-muted: hsl(var(--muted));
+ --color-muted-foreground: hsl(var(--muted-foreground));
+ --color-accent: hsl(var(--accent));
+ --color-accent-foreground: hsl(var(--accent-foreground));
+ --color-popover: hsl(var(--popover));
+ --color-popover-foreground: hsl(var(--popover-foreground));
+ --color-card: hsl(var(--card));
+ --color-card-foreground: hsl(var(--card-foreground));
+ --color-sidebar: hsl(var(--sidebar-background));
+ --color-sidebar-foreground: hsl(var(--sidebar-foreground));
+ --color-sidebar-primary: hsl(var(--sidebar-primary));
+ --color-sidebar-primary-foreground: hsl(var(--sidebar-primary-foreground));
+ --color-sidebar-accent: hsl(var(--sidebar-accent));
+ --color-sidebar-accent-foreground: hsl(var(--sidebar-accent-foreground));
+ --color-sidebar-border: hsl(var(--sidebar-border));
+ --color-sidebar-ring: hsl(var(--sidebar-ring));
+
+ /* Border */
+ --radius-xl: calc(var(--radius) + 4px);
+ --radius-lg: var(--radius);
+ --radius-md: calc(var(--radius) - 2px);
+ --radius-sm: calc(var(--radius) - 4px);
+
+ /* Animations */
+ --animate-accordion-down: 0.2s ease-out accordion-down;
+ --animate-accordion-up: 0.2s ease-out accordion-up;
+ --animate-caret-blink: 1.25s ease-out infinite caret-blink;
+
+ /* Keyframes */
+ @keyframes accordion-down {
+ from: {
+ height: 0;
+ }
+ to: {
+ height: var(--bits-accordion-content-height);
+ }
+ }
+ @keyframes accordion-up {
+ from: {
+ height: var(--bits-accordion-content-height);
+ }
+ to: {
+ height: 0;
+ }
+ }
+ @keyframes caret-blink {
+ 0%,
+ 70%,
+ 100% {
+ opacity: 1;
+ }
+ 20%,
+ 50% {
+ opacity: 0;
+ }
+ }
+}
+
+@layer base {
+ * {
+ @apply border-border;
+ }
+ body {
+ @apply bg-background text-foreground;
+ }
+}
diff --git a/svelte-link-ui/src/app.d.ts b/svelte-link-ui/src/app.d.ts
new file mode 100644
index 0000000..7cb0e2a
--- /dev/null
+++ b/svelte-link-ui/src/app.d.ts
@@ -0,0 +1,29 @@
+// See https://svelte.dev/docs/kit/types#app.d.ts
+
+import type { UserMeResult } from '$lib/server/user';
+
+// for information about these interfaces
+declare global {
+ namespace App {
+ // interface Error {}
+ // interface Locals {}
+ // interface PageData {}
+ // interface PageState {}
+ // interface Platform {}
+ }
+}
+
+declare global {
+ namespace App {
+ // interface Error {}
+ interface Locals {
+ session: Session | null;
+ user: UserMeResult | null;
+ }
+ // interface PageData {}
+ // interface PageState {}
+ // interface Platform {}
+ }
+}
+
+export {};
diff --git a/svelte-link-ui/src/app.html b/svelte-link-ui/src/app.html
new file mode 100644
index 0000000..77a5ff5
--- /dev/null
+++ b/svelte-link-ui/src/app.html
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+ %sveltekit.head%
+
+
+ %sveltekit.body%
+
+
diff --git a/svelte-link-ui/src/hooks.server.ts b/svelte-link-ui/src/hooks.server.ts
new file mode 100644
index 0000000..1cf55fb
--- /dev/null
+++ b/svelte-link-ui/src/hooks.server.ts
@@ -0,0 +1,190 @@
+import { TokenBucket } from '$lib/server/rate-limit';
+import {
+ validateSessionToken,
+ setSessionTokenCookie,
+ deleteSessionTokenCookie,
+ invalidateSession
+} from '$lib/server/session';
+import { getAuthToken, removeAuthTokenFromCache } from '$lib/server/backend-token';
+import { getUser } from '$lib/server/user';
+import { RabbitMessageBus } from '$lib/server/messaging';
+import { sequence } from '@sveltejs/kit/hooks';
+import { type Handle, type ServerInit } from '@sveltejs/kit';
+import { Guid } from 'guid-ts';
+import {
+ removeAllUsersFromCacheByTenantId,
+ removeAllUsersFromCache,
+ removeUserFromCache
+} from './lib/server/user';
+
+const bucket = new TokenBucket(100, 1);
+const LOGIN_URL = '/login';
+
+export const init: ServerInit = async () => {
+ // Register all the RabbitMQ stuff (for cache cleaning)
+ const rabbit = new RabbitMessageBus();
+ rabbit.initConnection();
+
+ // Add consumers
+ addCleanCacheConsumerForTenantUpdated(rabbit);
+ addCleanCacheConsumerForRoleDeleted(rabbit);
+ addCleanCacheConsumerForRoleUpdated(rabbit);
+ addCleanCacheConsumerForUserRequestSent(rabbit);
+ addCleanCacheConsumerForTenantDeleted(rabbit);
+
+ // Parse and dispose RabbitMQ resources on shutdown
+ onShutdownRabbit(rabbit);
+};
+
+const rateLimitHandle: Handle = async ({ event, resolve }) => {
+ // Note: Assumes X-Forwarded-For will always be defined.
+ const clientIP = event.request.headers.get('X-Forwarded-For');
+ if (clientIP === null) {
+ return resolve(event);
+ }
+ const cost = event.request.method === 'GET' || event.request.method === 'OPTIONS' ? 1 : 3;
+ if (!bucket.consume(clientIP, cost)) {
+ return new Response('Too many requests', {
+ status: 429
+ });
+ }
+ return resolve(event);
+};
+
+const authHandle: Handle = async ({ event, resolve }) => {
+ if (event.url.pathname.startsWith('/app')) {
+ const token = event.cookies.get('session');
+ if (!token) {
+ return redirectToLogin(event);
+ }
+ const session = await validateSessionToken(token);
+ if (!session) {
+ deleteSessionTokenCookie(event);
+ return redirectToLogin(event);
+ }
+
+ const backendToken = await getAuthToken(session.userId, session.expiresAt);
+ const user = backendToken ? await getUser(session.userId, backendToken.accessToken) : null;
+
+ if (user) {
+ await setSessionTokenCookie(event, token, session.expiresAt);
+ event.locals.user = user;
+ event.locals.session = session;
+ } else {
+ await invalidateSession(session.id, session.userId);
+ await removeAuthTokenFromCache(session.userId);
+ deleteSessionTokenCookie(event);
+ return redirectToLogin(event);
+ }
+ }
+
+ return resolve(event);
+};
+
+export const handle = sequence(rateLimitHandle, authHandle);
+
+//Consumers
+function addCleanCacheConsumerForUserRequestSent(messageBus: RabbitMessageBus) {
+ messageBus.registerConsumer(
+ 'svelte-ui-clean-cache-user-request-sent',
+ 'UbikLink.Security.Contracts.Users.Events:CleanCacheForUserRequestSent',
+ async (payload) => {
+ await removeUserFromCache(payload.authId.toString(), payload.tenantId?.toString() ?? null);
+ }
+ );
+}
+
+function addCleanCacheConsumerForTenantDeleted(messageBus: RabbitMessageBus) {
+ messageBus.registerConsumer(
+ 'svelte-ui-clean-cache-tenant-deleted',
+ 'UbikLink.Security.Contracts.Tenants.Events:CleanCacheTenantDeleted',
+ async (payload) => {
+ await removeAllUsersFromCacheByTenantId(payload.tenantId.toString());
+ }
+ );
+}
+
+function addCleanCacheConsumerForTenantUpdated(messageBus: RabbitMessageBus) {
+ messageBus.registerConsumer(
+ 'svelte-ui-clean-cache-tenant-updated',
+ 'UbikLink.Security.Contracts.Tenants.Events:CleanCacheTenantUpdated',
+ async (payload) => {
+ await removeAllUsersFromCacheByTenantId(payload.tenantId.toString());
+ }
+ );
+}
+
+function addCleanCacheConsumerForRoleDeleted(messageBus: RabbitMessageBus) {
+ messageBus.registerConsumer(
+ 'svelte-ui-clean-cache-role-deleted',
+ 'UbikLink.Security.Contracts.Roles.Events:CleanCacheRoleDeleted',
+ async (payload) => {
+ await removeAllUsersFromCache();
+ }
+ );
+}
+
+function addCleanCacheConsumerForRoleUpdated(messageBus: RabbitMessageBus) {
+ messageBus.registerConsumer(
+ 'svelte-ui-clean-cache-role-updated',
+ 'UbikLink.Security.Contracts.Roles.Events:CleanCacheRoleUpdated',
+ async (payload) => {
+ await removeAllUsersFromCache();
+ }
+ );
+}
+
+function redirectToLogin(event: any): Response {
+ event.locals.session = null;
+ event.locals.user = null;
+ return new Response(null, {
+ status: 302,
+ headers: { location: LOGIN_URL }
+ });
+}
+
+function onShutdownRabbit(rabbit: RabbitMessageBus) {
+ process.on('SIGINT', async () => {
+ await shutdownRabbit(rabbit);
+ process.exit(0);
+ });
+
+ process.on('SIGTERM', async () => {
+ await shutdownRabbit(rabbit);
+ process.exit(0);
+ });
+}
+
+async function shutdownRabbit(rabbit: RabbitMessageBus) {
+ for (const consumer of rabbit.consumers) {
+ await consumer.close();
+ }
+ await rabbit.connection?.close();
+ console.log('RabbitMQ consumers stopped and connection closed');
+}
+
+interface CleanCacheForUserRequestSent {
+ userId: Guid;
+ tenantId?: Guid | null;
+ authId: string;
+}
+
+interface CleanCacheTenantUpdated {
+ tenantId: Guid;
+}
+
+interface CleanCacheTenantDeleted {
+ tenantId: Guid;
+}
+
+interface CleanCacheRoleDeleted {
+ roleId: Guid;
+ tenantId?: Guid | null;
+}
+
+//For the moment, we only manage system roles so we clean the complete cache
+//But if one day we will have tenant specific roles, we will need to clean only the cache for the tenant
+interface CleanCacheRoleUpdated {
+ roleId: Guid;
+ tenantId?: Guid | null;
+}
diff --git a/svelte-link-ui/src/lib/components/toggle-theme.svelte b/svelte-link-ui/src/lib/components/toggle-theme.svelte
new file mode 100644
index 0000000..d3d3ae8
--- /dev/null
+++ b/svelte-link-ui/src/lib/components/toggle-theme.svelte
@@ -0,0 +1,17 @@
+
+
+
diff --git a/svelte-link-ui/src/lib/components/ui/button/button.svelte b/svelte-link-ui/src/lib/components/ui/button/button.svelte
new file mode 100644
index 0000000..1ed3a9e
--- /dev/null
+++ b/svelte-link-ui/src/lib/components/ui/button/button.svelte
@@ -0,0 +1,68 @@
+
+
+
+
+{#if href}
+
+ {@render children?.()}
+
+{:else}
+
+{/if}
diff --git a/svelte-link-ui/src/lib/components/ui/button/index.ts b/svelte-link-ui/src/lib/components/ui/button/index.ts
new file mode 100644
index 0000000..5414d9d
--- /dev/null
+++ b/svelte-link-ui/src/lib/components/ui/button/index.ts
@@ -0,0 +1,17 @@
+import Root, {
+ type ButtonProps,
+ type ButtonSize,
+ type ButtonVariant,
+ buttonVariants
+} from './button.svelte';
+
+export {
+ Root,
+ type ButtonProps as Props,
+ //
+ Root as Button,
+ buttonVariants,
+ type ButtonProps,
+ type ButtonSize,
+ type ButtonVariant
+};
diff --git a/svelte-link-ui/src/lib/index.ts b/svelte-link-ui/src/lib/index.ts
new file mode 100644
index 0000000..856f2b6
--- /dev/null
+++ b/svelte-link-ui/src/lib/index.ts
@@ -0,0 +1 @@
+// place files you want to import through the `$lib` alias in this folder.
diff --git a/svelte-link-ui/src/lib/server/backend-token.ts b/svelte-link-ui/src/lib/server/backend-token.ts
new file mode 100644
index 0000000..3958c4c
--- /dev/null
+++ b/svelte-link-ui/src/lib/server/backend-token.ts
@@ -0,0 +1,103 @@
+import { redis } from './redis';
+import { keycloak } from './oauth';
+import CryptoJS from 'crypto-js';
+import { TOKEN_STORE_SECRET } from '$env/static/private';
+
+export interface AuthToken {
+ key: string;
+ idToken: string;
+ accessToken: string;
+ refreshToken: string;
+ expiresUtc: Date;
+ expiresRefreshUtc: Date;
+}
+
+export async function createAuthTokenInCache(
+ key: string,
+ idToken: string,
+ accessToken: string,
+ refreshToken: string,
+ expiresUtc: Date,
+ expiresRefreshUtc: Date
+): Promise {
+ const tokens: AuthToken = {
+ key,
+ idToken,
+ accessToken,
+ refreshToken,
+ expiresUtc,
+ expiresRefreshUtc
+ };
+
+ const keyForCache = TOKEN_STORE_SECRET;
+
+ if (!keyForCache)
+ throw new Error('TOKEN_STORE_SECRET environment variable is not set or is empty');
+
+ await redis.set(
+ `jsapp-token:${key}`,
+ CryptoJS.AES.encrypt(JSON.stringify(tokens), keyForCache).toString(),
+ 'EX',
+ Math.floor((tokens.expiresRefreshUtc.getTime() - Date.now()) / 1000)
+ );
+
+ return tokens;
+}
+
+export async function removeAuthTokenFromCache(key: string): Promise {
+ await redis.del(`jsapp-token:${key}`);
+}
+
+export async function getAuthToken(key: string, sessionExpiresAt: Date): Promise {
+ const cache = await redis.get(`jsapp-token:${key}`);
+
+ if (cache === null) {
+ return null;
+ }
+
+ if (!TOKEN_STORE_SECRET)
+ throw new Error('TOKEN_STORE_SECRET environment variable is not set or is empty');
+
+ const tokens = CryptoJS.AES.decrypt(cache, TOKEN_STORE_SECRET).toString(CryptoJS.enc.Utf8);
+
+ const result = JSON.parse(tokens);
+
+ const expiresUtcDate = new Date(result.expiresUtc);
+ if (Date.now() + 60000 > expiresUtcDate.getTime()) {
+ return await refreshTokenAndCache(result.refreshToken, result.key, sessionExpiresAt);
+ }
+
+ return result;
+}
+
+//Refresh with race codition protection
+export async function refreshTokenAndCache(
+ refreshToken: string,
+ authId: string,
+ sessionExpiresAt: Date
+): Promise {
+ //Lock with redis
+ const lockKey = `lock:jsapp-token:${authId}`;
+ const lockAcquired = await redis.set(lockKey, 'locked', 'EX', 60, 'NX');
+ if (lockAcquired) {
+ try {
+ const response = await keycloak.refreshAccessToken(refreshToken);
+ const tokens = await createAuthTokenInCache(
+ authId,
+ response.idToken(),
+ response.accessToken(),
+ response.refreshToken(),
+ response.accessTokenExpiresAt(),
+ sessionExpiresAt
+ );
+ return tokens;
+ } catch {
+ return null;
+ } finally {
+ await redis.del(lockKey);
+ }
+ } else {
+ await new Promise((resolve) => setTimeout(resolve, 100));
+ return await refreshTokenAndCache(refreshToken, authId, sessionExpiresAt);
+ }
+}
diff --git a/svelte-link-ui/src/lib/server/current-user.ts b/svelte-link-ui/src/lib/server/current-user.ts
new file mode 100644
index 0000000..62f2666
--- /dev/null
+++ b/svelte-link-ui/src/lib/server/current-user.ts
@@ -0,0 +1,31 @@
+import { invalidateSession, deleteSessionTokenCookie } from './session';
+import { getAuthToken, removeAuthTokenFromCache } from './backend-token';
+import { logout } from './oauth';
+import { removeUserFromCache, getUserFromCache } from './user';
+import type { Session } from './session';
+import type { RequestEvent } from '../../routes/app/$types';
+
+export async function fullLogout(event: RequestEvent): Promise {
+ const session = event.locals.session;
+ await invalidateSession(session.id, session.userId);
+ deleteSessionTokenCookie(event);
+ //Logout from keycloak and clean tokens
+ const tokens = await getAuthToken(session.userId, session.expiresAt);
+ if (tokens !== null) {
+ logout(tokens?.refreshToken);
+ await removeAuthTokenFromCache(session.userId);
+ }
+
+ //Clean user
+ const user = await getUserFromCache(session.userId);
+ if (user !== null) {
+ await removeUserFromCache(user.authId, user.selectedTenantId);
+ }
+}
+
+export function checkIsLogged(event: RequestEvent): boolean {
+ if (event.locals.session === null || event.locals.user === null) {
+ return false;
+ }
+ return true;
+}
diff --git a/svelte-link-ui/src/lib/server/messaging.ts b/svelte-link-ui/src/lib/server/messaging.ts
new file mode 100644
index 0000000..345f446
--- /dev/null
+++ b/svelte-link-ui/src/lib/server/messaging.ts
@@ -0,0 +1,142 @@
+import { RABBIT_MQ_CONNECTION } from '$env/static/private';
+import { Connection, type Consumer } from 'rabbitmq-client';
+import { Buffer } from 'buffer';
+
+export class RabbitMessageBus {
+ private _connection: Connection | null = null;
+ private _consumers: Consumer[] = [];
+
+ constructor(connection: Connection | null = null) {
+ if (connection) {
+ this._connection = connection;
+ } else {
+ this._connection = this.rabbitMQConnection();
+ }
+ }
+
+ get connection(): Connection | null {
+ return this._connection;
+ }
+
+ get consumers(): Consumer[] {
+ return this._consumers;
+ }
+
+ public initConnection(): void {
+ if (!this._connection) {
+ this._connection = this.rabbitMQConnection();
+ }
+ }
+
+ private rabbitMQConnection(): Connection {
+ const con = new Connection(RABBIT_MQ_CONNECTION);
+
+ con.on('error', (err) => {
+ console.error('RabbitMQ connection error', err);
+ });
+ con.on('connection', () => {
+ console.log('Connection successfully (re)established');
+ });
+
+ return con;
+ }
+
+ public registerConsumer(
+ queueName: string,
+ sourceName: string,
+ handler: (payload: T) => Promise
+ ) {
+ if (!this._connection) {
+ throw new Error('Connection not initialized');
+ }
+ const sub = this._connection.createConsumer(
+ {
+ queue: queueName,
+ queueOptions: { durable: true },
+ qos: { prefetchCount: 2 },
+ exchanges: [{ exchange: queueName, type: 'fanout' }],
+ exchangeBindings: [
+ {
+ source: sourceName,
+ destination: queueName,
+ routingKey: '*'
+ }
+ ],
+ queueBindings: [{ exchange: queueName, routingKey: '*' }],
+ consumerTag: queueName
+ },
+ async (msg) => {
+ try {
+ const message: MasstransitMessage = msg as MasstransitMessage;
+ const payload = this.parseMessageBody(message);
+ await handler(payload);
+ } catch (error) {
+ console.error('Error processing message', error);
+ }
+ }
+ );
+
+ sub.on('error', (err) => {
+ console.error('Consumer error (user-events)', err);
+ });
+
+ this._consumers.push(sub);
+ }
+
+ private parseMessageBody(msg: MasstransitMessage): T {
+ const bodyString = msg.body.toString('utf-8');
+ const envelope: MasstransitEnvelope = JSON.parse(bodyString);
+ return envelope.message;
+ }
+}
+
+interface MasstransitMessage {
+ consumerTag: string;
+ deliveryTag: number;
+ redelivered: boolean;
+ exchange: string;
+ routingKey: string;
+ contentType: string;
+ headers: {
+ 'MT-Activity-Id': string;
+ TenantId: string;
+ UserId: string;
+ publishId: string;
+ };
+ deliveryMode: number;
+ priority: number;
+ messageId: string;
+ durable: boolean;
+ body: Buffer;
+}
+
+interface MasstransitEnvelope {
+ messageId: string;
+ requestId: string | null;
+ correlationId: string | null;
+ conversationId: string;
+ initiatorId: string | null;
+ sourceAddress: string;
+ destinationAddress: string;
+ responseAddress: string | null;
+ faultAddress: string | null;
+ messageType: string[];
+ message: T;
+ expirationTime: string | null;
+ sentTime: string;
+ headers: {
+ TenantId: string;
+ UserId: string;
+ 'MT-Activity-Id': string;
+ };
+ host: {
+ machineName: string;
+ processName: string;
+ processId: number;
+ assembly: string;
+ assemblyVersion: string;
+ frameworkVersion: string;
+ massTransitVersion: string;
+ operatingSystemVersion: string;
+ };
+}
diff --git a/svelte-link-ui/src/lib/server/oauth.ts b/svelte-link-ui/src/lib/server/oauth.ts
new file mode 100644
index 0000000..4abd5a2
--- /dev/null
+++ b/svelte-link-ui/src/lib/server/oauth.ts
@@ -0,0 +1,45 @@
+import { KeyCloak } from 'arctic';
+import {
+ OIDC_ISSUER,
+ OIDC_CLIENT_ID,
+ OIDC_CLIENT_SECRET,
+ OIDC_REDIRECT_URI
+} from '$env/static/private';
+
+export const keycloak = new KeyCloak(
+ OIDC_ISSUER || '',
+ OIDC_CLIENT_ID || '',
+ OIDC_CLIENT_SECRET || '',
+ OIDC_REDIRECT_URI || ''
+);
+
+export async function logout(refreshToken: string) {
+ const params = {
+ client_id: OIDC_CLIENT_ID || '',
+ client_secret: OIDC_CLIENT_SECRET || '',
+ grant_type: 'refresh_token'
+ };
+
+ const response = await fetch(`${OIDC_ISSUER}/protocol/openid-connect/logout`, {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/x-www-form-urlencoded'
+ },
+ body: new URLSearchParams({
+ refresh_token: refreshToken,
+ ...params
+ }),
+ credentials: 'include'
+ });
+
+ if (!response.ok) {
+ throw new Error(`Logout failed: ${response.statusText}`);
+ }
+
+ const text = await response.text();
+ if (text) {
+ return JSON.parse(text);
+ } else {
+ return {}; // or handle the empty response case as needed
+ }
+}
diff --git a/svelte-link-ui/src/lib/server/rate-limit.ts b/svelte-link-ui/src/lib/server/rate-limit.ts
new file mode 100644
index 0000000..b8d2a0f
--- /dev/null
+++ b/svelte-link-ui/src/lib/server/rate-limit.ts
@@ -0,0 +1,53 @@
+export class TokenBucket<_Key> {
+ public max: number;
+ public refillIntervalSeconds: number;
+
+ constructor(max: number, refillIntervalSeconds: number) {
+ this.max = max;
+ this.refillIntervalSeconds = refillIntervalSeconds;
+ }
+
+ private storage = new Map<_Key, Bucket>();
+
+ public check(key: _Key, cost: number): boolean {
+ const bucket = this.storage.get(key) ?? null;
+ if (bucket === null) {
+ return true;
+ }
+ const now = Date.now();
+ const refill = Math.floor((now - bucket.refilledAt) / (this.refillIntervalSeconds * 1000));
+ if (refill > 0) {
+ return Math.min(bucket.count + refill, this.max) >= cost;
+ }
+ return bucket.count >= cost;
+ }
+
+ public consume(key: _Key, cost: number): boolean {
+ let bucket = this.storage.get(key) ?? null;
+ const now = Date.now();
+ if (bucket === null) {
+ bucket = {
+ count: this.max - cost,
+ refilledAt: now
+ };
+ this.storage.set(key, bucket);
+ return true;
+ }
+ const refill = Math.floor((now - bucket.refilledAt) / (this.refillIntervalSeconds * 1000));
+ if (refill > 0) {
+ bucket.count = Math.min(bucket.count + refill, this.max);
+ bucket.refilledAt = now;
+ }
+ if (bucket.count < cost) {
+ this.storage.set(key, bucket);
+ return false;
+ }
+ bucket.count -= cost;
+ this.storage.set(key, bucket);
+ return true;
+ }
+}
+interface Bucket {
+ count: number;
+ refilledAt: number;
+}
diff --git a/svelte-link-ui/src/lib/server/redis.ts b/svelte-link-ui/src/lib/server/redis.ts
new file mode 100644
index 0000000..72953aa
--- /dev/null
+++ b/svelte-link-ui/src/lib/server/redis.ts
@@ -0,0 +1,9 @@
+import { Redis } from 'ioredis';
+import { REDIS_HOST, REDIS_PORT } from '$env/static/private';
+
+const redis = new Redis({
+ port: Number(REDIS_PORT),
+ host: REDIS_HOST
+});
+
+export { redis };
diff --git a/svelte-link-ui/src/lib/server/session.ts b/svelte-link-ui/src/lib/server/session.ts
new file mode 100644
index 0000000..2e697a4
--- /dev/null
+++ b/svelte-link-ui/src/lib/server/session.ts
@@ -0,0 +1,121 @@
+import { redis } from './redis';
+import { encodeBase32LowerCaseNoPadding, encodeHexLowerCase } from '@oslojs/encoding';
+import { sha256 } from '@oslojs/crypto/sha2';
+import type { RequestEvent } from '@sveltejs/kit';
+
+export function generateSessionToken(): string {
+ const bytes = new Uint8Array(20);
+ crypto.getRandomValues(bytes);
+ const token = encodeBase32LowerCaseNoPadding(bytes);
+ return token;
+}
+
+export async function createSession(token: string, userId: string): Promise {
+ const sessionId = encodeHexLowerCase(sha256(new TextEncoder().encode(token)));
+ const session: Session = {
+ id: sessionId,
+ userId,
+ expiresAt: new Date(Date.now() + 1000 * 60 * 60 * 24 * 30)
+ };
+ await redis.set(
+ `session:${session.id}`,
+ JSON.stringify({
+ id: session.id,
+ user_id: session.userId,
+ expires_at: Math.floor(session.expiresAt.getTime() / 1000)
+ }),
+ 'EX',
+ Math.floor((session.expiresAt.getTime() - Date.now()) / 1000)
+ );
+ await redis.sadd(`user_sessions:${userId}`, sessionId);
+
+ return session;
+}
+
+export async function validateSessionToken(token: string): Promise {
+ const sessionId = encodeHexLowerCase(sha256(new TextEncoder().encode(token)));
+ const item = await redis.get(`session:${sessionId}`);
+ if (item === null) {
+ return null;
+ }
+
+ const result = JSON.parse(item);
+ const session: Session = {
+ id: result.id,
+ userId: result.user_id,
+ expiresAt: new Date(result.expires_at * 1000)
+ };
+
+ if (Date.now() >= session.expiresAt.getTime()) {
+ await redis.del(`session:${sessionId}`);
+ await redis.srem(`user_sessions:${session.userId}`, sessionId);
+ return null;
+ }
+ if (Date.now() >= session.expiresAt.getTime() - 1000 * 60 * 60 * 24 * 15) {
+ session.expiresAt = new Date(Date.now() + 1000 * 60 * 60 * 24 * 30);
+ await redis.set(
+ `session:${session.id}`,
+ JSON.stringify({
+ id: session.id,
+ user_id: session.userId,
+ expires_at: Math.floor(session.expiresAt.getTime() / 1000)
+ }),
+ 'EX',
+ Math.floor(session.expiresAt.getTime() / 1000)
+ );
+ }
+ return session;
+}
+
+export async function invalidateSession(sessionId: string, userId: string): Promise {
+ await redis.del(`session:${sessionId}`);
+ await redis.srem(`user_sessions:${userId}`, sessionId);
+}
+
+export async function invalidateAllSessions(userId: string): Promise {
+ const sessionIds = await redis.smembers(`user_sessions:${userId}`);
+ if (sessionIds.length < 1) {
+ return;
+ }
+
+ const pipeline = redis.pipeline();
+
+ for (const sessionId of sessionIds) {
+ pipeline.unlink(`session:${sessionId}`);
+ }
+ pipeline.unlink(`user_sessions:${userId}`);
+
+ await pipeline.exec();
+}
+
+export async function setSessionTokenCookie(
+ event: RequestEvent,
+ token: string,
+ expiresAt: Date
+): Promise {
+ event.cookies.set('session', token, {
+ httpOnly: true,
+ path: '/',
+ secure: import.meta.env.PROD,
+ sameSite: 'lax',
+ expires: expiresAt
+ });
+}
+
+export function deleteSessionTokenCookie(event: RequestEvent): void {
+ event.cookies.set('session', '', {
+ httpOnly: true,
+ path: '/',
+ secure: import.meta.env.PROD,
+ sameSite: 'lax',
+ maxAge: 0
+ });
+}
+
+export interface Session {
+ id: string;
+ userId: string;
+ expiresAt: Date;
+}
+
+type SessionValidationResult = Session | null;
diff --git a/svelte-link-ui/src/lib/server/user.ts b/svelte-link-ui/src/lib/server/user.ts
new file mode 100644
index 0000000..649afb3
--- /dev/null
+++ b/svelte-link-ui/src/lib/server/user.ts
@@ -0,0 +1,139 @@
+import { redis } from './redis';
+import { Guid } from 'guid-ts';
+import { BACKEND_PROXY_URL } from '$env/static/private';
+
+export async function createUserInCache(user: UserMeResult, expires: Date): Promise {
+ await redis.set(
+ `jsapp-user:${user.authId}`,
+ JSON.stringify(user),
+ 'EX',
+ Math.floor((expires.getTime() - Date.now()) / 1000)
+ );
+
+ await redis.sadd(`jsapp-users-tenant:${user.selectedTenantId}`, `jsapp-user:${user.authId}`);
+ await redis.sadd(`jsapp-users`, `jsapp-user:${user.authId}`);
+ return user;
+}
+
+export async function getUser(authId: string, accessToken: string): Promise {
+ const user = await getUserFromCache(authId);
+
+ if (user !== null) {
+ return user;
+ }
+
+ // Fetch the user from the backend and put it in the cache
+ const response = await fetch(`${BACKEND_PROXY_URL}/security/api/v1/me/authinfo`, {
+ headers: {
+ Authorization: `Bearer ${accessToken}`
+ }
+ });
+
+ if (!response.ok) {
+ return null;
+ }
+ const userFromBackend: UserMeResult = await response.json();
+
+ //Create user in cache for next time
+ await createUserInCache(userFromBackend, new Date(Date.now() + 3600 * 1000 * 24)); // Cache for 1 day
+
+ return userFromBackend;
+}
+
+export async function getUserFromCache(authId: string): Promise {
+ const user = await redis.get(`jsapp-user:${authId}`);
+
+ if (user === null) {
+ return null;
+ }
+
+ const result = JSON.parse(user);
+ return result;
+}
+
+export async function removeAllUsersFromCacheByTenantId(tenantId: string): Promise {
+ console.log('Cleaning cache for tenant', tenantId);
+ // Get all user keys associated with the tenantId
+ const userKeys = await redis.smembers(`jsapp-users-tenant:${tenantId}`);
+
+ // Use a pipeline to execute multiple commands in a single round-trip
+ const pipeline = redis.pipeline();
+
+ // Delete each user key and remove it from the global user set
+ for (const userKey of userKeys) {
+ pipeline.del(userKey);
+ pipeline.srem(`jsapp-users`, userKey);
+ }
+
+ // Remove the tenant's user set
+ pipeline.del(`jsapp-users-tenant:${tenantId}`);
+
+ // Execute the pipeline
+ await pipeline.exec();
+ console.log('Cache cleaned for tenant', tenantId);
+}
+
+export async function removeUserFromCache(
+ userAuthId: string,
+ tenantId: string | null
+): Promise {
+ console.log('Removing user from cache', userAuthId);
+ await redis.del(`jsapp-user:${userAuthId}`);
+ await redis.srem(`jsapp-users`, `jsapp-user:${userAuthId}`);
+ if (tenantId !== null) {
+ await redis.srem(`jsapp-users-tenant:${tenantId}`, `jsapp-user:${userAuthId}`);
+ }
+ console.log('User removed from cache', userAuthId);
+}
+
+export async function removeAllUsersFromCache(): Promise {
+ console.log('Cleaning all cache entries and members');
+
+ // Use a pipeline to execute multiple commands in a single round-trip
+ const pipeline = redis.pipeline();
+
+ // Define patterns for keys and sets to be removed
+ const patterns = [
+ 'jsapp-users', // Global user set
+ 'jsapp-users-tenant:*', // Tenant user sets
+ 'jsapp-user:*' // User keys
+ ];
+
+ // Find keys matching the patterns and add delete commands to the pipeline
+ for (const pattern of patterns) {
+ const keys = await redis.keys(pattern);
+ for (const key of keys) {
+ pipeline.del(key);
+ }
+ }
+
+ // Execute the pipeline
+ await pipeline.exec();
+ console.log('All cache entries and members cleaned');
+}
+
+export interface UserMeResult {
+ id: Guid;
+ authId: string;
+ firstname: string;
+ lastname: string;
+ email: string;
+ isActivatedInSelectedSubscription: boolean;
+ isMegaAdmin: boolean;
+ ownerOfSubscriptionsIds: string[];
+ selectedTenantId: string | null;
+ isSubOwnerOfTheSelectedTenant: boolean;
+ selectedTenantAuthorizations: AuthorizationLightResult[];
+ selectedTenantRoles: RoleLightResult[];
+ version: string;
+}
+
+export interface AuthorizationLightResult {
+ id: string;
+ code: string;
+}
+
+export interface RoleLightResult {
+ id: string;
+ code: string;
+}
diff --git a/svelte-link-ui/src/lib/utils.ts b/svelte-link-ui/src/lib/utils.ts
new file mode 100644
index 0000000..256f86f
--- /dev/null
+++ b/svelte-link-ui/src/lib/utils.ts
@@ -0,0 +1,6 @@
+import { type ClassValue, clsx } from 'clsx';
+import { twMerge } from 'tailwind-merge';
+
+export function cn(...inputs: ClassValue[]) {
+ return twMerge(clsx(inputs));
+}
diff --git a/svelte-link-ui/src/routes/+layout.svelte b/svelte-link-ui/src/routes/+layout.svelte
new file mode 100644
index 0000000..9a1efd7
--- /dev/null
+++ b/svelte-link-ui/src/routes/+layout.svelte
@@ -0,0 +1,14 @@
+
+
+
+ Example secu
+
+
+
+
+ {@render children?.()}
+
diff --git a/svelte-link-ui/src/routes/+page.svelte b/svelte-link-ui/src/routes/+page.svelte
new file mode 100644
index 0000000..7d94fb0
--- /dev/null
+++ b/svelte-link-ui/src/routes/+page.svelte
@@ -0,0 +1,8 @@
+
+
+Public zone
+That 100k landing page.
+
+
diff --git a/svelte-link-ui/src/routes/app/+page.server.ts b/svelte-link-ui/src/routes/app/+page.server.ts
new file mode 100644
index 0000000..e26277e
--- /dev/null
+++ b/svelte-link-ui/src/routes/app/+page.server.ts
@@ -0,0 +1,21 @@
+import { redirect } from '@sveltejs/kit';
+import { fullLogout } from '$lib/server/current-user';
+import type { UserMeResult } from '$lib/server/user';
+
+import type { Actions, RequestEvent } from './$types';
+
+export async function load(event: RequestEvent) {
+ return {
+ user: event.locals.user as UserMeResult
+ };
+}
+
+export const actions: Actions = {
+ default: action
+};
+
+async function action(event: RequestEvent) {
+ await fullLogout(event);
+
+ return redirect(302, '/login');
+}
diff --git a/svelte-link-ui/src/routes/app/+page.svelte b/svelte-link-ui/src/routes/app/+page.svelte
new file mode 100644
index 0000000..6d7ffc1
--- /dev/null
+++ b/svelte-link-ui/src/routes/app/+page.svelte
@@ -0,0 +1,41 @@
+
+
+
+
Hi, {user.firstname} {user.lastname}!
+
+
+You are connected, and here, you can look at your security info
+
+ - ID: {user.id}
+ - Auth ID: {user.authId}
+ - First Name: {user.firstname}
+ - Last Name: {user.lastname}
+ - Email: {user.email}
+ -
+ Is Activated In Selected Subscription: {user.isActivatedInSelectedSubscription ? 'Yes' : 'No'}
+
+ - Is Mega Admin: {user.isMegaAdmin ? 'Yes' : 'No'}
+ - Owner Of Subscriptions IDs: {user.ownerOfSubscriptionsIds.join(', ')}
+ - Selected Tenant ID: {user.selectedTenantId}
+ - Is Sub Owner Of The Selected Tenant: {user.isSubOwnerOfTheSelectedTenant ? 'Yes' : 'No'}
+ -
+ Selected Tenant Authorizations: {user.selectedTenantAuthorizations
+ .map((auth) => auth.code)
+ .join(', ')}
+
+ - Selected Tenant Roles: {user.selectedTenantRoles.map((role) => role.code).join(', ')}
+ - Version: {user.version}
+
+
+
diff --git a/svelte-link-ui/src/routes/login/+page.svelte b/svelte-link-ui/src/routes/login/+page.svelte
new file mode 100644
index 0000000..186e9a7
--- /dev/null
+++ b/svelte-link-ui/src/routes/login/+page.svelte
@@ -0,0 +1,8 @@
+
+
+Welcome to the app
+Best app in the world !
+
+
diff --git a/svelte-link-ui/src/routes/login/auth/+server.ts b/svelte-link-ui/src/routes/login/auth/+server.ts
new file mode 100644
index 0000000..cce84e8
--- /dev/null
+++ b/svelte-link-ui/src/routes/login/auth/+server.ts
@@ -0,0 +1,34 @@
+import { generateState, generateCodeVerifier } from 'arctic';
+import { keycloak } from '$lib/server/oauth';
+
+import type { RequestEvent } from '@sveltejs/kit';
+
+export async function GET(event: RequestEvent): Promise {
+ const state = generateState();
+ const codeVerifier = generateCodeVerifier();
+ const url = keycloak.createAuthorizationURL(state, codeVerifier, [
+ 'openid',
+ 'profile',
+ 'offline_access'
+ ]);
+
+ event.cookies.set('keycloak_oauth_state', state, {
+ path: '/',
+ httpOnly: true,
+ maxAge: 60 * 10, // 10 minutes
+ sameSite: 'lax'
+ });
+ event.cookies.set('keycloak_code_verifier', codeVerifier, {
+ path: '/',
+ httpOnly: true,
+ maxAge: 60 * 10, // 10 minutes
+ sameSite: 'lax'
+ });
+
+ return new Response(null, {
+ status: 302,
+ headers: {
+ Location: url.toString()
+ }
+ });
+}
diff --git a/svelte-link-ui/src/routes/login/auth/callback/+server.ts b/svelte-link-ui/src/routes/login/auth/callback/+server.ts
new file mode 100644
index 0000000..6699dc4
--- /dev/null
+++ b/svelte-link-ui/src/routes/login/auth/callback/+server.ts
@@ -0,0 +1,84 @@
+import { generateSessionToken, createSession, setSessionTokenCookie } from '$lib/server/session';
+import { keycloak } from '$lib/server/oauth';
+import { getUser } from '$lib/server/user';
+import { createAuthTokenInCache } from '$lib/server/backend-token';
+import { decodeIdToken } from 'arctic';
+import type { OAuth2Tokens } from 'arctic';
+import { getUserFromCache } from '$lib/server/user';
+import type { RequestEvent } from '@sveltejs/kit';
+import { ObjectParser } from '@pilcrowjs/object-parser';
+
+export async function GET(event: RequestEvent): Promise {
+ const code = event.url.searchParams.get('code');
+ const state = event.url.searchParams.get('state');
+ const storedState = event.cookies.get('keycloak_oauth_state') ?? null;
+ const codeVerifier = event.cookies.get('keycloak_code_verifier') ?? null;
+
+ if (code === null || state === null || storedState === null || codeVerifier === null) {
+ return new Response(null, {
+ status: 400
+ });
+ }
+ if (state !== storedState) {
+ return new Response(null, {
+ status: 400
+ });
+ }
+
+ let tokens: OAuth2Tokens;
+ try {
+ tokens = await keycloak.validateAuthorizationCode(code, codeVerifier);
+ } catch (e) {
+ // Invalid code or client credentials
+ return new Response(null, {
+ status: 400
+ });
+ }
+ const claims = decodeIdToken(tokens.idToken());
+ const claimsParser = new ObjectParser(claims);
+ const keycloakUserId = claimsParser.getString('sub');
+
+ // Try to get the user from cache or the backend
+ const existingUser = await getUser(keycloakUserId, tokens.accessToken());
+
+ if (existingUser !== null) {
+ //Session and cookie
+ const sessionToken = generateSessionToken();
+ const session = await createSession(sessionToken, existingUser.authId);
+ await setSessionTokenCookie(event, sessionToken, session.expiresAt);
+
+ //Store token in cache
+ await createAuthTokenInCache(
+ existingUser.authId,
+ tokens.idToken(),
+ tokens.accessToken(),
+ tokens.refreshToken(),
+ tokens.accessTokenExpiresAt(),
+ session.expiresAt
+ );
+
+ return new Response(null, {
+ status: 302,
+ headers: {
+ Location: '/app'
+ }
+ });
+ } else {
+ return new Response(null, {
+ status: 401
+ });
+ }
+
+ // TODO: Use that for onboarding (maybe)
+ // const user = await createUser(keycloakUserId, username);
+
+ // const sessionToken = generateSessionToken();
+ // const session = await createSession(sessionToken, user.id);
+ // await setSessionTokenCookie(sessionToken, session.expiresAt);
+ // return new Response(null, {
+ // status: 302,
+ // headers: {
+ // Location: "/"
+ // }
+ // });
+}
diff --git a/svelte-link-ui/src/tailwindcss-animate.css b/svelte-link-ui/src/tailwindcss-animate.css
new file mode 100644
index 0000000..38bfdbd
--- /dev/null
+++ b/svelte-link-ui/src/tailwindcss-animate.css
@@ -0,0 +1,149 @@
+@theme inline {
+ --animation-delay-0: 0s;
+ --animation-delay-75: 75ms;
+ --animation-delay-100: 0.1s;
+ --animation-delay-150: 0.15s;
+ --animation-delay-200: 0.2s;
+ --animation-delay-300: 0.3s;
+ --animation-delay-500: 0.5s;
+ --animation-delay-700: 0.7s;
+ --animation-delay-1000: 1s;
+
+ --animation-repeat-0: 0;
+ --animation-repeat-1: 1;
+ --animation-repeat-infinite: infinite;
+
+ --animation-direction-normal: normal;
+ --animation-direction-reverse: reverse;
+ --animation-direction-alternate: alternate;
+ --animation-direction-alternate-reverse: alternate-reverse;
+
+ --animation-fill-mode-none: none;
+ --animation-fill-mode-forwards: forwards;
+ --animation-fill-mode-backwards: backwards;
+ --animation-fill-mode-both: both;
+
+ --animate-in: var(--tw-duration, 150ms) var(--tw-ease, ease) enter;
+ --animate-out: var(--tw-duration, 150ms) var(--tw-ease, ease) exit;
+
+ --percentage-0: 0;
+ --percentage-5: 0.05;
+ --percentage-10: 0.1;
+ --percentage-15: 0.15;
+ --percentage-20: 0.2;
+ --percentage-25: 0.25;
+ --percentage-30: 0.3;
+ --percentage-35: 0.35;
+ --percentage-40: 0.4;
+ --percentage-45: 0.45;
+ --percentage-50: 0.5;
+ --percentage-55: 0.55;
+ --percentage-60: 0.6;
+ --percentage-65: 0.65;
+ --percentage-70: 0.7;
+ --percentage-75: 0.75;
+ --percentage-80: 0.8;
+ --percentage-85: 0.85;
+ --percentage-90: 0.9;
+ --percentage-95: 0.95;
+ --percentage-100: 1;
+
+ @keyframes enter {
+ from {
+ opacity: var(--tw-enter-opacity, 1);
+ transform: translate3d(var(--tw-enter-translate-x, 0), var(--tw-enter-translate-y, 0), 0)
+ scale3d(var(--tw-enter-scale, 1), var(--tw-enter-scale, 1), var(--tw-enter-scale, 1))
+ rotate(var(--tw-enter-rotate, 0));
+ }
+ }
+
+ @keyframes exit {
+ to {
+ opacity: var(--tw-exit-opacity, 1);
+ transform: translate3d(var(--tw-exit-translate-x, 0), var(--tw-exit-translate-y, 0), 0)
+ scale3d(var(--tw-exit-scale, 1), var(--tw-exit-scale, 1), var(--tw-exit-scale, 1))
+ rotate(var(--tw-exit-rotate, 0));
+ }
+ }
+}
+
+/*
+ * Tailwind's default `duration` utility sets the `--tw-duration` variable, so
+ * can set `animation-duration` directly in the animation definition in the
+ * `@theme` section above. Same goes for the `animation-timing-function`, set
+ * with `--tw-ease`.
+ */
+
+@utility delay-* {
+ animation-delay: --value([duration]);
+ animation-delay: calc(--value(integer) * 1ms);
+ animation-delay: --value(--animation-delay- *);
+}
+
+@utility repeat-* {
+ animation-iteration-count: --value(--animation-repeat- *, integer);
+}
+
+@utility direction-* {
+ animation-direction: --value(--animation-direction- *);
+}
+
+@utility fill-mode-* {
+ animation-fill-mode: --value(--animation-fill-mode- *);
+}
+
+@utility running {
+ animation-play-state: running;
+}
+@utility paused {
+ animation-play-state: paused;
+}
+
+@utility fade-in-* {
+ --tw-enter-opacity: --value(--percentage- *);
+}
+@utility fade-out-* {
+ --tw-exit-opacity: --value(--percentage- *);
+}
+
+@utility zoom-in-* {
+ --tw-enter-scale: --value(--percentage- *);
+}
+@utility zoom-out-* {
+ --tw-exit-scale: --value(--percentage- *);
+}
+
+@utility spin-in-* {
+ --tw-enter-rotate: calc(--value(integer) * 1deg);
+ --tw-enter-rotate: --value(--rotate- *, [angle]);
+}
+@utility spin-out-* {
+ --tw-exit-rotate: calc(--value(integer) * 1deg);
+ --tw-exit-rotate: --value(--rotate- *, [angle]);
+}
+
+@utility slide-in-from-top-* {
+ --tw-enter-translate-y: calc(--value([percentage], [length]) * -1);
+}
+@utility slide-in-from-bottom-* {
+ --tw-enter-translate-y: --value([percentage], [length]);
+}
+@utility slide-in-from-left-* {
+ --tw-enter-translate-x: calc(--value([percentage], [length]) * -1);
+}
+@utility slide-in-from-right-* {
+ --tw-enter-translate-x: --value([percentage], [length]);
+}
+
+@utility slide-out-to-top-* {
+ --tw-exit-translate-y: calc(--value([percentage], [length]) * -1);
+}
+@utility slide-out-to-bottom-* {
+ --tw-exit-translate-y: --value([percentage], [length]);
+}
+@utility slide-out-to-left-* {
+ --tw-exit-translate-x: calc(--value([percentage], [length]) * -1);
+}
+@utility slide-out-to-right-* {
+ --tw-exit-translate-x: --value([percentage], [length]);
+}
diff --git a/svelte-link-ui/static/favicon.png b/svelte-link-ui/static/favicon.png
new file mode 100644
index 0000000..825b9e6
Binary files /dev/null and b/svelte-link-ui/static/favicon.png differ
diff --git a/svelte-link-ui/svelte.config.js b/svelte-link-ui/svelte.config.js
new file mode 100644
index 0000000..1295460
--- /dev/null
+++ b/svelte-link-ui/svelte.config.js
@@ -0,0 +1,18 @@
+import adapter from '@sveltejs/adapter-auto';
+import { vitePreprocess } from '@sveltejs/vite-plugin-svelte';
+
+/** @type {import('@sveltejs/kit').Config} */
+const config = {
+ // Consult https://svelte.dev/docs/kit/integrations
+ // for more information about preprocessors
+ preprocess: vitePreprocess(),
+
+ kit: {
+ // adapter-auto only supports some environments, see https://svelte.dev/docs/kit/adapter-auto for a list.
+ // If your environment is not supported, or you settled on a specific environment, switch out the adapter.
+ // See https://svelte.dev/docs/kit/adapters for more information about adapters.
+ adapter: adapter()
+ }
+};
+
+export default config;
diff --git a/svelte-link-ui/tmp.txt b/svelte-link-ui/tmp.txt
new file mode 100644
index 0000000..755c5ca
--- /dev/null
+++ b/svelte-link-ui/tmp.txt
@@ -0,0 +1,10 @@
+OIDC_ISSUER=http://localhost:8080/realms/ubik
+OIDC_CLIENT_ID=ubik_app
+OIDC_CLIENT_SECRET=Ye6Y36ocA4SaGqYzd0HgmqMhVaM2jlkE
+OIDC_AUDIENCE=account
+OIDC_REDIRECT_URI=http://localhost:5173/login/auth/callback
+REDIS_PORT=6379
+REDIS_HOST=localhost
+BACKEND_PROXY_URL=http://localhost:5235
+TOKEN_STORE_SECRET=Ye6Y36ocA4SaGqYzd0babaHgmqMhVaM2jlkE
+RABBIT_MQ_CONNECTION=amqp://guest:guest@localhost:58842
\ No newline at end of file
diff --git a/svelte-link-ui/tsconfig.json b/svelte-link-ui/tsconfig.json
new file mode 100644
index 0000000..0b2d886
--- /dev/null
+++ b/svelte-link-ui/tsconfig.json
@@ -0,0 +1,19 @@
+{
+ "extends": "./.svelte-kit/tsconfig.json",
+ "compilerOptions": {
+ "allowJs": true,
+ "checkJs": true,
+ "esModuleInterop": true,
+ "forceConsistentCasingInFileNames": true,
+ "resolveJsonModule": true,
+ "skipLibCheck": true,
+ "sourceMap": true,
+ "strict": true,
+ "moduleResolution": "bundler"
+ }
+ // Path aliases are handled by https://svelte.dev/docs/kit/configuration#alias
+ // except $lib which is handled by https://svelte.dev/docs/kit/configuration#files
+ //
+ // If you want to overwrite includes/excludes, make sure to copy over the relevant includes/excludes
+ // from the referenced tsconfig.json - TypeScript does not merge them in
+}
diff --git a/svelte-link-ui/vite.config.ts b/svelte-link-ui/vite.config.ts
new file mode 100644
index 0000000..dd2b1c8
--- /dev/null
+++ b/svelte-link-ui/vite.config.ts
@@ -0,0 +1,18 @@
+import { sveltekit } from '@sveltejs/kit/vite';
+import { defineConfig } from 'vite';
+import tailwindcss from '@tailwindcss/vite';
+
+export default defineConfig({
+ plugins: [tailwindcss(), sveltekit()],
+ resolve: {
+ extensions: ['.mjs', '.js', '.ts', '.json', '.svelte'],
+ alias: {
+ $components: '/src/lib/components',
+ $lib: '/src/lib',
+ $routes: '/src/routes'
+ }
+ },
+ optimizeDeps: {
+ include: ['lucide-svelte']
+ }
+});