Initial commit
This commit is contained in:
commit
d9cff2e70c
72 changed files with 2878 additions and 0 deletions
6
.env.example
Normal file
6
.env.example
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
CLIENT_URL=app.com
|
||||||
|
SERVER_URL=server.app.com
|
||||||
|
|
||||||
|
PORT=8080
|
||||||
|
PREFIXES=STA,LAB
|
||||||
|
POOL_SIZE=100
|
26
.gitignore
vendored
Normal file
26
.gitignore
vendored
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
/node_modules
|
||||||
|
|
||||||
|
# Idea
|
||||||
|
/.idea
|
||||||
|
|
||||||
|
# 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-*
|
1
.npmrc
Normal file
1
.npmrc
Normal file
|
@ -0,0 +1 @@
|
||||||
|
engine-strict=true
|
554
bun.lock
Normal file
554
bun.lock
Normal file
|
@ -0,0 +1,554 @@
|
||||||
|
{
|
||||||
|
"lockfileVersion": 1,
|
||||||
|
"workspaces": {
|
||||||
|
"": {
|
||||||
|
"name": "@hnu.de/hl7v2",
|
||||||
|
},
|
||||||
|
"packages/client": {
|
||||||
|
"name": "@hnu.de/hl7v2-client",
|
||||||
|
"version": "0.1.0",
|
||||||
|
"dependencies": {
|
||||||
|
"@hnu.de/hl7v2-shared": "workspace:*",
|
||||||
|
"dotenv": "^17.2.0",
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@internationalized/date": "^3.8.1",
|
||||||
|
"@lucide/svelte": "^0.515.0",
|
||||||
|
"@sveltejs/adapter-node": "^5.2.13",
|
||||||
|
"@sveltejs/kit": "^2.22.0",
|
||||||
|
"@sveltejs/vite-plugin-svelte": "^6.0.0",
|
||||||
|
"@tailwindcss/vite": "^4.0.0",
|
||||||
|
"@types/ws": "^8.18.1",
|
||||||
|
"bits-ui": "^2.8.6",
|
||||||
|
"clsx": "^2.1.1",
|
||||||
|
"formsnap": "^2.0.1",
|
||||||
|
"mode-watcher": "^1.1.0",
|
||||||
|
"svelte": "^5.0.0",
|
||||||
|
"svelte-check": "^4.0.0",
|
||||||
|
"sveltekit-superforms": "^2.26.1",
|
||||||
|
"tailwind-merge": "^3.3.1",
|
||||||
|
"tailwind-variants": "^1.0.0",
|
||||||
|
"tailwindcss": "^4.0.0",
|
||||||
|
"tw-animate-css": "^1.3.5",
|
||||||
|
"typescript": "^5.0.0",
|
||||||
|
"vite": "^7.0.4",
|
||||||
|
"ws": "^8.18.3",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"packages/server": {
|
||||||
|
"name": "@hnu.de/hl7v2-server",
|
||||||
|
"dependencies": {
|
||||||
|
"@hnu.de/hl7v2-shared": "workspace:*",
|
||||||
|
"dotenv": "^17.2.0",
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@types/bun": "latest",
|
||||||
|
"@types/ws": "^8.18.1",
|
||||||
|
"ws": "^8.18.3",
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"typescript": "^5.8.3",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"packages/shared": {
|
||||||
|
"name": "@hnu.de/hl7v2-shared",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"devDependencies": {
|
||||||
|
"@types/bun": "latest",
|
||||||
|
"@types/node": "^24.1.0",
|
||||||
|
"typescript": "^5.8.3",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"packages": {
|
||||||
|
"@ampproject/remapping": ["@ampproject/remapping@2.3.0", "", { "dependencies": { "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.24" } }, "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw=="],
|
||||||
|
|
||||||
|
"@ark/schema": ["@ark/schema@0.46.0", "", { "dependencies": { "@ark/util": "0.46.0" } }, "sha512-c2UQdKgP2eqqDArfBqQIJppxJHvNNXuQPeuSPlDML4rjw+f1cu0qAlzOG4b8ujgm9ctIDWwhpyw6gjG5ledIVQ=="],
|
||||||
|
|
||||||
|
"@ark/util": ["@ark/util@0.46.0", "", {}, "sha512-JPy/NGWn/lvf1WmGCPw2VGpBg5utZraE84I7wli18EDF3p3zc/e9WolT35tINeZO3l7C77SjqRJeAUoT0CvMRg=="],
|
||||||
|
|
||||||
|
"@babel/runtime": ["@babel/runtime@7.28.2", "", {}, "sha512-KHp2IflsnGywDjBWDkR9iEqiWSpc8GIi0lgTT3mOElT0PP1tG26P4tmFI2YvAdzgq9RGyoHZQEIEdZy6Ec5xCA=="],
|
||||||
|
|
||||||
|
"@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.25.8", "", { "os": "aix", "cpu": "ppc64" }, "sha512-urAvrUedIqEiFR3FYSLTWQgLu5tb+m0qZw0NBEasUeo6wuqatkMDaRT+1uABiGXEu5vqgPd7FGE1BhsAIy9QVA=="],
|
||||||
|
|
||||||
|
"@esbuild/android-arm": ["@esbuild/android-arm@0.25.8", "", { "os": "android", "cpu": "arm" }, "sha512-RONsAvGCz5oWyePVnLdZY/HHwA++nxYWIX1atInlaW6SEkwq6XkP3+cb825EUcRs5Vss/lGh/2YxAb5xqc07Uw=="],
|
||||||
|
|
||||||
|
"@esbuild/android-arm64": ["@esbuild/android-arm64@0.25.8", "", { "os": "android", "cpu": "arm64" }, "sha512-OD3p7LYzWpLhZEyATcTSJ67qB5D+20vbtr6vHlHWSQYhKtzUYrETuWThmzFpZtFsBIxRvhO07+UgVA9m0i/O1w=="],
|
||||||
|
|
||||||
|
"@esbuild/android-x64": ["@esbuild/android-x64@0.25.8", "", { "os": "android", "cpu": "x64" }, "sha512-yJAVPklM5+4+9dTeKwHOaA+LQkmrKFX96BM0A/2zQrbS6ENCmxc4OVoBs5dPkCCak2roAD+jKCdnmOqKszPkjA=="],
|
||||||
|
|
||||||
|
"@esbuild/darwin-arm64": ["@esbuild/darwin-arm64@0.25.8", "", { "os": "darwin", "cpu": "arm64" }, "sha512-Jw0mxgIaYX6R8ODrdkLLPwBqHTtYHJSmzzd+QeytSugzQ0Vg4c5rDky5VgkoowbZQahCbsv1rT1KW72MPIkevw=="],
|
||||||
|
|
||||||
|
"@esbuild/darwin-x64": ["@esbuild/darwin-x64@0.25.8", "", { "os": "darwin", "cpu": "x64" }, "sha512-Vh2gLxxHnuoQ+GjPNvDSDRpoBCUzY4Pu0kBqMBDlK4fuWbKgGtmDIeEC081xi26PPjn+1tct+Bh8FjyLlw1Zlg=="],
|
||||||
|
|
||||||
|
"@esbuild/freebsd-arm64": ["@esbuild/freebsd-arm64@0.25.8", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-YPJ7hDQ9DnNe5vxOm6jaie9QsTwcKedPvizTVlqWG9GBSq+BuyWEDazlGaDTC5NGU4QJd666V0yqCBL2oWKPfA=="],
|
||||||
|
|
||||||
|
"@esbuild/freebsd-x64": ["@esbuild/freebsd-x64@0.25.8", "", { "os": "freebsd", "cpu": "x64" }, "sha512-MmaEXxQRdXNFsRN/KcIimLnSJrk2r5H8v+WVafRWz5xdSVmWLoITZQXcgehI2ZE6gioE6HirAEToM/RvFBeuhw=="],
|
||||||
|
|
||||||
|
"@esbuild/linux-arm": ["@esbuild/linux-arm@0.25.8", "", { "os": "linux", "cpu": "arm" }, "sha512-FuzEP9BixzZohl1kLf76KEVOsxtIBFwCaLupVuk4eFVnOZfU+Wsn+x5Ryam7nILV2pkq2TqQM9EZPsOBuMC+kg=="],
|
||||||
|
|
||||||
|
"@esbuild/linux-arm64": ["@esbuild/linux-arm64@0.25.8", "", { "os": "linux", "cpu": "arm64" }, "sha512-WIgg00ARWv/uYLU7lsuDK00d/hHSfES5BzdWAdAig1ioV5kaFNrtK8EqGcUBJhYqotlUByUKz5Qo6u8tt7iD/w=="],
|
||||||
|
|
||||||
|
"@esbuild/linux-ia32": ["@esbuild/linux-ia32@0.25.8", "", { "os": "linux", "cpu": "ia32" }, "sha512-A1D9YzRX1i+1AJZuFFUMP1E9fMaYY+GnSQil9Tlw05utlE86EKTUA7RjwHDkEitmLYiFsRd9HwKBPEftNdBfjg=="],
|
||||||
|
|
||||||
|
"@esbuild/linux-loong64": ["@esbuild/linux-loong64@0.25.8", "", { "os": "linux", "cpu": "none" }, "sha512-O7k1J/dwHkY1RMVvglFHl1HzutGEFFZ3kNiDMSOyUrB7WcoHGf96Sh+64nTRT26l3GMbCW01Ekh/ThKM5iI7hQ=="],
|
||||||
|
|
||||||
|
"@esbuild/linux-mips64el": ["@esbuild/linux-mips64el@0.25.8", "", { "os": "linux", "cpu": "none" }, "sha512-uv+dqfRazte3BzfMp8PAQXmdGHQt2oC/y2ovwpTteqrMx2lwaksiFZ/bdkXJC19ttTvNXBuWH53zy/aTj1FgGw=="],
|
||||||
|
|
||||||
|
"@esbuild/linux-ppc64": ["@esbuild/linux-ppc64@0.25.8", "", { "os": "linux", "cpu": "ppc64" }, "sha512-GyG0KcMi1GBavP5JgAkkstMGyMholMDybAf8wF5A70CALlDM2p/f7YFE7H92eDeH/VBtFJA5MT4nRPDGg4JuzQ=="],
|
||||||
|
|
||||||
|
"@esbuild/linux-riscv64": ["@esbuild/linux-riscv64@0.25.8", "", { "os": "linux", "cpu": "none" }, "sha512-rAqDYFv3yzMrq7GIcen3XP7TUEG/4LK86LUPMIz6RT8A6pRIDn0sDcvjudVZBiiTcZCY9y2SgYX2lgK3AF+1eg=="],
|
||||||
|
|
||||||
|
"@esbuild/linux-s390x": ["@esbuild/linux-s390x@0.25.8", "", { "os": "linux", "cpu": "s390x" }, "sha512-Xutvh6VjlbcHpsIIbwY8GVRbwoviWT19tFhgdA7DlenLGC/mbc3lBoVb7jxj9Z+eyGqvcnSyIltYUrkKzWqSvg=="],
|
||||||
|
|
||||||
|
"@esbuild/linux-x64": ["@esbuild/linux-x64@0.25.8", "", { "os": "linux", "cpu": "x64" }, "sha512-ASFQhgY4ElXh3nDcOMTkQero4b1lgubskNlhIfJrsH5OKZXDpUAKBlNS0Kx81jwOBp+HCeZqmoJuihTv57/jvQ=="],
|
||||||
|
|
||||||
|
"@esbuild/netbsd-arm64": ["@esbuild/netbsd-arm64@0.25.8", "", { "os": "none", "cpu": "arm64" }, "sha512-d1KfruIeohqAi6SA+gENMuObDbEjn22olAR7egqnkCD9DGBG0wsEARotkLgXDu6c4ncgWTZJtN5vcgxzWRMzcw=="],
|
||||||
|
|
||||||
|
"@esbuild/netbsd-x64": ["@esbuild/netbsd-x64@0.25.8", "", { "os": "none", "cpu": "x64" }, "sha512-nVDCkrvx2ua+XQNyfrujIG38+YGyuy2Ru9kKVNyh5jAys6n+l44tTtToqHjino2My8VAY6Lw9H7RI73XFi66Cg=="],
|
||||||
|
|
||||||
|
"@esbuild/openbsd-arm64": ["@esbuild/openbsd-arm64@0.25.8", "", { "os": "openbsd", "cpu": "arm64" }, "sha512-j8HgrDuSJFAujkivSMSfPQSAa5Fxbvk4rgNAS5i3K+r8s1X0p1uOO2Hl2xNsGFppOeHOLAVgYwDVlmxhq5h+SQ=="],
|
||||||
|
|
||||||
|
"@esbuild/openbsd-x64": ["@esbuild/openbsd-x64@0.25.8", "", { "os": "openbsd", "cpu": "x64" }, "sha512-1h8MUAwa0VhNCDp6Af0HToI2TJFAn1uqT9Al6DJVzdIBAd21m/G0Yfc77KDM3uF3T/YaOgQq3qTJHPbTOInaIQ=="],
|
||||||
|
|
||||||
|
"@esbuild/openharmony-arm64": ["@esbuild/openharmony-arm64@0.25.8", "", { "os": "none", "cpu": "arm64" }, "sha512-r2nVa5SIK9tSWd0kJd9HCffnDHKchTGikb//9c7HX+r+wHYCpQrSgxhlY6KWV1nFo1l4KFbsMlHk+L6fekLsUg=="],
|
||||||
|
|
||||||
|
"@esbuild/sunos-x64": ["@esbuild/sunos-x64@0.25.8", "", { "os": "sunos", "cpu": "x64" }, "sha512-zUlaP2S12YhQ2UzUfcCuMDHQFJyKABkAjvO5YSndMiIkMimPmxA+BYSBikWgsRpvyxuRnow4nS5NPnf9fpv41w=="],
|
||||||
|
|
||||||
|
"@esbuild/win32-arm64": ["@esbuild/win32-arm64@0.25.8", "", { "os": "win32", "cpu": "arm64" }, "sha512-YEGFFWESlPva8hGL+zvj2z/SaK+pH0SwOM0Nc/d+rVnW7GSTFlLBGzZkuSU9kFIGIo8q9X3ucpZhu8PDN5A2sQ=="],
|
||||||
|
|
||||||
|
"@esbuild/win32-ia32": ["@esbuild/win32-ia32@0.25.8", "", { "os": "win32", "cpu": "ia32" }, "sha512-hiGgGC6KZ5LZz58OL/+qVVoZiuZlUYlYHNAmczOm7bs2oE1XriPFi5ZHHrS8ACpV5EjySrnoCKmcbQMN+ojnHg=="],
|
||||||
|
|
||||||
|
"@esbuild/win32-x64": ["@esbuild/win32-x64@0.25.8", "", { "os": "win32", "cpu": "x64" }, "sha512-cn3Yr7+OaaZq1c+2pe+8yxC8E144SReCQjN6/2ynubzYjvyqZjTXfQJpAcQpsdJq3My7XADANiYGHoFC69pLQw=="],
|
||||||
|
|
||||||
|
"@exodus/schemasafe": ["@exodus/schemasafe@1.3.0", "", {}, "sha512-5Aap/GaRupgNx/feGBwLLTVv8OQFfv3pq2lPRzPg9R+IOBnDgghTGW7l7EuVXOvg5cc/xSAlRW8rBrjIC3Nvqw=="],
|
||||||
|
|
||||||
|
"@floating-ui/core": ["@floating-ui/core@1.7.2", "", { "dependencies": { "@floating-ui/utils": "^0.2.10" } }, "sha512-wNB5ooIKHQc+Kui96jE/n69rHFWAVoxn5CAzL1Xdd8FG03cgY3MLO+GF9U3W737fYDSgPWA6MReKhBQBop6Pcw=="],
|
||||||
|
|
||||||
|
"@floating-ui/dom": ["@floating-ui/dom@1.7.2", "", { "dependencies": { "@floating-ui/core": "^1.7.2", "@floating-ui/utils": "^0.2.10" } }, "sha512-7cfaOQuCS27HD7DX+6ib2OrnW+b4ZBwDNnCcT0uTyidcmyWb03FnQqJybDBoCnpdxwBSfA94UAYlRCt7mV+TbA=="],
|
||||||
|
|
||||||
|
"@floating-ui/utils": ["@floating-ui/utils@0.2.10", "", {}, "sha512-aGTxbpbg8/b5JfU1HXSrbH3wXZuLPJcNEcZQFMxLs3oSzgtVu6nFPkbbGGUvBcUjKV2YyB9Wxxabo+HEH9tcRQ=="],
|
||||||
|
|
||||||
|
"@gcornut/valibot-json-schema": ["@gcornut/valibot-json-schema@0.42.0", "", { "dependencies": { "valibot": "~0.42.0" }, "optionalDependencies": { "@types/json-schema": ">= 7.0.14", "esbuild-runner": ">= 2.2.2" }, "bin": { "valibot-json-schema": "bin/index.js" } }, "sha512-4Et4AN6wmqeA0PfU5Clkv/IS27wiefsWf6TemAZrb75uzkClYEFavim7SboeKwbll9Nbsn2Iv0LT/HS5H7orZg=="],
|
||||||
|
|
||||||
|
"@hapi/hoek": ["@hapi/hoek@9.3.0", "", {}, "sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ=="],
|
||||||
|
|
||||||
|
"@hapi/topo": ["@hapi/topo@5.1.0", "", { "dependencies": { "@hapi/hoek": "^9.0.0" } }, "sha512-foQZKJig7Ob0BMAYBfcJk8d77QtOe7Wo4ox7ff1lQYoNNAb6jwcY1ncdoy2e9wQZzvNy7ODZCYJkK8kzmcAnAg=="],
|
||||||
|
|
||||||
|
"@hnu.de/hl7v2-client": ["@hnu.de/hl7v2-client@workspace:packages/client"],
|
||||||
|
|
||||||
|
"@hnu.de/hl7v2-server": ["@hnu.de/hl7v2-server@workspace:packages/server"],
|
||||||
|
|
||||||
|
"@hnu.de/hl7v2-shared": ["@hnu.de/hl7v2-shared@workspace:packages/shared"],
|
||||||
|
|
||||||
|
"@internationalized/date": ["@internationalized/date@3.8.2", "", { "dependencies": { "@swc/helpers": "^0.5.0" } }, "sha512-/wENk7CbvLbkUvX1tu0mwq49CVkkWpkXubGel6birjRPyo6uQ4nQpnq5xZu823zRCwwn82zgHrvgF1vZyvmVgA=="],
|
||||||
|
|
||||||
|
"@isaacs/fs-minipass": ["@isaacs/fs-minipass@4.0.1", "", { "dependencies": { "minipass": "^7.0.4" } }, "sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w=="],
|
||||||
|
|
||||||
|
"@jridgewell/gen-mapping": ["@jridgewell/gen-mapping@0.3.12", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.0", "@jridgewell/trace-mapping": "^0.3.24" } }, "sha512-OuLGC46TjB5BbN1dH8JULVVZY4WTdkF7tV9Ys6wLL1rubZnCMstOhNHueU5bLCrnRuDhKPDM4g6sw4Bel5Gzqg=="],
|
||||||
|
|
||||||
|
"@jridgewell/resolve-uri": ["@jridgewell/resolve-uri@3.1.2", "", {}, "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw=="],
|
||||||
|
|
||||||
|
"@jridgewell/sourcemap-codec": ["@jridgewell/sourcemap-codec@1.5.4", "", {}, "sha512-VT2+G1VQs/9oz078bLrYbecdZKs912zQlkelYpuf+SXF+QvZDYJlbx/LSx+meSAwdDFnF8FVXW92AVjjkVmgFw=="],
|
||||||
|
|
||||||
|
"@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.29", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, "sha512-uw6guiW/gcAGPDhLmd77/6lW8QLeiV5RUTsAX46Db6oLhGaVj4lhnPwb184s1bkc8kdVg/+h988dro8GRDpmYQ=="],
|
||||||
|
|
||||||
|
"@lucide/svelte": ["@lucide/svelte@0.515.0", "", { "peerDependencies": { "svelte": "^5" } }, "sha512-CEAyqcZmNBfYzVgaRmK2RFJP5tnbXxekRyDk0XX/eZQRfsJmkDvmQwXNX8C869BgNeryzmrRyjHhUL6g9ZOHNA=="],
|
||||||
|
|
||||||
|
"@polka/url": ["@polka/url@1.0.0-next.29", "", {}, "sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww=="],
|
||||||
|
|
||||||
|
"@poppinss/macroable": ["@poppinss/macroable@1.0.5", "", {}, "sha512-6u61y1HHd090MEk1Av0/1btDmm2Hh/+XoJj+HgFYRh9koUPI822ybJbwLHuqjLNCiY+o1gRykg2igEqOf/VBZw=="],
|
||||||
|
|
||||||
|
"@rollup/plugin-commonjs": ["@rollup/plugin-commonjs@28.0.6", "", { "dependencies": { "@rollup/pluginutils": "^5.0.1", "commondir": "^1.0.1", "estree-walker": "^2.0.2", "fdir": "^6.2.0", "is-reference": "1.2.1", "magic-string": "^0.30.3", "picomatch": "^4.0.2" }, "peerDependencies": { "rollup": "^2.68.0||^3.0.0||^4.0.0" }, "optionalPeers": ["rollup"] }, "sha512-XSQB1K7FUU5QP+3lOQmVCE3I0FcbbNvmNT4VJSj93iUjayaARrTQeoRdiYQoftAJBLrR9t2agwAd3ekaTgHNlw=="],
|
||||||
|
|
||||||
|
"@rollup/plugin-json": ["@rollup/plugin-json@6.1.0", "", { "dependencies": { "@rollup/pluginutils": "^5.1.0" }, "peerDependencies": { "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" }, "optionalPeers": ["rollup"] }, "sha512-EGI2te5ENk1coGeADSIwZ7G2Q8CJS2sF120T7jLw4xFw9n7wIOXHo+kIYRAoVpJAN+kmqZSoO3Fp4JtoNF4ReA=="],
|
||||||
|
|
||||||
|
"@rollup/plugin-node-resolve": ["@rollup/plugin-node-resolve@16.0.1", "", { "dependencies": { "@rollup/pluginutils": "^5.0.1", "@types/resolve": "1.20.2", "deepmerge": "^4.2.2", "is-module": "^1.0.0", "resolve": "^1.22.1" }, "peerDependencies": { "rollup": "^2.78.0||^3.0.0||^4.0.0" }, "optionalPeers": ["rollup"] }, "sha512-tk5YCxJWIG81umIvNkSod2qK5KyQW19qcBF/B78n1bjtOON6gzKoVeSzAE8yHCZEDmqkHKkxplExA8KzdJLJpA=="],
|
||||||
|
|
||||||
|
"@rollup/pluginutils": ["@rollup/pluginutils@5.2.0", "", { "dependencies": { "@types/estree": "^1.0.0", "estree-walker": "^2.0.2", "picomatch": "^4.0.2" }, "peerDependencies": { "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" }, "optionalPeers": ["rollup"] }, "sha512-qWJ2ZTbmumwiLFomfzTyt5Kng4hwPi9rwCYN4SHb6eaRU1KNO4ccxINHr/VhH4GgPlt1XfSTLX2LBTme8ne4Zw=="],
|
||||||
|
|
||||||
|
"@rollup/rollup-android-arm-eabi": ["@rollup/rollup-android-arm-eabi@4.45.1", "", { "os": "android", "cpu": "arm" }, "sha512-NEySIFvMY0ZQO+utJkgoMiCAjMrGvnbDLHvcmlA33UXJpYBCvlBEbMMtV837uCkS+plG2umfhn0T5mMAxGrlRA=="],
|
||||||
|
|
||||||
|
"@rollup/rollup-android-arm64": ["@rollup/rollup-android-arm64@4.45.1", "", { "os": "android", "cpu": "arm64" }, "sha512-ujQ+sMXJkg4LRJaYreaVx7Z/VMgBBd89wGS4qMrdtfUFZ+TSY5Rs9asgjitLwzeIbhwdEhyj29zhst3L1lKsRQ=="],
|
||||||
|
|
||||||
|
"@rollup/rollup-darwin-arm64": ["@rollup/rollup-darwin-arm64@4.45.1", "", { "os": "darwin", "cpu": "arm64" }, "sha512-FSncqHvqTm3lC6Y13xncsdOYfxGSLnP+73k815EfNmpewPs+EyM49haPS105Rh4aF5mJKywk9X0ogzLXZzN9lA=="],
|
||||||
|
|
||||||
|
"@rollup/rollup-darwin-x64": ["@rollup/rollup-darwin-x64@4.45.1", "", { "os": "darwin", "cpu": "x64" }, "sha512-2/vVn/husP5XI7Fsf/RlhDaQJ7x9zjvC81anIVbr4b/f0xtSmXQTFcGIQ/B1cXIYM6h2nAhJkdMHTnD7OtQ9Og=="],
|
||||||
|
|
||||||
|
"@rollup/rollup-freebsd-arm64": ["@rollup/rollup-freebsd-arm64@4.45.1", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-4g1kaDxQItZsrkVTdYQ0bxu4ZIQ32cotoQbmsAnW1jAE4XCMbcBPDirX5fyUzdhVCKgPcrwWuucI8yrVRBw2+g=="],
|
||||||
|
|
||||||
|
"@rollup/rollup-freebsd-x64": ["@rollup/rollup-freebsd-x64@4.45.1", "", { "os": "freebsd", "cpu": "x64" }, "sha512-L/6JsfiL74i3uK1Ti2ZFSNsp5NMiM4/kbbGEcOCps99aZx3g8SJMO1/9Y0n/qKlWZfn6sScf98lEOUe2mBvW9A=="],
|
||||||
|
|
||||||
|
"@rollup/rollup-linux-arm-gnueabihf": ["@rollup/rollup-linux-arm-gnueabihf@4.45.1", "", { "os": "linux", "cpu": "arm" }, "sha512-RkdOTu2jK7brlu+ZwjMIZfdV2sSYHK2qR08FUWcIoqJC2eywHbXr0L8T/pONFwkGukQqERDheaGTeedG+rra6Q=="],
|
||||||
|
|
||||||
|
"@rollup/rollup-linux-arm-musleabihf": ["@rollup/rollup-linux-arm-musleabihf@4.45.1", "", { "os": "linux", "cpu": "arm" }, "sha512-3kJ8pgfBt6CIIr1o+HQA7OZ9mp/zDk3ctekGl9qn/pRBgrRgfwiffaUmqioUGN9hv0OHv2gxmvdKOkARCtRb8Q=="],
|
||||||
|
|
||||||
|
"@rollup/rollup-linux-arm64-gnu": ["@rollup/rollup-linux-arm64-gnu@4.45.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-k3dOKCfIVixWjG7OXTCOmDfJj3vbdhN0QYEqB+OuGArOChek22hn7Uy5A/gTDNAcCy5v2YcXRJ/Qcnm4/ma1xw=="],
|
||||||
|
|
||||||
|
"@rollup/rollup-linux-arm64-musl": ["@rollup/rollup-linux-arm64-musl@4.45.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-PmI1vxQetnM58ZmDFl9/Uk2lpBBby6B6rF4muJc65uZbxCs0EA7hhKCk2PKlmZKuyVSHAyIw3+/SiuMLxKxWog=="],
|
||||||
|
|
||||||
|
"@rollup/rollup-linux-loongarch64-gnu": ["@rollup/rollup-linux-loongarch64-gnu@4.45.1", "", { "os": "linux", "cpu": "none" }, "sha512-9UmI0VzGmNJ28ibHW2GpE2nF0PBQqsyiS4kcJ5vK+wuwGnV5RlqdczVocDSUfGX/Na7/XINRVoUgJyFIgipoRg=="],
|
||||||
|
|
||||||
|
"@rollup/rollup-linux-powerpc64le-gnu": ["@rollup/rollup-linux-powerpc64le-gnu@4.45.1", "", { "os": "linux", "cpu": "ppc64" }, "sha512-7nR2KY8oEOUTD3pBAxIBBbZr0U7U+R9HDTPNy+5nVVHDXI4ikYniH1oxQz9VoB5PbBU1CZuDGHkLJkd3zLMWsg=="],
|
||||||
|
|
||||||
|
"@rollup/rollup-linux-riscv64-gnu": ["@rollup/rollup-linux-riscv64-gnu@4.45.1", "", { "os": "linux", "cpu": "none" }, "sha512-nlcl3jgUultKROfZijKjRQLUu9Ma0PeNv/VFHkZiKbXTBQXhpytS8CIj5/NfBeECZtY2FJQubm6ltIxm/ftxpw=="],
|
||||||
|
|
||||||
|
"@rollup/rollup-linux-riscv64-musl": ["@rollup/rollup-linux-riscv64-musl@4.45.1", "", { "os": "linux", "cpu": "none" }, "sha512-HJV65KLS51rW0VY6rvZkiieiBnurSzpzore1bMKAhunQiECPuxsROvyeaot/tcK3A3aGnI+qTHqisrpSgQrpgA=="],
|
||||||
|
|
||||||
|
"@rollup/rollup-linux-s390x-gnu": ["@rollup/rollup-linux-s390x-gnu@4.45.1", "", { "os": "linux", "cpu": "s390x" }, "sha512-NITBOCv3Qqc6hhwFt7jLV78VEO/il4YcBzoMGGNxznLgRQf43VQDae0aAzKiBeEPIxnDrACiMgbqjuihx08OOw=="],
|
||||||
|
|
||||||
|
"@rollup/rollup-linux-x64-gnu": ["@rollup/rollup-linux-x64-gnu@4.45.1", "", { "os": "linux", "cpu": "x64" }, "sha512-+E/lYl6qu1zqgPEnTrs4WysQtvc/Sh4fC2nByfFExqgYrqkKWp1tWIbe+ELhixnenSpBbLXNi6vbEEJ8M7fiHw=="],
|
||||||
|
|
||||||
|
"@rollup/rollup-linux-x64-musl": ["@rollup/rollup-linux-x64-musl@4.45.1", "", { "os": "linux", "cpu": "x64" }, "sha512-a6WIAp89p3kpNoYStITT9RbTbTnqarU7D8N8F2CV+4Cl9fwCOZraLVuVFvlpsW0SbIiYtEnhCZBPLoNdRkjQFw=="],
|
||||||
|
|
||||||
|
"@rollup/rollup-win32-arm64-msvc": ["@rollup/rollup-win32-arm64-msvc@4.45.1", "", { "os": "win32", "cpu": "arm64" }, "sha512-T5Bi/NS3fQiJeYdGvRpTAP5P02kqSOpqiopwhj0uaXB6nzs5JVi2XMJb18JUSKhCOX8+UE1UKQufyD6Or48dJg=="],
|
||||||
|
|
||||||
|
"@rollup/rollup-win32-ia32-msvc": ["@rollup/rollup-win32-ia32-msvc@4.45.1", "", { "os": "win32", "cpu": "ia32" }, "sha512-lxV2Pako3ujjuUe9jiU3/s7KSrDfH6IgTSQOnDWr9aJ92YsFd7EurmClK0ly/t8dzMkDtd04g60WX6yl0sGfdw=="],
|
||||||
|
|
||||||
|
"@rollup/rollup-win32-x64-msvc": ["@rollup/rollup-win32-x64-msvc@4.45.1", "", { "os": "win32", "cpu": "x64" }, "sha512-M/fKi4sasCdM8i0aWJjCSFm2qEnYRR8AMLG2kxp6wD13+tMGA4Z1tVAuHkNRjud5SW2EM3naLuK35w9twvf6aA=="],
|
||||||
|
|
||||||
|
"@sideway/address": ["@sideway/address@4.1.5", "", { "dependencies": { "@hapi/hoek": "^9.0.0" } }, "sha512-IqO/DUQHUkPeixNQ8n0JA6102hT9CmaljNTPmQ1u8MEhBo/R4Q8eKLN/vGZxuebwOroDB4cbpjheD4+/sKFK4Q=="],
|
||||||
|
|
||||||
|
"@sideway/formula": ["@sideway/formula@3.0.1", "", {}, "sha512-/poHZJJVjx3L+zVD6g9KgHfYnb443oi7wLu/XKojDviHy6HOEOA6z1Trk5aR1dGcmPenJEgb2sK2I80LeS3MIg=="],
|
||||||
|
|
||||||
|
"@sideway/pinpoint": ["@sideway/pinpoint@2.0.0", "", {}, "sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ=="],
|
||||||
|
|
||||||
|
"@sinclair/typebox": ["@sinclair/typebox@0.34.38", "", {}, "sha512-HpkxMmc2XmZKhvaKIZZThlHmx1L0I/V1hWK1NubtlFnr6ZqdiOpV72TKudZUNQjZNsyDBay72qFEhEvb+bcwcA=="],
|
||||||
|
|
||||||
|
"@standard-schema/spec": ["@standard-schema/spec@1.0.0", "", {}, "sha512-m2bOd0f2RT9k8QJx1JN85cZYyH1RqFBdlwtkSlf4tBDYLCiiZnv1fIIwacK6cqwXavOydf0NPToMQgpKq+dVlA=="],
|
||||||
|
|
||||||
|
"@sveltejs/acorn-typescript": ["@sveltejs/acorn-typescript@1.0.5", "", { "peerDependencies": { "acorn": "^8.9.0" } }, "sha512-IwQk4yfwLdibDlrXVE04jTZYlLnwsTT2PIOQQGNLWfjavGifnk1JD1LcZjZaBTRcxZu2FfPfNLOE04DSu9lqtQ=="],
|
||||||
|
|
||||||
|
"@sveltejs/adapter-node": ["@sveltejs/adapter-node@5.2.13", "", { "dependencies": { "@rollup/plugin-commonjs": "^28.0.1", "@rollup/plugin-json": "^6.1.0", "@rollup/plugin-node-resolve": "^16.0.0", "rollup": "^4.9.5" }, "peerDependencies": { "@sveltejs/kit": "^2.4.0" } }, "sha512-yS2TVFmIrxjGhYaV5/iIUrJ3mJl6zjaYn0lBD70vTLnYvJeqf3cjvLXeXCUCuYinhSBoyF4DpfGla49BnIy7sQ=="],
|
||||||
|
|
||||||
|
"@sveltejs/kit": ["@sveltejs/kit@2.25.2", "", { "dependencies": { "@sveltejs/acorn-typescript": "^1.0.5", "@types/cookie": "^0.6.0", "acorn": "^8.14.1", "cookie": "^0.6.0", "devalue": "^5.1.0", "esm-env": "^1.2.2", "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" }, "peerDependencies": { "@sveltejs/vite-plugin-svelte": "^3.0.0 || ^4.0.0-next.1 || ^5.0.0 || ^6.0.0-next.0", "svelte": "^4.0.0 || ^5.0.0-next.0", "vite": "^5.0.3 || ^6.0.0 || ^7.0.0-beta.0" }, "bin": { "svelte-kit": "svelte-kit.js" } }, "sha512-aKfj82vqEINedoH9Pw4Ip16jj3w8soNq9F3nJqc56kxXW74TcEu/gdTAuLUI+gsl8i+KXfetRqg1F+gG/AZRVQ=="],
|
||||||
|
|
||||||
|
"@sveltejs/vite-plugin-svelte": ["@sveltejs/vite-plugin-svelte@6.1.0", "", { "dependencies": { "@sveltejs/vite-plugin-svelte-inspector": "^5.0.0-next.1", "debug": "^4.4.1", "deepmerge": "^4.3.1", "kleur": "^4.1.5", "magic-string": "^0.30.17", "vitefu": "^1.1.1" }, "peerDependencies": { "svelte": "^5.0.0", "vite": "^6.3.0 || ^7.0.0" } }, "sha512-+U6lz1wvGEG/BvQyL4z/flyNdQ9xDNv5vrh+vWBWTHaebqT0c9RNggpZTo/XSPoHsSCWBlYaTlRX8pZ9GATXCw=="],
|
||||||
|
|
||||||
|
"@sveltejs/vite-plugin-svelte-inspector": ["@sveltejs/vite-plugin-svelte-inspector@5.0.0", "", { "dependencies": { "debug": "^4.4.1" }, "peerDependencies": { "@sveltejs/vite-plugin-svelte": "^6.0.0-next.0", "svelte": "^5.0.0", "vite": "^6.3.0 || ^7.0.0" } }, "sha512-iwQ8Z4ET6ZFSt/gC+tVfcsSBHwsqc6RumSaiLUkAurW3BCpJam65cmHw0oOlDMTO0u+PZi9hilBRYN+LZNHTUQ=="],
|
||||||
|
|
||||||
|
"@swc/helpers": ["@swc/helpers@0.5.17", "", { "dependencies": { "tslib": "^2.8.0" } }, "sha512-5IKx/Y13RsYd+sauPb2x+U/xZikHjolzfuDgTAl/Tdf3Q8rslRvC19NKDLgAJQ6wsqADk10ntlv08nPFw/gO/A=="],
|
||||||
|
|
||||||
|
"@tailwindcss/node": ["@tailwindcss/node@4.1.11", "", { "dependencies": { "@ampproject/remapping": "^2.3.0", "enhanced-resolve": "^5.18.1", "jiti": "^2.4.2", "lightningcss": "1.30.1", "magic-string": "^0.30.17", "source-map-js": "^1.2.1", "tailwindcss": "4.1.11" } }, "sha512-yzhzuGRmv5QyU9qLNg4GTlYI6STedBWRE7NjxP45CsFYYq9taI0zJXZBMqIC/c8fViNLhmrbpSFS57EoxUmD6Q=="],
|
||||||
|
|
||||||
|
"@tailwindcss/oxide": ["@tailwindcss/oxide@4.1.11", "", { "dependencies": { "detect-libc": "^2.0.4", "tar": "^7.4.3" }, "optionalDependencies": { "@tailwindcss/oxide-android-arm64": "4.1.11", "@tailwindcss/oxide-darwin-arm64": "4.1.11", "@tailwindcss/oxide-darwin-x64": "4.1.11", "@tailwindcss/oxide-freebsd-x64": "4.1.11", "@tailwindcss/oxide-linux-arm-gnueabihf": "4.1.11", "@tailwindcss/oxide-linux-arm64-gnu": "4.1.11", "@tailwindcss/oxide-linux-arm64-musl": "4.1.11", "@tailwindcss/oxide-linux-x64-gnu": "4.1.11", "@tailwindcss/oxide-linux-x64-musl": "4.1.11", "@tailwindcss/oxide-wasm32-wasi": "4.1.11", "@tailwindcss/oxide-win32-arm64-msvc": "4.1.11", "@tailwindcss/oxide-win32-x64-msvc": "4.1.11" } }, "sha512-Q69XzrtAhuyfHo+5/HMgr1lAiPP/G40OMFAnws7xcFEYqcypZmdW8eGXaOUIeOl1dzPJBPENXgbjsOyhg2nkrg=="],
|
||||||
|
|
||||||
|
"@tailwindcss/oxide-android-arm64": ["@tailwindcss/oxide-android-arm64@4.1.11", "", { "os": "android", "cpu": "arm64" }, "sha512-3IfFuATVRUMZZprEIx9OGDjG3Ou3jG4xQzNTvjDoKmU9JdmoCohQJ83MYd0GPnQIu89YoJqvMM0G3uqLRFtetg=="],
|
||||||
|
|
||||||
|
"@tailwindcss/oxide-darwin-arm64": ["@tailwindcss/oxide-darwin-arm64@4.1.11", "", { "os": "darwin", "cpu": "arm64" }, "sha512-ESgStEOEsyg8J5YcMb1xl8WFOXfeBmrhAwGsFxxB2CxY9evy63+AtpbDLAyRkJnxLy2WsD1qF13E97uQyP1lfQ=="],
|
||||||
|
|
||||||
|
"@tailwindcss/oxide-darwin-x64": ["@tailwindcss/oxide-darwin-x64@4.1.11", "", { "os": "darwin", "cpu": "x64" }, "sha512-EgnK8kRchgmgzG6jE10UQNaH9Mwi2n+yw1jWmof9Vyg2lpKNX2ioe7CJdf9M5f8V9uaQxInenZkOxnTVL3fhAw=="],
|
||||||
|
|
||||||
|
"@tailwindcss/oxide-freebsd-x64": ["@tailwindcss/oxide-freebsd-x64@4.1.11", "", { "os": "freebsd", "cpu": "x64" }, "sha512-xdqKtbpHs7pQhIKmqVpxStnY1skuNh4CtbcyOHeX1YBE0hArj2romsFGb6yUmzkq/6M24nkxDqU8GYrKrz+UcA=="],
|
||||||
|
|
||||||
|
"@tailwindcss/oxide-linux-arm-gnueabihf": ["@tailwindcss/oxide-linux-arm-gnueabihf@4.1.11", "", { "os": "linux", "cpu": "arm" }, "sha512-ryHQK2eyDYYMwB5wZL46uoxz2zzDZsFBwfjssgB7pzytAeCCa6glsiJGjhTEddq/4OsIjsLNMAiMlHNYnkEEeg=="],
|
||||||
|
|
||||||
|
"@tailwindcss/oxide-linux-arm64-gnu": ["@tailwindcss/oxide-linux-arm64-gnu@4.1.11", "", { "os": "linux", "cpu": "arm64" }, "sha512-mYwqheq4BXF83j/w75ewkPJmPZIqqP1nhoghS9D57CLjsh3Nfq0m4ftTotRYtGnZd3eCztgbSPJ9QhfC91gDZQ=="],
|
||||||
|
|
||||||
|
"@tailwindcss/oxide-linux-arm64-musl": ["@tailwindcss/oxide-linux-arm64-musl@4.1.11", "", { "os": "linux", "cpu": "arm64" }, "sha512-m/NVRFNGlEHJrNVk3O6I9ggVuNjXHIPoD6bqay/pubtYC9QIdAMpS+cswZQPBLvVvEF6GtSNONbDkZrjWZXYNQ=="],
|
||||||
|
|
||||||
|
"@tailwindcss/oxide-linux-x64-gnu": ["@tailwindcss/oxide-linux-x64-gnu@4.1.11", "", { "os": "linux", "cpu": "x64" }, "sha512-YW6sblI7xukSD2TdbbaeQVDysIm/UPJtObHJHKxDEcW2exAtY47j52f8jZXkqE1krdnkhCMGqP3dbniu1Te2Fg=="],
|
||||||
|
|
||||||
|
"@tailwindcss/oxide-linux-x64-musl": ["@tailwindcss/oxide-linux-x64-musl@4.1.11", "", { "os": "linux", "cpu": "x64" }, "sha512-e3C/RRhGunWYNC3aSF7exsQkdXzQ/M+aYuZHKnw4U7KQwTJotnWsGOIVih0s2qQzmEzOFIJ3+xt7iq67K/p56Q=="],
|
||||||
|
|
||||||
|
"@tailwindcss/oxide-wasm32-wasi": ["@tailwindcss/oxide-wasm32-wasi@4.1.11", "", { "dependencies": { "@emnapi/core": "^1.4.3", "@emnapi/runtime": "^1.4.3", "@emnapi/wasi-threads": "^1.0.2", "@napi-rs/wasm-runtime": "^0.2.11", "@tybys/wasm-util": "^0.9.0", "tslib": "^2.8.0" }, "cpu": "none" }, "sha512-Xo1+/GU0JEN/C/dvcammKHzeM6NqKovG+6921MR6oadee5XPBaKOumrJCXvopJ/Qb5TH7LX/UAywbqrP4lax0g=="],
|
||||||
|
|
||||||
|
"@tailwindcss/oxide-win32-arm64-msvc": ["@tailwindcss/oxide-win32-arm64-msvc@4.1.11", "", { "os": "win32", "cpu": "arm64" }, "sha512-UgKYx5PwEKrac3GPNPf6HVMNhUIGuUh4wlDFR2jYYdkX6pL/rn73zTq/4pzUm8fOjAn5L8zDeHp9iXmUGOXZ+w=="],
|
||||||
|
|
||||||
|
"@tailwindcss/oxide-win32-x64-msvc": ["@tailwindcss/oxide-win32-x64-msvc@4.1.11", "", { "os": "win32", "cpu": "x64" }, "sha512-YfHoggn1j0LK7wR82TOucWc5LDCguHnoS879idHekmmiR7g9HUtMw9MI0NHatS28u/Xlkfi9w5RJWgz2Dl+5Qg=="],
|
||||||
|
|
||||||
|
"@tailwindcss/vite": ["@tailwindcss/vite@4.1.11", "", { "dependencies": { "@tailwindcss/node": "4.1.11", "@tailwindcss/oxide": "4.1.11", "tailwindcss": "4.1.11" }, "peerDependencies": { "vite": "^5.2.0 || ^6 || ^7" } }, "sha512-RHYhrR3hku0MJFRV+fN2gNbDNEh3dwKvY8XJvTxCSXeMOsCRSr+uKvDWQcbizrHgjML6ZmTE5OwMrl5wKcujCw=="],
|
||||||
|
|
||||||
|
"@types/bun": ["@types/bun@1.2.19", "", { "dependencies": { "bun-types": "1.2.19" } }, "sha512-d9ZCmrH3CJ2uYKXQIUuZ/pUnTqIvLDS0SK7pFmbx8ma+ziH/FRMoAq5bYpRG7y+w1gl+HgyNZbtqgMq4W4e2Lg=="],
|
||||||
|
|
||||||
|
"@types/cookie": ["@types/cookie@0.6.0", "", {}, "sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA=="],
|
||||||
|
|
||||||
|
"@types/estree": ["@types/estree@1.0.8", "", {}, "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w=="],
|
||||||
|
|
||||||
|
"@types/json-schema": ["@types/json-schema@7.0.15", "", {}, "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA=="],
|
||||||
|
|
||||||
|
"@types/node": ["@types/node@24.1.0", "", { "dependencies": { "undici-types": "~7.8.0" } }, "sha512-ut5FthK5moxFKH2T1CUOC6ctR67rQRvvHdFLCD2Ql6KXmMuCrjsSsRI9UsLCm9M18BMwClv4pn327UvB7eeO1w=="],
|
||||||
|
|
||||||
|
"@types/react": ["@types/react@19.1.8", "", { "dependencies": { "csstype": "^3.0.2" } }, "sha512-AwAfQ2Wa5bCx9WP8nZL2uMZWod7J7/JSplxbTmBQ5ms6QpqNYm672H0Vu9ZVKVngQ+ii4R/byguVEUZQyeg44g=="],
|
||||||
|
|
||||||
|
"@types/resolve": ["@types/resolve@1.20.2", "", {}, "sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q=="],
|
||||||
|
|
||||||
|
"@types/validator": ["@types/validator@13.15.2", "", {}, "sha512-y7pa/oEJJ4iGYBxOpfAKn5b9+xuihvzDVnC/OSvlVnGxVg0pOqmjiMafiJ1KVNQEaPZf9HsEp5icEwGg8uIe5Q=="],
|
||||||
|
|
||||||
|
"@types/ws": ["@types/ws@8.18.1", "", { "dependencies": { "@types/node": "*" } }, "sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg=="],
|
||||||
|
|
||||||
|
"@typeschema/class-validator": ["@typeschema/class-validator@0.3.0", "", { "dependencies": { "@typeschema/core": "0.14.0" }, "peerDependencies": { "class-validator": "^0.14.1" }, "optionalPeers": ["class-validator"] }, "sha512-OJSFeZDIQ8EK1HTljKLT5CItM2wsbgczLN8tMEfz3I1Lmhc5TBfkZ0eikFzUC16tI3d1Nag7um6TfCgp2I2Bww=="],
|
||||||
|
|
||||||
|
"@typeschema/core": ["@typeschema/core@0.14.0", "", { "peerDependencies": { "@types/json-schema": "^7.0.15" }, "optionalPeers": ["@types/json-schema"] }, "sha512-Ia6PtZHcL3KqsAWXjMi5xIyZ7XMH4aSnOQes8mfMLx+wGFGtGRNlwe6Y7cYvX+WfNK67OL0/HSe9t8QDygV0/w=="],
|
||||||
|
|
||||||
|
"@vinejs/compiler": ["@vinejs/compiler@3.0.0", "", {}, "sha512-v9Lsv59nR56+bmy2p0+czjZxsLHwaibJ+SV5iK9JJfehlJMa501jUJQqqz4X/OqKXrxtE3uTQmSqjUqzF3B2mw=="],
|
||||||
|
|
||||||
|
"@vinejs/vine": ["@vinejs/vine@3.0.1", "", { "dependencies": { "@poppinss/macroable": "^1.0.4", "@types/validator": "^13.12.2", "@vinejs/compiler": "^3.0.0", "camelcase": "^8.0.0", "dayjs": "^1.11.13", "dlv": "^1.1.3", "normalize-url": "^8.0.1", "validator": "^13.12.0" } }, "sha512-ZtvYkYpZOYdvbws3uaOAvTFuvFXoQGAtmzeiXu+XSMGxi5GVsODpoI9Xu9TplEMuD/5fmAtBbKb9cQHkWkLXDQ=="],
|
||||||
|
|
||||||
|
"acorn": ["acorn@8.15.0", "", { "bin": { "acorn": "bin/acorn" } }, "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg=="],
|
||||||
|
|
||||||
|
"aria-query": ["aria-query@5.3.2", "", {}, "sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw=="],
|
||||||
|
|
||||||
|
"arktype": ["arktype@2.1.20", "", { "dependencies": { "@ark/schema": "0.46.0", "@ark/util": "0.46.0" } }, "sha512-IZCEEXaJ8g+Ijd59WtSYwtjnqXiwM8sWQ5EjGamcto7+HVN9eK0C4p0zDlCuAwWhpqr6fIBkxPuYDl4/Mcj/+Q=="],
|
||||||
|
|
||||||
|
"axobject-query": ["axobject-query@4.1.0", "", {}, "sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ=="],
|
||||||
|
|
||||||
|
"bits-ui": ["bits-ui@2.8.11", "", { "dependencies": { "@floating-ui/core": "^1.7.1", "@floating-ui/dom": "^1.7.1", "esm-env": "^1.1.2", "runed": "^0.29.1", "svelte-toolbelt": "^0.9.3", "tabbable": "^6.2.0" }, "peerDependencies": { "@internationalized/date": "^3.8.1", "svelte": "^5.33.0" } }, "sha512-lKN9rAk69my6j7H1D4B87r8LrHuEtfEsf1xCixBj9yViql2BdI3f04HyyyT7T1GOCpgb9+8b0B+nm3LN81Konw=="],
|
||||||
|
|
||||||
|
"buffer-from": ["buffer-from@1.1.2", "", {}, "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ=="],
|
||||||
|
|
||||||
|
"bun-types": ["bun-types@1.2.19", "", { "dependencies": { "@types/node": "*" }, "peerDependencies": { "@types/react": "^19" } }, "sha512-uAOTaZSPuYsWIXRpj7o56Let0g/wjihKCkeRqUBhlLVM/Bt+Fj9xTo+LhC1OV1XDaGkz4hNC80et5xgy+9KTHQ=="],
|
||||||
|
|
||||||
|
"camelcase": ["camelcase@8.0.0", "", {}, "sha512-8WB3Jcas3swSvjIeA2yvCJ+Miyz5l1ZmB6HFb9R1317dt9LCQoswg/BGrmAmkWVEszSrrg4RwmO46qIm2OEnSA=="],
|
||||||
|
|
||||||
|
"chokidar": ["chokidar@4.0.3", "", { "dependencies": { "readdirp": "^4.0.1" } }, "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA=="],
|
||||||
|
|
||||||
|
"chownr": ["chownr@3.0.0", "", {}, "sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g=="],
|
||||||
|
|
||||||
|
"class-validator": ["class-validator@0.14.2", "", { "dependencies": { "@types/validator": "^13.11.8", "libphonenumber-js": "^1.11.1", "validator": "^13.9.0" } }, "sha512-3kMVRF2io8N8pY1IFIXlho9r8IPUUIfHe2hYVtiebvAzU2XeQFXTv+XI4WX+TnXmtwXMDcjngcpkiPM0O9PvLw=="],
|
||||||
|
|
||||||
|
"clsx": ["clsx@2.1.1", "", {}, "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA=="],
|
||||||
|
|
||||||
|
"commondir": ["commondir@1.0.1", "", {}, "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg=="],
|
||||||
|
|
||||||
|
"cookie": ["cookie@0.6.0", "", {}, "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw=="],
|
||||||
|
|
||||||
|
"csstype": ["csstype@3.1.3", "", {}, "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw=="],
|
||||||
|
|
||||||
|
"dayjs": ["dayjs@1.11.13", "", {}, "sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg=="],
|
||||||
|
|
||||||
|
"debug": ["debug@4.4.1", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ=="],
|
||||||
|
|
||||||
|
"deepmerge": ["deepmerge@4.3.1", "", {}, "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A=="],
|
||||||
|
|
||||||
|
"detect-libc": ["detect-libc@2.0.4", "", {}, "sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA=="],
|
||||||
|
|
||||||
|
"devalue": ["devalue@5.1.1", "", {}, "sha512-maua5KUiapvEwiEAe+XnlZ3Rh0GD+qI1J/nb9vrJc3muPXvcF/8gXYTWF76+5DAqHyDUtOIImEuo0YKE9mshVw=="],
|
||||||
|
|
||||||
|
"dlv": ["dlv@1.1.3", "", {}, "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA=="],
|
||||||
|
|
||||||
|
"dotenv": ["dotenv@17.2.0", "", {}, "sha512-Q4sgBT60gzd0BB0lSyYD3xM4YxrXA9y4uBDof1JNYGzOXrQdQ6yX+7XIAqoFOGQFOTK1D3Hts5OllpxMDZFONQ=="],
|
||||||
|
|
||||||
|
"effect": ["effect@3.17.1", "", { "dependencies": { "@standard-schema/spec": "^1.0.0", "fast-check": "^3.23.1" } }, "sha512-t917ks10FGNf7MpwOxHUg6vo42p0XsdMHuBMVpy4NttPu5gIv8/ah5MgbHLVQJ2kmDvZfQUT1/xyCa1IR09u2Q=="],
|
||||||
|
|
||||||
|
"enhanced-resolve": ["enhanced-resolve@5.18.2", "", { "dependencies": { "graceful-fs": "^4.2.4", "tapable": "^2.2.0" } }, "sha512-6Jw4sE1maoRJo3q8MsSIn2onJFbLTOjY9hlx4DZXmOKvLRd1Ok2kXmAGXaafL2+ijsJZ1ClYbl/pmqr9+k4iUQ=="],
|
||||||
|
|
||||||
|
"esbuild": ["esbuild@0.25.8", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.25.8", "@esbuild/android-arm": "0.25.8", "@esbuild/android-arm64": "0.25.8", "@esbuild/android-x64": "0.25.8", "@esbuild/darwin-arm64": "0.25.8", "@esbuild/darwin-x64": "0.25.8", "@esbuild/freebsd-arm64": "0.25.8", "@esbuild/freebsd-x64": "0.25.8", "@esbuild/linux-arm": "0.25.8", "@esbuild/linux-arm64": "0.25.8", "@esbuild/linux-ia32": "0.25.8", "@esbuild/linux-loong64": "0.25.8", "@esbuild/linux-mips64el": "0.25.8", "@esbuild/linux-ppc64": "0.25.8", "@esbuild/linux-riscv64": "0.25.8", "@esbuild/linux-s390x": "0.25.8", "@esbuild/linux-x64": "0.25.8", "@esbuild/netbsd-arm64": "0.25.8", "@esbuild/netbsd-x64": "0.25.8", "@esbuild/openbsd-arm64": "0.25.8", "@esbuild/openbsd-x64": "0.25.8", "@esbuild/openharmony-arm64": "0.25.8", "@esbuild/sunos-x64": "0.25.8", "@esbuild/win32-arm64": "0.25.8", "@esbuild/win32-ia32": "0.25.8", "@esbuild/win32-x64": "0.25.8" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-vVC0USHGtMi8+R4Kz8rt6JhEWLxsv9Rnu/lGYbPR8u47B+DCBksq9JarW0zOO7bs37hyOK1l2/oqtbciutL5+Q=="],
|
||||||
|
|
||||||
|
"esbuild-runner": ["esbuild-runner@2.2.2", "", { "dependencies": { "source-map-support": "0.5.21", "tslib": "2.4.0" }, "peerDependencies": { "esbuild": "*" }, "bin": { "esr": "bin/esr.js" } }, "sha512-fRFVXcmYVmSmtYm2mL8RlUASt2TDkGh3uRcvHFOKNr/T58VrfVeKD9uT9nlgxk96u0LS0ehS/GY7Da/bXWKkhw=="],
|
||||||
|
|
||||||
|
"esm-env": ["esm-env@1.2.2", "", {}, "sha512-Epxrv+Nr/CaL4ZcFGPJIYLWFom+YeV1DqMLHJoEd9SYRxNbaFruBwfEX/kkHUJf55j2+TUbmDcmuilbP1TmXHA=="],
|
||||||
|
|
||||||
|
"esrap": ["esrap@2.1.0", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.4.15" } }, "sha512-yzmPNpl7TBbMRC5Lj2JlJZNPml0tzqoqP5B1JXycNUwtqma9AKCO0M2wHrdgsHcy1WRW7S9rJknAMtByg3usgA=="],
|
||||||
|
|
||||||
|
"estree-walker": ["estree-walker@2.0.2", "", {}, "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w=="],
|
||||||
|
|
||||||
|
"fast-check": ["fast-check@3.23.2", "", { "dependencies": { "pure-rand": "^6.1.0" } }, "sha512-h5+1OzzfCC3Ef7VbtKdcv7zsstUQwUDlYpUTvjeUsJAssPgLn7QzbboPtL5ro04Mq0rPOsMzl7q5hIbRs2wD1A=="],
|
||||||
|
|
||||||
|
"fdir": ["fdir@6.4.6", "", { "peerDependencies": { "picomatch": "^3 || ^4" }, "optionalPeers": ["picomatch"] }, "sha512-hiFoqpyZcfNm1yc4u8oWCf9A2c4D3QjCrks3zmoVKVxpQRzmPNar1hUJcBG2RQHvEVGDN+Jm81ZheVLAQMK6+w=="],
|
||||||
|
|
||||||
|
"formsnap": ["formsnap@2.0.1", "", { "dependencies": { "svelte-toolbelt": "^0.5.0" }, "peerDependencies": { "svelte": "^5.0.0", "sveltekit-superforms": "^2.19.0" } }, "sha512-iJSe4YKd/W6WhLwKDVJU9FQeaJRpEFuolhju7ZXlRpUVyDdqFdMP8AUBICgnVvQPyP41IPAlBa/v0Eo35iE6wQ=="],
|
||||||
|
|
||||||
|
"fsevents": ["fsevents@2.3.3", "", { "os": "darwin" }, "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw=="],
|
||||||
|
|
||||||
|
"function-bind": ["function-bind@1.1.2", "", {}, "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA=="],
|
||||||
|
|
||||||
|
"graceful-fs": ["graceful-fs@4.2.11", "", {}, "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ=="],
|
||||||
|
|
||||||
|
"hasown": ["hasown@2.0.2", "", { "dependencies": { "function-bind": "^1.1.2" } }, "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ=="],
|
||||||
|
|
||||||
|
"inline-style-parser": ["inline-style-parser@0.2.4", "", {}, "sha512-0aO8FkhNZlj/ZIbNi7Lxxr12obT7cL1moPfE4tg1LkX7LlLfC6DeX4l2ZEud1ukP9jNQyNnfzQVqwbwmAATY4Q=="],
|
||||||
|
|
||||||
|
"is-core-module": ["is-core-module@2.16.1", "", { "dependencies": { "hasown": "^2.0.2" } }, "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w=="],
|
||||||
|
|
||||||
|
"is-module": ["is-module@1.0.0", "", {}, "sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g=="],
|
||||||
|
|
||||||
|
"is-reference": ["is-reference@3.0.3", "", { "dependencies": { "@types/estree": "^1.0.6" } }, "sha512-ixkJoqQvAP88E6wLydLGGqCJsrFUnqoH6HnaczB8XmDH1oaWU+xxdptvikTgaEhtZ53Ky6YXiBuUI2WXLMCwjw=="],
|
||||||
|
|
||||||
|
"jiti": ["jiti@2.5.0", "", { "bin": { "jiti": "lib/jiti-cli.mjs" } }, "sha512-NWDAhdnATItTnRhip9VTd8oXDjVcbhetRN6YzckApnXGxpGUooKMAaf0KVvlZG0+KlJMGkeLElVn4M1ReuxKUQ=="],
|
||||||
|
|
||||||
|
"joi": ["joi@17.13.3", "", { "dependencies": { "@hapi/hoek": "^9.3.0", "@hapi/topo": "^5.1.0", "@sideway/address": "^4.1.5", "@sideway/formula": "^3.0.1", "@sideway/pinpoint": "^2.0.0" } }, "sha512-otDA4ldcIx+ZXsKHWmp0YizCweVRZG96J10b0FevjfuncLO1oX59THoAmHkNubYJ+9gWsYsp5k8v4ib6oDv1fA=="],
|
||||||
|
|
||||||
|
"json-schema-to-ts": ["json-schema-to-ts@3.1.1", "", { "dependencies": { "@babel/runtime": "^7.18.3", "ts-algebra": "^2.0.0" } }, "sha512-+DWg8jCJG2TEnpy7kOm/7/AxaYoaRbjVB4LFZLySZlWn8exGs3A4OLJR966cVvU26N7X9TWxl+Jsw7dzAqKT6g=="],
|
||||||
|
|
||||||
|
"kleur": ["kleur@4.1.5", "", {}, "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ=="],
|
||||||
|
|
||||||
|
"libphonenumber-js": ["libphonenumber-js@1.12.10", "", {}, "sha512-E91vHJD61jekHHR/RF/E83T/CMoaLXT7cwYA75T4gim4FZjnM6hbJjVIGg7chqlSqRsSvQ3izGmOjHy1SQzcGQ=="],
|
||||||
|
|
||||||
|
"lightningcss": ["lightningcss@1.30.1", "", { "dependencies": { "detect-libc": "^2.0.3" }, "optionalDependencies": { "lightningcss-darwin-arm64": "1.30.1", "lightningcss-darwin-x64": "1.30.1", "lightningcss-freebsd-x64": "1.30.1", "lightningcss-linux-arm-gnueabihf": "1.30.1", "lightningcss-linux-arm64-gnu": "1.30.1", "lightningcss-linux-arm64-musl": "1.30.1", "lightningcss-linux-x64-gnu": "1.30.1", "lightningcss-linux-x64-musl": "1.30.1", "lightningcss-win32-arm64-msvc": "1.30.1", "lightningcss-win32-x64-msvc": "1.30.1" } }, "sha512-xi6IyHML+c9+Q3W0S4fCQJOym42pyurFiJUHEcEyHS0CeKzia4yZDEsLlqOFykxOdHpNy0NmvVO31vcSqAxJCg=="],
|
||||||
|
|
||||||
|
"lightningcss-darwin-arm64": ["lightningcss-darwin-arm64@1.30.1", "", { "os": "darwin", "cpu": "arm64" }, "sha512-c8JK7hyE65X1MHMN+Viq9n11RRC7hgin3HhYKhrMyaXflk5GVplZ60IxyoVtzILeKr+xAJwg6zK6sjTBJ0FKYQ=="],
|
||||||
|
|
||||||
|
"lightningcss-darwin-x64": ["lightningcss-darwin-x64@1.30.1", "", { "os": "darwin", "cpu": "x64" }, "sha512-k1EvjakfumAQoTfcXUcHQZhSpLlkAuEkdMBsI/ivWw9hL+7FtilQc0Cy3hrx0AAQrVtQAbMI7YjCgYgvn37PzA=="],
|
||||||
|
|
||||||
|
"lightningcss-freebsd-x64": ["lightningcss-freebsd-x64@1.30.1", "", { "os": "freebsd", "cpu": "x64" }, "sha512-kmW6UGCGg2PcyUE59K5r0kWfKPAVy4SltVeut+umLCFoJ53RdCUWxcRDzO1eTaxf/7Q2H7LTquFHPL5R+Gjyig=="],
|
||||||
|
|
||||||
|
"lightningcss-linux-arm-gnueabihf": ["lightningcss-linux-arm-gnueabihf@1.30.1", "", { "os": "linux", "cpu": "arm" }, "sha512-MjxUShl1v8pit+6D/zSPq9S9dQ2NPFSQwGvxBCYaBYLPlCWuPh9/t1MRS8iUaR8i+a6w7aps+B4N0S1TYP/R+Q=="],
|
||||||
|
|
||||||
|
"lightningcss-linux-arm64-gnu": ["lightningcss-linux-arm64-gnu@1.30.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-gB72maP8rmrKsnKYy8XUuXi/4OctJiuQjcuqWNlJQ6jZiWqtPvqFziskH3hnajfvKB27ynbVCucKSm2rkQp4Bw=="],
|
||||||
|
|
||||||
|
"lightningcss-linux-arm64-musl": ["lightningcss-linux-arm64-musl@1.30.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-jmUQVx4331m6LIX+0wUhBbmMX7TCfjF5FoOH6SD1CttzuYlGNVpA7QnrmLxrsub43ClTINfGSYyHe2HWeLl5CQ=="],
|
||||||
|
|
||||||
|
"lightningcss-linux-x64-gnu": ["lightningcss-linux-x64-gnu@1.30.1", "", { "os": "linux", "cpu": "x64" }, "sha512-piWx3z4wN8J8z3+O5kO74+yr6ze/dKmPnI7vLqfSqI8bccaTGY5xiSGVIJBDd5K5BHlvVLpUB3S2YCfelyJ1bw=="],
|
||||||
|
|
||||||
|
"lightningcss-linux-x64-musl": ["lightningcss-linux-x64-musl@1.30.1", "", { "os": "linux", "cpu": "x64" }, "sha512-rRomAK7eIkL+tHY0YPxbc5Dra2gXlI63HL+v1Pdi1a3sC+tJTcFrHX+E86sulgAXeI7rSzDYhPSeHHjqFhqfeQ=="],
|
||||||
|
|
||||||
|
"lightningcss-win32-arm64-msvc": ["lightningcss-win32-arm64-msvc@1.30.1", "", { "os": "win32", "cpu": "arm64" }, "sha512-mSL4rqPi4iXq5YVqzSsJgMVFENoa4nGTT/GjO2c0Yl9OuQfPsIfncvLrEW6RbbB24WtZ3xP/2CCmI3tNkNV4oA=="],
|
||||||
|
|
||||||
|
"lightningcss-win32-x64-msvc": ["lightningcss-win32-x64-msvc@1.30.1", "", { "os": "win32", "cpu": "x64" }, "sha512-PVqXh48wh4T53F/1CCu8PIPCxLzWyCnn/9T5W1Jpmdy5h9Cwd+0YQS6/LwhHXSafuc61/xg9Lv5OrCby6a++jg=="],
|
||||||
|
|
||||||
|
"locate-character": ["locate-character@3.0.0", "", {}, "sha512-SW13ws7BjaeJ6p7Q6CO2nchbYEc3X3J6WrmTTDto7yMPqVSZTUyY5Tjbid+Ab8gLnATtygYtiDIJGQRRn2ZOiA=="],
|
||||||
|
|
||||||
|
"magic-string": ["magic-string@0.30.17", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.0" } }, "sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA=="],
|
||||||
|
|
||||||
|
"memoize-weak": ["memoize-weak@1.0.2", "", {}, "sha512-gj39xkrjEw7nCn4nJ1M5ms6+MyMlyiGmttzsqAUsAKn6bYKwuTHh/AO3cKPF8IBrTIYTxb0wWXFs3E//Y8VoWQ=="],
|
||||||
|
|
||||||
|
"minipass": ["minipass@7.1.2", "", {}, "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw=="],
|
||||||
|
|
||||||
|
"minizlib": ["minizlib@3.0.2", "", { "dependencies": { "minipass": "^7.1.2" } }, "sha512-oG62iEk+CYt5Xj2YqI5Xi9xWUeZhDI8jjQmC5oThVH5JGCTgIjr7ciJDzC7MBzYd//WvR1OTmP5Q38Q8ShQtVA=="],
|
||||||
|
|
||||||
|
"mkdirp": ["mkdirp@3.0.1", "", { "bin": { "mkdirp": "dist/cjs/src/bin.js" } }, "sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg=="],
|
||||||
|
|
||||||
|
"mode-watcher": ["mode-watcher@1.1.0", "", { "dependencies": { "runed": "^0.25.0", "svelte-toolbelt": "^0.7.1" }, "peerDependencies": { "svelte": "^5.27.0" } }, "sha512-mUT9RRGPDYenk59qJauN1rhsIMKBmWA3xMF+uRwE8MW/tjhaDSCCARqkSuDTq8vr4/2KcAxIGVjACxTjdk5C3g=="],
|
||||||
|
|
||||||
|
"mri": ["mri@1.2.0", "", {}, "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA=="],
|
||||||
|
|
||||||
|
"mrmime": ["mrmime@2.0.1", "", {}, "sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ=="],
|
||||||
|
|
||||||
|
"ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="],
|
||||||
|
|
||||||
|
"nanoid": ["nanoid@3.3.11", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w=="],
|
||||||
|
|
||||||
|
"normalize-url": ["normalize-url@8.0.2", "", {}, "sha512-Ee/R3SyN4BuynXcnTaekmaVdbDAEiNrHqjQIA37mHU8G9pf7aaAD4ZX3XjBLo6rsdcxA/gtkcNYZLt30ACgynw=="],
|
||||||
|
|
||||||
|
"path-parse": ["path-parse@1.0.7", "", {}, "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw=="],
|
||||||
|
|
||||||
|
"picocolors": ["picocolors@1.1.1", "", {}, "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="],
|
||||||
|
|
||||||
|
"picomatch": ["picomatch@4.0.3", "", {}, "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q=="],
|
||||||
|
|
||||||
|
"postcss": ["postcss@8.5.6", "", { "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } }, "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg=="],
|
||||||
|
|
||||||
|
"property-expr": ["property-expr@2.0.6", "", {}, "sha512-SVtmxhRE/CGkn3eZY1T6pC8Nln6Fr/lu1mKSgRud0eC73whjGfoAogbn78LkD8aFL0zz3bAFerKSnOl7NlErBA=="],
|
||||||
|
|
||||||
|
"pure-rand": ["pure-rand@6.1.0", "", {}, "sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA=="],
|
||||||
|
|
||||||
|
"readdirp": ["readdirp@4.1.2", "", {}, "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg=="],
|
||||||
|
|
||||||
|
"resolve": ["resolve@1.22.10", "", { "dependencies": { "is-core-module": "^2.16.0", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, "bin": { "resolve": "bin/resolve" } }, "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w=="],
|
||||||
|
|
||||||
|
"rollup": ["rollup@4.45.1", "", { "dependencies": { "@types/estree": "1.0.8" }, "optionalDependencies": { "@rollup/rollup-android-arm-eabi": "4.45.1", "@rollup/rollup-android-arm64": "4.45.1", "@rollup/rollup-darwin-arm64": "4.45.1", "@rollup/rollup-darwin-x64": "4.45.1", "@rollup/rollup-freebsd-arm64": "4.45.1", "@rollup/rollup-freebsd-x64": "4.45.1", "@rollup/rollup-linux-arm-gnueabihf": "4.45.1", "@rollup/rollup-linux-arm-musleabihf": "4.45.1", "@rollup/rollup-linux-arm64-gnu": "4.45.1", "@rollup/rollup-linux-arm64-musl": "4.45.1", "@rollup/rollup-linux-loongarch64-gnu": "4.45.1", "@rollup/rollup-linux-powerpc64le-gnu": "4.45.1", "@rollup/rollup-linux-riscv64-gnu": "4.45.1", "@rollup/rollup-linux-riscv64-musl": "4.45.1", "@rollup/rollup-linux-s390x-gnu": "4.45.1", "@rollup/rollup-linux-x64-gnu": "4.45.1", "@rollup/rollup-linux-x64-musl": "4.45.1", "@rollup/rollup-win32-arm64-msvc": "4.45.1", "@rollup/rollup-win32-ia32-msvc": "4.45.1", "@rollup/rollup-win32-x64-msvc": "4.45.1", "fsevents": "~2.3.2" }, "bin": { "rollup": "dist/bin/rollup" } }, "sha512-4iya7Jb76fVpQyLoiVpzUrsjQ12r3dM7fIVz+4NwoYvZOShknRmiv+iu9CClZml5ZLGb0XMcYLutK6w9tgxHDw=="],
|
||||||
|
|
||||||
|
"runed": ["runed@0.29.2", "", { "dependencies": { "esm-env": "^1.0.0" }, "peerDependencies": { "svelte": "^5.7.0" } }, "sha512-0cq6cA6sYGZwl/FvVqjx9YN+1xEBu9sDDyuWdDW1yWX7JF2wmvmVKfH+hVCZs+csW+P3ARH92MjI3H9QTagOQA=="],
|
||||||
|
|
||||||
|
"sade": ["sade@1.8.1", "", { "dependencies": { "mri": "^1.1.0" } }, "sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A=="],
|
||||||
|
|
||||||
|
"set-cookie-parser": ["set-cookie-parser@2.7.1", "", {}, "sha512-IOc8uWeOZgnb3ptbCURJWNjWUPcO3ZnTTdzsurqERrP6nPyv+paC55vJM0LpOlT2ne+Ix+9+CRG1MNLlyZ4GjQ=="],
|
||||||
|
|
||||||
|
"sirv": ["sirv@3.0.1", "", { "dependencies": { "@polka/url": "^1.0.0-next.24", "mrmime": "^2.0.0", "totalist": "^3.0.0" } }, "sha512-FoqMu0NCGBLCcAkS1qA+XJIQTR6/JHfQXl+uGteNCQ76T91DMUjPa9xfmeqMY3z80nLSg9yQmNjK0Px6RWsH/A=="],
|
||||||
|
|
||||||
|
"source-map": ["source-map@0.6.1", "", {}, "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="],
|
||||||
|
|
||||||
|
"source-map-js": ["source-map-js@1.2.1", "", {}, "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA=="],
|
||||||
|
|
||||||
|
"source-map-support": ["source-map-support@0.5.21", "", { "dependencies": { "buffer-from": "^1.0.0", "source-map": "^0.6.0" } }, "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w=="],
|
||||||
|
|
||||||
|
"style-to-object": ["style-to-object@1.0.9", "", { "dependencies": { "inline-style-parser": "0.2.4" } }, "sha512-G4qppLgKu/k6FwRpHiGiKPaPTFcG3g4wNVX/Qsfu+RqQM30E7Tyu/TEgxcL9PNLF5pdRLwQdE3YKKf+KF2Dzlw=="],
|
||||||
|
|
||||||
|
"superstruct": ["superstruct@2.0.2", "", {}, "sha512-uV+TFRZdXsqXTL2pRvujROjdZQ4RAlBUS5BTh9IGm+jTqQntYThciG/qu57Gs69yjnVUSqdxF9YLmSnpupBW9A=="],
|
||||||
|
|
||||||
|
"supports-preserve-symlinks-flag": ["supports-preserve-symlinks-flag@1.0.0", "", {}, "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w=="],
|
||||||
|
|
||||||
|
"svelte": ["svelte@5.36.15", "", { "dependencies": { "@ampproject/remapping": "^2.3.0", "@jridgewell/sourcemap-codec": "^1.5.0", "@sveltejs/acorn-typescript": "^1.0.5", "@types/estree": "^1.0.5", "acorn": "^8.12.1", "aria-query": "^5.3.1", "axobject-query": "^4.1.0", "clsx": "^2.1.1", "esm-env": "^1.2.1", "esrap": "^2.1.0", "is-reference": "^3.0.3", "locate-character": "^3.0.0", "magic-string": "^0.30.11", "zimmerframe": "^1.1.2" } }, "sha512-4oV3J7PbNWFM8sUx/qG8lvawAYL7Mj5EKURbP/lRuOmh4b3BKxb8EFQHSKq07RHttzsP2F+9HTKUyZ1khSd7SQ=="],
|
||||||
|
|
||||||
|
"svelte-check": ["svelte-check@4.3.0", "", { "dependencies": { "@jridgewell/trace-mapping": "^0.3.25", "chokidar": "^4.0.1", "fdir": "^6.2.0", "picocolors": "^1.0.0", "sade": "^1.7.4" }, "peerDependencies": { "svelte": "^4.0.0 || ^5.0.0-next.0", "typescript": ">=5.0.0" }, "bin": { "svelte-check": "bin/svelte-check" } }, "sha512-Iz8dFXzBNAM7XlEIsUjUGQhbEE+Pvv9odb9+0+ITTgFWZBGeJRRYqHUUglwe2EkLD5LIsQaAc4IUJyvtKuOO5w=="],
|
||||||
|
|
||||||
|
"svelte-toolbelt": ["svelte-toolbelt@0.9.3", "", { "dependencies": { "clsx": "^2.1.1", "runed": "^0.29.0", "style-to-object": "^1.0.8" }, "peerDependencies": { "svelte": "^5.30.2" } }, "sha512-HCSWxCtVmv+c6g1ACb8LTwHVbDqLKJvHpo6J8TaqwUme2hj9ATJCpjCPNISR1OCq2Q4U1KT41if9ON0isINQZw=="],
|
||||||
|
|
||||||
|
"sveltekit-superforms": ["sveltekit-superforms@2.27.1", "", { "dependencies": { "devalue": "^5.1.1", "memoize-weak": "^1.0.2", "ts-deepmerge": "^7.0.3" }, "optionalDependencies": { "@exodus/schemasafe": "^1.3.0", "@gcornut/valibot-json-schema": "^0.42.0", "@sinclair/typebox": "^0.34.35", "@typeschema/class-validator": "^0.3.0", "@vinejs/vine": "^3.0.1", "arktype": "^2.1.20", "class-validator": "^0.14.2", "effect": "^3.16.7", "joi": "^17.13.3", "json-schema-to-ts": "^3.1.1", "superstruct": "^2.0.2", "valibot": "^1.1.0", "yup": "^1.6.1", "zod": "^3.25.64", "zod-to-json-schema": "^3.24.5" }, "peerDependencies": { "@sveltejs/kit": "1.x || 2.x", "svelte": "3.x || 4.x || >=5.0.0-next.51" } }, "sha512-cvq2AevkZ0Zrk0w0gNM3kjcnJMtJ0jzu+2zqDoM9a+lZa+8bGpNl4YqxVkemiJNkGnFgNC8xr5xF5BlMzjookQ=="],
|
||||||
|
|
||||||
|
"tabbable": ["tabbable@6.2.0", "", {}, "sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew=="],
|
||||||
|
|
||||||
|
"tailwind-merge": ["tailwind-merge@3.3.1", "", {}, "sha512-gBXpgUm/3rp1lMZZrM/w7D8GKqshif0zAymAhbCyIt8KMe+0v9DQ7cdYLR4FHH/cKpdTXb+A/tKKU3eolfsI+g=="],
|
||||||
|
|
||||||
|
"tailwind-variants": ["tailwind-variants@1.0.0", "", { "dependencies": { "tailwind-merge": "3.0.2" }, "peerDependencies": { "tailwindcss": "*" } }, "sha512-2WSbv4ulEEyuBKomOunut65D8UZwxrHoRfYnxGcQNnHqlSCp2+B7Yz2W+yrNDrxRodOXtGD/1oCcKGNBnUqMqA=="],
|
||||||
|
|
||||||
|
"tailwindcss": ["tailwindcss@4.1.11", "", {}, "sha512-2E9TBm6MDD/xKYe+dvJZAmg3yxIEDNRc0jwlNyDg/4Fil2QcSLjFKGVff0lAf1jjeaArlG/M75Ey/EYr/OJtBA=="],
|
||||||
|
|
||||||
|
"tapable": ["tapable@2.2.2", "", {}, "sha512-Re10+NauLTMCudc7T5WLFLAwDhQ0JWdrMK+9B2M8zR5hRExKmsRDCBA7/aV/pNJFltmBFO5BAMlQFi/vq3nKOg=="],
|
||||||
|
|
||||||
|
"tar": ["tar@7.4.3", "", { "dependencies": { "@isaacs/fs-minipass": "^4.0.0", "chownr": "^3.0.0", "minipass": "^7.1.2", "minizlib": "^3.0.1", "mkdirp": "^3.0.1", "yallist": "^5.0.0" } }, "sha512-5S7Va8hKfV7W5U6g3aYxXmlPoZVAwUMy9AOKyF2fVuZa2UD3qZjg578OrLRt8PcNN1PleVaL/5/yYATNL0ICUw=="],
|
||||||
|
|
||||||
|
"tiny-case": ["tiny-case@1.0.3", "", {}, "sha512-Eet/eeMhkO6TX8mnUteS9zgPbUMQa4I6Kkp5ORiBD5476/m+PIRiumP5tmh5ioJpH7k51Kehawy2UDfsnxxY8Q=="],
|
||||||
|
|
||||||
|
"tinyglobby": ["tinyglobby@0.2.14", "", { "dependencies": { "fdir": "^6.4.4", "picomatch": "^4.0.2" } }, "sha512-tX5e7OM1HnYr2+a2C/4V0htOcSQcoSTH9KgJnVvNm5zm/cyEWKJ7j7YutsH9CxMdtOkkLFy2AHrMci9IM8IPZQ=="],
|
||||||
|
|
||||||
|
"toposort": ["toposort@2.0.2", "", {}, "sha512-0a5EOkAUp8D4moMi2W8ZF8jcga7BgZd91O/yabJCFY8az+XSzeGyTKs0Aoo897iV1Nj6guFq8orWDS96z91oGg=="],
|
||||||
|
|
||||||
|
"totalist": ["totalist@3.0.1", "", {}, "sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ=="],
|
||||||
|
|
||||||
|
"ts-algebra": ["ts-algebra@2.0.0", "", {}, "sha512-FPAhNPFMrkwz76P7cdjdmiShwMynZYN6SgOujD1urY4oNm80Ou9oMdmbR45LotcKOXoy7wSmHkRFE6Mxbrhefw=="],
|
||||||
|
|
||||||
|
"ts-deepmerge": ["ts-deepmerge@7.0.3", "", {}, "sha512-Du/ZW2RfwV/D4cmA5rXafYjBQVuvu4qGiEEla4EmEHVHgRdx68Gftx7i66jn2bzHPwSVZY36Ae6OuDn9el4ZKA=="],
|
||||||
|
|
||||||
|
"tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="],
|
||||||
|
|
||||||
|
"tw-animate-css": ["tw-animate-css@1.3.5", "", {}, "sha512-t3u+0YNoloIhj1mMXs779P6MO9q3p3mvGn4k1n3nJPqJw/glZcuijG2qTSN4z4mgNRfW5ZC3aXJFLwDtiipZXA=="],
|
||||||
|
|
||||||
|
"type-fest": ["type-fest@2.19.0", "", {}, "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA=="],
|
||||||
|
|
||||||
|
"typescript": ["typescript@5.8.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ=="],
|
||||||
|
|
||||||
|
"undici-types": ["undici-types@7.8.0", "", {}, "sha512-9UJ2xGDvQ43tYyVMpuHlsgApydB8ZKfVYTsLDhXkFL/6gfkp+U8xTGdh8pMJv1SpZna0zxG1DwsKZsreLbXBxw=="],
|
||||||
|
|
||||||
|
"valibot": ["valibot@1.1.0", "", { "peerDependencies": { "typescript": ">=5" }, "optionalPeers": ["typescript"] }, "sha512-Nk8lX30Qhu+9txPYTwM0cFlWLdPFsFr6LblzqIySfbZph9+BFsAHsNvHOymEviUepeIW6KFHzpX8TKhbptBXXw=="],
|
||||||
|
|
||||||
|
"validator": ["validator@13.15.15", "", {}, "sha512-BgWVbCI72aIQy937xbawcs+hrVaN/CZ2UwutgaJ36hGqRrLNM+f5LUT/YPRbo8IV/ASeFzXszezV+y2+rq3l8A=="],
|
||||||
|
|
||||||
|
"vite": ["vite@7.0.6", "", { "dependencies": { "esbuild": "^0.25.0", "fdir": "^6.4.6", "picomatch": "^4.0.3", "postcss": "^8.5.6", "rollup": "^4.40.0", "tinyglobby": "^0.2.14" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^20.19.0 || >=22.12.0", "jiti": ">=1.21.0", "less": "^4.0.0", "lightningcss": "^1.21.0", "sass": "^1.70.0", "sass-embedded": "^1.70.0", "stylus": ">=0.54.8", "sugarss": "^5.0.0", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "jiti", "less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-MHFiOENNBd+Bd9uvc8GEsIzdkn1JxMmEeYX35tI3fv0sJBUTfW5tQsoaOwuY4KhBI09A3dUJ/DXf2yxPVPUceg=="],
|
||||||
|
|
||||||
|
"vitefu": ["vitefu@1.1.1", "", { "peerDependencies": { "vite": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0-beta.0" }, "optionalPeers": ["vite"] }, "sha512-B/Fegf3i8zh0yFbpzZ21amWzHmuNlLlmJT6n7bu5e+pCHUKQIfXSYokrqOBGEMMe9UG2sostKQF9mml/vYaWJQ=="],
|
||||||
|
|
||||||
|
"ws": ["ws@8.18.3", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg=="],
|
||||||
|
|
||||||
|
"yallist": ["yallist@5.0.0", "", {}, "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw=="],
|
||||||
|
|
||||||
|
"yup": ["yup@1.6.1", "", { "dependencies": { "property-expr": "^2.0.5", "tiny-case": "^1.0.3", "toposort": "^2.0.2", "type-fest": "^2.19.0" } }, "sha512-JED8pB50qbA4FOkDol0bYF/p60qSEDQqBD0/qeIrUCG1KbPBIQ776fCUNb9ldbPcSTxA69g/47XTo4TqWiuXOA=="],
|
||||||
|
|
||||||
|
"zimmerframe": ["zimmerframe@1.1.2", "", {}, "sha512-rAbqEGa8ovJy4pyBxZM70hg4pE6gDgaQ0Sl9M3enG3I0d6H4XSAM3GeNGLKnsBpuijUow064sf7ww1nutC5/3w=="],
|
||||||
|
|
||||||
|
"zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="],
|
||||||
|
|
||||||
|
"zod-to-json-schema": ["zod-to-json-schema@3.24.6", "", { "peerDependencies": { "zod": "^3.24.1" } }, "sha512-h/z3PKvcTcTetyjl1fkj79MHNEjm+HpD6NXheWjzOekY7kV+lwDYnHw+ivHkijnCSMz1yJaWBD9vu/Fcmk+vEg=="],
|
||||||
|
|
||||||
|
"@gcornut/valibot-json-schema/valibot": ["valibot@0.42.1", "", { "peerDependencies": { "typescript": ">=5" }, "optionalPeers": ["typescript"] }, "sha512-3keXV29Ar5b//Hqi4MbSdV7lfVp6zuYLZuA9V1PvQUsXqogr+u5lvLPLk3A4f74VUXDnf/JfWMN6sB+koJ/FFw=="],
|
||||||
|
|
||||||
|
"@rollup/plugin-commonjs/is-reference": ["is-reference@1.2.1", "", { "dependencies": { "@types/estree": "*" } }, "sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ=="],
|
||||||
|
|
||||||
|
"@tailwindcss/oxide-wasm32-wasi/@emnapi/core": ["@emnapi/core@1.4.5", "", { "dependencies": { "@emnapi/wasi-threads": "1.0.4", "tslib": "^2.4.0" }, "bundled": true }, "sha512-XsLw1dEOpkSX/WucdqUhPWP7hDxSvZiY+fsUC14h+FtQ2Ifni4znbBt8punRX+Uj2JG/uDb8nEHVKvrVlvdZ5Q=="],
|
||||||
|
|
||||||
|
"@tailwindcss/oxide-wasm32-wasi/@emnapi/runtime": ["@emnapi/runtime@1.4.5", "", { "dependencies": { "tslib": "^2.4.0" }, "bundled": true }, "sha512-++LApOtY0pEEz1zrd9vy1/zXVaVJJ/EbAF3u0fXIzPJEDtnITsBGbbK0EkM72amhl/R5b+5xx0Y/QhcVOpuulg=="],
|
||||||
|
|
||||||
|
"@tailwindcss/oxide-wasm32-wasi/@emnapi/wasi-threads": ["@emnapi/wasi-threads@1.0.4", "", { "dependencies": { "tslib": "^2.4.0" }, "bundled": true }, "sha512-PJR+bOmMOPH8AtcTGAyYNiuJ3/Fcoj2XN/gBEWzDIKh254XO+mM9XoXHk5GNEhodxeMznbg7BlRojVbKN+gC6g=="],
|
||||||
|
|
||||||
|
"@tailwindcss/oxide-wasm32-wasi/@napi-rs/wasm-runtime": ["@napi-rs/wasm-runtime@0.2.12", "", { "dependencies": { "@emnapi/core": "^1.4.3", "@emnapi/runtime": "^1.4.3", "@tybys/wasm-util": "^0.10.0" }, "bundled": true }, "sha512-ZVWUcfwY4E/yPitQJl481FjFo3K22D6qF0DuFH6Y/nbnE11GY5uguDxZMGXPQ8WQ0128MXQD7TnfHyK4oWoIJQ=="],
|
||||||
|
|
||||||
|
"@tailwindcss/oxide-wasm32-wasi/@tybys/wasm-util": ["@tybys/wasm-util@0.9.0", "", { "dependencies": { "tslib": "^2.4.0" }, "bundled": true }, "sha512-6+7nlbMVX/PVDCwaIQ8nTOPveOcFLSt8GcXdx8hD0bt39uWxYT88uXzqTd4fTvqta7oeUJqudepapKNt2DYJFw=="],
|
||||||
|
|
||||||
|
"@tailwindcss/oxide-wasm32-wasi/tslib": ["tslib@2.8.1", "", { "bundled": true }, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="],
|
||||||
|
|
||||||
|
"esbuild-runner/tslib": ["tslib@2.4.0", "", {}, "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ=="],
|
||||||
|
|
||||||
|
"formsnap/svelte-toolbelt": ["svelte-toolbelt@0.5.0", "", { "dependencies": { "clsx": "^2.1.1", "style-to-object": "^1.0.8" }, "peerDependencies": { "svelte": "^5.0.0-next.126" } }, "sha512-t3tenZcnfQoIeRuQf/jBU7bvTeT3TGkcEE+1EUr5orp0lR7NEpprflpuie3x9Dn0W9nOKqs3HwKGJeeN5Ok1sQ=="],
|
||||||
|
|
||||||
|
"mode-watcher/runed": ["runed@0.25.0", "", { "dependencies": { "esm-env": "^1.0.0" }, "peerDependencies": { "svelte": "^5.7.0" } }, "sha512-7+ma4AG9FT2sWQEA0Egf6mb7PBT2vHyuHail1ie8ropfSjvZGtEAx8YTmUjv/APCsdRRxEVvArNjALk9zFSOrg=="],
|
||||||
|
|
||||||
|
"mode-watcher/svelte-toolbelt": ["svelte-toolbelt@0.7.1", "", { "dependencies": { "clsx": "^2.1.1", "runed": "^0.23.2", "style-to-object": "^1.0.8" }, "peerDependencies": { "svelte": "^5.0.0" } }, "sha512-HcBOcR17Vx9bjaOceUvxkY3nGmbBmCBBbuWLLEWO6jtmWH8f/QoWmbyUfQZrpDINH39en1b8mptfPQT9VKQ1xQ=="],
|
||||||
|
|
||||||
|
"tailwind-variants/tailwind-merge": ["tailwind-merge@3.0.2", "", {}, "sha512-l7z+OYZ7mu3DTqrL88RiKrKIqO3NcpEO8V/Od04bNpvk0kiIFndGEoqfuzvj4yuhRkHKjRkII2z+KS2HfPcSxw=="],
|
||||||
|
|
||||||
|
"@tailwindcss/oxide-wasm32-wasi/@napi-rs/wasm-runtime/@tybys/wasm-util": ["@tybys/wasm-util@0.10.0", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-VyyPYFlOMNylG45GoAe0xDoLwWuowvf92F9kySqzYh8vmYm7D2u4iUJKa1tOUpS70Ku13ASrOkS4ScXFsTaCNQ=="],
|
||||||
|
|
||||||
|
"mode-watcher/svelte-toolbelt/runed": ["runed@0.23.4", "", { "dependencies": { "esm-env": "^1.0.0" }, "peerDependencies": { "svelte": "^5.7.0" } }, "sha512-9q8oUiBYeXIDLWNK5DfCWlkL0EW3oGbk845VdKlPeia28l751VpfesaB/+7pI6rnbx1I6rqoZ2fZxptOJLxILA=="],
|
||||||
|
}
|
||||||
|
}
|
50
compose.yaml
Normal file
50
compose.yaml
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
services:
|
||||||
|
|
||||||
|
server:
|
||||||
|
image: git.thielker.dev/markus/hl7v2-server:latest
|
||||||
|
build:
|
||||||
|
context: .
|
||||||
|
dockerfile: packages/server/Containerfile
|
||||||
|
ports:
|
||||||
|
- "8080:8080"
|
||||||
|
networks:
|
||||||
|
- internal
|
||||||
|
- web
|
||||||
|
environment:
|
||||||
|
- NODE_ENV=production
|
||||||
|
- PORT=${PORT}
|
||||||
|
- PREFIXES=${PREFIXES}
|
||||||
|
- POOL_SIZE=${POOL_SIZE}
|
||||||
|
labels:
|
||||||
|
- "traefik.enable=true"
|
||||||
|
- "traefik.http.routers.dev-thielker-hnu-hl7v2-server.rule=Host(`${SERVER_URL}`)"
|
||||||
|
- "traefik.http.routers.dev-thielker-hnu-hl7v2-server.entrypoints=websecure"
|
||||||
|
- "traefik.http.routers.dev-thielker-hnu-hl7v2-server.tls=true"
|
||||||
|
- "traefik.http.routers.dev-thielker-hnu-hl7v2-server.tls.certresolver=lets-encrypt"
|
||||||
|
|
||||||
|
client:
|
||||||
|
image: git.thielker.dev/markus/hl7v2-client:latest
|
||||||
|
build:
|
||||||
|
context: .
|
||||||
|
dockerfile: packages/client/Containerfile
|
||||||
|
ports:
|
||||||
|
- "3000:3000"
|
||||||
|
networks:
|
||||||
|
- web
|
||||||
|
- internal
|
||||||
|
environment:
|
||||||
|
- NODE_ENV=production
|
||||||
|
- PUBLIC_SERVER=${SERVER_URL}
|
||||||
|
depends_on:
|
||||||
|
- server
|
||||||
|
labels:
|
||||||
|
- "traefik.enable=true"
|
||||||
|
- "traefik.http.routers.dev-thielker-hnu-hl7v2-client.rule=Host(`${CLIENT_URL}`)"
|
||||||
|
- "traefik.http.routers.dev-thielker-hnu-hl7v2-client.entrypoints=websecure"
|
||||||
|
- "traefik.http.routers.dev-thielker-hnu-hl7v2-client.tls=true"
|
||||||
|
- "traefik.http.routers.dev-thielker-hnu-hl7v2-client.tls.certresolver=lets-encrypt"
|
||||||
|
|
||||||
|
networks:
|
||||||
|
web:
|
||||||
|
external: true
|
||||||
|
internal:
|
11
package.json
Normal file
11
package.json
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
{
|
||||||
|
"name": "@hnu.de/hl7v2",
|
||||||
|
"private": true,
|
||||||
|
"workspaces": [
|
||||||
|
"packages/*"
|
||||||
|
],
|
||||||
|
"scripts": {
|
||||||
|
"dev": "bun run --filter '*' dev",
|
||||||
|
"build": "bun run --filter '*' build"
|
||||||
|
}
|
||||||
|
}
|
26
packages/client/.gitignore
vendored
Normal file
26
packages/client/.gitignore
vendored
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
/node_modules
|
||||||
|
|
||||||
|
# Idea
|
||||||
|
/.idea
|
||||||
|
|
||||||
|
# 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-*
|
59
packages/client/Containerfile
Normal file
59
packages/client/Containerfile
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
# Stage 1: Builder
|
||||||
|
# This stage installs all dependencies and builds all packages.
|
||||||
|
FROM oven/bun:1 AS builder
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
# Copy dependency manifests
|
||||||
|
COPY package.json bun.lock ./
|
||||||
|
COPY tsconfig.base.json ./
|
||||||
|
|
||||||
|
# Copy package-specific manifests to leverage Docker cache
|
||||||
|
COPY packages/shared/package.json packages/shared/tsconfig.json ./packages/shared/
|
||||||
|
COPY packages/client/package.json packages/client/tsconfig.json ./packages/client/
|
||||||
|
|
||||||
|
# Install ALL workspace dependencies
|
||||||
|
RUN bun install
|
||||||
|
|
||||||
|
# Copy source code
|
||||||
|
COPY packages/shared ./packages/shared/
|
||||||
|
COPY packages/client ./packages/client/
|
||||||
|
|
||||||
|
# Build the client and its dependencies (i.e., 'shared')
|
||||||
|
RUN bun run --filter=@hnu.de/hl7v2-shared build
|
||||||
|
RUN bun run --filter=@hnu.de/hl7v2-client build
|
||||||
|
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------
|
||||||
|
|
||||||
|
# Stage 2: Production
|
||||||
|
FROM oven/bun:1-slim
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
# Create the full directory structure first
|
||||||
|
RUN mkdir -p packages/shared packages/client
|
||||||
|
|
||||||
|
# Copy workspace configuration
|
||||||
|
COPY --from=builder /app/package.json /app/bun.lock ./
|
||||||
|
|
||||||
|
# Set up shared package with its dist directory
|
||||||
|
COPY --from=builder /app/packages/shared/package.json ./packages/shared/
|
||||||
|
COPY --from=builder /app/packages/shared/dist ./packages/shared/dist
|
||||||
|
|
||||||
|
# Set up client package with its dist directory
|
||||||
|
COPY --from=builder /app/packages/client/package.json ./packages/client/
|
||||||
|
COPY --from=builder /app/packages/client/build ./packages/client/build
|
||||||
|
|
||||||
|
# Install ONLY production dependencies
|
||||||
|
ENV NODE_ENV=production
|
||||||
|
RUN bun install \
|
||||||
|
--frozen-lockfile \
|
||||||
|
--production
|
||||||
|
|
||||||
|
# Set environment variables from config.ts
|
||||||
|
ENV PUBLIC_SERVER=localhost:8080
|
||||||
|
|
||||||
|
EXPOSE 3000
|
||||||
|
|
||||||
|
# Run the client from its package directory
|
||||||
|
WORKDIR /app/packages/client
|
||||||
|
CMD ["bun", "-r", "dotenv/config", "build/index.js"]
|
16
packages/client/components.json
Normal file
16
packages/client/components.json
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
{
|
||||||
|
"$schema": "https://shadcn-svelte.com/schema.json",
|
||||||
|
"tailwind": {
|
||||||
|
"css": "src/app.css",
|
||||||
|
"baseColor": "neutral"
|
||||||
|
},
|
||||||
|
"aliases": {
|
||||||
|
"components": "$lib/components",
|
||||||
|
"utils": "$lib/utils",
|
||||||
|
"ui": "$lib/components/ui",
|
||||||
|
"hooks": "$lib/hooks",
|
||||||
|
"lib": "$lib"
|
||||||
|
},
|
||||||
|
"typescript": true,
|
||||||
|
"registry": "https://shadcn-svelte.com/registry"
|
||||||
|
}
|
41
packages/client/package.json
Normal file
41
packages/client/package.json
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
{
|
||||||
|
"name": "@hnu.de/hl7v2-client",
|
||||||
|
"private": true,
|
||||||
|
"version": "0.1.0",
|
||||||
|
"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"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@hnu.de/hl7v2-shared": "workspace:*",
|
||||||
|
"dotenv": "^17.2.0"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@internationalized/date": "^3.8.1",
|
||||||
|
"@lucide/svelte": "^0.515.0",
|
||||||
|
"@sveltejs/adapter-node": "^5.2.13",
|
||||||
|
"@sveltejs/kit": "^2.22.0",
|
||||||
|
"@sveltejs/vite-plugin-svelte": "^6.0.0",
|
||||||
|
"@tailwindcss/vite": "^4.0.0",
|
||||||
|
"@types/ws": "^8.18.1",
|
||||||
|
"bits-ui": "^2.8.6",
|
||||||
|
"clsx": "^2.1.1",
|
||||||
|
"formsnap": "^2.0.1",
|
||||||
|
"mode-watcher": "^1.1.0",
|
||||||
|
"svelte": "^5.0.0",
|
||||||
|
"svelte-check": "^4.0.0",
|
||||||
|
"sveltekit-superforms": "^2.26.1",
|
||||||
|
"tailwind-merge": "^3.3.1",
|
||||||
|
"tailwind-variants": "^1.0.0",
|
||||||
|
"tailwindcss": "^4.0.0",
|
||||||
|
"tw-animate-css": "^1.3.5",
|
||||||
|
"typescript": "^5.0.0",
|
||||||
|
"vite": "^7.0.4",
|
||||||
|
"ws": "^8.18.3"
|
||||||
|
}
|
||||||
|
}
|
121
packages/client/src/app.css
Normal file
121
packages/client/src/app.css
Normal file
|
@ -0,0 +1,121 @@
|
||||||
|
@import "tailwindcss";
|
||||||
|
@import "tw-animate-css";
|
||||||
|
|
||||||
|
@custom-variant dark (&:is(.dark *));
|
||||||
|
|
||||||
|
:root {
|
||||||
|
--radius: 0.625rem;
|
||||||
|
--background: oklch(1 0 0);
|
||||||
|
--foreground: oklch(0.145 0 0);
|
||||||
|
--card: oklch(1 0 0);
|
||||||
|
--card-foreground: oklch(0.145 0 0);
|
||||||
|
--popover: oklch(1 0 0);
|
||||||
|
--popover-foreground: oklch(0.145 0 0);
|
||||||
|
--primary: oklch(0.205 0 0);
|
||||||
|
--primary-foreground: oklch(0.985 0 0);
|
||||||
|
--secondary: oklch(0.97 0 0);
|
||||||
|
--secondary-foreground: oklch(0.205 0 0);
|
||||||
|
--muted: oklch(0.97 0 0);
|
||||||
|
--muted-foreground: oklch(0.556 0 0);
|
||||||
|
--accent: oklch(0.97 0 0);
|
||||||
|
--accent-foreground: oklch(0.205 0 0);
|
||||||
|
--destructive: oklch(0.577 0.245 27.325);
|
||||||
|
--border: oklch(0.922 0 0);
|
||||||
|
--input: oklch(0.922 0 0);
|
||||||
|
--ring: oklch(0.708 0 0);
|
||||||
|
--chart-1: oklch(0.646 0.222 41.116);
|
||||||
|
--chart-2: oklch(0.6 0.118 184.704);
|
||||||
|
--chart-3: oklch(0.398 0.07 227.392);
|
||||||
|
--chart-4: oklch(0.828 0.189 84.429);
|
||||||
|
--chart-5: oklch(0.769 0.188 70.08);
|
||||||
|
--sidebar: oklch(0.985 0 0);
|
||||||
|
--sidebar-foreground: oklch(0.145 0 0);
|
||||||
|
--sidebar-primary: oklch(0.205 0 0);
|
||||||
|
--sidebar-primary-foreground: oklch(0.985 0 0);
|
||||||
|
--sidebar-accent: oklch(0.97 0 0);
|
||||||
|
--sidebar-accent-foreground: oklch(0.205 0 0);
|
||||||
|
--sidebar-border: oklch(0.922 0 0);
|
||||||
|
--sidebar-ring: oklch(0.708 0 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
.dark {
|
||||||
|
--background: oklch(0.145 0 0);
|
||||||
|
--foreground: oklch(0.985 0 0);
|
||||||
|
--card: oklch(0.205 0 0);
|
||||||
|
--card-foreground: oklch(0.985 0 0);
|
||||||
|
--popover: oklch(0.205 0 0);
|
||||||
|
--popover-foreground: oklch(0.985 0 0);
|
||||||
|
--primary: oklch(0.922 0 0);
|
||||||
|
--primary-foreground: oklch(0.205 0 0);
|
||||||
|
--secondary: oklch(0.269 0 0);
|
||||||
|
--secondary-foreground: oklch(0.985 0 0);
|
||||||
|
--muted: oklch(0.269 0 0);
|
||||||
|
--muted-foreground: oklch(0.708 0 0);
|
||||||
|
--accent: oklch(0.269 0 0);
|
||||||
|
--accent-foreground: oklch(0.985 0 0);
|
||||||
|
--destructive: oklch(0.704 0.191 22.216);
|
||||||
|
--border: oklch(1 0 0 / 10%);
|
||||||
|
--input: oklch(1 0 0 / 15%);
|
||||||
|
--ring: oklch(0.556 0 0);
|
||||||
|
--chart-1: oklch(0.488 0.243 264.376);
|
||||||
|
--chart-2: oklch(0.696 0.17 162.48);
|
||||||
|
--chart-3: oklch(0.769 0.188 70.08);
|
||||||
|
--chart-4: oklch(0.627 0.265 303.9);
|
||||||
|
--chart-5: oklch(0.645 0.246 16.439);
|
||||||
|
--sidebar: oklch(0.205 0 0);
|
||||||
|
--sidebar-foreground: oklch(0.985 0 0);
|
||||||
|
--sidebar-primary: oklch(0.488 0.243 264.376);
|
||||||
|
--sidebar-primary-foreground: oklch(0.985 0 0);
|
||||||
|
--sidebar-accent: oklch(0.269 0 0);
|
||||||
|
--sidebar-accent-foreground: oklch(0.985 0 0);
|
||||||
|
--sidebar-border: oklch(1 0 0 / 10%);
|
||||||
|
--sidebar-ring: oklch(0.556 0 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@theme inline {
|
||||||
|
--radius-sm: calc(var(--radius) - 4px);
|
||||||
|
--radius-md: calc(var(--radius) - 2px);
|
||||||
|
--radius-lg: var(--radius);
|
||||||
|
--radius-xl: calc(var(--radius) + 4px);
|
||||||
|
--color-background: var(--background);
|
||||||
|
--color-foreground: var(--foreground);
|
||||||
|
--color-card: var(--card);
|
||||||
|
--color-card-foreground: var(--card-foreground);
|
||||||
|
--color-popover: var(--popover);
|
||||||
|
--color-popover-foreground: var(--popover-foreground);
|
||||||
|
--color-primary: var(--primary);
|
||||||
|
--color-primary-foreground: var(--primary-foreground);
|
||||||
|
--color-secondary: var(--secondary);
|
||||||
|
--color-secondary-foreground: var(--secondary-foreground);
|
||||||
|
--color-muted: var(--muted);
|
||||||
|
--color-muted-foreground: var(--muted-foreground);
|
||||||
|
--color-accent: var(--accent);
|
||||||
|
--color-accent-foreground: var(--accent-foreground);
|
||||||
|
--color-destructive: var(--destructive);
|
||||||
|
--color-border: var(--border);
|
||||||
|
--color-input: var(--input);
|
||||||
|
--color-ring: var(--ring);
|
||||||
|
--color-chart-1: var(--chart-1);
|
||||||
|
--color-chart-2: var(--chart-2);
|
||||||
|
--color-chart-3: var(--chart-3);
|
||||||
|
--color-chart-4: var(--chart-4);
|
||||||
|
--color-chart-5: var(--chart-5);
|
||||||
|
--color-sidebar: var(--sidebar);
|
||||||
|
--color-sidebar-foreground: var(--sidebar-foreground);
|
||||||
|
--color-sidebar-primary: var(--sidebar-primary);
|
||||||
|
--color-sidebar-primary-foreground: var(--sidebar-primary-foreground);
|
||||||
|
--color-sidebar-accent: var(--sidebar-accent);
|
||||||
|
--color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
|
||||||
|
--color-sidebar-border: var(--sidebar-border);
|
||||||
|
--color-sidebar-ring: var(--sidebar-ring);
|
||||||
|
}
|
||||||
|
|
||||||
|
@layer base {
|
||||||
|
* {
|
||||||
|
@apply border-border outline-ring/50;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
@apply bg-background text-foreground;
|
||||||
|
}
|
||||||
|
}
|
13
packages/client/src/app.d.ts
vendored
Normal file
13
packages/client/src/app.d.ts
vendored
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
import type { WebSocketServer } from 'ws';
|
||||||
|
|
||||||
|
declare global {
|
||||||
|
namespace App {
|
||||||
|
// interface Error {}
|
||||||
|
// interface Locals {}
|
||||||
|
// interface PageData {}
|
||||||
|
// interface PageState {}
|
||||||
|
// interface Platform {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export {};
|
12
packages/client/src/app.html
Normal file
12
packages/client/src/app.html
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
<!doctype html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8"/>
|
||||||
|
<link rel="icon" href="%sveltekit.assets%/favicon.svg"/>
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1"/>
|
||||||
|
%sveltekit.head%
|
||||||
|
</head>
|
||||||
|
<body data-sveltekit-preload-data="hover">
|
||||||
|
<div style="display: contents">%sveltekit.body%</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
40
packages/client/src/lib/components/theme-selector.svelte
Normal file
40
packages/client/src/lib/components/theme-selector.svelte
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
<script lang="ts">
|
||||||
|
|
||||||
|
import { userPrefersMode, resetMode, setMode } from "mode-watcher"
|
||||||
|
import { buttonVariants } from "$lib/components/ui/button"
|
||||||
|
import {
|
||||||
|
DropdownMenu,
|
||||||
|
DropdownMenuContent,
|
||||||
|
DropdownMenuItem,
|
||||||
|
DropdownMenuTrigger
|
||||||
|
} from "$lib/components/ui/dropdown-menu"
|
||||||
|
import { MoonIcon, SunIcon, SunMoonIcon } from "@lucide/svelte"
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<DropdownMenu>
|
||||||
|
<DropdownMenuTrigger class={buttonVariants({ variant: "ghost", size: "icon" })}>
|
||||||
|
{#if userPrefersMode.current === "light"}
|
||||||
|
<SunIcon class="size-[1.2rem]"/>
|
||||||
|
{:else if userPrefersMode.current === "dark"}
|
||||||
|
<MoonIcon class="size-[1.2rem]"/>
|
||||||
|
{:else}
|
||||||
|
<SunMoonIcon class="size-[1.2rem]"/>
|
||||||
|
{/if}
|
||||||
|
<span class="sr-only">Toggle theme</span>
|
||||||
|
</DropdownMenuTrigger>
|
||||||
|
<DropdownMenuContent align="end">
|
||||||
|
<DropdownMenuItem onclick={() => setMode("light")}>
|
||||||
|
<SunIcon/>
|
||||||
|
Light
|
||||||
|
</DropdownMenuItem>
|
||||||
|
<DropdownMenuItem onclick={() => setMode("dark")}>
|
||||||
|
<MoonIcon/>
|
||||||
|
Dark
|
||||||
|
</DropdownMenuItem>
|
||||||
|
<DropdownMenuItem onclick={() => resetMode()}>
|
||||||
|
<SunMoonIcon/>
|
||||||
|
System
|
||||||
|
</DropdownMenuItem>
|
||||||
|
</DropdownMenuContent>
|
||||||
|
</DropdownMenu>
|
80
packages/client/src/lib/components/ui/button/button.svelte
Normal file
80
packages/client/src/lib/components/ui/button/button.svelte
Normal file
|
@ -0,0 +1,80 @@
|
||||||
|
<script lang="ts" module>
|
||||||
|
import { cn, type WithElementRef } from '$lib/utils.js';
|
||||||
|
import type { HTMLAnchorAttributes, HTMLButtonAttributes } from 'svelte/elements';
|
||||||
|
import { tv, type VariantProps } from 'tailwind-variants';
|
||||||
|
|
||||||
|
export const buttonVariants = tv({
|
||||||
|
base: 'focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive inline-flex shrink-0 items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium outline-none transition-all focus-visible:ring-[3px] disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50 [&_svg:not([class*=\'size-\'])]:size-4 [&_svg]:pointer-events-none [&_svg]:shrink-0',
|
||||||
|
variants: {
|
||||||
|
variant: {
|
||||||
|
default: 'bg-primary text-primary-foreground shadow-xs hover:bg-primary/90',
|
||||||
|
destructive:
|
||||||
|
'bg-destructive shadow-xs hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60 text-white',
|
||||||
|
outline:
|
||||||
|
'bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50 border',
|
||||||
|
secondary: 'bg-secondary text-secondary-foreground shadow-xs hover:bg-secondary/80',
|
||||||
|
ghost: 'hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50',
|
||||||
|
link: 'text-primary underline-offset-4 hover:underline',
|
||||||
|
},
|
||||||
|
size: {
|
||||||
|
default: 'h-9 px-4 py-2 has-[>svg]:px-3',
|
||||||
|
sm: 'h-8 gap-1.5 rounded-md px-3 has-[>svg]:px-2.5',
|
||||||
|
lg: 'h-10 rounded-md px-6 has-[>svg]:px-4',
|
||||||
|
icon: 'size-9',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
defaultVariants: {
|
||||||
|
variant: 'default',
|
||||||
|
size: 'default',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export type ButtonVariant = VariantProps<typeof buttonVariants>['variant'];
|
||||||
|
export type ButtonSize = VariantProps<typeof buttonVariants>['size'];
|
||||||
|
|
||||||
|
export type ButtonProps = WithElementRef<HTMLButtonAttributes> &
|
||||||
|
WithElementRef<HTMLAnchorAttributes> & {
|
||||||
|
variant?: ButtonVariant;
|
||||||
|
size?: ButtonSize;
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
let {
|
||||||
|
class: className,
|
||||||
|
variant = 'default',
|
||||||
|
size = 'default',
|
||||||
|
ref = $bindable(null),
|
||||||
|
href = undefined,
|
||||||
|
type = 'button',
|
||||||
|
disabled,
|
||||||
|
children,
|
||||||
|
...restProps
|
||||||
|
}: ButtonProps = $props();
|
||||||
|
</script>
|
||||||
|
|
||||||
|
{#if href}
|
||||||
|
<a
|
||||||
|
bind:this={ref}
|
||||||
|
data-slot="button"
|
||||||
|
class={cn(buttonVariants({ variant, size }), className)}
|
||||||
|
href={disabled ? undefined : href}
|
||||||
|
aria-disabled={disabled}
|
||||||
|
role={disabled ? "link" : undefined}
|
||||||
|
tabindex={disabled ? -1 : undefined}
|
||||||
|
{...restProps}
|
||||||
|
>
|
||||||
|
{@render children?.()}
|
||||||
|
</a>
|
||||||
|
{:else}
|
||||||
|
<button
|
||||||
|
bind:this={ref}
|
||||||
|
data-slot="button"
|
||||||
|
class={cn(buttonVariants({ variant, size }), className)}
|
||||||
|
{type}
|
||||||
|
{disabled}
|
||||||
|
{...restProps}
|
||||||
|
>
|
||||||
|
{@render children?.()}
|
||||||
|
</button>
|
||||||
|
{/if}
|
12
packages/client/src/lib/components/ui/button/index.ts
Normal file
12
packages/client/src/lib/components/ui/button/index.ts
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
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,
|
||||||
|
};
|
|
@ -0,0 +1,20 @@
|
||||||
|
<script lang="ts">
|
||||||
|
import { cn, type WithElementRef } from '$lib/utils.js';
|
||||||
|
import type { HTMLAttributes } from 'svelte/elements';
|
||||||
|
|
||||||
|
let {
|
||||||
|
ref = $bindable(null),
|
||||||
|
class: className,
|
||||||
|
children,
|
||||||
|
...restProps
|
||||||
|
}: WithElementRef<HTMLAttributes<HTMLDivElement>> = $props();
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div
|
||||||
|
bind:this={ref}
|
||||||
|
data-slot="card-action"
|
||||||
|
class={cn("col-start-2 row-span-2 row-start-1 self-start justify-self-end", className)}
|
||||||
|
{...restProps}
|
||||||
|
>
|
||||||
|
{@render children?.()}
|
||||||
|
</div>
|
|
@ -0,0 +1,15 @@
|
||||||
|
<script lang="ts">
|
||||||
|
import type { HTMLAttributes } from 'svelte/elements';
|
||||||
|
import { cn, type WithElementRef } from '$lib/utils.js';
|
||||||
|
|
||||||
|
let {
|
||||||
|
ref = $bindable(null),
|
||||||
|
class: className,
|
||||||
|
children,
|
||||||
|
...restProps
|
||||||
|
}: WithElementRef<HTMLAttributes<HTMLDivElement>> = $props();
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div bind:this={ref} data-slot="card-content" class={cn("px-6", className)} {...restProps}>
|
||||||
|
{@render children?.()}
|
||||||
|
</div>
|
|
@ -0,0 +1,20 @@
|
||||||
|
<script lang="ts">
|
||||||
|
import type { HTMLAttributes } from 'svelte/elements';
|
||||||
|
import { cn, type WithElementRef } from '$lib/utils.js';
|
||||||
|
|
||||||
|
let {
|
||||||
|
ref = $bindable(null),
|
||||||
|
class: className,
|
||||||
|
children,
|
||||||
|
...restProps
|
||||||
|
}: WithElementRef<HTMLAttributes<HTMLParagraphElement>> = $props();
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<p
|
||||||
|
bind:this={ref}
|
||||||
|
data-slot="card-description"
|
||||||
|
class={cn("text-muted-foreground text-sm", className)}
|
||||||
|
{...restProps}
|
||||||
|
>
|
||||||
|
{@render children?.()}
|
||||||
|
</p>
|
|
@ -0,0 +1,20 @@
|
||||||
|
<script lang="ts">
|
||||||
|
import { cn, type WithElementRef } from '$lib/utils.js';
|
||||||
|
import type { HTMLAttributes } from 'svelte/elements';
|
||||||
|
|
||||||
|
let {
|
||||||
|
ref = $bindable(null),
|
||||||
|
class: className,
|
||||||
|
children,
|
||||||
|
...restProps
|
||||||
|
}: WithElementRef<HTMLAttributes<HTMLDivElement>> = $props();
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div
|
||||||
|
bind:this={ref}
|
||||||
|
data-slot="card-footer"
|
||||||
|
class={cn("[.border-t]:pt-6 flex items-center px-6", className)}
|
||||||
|
{...restProps}
|
||||||
|
>
|
||||||
|
{@render children?.()}
|
||||||
|
</div>
|
|
@ -0,0 +1,23 @@
|
||||||
|
<script lang="ts">
|
||||||
|
import { cn, type WithElementRef } from '$lib/utils.js';
|
||||||
|
import type { HTMLAttributes } from 'svelte/elements';
|
||||||
|
|
||||||
|
let {
|
||||||
|
ref = $bindable(null),
|
||||||
|
class: className,
|
||||||
|
children,
|
||||||
|
...restProps
|
||||||
|
}: WithElementRef<HTMLAttributes<HTMLDivElement>> = $props();
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div
|
||||||
|
bind:this={ref}
|
||||||
|
data-slot="card-header"
|
||||||
|
class={cn(
|
||||||
|
"@container/card-header has-data-[slot=card-action]:grid-cols-[1fr_auto] [.border-b]:pb-6 grid auto-rows-min grid-rows-[auto_auto] items-start gap-1.5 px-6",
|
||||||
|
className
|
||||||
|
)}
|
||||||
|
{...restProps}
|
||||||
|
>
|
||||||
|
{@render children?.()}
|
||||||
|
</div>
|
20
packages/client/src/lib/components/ui/card/card-title.svelte
Normal file
20
packages/client/src/lib/components/ui/card/card-title.svelte
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
<script lang="ts">
|
||||||
|
import type { HTMLAttributes } from 'svelte/elements';
|
||||||
|
import { cn, type WithElementRef } from '$lib/utils.js';
|
||||||
|
|
||||||
|
let {
|
||||||
|
ref = $bindable(null),
|
||||||
|
class: className,
|
||||||
|
children,
|
||||||
|
...restProps
|
||||||
|
}: WithElementRef<HTMLAttributes<HTMLDivElement>> = $props();
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div
|
||||||
|
bind:this={ref}
|
||||||
|
data-slot="card-title"
|
||||||
|
class={cn("font-semibold leading-none", className)}
|
||||||
|
{...restProps}
|
||||||
|
>
|
||||||
|
{@render children?.()}
|
||||||
|
</div>
|
23
packages/client/src/lib/components/ui/card/card.svelte
Normal file
23
packages/client/src/lib/components/ui/card/card.svelte
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
<script lang="ts">
|
||||||
|
import type { HTMLAttributes } from 'svelte/elements';
|
||||||
|
import { cn, type WithElementRef } from '$lib/utils.js';
|
||||||
|
|
||||||
|
let {
|
||||||
|
ref = $bindable(null),
|
||||||
|
class: className,
|
||||||
|
children,
|
||||||
|
...restProps
|
||||||
|
}: WithElementRef<HTMLAttributes<HTMLDivElement>> = $props();
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div
|
||||||
|
bind:this={ref}
|
||||||
|
data-slot="card"
|
||||||
|
class={cn(
|
||||||
|
"bg-card text-card-foreground flex flex-col gap-6 rounded-xl border py-6 shadow-sm",
|
||||||
|
className
|
||||||
|
)}
|
||||||
|
{...restProps}
|
||||||
|
>
|
||||||
|
{@render children?.()}
|
||||||
|
</div>
|
25
packages/client/src/lib/components/ui/card/index.ts
Normal file
25
packages/client/src/lib/components/ui/card/index.ts
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
import Root from './card.svelte';
|
||||||
|
import Content from './card-content.svelte';
|
||||||
|
import Description from './card-description.svelte';
|
||||||
|
import Footer from './card-footer.svelte';
|
||||||
|
import Header from './card-header.svelte';
|
||||||
|
import Title from './card-title.svelte';
|
||||||
|
import Action from './card-action.svelte';
|
||||||
|
|
||||||
|
export {
|
||||||
|
Root,
|
||||||
|
Content,
|
||||||
|
Description,
|
||||||
|
Footer,
|
||||||
|
Header,
|
||||||
|
Title,
|
||||||
|
Action,
|
||||||
|
//
|
||||||
|
Root as Card,
|
||||||
|
Content as CardContent,
|
||||||
|
Description as CardDescription,
|
||||||
|
Footer as CardFooter,
|
||||||
|
Header as CardHeader,
|
||||||
|
Title as CardTitle,
|
||||||
|
Action as CardAction,
|
||||||
|
};
|
|
@ -0,0 +1,41 @@
|
||||||
|
<script lang="ts">
|
||||||
|
import { DropdownMenu as DropdownMenuPrimitive } from "bits-ui";
|
||||||
|
import CheckIcon from "@lucide/svelte/icons/check";
|
||||||
|
import MinusIcon from "@lucide/svelte/icons/minus";
|
||||||
|
import { cn, type WithoutChildrenOrChild } from "$lib/utils.js";
|
||||||
|
import type { Snippet } from "svelte";
|
||||||
|
|
||||||
|
let {
|
||||||
|
ref = $bindable(null),
|
||||||
|
checked = $bindable(false),
|
||||||
|
indeterminate = $bindable(false),
|
||||||
|
class: className,
|
||||||
|
children: childrenProp,
|
||||||
|
...restProps
|
||||||
|
}: WithoutChildrenOrChild<DropdownMenuPrimitive.CheckboxItemProps> & {
|
||||||
|
children?: Snippet;
|
||||||
|
} = $props();
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<DropdownMenuPrimitive.CheckboxItem
|
||||||
|
bind:ref
|
||||||
|
bind:checked
|
||||||
|
bind:indeterminate
|
||||||
|
data-slot="dropdown-menu-checkbox-item"
|
||||||
|
class={cn(
|
||||||
|
"focus:bg-accent focus:text-accent-foreground outline-hidden relative flex cursor-default select-none items-center gap-2 rounded-sm py-1.5 pl-8 pr-2 text-sm data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg:not([class*='size-'])]:size-4 [&_svg]:pointer-events-none [&_svg]:shrink-0",
|
||||||
|
className
|
||||||
|
)}
|
||||||
|
{...restProps}
|
||||||
|
>
|
||||||
|
{#snippet children({ checked, indeterminate })}
|
||||||
|
<span class="pointer-events-none absolute left-2 flex size-3.5 items-center justify-center">
|
||||||
|
{#if indeterminate}
|
||||||
|
<MinusIcon class="size-4" />
|
||||||
|
{:else}
|
||||||
|
<CheckIcon class={cn("size-4", !checked && "text-transparent")} />
|
||||||
|
{/if}
|
||||||
|
</span>
|
||||||
|
{@render childrenProp?.()}
|
||||||
|
{/snippet}
|
||||||
|
</DropdownMenuPrimitive.CheckboxItem>
|
|
@ -0,0 +1,27 @@
|
||||||
|
<script lang="ts">
|
||||||
|
import { cn } from "$lib/utils.js";
|
||||||
|
import { DropdownMenu as DropdownMenuPrimitive } from "bits-ui";
|
||||||
|
|
||||||
|
let {
|
||||||
|
ref = $bindable(null),
|
||||||
|
sideOffset = 4,
|
||||||
|
portalProps,
|
||||||
|
class: className,
|
||||||
|
...restProps
|
||||||
|
}: DropdownMenuPrimitive.ContentProps & {
|
||||||
|
portalProps?: DropdownMenuPrimitive.PortalProps;
|
||||||
|
} = $props();
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<DropdownMenuPrimitive.Portal {...portalProps}>
|
||||||
|
<DropdownMenuPrimitive.Content
|
||||||
|
bind:ref
|
||||||
|
data-slot="dropdown-menu-content"
|
||||||
|
{sideOffset}
|
||||||
|
class={cn(
|
||||||
|
"bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 max-h-(--bits-dropdown-menu-content-available-height) origin-(--bits-dropdown-menu-content-transform-origin) z-50 min-w-[8rem] overflow-y-auto overflow-x-hidden rounded-md border p-1 shadow-md outline-none",
|
||||||
|
className
|
||||||
|
)}
|
||||||
|
{...restProps}
|
||||||
|
/>
|
||||||
|
</DropdownMenuPrimitive.Portal>
|
|
@ -0,0 +1,22 @@
|
||||||
|
<script lang="ts">
|
||||||
|
import { DropdownMenu as DropdownMenuPrimitive } from "bits-ui";
|
||||||
|
import { cn } from "$lib/utils.js";
|
||||||
|
import type { ComponentProps } from "svelte";
|
||||||
|
|
||||||
|
let {
|
||||||
|
ref = $bindable(null),
|
||||||
|
class: className,
|
||||||
|
inset,
|
||||||
|
...restProps
|
||||||
|
}: ComponentProps<typeof DropdownMenuPrimitive.GroupHeading> & {
|
||||||
|
inset?: boolean;
|
||||||
|
} = $props();
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<DropdownMenuPrimitive.GroupHeading
|
||||||
|
bind:ref
|
||||||
|
data-slot="dropdown-menu-group-heading"
|
||||||
|
data-inset={inset}
|
||||||
|
class={cn("px-2 py-1.5 text-sm font-semibold data-[inset]:pl-8", className)}
|
||||||
|
{...restProps}
|
||||||
|
/>
|
|
@ -0,0 +1,7 @@
|
||||||
|
<script lang="ts">
|
||||||
|
import { DropdownMenu as DropdownMenuPrimitive } from "bits-ui";
|
||||||
|
|
||||||
|
let { ref = $bindable(null), ...restProps }: DropdownMenuPrimitive.GroupProps = $props();
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<DropdownMenuPrimitive.Group bind:ref data-slot="dropdown-menu-group" {...restProps} />
|
|
@ -0,0 +1,27 @@
|
||||||
|
<script lang="ts">
|
||||||
|
import { cn } from "$lib/utils.js";
|
||||||
|
import { DropdownMenu as DropdownMenuPrimitive } from "bits-ui";
|
||||||
|
|
||||||
|
let {
|
||||||
|
ref = $bindable(null),
|
||||||
|
class: className,
|
||||||
|
inset,
|
||||||
|
variant = "default",
|
||||||
|
...restProps
|
||||||
|
}: DropdownMenuPrimitive.ItemProps & {
|
||||||
|
inset?: boolean;
|
||||||
|
variant?: "default" | "destructive";
|
||||||
|
} = $props();
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<DropdownMenuPrimitive.Item
|
||||||
|
bind:ref
|
||||||
|
data-slot="dropdown-menu-item"
|
||||||
|
data-inset={inset}
|
||||||
|
data-variant={variant}
|
||||||
|
class={cn(
|
||||||
|
"data-highlighted:bg-accent data-highlighted:text-accent-foreground data-[variant=destructive]:text-destructive data-[variant=destructive]:data-highlighted:bg-destructive/10 dark:data-[variant=destructive]:data-highlighted:bg-destructive/20 data-[variant=destructive]:data-highlighted:text-destructive data-[variant=destructive]:*:[svg]:!text-destructive [&_svg:not([class*='text-'])]:text-muted-foreground outline-hidden relative flex cursor-default select-none items-center gap-2 rounded-sm px-2 py-1.5 text-sm data-[disabled]:pointer-events-none data-[inset]:pl-8 data-[disabled]:opacity-50 [&_svg:not([class*='size-'])]:size-4 [&_svg]:pointer-events-none [&_svg]:shrink-0",
|
||||||
|
className
|
||||||
|
)}
|
||||||
|
{...restProps}
|
||||||
|
/>
|
|
@ -0,0 +1,24 @@
|
||||||
|
<script lang="ts">
|
||||||
|
import { cn, type WithElementRef } from "$lib/utils.js";
|
||||||
|
import type { HTMLAttributes } from "svelte/elements";
|
||||||
|
|
||||||
|
let {
|
||||||
|
ref = $bindable(null),
|
||||||
|
class: className,
|
||||||
|
inset,
|
||||||
|
children,
|
||||||
|
...restProps
|
||||||
|
}: WithElementRef<HTMLAttributes<HTMLDivElement>> & {
|
||||||
|
inset?: boolean;
|
||||||
|
} = $props();
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div
|
||||||
|
bind:this={ref}
|
||||||
|
data-slot="dropdown-menu-label"
|
||||||
|
data-inset={inset}
|
||||||
|
class={cn("px-2 py-1.5 text-sm font-semibold data-[inset]:pl-8", className)}
|
||||||
|
{...restProps}
|
||||||
|
>
|
||||||
|
{@render children?.()}
|
||||||
|
</div>
|
|
@ -0,0 +1,16 @@
|
||||||
|
<script lang="ts">
|
||||||
|
import { DropdownMenu as DropdownMenuPrimitive } from "bits-ui";
|
||||||
|
|
||||||
|
let {
|
||||||
|
ref = $bindable(null),
|
||||||
|
value = $bindable(),
|
||||||
|
...restProps
|
||||||
|
}: DropdownMenuPrimitive.RadioGroupProps = $props();
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<DropdownMenuPrimitive.RadioGroup
|
||||||
|
bind:ref
|
||||||
|
bind:value
|
||||||
|
data-slot="dropdown-menu-radio-group"
|
||||||
|
{...restProps}
|
||||||
|
/>
|
|
@ -0,0 +1,31 @@
|
||||||
|
<script lang="ts">
|
||||||
|
import { DropdownMenu as DropdownMenuPrimitive } from "bits-ui";
|
||||||
|
import CircleIcon from "@lucide/svelte/icons/circle";
|
||||||
|
import { cn, type WithoutChild } from "$lib/utils.js";
|
||||||
|
|
||||||
|
let {
|
||||||
|
ref = $bindable(null),
|
||||||
|
class: className,
|
||||||
|
children: childrenProp,
|
||||||
|
...restProps
|
||||||
|
}: WithoutChild<DropdownMenuPrimitive.RadioItemProps> = $props();
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<DropdownMenuPrimitive.RadioItem
|
||||||
|
bind:ref
|
||||||
|
data-slot="dropdown-menu-radio-item"
|
||||||
|
class={cn(
|
||||||
|
"focus:bg-accent focus:text-accent-foreground outline-hidden relative flex cursor-default select-none items-center gap-2 rounded-sm py-1.5 pl-8 pr-2 text-sm data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg:not([class*='size-'])]:size-4 [&_svg]:pointer-events-none [&_svg]:shrink-0",
|
||||||
|
className
|
||||||
|
)}
|
||||||
|
{...restProps}
|
||||||
|
>
|
||||||
|
{#snippet children({ checked })}
|
||||||
|
<span class="pointer-events-none absolute left-2 flex size-3.5 items-center justify-center">
|
||||||
|
{#if checked}
|
||||||
|
<CircleIcon class="size-2 fill-current" />
|
||||||
|
{/if}
|
||||||
|
</span>
|
||||||
|
{@render childrenProp?.({ checked })}
|
||||||
|
{/snippet}
|
||||||
|
</DropdownMenuPrimitive.RadioItem>
|
|
@ -0,0 +1,17 @@
|
||||||
|
<script lang="ts">
|
||||||
|
import { DropdownMenu as DropdownMenuPrimitive } from "bits-ui";
|
||||||
|
import { cn } from "$lib/utils.js";
|
||||||
|
|
||||||
|
let {
|
||||||
|
ref = $bindable(null),
|
||||||
|
class: className,
|
||||||
|
...restProps
|
||||||
|
}: DropdownMenuPrimitive.SeparatorProps = $props();
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<DropdownMenuPrimitive.Separator
|
||||||
|
bind:ref
|
||||||
|
data-slot="dropdown-menu-separator"
|
||||||
|
class={cn("bg-border -mx-1 my-1 h-px", className)}
|
||||||
|
{...restProps}
|
||||||
|
/>
|
|
@ -0,0 +1,20 @@
|
||||||
|
<script lang="ts">
|
||||||
|
import type { HTMLAttributes } from "svelte/elements";
|
||||||
|
import { cn, type WithElementRef } from "$lib/utils.js";
|
||||||
|
|
||||||
|
let {
|
||||||
|
ref = $bindable(null),
|
||||||
|
class: className,
|
||||||
|
children,
|
||||||
|
...restProps
|
||||||
|
}: WithElementRef<HTMLAttributes<HTMLSpanElement>> = $props();
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<span
|
||||||
|
bind:this={ref}
|
||||||
|
data-slot="dropdown-menu-shortcut"
|
||||||
|
class={cn("text-muted-foreground ml-auto text-xs tracking-widest", className)}
|
||||||
|
{...restProps}
|
||||||
|
>
|
||||||
|
{@render children?.()}
|
||||||
|
</span>
|
|
@ -0,0 +1,20 @@
|
||||||
|
<script lang="ts">
|
||||||
|
import { DropdownMenu as DropdownMenuPrimitive } from "bits-ui";
|
||||||
|
import { cn } from "$lib/utils.js";
|
||||||
|
|
||||||
|
let {
|
||||||
|
ref = $bindable(null),
|
||||||
|
class: className,
|
||||||
|
...restProps
|
||||||
|
}: DropdownMenuPrimitive.SubContentProps = $props();
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<DropdownMenuPrimitive.SubContent
|
||||||
|
bind:ref
|
||||||
|
data-slot="dropdown-menu-sub-content"
|
||||||
|
class={cn(
|
||||||
|
"bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 origin-(--bits-dropdown-menu-content-transform-origin) z-50 min-w-[8rem] overflow-hidden rounded-md border p-1 shadow-lg",
|
||||||
|
className
|
||||||
|
)}
|
||||||
|
{...restProps}
|
||||||
|
/>
|
|
@ -0,0 +1,29 @@
|
||||||
|
<script lang="ts">
|
||||||
|
import { DropdownMenu as DropdownMenuPrimitive } from "bits-ui";
|
||||||
|
import ChevronRightIcon from "@lucide/svelte/icons/chevron-right";
|
||||||
|
import { cn } from "$lib/utils.js";
|
||||||
|
|
||||||
|
let {
|
||||||
|
ref = $bindable(null),
|
||||||
|
class: className,
|
||||||
|
inset,
|
||||||
|
children,
|
||||||
|
...restProps
|
||||||
|
}: DropdownMenuPrimitive.SubTriggerProps & {
|
||||||
|
inset?: boolean;
|
||||||
|
} = $props();
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<DropdownMenuPrimitive.SubTrigger
|
||||||
|
bind:ref
|
||||||
|
data-slot="dropdown-menu-sub-trigger"
|
||||||
|
data-inset={inset}
|
||||||
|
class={cn(
|
||||||
|
"data-highlighted:bg-accent data-highlighted:text-accent-foreground data-[state=open]:bg-accent data-[state=open]:text-accent-foreground outline-hidden [&_svg:not([class*='text-'])]:text-muted-foreground flex cursor-default select-none items-center gap-2 rounded-sm px-2 py-1.5 text-sm data-[disabled]:pointer-events-none data-[inset]:pl-8 data-[disabled]:opacity-50 [&_svg:not([class*='size-'])]:size-4 [&_svg]:pointer-events-none [&_svg]:shrink-0",
|
||||||
|
className
|
||||||
|
)}
|
||||||
|
{...restProps}
|
||||||
|
>
|
||||||
|
{@render children?.()}
|
||||||
|
<ChevronRightIcon class="ml-auto size-4" />
|
||||||
|
</DropdownMenuPrimitive.SubTrigger>
|
|
@ -0,0 +1,7 @@
|
||||||
|
<script lang="ts">
|
||||||
|
import { DropdownMenu as DropdownMenuPrimitive } from "bits-ui";
|
||||||
|
|
||||||
|
let { ref = $bindable(null), ...restProps }: DropdownMenuPrimitive.TriggerProps = $props();
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<DropdownMenuPrimitive.Trigger bind:ref data-slot="dropdown-menu-trigger" {...restProps} />
|
49
packages/client/src/lib/components/ui/dropdown-menu/index.ts
Normal file
49
packages/client/src/lib/components/ui/dropdown-menu/index.ts
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
import { DropdownMenu as DropdownMenuPrimitive } from "bits-ui";
|
||||||
|
import CheckboxItem from "./dropdown-menu-checkbox-item.svelte";
|
||||||
|
import Content from "./dropdown-menu-content.svelte";
|
||||||
|
import Group from "./dropdown-menu-group.svelte";
|
||||||
|
import Item from "./dropdown-menu-item.svelte";
|
||||||
|
import Label from "./dropdown-menu-label.svelte";
|
||||||
|
import RadioGroup from "./dropdown-menu-radio-group.svelte";
|
||||||
|
import RadioItem from "./dropdown-menu-radio-item.svelte";
|
||||||
|
import Separator from "./dropdown-menu-separator.svelte";
|
||||||
|
import Shortcut from "./dropdown-menu-shortcut.svelte";
|
||||||
|
import Trigger from "./dropdown-menu-trigger.svelte";
|
||||||
|
import SubContent from "./dropdown-menu-sub-content.svelte";
|
||||||
|
import SubTrigger from "./dropdown-menu-sub-trigger.svelte";
|
||||||
|
import GroupHeading from "./dropdown-menu-group-heading.svelte";
|
||||||
|
const Sub = DropdownMenuPrimitive.Sub;
|
||||||
|
const Root = DropdownMenuPrimitive.Root;
|
||||||
|
|
||||||
|
export {
|
||||||
|
CheckboxItem,
|
||||||
|
Content,
|
||||||
|
Root as DropdownMenu,
|
||||||
|
CheckboxItem as DropdownMenuCheckboxItem,
|
||||||
|
Content as DropdownMenuContent,
|
||||||
|
Group as DropdownMenuGroup,
|
||||||
|
Item as DropdownMenuItem,
|
||||||
|
Label as DropdownMenuLabel,
|
||||||
|
RadioGroup as DropdownMenuRadioGroup,
|
||||||
|
RadioItem as DropdownMenuRadioItem,
|
||||||
|
Separator as DropdownMenuSeparator,
|
||||||
|
Shortcut as DropdownMenuShortcut,
|
||||||
|
Sub as DropdownMenuSub,
|
||||||
|
SubContent as DropdownMenuSubContent,
|
||||||
|
SubTrigger as DropdownMenuSubTrigger,
|
||||||
|
Trigger as DropdownMenuTrigger,
|
||||||
|
GroupHeading as DropdownMenuGroupHeading,
|
||||||
|
Group,
|
||||||
|
GroupHeading,
|
||||||
|
Item,
|
||||||
|
Label,
|
||||||
|
RadioGroup,
|
||||||
|
RadioItem,
|
||||||
|
Root,
|
||||||
|
Separator,
|
||||||
|
Shortcut,
|
||||||
|
Sub,
|
||||||
|
SubContent,
|
||||||
|
SubTrigger,
|
||||||
|
Trigger,
|
||||||
|
};
|
7
packages/client/src/lib/components/ui/input/index.ts
Normal file
7
packages/client/src/lib/components/ui/input/index.ts
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
import Root from './input.svelte';
|
||||||
|
|
||||||
|
export {
|
||||||
|
Root,
|
||||||
|
//
|
||||||
|
Root as Input,
|
||||||
|
};
|
51
packages/client/src/lib/components/ui/input/input.svelte
Normal file
51
packages/client/src/lib/components/ui/input/input.svelte
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
<script lang="ts">
|
||||||
|
import type { HTMLInputAttributes, HTMLInputTypeAttribute } from 'svelte/elements';
|
||||||
|
import { cn, type WithElementRef } from '$lib/utils.js';
|
||||||
|
|
||||||
|
type InputType = Exclude<HTMLInputTypeAttribute, 'file'>;
|
||||||
|
|
||||||
|
type Props = WithElementRef<
|
||||||
|
Omit<HTMLInputAttributes, 'type'> &
|
||||||
|
({ type: 'file'; files?: FileList } | { type?: InputType; files?: undefined })
|
||||||
|
>;
|
||||||
|
|
||||||
|
let {
|
||||||
|
ref = $bindable(null),
|
||||||
|
value = $bindable(),
|
||||||
|
type,
|
||||||
|
files = $bindable(),
|
||||||
|
class: className,
|
||||||
|
...restProps
|
||||||
|
}: Props = $props();
|
||||||
|
</script>
|
||||||
|
|
||||||
|
{#if type === "file"}
|
||||||
|
<input
|
||||||
|
bind:this={ref}
|
||||||
|
data-slot="input"
|
||||||
|
class={cn(
|
||||||
|
"selection:bg-primary dark:bg-input/30 selection:text-primary-foreground border-input ring-offset-background placeholder:text-muted-foreground shadow-xs flex h-9 w-full min-w-0 rounded-md border bg-transparent px-3 pt-1.5 text-sm font-medium outline-none transition-[color,box-shadow] disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
|
||||||
|
"focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]",
|
||||||
|
"aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",
|
||||||
|
className
|
||||||
|
)}
|
||||||
|
type="file"
|
||||||
|
bind:files
|
||||||
|
bind:value
|
||||||
|
{...restProps}
|
||||||
|
/>
|
||||||
|
{:else}
|
||||||
|
<input
|
||||||
|
bind:this={ref}
|
||||||
|
data-slot="input"
|
||||||
|
class={cn(
|
||||||
|
"border-input bg-background selection:bg-primary dark:bg-input/30 selection:text-primary-foreground ring-offset-background placeholder:text-muted-foreground shadow-xs flex h-9 w-full min-w-0 rounded-md border px-3 py-1 text-base outline-none transition-[color,box-shadow] disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
|
||||||
|
"focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]",
|
||||||
|
"aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",
|
||||||
|
className
|
||||||
|
)}
|
||||||
|
{type}
|
||||||
|
bind:value
|
||||||
|
{...restProps}
|
||||||
|
/>
|
||||||
|
{/if}
|
|
@ -0,0 +1,28 @@
|
||||||
|
import Root from './navigation-menu.svelte';
|
||||||
|
import Content from './navigation-menu-content.svelte';
|
||||||
|
import Indicator from './navigation-menu-indicator.svelte';
|
||||||
|
import Item from './navigation-menu-item.svelte';
|
||||||
|
import Link from './navigation-menu-link.svelte';
|
||||||
|
import List from './navigation-menu-list.svelte';
|
||||||
|
import Trigger from './navigation-menu-trigger.svelte';
|
||||||
|
import Viewport from './navigation-menu-viewport.svelte';
|
||||||
|
|
||||||
|
export {
|
||||||
|
Root,
|
||||||
|
Content,
|
||||||
|
Indicator,
|
||||||
|
Item,
|
||||||
|
Link,
|
||||||
|
List,
|
||||||
|
Trigger,
|
||||||
|
Viewport,
|
||||||
|
//
|
||||||
|
Root as NavigationMenuRoot,
|
||||||
|
Content as NavigationMenuContent,
|
||||||
|
Indicator as NavigationMenuIndicator,
|
||||||
|
Item as NavigationMenuItem,
|
||||||
|
Link as NavigationMenuLink,
|
||||||
|
List as NavigationMenuList,
|
||||||
|
Trigger as NavigationMenuTrigger,
|
||||||
|
Viewport as NavigationMenuViewport,
|
||||||
|
};
|
|
@ -0,0 +1,21 @@
|
||||||
|
<script lang="ts">
|
||||||
|
import { NavigationMenu as NavigationMenuPrimitive } from 'bits-ui';
|
||||||
|
import { cn } from '$lib/utils.js';
|
||||||
|
|
||||||
|
let {
|
||||||
|
ref = $bindable(null),
|
||||||
|
class: className,
|
||||||
|
...restProps
|
||||||
|
}: NavigationMenuPrimitive.ContentProps = $props();
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<NavigationMenuPrimitive.Content
|
||||||
|
bind:ref
|
||||||
|
data-slot="navigation-menu-content"
|
||||||
|
class={cn(
|
||||||
|
"data-[motion^=from-]:animate-in data-[motion^=to-]:animate-out data-[motion^=from-]:fade-in data-[motion^=to-]:fade-out data-[motion=from-end]:slide-in-from-right-52 data-[motion=from-start]:slide-in-from-left-52 data-[motion=to-end]:slide-out-to-right-52 data-[motion=to-start]:slide-out-to-left-52 left-0 top-0 w-full md:absolute md:w-auto",
|
||||||
|
"group-data-[viewport=false]/navigation-menu:bg-popover group-data-[viewport=false]/navigation-menu:text-popover-foreground group-data-[viewport=false]/navigation-menu:data-[state=open]:animate-in group-data-[viewport=false]/navigation-menu:data-[state=closed]:animate-out group-data-[viewport=false]/navigation-menu:data-[state=closed]:zoom-out-95 group-data-[viewport=false]/navigation-menu:data-[state=open]:zoom-in-95 group-data-[viewport=false]/navigation-menu:data-[state=open]:fade-in-0 group-data-[viewport=false]/navigation-menu:data-[state=closed]:fade-out-0 **:data-[slot=navigation-menu-link]:focus:ring-0 **:data-[slot=navigation-menu-link]:focus:outline-none group-data-[viewport=false]/navigation-menu:top-full group-data-[viewport=false]/navigation-menu:mt-1.5 group-data-[viewport=false]/navigation-menu:overflow-hidden group-data-[viewport=false]/navigation-menu:rounded-md group-data-[viewport=false]/navigation-menu:border group-data-[viewport=false]/navigation-menu:shadow group-data-[viewport=false]/navigation-menu:duration-200",
|
||||||
|
className
|
||||||
|
)}
|
||||||
|
{...restProps}
|
||||||
|
/>
|
|
@ -0,0 +1,22 @@
|
||||||
|
<script lang="ts">
|
||||||
|
import { NavigationMenu as NavigationMenuPrimitive } from 'bits-ui';
|
||||||
|
import { cn } from '$lib/utils.js';
|
||||||
|
|
||||||
|
let {
|
||||||
|
ref = $bindable(null),
|
||||||
|
class: className,
|
||||||
|
...restProps
|
||||||
|
}: NavigationMenuPrimitive.IndicatorProps = $props();
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<NavigationMenuPrimitive.Indicator
|
||||||
|
bind:ref
|
||||||
|
data-slot="navigation-menu-indicator"
|
||||||
|
class={cn(
|
||||||
|
"data-[state=visible]:animate-in data-[state=hidden]:animate-out data-[state=hidden]:fade-out data-[state=visible]:fade-in top-full z-[1] flex h-1.5 items-end justify-center overflow-hidden",
|
||||||
|
className
|
||||||
|
)}
|
||||||
|
{...restProps}
|
||||||
|
>
|
||||||
|
<div class="bg-border relative top-[60%] h-2 w-2 rotate-45 rounded-tl-sm shadow-md"></div>
|
||||||
|
</NavigationMenuPrimitive.Indicator>
|
|
@ -0,0 +1,17 @@
|
||||||
|
<script lang="ts">
|
||||||
|
import { NavigationMenu as NavigationMenuPrimitive } from 'bits-ui';
|
||||||
|
import { cn } from '$lib/utils.js';
|
||||||
|
|
||||||
|
let {
|
||||||
|
ref = $bindable(null),
|
||||||
|
class: className,
|
||||||
|
...restProps
|
||||||
|
}: NavigationMenuPrimitive.ItemProps = $props();
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<NavigationMenuPrimitive.Item
|
||||||
|
bind:ref
|
||||||
|
data-slot="navigation-menu-item"
|
||||||
|
class={cn("relative", className)}
|
||||||
|
{...restProps}
|
||||||
|
/>
|
|
@ -0,0 +1,20 @@
|
||||||
|
<script lang="ts">
|
||||||
|
import { NavigationMenu as NavigationMenuPrimitive } from 'bits-ui';
|
||||||
|
import { cn } from '$lib/utils.js';
|
||||||
|
|
||||||
|
let {
|
||||||
|
ref = $bindable(null),
|
||||||
|
class: className,
|
||||||
|
...restProps
|
||||||
|
}: NavigationMenuPrimitive.LinkProps = $props();
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<NavigationMenuPrimitive.Link
|
||||||
|
bind:ref
|
||||||
|
data-slot="navigation-menu-link"
|
||||||
|
class={cn(
|
||||||
|
"data-[active=true]:focus:bg-accent data-[active=true]:hover:bg-accent data-[active=true]:bg-accent/50 data-[active=true]:text-accent-foreground hover:bg-accent hover:text-accent-foreground focus:bg-accent focus:text-accent-foreground focus-visible:ring-ring/50 [&_svg:not([class*='text-'])]:text-muted-foreground flex flex-col gap-1 rounded-sm p-2 text-sm outline-none transition-all focus-visible:outline-1 focus-visible:ring-[3px] [&_svg:not([class*='size-'])]:size-4",
|
||||||
|
className
|
||||||
|
)}
|
||||||
|
{...restProps}
|
||||||
|
/>
|
|
@ -0,0 +1,17 @@
|
||||||
|
<script lang="ts">
|
||||||
|
import { NavigationMenu as NavigationMenuPrimitive } from 'bits-ui';
|
||||||
|
import { cn } from '$lib/utils.js';
|
||||||
|
|
||||||
|
let {
|
||||||
|
ref = $bindable(null),
|
||||||
|
class: className,
|
||||||
|
...restProps
|
||||||
|
}: NavigationMenuPrimitive.ListProps = $props();
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<NavigationMenuPrimitive.List
|
||||||
|
bind:ref
|
||||||
|
data-slot="navigation-menu-list"
|
||||||
|
class={cn("group flex flex-1 list-none items-center justify-center gap-1", className)}
|
||||||
|
{...restProps}
|
||||||
|
/>
|
|
@ -0,0 +1,34 @@
|
||||||
|
<script lang="ts" module>
|
||||||
|
import { cn } from '$lib/utils.js';
|
||||||
|
import { tv } from 'tailwind-variants';
|
||||||
|
|
||||||
|
export const navigationMenuTriggerStyle = tv({
|
||||||
|
base: 'bg-background hover:bg-accent hover:text-accent-foreground focus:bg-accent focus:text-accent-foreground data-[state=open]:hover:bg-accent data-[state=open]:text-accent-foreground data-[state=open]:focus:bg-accent data-[state=open]:bg-accent/50 focus-visible:ring-ring/50 group inline-flex h-9 w-max items-center justify-center rounded-md px-4 py-2 text-sm font-medium outline-none transition-[color,box-shadow] focus-visible:outline-1 focus-visible:ring-[3px] disabled:pointer-events-none disabled:opacity-50',
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
import { NavigationMenu as NavigationMenuPrimitive } from 'bits-ui';
|
||||||
|
import ChevronDownIcon from '@lucide/svelte/icons/chevron-down';
|
||||||
|
|
||||||
|
let {
|
||||||
|
ref = $bindable(null),
|
||||||
|
class: className,
|
||||||
|
children,
|
||||||
|
...restProps
|
||||||
|
}: NavigationMenuPrimitive.TriggerProps = $props();
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<NavigationMenuPrimitive.Trigger
|
||||||
|
bind:ref
|
||||||
|
data-slot="navigation-menu-trigger"
|
||||||
|
class={cn(navigationMenuTriggerStyle(), "group", className)}
|
||||||
|
{...restProps}
|
||||||
|
>
|
||||||
|
{@render children?.()}
|
||||||
|
|
||||||
|
<ChevronDownIcon
|
||||||
|
class="relative top-[1px] ml-1 size-3 transition duration-300 group-data-[state=open]:rotate-180"
|
||||||
|
aria-hidden="true"
|
||||||
|
/>
|
||||||
|
</NavigationMenuPrimitive.Trigger>
|
|
@ -0,0 +1,22 @@
|
||||||
|
<script lang="ts">
|
||||||
|
import { NavigationMenu as NavigationMenuPrimitive } from 'bits-ui';
|
||||||
|
import { cn } from '$lib/utils.js';
|
||||||
|
|
||||||
|
let {
|
||||||
|
ref = $bindable(null),
|
||||||
|
class: className,
|
||||||
|
...restProps
|
||||||
|
}: NavigationMenuPrimitive.ViewportProps = $props();
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div class={cn("absolute left-0 top-full isolate z-50 flex justify-center")}>
|
||||||
|
<NavigationMenuPrimitive.Viewport
|
||||||
|
bind:ref
|
||||||
|
data-slot="navigation-menu-viewport"
|
||||||
|
class={cn(
|
||||||
|
"origin-top-center bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-90 relative mt-1.5 h-[var(--bits-navigation-menu-viewport-height)] w-full overflow-hidden rounded-md border shadow md:w-[var(--bits-navigation-menu-viewport-width)]",
|
||||||
|
className
|
||||||
|
)}
|
||||||
|
{...restProps}
|
||||||
|
/>
|
||||||
|
</div>
|
|
@ -0,0 +1,32 @@
|
||||||
|
<script lang="ts">
|
||||||
|
import { NavigationMenu as NavigationMenuPrimitive } from 'bits-ui';
|
||||||
|
import { cn } from '$lib/utils.js';
|
||||||
|
import NavigationMenuViewport from './navigation-menu-viewport.svelte';
|
||||||
|
|
||||||
|
let {
|
||||||
|
ref = $bindable(null),
|
||||||
|
class: className,
|
||||||
|
viewport = true,
|
||||||
|
children,
|
||||||
|
...restProps
|
||||||
|
}: NavigationMenuPrimitive.RootProps & {
|
||||||
|
viewport?: boolean;
|
||||||
|
} = $props();
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<NavigationMenuPrimitive.Root
|
||||||
|
bind:ref
|
||||||
|
data-slot="navigation-menu"
|
||||||
|
data-viewport={viewport}
|
||||||
|
class={cn(
|
||||||
|
"group/navigation-menu relative flex max-w-max flex-1 items-center justify-center",
|
||||||
|
className
|
||||||
|
)}
|
||||||
|
{...restProps}
|
||||||
|
>
|
||||||
|
{@render children?.()}
|
||||||
|
|
||||||
|
{#if viewport}
|
||||||
|
<NavigationMenuViewport/>
|
||||||
|
{/if}
|
||||||
|
</NavigationMenuPrimitive.Root>
|
21
packages/client/src/lib/components/ui/tooltip/index.ts
Normal file
21
packages/client/src/lib/components/ui/tooltip/index.ts
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
import { Tooltip as TooltipPrimitive } from "bits-ui";
|
||||||
|
import Trigger from "./tooltip-trigger.svelte";
|
||||||
|
import Content from "./tooltip-content.svelte";
|
||||||
|
|
||||||
|
const Root = TooltipPrimitive.Root;
|
||||||
|
const Provider = TooltipPrimitive.Provider;
|
||||||
|
const Portal = TooltipPrimitive.Portal;
|
||||||
|
|
||||||
|
export {
|
||||||
|
Root,
|
||||||
|
Trigger,
|
||||||
|
Content,
|
||||||
|
Provider,
|
||||||
|
Portal,
|
||||||
|
//
|
||||||
|
Root as Tooltip,
|
||||||
|
Content as TooltipContent,
|
||||||
|
Trigger as TooltipTrigger,
|
||||||
|
Provider as TooltipProvider,
|
||||||
|
Portal as TooltipPortal,
|
||||||
|
};
|
|
@ -0,0 +1,47 @@
|
||||||
|
<script lang="ts">
|
||||||
|
import { Tooltip as TooltipPrimitive } from "bits-ui";
|
||||||
|
import { cn } from "$lib/utils.js";
|
||||||
|
|
||||||
|
let {
|
||||||
|
ref = $bindable(null),
|
||||||
|
class: className,
|
||||||
|
sideOffset = 0,
|
||||||
|
side = "top",
|
||||||
|
children,
|
||||||
|
arrowClasses,
|
||||||
|
...restProps
|
||||||
|
}: TooltipPrimitive.ContentProps & {
|
||||||
|
arrowClasses?: string;
|
||||||
|
} = $props();
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<TooltipPrimitive.Portal>
|
||||||
|
<TooltipPrimitive.Content
|
||||||
|
bind:ref
|
||||||
|
data-slot="tooltip-content"
|
||||||
|
{sideOffset}
|
||||||
|
{side}
|
||||||
|
class={cn(
|
||||||
|
"bg-primary text-primary-foreground animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 origin-(--bits-tooltip-content-transform-origin) z-50 w-fit text-balance rounded-md px-3 py-1.5 text-xs",
|
||||||
|
className
|
||||||
|
)}
|
||||||
|
{...restProps}
|
||||||
|
>
|
||||||
|
{@render children?.()}
|
||||||
|
<TooltipPrimitive.Arrow>
|
||||||
|
{#snippet child({ props })}
|
||||||
|
<div
|
||||||
|
class={cn(
|
||||||
|
"bg-primary z-50 size-2.5 rotate-45 rounded-[2px]",
|
||||||
|
"data-[side=top]:translate-x-1/2 data-[side=top]:translate-y-[calc(-50%_+_2px)]",
|
||||||
|
"data-[side=bottom]:-translate-x-1/2 data-[side=bottom]:-translate-y-[calc(-50%_+_1px)]",
|
||||||
|
"data-[side=right]:translate-x-[calc(50%_+_2px)] data-[side=right]:translate-y-1/2",
|
||||||
|
"data-[side=left]:-translate-y-[calc(50%_-_3px)]",
|
||||||
|
arrowClasses
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
></div>
|
||||||
|
{/snippet}
|
||||||
|
</TooltipPrimitive.Arrow>
|
||||||
|
</TooltipPrimitive.Content>
|
||||||
|
</TooltipPrimitive.Portal>
|
|
@ -0,0 +1,7 @@
|
||||||
|
<script lang="ts">
|
||||||
|
import { Tooltip as TooltipPrimitive } from "bits-ui";
|
||||||
|
|
||||||
|
let { ref = $bindable(null), ...restProps }: TooltipPrimitive.TriggerProps = $props();
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<TooltipPrimitive.Trigger bind:ref data-slot="tooltip-trigger" {...restProps} />
|
13
packages/client/src/lib/utils.ts
Normal file
13
packages/client/src/lib/utils.ts
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
import { type ClassValue, clsx } from 'clsx';
|
||||||
|
import { twMerge } from 'tailwind-merge';
|
||||||
|
|
||||||
|
export function cn(...inputs: ClassValue[]) {
|
||||||
|
return twMerge(clsx(inputs));
|
||||||
|
}
|
||||||
|
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
|
export type WithoutChild<T> = T extends { child?: any } ? Omit<T, 'child'> : T;
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
|
export type WithoutChildren<T> = T extends { children?: any } ? Omit<T, 'children'> : T;
|
||||||
|
export type WithoutChildrenOrChild<T> = WithoutChildren<WithoutChild<T>>;
|
||||||
|
export type WithElementRef<T, U extends HTMLElement = HTMLElement> = T & { ref?: U | null };
|
26
packages/client/src/routes/+layout.svelte
Normal file
26
packages/client/src/routes/+layout.svelte
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
<script lang="ts">
|
||||||
|
|
||||||
|
import '../app.css';
|
||||||
|
import ThemeSelector from '$lib/components/theme-selector.svelte';
|
||||||
|
import { ModeWatcher } from 'mode-watcher';
|
||||||
|
|
||||||
|
let { children } = $props();
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<ModeWatcher/>
|
||||||
|
|
||||||
|
<!-- navigation bar -->
|
||||||
|
<header class="sticky top-0 right-0 left-0 flex justify-center z-50 backdrop-blur py-4 px-4 lg:px-8">
|
||||||
|
<div class="flex items-center justify-between w-full max-w-7xl">
|
||||||
|
<a href="/" class="cursor-pointer">
|
||||||
|
<img class="w-24 hidden dark:block" src="logo_white.svg" alt="HNU Logo"/>
|
||||||
|
<img class="w-24 block dark:hidden" src="logo_black.svg" alt="HNU Logo"/>
|
||||||
|
</a>
|
||||||
|
<div class="flex space-x-2">
|
||||||
|
<ThemeSelector/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
{@render children()}
|
298
packages/client/src/routes/+page.svelte
Normal file
298
packages/client/src/routes/+page.svelte
Normal file
|
@ -0,0 +1,298 @@
|
||||||
|
<script lang="ts">
|
||||||
|
import {
|
||||||
|
CheckIcon,
|
||||||
|
ChevronRightIcon,
|
||||||
|
CopyIcon,
|
||||||
|
Loader2Icon,
|
||||||
|
MessageSquareIcon,
|
||||||
|
SendIcon,
|
||||||
|
UnplugIcon,
|
||||||
|
UserIcon,
|
||||||
|
} from '@lucide/svelte';
|
||||||
|
import { ConnectionState, type Message, MessageType, type ReceiveHl7v2Message } from '@hnu.de/hl7v2-shared';
|
||||||
|
import { Button } from '$lib/components/ui/button';
|
||||||
|
import { Card, CardContent, CardHeader } from '$lib/components/ui/card';
|
||||||
|
import { Input } from '$lib/components/ui/input';
|
||||||
|
import { Label } from '$lib/components/ui/dropdown-menu';
|
||||||
|
import { env } from '$env/dynamic/public';
|
||||||
|
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '$lib/components/ui/tooltip';
|
||||||
|
|
||||||
|
// connection state
|
||||||
|
let ws = $state<WebSocket | undefined>(undefined);
|
||||||
|
let userId = $state<string | undefined>(undefined);
|
||||||
|
let connectionState = $state<ConnectionState>(ConnectionState.disconnected);
|
||||||
|
|
||||||
|
// client state
|
||||||
|
let composedMessage = $state('');
|
||||||
|
let sentMessages = $state<ReceiveHl7v2Message[]>([]); // storing sent messages with client-timestamp for now
|
||||||
|
let receivedMessages = $state<ReceiveHl7v2Message[]>([]);
|
||||||
|
let isSending = $state(false);
|
||||||
|
let copySuccess = $state(false);
|
||||||
|
let deliveryError = $state('');
|
||||||
|
|
||||||
|
// segment presets
|
||||||
|
const segmentTemplates = {
|
||||||
|
MSH: {
|
||||||
|
name: 'Message Header',
|
||||||
|
template: () => `MSH|^~\\&|SENDER_APP|SENDER_FACILITY|RECIPIENT_USER_ID|RECEIVER_FACILITY|${new Date().toISOString().replace(/[-:.]/g, '').slice(0, 14)}||ADT^A01|${Date.now()}|P|2.3`,
|
||||||
|
},
|
||||||
|
PID: {
|
||||||
|
name: 'Patient Identification',
|
||||||
|
template: () => `PID|||PATIENT_MRN||Doe^John^J||19900101|M`,
|
||||||
|
},
|
||||||
|
PV1: {
|
||||||
|
name: 'Patient Visit',
|
||||||
|
template: () => `PV1||I|ER^101^A|||1234^Welby^Marcus`,
|
||||||
|
},
|
||||||
|
AL1: {
|
||||||
|
name: 'Patient Allergy Information',
|
||||||
|
template: () => 'AL1|1|DA|12345^Penicillin|SV|Hives',
|
||||||
|
},
|
||||||
|
ITM: {
|
||||||
|
name: 'Material Item',
|
||||||
|
template: () => 'ITM|1|ITEM-789|Gauze Pads|Sterile Gauze Pads 4x4',
|
||||||
|
},
|
||||||
|
IVC: {
|
||||||
|
name: 'Invoice',
|
||||||
|
template: () => 'IVC|INV-987|ACCT-654|500.00|20230201',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
const segmentTypes = Object.keys(segmentTemplates) as Array<keyof typeof segmentTemplates>;
|
||||||
|
|
||||||
|
function connectToServer() {
|
||||||
|
|
||||||
|
console.log('Connecting to server...');
|
||||||
|
connectionState = ConnectionState.connecting;
|
||||||
|
|
||||||
|
const socket = new WebSocket(`wss://${env.PUBLIC_SERVER}`);
|
||||||
|
|
||||||
|
socket.onopen = () => {
|
||||||
|
console.log('WebSocket connection established.');
|
||||||
|
ws = socket;
|
||||||
|
};
|
||||||
|
|
||||||
|
socket.onmessage = (event) => {
|
||||||
|
|
||||||
|
const message = JSON.parse(event.data) as Message;
|
||||||
|
console.log('Message received from server:', message);
|
||||||
|
|
||||||
|
switch (message.type) {
|
||||||
|
|
||||||
|
// initial message from server assigning ID
|
||||||
|
case MessageType.assign_id:
|
||||||
|
userId = message.payload.userId;
|
||||||
|
composedMessage = segmentTemplates.MSH.template();
|
||||||
|
connectionState = ConnectionState.connected;
|
||||||
|
break;
|
||||||
|
|
||||||
|
// message from another client
|
||||||
|
case MessageType.receive_hl7v2:
|
||||||
|
receivedMessages = [message, ...receivedMessages];
|
||||||
|
break;
|
||||||
|
|
||||||
|
// message from server due to delivery error
|
||||||
|
case MessageType.delivery_error:
|
||||||
|
deliveryError = message.payload.error;
|
||||||
|
setTimeout(() => deliveryError = '', 5000); // Clear error after 5 seconds
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
socket.onclose = () => {
|
||||||
|
console.log('WebSocket connection closed.');
|
||||||
|
connectionState = ConnectionState.disconnected;
|
||||||
|
ws = undefined;
|
||||||
|
};
|
||||||
|
|
||||||
|
socket.onerror = (error) => {
|
||||||
|
console.error('WebSocket error:', error);
|
||||||
|
connectionState = ConnectionState.disconnected;
|
||||||
|
ws = undefined;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// clean up on close
|
||||||
|
$effect(() => {
|
||||||
|
return () => {
|
||||||
|
if (ws && ws.readyState === WebSocket.OPEN) {
|
||||||
|
connectionState = ConnectionState.disconnected;
|
||||||
|
ws.close();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
function addSegment(type: keyof typeof segmentTemplates) {
|
||||||
|
const template = segmentTemplates[type].template();
|
||||||
|
composedMessage += `\r\n${template}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleSendMessage(message: string) {
|
||||||
|
|
||||||
|
if (!ws || ws.readyState !== WebSocket.OPEN || isSending || !userId) {
|
||||||
|
console.log('Socket not ready');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
isSending = true;
|
||||||
|
deliveryError = '';
|
||||||
|
|
||||||
|
const messageToSend = {
|
||||||
|
type: 'send_hl7v2',
|
||||||
|
payload: { message },
|
||||||
|
} as Message;
|
||||||
|
ws.send(JSON.stringify(messageToSend));
|
||||||
|
|
||||||
|
sentMessages = [{
|
||||||
|
type: MessageType.receive_hl7v2,
|
||||||
|
payload: { message, timestamp: new Date().toISOString() },
|
||||||
|
} as ReceiveHl7v2Message, ...sentMessages];
|
||||||
|
composedMessage = segmentTemplates.MSH.template();
|
||||||
|
isSending = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
function copyUserId() {
|
||||||
|
if (userId) {
|
||||||
|
navigator.clipboard.writeText(userId).then(() => {
|
||||||
|
copySuccess = true;
|
||||||
|
setTimeout(() => copySuccess = false, 2000);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
|
||||||
|
{#snippet message(msg: ReceiveHl7v2Message)}
|
||||||
|
<div class="bg-foreground/10 p-3 rounded-md space-y-1">
|
||||||
|
<p class="text-xs">{new Date(msg.payload.timestamp).toLocaleString()}</p>
|
||||||
|
<pre class="text-sm whitespace-pre-wrap break-all">{msg.payload.message}</pre>
|
||||||
|
</div>
|
||||||
|
{/snippet}
|
||||||
|
|
||||||
|
|
||||||
|
<div class="p-4 lg:p-8">
|
||||||
|
<div class="max-w-7xl mx-auto">
|
||||||
|
<main class="grid grid-cols-1 lg:grid-cols-3 gap-6">
|
||||||
|
|
||||||
|
<!-- Left Column: User Info & Logs -->
|
||||||
|
<div class="space-y-6">
|
||||||
|
<Card>
|
||||||
|
<CardHeader class="flex flex-row items-center">
|
||||||
|
<UserIcon class="mr-2"/>
|
||||||
|
Your Info
|
||||||
|
</CardHeader>
|
||||||
|
<CardContent>
|
||||||
|
{#if connectionState === ConnectionState.connected && userId}
|
||||||
|
<Label class="">Station ID</Label>
|
||||||
|
<div class="flex items-center space-x-2">
|
||||||
|
<Input disabled bind:value={userId}/>
|
||||||
|
<Button variant="outline" size="icon" onclick={copyUserId}>
|
||||||
|
{#if copySuccess}
|
||||||
|
<CheckIcon class={'text-green-400'}/>
|
||||||
|
{:else}
|
||||||
|
<CopyIcon/>
|
||||||
|
{/if}
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
{:else if connectionState === ConnectionState.disconnected}
|
||||||
|
<div class="flex items-center space-x-2">
|
||||||
|
<UnplugIcon/>
|
||||||
|
<span>Disconnected</span>
|
||||||
|
</div>
|
||||||
|
{:else if connectionState === ConnectionState.connecting}
|
||||||
|
<div class="flex items-center space-x-2">
|
||||||
|
<Loader2Icon class="animate-spin"/>
|
||||||
|
<span>Connecting...</span>
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
</CardContent>
|
||||||
|
</Card>
|
||||||
|
|
||||||
|
<Card>
|
||||||
|
<CardHeader class="flex items-center space-x-2">
|
||||||
|
<ChevronRightIcon class="text-green-400"/>
|
||||||
|
<span>Received Messages</span>
|
||||||
|
</CardHeader>
|
||||||
|
<CardContent class="space-y-2">
|
||||||
|
{#if receivedMessages.length === 0}
|
||||||
|
<p class="text-foreground/70 italic">Waiting for incoming messages...</p>
|
||||||
|
{/if}
|
||||||
|
{#each receivedMessages as msg (msg.payload.timestamp)}
|
||||||
|
{@render message(msg)}
|
||||||
|
{/each}
|
||||||
|
</CardContent>
|
||||||
|
</Card>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Right Column: Composer and Sent Log -->
|
||||||
|
<div class="lg:col-span-2 space-y-6">
|
||||||
|
<Card>
|
||||||
|
<CardHeader class="flex items-center space-x-2">
|
||||||
|
<MessageSquareIcon/>
|
||||||
|
<span>HL7v2 Message Editor</span>
|
||||||
|
</CardHeader>
|
||||||
|
<CardContent>
|
||||||
|
{#if connectionState === ConnectionState.connected && userId}
|
||||||
|
<div>
|
||||||
|
<div class="flex flex-wrap gap-2 mb-4">
|
||||||
|
{#each segmentTypes as type (type)}
|
||||||
|
{#if type !== 'MSH'}
|
||||||
|
<TooltipProvider>
|
||||||
|
<Tooltip>
|
||||||
|
<TooltipTrigger>
|
||||||
|
<Button onclick={() => addSegment(type)}>
|
||||||
|
+ {type}
|
||||||
|
</Button>
|
||||||
|
</TooltipTrigger
|
||||||
|
>
|
||||||
|
<TooltipContent>
|
||||||
|
{segmentTemplates[type].name}
|
||||||
|
</TooltipContent>
|
||||||
|
</Tooltip>
|
||||||
|
</TooltipProvider>
|
||||||
|
{/if}
|
||||||
|
{/each}
|
||||||
|
</div>
|
||||||
|
<textarea bind:value={composedMessage}
|
||||||
|
class="w-full h-64 bg-black font-mono text-sm text-green-400 p-4 rounded-md"></textarea>
|
||||||
|
<Button onclick={() => handleSendMessage(composedMessage)}
|
||||||
|
disabled={isSending || !composedMessage} class="w-full space-x-2">
|
||||||
|
<SendIcon/>
|
||||||
|
<span>Send Message</span>
|
||||||
|
</Button>
|
||||||
|
{#if deliveryError}
|
||||||
|
<p class="text-red-600 dark:text-red-400 text-center mt-2">{deliveryError}</p>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
{:else if connectionState === ConnectionState.disconnected}
|
||||||
|
<div class="flex flex-col items-center justify-center min-h-96 text-foreground/70 space-y-4">
|
||||||
|
<h3 class="text-xl font-bold">Connect as a client</h3>
|
||||||
|
<Button onclick={connectToServer}>Connect</Button>
|
||||||
|
</div>
|
||||||
|
{:else if connectionState === ConnectionState.connecting}
|
||||||
|
<div class="flex flex-col items-center justify-center min-h-96 text-foreground/70">
|
||||||
|
<Loader2Icon class="animate-spin mb-4" size={48}/>
|
||||||
|
<h3 class="text-xl font-bold">Connecting...</h3>
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
</CardContent>
|
||||||
|
</Card>
|
||||||
|
|
||||||
|
<Card>
|
||||||
|
<CardHeader class="flex items-center space-x-2">
|
||||||
|
<SendIcon class="text-blue-400"/>
|
||||||
|
<span>Sent Messages Log</span>
|
||||||
|
</CardHeader>
|
||||||
|
<CardContent class="space-y-2">
|
||||||
|
{#if sentMessages.length === 0}
|
||||||
|
<p class="text-foreground/70 italic">Your sent messages will appear here.</p>
|
||||||
|
{/if}
|
||||||
|
{#each sentMessages as msg (msg.payload.timestamp)}
|
||||||
|
{@render message(msg)}
|
||||||
|
{/each}
|
||||||
|
</CardContent>
|
||||||
|
</Card>
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
</div>
|
||||||
|
</div>
|
7
packages/client/static/favicon.svg
Normal file
7
packages/client/static/favicon.svg
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="107" height="128" viewBox="0 0 107 128">
|
||||||
|
<title>svelte-logo</title>
|
||||||
|
<path d="M94.157 22.819c-10.4-14.885-30.94-19.297-45.792-9.835L22.282 29.608A29.92 29.92 0 0 0 8.764 49.65a31.5 31.5 0 0 0 3.108 20.231 30 30 0 0 0-4.477 11.183 31.9 31.9 0 0 0 5.448 24.116c10.402 14.887 30.942 19.297 45.791 9.835l26.083-16.624A29.92 29.92 0 0 0 98.235 78.35a31.53 31.53 0 0 0-3.105-20.232 30 30 0 0 0 4.474-11.182 31.88 31.88 0 0 0-5.447-24.116"
|
||||||
|
style="fill:#ff3e00"/>
|
||||||
|
<path d="M45.817 106.582a20.72 20.72 0 0 1-22.237-8.243 19.17 19.17 0 0 1-3.277-14.503 18 18 0 0 1 .624-2.435l.49-1.498 1.337.981a33.6 33.6 0 0 0 10.203 5.098l.97.294-.09.968a5.85 5.85 0 0 0 1.052 3.878 6.24 6.24 0 0 0 6.695 2.485 5.8 5.8 0 0 0 1.603-.704L69.27 76.28a5.43 5.43 0 0 0 2.45-3.631 5.8 5.8 0 0 0-.987-4.371 6.24 6.24 0 0 0-6.698-2.487 5.7 5.7 0 0 0-1.6.704l-9.953 6.345a19 19 0 0 1-5.296 2.326 20.72 20.72 0 0 1-22.237-8.243 19.17 19.17 0 0 1-3.277-14.502 17.99 17.99 0 0 1 8.13-12.052l26.081-16.623a19 19 0 0 1 5.3-2.329 20.72 20.72 0 0 1 22.237 8.243 19.17 19.17 0 0 1 3.277 14.503 18 18 0 0 1-.624 2.435l-.49 1.498-1.337-.98a33.6 33.6 0 0 0-10.203-5.1l-.97-.294.09-.968a5.86 5.86 0 0 0-1.052-3.878 6.24 6.24 0 0 0-6.696-2.485 5.8 5.8 0 0 0-1.602.704L37.73 51.72a5.42 5.42 0 0 0-2.449 3.63 5.79 5.79 0 0 0 .986 4.372 6.24 6.24 0 0 0 6.698 2.486 5.8 5.8 0 0 0 1.602-.704l9.952-6.342a19 19 0 0 1 5.295-2.328 20.72 20.72 0 0 1 22.237 8.242 19.17 19.17 0 0 1 3.277 14.503 18 18 0 0 1-8.13 12.053l-26.081 16.622a19 19 0 0 1-5.3 2.328"
|
||||||
|
style="fill:#fff"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.6 KiB |
80
packages/client/static/logo_black.svg
Normal file
80
packages/client/static/logo_black.svg
Normal file
|
@ -0,0 +1,80 @@
|
||||||
|
<svg version="1.1" id="Layer_1" xmlns:x="ns_extend;" xmlns:i="ns_ai;" xmlns:graph="ns_graphs;" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 188.3 100" style="enable-background:new 0 0 188.3 100;" xml:space="preserve">
|
||||||
|
<metadata>
|
||||||
|
<sfw xmlns="ns_sfw;">
|
||||||
|
<slices>
|
||||||
|
</slices>
|
||||||
|
<sliceSourceBounds bottomLeftOrigin="true" height="100" width="188.3" x="-68.6" y="1.5">
|
||||||
|
</sliceSourceBounds>
|
||||||
|
</sfw>
|
||||||
|
</metadata>
|
||||||
|
<g>
|
||||||
|
<path d="M7,76.3H1.3v-4.1H0v9.7h1.3v-4.4H7v4.4h1.3v-9.7H7V76.3z M13.1,75c-1.9,0-3.5,1.4-3.5,3.5s1.4,3.5,3.5,3.5s3.5-1.4,3.5-3.5
|
||||||
|
S15.2,75,13.1,75z M13.1,81c-1.4,0-2.1-1.1-2.1-2.5c0-1.6,0.8-2.5,2.1-2.5c1.4,0,2.1,1.1,2.1,2.5C15.3,80.1,14.6,81,13.1,81z
|
||||||
|
M21.2,75.9c1.3,0,1.9,0.8,2.1,2.1h1.1c-0.2-1.6-1.3-3-3.2-3c-2.1,0-3.5,1.4-3.5,3.5c0,2.2,1.4,3.5,3.5,3.5c1.9,0,3-1.3,3.2-3
|
||||||
|
l-1.1-0.2c-0.2,1.1-0.8,2.1-2.1,2.1c-1.3,0-2.1-0.9-2.1-2.5C19,76.9,19.9,75.9,21.2,75.9z M29,75.9c1.1,0,1.6,0.6,1.6,1.9V82h1.3
|
||||||
|
v-4.1c0-1.6-0.6-2.7-2.5-2.7c-0.9,0-1.9,0.6-2.2,1.4v-4.1h-1.3v9.7h1.3v-3.8C27.1,76.7,27.8,75.9,29,75.9z M36.2,81.2
|
||||||
|
c-1.1,0-1.9-0.5-2.1-1.6h-1.1c0.2,1.6,1.4,2.4,3,2.4s2.7-0.8,2.7-2.1c0-1.3-0.8-1.7-2.2-1.9l-1.3-0.2c-0.6-0.2-1.1-0.5-1.1-0.9
|
||||||
|
c0-0.6,0.5-0.9,1.4-0.9c1.1,0,1.7,0.5,1.9,1.6h1.1c-0.2-1.6-1.1-2.4-3-2.4c-1.6,0-2.5,0.8-2.5,2.1c0,1.1,0.8,1.7,2.1,1.9h1.3
|
||||||
|
c0.8,0.2,1.3,0.3,1.3,0.9C37.7,80.9,37,81.2,36.2,81.2z M43.4,75.9c1.3,0,1.9,0.8,2.1,2.1h1.1c-0.2-1.6-1.3-3-3.2-3
|
||||||
|
c-2.1,0-3.5,1.4-3.5,3.5c0,2.2,1.4,3.5,3.5,3.5c1.9,0,3-1.3,3.2-3l-1.1-0.2c-0.2,1.1-0.8,2.1-2.1,2.1c-1.3,0-2.1-0.9-2.1-2.5
|
||||||
|
C41.3,76.9,42.1,75.9,43.4,75.9z M51.1,75.9c1.1,0,1.6,0.6,1.6,1.9V82H54v-4.1c0-1.6-0.6-2.7-2.5-2.7c-0.9,0-1.9,0.6-2.2,1.4v-4.1
|
||||||
|
h-1.3v9.7h1.3v-3.8C49.4,76.7,50.2,75.9,51.1,75.9z M60.4,79c0,1.3-0.8,2.1-1.7,2.1c-1.1,0-1.6-0.8-1.6-1.9V75h-1.3v4.1
|
||||||
|
c0,1.6,0.6,2.7,2.4,2.7c0.9,0,1.9-0.6,2.2-1.4v1.1h1.3v-6.6h-1.3C60.4,74.8,60.4,79,60.4,79z M63.6,72.2h1.3v9.7h-1.3V72.2z
|
||||||
|
M69.8,82.1c1.7,0,2.8-0.9,3.2-2.4l-1.1-0.2c-0.3,1.1-0.9,1.6-2.1,1.6c-1.3,0-2.1-0.9-2.2-2.2h5.4v-0.5c0-1.9-1.1-3.3-3.2-3.3
|
||||||
|
c-1.9,0-3.3,1.6-3.3,3.6C66.3,80.7,67.7,82.1,69.8,82.1z M69.6,75.9c1.3,0,1.9,0.9,1.9,2.1h-4C67.7,76.9,68.5,75.9,69.6,75.9z
|
||||||
|
M85.3,81.8v-9.7H84v7.4l-5.2-7.4h-1.4v9.7h1.3v-7.8l5.5,7.8H85.3z M93.5,79.6l-1.1-0.2c-0.3,1.1-0.9,1.6-2.1,1.6
|
||||||
|
c-1.3,0-2.2-0.9-2.2-2.2h5.4v-0.5c0-1.9-1.1-3.3-3.2-3.3c-1.9,0-3.3,1.6-3.3,3.6s1.4,3.5,3.5,3.5C91.9,82.1,93,81.2,93.5,79.6z
|
||||||
|
M90.2,75.9c1.3,0,1.9,0.9,1.9,2.1h-4C88.3,76.9,89.1,75.9,90.2,75.9z M94.9,75.2v4.1c0,1.6,0.6,2.7,2.4,2.7c0.9,0,1.9-0.6,2.2-1.4
|
||||||
|
v1.1h1.3V75h-1.3v3.8c0,1.3-0.8,2.1-1.7,2.1c-1.1,0-1.6-0.8-1.6-1.9v-4.1h-1.3V75.2z M102.7,77.4h3.5v1.1h-3.5V77.4z M115.8,78.2
|
||||||
|
v-6h-1.3v6c0,1.9-0.9,2.7-2.7,2.7c-1.7,0-2.5-0.9-2.5-2.7v-6h-1.3v6c0,2.8,1.7,4,4,4S115.8,81,115.8,78.2z M117.7,72.2h1.3v9.7
|
||||||
|
h-1.3V72.2z M128.8,75c-1.1,0-1.9,0.6-2.2,1.4c-0.3-0.9-0.9-1.4-2.2-1.4c-1.1,0-1.7,0.6-2.1,1.4v-1.3H121v6.6h1.3V78
|
||||||
|
c0-1.3,0.8-2.1,1.7-2.1c1.1,0,1.4,0.6,1.4,1.9V82h1.1v-3.8c0-1.3,0.8-2.1,1.7-2.1c1.1,0,1.4,0.6,1.4,1.9v4.1h1.3V78
|
||||||
|
C131.2,76.3,130.5,75,128.8,75z M6.5,93.7c0,1.9-0.9,2.7-2.7,2.7s-2.5-0.9-2.5-2.7v-6H0v6c0,2.8,1.7,4,4,4s4-1.1,4-4v-6H6.5V93.7z
|
||||||
|
M13.1,90.5c-0.9,0-1.9,0.6-2.2,1.4v-1.3H9.7v6.6h1.3v-3.8c0-1.3,0.8-2.1,1.7-2.1c1.1,0,1.6,0.6,1.6,1.9v4.1h1.3v-4.1
|
||||||
|
C15.7,91.6,14.9,90.5,13.1,90.5z M17.4,90.7h1.3v6.6h-1.3V90.7z M17.4,87.7h1.3v1.4h-1.3V87.7z M23.4,95.9h-0.2l-2.1-5.2h-1.3
|
||||||
|
l2.7,6.6h1.3l2.7-6.6h-1.1L23.4,95.9z M30.7,90.5c-1.9,0-3.3,1.6-3.3,3.6s1.4,3.5,3.5,3.5c1.7,0,2.8-0.9,3.2-2.4l-1.3-0.3
|
||||||
|
c-0.3,1.1-0.9,1.6-2.1,1.6c-1.3,0-2.2-0.9-2.2-2.2h5.4v-0.5C33.9,91.9,32.8,90.5,30.7,90.5z M28.5,93.5c0.2-1.1,0.9-2.1,2.1-2.1
|
||||||
|
c1.3,0,1.9,0.9,1.9,2.1H28.5z M36.6,92.1v-1.4h-1.3v6.6h1.3v-3.5c0-1.3,0.8-2.2,1.7-2.2c0.5,0,0.6,0,1.1,0.3l0.2-1.1
|
||||||
|
c-0.2-0.2-0.5-0.3-0.9-0.3C37.5,90.5,36.9,91.3,36.6,92.1z M43.7,93.5l-1.3-0.2c-0.6-0.2-1.1-0.5-1.1-0.9c0-0.6,0.5-0.9,1.4-0.9
|
||||||
|
c1.1,0,1.7,0.5,1.9,1.6h1.1c-0.2-1.6-1.1-2.4-3-2.4c-1.6,0-2.5,0.8-2.5,2.1c0,1.1,0.8,1.7,2.1,1.9l1.1,0.2c0.8,0.2,1.3,0.3,1.3,0.9
|
||||||
|
c0,0.6-0.6,0.9-1.6,0.9c-1.1,0-1.9-0.5-2.1-1.6h-1.1c0.2,1.6,1.4,2.4,3,2.4c1.6,0,2.7-0.8,2.7-2.1C45.9,94.3,45.1,93.8,43.7,93.5z
|
||||||
|
M47.3,87.7h1.3v1.4h-1.3V87.7z M47.3,90.7h1.3v6.6h-1.3V90.7z M52.1,95.7v-4.1H54v-0.9h-1.9v-1.9h-0.8l-0.2,0.9
|
||||||
|
c-0.2,0.6-0.3,0.9-0.9,1.1h-0.5v0.6h0.9v4.3c0,1.3,0.6,1.7,1.6,1.7c0.8,0,1.3-0.2,1.7-0.6V96c-0.3,0.2-0.8,0.5-1.3,0.5
|
||||||
|
S52.1,96.2,52.1,95.7z M58.1,95.9l-2.2-5.2h-1.3l2.8,6.6l-1.1,2.7h1.3l3.8-9.3h-1.3L58.1,95.9z M68.5,90.5c-1.9,0-3.5,1.4-3.5,3.5
|
||||||
|
s1.4,3.5,3.5,3.5S72,96,72,94S70.4,90.5,68.5,90.5z M68.5,96.5c-1.4,0-2.1-1.1-2.1-2.5c0-1.6,0.8-2.5,2.1-2.5
|
||||||
|
c1.4,0,2.1,1.1,2.1,2.5C70.6,95.6,69.8,96.5,68.5,96.5z M75.9,87.5c-1.4,0-2.2,0.9-2.2,2.4v0.8h-1.1v0.9h1.1v5.9H75v-5.9h1.9v-0.9
|
||||||
|
H75v-0.9c0-0.8,0.3-1.3,1.1-1.3c0.6,0,0.9,0.5,1.1,0.9l0.9-0.3C77.7,88,77.1,87.5,75.9,87.5z M84.2,87.7l-4,9.7h1.3l1.1-2.8H87
|
||||||
|
l1.1,2.8h1.4l-4-9.7H84.2z M83.1,93.5l1.7-4.3l1.7,4.3C86.6,93.5,83.1,93.5,83.1,93.5z M94.5,90.5c-1.3,0-2.1,0.8-2.4,1.6v-1.4
|
||||||
|
h-1.3v9.3h1.3v-4c0.3,0.8,1.1,1.6,2.4,1.6c2.1,0,3-1.6,3-3.5C97.6,92.1,96.5,90.5,94.5,90.5z M94.3,96.5c-1.3,0-2.2-0.8-2.2-2.4
|
||||||
|
v-0.3c0-1.4,0.9-2.4,2.2-2.4c1.3,0,2.1,0.9,2.1,2.5C96.2,95.6,95.6,96.5,94.3,96.5z M102.7,90.5c-1.3,0-2.1,0.8-2.4,1.6v-1.4h-1.3
|
||||||
|
v9.3h1.3v-4c0.3,0.8,1.1,1.6,2.4,1.6c2.1,0,3-1.6,3-3.5C105.9,92.1,104.7,90.5,102.7,90.5z M102.5,96.5c-1.3,0-2.2-0.8-2.2-2.4
|
||||||
|
v-0.3c0-1.4,0.9-2.4,2.2-2.4c1.3,0,2.1,0.9,2.1,2.5C104.6,95.6,103.8,96.5,102.5,96.5z M107.3,87.7h1.3v9.7h-1.3V87.7z M110.4,87.7
|
||||||
|
h1.3v1.4h-1.3V87.7z M110.4,90.7h1.3v6.6h-1.3V90.7z M116.6,90.5c-1.9,0-3.3,1.6-3.3,3.6s1.4,3.5,3.5,3.5c1.7,0,2.8-0.9,3.2-2.4
|
||||||
|
l-1.1-0.3c-0.3,1.1-0.9,1.6-2.1,1.6c-1.3,0-2.1-0.9-2.2-2.2h5.4v-0.5C119.8,91.9,118.8,90.5,116.6,90.5z M114.6,93.5
|
||||||
|
c0.2-1.1,0.9-2.1,2.1-2.1c1.3,0,1.9,0.9,1.9,2.1H114.6z M126.4,92.1c-0.3-0.8-1.1-1.6-2.4-1.6c-2.1,0-3,1.6-3,3.5
|
||||||
|
c0,2.1,1.1,3.5,3,3.5c1.3,0,2.1-0.8,2.4-1.6v1.4h1.3v-9.7h-1.3C126.4,87.7,126.4,92.1,126.4,92.1z M126.4,94.1
|
||||||
|
c0,1.4-0.9,2.4-2.1,2.4c-1.3,0-2.1-0.9-2.1-2.5s0.8-2.5,2.1-2.5c1.3,0,2.1,0.8,2.1,2.4C126.4,93.8,126.4,94.1,126.4,94.1z
|
||||||
|
M137,92.1l-1.7-0.3c-1.1-0.2-1.7-0.5-1.7-1.4c0-1.1,0.8-1.7,2.2-1.7c1.6,0,2.5,0.9,2.7,2.5h1.3c0-2.2-1.4-3.5-3.8-3.5
|
||||||
|
c-2.1,0-3.5,1.1-3.5,2.8c0,1.6,0.9,2.2,2.4,2.5l1.9,0.3c1.3,0.3,1.9,0.6,1.9,1.6c0,1.1-0.9,1.7-2.4,1.7c-1.6,0-2.8-0.9-2.8-2.7
|
||||||
|
h-1.3c0,2.4,1.7,3.6,4.1,3.6c2.1,0,3.6-1.1,3.6-2.8C139.7,93.2,138.8,92.4,137,92.1z M144.3,91.5c1.3,0,1.9,0.8,2.1,2.1h1.1
|
||||||
|
c-0.2-1.6-1.3-3-3.2-3c-2.1,0-3.5,1.4-3.5,3.5c0,2.2,1.4,3.5,3.5,3.5c1.9,0,3-1.3,3.2-3l-1.1-0.2c0,1.4-0.8,2.2-2.1,2.2
|
||||||
|
c-1.3,0-2.1-0.9-2.1-2.5S143,91.5,144.3,91.5z M148.9,87.7h1.3v1.4h-1.3V87.7z M149.1,90.7h1.3v6.6h-1.3V90.7z M155.1,90.5
|
||||||
|
c-1.9,0-3.3,1.6-3.3,3.6s1.4,3.5,3.5,3.5c1.7,0,2.8-0.9,3.2-2.4l-1.1-0.3c-0.3,1.1-0.9,1.6-2.1,1.6c-1.3,0-2.2-0.9-2.2-2.2h5.4
|
||||||
|
v-0.5C158.4,91.9,157.3,90.5,155.1,90.5z M153,93.5c0.2-1.1,0.9-2.1,2.1-2.1c1.3,0,1.9,0.9,1.9,2.1H153z M163.3,90.5
|
||||||
|
c-0.9,0-1.9,0.6-2.2,1.4v-1.3h-1.3v6.6h1.3v-3.8c0-1.3,0.8-2.1,1.7-2.1c1.1,0,1.6,0.6,1.6,1.9v4.1h1.3v-4.1
|
||||||
|
C165.8,91.6,165,90.5,163.3,90.5z M170.6,91.5c1.3,0,1.9,0.8,2.1,2.1h1.1c-0.2-1.6-1.3-3-3.2-3c-2.1,0-3.5,1.4-3.5,3.5
|
||||||
|
c0,2.2,1.4,3.5,3.5,3.5c1.9,0,3-1.3,3.2-3l-1.1-0.2c-0.2,1.1-0.8,2.1-2.1,2.1s-2.1-0.9-2.1-2.5C168.5,92.4,169.3,91.5,170.6,91.5z
|
||||||
|
M178.3,90.5c-1.9,0-3.3,1.6-3.3,3.6s1.4,3.5,3.5,3.5c1.7,0,2.8-0.9,3.2-2.4l-1.3-0.3c-0.3,1.1-0.9,1.6-2.1,1.6
|
||||||
|
c-1.3,0-2.2-0.9-2.2-2.2h5.4v-0.5C181.5,91.9,180.4,90.5,178.3,90.5z M176.1,93.5c0.2-1.1,0.9-2.1,2.1-2.1c1.3,0,1.9,0.9,1.9,2.1
|
||||||
|
H176.1z M186.2,93.5l-1.3-0.2c-0.6-0.2-1.1-0.5-1.1-0.9c0-0.6,0.5-0.9,1.4-0.9c1.1,0,1.7,0.5,1.9,1.6h1.1c-0.2-1.6-1.1-2.4-3-2.4
|
||||||
|
c-1.6,0-2.5,0.8-2.5,2.1c0,1.1,0.8,1.7,2.1,1.9l1.1,0.2c0.8,0.2,1.3,0.3,1.3,0.9c0,0.6-0.6,0.9-1.6,0.9c-1.1,0-1.9-0.5-2.1-1.6
|
||||||
|
h-1.1c0.2,1.6,1.4,2.4,3,2.4c1.6,0,2.7-0.8,2.7-2.1C188.4,94.3,187.5,93.8,186.2,93.5z M6.2,0h11.7v19.8H6.2V0z M17.7,37.7h10.1
|
||||||
|
v-4.7H6.2V57H0v3.6h17.7V37.7z M55.2,0H43.7v57h-6.2v3.6h17.7V0z M149.2,44.3c1.7,0,3.3-0.2,4.6-0.6c-2.1-1.9-3-5.1-3-10V0h-11.6
|
||||||
|
v30.2C139.2,39.4,141.6,44.3,149.2,44.3z">
|
||||||
|
</path>
|
||||||
|
<path d="M144,57.8c4.4,2.5,10,4,16.6,4c17.6,0,27.7-9.3,27.7-25.5V0h-11.6v32.9c0,17.7-12,25.2-27.5,25.2
|
||||||
|
C147.3,58.1,145.6,57.9,144,57.8z M95.7,15.7L84.7,0H73.3l22.5,31.8V15.7z M122.3,60.6V0h-11.7v57h-5.5l2.7,3.6H122.3z M84.8,37.5
|
||||||
|
L72.3,20.6V57h-4.6v3.6h17.1V37.5z">
|
||||||
|
</path>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 8.2 KiB |
83
packages/client/static/logo_white.svg
Normal file
83
packages/client/static/logo_white.svg
Normal file
|
@ -0,0 +1,83 @@
|
||||||
|
<svg version="1.1" id="Layer_1" xmlns:x="ns_extend;" xmlns:i="ns_ai;" xmlns:graph="ns_graphs;" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 188.3 100" style="enable-background:new 0 0 188.3 100;" xml:space="preserve">
|
||||||
|
<style type="text/css">
|
||||||
|
.st0{fill:#FFFFFF;}
|
||||||
|
</style>
|
||||||
|
<metadata>
|
||||||
|
<sfw xmlns="ns_sfw;">
|
||||||
|
<slices>
|
||||||
|
</slices>
|
||||||
|
<sliceSourceBounds bottomLeftOrigin="true" height="100" width="188.3" x="-68.6" y="1.5">
|
||||||
|
</sliceSourceBounds>
|
||||||
|
</sfw>
|
||||||
|
</metadata>
|
||||||
|
<g>
|
||||||
|
<path class="st0" d="M7,76.3H1.3v-4.1H0v9.7h1.3v-4.4H7v4.4h1.3v-9.7H7V76.3z M13.1,75c-1.9,0-3.5,1.4-3.5,3.5s1.4,3.5,3.5,3.5
|
||||||
|
s3.5-1.4,3.5-3.5S15.2,75,13.1,75z M13.1,81c-1.4,0-2.1-1.1-2.1-2.5c0-1.6,0.8-2.5,2.1-2.5c1.4,0,2.1,1.1,2.1,2.5
|
||||||
|
C15.3,80.1,14.6,81,13.1,81z M21.2,75.9c1.3,0,1.9,0.8,2.1,2.1h1.1c-0.2-1.6-1.3-3-3.2-3c-2.1,0-3.5,1.4-3.5,3.5
|
||||||
|
c0,2.2,1.4,3.5,3.5,3.5c1.9,0,3-1.3,3.2-3l-1.1-0.2c-0.2,1.1-0.8,2.1-2.1,2.1c-1.3,0-2.1-0.9-2.1-2.5C19,76.9,19.9,75.9,21.2,75.9z
|
||||||
|
M29,75.9c1.1,0,1.6,0.6,1.6,1.9V82h1.3v-4.1c0-1.6-0.6-2.7-2.5-2.7c-0.9,0-1.9,0.6-2.2,1.4v-4.1h-1.3v9.7h1.3v-3.8
|
||||||
|
C27.1,76.7,27.8,75.9,29,75.9z M36.2,81.2c-1.1,0-1.9-0.5-2.1-1.6h-1.1c0.2,1.6,1.4,2.4,3,2.4s2.7-0.8,2.7-2.1
|
||||||
|
c0-1.3-0.8-1.7-2.2-1.9l-1.3-0.2c-0.6-0.2-1.1-0.5-1.1-0.9c0-0.6,0.5-0.9,1.4-0.9c1.1,0,1.7,0.5,1.9,1.6h1.1
|
||||||
|
c-0.2-1.6-1.1-2.4-3-2.4c-1.6,0-2.5,0.8-2.5,2.1c0,1.1,0.8,1.7,2.1,1.9h1.3c0.8,0.2,1.3,0.3,1.3,0.9C37.7,80.9,37,81.2,36.2,81.2z
|
||||||
|
M43.4,75.9c1.3,0,1.9,0.8,2.1,2.1h1.1c-0.2-1.6-1.3-3-3.2-3c-2.1,0-3.5,1.4-3.5,3.5c0,2.2,1.4,3.5,3.5,3.5c1.9,0,3-1.3,3.2-3
|
||||||
|
l-1.1-0.2c-0.2,1.1-0.8,2.1-2.1,2.1c-1.3,0-2.1-0.9-2.1-2.5C41.3,76.9,42.1,75.9,43.4,75.9z M51.1,75.9c1.1,0,1.6,0.6,1.6,1.9V82
|
||||||
|
H54v-4.1c0-1.6-0.6-2.7-2.5-2.7c-0.9,0-1.9,0.6-2.2,1.4v-4.1h-1.3v9.7h1.3v-3.8C49.4,76.7,50.2,75.9,51.1,75.9z M60.4,79
|
||||||
|
c0,1.3-0.8,2.1-1.7,2.1c-1.1,0-1.6-0.8-1.6-1.9V75h-1.3v4.1c0,1.6,0.6,2.7,2.4,2.7c0.9,0,1.9-0.6,2.2-1.4v1.1h1.3v-6.6h-1.3
|
||||||
|
C60.4,74.8,60.4,79,60.4,79z M63.6,72.2h1.3v9.7h-1.3V72.2z M69.8,82.1c1.7,0,2.8-0.9,3.2-2.4l-1.1-0.2c-0.3,1.1-0.9,1.6-2.1,1.6
|
||||||
|
c-1.3,0-2.1-0.9-2.2-2.2h5.4v-0.5c0-1.9-1.1-3.3-3.2-3.3c-1.9,0-3.3,1.6-3.3,3.6C66.3,80.7,67.7,82.1,69.8,82.1z M69.6,75.9
|
||||||
|
c1.3,0,1.9,0.9,1.9,2.1h-4C67.7,76.9,68.5,75.9,69.6,75.9z M85.3,81.8v-9.7H84v7.4l-5.2-7.4h-1.4v9.7h1.3v-7.8l5.5,7.8H85.3z
|
||||||
|
M93.5,79.6l-1.1-0.2c-0.3,1.1-0.9,1.6-2.1,1.6c-1.3,0-2.2-0.9-2.2-2.2h5.4v-0.5c0-1.9-1.1-3.3-3.2-3.3c-1.9,0-3.3,1.6-3.3,3.6
|
||||||
|
s1.4,3.5,3.5,3.5C91.9,82.1,93,81.2,93.5,79.6z M90.2,75.9c1.3,0,1.9,0.9,1.9,2.1h-4C88.3,76.9,89.1,75.9,90.2,75.9z M94.9,75.2
|
||||||
|
v4.1c0,1.6,0.6,2.7,2.4,2.7c0.9,0,1.9-0.6,2.2-1.4v1.1h1.3V75h-1.3v3.8c0,1.3-0.8,2.1-1.7,2.1c-1.1,0-1.6-0.8-1.6-1.9v-4.1h-1.3
|
||||||
|
V75.2z M102.7,77.4h3.5v1.1h-3.5V77.4z M115.8,78.2v-6h-1.3v6c0,1.9-0.9,2.7-2.7,2.7c-1.7,0-2.5-0.9-2.5-2.7v-6h-1.3v6
|
||||||
|
c0,2.8,1.7,4,4,4S115.8,81,115.8,78.2z M117.7,72.2h1.3v9.7h-1.3V72.2z M128.8,75c-1.1,0-1.9,0.6-2.2,1.4c-0.3-0.9-0.9-1.4-2.2-1.4
|
||||||
|
c-1.1,0-1.7,0.6-2.1,1.4v-1.3H121v6.6h1.3V78c0-1.3,0.8-2.1,1.7-2.1c1.1,0,1.4,0.6,1.4,1.9V82h1.1v-3.8c0-1.3,0.8-2.1,1.7-2.1
|
||||||
|
c1.1,0,1.4,0.6,1.4,1.9v4.1h1.3V78C131.2,76.3,130.5,75,128.8,75z M6.5,93.7c0,1.9-0.9,2.7-2.7,2.7s-2.5-0.9-2.5-2.7v-6H0v6
|
||||||
|
c0,2.8,1.7,4,4,4s4-1.1,4-4v-6H6.5V93.7z M13.1,90.5c-0.9,0-1.9,0.6-2.2,1.4v-1.3H9.7v6.6h1.3v-3.8c0-1.3,0.8-2.1,1.7-2.1
|
||||||
|
c1.1,0,1.6,0.6,1.6,1.9v4.1h1.3v-4.1C15.7,91.6,14.9,90.5,13.1,90.5z M17.4,90.7h1.3v6.6h-1.3V90.7z M17.4,87.7h1.3v1.4h-1.3V87.7z
|
||||||
|
M23.4,95.9h-0.2l-2.1-5.2h-1.3l2.7,6.6h1.3l2.7-6.6h-1.1L23.4,95.9z M30.7,90.5c-1.9,0-3.3,1.6-3.3,3.6s1.4,3.5,3.5,3.5
|
||||||
|
c1.7,0,2.8-0.9,3.2-2.4l-1.3-0.3c-0.3,1.1-0.9,1.6-2.1,1.6c-1.3,0-2.2-0.9-2.2-2.2h5.4v-0.5C33.9,91.9,32.8,90.5,30.7,90.5z
|
||||||
|
M28.5,93.5c0.2-1.1,0.9-2.1,2.1-2.1c1.3,0,1.9,0.9,1.9,2.1H28.5z M36.6,92.1v-1.4h-1.3v6.6h1.3v-3.5c0-1.3,0.8-2.2,1.7-2.2
|
||||||
|
c0.5,0,0.6,0,1.1,0.3l0.2-1.1c-0.2-0.2-0.5-0.3-0.9-0.3C37.5,90.5,36.9,91.3,36.6,92.1z M43.7,93.5l-1.3-0.2
|
||||||
|
c-0.6-0.2-1.1-0.5-1.1-0.9c0-0.6,0.5-0.9,1.4-0.9c1.1,0,1.7,0.5,1.9,1.6h1.1c-0.2-1.6-1.1-2.4-3-2.4c-1.6,0-2.5,0.8-2.5,2.1
|
||||||
|
c0,1.1,0.8,1.7,2.1,1.9l1.1,0.2c0.8,0.2,1.3,0.3,1.3,0.9c0,0.6-0.6,0.9-1.6,0.9c-1.1,0-1.9-0.5-2.1-1.6h-1.1c0.2,1.6,1.4,2.4,3,2.4
|
||||||
|
c1.6,0,2.7-0.8,2.7-2.1C45.9,94.3,45.1,93.8,43.7,93.5z M47.3,87.7h1.3v1.4h-1.3V87.7z M47.3,90.7h1.3v6.6h-1.3V90.7z M52.1,95.7
|
||||||
|
v-4.1H54v-0.9h-1.9v-1.9h-0.8l-0.2,0.9c-0.2,0.6-0.3,0.9-0.9,1.1h-0.5v0.6h0.9v4.3c0,1.3,0.6,1.7,1.6,1.7c0.8,0,1.3-0.2,1.7-0.6V96
|
||||||
|
c-0.3,0.2-0.8,0.5-1.3,0.5S52.1,96.2,52.1,95.7z M58.1,95.9l-2.2-5.2h-1.3l2.8,6.6l-1.1,2.7h1.3l3.8-9.3h-1.3L58.1,95.9z
|
||||||
|
M68.5,90.5c-1.9,0-3.5,1.4-3.5,3.5s1.4,3.5,3.5,3.5S72,96,72,94S70.4,90.5,68.5,90.5z M68.5,96.5c-1.4,0-2.1-1.1-2.1-2.5
|
||||||
|
c0-1.6,0.8-2.5,2.1-2.5c1.4,0,2.1,1.1,2.1,2.5C70.6,95.6,69.8,96.5,68.5,96.5z M75.9,87.5c-1.4,0-2.2,0.9-2.2,2.4v0.8h-1.1v0.9h1.1
|
||||||
|
v5.9H75v-5.9h1.9v-0.9H75v-0.9c0-0.8,0.3-1.3,1.1-1.3c0.6,0,0.9,0.5,1.1,0.9l0.9-0.3C77.7,88,77.1,87.5,75.9,87.5z M84.2,87.7
|
||||||
|
l-4,9.7h1.3l1.1-2.8H87l1.1,2.8h1.4l-4-9.7H84.2z M83.1,93.5l1.7-4.3l1.7,4.3C86.6,93.5,83.1,93.5,83.1,93.5z M94.5,90.5
|
||||||
|
c-1.3,0-2.1,0.8-2.4,1.6v-1.4h-1.3v9.3h1.3v-4c0.3,0.8,1.1,1.6,2.4,1.6c2.1,0,3-1.6,3-3.5C97.6,92.1,96.5,90.5,94.5,90.5z
|
||||||
|
M94.3,96.5c-1.3,0-2.2-0.8-2.2-2.4v-0.3c0-1.4,0.9-2.4,2.2-2.4c1.3,0,2.1,0.9,2.1,2.5C96.2,95.6,95.6,96.5,94.3,96.5z M102.7,90.5
|
||||||
|
c-1.3,0-2.1,0.8-2.4,1.6v-1.4h-1.3v9.3h1.3v-4c0.3,0.8,1.1,1.6,2.4,1.6c2.1,0,3-1.6,3-3.5C105.9,92.1,104.7,90.5,102.7,90.5z
|
||||||
|
M102.5,96.5c-1.3,0-2.2-0.8-2.2-2.4v-0.3c0-1.4,0.9-2.4,2.2-2.4c1.3,0,2.1,0.9,2.1,2.5C104.6,95.6,103.8,96.5,102.5,96.5z
|
||||||
|
M107.3,87.7h1.3v9.7h-1.3V87.7z M110.4,87.7h1.3v1.4h-1.3V87.7z M110.4,90.7h1.3v6.6h-1.3V90.7z M116.6,90.5
|
||||||
|
c-1.9,0-3.3,1.6-3.3,3.6s1.4,3.5,3.5,3.5c1.7,0,2.8-0.9,3.2-2.4l-1.1-0.3c-0.3,1.1-0.9,1.6-2.1,1.6c-1.3,0-2.1-0.9-2.2-2.2h5.4
|
||||||
|
v-0.5C119.8,91.9,118.8,90.5,116.6,90.5z M114.6,93.5c0.2-1.1,0.9-2.1,2.1-2.1c1.3,0,1.9,0.9,1.9,2.1H114.6z M126.4,92.1
|
||||||
|
c-0.3-0.8-1.1-1.6-2.4-1.6c-2.1,0-3,1.6-3,3.5c0,2.1,1.1,3.5,3,3.5c1.3,0,2.1-0.8,2.4-1.6v1.4h1.3v-9.7h-1.3
|
||||||
|
C126.4,87.7,126.4,92.1,126.4,92.1z M126.4,94.1c0,1.4-0.9,2.4-2.1,2.4c-1.3,0-2.1-0.9-2.1-2.5s0.8-2.5,2.1-2.5
|
||||||
|
c1.3,0,2.1,0.8,2.1,2.4C126.4,93.8,126.4,94.1,126.4,94.1z M137,92.1l-1.7-0.3c-1.1-0.2-1.7-0.5-1.7-1.4c0-1.1,0.8-1.7,2.2-1.7
|
||||||
|
c1.6,0,2.5,0.9,2.7,2.5h1.3c0-2.2-1.4-3.5-3.8-3.5c-2.1,0-3.5,1.1-3.5,2.8c0,1.6,0.9,2.2,2.4,2.5l1.9,0.3c1.3,0.3,1.9,0.6,1.9,1.6
|
||||||
|
c0,1.1-0.9,1.7-2.4,1.7c-1.6,0-2.8-0.9-2.8-2.7h-1.3c0,2.4,1.7,3.6,4.1,3.6c2.1,0,3.6-1.1,3.6-2.8C139.7,93.2,138.8,92.4,137,92.1z
|
||||||
|
M144.3,91.5c1.3,0,1.9,0.8,2.1,2.1h1.1c-0.2-1.6-1.3-3-3.2-3c-2.1,0-3.5,1.4-3.5,3.5c0,2.2,1.4,3.5,3.5,3.5c1.9,0,3-1.3,3.2-3
|
||||||
|
l-1.1-0.2c0,1.4-0.8,2.2-2.1,2.2c-1.3,0-2.1-0.9-2.1-2.5S143,91.5,144.3,91.5z M148.9,87.7h1.3v1.4h-1.3V87.7z M149.1,90.7h1.3v6.6
|
||||||
|
h-1.3V90.7z M155.1,90.5c-1.9,0-3.3,1.6-3.3,3.6s1.4,3.5,3.5,3.5c1.7,0,2.8-0.9,3.2-2.4l-1.1-0.3c-0.3,1.1-0.9,1.6-2.1,1.6
|
||||||
|
c-1.3,0-2.2-0.9-2.2-2.2h5.4v-0.5C158.4,91.9,157.3,90.5,155.1,90.5z M153,93.5c0.2-1.1,0.9-2.1,2.1-2.1c1.3,0,1.9,0.9,1.9,2.1H153
|
||||||
|
z M163.3,90.5c-0.9,0-1.9,0.6-2.2,1.4v-1.3h-1.3v6.6h1.3v-3.8c0-1.3,0.8-2.1,1.7-2.1c1.1,0,1.6,0.6,1.6,1.9v4.1h1.3v-4.1
|
||||||
|
C165.8,91.6,165,90.5,163.3,90.5z M170.6,91.5c1.3,0,1.9,0.8,2.1,2.1h1.1c-0.2-1.6-1.3-3-3.2-3c-2.1,0-3.5,1.4-3.5,3.5
|
||||||
|
c0,2.2,1.4,3.5,3.5,3.5c1.9,0,3-1.3,3.2-3l-1.1-0.2c-0.2,1.1-0.8,2.1-2.1,2.1s-2.1-0.9-2.1-2.5C168.5,92.4,169.3,91.5,170.6,91.5z
|
||||||
|
M178.3,90.5c-1.9,0-3.3,1.6-3.3,3.6s1.4,3.5,3.5,3.5c1.7,0,2.8-0.9,3.2-2.4l-1.3-0.3c-0.3,1.1-0.9,1.6-2.1,1.6
|
||||||
|
c-1.3,0-2.2-0.9-2.2-2.2h5.4v-0.5C181.5,91.9,180.4,90.5,178.3,90.5z M176.1,93.5c0.2-1.1,0.9-2.1,2.1-2.1c1.3,0,1.9,0.9,1.9,2.1
|
||||||
|
H176.1z M186.2,93.5l-1.3-0.2c-0.6-0.2-1.1-0.5-1.1-0.9c0-0.6,0.5-0.9,1.4-0.9c1.1,0,1.7,0.5,1.9,1.6h1.1c-0.2-1.6-1.1-2.4-3-2.4
|
||||||
|
c-1.6,0-2.5,0.8-2.5,2.1c0,1.1,0.8,1.7,2.1,1.9l1.1,0.2c0.8,0.2,1.3,0.3,1.3,0.9c0,0.6-0.6,0.9-1.6,0.9c-1.1,0-1.9-0.5-2.1-1.6
|
||||||
|
h-1.1c0.2,1.6,1.4,2.4,3,2.4c1.6,0,2.7-0.8,2.7-2.1C188.4,94.3,187.5,93.8,186.2,93.5z M6.2,0h11.7v19.8H6.2V0z M17.7,37.7h10.1
|
||||||
|
v-4.7H6.2V57H0v3.6h17.7V37.7z M55.2,0H43.7v57h-6.2v3.6h17.7V0z M149.2,44.3c1.7,0,3.3-0.2,4.6-0.6c-2.1-1.9-3-5.1-3-10V0h-11.6
|
||||||
|
v30.2C139.2,39.4,141.6,44.3,149.2,44.3z">
|
||||||
|
</path>
|
||||||
|
<path class="st0" d="M144,57.8c4.4,2.5,10,4,16.6,4c17.6,0,27.7-9.3,27.7-25.5V0h-11.6v32.9c0,17.7-12,25.2-27.5,25.2
|
||||||
|
C147.3,58.1,145.6,57.9,144,57.8z M95.7,15.7L84.7,0H73.3l22.5,31.8V15.7z M122.3,60.6V0h-11.7v57h-5.5l2.7,3.6H122.3z M84.8,37.5
|
||||||
|
L72.3,20.6V57h-4.6v3.6h17.1V37.5z">
|
||||||
|
</path>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 8.3 KiB |
12
packages/client/svelte.config.js
Normal file
12
packages/client/svelte.config.js
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
import adapter from '@sveltejs/adapter-node';
|
||||||
|
import {vitePreprocess} from '@sveltejs/vite-plugin-svelte';
|
||||||
|
|
||||||
|
/** @type {import('@sveltejs/kit').Config} */
|
||||||
|
const config = {
|
||||||
|
preprocess: vitePreprocess(),
|
||||||
|
kit: {
|
||||||
|
adapter: adapter(),
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export default config;
|
14
packages/client/tsconfig.json
Normal file
14
packages/client/tsconfig.json
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
{
|
||||||
|
"extends": "./.svelte-kit/tsconfig.json",
|
||||||
|
"compilerOptions": {
|
||||||
|
"allowJs": true,
|
||||||
|
"checkJs": true,
|
||||||
|
"esModuleInterop": true,
|
||||||
|
"forceConsistentCasingInFileNames": true,
|
||||||
|
"resolveJsonModule": true,
|
||||||
|
"skipLibCheck": true,
|
||||||
|
"sourceMap": true,
|
||||||
|
"strict": true,
|
||||||
|
"moduleResolution": "bundler",
|
||||||
|
},
|
||||||
|
}
|
10
packages/client/vite.config.ts
Normal file
10
packages/client/vite.config.ts
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
import tailwindcss from '@tailwindcss/vite';
|
||||||
|
import { sveltekit } from '@sveltejs/kit/vite';
|
||||||
|
import { defineConfig } from 'vite';
|
||||||
|
|
||||||
|
export default defineConfig({
|
||||||
|
plugins: [
|
||||||
|
sveltekit(),
|
||||||
|
tailwindcss()
|
||||||
|
],
|
||||||
|
});
|
34
packages/server/.gitignore
vendored
Normal file
34
packages/server/.gitignore
vendored
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
# dependencies (bun install)
|
||||||
|
node_modules
|
||||||
|
|
||||||
|
# output
|
||||||
|
out
|
||||||
|
dist
|
||||||
|
*.tgz
|
||||||
|
|
||||||
|
# code coverage
|
||||||
|
coverage
|
||||||
|
*.lcov
|
||||||
|
|
||||||
|
# logs
|
||||||
|
logs
|
||||||
|
_.log
|
||||||
|
report.[0-9]_.[0-9]_.[0-9]_.[0-9]_.json
|
||||||
|
|
||||||
|
# dotenv environment variable files
|
||||||
|
.env
|
||||||
|
.env.development.local
|
||||||
|
.env.test.local
|
||||||
|
.env.production.local
|
||||||
|
.env.local
|
||||||
|
|
||||||
|
# caches
|
||||||
|
.eslintcache
|
||||||
|
.cache
|
||||||
|
*.tsbuildinfo
|
||||||
|
|
||||||
|
# IntelliJ based IDEs
|
||||||
|
.idea
|
||||||
|
|
||||||
|
# Finder (MacOS) folder config
|
||||||
|
.DS_Store
|
61
packages/server/Containerfile
Normal file
61
packages/server/Containerfile
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
# Stage 1: Builder
|
||||||
|
# This stage installs all dependencies and builds all packages.
|
||||||
|
FROM oven/bun:1 AS builder
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
# Copy dependency manifests
|
||||||
|
COPY package.json bun.lock ./
|
||||||
|
COPY tsconfig.base.json ./
|
||||||
|
|
||||||
|
# Copy package-specific manifests to leverage Docker cache
|
||||||
|
COPY packages/shared/package.json packages/shared/tsconfig.json ./packages/shared/
|
||||||
|
COPY packages/server/package.json packages/server/tsconfig.json ./packages/server/
|
||||||
|
|
||||||
|
# Install ALL workspace dependencies
|
||||||
|
RUN bun install
|
||||||
|
|
||||||
|
# Copy source code
|
||||||
|
COPY packages/shared ./packages/shared/
|
||||||
|
COPY packages/server ./packages/server/
|
||||||
|
|
||||||
|
# Build the server and its dependencies (i.e., 'shared')
|
||||||
|
RUN bun run --filter=@hnu.de/hl7v2-shared build
|
||||||
|
RUN bun run --filter=@hnu.de/hl7v2-server build
|
||||||
|
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------
|
||||||
|
|
||||||
|
# Stage 2: Production
|
||||||
|
FROM oven/bun:1-slim
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
# Create the full directory structure first
|
||||||
|
RUN mkdir -p packages/shared packages/server
|
||||||
|
|
||||||
|
# Copy workspace configuration
|
||||||
|
COPY --from=builder /app/package.json /app/bun.lock ./
|
||||||
|
|
||||||
|
# Set up shared package with its dist directory
|
||||||
|
COPY --from=builder /app/packages/shared/package.json ./packages/shared/
|
||||||
|
COPY --from=builder /app/packages/shared/dist ./packages/shared/dist
|
||||||
|
|
||||||
|
# Set up server package with its dist directory
|
||||||
|
COPY --from=builder /app/packages/server/package.json ./packages/server/
|
||||||
|
COPY --from=builder /app/packages/server/dist ./packages/server/dist
|
||||||
|
|
||||||
|
# Install ONLY production dependencies
|
||||||
|
ENV NODE_ENV=production
|
||||||
|
RUN bun install \
|
||||||
|
--frozen-lockfile \
|
||||||
|
--production
|
||||||
|
|
||||||
|
# Set environment variables from config.ts
|
||||||
|
ENV PORT=8080 \
|
||||||
|
PREFIXES=STA \
|
||||||
|
POOL_SIZE=100
|
||||||
|
|
||||||
|
EXPOSE 8080
|
||||||
|
|
||||||
|
# Run the server from its package directory
|
||||||
|
WORKDIR /app/packages/server
|
||||||
|
CMD ["bun", "run", "dist/index.js"]
|
23
packages/server/config.ts
Normal file
23
packages/server/config.ts
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
interface Config {
|
||||||
|
port: number;
|
||||||
|
prefixes: string[];
|
||||||
|
poolSize: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const config: Config = {
|
||||||
|
port: parseInt(process.env.PORT || '8080', 10),
|
||||||
|
prefixes: (process.env.PREFIXES || 'STA').split(","),
|
||||||
|
poolSize: parseInt(process.env.POOL_SIZE || '100', 10),
|
||||||
|
};
|
||||||
|
|
||||||
|
if (isNaN(config.port) || config.port < 1024 || config.port > 49151) {
|
||||||
|
throw new Error('Invalid PORT environment variable (1024 - 49151)');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (config.prefixes.length === 0) {
|
||||||
|
throw new Error('Invalid PREFIXES environment variable (length > 1)');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isNaN(config.poolSize) || config.poolSize < config.prefixes.length) {
|
||||||
|
throw new Error('Invalid PORT environment variable (poolSize >= prefix.length)');
|
||||||
|
}
|
160
packages/server/index.ts
Normal file
160
packages/server/index.ts
Normal file
|
@ -0,0 +1,160 @@
|
||||||
|
import { WebSocketServer } from 'ws';
|
||||||
|
import { type Message, MessageType } from '@hnu.de/hl7v2-shared';
|
||||||
|
import 'dotenv/config';
|
||||||
|
import { config } from './config';
|
||||||
|
|
||||||
|
|
||||||
|
// ###########################################################################
|
||||||
|
// ### ID Pool
|
||||||
|
// ###########################################################################
|
||||||
|
|
||||||
|
let availableIds: string[] = [];
|
||||||
|
|
||||||
|
for (const prefix of config.prefixes) {
|
||||||
|
for (let i = 1; i <= config.poolSize / config.prefixes.length; i++) {
|
||||||
|
const number = i.toString().padStart(config.poolSize.toString().length, '0');
|
||||||
|
availableIds.push(`${prefix}-${number}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function shake(arr: any[]) {
|
||||||
|
for (let i = arr.length - 1; i > 0; i--) {
|
||||||
|
const j = Math.floor(Math.random() * (i + 1));
|
||||||
|
[arr[i], arr[j]] = [arr[j], arr[i]];
|
||||||
|
}
|
||||||
|
return arr;
|
||||||
|
}
|
||||||
|
|
||||||
|
availableIds = shake(availableIds);
|
||||||
|
|
||||||
|
|
||||||
|
// ###########################################################################
|
||||||
|
// ### Websocket Server
|
||||||
|
// ###########################################################################
|
||||||
|
|
||||||
|
const wss = new WebSocketServer({ port: config.port });
|
||||||
|
|
||||||
|
const clients = new Map();
|
||||||
|
|
||||||
|
console.log(`Starting WebSocket server ...`);
|
||||||
|
|
||||||
|
console.log("Server configuration:", config);
|
||||||
|
|
||||||
|
wss.on('connection', (ws) => {
|
||||||
|
|
||||||
|
// check for available IDs
|
||||||
|
if (availableIds.length === 0) {
|
||||||
|
console.log('Connection rejected: No available IDs.');
|
||||||
|
ws.close(1013, 'Server is full. Please try again later.'); // 1013: Try again later
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// get ID from pool and assign to user
|
||||||
|
const userId = availableIds.pop();
|
||||||
|
if (!userId) {
|
||||||
|
console.log('Connection rejected: Failed to retrieve ID.');
|
||||||
|
ws.close(1013, 'Server is full. Please try again later.'); // 1013: Try again later
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// store client in map
|
||||||
|
clients.set(userId, ws);
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
// send user ID to client
|
||||||
|
const welcomeMessage = {
|
||||||
|
type: 'assign_id',
|
||||||
|
payload: {
|
||||||
|
userId: userId,
|
||||||
|
},
|
||||||
|
} as Message;
|
||||||
|
ws.send(JSON.stringify(welcomeMessage));
|
||||||
|
|
||||||
|
console.log(`Client connected. Assigning ID: ${userId}`);
|
||||||
|
}, 0);
|
||||||
|
|
||||||
|
ws.on('message', (message) => {
|
||||||
|
try {
|
||||||
|
|
||||||
|
const parsedMessage: Message = JSON.parse(message.toString());
|
||||||
|
console.log(`Received message from ${userId}:`, parsedMessage);
|
||||||
|
|
||||||
|
// We only expect one type of message from clients: 'send_hl7v2'
|
||||||
|
if (parsedMessage.type === MessageType.send_hl7v2) {
|
||||||
|
|
||||||
|
const { message } = parsedMessage.payload;
|
||||||
|
// TODO: validate message
|
||||||
|
|
||||||
|
// get sender and recipient ID
|
||||||
|
const recipientId = parseMshField(message, 5);
|
||||||
|
if (!recipientId) {
|
||||||
|
const errorMessage = {
|
||||||
|
type: 'delivery_error',
|
||||||
|
payload: {
|
||||||
|
error: `Message is missing header field 5.`,
|
||||||
|
},
|
||||||
|
} as Message;
|
||||||
|
ws.send(JSON.stringify(errorMessage));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find the recipient's WebSocket connection in our map.
|
||||||
|
const recipientWs = clients.get(recipientId);
|
||||||
|
|
||||||
|
if (recipientWs && recipientWs.readyState === WebSocket.OPEN) {
|
||||||
|
|
||||||
|
// The recipient is connected. Forward the message.
|
||||||
|
const forwardMessage = {
|
||||||
|
type: MessageType.receive_hl7v2,
|
||||||
|
payload: {
|
||||||
|
message: message,
|
||||||
|
timestamp: new Date().toISOString(),
|
||||||
|
},
|
||||||
|
} as Message;
|
||||||
|
recipientWs.send(JSON.stringify(forwardMessage));
|
||||||
|
console.log(`Forwarded message to ${recipientId}`);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
// The recipient is not connected or not found.
|
||||||
|
console.log(`Recipient ${recipientId} not found or not connected.`);
|
||||||
|
const errorMessage = {
|
||||||
|
type: MessageType.delivery_error,
|
||||||
|
payload: {
|
||||||
|
error: `Station with ID ${recipientId} is not available.`,
|
||||||
|
},
|
||||||
|
} as Message;
|
||||||
|
ws.send(JSON.stringify(errorMessage));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`Failed to process message from ${userId}:`, error);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// listen to disconnects to free IDs
|
||||||
|
ws.on('close', () => {
|
||||||
|
console.log(`Client ${userId} disconnected.`);
|
||||||
|
clients.delete(userId);
|
||||||
|
if (userId) {
|
||||||
|
availableIds.push(userId);
|
||||||
|
}
|
||||||
|
availableIds = shake(availableIds);
|
||||||
|
});
|
||||||
|
|
||||||
|
ws.on('error', (error) => {
|
||||||
|
console.error(`WebSocket error for client ${userId}:`, error);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
function parseMshField(message: string, fieldIndex: number) {
|
||||||
|
try {
|
||||||
|
const mshLine = message.split(/[\r\n]+/)[0];
|
||||||
|
if (!mshLine || !mshLine.startsWith('MSH')) return null;
|
||||||
|
const fields = mshLine.split('|');
|
||||||
|
return fields[fieldIndex] || null;
|
||||||
|
} catch (e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(`WebSocket server started on port ${config.port}`);
|
21
packages/server/package.json
Normal file
21
packages/server/package.json
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
{
|
||||||
|
"name": "@hnu.de/hl7v2-server",
|
||||||
|
"module": "index.ts",
|
||||||
|
"type": "module",
|
||||||
|
"private": true,
|
||||||
|
"scripts": {
|
||||||
|
"build": "tsc",
|
||||||
|
"dev": "bun --watch index.ts --watch config.ts",
|
||||||
|
"start": "bun index.ts"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@types/bun": "latest",
|
||||||
|
"@types/ws": "^8.18.1",
|
||||||
|
"typescript": "^5.8.3",
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@hnu.de/hl7v2-shared": "workspace:*",
|
||||||
|
"dotenv": "^17.2.0",
|
||||||
|
"ws": "^8.18.3"
|
||||||
|
}
|
||||||
|
}
|
19
packages/server/tsconfig.json
Normal file
19
packages/server/tsconfig.json
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
{
|
||||||
|
"extends": "../../tsconfig.base.json",
|
||||||
|
"compilerOptions": {
|
||||||
|
"outDir": "./dist",
|
||||||
|
"declaration": true,
|
||||||
|
"strict": true,
|
||||||
|
"skipLibCheck": true,
|
||||||
|
"noFallthroughCasesInSwitch": true,
|
||||||
|
"noUncheckedIndexedAccess": true,
|
||||||
|
"noImplicitOverride": true
|
||||||
|
},
|
||||||
|
"include": [
|
||||||
|
"*.ts"
|
||||||
|
],
|
||||||
|
"exclude": [
|
||||||
|
"node_modules",
|
||||||
|
"dist"
|
||||||
|
]
|
||||||
|
}
|
34
packages/shared/.gitignore
vendored
Normal file
34
packages/shared/.gitignore
vendored
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
# dependencies (bun install)
|
||||||
|
node_modules
|
||||||
|
|
||||||
|
# output
|
||||||
|
out
|
||||||
|
dist
|
||||||
|
*.tgz
|
||||||
|
|
||||||
|
# code coverage
|
||||||
|
coverage
|
||||||
|
*.lcov
|
||||||
|
|
||||||
|
# logs
|
||||||
|
logs
|
||||||
|
_.log
|
||||||
|
report.[0-9]_.[0-9]_.[0-9]_.[0-9]_.json
|
||||||
|
|
||||||
|
# dotenv environment variable files
|
||||||
|
.env
|
||||||
|
.env.development.local
|
||||||
|
.env.test.local
|
||||||
|
.env.production.local
|
||||||
|
.env.local
|
||||||
|
|
||||||
|
# caches
|
||||||
|
.eslintcache
|
||||||
|
.cache
|
||||||
|
*.tsbuildinfo
|
||||||
|
|
||||||
|
# IntelliJ based IDEs
|
||||||
|
.idea
|
||||||
|
|
||||||
|
# Finder (MacOS) folder config
|
||||||
|
.DS_Store
|
16
packages/shared/package.json
Normal file
16
packages/shared/package.json
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
{
|
||||||
|
"name": "@hnu.de/hl7v2-shared",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"main": "./dist/types.js",
|
||||||
|
"types": "./dist/types.d.ts",
|
||||||
|
"type": "module",
|
||||||
|
"scripts": {
|
||||||
|
"build": "tsc"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@types/bun": "latest",
|
||||||
|
"@types/node": "^24.1.0",
|
||||||
|
"typescript": "^5.8.3"
|
||||||
|
},
|
||||||
|
"private": true
|
||||||
|
}
|
19
packages/shared/tsconfig.json
Normal file
19
packages/shared/tsconfig.json
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
{
|
||||||
|
"extends": "../../tsconfig.base.json",
|
||||||
|
"compilerOptions": {
|
||||||
|
"outDir": "./dist",
|
||||||
|
"declaration": true,
|
||||||
|
"strict": true,
|
||||||
|
"skipLibCheck": true,
|
||||||
|
"noFallthroughCasesInSwitch": true,
|
||||||
|
"noUncheckedIndexedAccess": true,
|
||||||
|
"noImplicitOverride": true
|
||||||
|
},
|
||||||
|
"include": [
|
||||||
|
"*.ts"
|
||||||
|
],
|
||||||
|
"exclude": [
|
||||||
|
"node_modules",
|
||||||
|
"dist"
|
||||||
|
]
|
||||||
|
}
|
20
packages/shared/types.ts
Normal file
20
packages/shared/types.ts
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
export enum ConnectionState {
|
||||||
|
connecting = 'connecting',
|
||||||
|
connected = 'connected',
|
||||||
|
disconnected = 'disconnected',
|
||||||
|
}
|
||||||
|
|
||||||
|
export enum MessageType {
|
||||||
|
assign_id = 'assign_id',
|
||||||
|
send_hl7v2 = 'send_hl7v2',
|
||||||
|
receive_hl7v2 = 'receive_hl7v2',
|
||||||
|
delivery_error = 'delivery_error',
|
||||||
|
}
|
||||||
|
|
||||||
|
export type Message =
|
||||||
|
| { type: MessageType.assign_id, payload: { userId: string }}
|
||||||
|
| { type: MessageType.send_hl7v2, payload: { message: string }}
|
||||||
|
| { type: MessageType.receive_hl7v2, payload: { message: string, timestamp: string }}
|
||||||
|
| { type: MessageType.delivery_error, payload: { error: string }}
|
||||||
|
|
||||||
|
export type ReceiveHl7v2Message = Extract<Message, { type: MessageType.receive_hl7v2 }>;
|
11
tsconfig.base.json
Normal file
11
tsconfig.base.json
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"target": "ESNext",
|
||||||
|
"module": "ESNext",
|
||||||
|
"moduleResolution": "bundler",
|
||||||
|
"strict": true,
|
||||||
|
"paths": {
|
||||||
|
"@hnu.de/hl7v2-shared/*": ["./packages/shared/*"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue