diff --git a/PROJECT.md b/PROJECT.md
new file mode 100644
index 0000000..1abf397
--- /dev/null
+++ b/PROJECT.md
@@ -0,0 +1,37 @@
+## Status
+### Last Completed
+Worked on the (Feature List)[#feature-list]
+
+### Next Up
+Start building the database structure or the app layout and structure
+
+## Feature List
+### Must Haves
+- Events
+ - Event guests (related to Guests)
+ - Related guest (for +1s)
+ - RSVP status
+ - To Do list
+ - Event Vendor (related to Vendors)
+ - Event Venue (related to Venues)
+ - General Notes
+- Guests (address book)
+- Vendors
+ - Contact info
+ - Contracts
+- Venues
+ - Contact info
+ - Contracts
+### Eventual Features
+- Registry (related to Events)
+ - Ability to upload any url
+ - Redirects
+ - Convert url to `BASE_URL.com/[EVENT_SLUG]/registry/[item123]` which redirects to actually link
+
+## Decisions Log
+At the top level the guest book will contain "Households". Every guest will belong to a household even if they are alone. This will allow for Guests to RSVP for everyone in their household.
+
+For guests that are given a +1, there will be a placeholder name added as a Guest `"Guest of [NAME]"`. And a flag will be added to that guest entry. When responding to the RSVP, there will be an option to fill in the +1's name.
+
+
+## Open Questions
\ No newline at end of file
diff --git a/bun.lock b/bun.lock
index 594001c..f1ebf92 100644
--- a/bun.lock
+++ b/bun.lock
@@ -5,32 +5,47 @@
"": {
"name": "planner",
"devDependencies": {
+ "@dnd-kit-svelte/svelte": "^0.1.5",
+ "@dnd-kit/abstract": "^0.1.21",
+ "@dnd-kit/helpers": "^0.1.21",
"@eslint/js": "^10.0.1",
"@fontsource-variable/inter": "^5.3.0",
+ "@internationalized/date": "^3.12.0",
"@lucide/svelte": "^1.52.0",
"@sveltejs/adapter-auto": "^8.0.0",
"@sveltejs/kit": "^3.0.0",
"@sveltejs/vite-plugin-svelte": "^7.2.0",
+ "@tabler/icons-svelte": "^3.40.0",
"@tailwindcss/typography": "^0.5.19",
"@tailwindcss/vite": "^4.3.0",
+ "@tanstack/svelte-table": "^9.0.0",
+ "@types/d3-scale": "^4.0.9",
+ "@types/d3-shape": "^3.1.8",
"@types/node": "^26",
+ "bits-ui": "^2.18.0",
"cn": "^0.3.0",
+ "d3-scale": "^4.0.2",
+ "d3-shape": "^3.2.0",
"eslint": "^10.4.1",
"eslint-config-prettier": "^10.1.8",
"eslint-plugin-svelte": "^3.19.0",
"globals": "^17.6.0",
+ "layerchart": "^2.0.0",
"prettier": "^3.8.3",
"prettier-plugin-svelte": "^4.1.0",
"prettier-plugin-tailwindcss": "^0.8.0",
"shadcn-svelte": "^1.7.0",
"svelte": "^5.57.1",
"svelte-check": "^4.6.0",
+ "svelte-sonner": "^1.2.0",
"tailwind-variants": "^3.3.1",
"tailwindcss": "^4.3.0",
"tw-animate-css": "^1.4.0",
"typescript": "^6.0.3",
"typescript-eslint": "^8.60.1",
+ "vaul-svelte": "^1.0.0-next.7",
"vite": "^8.3.0",
+ "zod": "^4.4.3",
},
},
},
@@ -39,6 +54,24 @@
"@cacheable/utils": ["@cacheable/utils@2.5.0", "", { "dependencies": { "hashery": "^1.5.1", "keyv": "^5.6.0" } }, "sha512-buipgOVDkkPXNR5+xBpDw7Zk2n1EvU7qBJCNUcL7rhQ//kfpOXPAvQ511Os0vpLYJ1pZnvudNytkQt2hst3wqA=="],
+ "@dagrejs/dagre": ["@dagrejs/dagre@2.0.4", "", { "dependencies": { "@dagrejs/graphlib": "3.0.4" } }, "sha512-J6vCWTNpicHF4zFlZG1cS5DkGzMr9941gddYkakjrg3ZNev4bbqEgLHFTWiFrcJm7UCRu7olO3K6IRDd9gSGhA=="],
+
+ "@dagrejs/graphlib": ["@dagrejs/graphlib@3.0.4", "", {}, "sha512-HxZ7fCvAwTLCWCO0WjDkzAFQze8LdC6iOpKbetDKHIuDfIgMlIzYzqZ4nxwLlclQX+3ZVeZ1K2OuaOE2WWcyOg=="],
+
+ "@dnd-kit-svelte/svelte": ["@dnd-kit-svelte/svelte@0.1.6", "", { "dependencies": { "@dnd-kit/abstract": "^0.2.3", "@dnd-kit/collision": "^0.2.3", "@dnd-kit/dom": "^0.2.3", "@dnd-kit/geometry": "^0.1.21", "@dnd-kit/state": "^0.2.3" }, "peerDependencies": { "svelte": "^5.0.0" } }, "sha512-kpmNWeQoPFrJ4SNB0thRkdWtN3kiYMQI/SvEj6MTKTQ8W5VyHBrbXDRm+mdiTj9tzmG8jgCPg+Fgp3aYIU+Hug=="],
+
+ "@dnd-kit/abstract": ["@dnd-kit/abstract@0.1.21", "", { "dependencies": { "@dnd-kit/geometry": "^0.1.21", "@dnd-kit/state": "^0.1.21", "tslib": "^2.6.2" } }, "sha512-6sJut6/D21xPIK8EFMu+JJeF+fBCOmQKN1BRpeUYFi5m9P1CJpTYbBwfI107h7PHObI6a5bsckiKkRpF2orHpw=="],
+
+ "@dnd-kit/collision": ["@dnd-kit/collision@0.2.4", "", { "dependencies": { "@dnd-kit/abstract": "^0.2.4", "@dnd-kit/geometry": "^0.2.4", "tslib": "^2.6.2" } }, "sha512-w8Vzq8MKu8MYvrwtasqQhw2l27v9eRMzL+jOdj8Qp0jnPQ1FICGgUwjAStZ87wO1Pc2WIt0rQWDDPIEyRd6S8A=="],
+
+ "@dnd-kit/dom": ["@dnd-kit/dom@0.2.4", "", { "dependencies": { "@dnd-kit/abstract": "^0.2.4", "@dnd-kit/collision": "^0.2.4", "@dnd-kit/geometry": "^0.2.4", "@dnd-kit/state": "^0.2.4", "tslib": "^2.6.2" } }, "sha512-ZYIJgx/uyZvmGOHPBDbIeJfqa2xlEUHnkHEHcKlR/VMQz9NoSkPGcjPdcAjpwB+T4dleRQ4tZ8h9X5I3UdTQPw=="],
+
+ "@dnd-kit/geometry": ["@dnd-kit/geometry@0.1.21", "", { "dependencies": { "@dnd-kit/state": "^0.1.21", "tslib": "^2.6.2" } }, "sha512-Tir97wNJbopN2HgkD7AjAcoB3vvrVuUHvwdPALmNDUH0fWR637c4MKQ66YjjZAbUEAR8KL6mlDiHH4MzTLd7CQ=="],
+
+ "@dnd-kit/helpers": ["@dnd-kit/helpers@0.1.21", "", { "dependencies": { "@dnd-kit/abstract": "^0.1.21", "tslib": "^2.6.2" } }, "sha512-yAFOcGaef8OqGJW/sHWnJn77b1Qe00f9ByPm19gNSEDH3/sgDszug7OwvqjoFAEnsDiKwdTgGYsPoyLSnrlprA=="],
+
+ "@dnd-kit/state": ["@dnd-kit/state@0.2.4", "", { "dependencies": { "@preact/signals-core": "^1.10.0", "tslib": "^2.6.2" } }, "sha512-mPtQfmqBZBcVKa+Fi8AV2ocQWa+phvZa9Muq3PxFM3WIyjrFiEosGGPiPcx5hC3K+i2gkmr6Msc7iPrrpYkB5g=="],
+
"@eslint-community/eslint-utils": ["@eslint-community/eslint-utils@4.10.1", "", { "dependencies": { "eslint-visitor-keys": "^3.4.3" }, "peerDependencies": { "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" } }, "sha512-cuadcxVFE8sDK6iWJbs8Sn0av2Nrh2QSGQhVlBW9AaAHqHwjWsZHT8LJ4hFGPh7ASBV2deFdM7H/DPjulmh8rg=="],
"@eslint-community/regexpp": ["@eslint-community/regexpp@4.12.2", "", {}, "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew=="],
@@ -55,6 +88,12 @@
"@eslint/plugin-kit": ["@eslint/plugin-kit@0.7.3", "", { "dependencies": { "@eslint/core": "^1.2.1", "levn": "^0.4.1" } }, "sha512-IkO+/KEUvwbVpiURZg+P7zF74z5Jxe0UgJxVni+RtoHQ6IZieXaO02kmadomap/q+l6bc/jdPGGqTjhuZnuz1Q=="],
+ "@floating-ui/core": ["@floating-ui/core@1.8.0", "", { "dependencies": { "@floating-ui/utils": "^0.2.12" } }, "sha512-0CIZ5itps/8x7BG8dEIhs53BvCUH2PCoogtakwRTut+Arm58sJooJ0AuZhLw2HJYIR5cMLNPBSS728sPho2khQ=="],
+
+ "@floating-ui/dom": ["@floating-ui/dom@1.8.0", "", { "dependencies": { "@floating-ui/core": "^1.8.0", "@floating-ui/utils": "^0.2.12" } }, "sha512-yXSrzeHZBTZadLOlfyhCkJHNeLJnHRnRInwdZ40L7ZiaAtrBwoYlsDrX3v5zB1Utk7CLfzcOVnVVWoXEky7Ceg=="],
+
+ "@floating-ui/utils": ["@floating-ui/utils@0.2.12", "", {}, "sha512-HpCo8tmWzLVad5s2d19EhAz5zqrrQ6s69qd6moPMQvkOuSwDT1YgRfWSVuc4ennqrgv3OHppiOGMQ7oC13yIww=="],
+
"@fontsource-variable/inter": ["@fontsource-variable/inter@5.3.0", "", {}, "sha512-OupL48va4JNofb97w6NYeF9S7W/kHNKM0Er8Dem5nqi4jeOLrVJDoE8tZEpnMJmtkvNbB1EIPPwHcdkF6b1oUA=="],
"@humanfs/core": ["@humanfs/core@0.19.2", "", { "dependencies": { "@humanfs/types": "^0.15.0" } }, "sha512-UhXNm+CFMWcbChXywFwkmhqjs3PRCmcSa/hfBgLIb7oQ5HNb1wS0icWsGtSAUNgefHeI+eBrA8I1fxmbHsGdvA=="],
@@ -67,6 +106,8 @@
"@humanwhocodes/retry": ["@humanwhocodes/retry@0.4.3", "", {}, "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ=="],
+ "@internationalized/date": ["@internationalized/date@3.12.4", "", { "dependencies": { "@swc/helpers": "^0.5.0" } }, "sha512-M1dEn4c1U1HsSlaVR8upZtSqvXrTkHDfv18H01uCSJyjVLDxnBR38v/fMxecmlwXKR4i9HeZcmgQAPE6A+aGJQ=="],
+
"@jridgewell/gen-mapping": ["@jridgewell/gen-mapping@0.3.13", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.0", "@jridgewell/trace-mapping": "^0.3.24" } }, "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA=="],
"@jridgewell/remapping": ["@jridgewell/remapping@2.3.5", "", { "dependencies": { "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.24" } }, "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ=="],
@@ -81,12 +122,22 @@
"@keyv/serialize": ["@keyv/serialize@1.1.1", "", {}, "sha512-dXn3FZhPv0US+7dtJsIi2R+c7qWYiReoEh5zUntWCf4oSpMNib8FDhSoed6m3QyZdx5hK7iLFkYk3rNxwt8vTA=="],
+ "@layerstack/svelte-actions": ["@layerstack/svelte-actions@1.0.1-next.20", "", { "dependencies": { "@floating-ui/dom": "^1.7.0", "@layerstack/utils": "2.0.0-next.19", "d3-scale": "^4.0.2" } }, "sha512-OtFteDyvTUR6F7dSKPkpD/S77K7vbCHStApSlx8djJBxDKJHU3zxA4gYP6Z71Nc6HB/wLCfjZopkvxnMblbRRw=="],
+
+ "@layerstack/svelte-state": ["@layerstack/svelte-state@0.1.0-next.25", "", { "dependencies": { "@layerstack/utils": "2.0.0-next.19" } }, "sha512-K+SO4dYd2D9OSCnj92Ugo6i5OfVKZoHHA1DA7gs2ynigylRKInicniGI/OmRpp+002n3mhE/i2r3Kfctj8eAdw=="],
+
+ "@layerstack/tailwind": ["@layerstack/tailwind@2.0.0-next.21", "", { "dependencies": { "@layerstack/utils": "^2.0.0-next.18", "clsx": "^2.1.1", "d3-array": "^3.2.4", "tailwind-merge": "^3.2.0" } }, "sha512-Qgp2EpmEHmjtura8MQzWicR6ztBRSsRvddakFtx9ShrLMz6jWzd6bCMVVRu44Q3ZOrtXmSu4QxjCZWu1ytvuPg=="],
+
+ "@layerstack/utils": ["@layerstack/utils@2.0.0-next.19", "", { "dependencies": { "d3-array": "^3.2.4", "d3-time": "^3.1.0", "d3-time-format": "^4.1.0" } }, "sha512-HyXCEz9pge4rFWklrSgFr3YIwdE1gP8WM6GPetmnKPDfYLF1/oetRFKI9FqiE+dw4brnULGPKJsVhjM3vQfD4A=="],
+
"@lucide/svelte": ["@lucide/svelte@1.52.0", "", { "peerDependencies": { "svelte": "^5" } }, "sha512-bQ8t3IcZxWqAdmdMZPyZEv8Qf+MDgBAf7n43eRQoXyBeLWr8HWToiMIO6vKlHxC/lnMiCDdTzm09hjy92ch46A=="],
"@oxc-project/types": ["@oxc-project/types@0.152.0", "", {}, "sha512-oM/5rLBm2tPkg0iBgkH/FOeR3PCDpY19GTgAZjMFM8h9WI9VW7cLgzp6nwtarYKmovavIQZ+Fe/RKX/8C8O/Rw=="],
"@polka/url": ["@polka/url@1.0.0-next.29", "", {}, "sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww=="],
+ "@preact/signals-core": ["@preact/signals-core@1.14.4", "", {}, "sha512-HNB6HYeYKhQbJ1aKl+YRjrS4+QWHLKX6qKoUsfS/m0vqzsVaEBiZiaKbG/e+NKk2ch5ALQr/ihWaMHxiCuuWHA=="],
+
"@rolldown/binding-android-arm-eabi": ["@rolldown/binding-android-arm-eabi@1.2.12", "", { "os": "android", "cpu": "arm" }, "sha512-dB/a1214qKfHMXCpgqR4OZT+jS4kTyEXbQGJPqzobt5EwH5rX080pxE37alt3RzvR1bf1Yz/yGqRfrYAxuPw0A=="],
"@rolldown/binding-android-arm64": ["@rolldown/binding-android-arm64@1.2.12", "", { "os": "android", "cpu": "arm64" }, "sha512-7KHFgQ5VJxIHcLlrwrc3Xbds7oTNQT7Pgi9gQCJKrd2VGab/UksIOYp6VD8MzCstGxOKMgNamPwUCfxPdP1OHg=="],
@@ -131,6 +182,12 @@
"@sveltejs/vite-plugin-svelte": ["@sveltejs/vite-plugin-svelte@7.3.1", "", { "dependencies": { "deepmerge": "^4.3.1", "magic-string": "^1.0.0", "obug": "^2.1.0", "vitefu": "^1.1.2" }, "peerDependencies": { "svelte": "^5.46.4", "vite": "^8.0.0-beta.7 || ^8.0.0" } }, "sha512-ZPsLN8B1e/En+Ak5s4V7srFDT532oS0qieLsQwu63NGKsS+iAjoO2Js1BochlHlglcU+Pt7WAO3C5Ee+4f6gVA=="],
+ "@swc/helpers": ["@swc/helpers@0.5.23", "", { "dependencies": { "tslib": "^2.8.0" } }, "sha512-5lSsMOTXURePglDfvuAQUqkGek9Hg2kksOYay2m0+XR++b2NWYL/4sWyuvVBIs8oKnJaxkdi9whaL/sqN13afw=="],
+
+ "@tabler/icons": ["@tabler/icons@3.49.0", "", {}, "sha512-l+GnSkFETx0U26icxv1VUFnxxiTqXfCcVRiRAnyMwibupM2S2L/hSaZ9gmSgz01rkrsH/93NvLsxykqdanc6lw=="],
+
+ "@tabler/icons-svelte": ["@tabler/icons-svelte@3.49.0", "", { "dependencies": { "@tabler/icons": "3.49.0" }, "peerDependencies": { "svelte": ">=3 <6 || >=5.0.0-next.0" } }, "sha512-+omJWDCEHHfloOoMELXkdlrIpoQCN2XBx2xnb2NxqDjxsAGGTii0UQF05UoKiUO97skqe1eEIbeGjRZ9xUye0w=="],
+
"@tailwindcss/node": ["@tailwindcss/node@4.3.3", "", { "dependencies": { "@jridgewell/remapping": "^2.3.5", "enhanced-resolve": "^5.24.1", "jiti": "^2.7.0", "lightningcss": "1.32.0", "magic-string": "^0.30.21", "source-map-js": "^1.2.1", "tailwindcss": "4.3.3" } }, "sha512-/T8IKEsf9VTU6tLjgC7+sv2mOPtQxzE2jMw7u4Tt40Tx+QSZxpzh95/H6cMKoja9XuW7iMdLJYBB0o9G1CaAgg=="],
"@tailwindcss/oxide": ["@tailwindcss/oxide@4.3.3", "", { "optionalDependencies": { "@tailwindcss/oxide-android-arm64": "4.3.3", "@tailwindcss/oxide-darwin-arm64": "4.3.3", "@tailwindcss/oxide-darwin-x64": "4.3.3", "@tailwindcss/oxide-freebsd-x64": "4.3.3", "@tailwindcss/oxide-linux-arm-gnueabihf": "4.3.3", "@tailwindcss/oxide-linux-arm64-gnu": "4.3.3", "@tailwindcss/oxide-linux-arm64-musl": "4.3.3", "@tailwindcss/oxide-linux-x64-gnu": "4.3.3", "@tailwindcss/oxide-linux-x64-musl": "4.3.3", "@tailwindcss/oxide-wasm32-wasi": "4.3.3", "@tailwindcss/oxide-win32-arm64-msvc": "4.3.3", "@tailwindcss/oxide-win32-x64-msvc": "4.3.3" } }, "sha512-krXjAikiaFSPaK/FkAQT5UTx3VormQaiZ5hBFlJZ9UFQGB/rwg1MZIhHAG9smMQRTdyJxP6Qt5MwMtdyU5FWrA=="],
@@ -163,10 +220,32 @@
"@tailwindcss/vite": ["@tailwindcss/vite@4.3.3", "", { "dependencies": { "@tailwindcss/node": "4.3.3", "@tailwindcss/oxide": "4.3.3", "tailwindcss": "4.3.3" }, "peerDependencies": { "vite": "^5.2.0 || ^6 || ^7 || ^8" } }, "sha512-yYU8cogLeSh/ms2jh8Fj7jaba/EWa7Ja6GoUqYZaraEuCI5YS6ms6ObZgjjedm+jm6XZjdNRWBpPP6Z86oOxcw=="],
+ "@tanstack/store": ["@tanstack/store@0.11.2", "", {}, "sha512-sJ4mjol8uQsHV0gOJzzjwXfh2Fwm+Sz0+8deqiTm4jGbMdjzNSW+xZCFm0kUa870uhd8yi+DpKnZb5Kc4apa0Q=="],
+
+ "@tanstack/svelte-store": ["@tanstack/svelte-store@0.12.2", "", { "dependencies": { "@tanstack/store": "0.11.2" }, "peerDependencies": { "svelte": "^5.0.0" } }, "sha512-zI+LjpxnbfKm5vDogx07RN12oOuI6LR+GysrQ4aVCuw76pY8pwcPT2DU9JGIX+L+r1dzsxBGac8XZETzLGQxiA=="],
+
+ "@tanstack/svelte-table": ["@tanstack/svelte-table@9.2.6", "", { "dependencies": { "@tanstack/svelte-store": "^0.12.2", "@tanstack/table-core": "9.2.6" }, "peerDependencies": { "svelte": "^5.0.0" } }, "sha512-+enojkMPHDwX9W1D9R2ZeBQt2K+6vWp6mhHdsapGtLgmXb7sDLQmYPvq/rE4K9o+MBUVqmaq++UV/1h2/Iw83Q=="],
+
+ "@tanstack/table-core": ["@tanstack/table-core@9.2.6", "", { "dependencies": { "@tanstack/store": "^0.11.2" } }, "sha512-t5LaLx8gDCgzjvwtZo5xtLklJP11D9zaKOW8q6jOCyuQYhkqpTK1heqMfgTQwDlhl0dU8f1X66Xurbj3jpCUSw=="],
+
+ "@types/d3-array": ["@types/d3-array@3.2.2", "", {}, "sha512-hOLWVbm7uRza0BYXpIIW5pxfrKe0W+D5lrFiAEYR+pb6w3N2SwSMaJbXdUfSEv+dT4MfHBLtn5js0LAWaO6otw=="],
+
+ "@types/d3-contour": ["@types/d3-contour@3.0.6", "", { "dependencies": { "@types/d3-array": "*", "@types/geojson": "*" } }, "sha512-BjzLgXGnCWjUSYGfH1cpdo41/hgdWETu4YxpezoztawmqsvCeep+8QGfiY6YbDvfgHz/DkjeIkkZVJavB4a3rg=="],
+
+ "@types/d3-path": ["@types/d3-path@3.1.1", "", {}, "sha512-VMZBYyQvbGmWyWVea0EHs/BwLgxc+MKi1zLDCONksozI4YJMcTt8ZEuIR4Sb1MMTE8MMW49v0IwI5+b7RmfWlg=="],
+
+ "@types/d3-scale": ["@types/d3-scale@4.0.9", "", { "dependencies": { "@types/d3-time": "*" } }, "sha512-dLmtwB8zkAeO/juAMfnV+sItKjlsw2lKdZVVy6LRr0cBmegxSABiLEpGVmSJJ8O08i4+sGR6qQtb6WtuwJdvVw=="],
+
+ "@types/d3-shape": ["@types/d3-shape@3.2.0", "", { "dependencies": { "@types/d3-path": "*" } }, "sha512-kVd74ta9eof3eJOvbNd1vGKS/XERRyQbT26Og63hIsvDO84cjD5gEOhsXf26w3FSoNlPVz84DOFcKv/oou+fMw=="],
+
+ "@types/d3-time": ["@types/d3-time@3.0.4", "", {}, "sha512-yuzZug1nkAAaBlBBikKZTgzCeA+k1uy4ZFwWANOfKw5z5LRhV0gNA7gNkKm7HoK+HRN0wX3EkxGk0fpbWhmB7g=="],
+
"@types/esrecurse": ["@types/esrecurse@4.3.1", "", {}, "sha512-xJBAbDifo5hpffDBuHl0Y8ywswbiAp/Wi7Y/GtAgSlZyIABppyurxVueOPE8LUQOxdlgi6Zqce7uoEpqNTeiUw=="],
"@types/estree": ["@types/estree@1.0.9", "", {}, "sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg=="],
+ "@types/geojson": ["@types/geojson@7946.0.16", "", {}, "sha512-6C8nqWur3j98U6+lXDfTUWIfgvZU+EumvpHKcYjujKH7woYyLj2sUmff0tRhrqM7BohUw7Pz3ZB1jj2gW9Fvmg=="],
+
"@types/json-schema": ["@types/json-schema@7.0.15", "", {}, "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA=="],
"@types/node": ["@types/node@26.6.4", "", { "dependencies": { "undici-types": "~8.9.0" } }, "sha512-ldVPDCzj7fsaGZrLB0NuHuTvJcsNasysBAqMolr/cgxrLd1xbqxIr3XJiPnHHJUCxj5sNF1vnRj9aWnrVh5Jcg=="],
@@ -203,6 +282,8 @@
"balanced-match": ["balanced-match@4.0.4", "", {}, "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA=="],
+ "bits-ui": ["bits-ui@2.19.5", "", { "dependencies": { "@floating-ui/core": "^1.7.1", "@floating-ui/dom": "^1.7.1", "esm-env": "^1.1.2", "runed": "^0.35.1", "svelte-toolbelt": "^0.10.6", "tabbable": "^6.2.0" }, "peerDependencies": { "@internationalized/date": "^3.8.1", "svelte": "^5.33.0" } }, "sha512-TEwkLSYElE5SE0fIdcItiFPfyg9vrR67N1Mt6VvZCqZo24dwTA1MpGVV3WeyIg7rfVAaZ0So8a0/dcnPngCoew=="],
+
"brace-expansion": ["brace-expansion@5.0.12", "", { "dependencies": { "balanced-match": "^4.0.2" } }, "sha512-YovQ3rzhaLMIrDjNDMkNS01tea93qhEhG5xy8f6+R0l+dw3Ki+5sCoIoI942iuLZTHWogWktgwVDhU09iNEimQ=="],
"cacheable": ["cacheable@2.5.0", "", { "dependencies": { "@cacheable/memory": "^2.2.0", "@cacheable/utils": "^2.5.0", "hookified": "^1.15.0", "keyv": "^5.6.0", "qified": "^0.10.1" } }, "sha512-60cyAOytib/OzBw1JNSoSV/boK1AtHryDIjvVBk7XbN4ugfkM3+Sry7fEjNgPMGgOjuaZPAp8ruZ0Cxafwyq9g=="],
@@ -221,12 +302,70 @@
"cssesc": ["cssesc@3.0.0", "", { "bin": { "cssesc": "bin/cssesc" } }, "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg=="],
+ "d3-array": ["d3-array@3.2.4", "", { "dependencies": { "internmap": "1 - 2" } }, "sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg=="],
+
+ "d3-chord": ["d3-chord@3.0.1", "", { "dependencies": { "d3-path": "1 - 3" } }, "sha512-VE5S6TNa+j8msksl7HwjxMHDM2yNK3XCkusIlpX5kwauBfXuyLAtNg9jCp/iHH61tgI4sb6R/EIMWCqEIdjT/g=="],
+
+ "d3-color": ["d3-color@3.1.0", "", {}, "sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA=="],
+
+ "d3-contour": ["d3-contour@4.0.2", "", { "dependencies": { "d3-array": "^3.2.0" } }, "sha512-4EzFTRIikzs47RGmdxbeUvLWtGedDUNkTcmzoeyg4sP/dvCexO47AaQL7VKy/gul85TOxw+IBgA8US2xwbToNA=="],
+
+ "d3-delaunay": ["d3-delaunay@6.0.4", "", { "dependencies": { "delaunator": "5" } }, "sha512-mdjtIZ1XLAM8bm/hx3WwjfHt6Sggek7qH043O8KEjDXN40xi3vx/6pYSVTwLjEgiXQTbvaouWKynLBiUZ6SK6A=="],
+
+ "d3-dispatch": ["d3-dispatch@3.0.1", "", {}, "sha512-rzUyPU/S7rwUflMyLc1ETDeBj0NRuHKKAcvukozwhshr6g6c5d8zh4c2gQjY2bZ0dXeGLWc1PF174P2tVvKhfg=="],
+
+ "d3-dsv": ["d3-dsv@3.0.1", "", { "dependencies": { "commander": "7", "iconv-lite": "0.6", "rw": "1" }, "bin": { "csv2json": "bin/dsv2json.js", "csv2tsv": "bin/dsv2dsv.js", "dsv2dsv": "bin/dsv2dsv.js", "dsv2json": "bin/dsv2json.js", "json2csv": "bin/json2dsv.js", "json2dsv": "bin/json2dsv.js", "json2tsv": "bin/json2dsv.js", "tsv2csv": "bin/dsv2dsv.js", "tsv2json": "bin/dsv2json.js" } }, "sha512-UG6OvdI5afDIFP9w4G0mNq50dSOsXHJaRE8arAS5o9ApWnIElp8GZw1Dun8vP8OyHOZ/QJUKUJwxiiCCnUwm+Q=="],
+
+ "d3-force": ["d3-force@3.0.0", "", { "dependencies": { "d3-dispatch": "1 - 3", "d3-quadtree": "1 - 3", "d3-timer": "1 - 3" } }, "sha512-zxV/SsA+U4yte8051P4ECydjD/S+qeYtnaIyAs9tgHCqfguma/aAQDjo85A9Z6EKhBirHRJHXIgJUlffT4wdLg=="],
+
+ "d3-format": ["d3-format@3.1.2", "", {}, "sha512-AJDdYOdnyRDV5b6ArilzCPPwc1ejkHcoyFarqlPqT7zRYjhavcT3uSrqcMvsgh2CgoPbK3RCwyHaVyxYcP2Arg=="],
+
+ "d3-geo": ["d3-geo@3.1.1", "", { "dependencies": { "d3-array": "2.5.0 - 3" } }, "sha512-637ln3gXKXOwhalDzinUgY83KzNWZRKbYubaG+fGVuc/dxO64RRljtCTnf5ecMyE1RIdtqpkVcq0IbtU2S8j2Q=="],
+
+ "d3-geo-voronoi": ["d3-geo-voronoi@2.1.0", "", { "dependencies": { "d3-array": "3", "d3-delaunay": "6", "d3-geo": "3", "d3-tricontour": "1" } }, "sha512-kqE4yYuOjPbKdBXG0xztCacPwkVSK2REF1opSNrnqqtXJmNcM++UbwQ8SxvwP6IQTj9RvIjjK4qeiVsEfj0Z2Q=="],
+
+ "d3-hierarchy": ["d3-hierarchy@3.1.2", "", {}, "sha512-FX/9frcub54beBdugHjDCdikxThEqjnR93Qt7PvQTOHxyiNCAlvMrHhclk3cD5VeAaq9fxmfRp+CnWw9rEMBuA=="],
+
+ "d3-interpolate": ["d3-interpolate@3.0.1", "", { "dependencies": { "d3-color": "1 - 3" } }, "sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g=="],
+
+ "d3-interpolate-path": ["d3-interpolate-path@2.3.0", "", {}, "sha512-tZYtGXxBmbgHsIc9Wms6LS5u4w6KbP8C09a4/ZYc4KLMYYqub57rRBUgpUr2CIarIrJEpdAWWxWQvofgaMpbKQ=="],
+
+ "d3-path": ["d3-path@3.1.0", "", {}, "sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ=="],
+
+ "d3-polygon": ["d3-polygon@3.0.1", "", {}, "sha512-3vbA7vXYwfe1SYhED++fPUQlWSYTTGmFmQiany/gdbiWgU/iEyQzyymwL9SkJjFFuCS4902BSzewVGsHHmHtXg=="],
+
+ "d3-quadtree": ["d3-quadtree@3.0.1", "", {}, "sha512-04xDrxQTDTCFwP5H6hRhsRcb9xxv2RzkcsygFzmkSIOJy3PeRJP7sNk3VRIbKXcog561P9oU0/rVH6vDROAgUw=="],
+
+ "d3-random": ["d3-random@3.0.1", "", {}, "sha512-FXMe9GfxTxqd5D6jFsQ+DJ8BJS4E/fT5mqqdjovykEB2oFbTMDVdg1MGFxfQW+FBOGoB++k8swBrgwSHT1cUXQ=="],
+
+ "d3-sankey": ["d3-sankey@0.12.3", "", { "dependencies": { "d3-array": "1 - 2", "d3-shape": "^1.2.0" } }, "sha512-nQhsBRmM19Ax5xEIPLMY9ZmJ/cDvd1BG3UVvt5h3WRxKg5zGRbvnteTyWAbzeSvlh3tW7ZEmq4VwR5mB3tutmQ=="],
+
+ "d3-scale": ["d3-scale@4.0.2", "", { "dependencies": { "d3-array": "2.10.0 - 3", "d3-format": "1 - 3", "d3-interpolate": "1.2.0 - 3", "d3-time": "2.1.1 - 3", "d3-time-format": "2 - 4" } }, "sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ=="],
+
+ "d3-scale-chromatic": ["d3-scale-chromatic@3.1.0", "", { "dependencies": { "d3-color": "1 - 3", "d3-interpolate": "1 - 3" } }, "sha512-A3s5PWiZ9YCXFye1o246KoscMWqf8BsD9eRiJ3He7C9OBaxKhAd5TFCdEx/7VbKtxxTsu//1mMJFrEt572cEyQ=="],
+
+ "d3-shape": ["d3-shape@3.2.0", "", { "dependencies": { "d3-path": "^3.1.0" } }, "sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA=="],
+
+ "d3-tile": ["d3-tile@1.0.0", "", {}, "sha512-79fnTKpPMPDS5xQ0xuS9ir0165NEwwkFpe/DSOmc2Gl9ldYzKKRDWogmTTE8wAJ8NA7PMapNfEcyKhI9Lxdu5Q=="],
+
+ "d3-time": ["d3-time@3.1.0", "", { "dependencies": { "d3-array": "2 - 3" } }, "sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q=="],
+
+ "d3-time-format": ["d3-time-format@4.1.0", "", { "dependencies": { "d3-time": "1 - 3" } }, "sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg=="],
+
+ "d3-timer": ["d3-timer@3.0.1", "", {}, "sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA=="],
+
+ "d3-tricontour": ["d3-tricontour@1.1.0", "", { "dependencies": { "d3-delaunay": "6", "d3-scale": "4" } }, "sha512-G7gHKj89n2owmkGb6WX6ixcnQ0Kf/0wpa9VIh9DGdbHu8wdrlaHU4ir3/bFNERl8N8nn4G7e7qbtBG8N9caihQ=="],
+
"debug": ["debug@4.4.3", "", { "dependencies": { "ms": "^2.1.3" }, "peerDependencies": { "supports-color": "*" }, "optionalPeers": ["supports-color"] }, "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA=="],
"deep-is": ["deep-is@0.1.4", "", {}, "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ=="],
"deepmerge": ["deepmerge@4.3.1", "", {}, "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A=="],
+ "delaunator": ["delaunator@5.1.0", "", { "dependencies": { "robust-predicates": "^3.0.2" } }, "sha512-AGrQ4QSgssa1NGmWmLPqN5NY2KajF5MqxetNEO+o0n3ZwZZeTmt7bBnvzHWrmkZFxGgr4HdyFgelzgi06otLuQ=="],
+
+ "dequal": ["dequal@2.0.3", "", {}, "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA=="],
+
"detect-libc": ["detect-libc@2.1.2", "", {}, "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ=="],
"devalue": ["devalue@5.9.4", "", {}, "sha512-sPAT4pztbu6586/hrhOnMKS17IJrvg12mXiSPSS3W5qDeN2RGgvZ0diZCm31dBbnevfVmujNO3IM2wrS4Y2Rhg=="],
@@ -287,10 +426,16 @@
"hookified": ["hookified@1.15.1", "", {}, "sha512-MvG/clsADq1GPM2KGo2nyfaWVyn9naPiXrqIe4jYjXNZQt238kWyOGrsyc/DmRAQ+Re6yeo6yX/yoNCG5KAEVg=="],
+ "iconv-lite": ["iconv-lite@0.6.3", "", { "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" } }, "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw=="],
+
"ignore": ["ignore@5.3.2", "", {}, "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g=="],
"imurmurhash": ["imurmurhash@0.1.4", "", {}, "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA=="],
+ "inline-style-parser": ["inline-style-parser@0.2.7", "", {}, "sha512-Nb2ctOyNR8DqQoR0OwRG95uNWIC0C1lCgf5Naz5H6Ji72KZ8OcFZLz2P5sNgwlyoJ8Yif11oMuYs5pBQa86csA=="],
+
+ "internmap": ["internmap@2.0.3", "", {}, "sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg=="],
+
"is-extglob": ["is-extglob@2.1.1", "", {}, "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ=="],
"is-glob": ["is-glob@4.0.3", "", { "dependencies": { "is-extglob": "^2.1.1" } }, "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg=="],
@@ -309,6 +454,8 @@
"known-css-properties": ["known-css-properties@0.37.0", "", {}, "sha512-JCDrsP4Z1Sb9JwG0aJ8Eo2r7k4Ou5MwmThS/6lcIe1ICyb7UBJKGRIUUdqc2ASdE/42lgz6zFUnzAIhtXnBVrQ=="],
+ "layerchart": ["layerchart@2.5.1", "", { "dependencies": { "@dagrejs/dagre": "^2.0.4", "@layerstack/svelte-actions": "1.0.1-next.20", "@layerstack/svelte-state": "0.1.0-next.25", "@layerstack/tailwind": "2.0.0-next.21", "@layerstack/utils": "2.0.0-next.19", "@types/d3-contour": "^3.0.6", "d3-array": "^3.2.4", "d3-chord": "^3.0.1", "d3-color": "^3.1.0", "d3-contour": "^4.0.2", "d3-delaunay": "^6.0.4", "d3-dsv": "^3.0.1", "d3-force": "^3.0.0", "d3-geo": "^3.1.1", "d3-geo-voronoi": "^2.1.0", "d3-hierarchy": "^3.1.2", "d3-interpolate": "^3.0.1", "d3-interpolate-path": "^2.3.0", "d3-path": "^3.1.0", "d3-polygon": "^3.0.1", "d3-quadtree": "^3.0.1", "d3-random": "^3.0.1", "d3-sankey": "^0.12.3", "d3-scale": "^4.0.2", "d3-scale-chromatic": "^3.1.0", "d3-shape": "^3.2.0", "d3-tile": "^1.0.0", "d3-time": "^3.1.0", "memoize": "^10.2.0", "runed": "^0.37.1" }, "peerDependencies": { "svelte": "^5.0.0" } }, "sha512-OMrjH4yHTIJ0pQ5Qs/o7M9S5IoF15c/1/CEBKcCaZ3xqKxh4Tm5hzqoIjt0uud65t7BxgseavUh1Ah/bWUmjaA=="],
+
"levn": ["levn@0.4.1", "", { "dependencies": { "prelude-ls": "^1.2.1", "type-check": "~0.4.0" } }, "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ=="],
"lightningcss": ["lightningcss@1.33.0", "", { "dependencies": { "detect-libc": "^2.0.3" }, "optionalDependencies": { "lightningcss-android-arm64": "1.33.0", "lightningcss-darwin-arm64": "1.33.0", "lightningcss-darwin-x64": "1.33.0", "lightningcss-freebsd-x64": "1.33.0", "lightningcss-linux-arm-gnueabihf": "1.33.0", "lightningcss-linux-arm64-gnu": "1.33.0", "lightningcss-linux-arm64-musl": "1.33.0", "lightningcss-linux-x64-gnu": "1.33.0", "lightningcss-linux-x64-musl": "1.33.0", "lightningcss-win32-arm64-msvc": "1.33.0", "lightningcss-win32-x64-msvc": "1.33.0" } }, "sha512-WkUDrojuJs0xkgGf2udWxa3yGBRxPtxUkB79i6aCZLRgc7PM8fZe9TosfPDcvEpQZbuFASnHYmRLBLUbmLOIIA=="],
@@ -341,8 +488,14 @@
"locate-path": ["locate-path@6.0.0", "", { "dependencies": { "p-locate": "^5.0.0" } }, "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw=="],
+ "lz-string": ["lz-string@1.5.0", "", { "bin": { "lz-string": "bin/bin.js" } }, "sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ=="],
+
"magic-string": ["magic-string@1.4.3", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.6.0" } }, "sha512-z12OxmaPGE0F4xlpGdjuAUckipLpQlTAuAmyGhNoD7ODpYUzvDfvtxUbjM/jwznyP178oju/KDdyi220wNJ0RQ=="],
+ "memoize": ["memoize@10.2.0", "", { "dependencies": { "mimic-function": "^5.0.1" } }, "sha512-DeC6b7QBrZsRs3Y02A6A7lQyzFbsQbqgjI6UW0GigGWV+u1s25TycMr0XHZE4cJce7rY/vyw2ctMQqfDkIhUEA=="],
+
+ "mimic-function": ["mimic-function@5.0.1", "", {}, "sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA=="],
+
"minimatch": ["minimatch@10.2.6", "", { "dependencies": { "brace-expansion": "^5.0.8" } }, "sha512-vpLQEs+VLCr1nU0BXS07maYoFwlDAH0gngQuuttxIwutDFEMHq2blX+8vpgxDdK3J1PwjCJiep77OitTZ4Ll1A=="],
"mri": ["mri@1.2.0", "", {}, "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA=="],
@@ -397,10 +550,18 @@
"readdirp": ["readdirp@4.1.2", "", {}, "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg=="],
+ "robust-predicates": ["robust-predicates@3.0.3", "", {}, "sha512-NS3levdsRIUOmiJ8FZWCP7LG3QpJyrs/TE0Zpf1yvZu8cAJJ6QMW92H1c7kWpdIHo8RvmLxN/o2JXTKHp74lUA=="],
+
"rolldown": ["rolldown@1.2.12", "", { "dependencies": { "@oxc-project/types": "=0.152.0", "@rolldown/pluginutils": "^1.0.0" }, "optionalDependencies": { "@rolldown/binding-android-arm-eabi": "1.2.12", "@rolldown/binding-android-arm64": "1.2.12", "@rolldown/binding-darwin-arm64": "1.2.12", "@rolldown/binding-darwin-x64": "1.2.12", "@rolldown/binding-freebsd-x64": "1.2.12", "@rolldown/binding-linux-arm-gnueabihf": "1.2.12", "@rolldown/binding-linux-arm64-gnu": "1.2.12", "@rolldown/binding-linux-arm64-musl": "1.2.12", "@rolldown/binding-linux-ppc64-gnu": "1.2.12", "@rolldown/binding-linux-s390x-gnu": "1.2.12", "@rolldown/binding-linux-x64-gnu": "1.2.12", "@rolldown/binding-linux-x64-musl": "1.2.12", "@rolldown/binding-openharmony-arm64": "1.2.12", "@rolldown/binding-win32-arm64-msvc": "1.2.12", "@rolldown/binding-win32-x64-msvc": "1.2.12" }, "bin": { "rolldown": "./bin/cli.mjs" } }, "sha512-8wafseiaG80xmXSfqidUNqZcylTlhmPZZt+za2m+js2sFZ8dTNlhIOV2WcbIPx2hgwPBJpEUGFAMZ9bgBBLTSQ=="],
+ "runed": ["runed@0.35.1", "", { "dependencies": { "dequal": "^2.0.3", "esm-env": "^1.0.0", "lz-string": "^1.5.0" }, "peerDependencies": { "@sveltejs/kit": "^2.21.0", "svelte": "^5.7.0" }, "optionalPeers": ["@sveltejs/kit"] }, "sha512-2F4Q/FZzbeJTFdIS/PuOoPRSm92sA2LhzTnv6FXhCoENb3huf5+fDuNOg1LNvGOouy3u/225qxmuJvcV3IZK5Q=="],
+
+ "rw": ["rw@1.3.3", "", {}, "sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ=="],
+
"sade": ["sade@1.8.1", "", { "dependencies": { "mri": "^1.1.0" } }, "sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A=="],
+ "safer-buffer": ["safer-buffer@2.1.2", "", {}, "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="],
+
"semver": ["semver@7.8.5", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA=="],
"shadcn-svelte": ["shadcn-svelte@1.7.0", "", { "dependencies": { "cn": "^0.3.0", "commander": "^14.0.0", "node-fetch-native": "^1.6.4", "postcss": "^8.5.10" }, "peerDependencies": { "svelte": "^5.0.0" }, "bin": { "shadcn-svelte": "dist/index.mjs" } }, "sha512-AK3ZsYOL8PN/RxcEBCHGvQj2TrLfaaBsbw0QohyEb3nn/yPNDRC/+9iSjnTp/uKEe+tAi0tBxB/Yhzno0N7EEg=="],
@@ -413,12 +574,22 @@
"source-map-js": ["source-map-js@1.2.2", "", {}, "sha512-KGj/8Y43x35aZVDtt+J4mK1hoLGHULMYfSkODJNQjNDC3oW1PqPoxMwo0pLUsWM/UEGzON/NxeHywEfNXNP3Vw=="],
+ "style-to-object": ["style-to-object@1.0.14", "", { "dependencies": { "inline-style-parser": "0.2.7" } }, "sha512-LIN7rULI0jBscWQYaSswptyderlarFkjQ+t79nzty8tcIAceVomEVlLzH5VP4Cmsv6MtKhs7qaAiwlcp+Mgaxw=="],
+
"svelte": ["svelte@5.57.1", "", { "dependencies": { "@jridgewell/remapping": "^2.3.5", "@jridgewell/sourcemap-codec": "^1.6.0", "@sveltejs/acorn-typescript": "^1.0.13", "@types/estree": "^1.0.9", "acorn": "^8.18.0", "aria-query": "5.3.1", "axobject-query": "^4.1.0", "clsx": "^2.1.1", "devalue": "^5.9.2", "esm-env": "^1.2.1", "esrap": "^2.3.6", "is-reference": "^3.0.3", "locate-character": "^3.0.0", "magic-string": "^0.30.11", "zimmerframe": "^1.1.2" } }, "sha512-Uqj49lWKB+iSSnneuwiYYJ7MZgkB+eXr0LXBhv4uDuAkXqnWmq65Sxflfvp0Lc6MdKjMUxGaeOKWJqz5SNiVIA=="],
"svelte-check": ["svelte-check@4.7.6", "", { "dependencies": { "@jridgewell/trace-mapping": "^0.3.25", "@sveltejs/load-config": "^0.2.3", "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 || ^6.0.0" }, "bin": { "svelte-check": "bin/svelte-check" } }, "sha512-t2scM//ZuVbSY/T2w6FSBw1v9s2NEmh/g+sy1lqtosW5ylBV5AF4wFb1Ts9Kf3MbfPDUDJDZ9L436YT0SPTdvw=="],
"svelte-eslint-parser": ["svelte-eslint-parser@1.8.1", "", { "dependencies": { "eslint-scope": "^8.2.0", "eslint-visitor-keys": "^4.0.0", "espree": "^10.0.0", "postcss": "^8.4.49", "postcss-scss": "^4.0.9", "postcss-selector-parser": "^7.0.0", "semver": "^7.7.2" }, "peerDependencies": { "svelte": "^3.37.0 || ^4.0.0 || ^5.0.0" }, "optionalPeers": ["svelte"] }, "sha512-5zgKBqAf6V8Jyrmr1jViksyG4NKT8NheYwkdxRaMRDAqpGWi9wR8ktcGrAZbfMn/PHUp1BWzAp0cYQECkWuAMA=="],
+ "svelte-sonner": ["svelte-sonner@1.2.1", "", { "dependencies": { "runed": "^0.28.0" }, "peerDependencies": { "svelte": "^5.0.0" } }, "sha512-N00LOWb60fjKXULbpngku+7E9Krb16KpNq4/Eax5Vu7o1Dpbca55QpaLPsB+yp82JIEdFhfJuv5cVXLoe0ZtVA=="],
+
+ "svelte-toolbelt": ["svelte-toolbelt@0.10.6", "", { "dependencies": { "clsx": "^2.1.1", "runed": "^0.35.1", "style-to-object": "^1.0.8" }, "peerDependencies": { "svelte": "^5.30.2" } }, "sha512-YWuX+RE+CnWYx09yseAe4ZVMM7e7GRFZM6OYWpBKOb++s+SQ8RBIMMe+Bs/CznBMc0QPLjr+vDBxTAkozXsFXQ=="],
+
+ "tabbable": ["tabbable@6.5.0", "", {}, "sha512-wieBHXygIm7OyQOu5hQlkk62/WyCFYGlWg7L6/ZCUZwx0o398Zkn4pVmMyfYhfMG8kGrj/Krt8eIk6UKC6VzwA=="],
+
+ "tailwind-merge": ["tailwind-merge@3.7.0", "", {}, "sha512-XPPUyAc+cvspz3lHTcR/QgPfW2A0lv/xQNIjX3HGhLR+Nq2lHaLq5MtTesHn8GUr3W3DguT2KT5x3NVgRtYwmA=="],
+
"tailwind-variants": ["tailwind-variants@3.3.1", "", { "peerDependencies": { "tailwind-merge": ">=3.0.0", "tailwindcss": "*" }, "optionalPeers": ["tailwind-merge", "tailwindcss"] }, "sha512-4pAvwUtM4HKBiRZftncAbpn6V9Hhwoa5Fl7O2u5zbp7Z5Cvu+/o/6+176WY3WCEES209543quG8zFIcXCsc5Jw=="],
"tailwindcss": ["tailwindcss@4.3.3", "", {}, "sha512-gOhV3P7ufE62QDGg1zVaTgCR+EtPv92k2nIhVcVKcLmxT1sUBsQGhnZj175j+MqRt4zLF7ic+sCYjfhxMxj7YQ=="],
@@ -431,6 +602,8 @@
"ts-api-utils": ["ts-api-utils@2.5.0", "", { "peerDependencies": { "typescript": ">=4.8.4" } }, "sha512-OJ/ibxhPlqrMM0UiNHJ/0CKQkoKF243/AEmplt3qpRgkW8VG7IfOS41h7V8TjITqdByHzrjcS/2si+y4lIh8NA=="],
+ "tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="],
+
"tw-animate-css": ["tw-animate-css@1.4.0", "", {}, "sha512-7bziOlRqH0hJx80h/3mbicLW7o8qLsH5+RaLR2t+OHM3D0JlWGODQKQ4cxbK7WlvmUxpcj6Kgu6EKqjrGFe3QQ=="],
"type-check": ["type-check@0.4.0", "", { "dependencies": { "prelude-ls": "^1.2.1" } }, "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew=="],
@@ -445,6 +618,8 @@
"util-deprecate": ["util-deprecate@1.0.2", "", {}, "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="],
+ "vaul-svelte": ["vaul-svelte@1.0.0-next.7", "", { "dependencies": { "runed": "^0.23.2", "svelte-toolbelt": "^0.7.1" }, "peerDependencies": { "svelte": "^5.0.0" } }, "sha512-7zN7Bi3dFQixvvbUJY9uGDe7Ws/dGZeBQR2pXdXmzQiakjrxBvWo0QrmsX3HK+VH+SZOltz378cmgmCS9f9rSg=="],
+
"vite": ["vite@8.3.2", "", { "dependencies": { "lightningcss": "^1.33.0", "picomatch": "^4.0.7", "postcss": "^8.5.28", "rolldown": "~1.2.11", "tinyglobby": "^0.2.17" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^20.19.0 || >=22.12.0", "@vitejs/devtools": "^0.7.1", "esbuild": "^0.27.0 || ^0.28.0", "jiti": ">=1.21.0", "less": "^4.0.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", "@vitejs/devtools", "esbuild", "jiti", "less", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-SQr1x6W5vVSbROg7vsyXIaxK9b0G7zsT68acdWWRmnBUsgDieLCRG+Rep9WdZgcposvv/GSnr4GUUBqB3vXq6w=="],
"vitefu": ["vitefu@1.1.3", "", { "peerDependencies": { "vite": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0" }, "optionalPeers": ["vite"] }, "sha512-ub4okH7Z5KLjb6hDyjqrGXqWtWvoYdU3IGm/NorpgHncKoLTCfRIbvlhBm7r0YstIaQRYlp4yEbFqDcKSzXSSg=="],
@@ -459,6 +634,22 @@
"zimmerframe": ["zimmerframe@1.1.5", "", {}, "sha512-msJxIvYDYcoNL+PJsu+7qmpDWsYmAxTY+2TNYXXF0hzBzBk0BMecOqDOG/EckUoKCuKwObfbugIl8QpqHDXeFA=="],
+ "zod": ["zod@4.6.5", "", {}, "sha512-v5l/aFXZQeai4awLbOpSoHecE9UiMrnfx75tEXLjNonXVARxQ5mOeipTjROUchszUNCqnE+hqAMujRsRHsut2Q=="],
+
+ "@dnd-kit-svelte/svelte/@dnd-kit/abstract": ["@dnd-kit/abstract@0.2.4", "", { "dependencies": { "@dnd-kit/geometry": "^0.2.4", "@dnd-kit/state": "^0.2.4", "tslib": "^2.6.2" } }, "sha512-1F3JQaD8upvTNpfDrhvec57cldTEaUggmVrVJZIpRTIdZR7trKqS7vBYZR1mW3qNjWsxC91eEQAXYWv0vxXXuw=="],
+
+ "@dnd-kit/abstract/@dnd-kit/state": ["@dnd-kit/state@0.1.21", "", { "dependencies": { "@preact/signals-core": "^1.10.0", "tslib": "^2.6.2" } }, "sha512-pdhntEPvn/QttcF295bOJpWiLsRqA/Iczh1ODOJUxGiR+E4GkYVz9VapNNm9gDq6ST0tr/e1Q2xBztUHlJqQgA=="],
+
+ "@dnd-kit/collision/@dnd-kit/abstract": ["@dnd-kit/abstract@0.2.4", "", { "dependencies": { "@dnd-kit/geometry": "^0.2.4", "@dnd-kit/state": "^0.2.4", "tslib": "^2.6.2" } }, "sha512-1F3JQaD8upvTNpfDrhvec57cldTEaUggmVrVJZIpRTIdZR7trKqS7vBYZR1mW3qNjWsxC91eEQAXYWv0vxXXuw=="],
+
+ "@dnd-kit/collision/@dnd-kit/geometry": ["@dnd-kit/geometry@0.2.4", "", { "dependencies": { "@dnd-kit/state": "^0.2.4", "tslib": "^2.6.2" } }, "sha512-S8wVj4rQIErimDQoRT0n1+lgxPvlO/gvzT9/1vzyyw1U4bB/S8avtrI+REVw/jH84c/dii+GwrrzVkDDoIluNw=="],
+
+ "@dnd-kit/dom/@dnd-kit/abstract": ["@dnd-kit/abstract@0.2.4", "", { "dependencies": { "@dnd-kit/geometry": "^0.2.4", "@dnd-kit/state": "^0.2.4", "tslib": "^2.6.2" } }, "sha512-1F3JQaD8upvTNpfDrhvec57cldTEaUggmVrVJZIpRTIdZR7trKqS7vBYZR1mW3qNjWsxC91eEQAXYWv0vxXXuw=="],
+
+ "@dnd-kit/dom/@dnd-kit/geometry": ["@dnd-kit/geometry@0.2.4", "", { "dependencies": { "@dnd-kit/state": "^0.2.4", "tslib": "^2.6.2" } }, "sha512-S8wVj4rQIErimDQoRT0n1+lgxPvlO/gvzT9/1vzyyw1U4bB/S8avtrI+REVw/jH84c/dii+GwrrzVkDDoIluNw=="],
+
+ "@dnd-kit/geometry/@dnd-kit/state": ["@dnd-kit/state@0.1.21", "", { "dependencies": { "@preact/signals-core": "^1.10.0", "tslib": "^2.6.2" } }, "sha512-pdhntEPvn/QttcF295bOJpWiLsRqA/Iczh1ODOJUxGiR+E4GkYVz9VapNNm9gDq6ST0tr/e1Q2xBztUHlJqQgA=="],
+
"@eslint-community/eslint-utils/eslint-visitor-keys": ["eslint-visitor-keys@3.4.3", "", {}, "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag=="],
"@tailwindcss/node/lightningcss": ["lightningcss@1.32.0", "", { "dependencies": { "detect-libc": "^2.0.3" }, "optionalDependencies": { "lightningcss-android-arm64": "1.32.0", "lightningcss-darwin-arm64": "1.32.0", "lightningcss-darwin-x64": "1.32.0", "lightningcss-freebsd-x64": "1.32.0", "lightningcss-linux-arm-gnueabihf": "1.32.0", "lightningcss-linux-arm64-gnu": "1.32.0", "lightningcss-linux-arm64-musl": "1.32.0", "lightningcss-linux-x64-gnu": "1.32.0", "lightningcss-linux-x64-musl": "1.32.0", "lightningcss-win32-arm64-msvc": "1.32.0", "lightningcss-win32-x64-msvc": "1.32.0" } }, "sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ=="],
@@ -479,8 +670,16 @@
"@typescript-eslint/eslint-plugin/ignore": ["ignore@7.0.12", "", {}, "sha512-/8UvqAPU9DGTI9k4mxtf49U37Isfwr8Uts96+SBHIkFxPJnHS0Ew4f00sM4Scd8V8EjM0jUNtVDdv1kPdt35lg=="],
+ "d3-dsv/commander": ["commander@7.2.0", "", {}, "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw=="],
+
+ "d3-sankey/d3-array": ["d3-array@2.12.1", "", { "dependencies": { "internmap": "^1.0.0" } }, "sha512-B0ErZK/66mHtEsR1TkPEEkwdy+WDesimkM5gpZr5Dsg54BiTA5RXtYW5qTLIAcekaS9xfZrzBLF/OAkB3Qn1YQ=="],
+
+ "d3-sankey/d3-shape": ["d3-shape@1.3.7", "", { "dependencies": { "d3-path": "1" } }, "sha512-EUkvKjqPFUAZyOlhY5gzCxCeI0Aep04LwIRpsZ/mLFelJiUfnK56jo5JMDSE7yyP2kLSb6LtF+S5chMk7uqPqw=="],
+
"eslint-plugin-svelte/globals": ["globals@16.5.0", "", {}, "sha512-c/c15i26VrJ4IRt5Z89DnIzCGDn9EcebibhAOjw5ibqEHsE1wLUgkPn9RDmNcUKyU87GeaL633nyJ+pplFR2ZQ=="],
+ "layerchart/runed": ["runed@0.37.1", "", { "dependencies": { "dequal": "^2.0.3", "esm-env": "^1.0.0", "lz-string": "^1.5.0" }, "peerDependencies": { "@sveltejs/kit": "^2.21.0", "svelte": "^5.7.0", "zod": "^4.1.0" }, "optionalPeers": ["@sveltejs/kit", "zod"] }, "sha512-MeFY73xBW8IueWBm012nNFIGy19WUGPLtknavyUPMpnyt350M47PhGSGrGoSLbidwn+Zlt/O0cp8/OZE3LASWA=="],
+
"qified/hookified": ["hookified@2.2.0", "", {}, "sha512-p/LgFzRN5FeoD3DLS6bkUapeye6E4SI6yJs6KetENd18S+FBthqYq2amJUWpt5z0EQwwHemidjY5OqJGEKm5uA=="],
"svelte/magic-string": ["magic-string@0.30.21", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.5" } }, "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ=="],
@@ -493,6 +692,14 @@
"svelte-eslint-parser/postcss-selector-parser": ["postcss-selector-parser@7.1.6", "", { "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" } }, "sha512-7qASPzhKF2l2KLboRZux8CCTRMdGiV08vWmyKzPz22qZ7ZjQBOeY7rNzNoCLSUiftJ7HUq0GERHmxw/t0dCdMw=="],
+ "svelte-sonner/runed": ["runed@0.28.0", "", { "dependencies": { "esm-env": "^1.0.0" }, "peerDependencies": { "svelte": "^5.7.0" } }, "sha512-k2xx7RuO9hWcdd9f+8JoBeqWtYrm5CALfgpkg2YDB80ds/QE4w0qqu34A7fqiAwiBBSBQOid7TLxwxVC27ymWQ=="],
+
+ "vaul-svelte/runed": ["runed@0.23.4", "", { "dependencies": { "esm-env": "^1.0.0" }, "peerDependencies": { "svelte": "^5.7.0" } }, "sha512-9q8oUiBYeXIDLWNK5DfCWlkL0EW3oGbk845VdKlPeia28l751VpfesaB/+7pI6rnbx1I6rqoZ2fZxptOJLxILA=="],
+
+ "vaul-svelte/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=="],
+
+ "@dnd-kit-svelte/svelte/@dnd-kit/abstract/@dnd-kit/geometry": ["@dnd-kit/geometry@0.2.4", "", { "dependencies": { "@dnd-kit/state": "^0.2.4", "tslib": "^2.6.2" } }, "sha512-S8wVj4rQIErimDQoRT0n1+lgxPvlO/gvzT9/1vzyyw1U4bB/S8avtrI+REVw/jH84c/dii+GwrrzVkDDoIluNw=="],
+
"@tailwindcss/node/lightningcss/lightningcss-android-arm64": ["lightningcss-android-arm64@1.32.0", "", { "os": "android", "cpu": "arm64" }, "sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg=="],
"@tailwindcss/node/lightningcss/lightningcss-darwin-arm64": ["lightningcss-darwin-arm64@1.32.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ=="],
@@ -514,5 +721,9 @@
"@tailwindcss/node/lightningcss/lightningcss-win32-arm64-msvc": ["lightningcss-win32-arm64-msvc@1.32.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw=="],
"@tailwindcss/node/lightningcss/lightningcss-win32-x64-msvc": ["lightningcss-win32-x64-msvc@1.32.0", "", { "os": "win32", "cpu": "x64" }, "sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q=="],
+
+ "d3-sankey/d3-array/internmap": ["internmap@1.0.1", "", {}, "sha512-lDB5YccMydFBtasVtxnZ3MRBHuaoE8GKsppq+EchKL2U4nK/DmEpPHNH8MZe5HkMtpSiTSOZwfN0tzYjO/lJEw=="],
+
+ "d3-sankey/d3-shape/d3-path": ["d3-path@1.0.9", "", {}, "sha512-VLaYcn81dtHVTjEHd8B+pbe9yHWpXKZUC87PzoFmsFrJqgFwDe/qxfp5MlfsfM1V5E/iVt0MmEbWQ7FVIXh/bg=="],
}
}
diff --git a/package.json b/package.json
index a8474cb..8b810f8 100644
--- a/package.json
+++ b/package.json
@@ -14,32 +14,47 @@
"format": "prettier --write ."
},
"devDependencies": {
+ "@dnd-kit-svelte/svelte": "^0.1.5",
+ "@dnd-kit/abstract": "^0.1.21",
+ "@dnd-kit/helpers": "^0.1.21",
"@eslint/js": "^10.0.1",
"@fontsource-variable/inter": "^5.3.0",
+ "@internationalized/date": "^3.12.0",
"@lucide/svelte": "^1.52.0",
"@sveltejs/adapter-auto": "^8.0.0",
"@sveltejs/kit": "^3.0.0",
"@sveltejs/vite-plugin-svelte": "^7.2.0",
+ "@tabler/icons-svelte": "^3.40.0",
"@tailwindcss/typography": "^0.5.19",
"@tailwindcss/vite": "^4.3.0",
+ "@tanstack/svelte-table": "^9.0.0",
+ "@types/d3-scale": "^4.0.9",
+ "@types/d3-shape": "^3.1.8",
"@types/node": "^26",
+ "bits-ui": "^2.18.0",
"cn": "^0.3.0",
+ "d3-scale": "^4.0.2",
+ "d3-shape": "^3.2.0",
"eslint": "^10.4.1",
"eslint-config-prettier": "^10.1.8",
"eslint-plugin-svelte": "^3.19.0",
"globals": "^17.6.0",
+ "layerchart": "^2.0.0",
"prettier": "^3.8.3",
"prettier-plugin-svelte": "^4.1.0",
"prettier-plugin-tailwindcss": "^0.8.0",
"shadcn-svelte": "^1.7.0",
"svelte": "^5.57.1",
"svelte-check": "^4.6.0",
+ "svelte-sonner": "^1.2.0",
"tailwind-variants": "^3.3.1",
"tailwindcss": "^4.3.0",
"tw-animate-css": "^1.4.0",
"typescript": "^6.0.3",
"typescript-eslint": "^8.60.1",
- "vite": "^8.3.0"
+ "vaul-svelte": "^1.0.0-next.7",
+ "vite": "^8.3.0",
+ "zod": "^4.4.3"
},
"imports": {
"#lib": "./src/lib/index.js",
diff --git a/src/lib/components/app-sidebar.svelte b/src/lib/components/app-sidebar.svelte
new file mode 100644
index 0000000..46f6cd5
--- /dev/null
+++ b/src/lib/components/app-sidebar.svelte
@@ -0,0 +1,167 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/lib/components/chart-area-interactive.svelte b/src/lib/components/chart-area-interactive.svelte
new file mode 100644
index 0000000..7b8884d
--- /dev/null
+++ b/src/lib/components/chart-area-interactive.svelte
@@ -0,0 +1,247 @@
+
+
+
+
+ Total Visitors
+
+ Total for the last 3 months
+ Last 3 months
+
+
+
+ Last 3 months
+ Last 30 days
+ Last 7 days
+
+
+
+
+ {selectedLabel}
+
+
+
+ Last 3 months
+ Last 30 days
+ Last 7 days
+
+
+
+
+
+
+ {
+ return v.toLocaleDateString("en-US", {
+ month: "short",
+ day: "numeric",
+ });
+ },
+ },
+ yAxis: { format: () => "" },
+ }}
+ >
+ {#snippet marks({ context })}
+
+
+
+
+
+
+
+
+
+
+ {#each context.series.visibleSeries as s (s.key)}
+
+ {/each}
+ {/snippet}
+ {#snippet tooltip()}
+ {
+ return v.toLocaleDateString("en-US", {
+ month: "short",
+ day: "numeric",
+ });
+ }}
+ indicator="line"
+ />
+ {/snippet}
+
+
+
+
diff --git a/src/lib/components/data-table-actions.svelte b/src/lib/components/data-table-actions.svelte
new file mode 100644
index 0000000..995742b
--- /dev/null
+++ b/src/lib/components/data-table-actions.svelte
@@ -0,0 +1,23 @@
+
+
+
+
+ {#snippet child({ props })}
+
+ {/snippet}
+
+
+ Edit
+ Make a copy
+ Favorite
+
+ Delete
+
+
diff --git a/src/lib/components/data-table-cell-viewer.svelte b/src/lib/components/data-table-cell-viewer.svelte
new file mode 100644
index 0000000..2430b5a
--- /dev/null
+++ b/src/lib/components/data-table-cell-viewer.svelte
@@ -0,0 +1,189 @@
+
+
+
+
+ {#snippet child({ props })}
+
+ {/snippet}
+
+
+
+ {item.header}
+ Showing total visitors for the last 6 months
+
+
+ {#if !isMobile.current}
+
+ v.toLocaleDateString("en-US", { month: "short" }),
+ },
+ yAxis: { ticks: [0, 300, 600] },
+ }}
+ >
+ {#snippet tooltip()}
+ {
+ return v.toLocaleDateString("en-US", {
+ month: "long",
+ });
+ }}
+ indicator="dot"
+ />
+ {/snippet}
+
+
+
+
+
+ Trending up by 5.2% this month
+
+
+
+ Showing total visitors for the last 6 months. This is just some random text to test the
+ layout. It spans multiple lines and should wrap around.
+
+
+
+ {/if}
+
+
+
+
+
+ {#snippet child({ props })}
+
+ {/snippet}
+
+
+
+
diff --git a/src/lib/components/data-table-checkbox.svelte b/src/lib/components/data-table-checkbox.svelte
new file mode 100644
index 0000000..b4c665f
--- /dev/null
+++ b/src/lib/components/data-table-checkbox.svelte
@@ -0,0 +1,14 @@
+
+
+
+ checked, onCheckedChange} {...restProps} />
+
diff --git a/src/lib/components/data-table-drag-handle.svelte b/src/lib/components/data-table-drag-handle.svelte
new file mode 100644
index 0000000..2853b5c
--- /dev/null
+++ b/src/lib/components/data-table-drag-handle.svelte
@@ -0,0 +1,17 @@
+
+
+
diff --git a/src/lib/components/data-table-features.ts b/src/lib/components/data-table-features.ts
new file mode 100644
index 0000000..e2a4d3b
--- /dev/null
+++ b/src/lib/components/data-table-features.ts
@@ -0,0 +1,26 @@
+import {
+ columnFilteringFeature,
+ columnVisibilityFeature,
+ createFilteredRowModel,
+ createPaginatedRowModel,
+ createSortedRowModel,
+ rowPaginationFeature,
+ rowSelectionFeature,
+ rowSortingFeature,
+ tableFeatures,
+} from "@tanstack/svelte-table";
+
+// New in v9: declare the features this table uses — anything you don't
+// register is tree-shaken out of the bundle.
+export const features = tableFeatures({
+ columnFilteringFeature,
+ columnVisibilityFeature,
+ rowPaginationFeature,
+ rowSelectionFeature,
+ rowSortingFeature,
+ filteredRowModel: createFilteredRowModel(),
+ paginatedRowModel: createPaginatedRowModel(),
+ sortedRowModel: createSortedRowModel(),
+});
+
+export type DashboardTableFeatures = typeof features;
diff --git a/src/lib/components/data-table-header-limit.svelte b/src/lib/components/data-table-header-limit.svelte
new file mode 100644
index 0000000..25c0fe8
--- /dev/null
+++ b/src/lib/components/data-table-header-limit.svelte
@@ -0,0 +1 @@
+Limit
diff --git a/src/lib/components/data-table-header-target.svelte b/src/lib/components/data-table-header-target.svelte
new file mode 100644
index 0000000..26bbc01
--- /dev/null
+++ b/src/lib/components/data-table-header-target.svelte
@@ -0,0 +1 @@
+Target
diff --git a/src/lib/components/data-table-limit.svelte b/src/lib/components/data-table-limit.svelte
new file mode 100644
index 0000000..d3e4a9d
--- /dev/null
+++ b/src/lib/components/data-table-limit.svelte
@@ -0,0 +1,28 @@
+
+
+
diff --git a/src/lib/components/data-table-reviewer.svelte b/src/lib/components/data-table-reviewer.svelte
new file mode 100644
index 0000000..b4dbd90
--- /dev/null
+++ b/src/lib/components/data-table-reviewer.svelte
@@ -0,0 +1,33 @@
+
+
+{#if isAssigned}
+ {row.original.reviewer}
+{:else}
+
+
+
+
+ {reviewer !== "" ? reviewer : "Assign reviewer"}
+
+
+
+ Eddie Lake
+ Jamik Tashpulatov
+
+
+{/if}
diff --git a/src/lib/components/data-table-status.svelte b/src/lib/components/data-table-status.svelte
new file mode 100644
index 0000000..1633957
--- /dev/null
+++ b/src/lib/components/data-table-status.svelte
@@ -0,0 +1,19 @@
+
+
+
+ {#if row.original.status === "Done"}
+
+ {:else}
+
+ {/if}
+ {row.original.status}
+
diff --git a/src/lib/components/data-table-target.svelte b/src/lib/components/data-table-target.svelte
new file mode 100644
index 0000000..7702987
--- /dev/null
+++ b/src/lib/components/data-table-target.svelte
@@ -0,0 +1,28 @@
+
+
+
diff --git a/src/lib/components/data-table-type.svelte b/src/lib/components/data-table-type.svelte
new file mode 100644
index 0000000..0c097c2
--- /dev/null
+++ b/src/lib/components/data-table-type.svelte
@@ -0,0 +1,14 @@
+
+
+
+
+ {row.original.type}
+
+
diff --git a/src/lib/components/data-table.svelte b/src/lib/components/data-table.svelte
new file mode 100644
index 0000000..1f0c6c8
--- /dev/null
+++ b/src/lib/components/data-table.svelte
@@ -0,0 +1,355 @@
+
+
+
+
+
+
+
+ {viewLabel}
+
+
+ {#each views as view (view.id)}
+ {view.label}
+ {/each}
+
+
+
+ {#each views as view (view.id)}
+
+ {view.label}
+ {#if view.badge > 0}
+ {view.badge}
+ {/if}
+
+ {/each}
+
+
+
+
+ {#snippet child({ props })}
+
+ {/snippet}
+
+
+ {#each table
+ .getAllColumns()
+ .filter((col) => typeof col.accessorFn !== "undefined" && col.getCanHide()) as column (column.id)}
+ column.toggleVisibility(!!value)}
+ >
+ {column.id}
+
+ {/each}
+
+
+
+
+
+
+
+
(data = move(data, e))}
+ >
+
+
+ {#each table.getHeaderGroups() as headerGroup (headerGroup.id)}
+
+ {#each headerGroup.headers as header (header.id)}
+
+ {#if !header.isPlaceholder}
+
+ {/if}
+
+ {/each}
+
+ {/each}
+
+
+ {#if table.getRowModel().rows?.length}
+ {#each table.getRowModel().rows as row (row.id)}
+ {@render DraggableRow({ row })}
+ {/each}
+ {:else}
+
+
+ No results.
+
+
+ {/if}
+
+
+
+
+
+
+ {table.getFilteredSelectedRowModel().rows.length} of
+ {table.getFilteredRowModel().rows.length} row(s) selected.
+
+
+
+
+ `${pagination.pageSize}`, (v) => table.setPageSize(Number(v))}
+ >
+
+ {pagination.pageSize}
+
+
+ {#each [10, 20, 30, 40, 50] as pageSize (pageSize)}
+
+ {pageSize}
+
+ {/each}
+
+
+
+
+ Page {pagination.pageIndex + 1} of
+ {table.getPageCount()}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+{#snippet DraggableRow({ row }: { row: Row })}
+ {@const { ref, isDragging, handleRef } = useSortable({
+ id: row.original.id,
+ index: () => row.index,
+ })}
+
+
+ {#each row.getVisibleCells() as cell (cell.id)}
+
+ {#if cell.column.id === "drag"}
+
+
+ {:else}
+
+ {/if}
+
+ {/each}
+
+{/snippet}
diff --git a/src/lib/components/nav-documents.svelte b/src/lib/components/nav-documents.svelte
new file mode 100644
index 0000000..386ed5a
--- /dev/null
+++ b/src/lib/components/nav-documents.svelte
@@ -0,0 +1,70 @@
+
+
+
+ Documents
+
+ {#each items as item (item.name)}
+
+
+ {#snippet child({ props })}
+
+
+ {item.name}
+
+ {/snippet}
+
+
+
+ {#snippet child({ props })}
+
+
+ More
+
+ {/snippet}
+
+
+
+
+ Open
+
+
+
+ Share
+
+
+
+
+ Delete
+
+
+
+
+ {/each}
+
+
+
+
+
diff --git a/src/lib/components/nav-main.svelte b/src/lib/components/nav-main.svelte
new file mode 100644
index 0000000..77523eb
--- /dev/null
+++ b/src/lib/components/nav-main.svelte
@@ -0,0 +1,45 @@
+
+
+
+
+
+
+
+
+ Quick Create
+
+
+
+
+
+ {#each items as item (item.title)}
+
+
+ {#if item.icon}
+
+ {/if}
+ {item.title}
+
+
+ {/each}
+
+
+
diff --git a/src/lib/components/nav-secondary.svelte b/src/lib/components/nav-secondary.svelte
new file mode 100644
index 0000000..89e4676
--- /dev/null
+++ b/src/lib/components/nav-secondary.svelte
@@ -0,0 +1,32 @@
+
+
+
+
+
+ {#each items as item (item.title)}
+
+
+ {#snippet child({ props })}
+
+
+ {item.title}
+
+ {/snippet}
+
+
+ {/each}
+
+
+
diff --git a/src/lib/components/nav-user.svelte b/src/lib/components/nav-user.svelte
new file mode 100644
index 0000000..5999e26
--- /dev/null
+++ b/src/lib/components/nav-user.svelte
@@ -0,0 +1,83 @@
+
+
+
+
+
+
+ {#snippet child({ props })}
+
+ {/snippet}
+
+
+
+
+
diff --git a/src/lib/components/schemas.ts b/src/lib/components/schemas.ts
new file mode 100644
index 0000000..9ba0b83
--- /dev/null
+++ b/src/lib/components/schemas.ts
@@ -0,0 +1,13 @@
+import { z } from "zod";
+
+export const schema = z.object({
+ id: z.number(),
+ header: z.string(),
+ type: z.string(),
+ status: z.string(),
+ target: z.string(),
+ limit: z.string(),
+ reviewer: z.string(),
+});
+
+export type Schema = z.infer;
diff --git a/src/lib/components/section-cards.svelte b/src/lib/components/section-cards.svelte
new file mode 100644
index 0000000..1044437
--- /dev/null
+++ b/src/lib/components/section-cards.svelte
@@ -0,0 +1,91 @@
+
+
+
+
+
+ Total Revenue
+
+ $1,250.00
+
+
+
+
+ +12.5%
+
+
+
+
+
+ Trending up this month
+
+ Visitors for the last 6 months
+
+
+
+
+ New Customers
+
+ 1,234
+
+
+
+
+ -20%
+
+
+
+
+
+ Down 20% this period
+
+ Acquisition needs attention
+
+
+
+
+ Active Accounts
+
+ 45,678
+
+
+
+
+ +12.5%
+
+
+
+
+
+ Strong user retention
+
+ Engagement exceed targets
+
+
+
+
+ Growth Rate
+
+ 4.5%
+
+
+
+
+ +4.5%
+
+
+
+
+
+ Steady performance increase
+
+ Meets growth projections
+
+
+
diff --git a/src/lib/components/site-header.svelte b/src/lib/components/site-header.svelte
new file mode 100644
index 0000000..47f83c3
--- /dev/null
+++ b/src/lib/components/site-header.svelte
@@ -0,0 +1,27 @@
+
+
+
diff --git a/src/lib/components/ui/avatar/avatar-badge.svelte b/src/lib/components/ui/avatar/avatar-badge.svelte
new file mode 100644
index 0000000..7bf61c6
--- /dev/null
+++ b/src/lib/components/ui/avatar/avatar-badge.svelte
@@ -0,0 +1,26 @@
+
+
+svg]:hidden",
+ "group-data-[size=default]/avatar:size-2.5 group-data-[size=default]/avatar:[&>svg]:size-2",
+ "group-data-[size=lg]/avatar:size-3 group-data-[size=lg]/avatar:[&>svg]:size-2",
+ className
+ )}
+ {...restProps}
+>
+ {@render children?.()}
+
diff --git a/src/lib/components/ui/avatar/avatar-fallback.svelte b/src/lib/components/ui/avatar/avatar-fallback.svelte
new file mode 100644
index 0000000..30fa764
--- /dev/null
+++ b/src/lib/components/ui/avatar/avatar-fallback.svelte
@@ -0,0 +1,20 @@
+
+
+
diff --git a/src/lib/components/ui/avatar/avatar-group-count.svelte b/src/lib/components/ui/avatar/avatar-group-count.svelte
new file mode 100644
index 0000000..f958b83
--- /dev/null
+++ b/src/lib/components/ui/avatar/avatar-group-count.svelte
@@ -0,0 +1,23 @@
+
+
+svg]:size-4 group-has-data-[size=lg]/avatar-group:[&>svg]:size-5 group-has-data-[size=sm]/avatar-group:[&>svg]:size-3 relative flex shrink-0 items-center justify-center ring-2 ring-background",
+ className
+ )}
+ {...restProps}
+>
+ {@render children?.()}
+
diff --git a/src/lib/components/ui/avatar/avatar-group.svelte b/src/lib/components/ui/avatar/avatar-group.svelte
new file mode 100644
index 0000000..a192200
--- /dev/null
+++ b/src/lib/components/ui/avatar/avatar-group.svelte
@@ -0,0 +1,23 @@
+
+
+
+ {@render children?.()}
+
diff --git a/src/lib/components/ui/avatar/avatar-image.svelte b/src/lib/components/ui/avatar/avatar-image.svelte
new file mode 100644
index 0000000..d4aff87
--- /dev/null
+++ b/src/lib/components/ui/avatar/avatar-image.svelte
@@ -0,0 +1,17 @@
+
+
+
diff --git a/src/lib/components/ui/avatar/avatar.svelte b/src/lib/components/ui/avatar/avatar.svelte
new file mode 100644
index 0000000..2e6137f
--- /dev/null
+++ b/src/lib/components/ui/avatar/avatar.svelte
@@ -0,0 +1,26 @@
+
+
+
diff --git a/src/lib/components/ui/avatar/index.ts b/src/lib/components/ui/avatar/index.ts
new file mode 100644
index 0000000..963a923
--- /dev/null
+++ b/src/lib/components/ui/avatar/index.ts
@@ -0,0 +1,22 @@
+import Badge from "./avatar-badge.svelte";
+import Fallback from "./avatar-fallback.svelte";
+import GroupCount from "./avatar-group-count.svelte";
+import Group from "./avatar-group.svelte";
+import Image from "./avatar-image.svelte";
+import Root from "./avatar.svelte";
+
+export {
+ Root,
+ Image,
+ Fallback,
+ Badge,
+ Group,
+ GroupCount,
+ //
+ Root as Avatar,
+ Image as AvatarImage,
+ Fallback as AvatarFallback,
+ Badge as AvatarBadge,
+ Group as AvatarGroup,
+ GroupCount as AvatarGroupCount,
+};
diff --git a/src/lib/components/ui/badge/badge.svelte b/src/lib/components/ui/badge/badge.svelte
new file mode 100644
index 0000000..55b43ad
--- /dev/null
+++ b/src/lib/components/ui/badge/badge.svelte
@@ -0,0 +1,49 @@
+
+
+
+
+
+ {@render children?.()}
+
diff --git a/src/lib/components/ui/badge/index.ts b/src/lib/components/ui/badge/index.ts
new file mode 100644
index 0000000..64e0aa9
--- /dev/null
+++ b/src/lib/components/ui/badge/index.ts
@@ -0,0 +1,2 @@
+export { default as Badge } from "./badge.svelte";
+export { badgeVariants, type BadgeVariant } from "./badge.svelte";
diff --git a/src/lib/components/ui/card/card-action.svelte b/src/lib/components/ui/card/card-action.svelte
new file mode 100644
index 0000000..23ad84e
--- /dev/null
+++ b/src/lib/components/ui/card/card-action.svelte
@@ -0,0 +1,23 @@
+
+
+
+ {@render children?.()}
+
diff --git a/src/lib/components/ui/card/card-content.svelte b/src/lib/components/ui/card/card-content.svelte
new file mode 100644
index 0000000..dfe575a
--- /dev/null
+++ b/src/lib/components/ui/card/card-content.svelte
@@ -0,0 +1,20 @@
+
+
+
+ {@render children?.()}
+
diff --git a/src/lib/components/ui/card/card-description.svelte b/src/lib/components/ui/card/card-description.svelte
new file mode 100644
index 0000000..c5be813
--- /dev/null
+++ b/src/lib/components/ui/card/card-description.svelte
@@ -0,0 +1,20 @@
+
+
+
+ {@render children?.()}
+
diff --git a/src/lib/components/ui/card/card-footer.svelte b/src/lib/components/ui/card/card-footer.svelte
new file mode 100644
index 0000000..cc93776
--- /dev/null
+++ b/src/lib/components/ui/card/card-footer.svelte
@@ -0,0 +1,20 @@
+
+
+
+ {@render children?.()}
+
diff --git a/src/lib/components/ui/card/card-header.svelte b/src/lib/components/ui/card/card-header.svelte
new file mode 100644
index 0000000..50b47b0
--- /dev/null
+++ b/src/lib/components/ui/card/card-header.svelte
@@ -0,0 +1,23 @@
+
+
+
+ {@render children?.()}
+
diff --git a/src/lib/components/ui/card/card-title.svelte b/src/lib/components/ui/card/card-title.svelte
new file mode 100644
index 0000000..81293f2
--- /dev/null
+++ b/src/lib/components/ui/card/card-title.svelte
@@ -0,0 +1,20 @@
+
+
+
+ {@render children?.()}
+
diff --git a/src/lib/components/ui/card/card.svelte b/src/lib/components/ui/card/card.svelte
new file mode 100644
index 0000000..ac05086
--- /dev/null
+++ b/src/lib/components/ui/card/card.svelte
@@ -0,0 +1,22 @@
+
+
+img:first-child]:pt-0 data-[size=sm]:[--card-spacing:--spacing(4)] *:[img:first-child]:rounded-t-xl *:[img:last-child]:rounded-b-xl group/card flex flex-col", className)}
+ {...restProps}
+>
+ {@render children?.()}
+
diff --git a/src/lib/components/ui/card/index.ts b/src/lib/components/ui/card/index.ts
new file mode 100644
index 0000000..5705f13
--- /dev/null
+++ b/src/lib/components/ui/card/index.ts
@@ -0,0 +1,25 @@
+import Action from "./card-action.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 Root from "./card.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,
+};
diff --git a/src/lib/components/ui/chart/chart-container.svelte b/src/lib/components/ui/chart/chart-container.svelte
new file mode 100644
index 0000000..34cf3a4
--- /dev/null
+++ b/src/lib/components/ui/chart/chart-container.svelte
@@ -0,0 +1,80 @@
+
+
+
+
+ {@render children?.()}
+
diff --git a/src/lib/components/ui/chart/chart-style.svelte b/src/lib/components/ui/chart/chart-style.svelte
new file mode 100644
index 0000000..74c2b8a
--- /dev/null
+++ b/src/lib/components/ui/chart/chart-style.svelte
@@ -0,0 +1,37 @@
+
+
+{#if themeContents}
+ {#key id}
+
+ {themeContents}
+
+ {/key}
+{/if}
diff --git a/src/lib/components/ui/chart/chart-tooltip.svelte b/src/lib/components/ui/chart/chart-tooltip.svelte
new file mode 100644
index 0000000..31e532a
--- /dev/null
+++ b/src/lib/components/ui/chart/chart-tooltip.svelte
@@ -0,0 +1,180 @@
+
+
+{#snippet TooltipLabel()}
+ {#if formattedLabel}
+
+ {#if typeof formattedLabel === "function"}
+ {@render formattedLabel()}
+ {:else}
+ {formattedLabel}
+ {/if}
+
+ {/if}
+{/snippet}
+
+
+
+ {#if !nestLabel}
+ {@render TooltipLabel()}
+ {/if}
+
+ {#each visibleSeries as item, i (item.key + i)}
+ {@const key = `${nameKey || item.key || item.label || "value"}`}
+ {@const itemConfig = getPayloadConfigFromPayload(
+ chart.config,
+ item,
+ key,
+ chartCtx.tooltip.data
+ )}
+ {@const indicatorColor = color || item.config?.color || item.color}
+
svg]:h-2.5 [&>svg]:w-2.5 [&>svg]:text-muted-foreground",
+ indicator === "dot" && "items-center"
+ )}
+ >
+ {#if formatter && item.value !== undefined && item.label}
+ {@render formatter({
+ value: item.value,
+ name: item.label,
+ item,
+ index: i,
+ payload: visibleSeries,
+ })}
+ {:else}
+ {#if itemConfig?.icon}
+
+ {:else if !hideIndicator}
+
+ {/if}
+
+
+ {#if nestLabel}
+ {@render TooltipLabel()}
+ {/if}
+
+ {itemConfig?.label || item.label}
+
+
+ {#if item.value !== undefined}
+
+ {item.value.toLocaleString()}
+
+ {/if}
+
+ {/if}
+
+ {/each}
+
+
+
diff --git a/src/lib/components/ui/chart/chart-utils.ts b/src/lib/components/ui/chart/chart-utils.ts
new file mode 100644
index 0000000..6e1f000
--- /dev/null
+++ b/src/lib/components/ui/chart/chart-utils.ts
@@ -0,0 +1,68 @@
+import { getContext, setContext, type Component, type Snippet } from "svelte";
+import type { Tooltip } from "layerchart";
+
+export const THEMES = { light: "", dark: ".dark" } as const;
+
+export type ChartConfig = {
+ [k in string]: {
+ label?: string;
+ icon?: Component;
+ } & (
+ | { color?: string; theme?: never }
+ | { color?: never; theme: Record }
+ );
+};
+
+export type ExtractSnippetParams = T extends Snippet<[infer P]> ? P : never;
+
+export type TooltipPayload = Tooltip.TooltipSeries;
+
+// Helper to extract item config from a payload.
+export function getPayloadConfigFromPayload(
+ config: ChartConfig,
+ payload: TooltipPayload,
+ key: string,
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ data?: Record | null
+) {
+ if (typeof payload !== "object" || payload === null) return undefined;
+
+ const payloadConfig =
+ "config" in payload && typeof payload.config === "object" && payload.config !== null
+ ? payload.config
+ : undefined;
+
+ let configLabelKey: string = key;
+
+ if (payload.key === key) {
+ configLabelKey = payload.key;
+ } else if (payload.label === key) {
+ configLabelKey = payload.label;
+ } else if (key in payload && typeof payload[key as keyof typeof payload] === "string") {
+ configLabelKey = payload[key as keyof typeof payload] as string;
+ } else if (
+ payloadConfig !== undefined &&
+ key in payloadConfig &&
+ typeof payloadConfig[key as keyof typeof payloadConfig] === "string"
+ ) {
+ configLabelKey = payloadConfig[key as keyof typeof payloadConfig] as string;
+ } else if (data != null && key in data && typeof data[key] === "string") {
+ configLabelKey = data[key] as string;
+ }
+
+ return configLabelKey in config ? config[configLabelKey] : config[key as keyof typeof config];
+}
+
+type ChartContextValue = {
+ config: ChartConfig;
+};
+
+const chartContextKey = Symbol("chart-context");
+
+export function setChartContext(value: ChartContextValue) {
+ return setContext(chartContextKey, value);
+}
+
+export function useChart() {
+ return getContext(chartContextKey);
+}
diff --git a/src/lib/components/ui/chart/index.ts b/src/lib/components/ui/chart/index.ts
new file mode 100644
index 0000000..f22375e
--- /dev/null
+++ b/src/lib/components/ui/chart/index.ts
@@ -0,0 +1,6 @@
+import ChartContainer from "./chart-container.svelte";
+import ChartTooltip from "./chart-tooltip.svelte";
+
+export { getPayloadConfigFromPayload, type ChartConfig } from "./chart-utils.js";
+
+export { ChartContainer, ChartTooltip, ChartContainer as Container, ChartTooltip as Tooltip };
diff --git a/src/lib/components/ui/checkbox/checkbox.svelte b/src/lib/components/ui/checkbox/checkbox.svelte
new file mode 100644
index 0000000..c892a8e
--- /dev/null
+++ b/src/lib/components/ui/checkbox/checkbox.svelte
@@ -0,0 +1,39 @@
+
+
+
+ {#snippet children({ checked, indeterminate })}
+
+ {#if checked}
+
+ {:else if indeterminate}
+
+ {/if}
+
+ {/snippet}
+
diff --git a/src/lib/components/ui/checkbox/index.ts b/src/lib/components/ui/checkbox/index.ts
new file mode 100644
index 0000000..6d92d94
--- /dev/null
+++ b/src/lib/components/ui/checkbox/index.ts
@@ -0,0 +1,6 @@
+import Root from "./checkbox.svelte";
+export {
+ Root,
+ //
+ Root as Checkbox,
+};
diff --git a/src/lib/components/ui/drawer/drawer-close.svelte b/src/lib/components/ui/drawer/drawer-close.svelte
new file mode 100644
index 0000000..95c2479
--- /dev/null
+++ b/src/lib/components/ui/drawer/drawer-close.svelte
@@ -0,0 +1,7 @@
+
+
+
diff --git a/src/lib/components/ui/drawer/drawer-content.svelte b/src/lib/components/ui/drawer/drawer-content.svelte
new file mode 100644
index 0000000..12ba01b
--- /dev/null
+++ b/src/lib/components/ui/drawer/drawer-content.svelte
@@ -0,0 +1,36 @@
+
+
+
+
+
+
+ {@render children?.()}
+
+
diff --git a/src/lib/components/ui/drawer/drawer-description.svelte b/src/lib/components/ui/drawer/drawer-description.svelte
new file mode 100644
index 0000000..b92db5a
--- /dev/null
+++ b/src/lib/components/ui/drawer/drawer-description.svelte
@@ -0,0 +1,17 @@
+
+
+
diff --git a/src/lib/components/ui/drawer/drawer-footer.svelte b/src/lib/components/ui/drawer/drawer-footer.svelte
new file mode 100644
index 0000000..9a4df1d
--- /dev/null
+++ b/src/lib/components/ui/drawer/drawer-footer.svelte
@@ -0,0 +1,20 @@
+
+
+
+ {@render children?.()}
+
diff --git a/src/lib/components/ui/drawer/drawer-header.svelte b/src/lib/components/ui/drawer/drawer-header.svelte
new file mode 100644
index 0000000..06dbfbd
--- /dev/null
+++ b/src/lib/components/ui/drawer/drawer-header.svelte
@@ -0,0 +1,23 @@
+
+
+
+ {@render children?.()}
+
diff --git a/src/lib/components/ui/drawer/drawer-nested.svelte b/src/lib/components/ui/drawer/drawer-nested.svelte
new file mode 100644
index 0000000..834af94
--- /dev/null
+++ b/src/lib/components/ui/drawer/drawer-nested.svelte
@@ -0,0 +1,12 @@
+
+
+
diff --git a/src/lib/components/ui/drawer/drawer-overlay.svelte b/src/lib/components/ui/drawer/drawer-overlay.svelte
new file mode 100644
index 0000000..742a0f6
--- /dev/null
+++ b/src/lib/components/ui/drawer/drawer-overlay.svelte
@@ -0,0 +1,20 @@
+
+
+
diff --git a/src/lib/components/ui/drawer/drawer-portal.svelte b/src/lib/components/ui/drawer/drawer-portal.svelte
new file mode 100644
index 0000000..5a0dd74
--- /dev/null
+++ b/src/lib/components/ui/drawer/drawer-portal.svelte
@@ -0,0 +1,7 @@
+
+
+
diff --git a/src/lib/components/ui/drawer/drawer-title.svelte b/src/lib/components/ui/drawer/drawer-title.svelte
new file mode 100644
index 0000000..b68fa68
--- /dev/null
+++ b/src/lib/components/ui/drawer/drawer-title.svelte
@@ -0,0 +1,17 @@
+
+
+
diff --git a/src/lib/components/ui/drawer/drawer-trigger.svelte b/src/lib/components/ui/drawer/drawer-trigger.svelte
new file mode 100644
index 0000000..f1877d8
--- /dev/null
+++ b/src/lib/components/ui/drawer/drawer-trigger.svelte
@@ -0,0 +1,7 @@
+
+
+
diff --git a/src/lib/components/ui/drawer/drawer.svelte b/src/lib/components/ui/drawer/drawer.svelte
new file mode 100644
index 0000000..0cb57ff
--- /dev/null
+++ b/src/lib/components/ui/drawer/drawer.svelte
@@ -0,0 +1,12 @@
+
+
+
diff --git a/src/lib/components/ui/drawer/index.ts b/src/lib/components/ui/drawer/index.ts
new file mode 100644
index 0000000..a71749d
--- /dev/null
+++ b/src/lib/components/ui/drawer/index.ts
@@ -0,0 +1,38 @@
+import Close from "./drawer-close.svelte";
+import Content from "./drawer-content.svelte";
+import Description from "./drawer-description.svelte";
+import Footer from "./drawer-footer.svelte";
+import Header from "./drawer-header.svelte";
+import NestedRoot from "./drawer-nested.svelte";
+import Overlay from "./drawer-overlay.svelte";
+import Portal from "./drawer-portal.svelte";
+import Title from "./drawer-title.svelte";
+import Trigger from "./drawer-trigger.svelte";
+import Root from "./drawer.svelte";
+
+export {
+ Root,
+ NestedRoot,
+ Content,
+ Description,
+ Overlay,
+ Footer,
+ Header,
+ Title,
+ Trigger,
+ Portal,
+ Close,
+
+ //
+ Root as Drawer,
+ NestedRoot as DrawerNestedRoot,
+ Content as DrawerContent,
+ Description as DrawerDescription,
+ Overlay as DrawerOverlay,
+ Footer as DrawerFooter,
+ Header as DrawerHeader,
+ Title as DrawerTitle,
+ Trigger as DrawerTrigger,
+ Portal as DrawerPortal,
+ Close as DrawerClose,
+};
diff --git a/src/lib/components/ui/dropdown-menu/dropdown-menu-checkbox-group.svelte b/src/lib/components/ui/dropdown-menu/dropdown-menu-checkbox-group.svelte
new file mode 100644
index 0000000..e0e1971
--- /dev/null
+++ b/src/lib/components/ui/dropdown-menu/dropdown-menu-checkbox-group.svelte
@@ -0,0 +1,16 @@
+
+
+
diff --git a/src/lib/components/ui/dropdown-menu/dropdown-menu-checkbox-item.svelte b/src/lib/components/ui/dropdown-menu/dropdown-menu-checkbox-item.svelte
new file mode 100644
index 0000000..89fd2d1
--- /dev/null
+++ b/src/lib/components/ui/dropdown-menu/dropdown-menu-checkbox-item.svelte
@@ -0,0 +1,46 @@
+
+
+
+ {#snippet children({ checked, indeterminate })}
+
+ {#if indeterminate}
+
+ {:else if checked}
+
+ {/if}
+
+ {@render childrenProp?.()}
+ {/snippet}
+
diff --git a/src/lib/components/ui/dropdown-menu/dropdown-menu-content.svelte b/src/lib/components/ui/dropdown-menu/dropdown-menu-content.svelte
new file mode 100644
index 0000000..ca3432c
--- /dev/null
+++ b/src/lib/components/ui/dropdown-menu/dropdown-menu-content.svelte
@@ -0,0 +1,31 @@
+
+
+
+
+
diff --git a/src/lib/components/ui/dropdown-menu/dropdown-menu-group-heading.svelte b/src/lib/components/ui/dropdown-menu/dropdown-menu-group-heading.svelte
new file mode 100644
index 0000000..e09062b
--- /dev/null
+++ b/src/lib/components/ui/dropdown-menu/dropdown-menu-group-heading.svelte
@@ -0,0 +1,22 @@
+
+
+
diff --git a/src/lib/components/ui/dropdown-menu/dropdown-menu-group.svelte b/src/lib/components/ui/dropdown-menu/dropdown-menu-group.svelte
new file mode 100644
index 0000000..aca1f7b
--- /dev/null
+++ b/src/lib/components/ui/dropdown-menu/dropdown-menu-group.svelte
@@ -0,0 +1,7 @@
+
+
+
diff --git a/src/lib/components/ui/dropdown-menu/dropdown-menu-item.svelte b/src/lib/components/ui/dropdown-menu/dropdown-menu-item.svelte
new file mode 100644
index 0000000..a342d6f
--- /dev/null
+++ b/src/lib/components/ui/dropdown-menu/dropdown-menu-item.svelte
@@ -0,0 +1,27 @@
+
+
+
diff --git a/src/lib/components/ui/dropdown-menu/dropdown-menu-label.svelte b/src/lib/components/ui/dropdown-menu/dropdown-menu-label.svelte
new file mode 100644
index 0000000..76a12dd
--- /dev/null
+++ b/src/lib/components/ui/dropdown-menu/dropdown-menu-label.svelte
@@ -0,0 +1,24 @@
+
+
+
+ {@render children?.()}
+
diff --git a/src/lib/components/ui/dropdown-menu/dropdown-menu-portal.svelte b/src/lib/components/ui/dropdown-menu/dropdown-menu-portal.svelte
new file mode 100644
index 0000000..274cfef
--- /dev/null
+++ b/src/lib/components/ui/dropdown-menu/dropdown-menu-portal.svelte
@@ -0,0 +1,7 @@
+
+
+
diff --git a/src/lib/components/ui/dropdown-menu/dropdown-menu-radio-group.svelte b/src/lib/components/ui/dropdown-menu/dropdown-menu-radio-group.svelte
new file mode 100644
index 0000000..189aef4
--- /dev/null
+++ b/src/lib/components/ui/dropdown-menu/dropdown-menu-radio-group.svelte
@@ -0,0 +1,16 @@
+
+
+
diff --git a/src/lib/components/ui/dropdown-menu/dropdown-menu-radio-item.svelte b/src/lib/components/ui/dropdown-menu/dropdown-menu-radio-item.svelte
new file mode 100644
index 0000000..1c1b669
--- /dev/null
+++ b/src/lib/components/ui/dropdown-menu/dropdown-menu-radio-item.svelte
@@ -0,0 +1,36 @@
+
+
+
+ {#snippet children({ checked })}
+
+ {#if checked}
+
+ {/if}
+
+ {@render childrenProp?.({ checked })}
+ {/snippet}
+
diff --git a/src/lib/components/ui/dropdown-menu/dropdown-menu-separator.svelte b/src/lib/components/ui/dropdown-menu/dropdown-menu-separator.svelte
new file mode 100644
index 0000000..ea5adbf
--- /dev/null
+++ b/src/lib/components/ui/dropdown-menu/dropdown-menu-separator.svelte
@@ -0,0 +1,17 @@
+
+
+
diff --git a/src/lib/components/ui/dropdown-menu/dropdown-menu-shortcut.svelte b/src/lib/components/ui/dropdown-menu/dropdown-menu-shortcut.svelte
new file mode 100644
index 0000000..af0241f
--- /dev/null
+++ b/src/lib/components/ui/dropdown-menu/dropdown-menu-shortcut.svelte
@@ -0,0 +1,20 @@
+
+
+
+ {@render children?.()}
+
diff --git a/src/lib/components/ui/dropdown-menu/dropdown-menu-sub-content.svelte b/src/lib/components/ui/dropdown-menu/dropdown-menu-sub-content.svelte
new file mode 100644
index 0000000..8b04d0b
--- /dev/null
+++ b/src/lib/components/ui/dropdown-menu/dropdown-menu-sub-content.svelte
@@ -0,0 +1,31 @@
+
+
+
+
+
diff --git a/src/lib/components/ui/dropdown-menu/dropdown-menu-sub-trigger.svelte b/src/lib/components/ui/dropdown-menu/dropdown-menu-sub-trigger.svelte
new file mode 100644
index 0000000..4df0109
--- /dev/null
+++ b/src/lib/components/ui/dropdown-menu/dropdown-menu-sub-trigger.svelte
@@ -0,0 +1,29 @@
+
+
+
+ {@render children?.()}
+
+
diff --git a/src/lib/components/ui/dropdown-menu/dropdown-menu-sub.svelte b/src/lib/components/ui/dropdown-menu/dropdown-menu-sub.svelte
new file mode 100644
index 0000000..f044581
--- /dev/null
+++ b/src/lib/components/ui/dropdown-menu/dropdown-menu-sub.svelte
@@ -0,0 +1,7 @@
+
+
+
diff --git a/src/lib/components/ui/dropdown-menu/dropdown-menu-trigger.svelte b/src/lib/components/ui/dropdown-menu/dropdown-menu-trigger.svelte
new file mode 100644
index 0000000..cb05344
--- /dev/null
+++ b/src/lib/components/ui/dropdown-menu/dropdown-menu-trigger.svelte
@@ -0,0 +1,7 @@
+
+
+
diff --git a/src/lib/components/ui/dropdown-menu/dropdown-menu.svelte b/src/lib/components/ui/dropdown-menu/dropdown-menu.svelte
new file mode 100644
index 0000000..cb4bc62
--- /dev/null
+++ b/src/lib/components/ui/dropdown-menu/dropdown-menu.svelte
@@ -0,0 +1,7 @@
+
+
+
diff --git a/src/lib/components/ui/dropdown-menu/index.ts b/src/lib/components/ui/dropdown-menu/index.ts
new file mode 100644
index 0000000..0c8bbd6
--- /dev/null
+++ b/src/lib/components/ui/dropdown-menu/index.ts
@@ -0,0 +1,54 @@
+import CheckboxGroup from "./dropdown-menu-checkbox-group.svelte";
+import CheckboxItem from "./dropdown-menu-checkbox-item.svelte";
+import Content from "./dropdown-menu-content.svelte";
+import GroupHeading from "./dropdown-menu-group-heading.svelte";
+import Group from "./dropdown-menu-group.svelte";
+import Item from "./dropdown-menu-item.svelte";
+import Label from "./dropdown-menu-label.svelte";
+import Portal from "./dropdown-menu-portal.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 SubContent from "./dropdown-menu-sub-content.svelte";
+import SubTrigger from "./dropdown-menu-sub-trigger.svelte";
+import Sub from "./dropdown-menu-sub.svelte";
+import Trigger from "./dropdown-menu-trigger.svelte";
+import Root from "./dropdown-menu.svelte";
+
+export {
+ CheckboxGroup,
+ CheckboxItem,
+ Content,
+ Portal,
+ Root as DropdownMenu,
+ CheckboxGroup as DropdownMenuCheckboxGroup,
+ CheckboxItem as DropdownMenuCheckboxItem,
+ Content as DropdownMenuContent,
+ Portal as DropdownMenuPortal,
+ 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,
+};
diff --git a/src/lib/components/ui/input/index.ts b/src/lib/components/ui/input/index.ts
new file mode 100644
index 0000000..f47b6d3
--- /dev/null
+++ b/src/lib/components/ui/input/index.ts
@@ -0,0 +1,7 @@
+import Root from "./input.svelte";
+
+export {
+ Root,
+ //
+ Root as Input,
+};
diff --git a/src/lib/components/ui/input/input.svelte b/src/lib/components/ui/input/input.svelte
new file mode 100644
index 0000000..a1ff9cb
--- /dev/null
+++ b/src/lib/components/ui/input/input.svelte
@@ -0,0 +1,48 @@
+
+
+{#if type === "file"}
+
+{:else}
+
+{/if}
diff --git a/src/lib/components/ui/label/index.ts b/src/lib/components/ui/label/index.ts
new file mode 100644
index 0000000..8bfca0b
--- /dev/null
+++ b/src/lib/components/ui/label/index.ts
@@ -0,0 +1,7 @@
+import Root from "./label.svelte";
+
+export {
+ Root,
+ //
+ Root as Label,
+};
diff --git a/src/lib/components/ui/label/label.svelte b/src/lib/components/ui/label/label.svelte
new file mode 100644
index 0000000..fd5573b
--- /dev/null
+++ b/src/lib/components/ui/label/label.svelte
@@ -0,0 +1,20 @@
+
+
+
diff --git a/src/lib/components/ui/select/index.ts b/src/lib/components/ui/select/index.ts
new file mode 100644
index 0000000..4960d45
--- /dev/null
+++ b/src/lib/components/ui/select/index.ts
@@ -0,0 +1,40 @@
+import Content from "./select-content.svelte";
+import GroupHeading from "./select-group-heading.svelte";
+import Group from "./select-group.svelte";
+import Item from "./select-item.svelte";
+import Label from "./select-label.svelte";
+import Portal from "./select-portal.svelte";
+import ScrollDownButton from "./select-scroll-down-button.svelte";
+import ScrollUpButton from "./select-scroll-up-button.svelte";
+import Separator from "./select-separator.svelte";
+import Trigger from "./select-trigger.svelte";
+import Value from "./select-value.svelte";
+import Root from "./select.svelte";
+
+export {
+ Root,
+ Group,
+ Label,
+ Item,
+ Content,
+ Trigger,
+ Separator,
+ ScrollDownButton,
+ ScrollUpButton,
+ GroupHeading,
+ Portal,
+ Value,
+ //
+ Root as Select,
+ Group as SelectGroup,
+ Label as SelectLabel,
+ Item as SelectItem,
+ Content as SelectContent,
+ Trigger as SelectTrigger,
+ Separator as SelectSeparator,
+ ScrollDownButton as SelectScrollDownButton,
+ ScrollUpButton as SelectScrollUpButton,
+ GroupHeading as SelectGroupHeading,
+ Portal as SelectPortal,
+ Value as SelectValue,
+};
diff --git a/src/lib/components/ui/select/select-content.svelte b/src/lib/components/ui/select/select-content.svelte
new file mode 100644
index 0000000..824e283
--- /dev/null
+++ b/src/lib/components/ui/select/select-content.svelte
@@ -0,0 +1,45 @@
+
+
+
+
+
+
+ {@render children?.()}
+
+
+
+
diff --git a/src/lib/components/ui/select/select-group-heading.svelte b/src/lib/components/ui/select/select-group-heading.svelte
new file mode 100644
index 0000000..8f12b57
--- /dev/null
+++ b/src/lib/components/ui/select/select-group-heading.svelte
@@ -0,0 +1,21 @@
+
+
+
+ {@render children?.()}
+
diff --git a/src/lib/components/ui/select/select-group.svelte b/src/lib/components/ui/select/select-group.svelte
new file mode 100644
index 0000000..f29f7b7
--- /dev/null
+++ b/src/lib/components/ui/select/select-group.svelte
@@ -0,0 +1,17 @@
+
+
+
diff --git a/src/lib/components/ui/select/select-item.svelte b/src/lib/components/ui/select/select-item.svelte
new file mode 100644
index 0000000..935b274
--- /dev/null
+++ b/src/lib/components/ui/select/select-item.svelte
@@ -0,0 +1,42 @@
+
+
+
+ {#snippet children({ selected, highlighted })}
+
+ {#if selected}
+
+ {/if}
+
+
+ {#if childrenProp}
+ {@render childrenProp({ selected, highlighted })}
+ {:else}
+ {label || value}
+ {/if}
+
+ {/snippet}
+
diff --git a/src/lib/components/ui/select/select-label.svelte b/src/lib/components/ui/select/select-label.svelte
new file mode 100644
index 0000000..507f410
--- /dev/null
+++ b/src/lib/components/ui/select/select-label.svelte
@@ -0,0 +1,20 @@
+
+
+
+ {@render children?.()}
+
diff --git a/src/lib/components/ui/select/select-portal.svelte b/src/lib/components/ui/select/select-portal.svelte
new file mode 100644
index 0000000..424bcdd
--- /dev/null
+++ b/src/lib/components/ui/select/select-portal.svelte
@@ -0,0 +1,7 @@
+
+
+
diff --git a/src/lib/components/ui/select/select-scroll-down-button.svelte b/src/lib/components/ui/select/select-scroll-down-button.svelte
new file mode 100644
index 0000000..befc335
--- /dev/null
+++ b/src/lib/components/ui/select/select-scroll-down-button.svelte
@@ -0,0 +1,20 @@
+
+
+
+
+
diff --git a/src/lib/components/ui/select/select-scroll-up-button.svelte b/src/lib/components/ui/select/select-scroll-up-button.svelte
new file mode 100644
index 0000000..3e3b639
--- /dev/null
+++ b/src/lib/components/ui/select/select-scroll-up-button.svelte
@@ -0,0 +1,20 @@
+
+
+
+
+
diff --git a/src/lib/components/ui/select/select-separator.svelte b/src/lib/components/ui/select/select-separator.svelte
new file mode 100644
index 0000000..8d40830
--- /dev/null
+++ b/src/lib/components/ui/select/select-separator.svelte
@@ -0,0 +1,18 @@
+
+
+
diff --git a/src/lib/components/ui/select/select-trigger.svelte b/src/lib/components/ui/select/select-trigger.svelte
new file mode 100644
index 0000000..d454b9a
--- /dev/null
+++ b/src/lib/components/ui/select/select-trigger.svelte
@@ -0,0 +1,29 @@
+
+
+
+ {@render children?.()}
+
+
diff --git a/src/lib/components/ui/select/select-value.svelte b/src/lib/components/ui/select/select-value.svelte
new file mode 100644
index 0000000..ff34b0e
--- /dev/null
+++ b/src/lib/components/ui/select/select-value.svelte
@@ -0,0 +1,7 @@
+
+
+
diff --git a/src/lib/components/ui/select/select.svelte b/src/lib/components/ui/select/select.svelte
new file mode 100644
index 0000000..05eb663
--- /dev/null
+++ b/src/lib/components/ui/select/select.svelte
@@ -0,0 +1,11 @@
+
+
+
diff --git a/src/lib/components/ui/separator/index.ts b/src/lib/components/ui/separator/index.ts
new file mode 100644
index 0000000..82442d2
--- /dev/null
+++ b/src/lib/components/ui/separator/index.ts
@@ -0,0 +1,7 @@
+import Root from "./separator.svelte";
+
+export {
+ Root,
+ //
+ Root as Separator,
+};
diff --git a/src/lib/components/ui/separator/separator.svelte b/src/lib/components/ui/separator/separator.svelte
new file mode 100644
index 0000000..e7f4734
--- /dev/null
+++ b/src/lib/components/ui/separator/separator.svelte
@@ -0,0 +1,21 @@
+
+
+
diff --git a/src/lib/components/ui/sheet/index.ts b/src/lib/components/ui/sheet/index.ts
new file mode 100644
index 0000000..12a55b2
--- /dev/null
+++ b/src/lib/components/ui/sheet/index.ts
@@ -0,0 +1,34 @@
+import Close from "./sheet-close.svelte";
+import Content from "./sheet-content.svelte";
+import Description from "./sheet-description.svelte";
+import Footer from "./sheet-footer.svelte";
+import Header from "./sheet-header.svelte";
+import Overlay from "./sheet-overlay.svelte";
+import Portal from "./sheet-portal.svelte";
+import Title from "./sheet-title.svelte";
+import Trigger from "./sheet-trigger.svelte";
+import Root from "./sheet.svelte";
+
+export {
+ Root,
+ Close,
+ Trigger,
+ Portal,
+ Overlay,
+ Content,
+ Header,
+ Footer,
+ Title,
+ Description,
+ //
+ Root as Sheet,
+ Close as SheetClose,
+ Trigger as SheetTrigger,
+ Portal as SheetPortal,
+ Overlay as SheetOverlay,
+ Content as SheetContent,
+ Header as SheetHeader,
+ Footer as SheetFooter,
+ Title as SheetTitle,
+ Description as SheetDescription,
+};
diff --git a/src/lib/components/ui/sheet/sheet-close.svelte b/src/lib/components/ui/sheet/sheet-close.svelte
new file mode 100644
index 0000000..ae382c1
--- /dev/null
+++ b/src/lib/components/ui/sheet/sheet-close.svelte
@@ -0,0 +1,7 @@
+
+
+
diff --git a/src/lib/components/ui/sheet/sheet-content.svelte b/src/lib/components/ui/sheet/sheet-content.svelte
new file mode 100644
index 0000000..c80aadb
--- /dev/null
+++ b/src/lib/components/ui/sheet/sheet-content.svelte
@@ -0,0 +1,55 @@
+
+
+
+
+
+
+
+ {@render children?.()}
+ {#if showCloseButton}
+
+ {#snippet child({ props })}
+
+ {/snippet}
+
+ {/if}
+
+
diff --git a/src/lib/components/ui/sheet/sheet-description.svelte b/src/lib/components/ui/sheet/sheet-description.svelte
new file mode 100644
index 0000000..888236e
--- /dev/null
+++ b/src/lib/components/ui/sheet/sheet-description.svelte
@@ -0,0 +1,17 @@
+
+
+
diff --git a/src/lib/components/ui/sheet/sheet-footer.svelte b/src/lib/components/ui/sheet/sheet-footer.svelte
new file mode 100644
index 0000000..0ca6199
--- /dev/null
+++ b/src/lib/components/ui/sheet/sheet-footer.svelte
@@ -0,0 +1,20 @@
+
+
+
+ {@render children?.()}
+
diff --git a/src/lib/components/ui/sheet/sheet-header.svelte b/src/lib/components/ui/sheet/sheet-header.svelte
new file mode 100644
index 0000000..8fe1ff0
--- /dev/null
+++ b/src/lib/components/ui/sheet/sheet-header.svelte
@@ -0,0 +1,20 @@
+
+
+
+ {@render children?.()}
+
diff --git a/src/lib/components/ui/sheet/sheet-overlay.svelte b/src/lib/components/ui/sheet/sheet-overlay.svelte
new file mode 100644
index 0000000..6b35ea6
--- /dev/null
+++ b/src/lib/components/ui/sheet/sheet-overlay.svelte
@@ -0,0 +1,20 @@
+
+
+
diff --git a/src/lib/components/ui/sheet/sheet-portal.svelte b/src/lib/components/ui/sheet/sheet-portal.svelte
new file mode 100644
index 0000000..f3085a3
--- /dev/null
+++ b/src/lib/components/ui/sheet/sheet-portal.svelte
@@ -0,0 +1,7 @@
+
+
+
diff --git a/src/lib/components/ui/sheet/sheet-title.svelte b/src/lib/components/ui/sheet/sheet-title.svelte
new file mode 100644
index 0000000..0f39e52
--- /dev/null
+++ b/src/lib/components/ui/sheet/sheet-title.svelte
@@ -0,0 +1,17 @@
+
+
+
diff --git a/src/lib/components/ui/sheet/sheet-trigger.svelte b/src/lib/components/ui/sheet/sheet-trigger.svelte
new file mode 100644
index 0000000..e266975
--- /dev/null
+++ b/src/lib/components/ui/sheet/sheet-trigger.svelte
@@ -0,0 +1,7 @@
+
+
+
diff --git a/src/lib/components/ui/sheet/sheet.svelte b/src/lib/components/ui/sheet/sheet.svelte
new file mode 100644
index 0000000..5bf9783
--- /dev/null
+++ b/src/lib/components/ui/sheet/sheet.svelte
@@ -0,0 +1,7 @@
+
+
+
diff --git a/src/lib/components/ui/sidebar/constants.ts b/src/lib/components/ui/sidebar/constants.ts
new file mode 100644
index 0000000..1347e83
--- /dev/null
+++ b/src/lib/components/ui/sidebar/constants.ts
@@ -0,0 +1,6 @@
+export const SIDEBAR_COOKIE_NAME = "sidebar_state";
+export const SIDEBAR_COOKIE_MAX_AGE = 60 * 60 * 24 * 7;
+export const SIDEBAR_WIDTH = "16rem";
+export const SIDEBAR_WIDTH_MOBILE = "18rem";
+export const SIDEBAR_WIDTH_ICON = "3rem";
+export const SIDEBAR_KEYBOARD_SHORTCUT = "b";
diff --git a/src/lib/components/ui/sidebar/context.svelte.ts b/src/lib/components/ui/sidebar/context.svelte.ts
new file mode 100644
index 0000000..d5fa0fa
--- /dev/null
+++ b/src/lib/components/ui/sidebar/context.svelte.ts
@@ -0,0 +1,79 @@
+import { getContext, setContext } from "svelte";
+import { IsMobile } from "#lib/hooks/is-mobile.svelte.js";
+import { SIDEBAR_KEYBOARD_SHORTCUT } from "./constants.js";
+
+type Getter = () => T;
+
+export type SidebarStateProps = {
+ /**
+ * A getter function that returns the current open state of the sidebar.
+ * We use a getter function here to support `bind:open` on the `Sidebar.Provider`
+ * component.
+ */
+ open: Getter;
+
+ /**
+ * A function that sets the open state of the sidebar. To support `bind:open`, we need
+ * a source of truth for changing the open state to ensure it will be synced throughout
+ * the sub-components and any `bind:` references.
+ */
+ setOpen: (open: boolean) => void;
+};
+
+class SidebarState {
+ readonly props: SidebarStateProps;
+ open = $derived.by(() => this.props.open());
+ openMobile = $state(false);
+ setOpen: SidebarStateProps["setOpen"];
+ #isMobile: IsMobile;
+ state = $derived.by(() => (this.open ? "expanded" : "collapsed"));
+
+ constructor(props: SidebarStateProps) {
+ this.setOpen = props.setOpen;
+ this.#isMobile = new IsMobile();
+ this.props = props;
+ }
+
+ // Convenience getter for checking if the sidebar is mobile
+ // without this, we would need to use `sidebar.isMobile.current` everywhere
+ get isMobile() {
+ return this.#isMobile.current;
+ }
+
+ // Event handler to apply to the ``
+ handleShortcutKeydown = (e: KeyboardEvent) => {
+ if (e.key === SIDEBAR_KEYBOARD_SHORTCUT && (e.metaKey || e.ctrlKey)) {
+ e.preventDefault();
+ this.toggle();
+ }
+ };
+
+ setOpenMobile = (value: boolean) => {
+ this.openMobile = value;
+ };
+
+ toggle = () => {
+ return this.#isMobile.current ? (this.openMobile = !this.openMobile) : this.setOpen(!this.open);
+ };
+}
+
+const SYMBOL_KEY = "scn-sidebar";
+
+/**
+ * Instantiates a new `SidebarState` instance and sets it in the context.
+ *
+ * @param props The constructor props for the `SidebarState` class.
+ * @returns The `SidebarState` instance.
+ */
+export function setSidebar(props: SidebarStateProps): SidebarState {
+ return setContext(Symbol.for(SYMBOL_KEY), new SidebarState(props));
+}
+
+/**
+ * Retrieves the `SidebarState` instance from the context. This is a class instance,
+ * so you cannot destructure it.
+ * @returns The `SidebarState` instance.
+ */
+export function useSidebar(): SidebarState {
+ return getContext(Symbol.for(SYMBOL_KEY));
+}
diff --git a/src/lib/components/ui/sidebar/index.ts b/src/lib/components/ui/sidebar/index.ts
new file mode 100644
index 0000000..6e65d82
--- /dev/null
+++ b/src/lib/components/ui/sidebar/index.ts
@@ -0,0 +1,75 @@
+import Content from "./sidebar-content.svelte";
+import Footer from "./sidebar-footer.svelte";
+import GroupAction from "./sidebar-group-action.svelte";
+import GroupContent from "./sidebar-group-content.svelte";
+import GroupLabel from "./sidebar-group-label.svelte";
+import Group from "./sidebar-group.svelte";
+import Header from "./sidebar-header.svelte";
+import Input from "./sidebar-input.svelte";
+import Inset from "./sidebar-inset.svelte";
+import MenuAction from "./sidebar-menu-action.svelte";
+import MenuBadge from "./sidebar-menu-badge.svelte";
+import MenuButton from "./sidebar-menu-button.svelte";
+import MenuItem from "./sidebar-menu-item.svelte";
+import MenuSkeleton from "./sidebar-menu-skeleton.svelte";
+import MenuSubButton from "./sidebar-menu-sub-button.svelte";
+import MenuSubItem from "./sidebar-menu-sub-item.svelte";
+import MenuSub from "./sidebar-menu-sub.svelte";
+import Menu from "./sidebar-menu.svelte";
+import Provider from "./sidebar-provider.svelte";
+import Rail from "./sidebar-rail.svelte";
+import Separator from "./sidebar-separator.svelte";
+import Trigger from "./sidebar-trigger.svelte";
+import Root from "./sidebar.svelte";
+import { useSidebar } from "./context.svelte.js";
+
+export {
+ Content,
+ Footer,
+ Group,
+ GroupAction,
+ GroupContent,
+ GroupLabel,
+ Header,
+ Input,
+ Inset,
+ Menu,
+ MenuAction,
+ MenuBadge,
+ MenuButton,
+ MenuItem,
+ MenuSkeleton,
+ MenuSub,
+ MenuSubButton,
+ MenuSubItem,
+ Provider,
+ Rail,
+ Root,
+ Separator,
+ //
+ Root as Sidebar,
+ Content as SidebarContent,
+ Footer as SidebarFooter,
+ Group as SidebarGroup,
+ GroupAction as SidebarGroupAction,
+ GroupContent as SidebarGroupContent,
+ GroupLabel as SidebarGroupLabel,
+ Header as SidebarHeader,
+ Input as SidebarInput,
+ Inset as SidebarInset,
+ Menu as SidebarMenu,
+ MenuAction as SidebarMenuAction,
+ MenuBadge as SidebarMenuBadge,
+ MenuButton as SidebarMenuButton,
+ MenuItem as SidebarMenuItem,
+ MenuSkeleton as SidebarMenuSkeleton,
+ MenuSub as SidebarMenuSub,
+ MenuSubButton as SidebarMenuSubButton,
+ MenuSubItem as SidebarMenuSubItem,
+ Provider as SidebarProvider,
+ Rail as SidebarRail,
+ Separator as SidebarSeparator,
+ Trigger as SidebarTrigger,
+ Trigger,
+ useSidebar,
+};
diff --git a/src/lib/components/ui/sidebar/sidebar-content.svelte b/src/lib/components/ui/sidebar/sidebar-content.svelte
new file mode 100644
index 0000000..bff883b
--- /dev/null
+++ b/src/lib/components/ui/sidebar/sidebar-content.svelte
@@ -0,0 +1,24 @@
+
+
+
+ {@render children?.()}
+
diff --git a/src/lib/components/ui/sidebar/sidebar-footer.svelte b/src/lib/components/ui/sidebar/sidebar-footer.svelte
new file mode 100644
index 0000000..7bf0b89
--- /dev/null
+++ b/src/lib/components/ui/sidebar/sidebar-footer.svelte
@@ -0,0 +1,21 @@
+
+
+
+ {@render children?.()}
+
diff --git a/src/lib/components/ui/sidebar/sidebar-group-action.svelte b/src/lib/components/ui/sidebar/sidebar-group-action.svelte
new file mode 100644
index 0000000..30346f4
--- /dev/null
+++ b/src/lib/components/ui/sidebar/sidebar-group-action.svelte
@@ -0,0 +1,33 @@
+
+
+{#if child}
+ {@render child({ props: mergedProps })}
+{:else}
+
+{/if}
diff --git a/src/lib/components/ui/sidebar/sidebar-group-content.svelte b/src/lib/components/ui/sidebar/sidebar-group-content.svelte
new file mode 100644
index 0000000..864def1
--- /dev/null
+++ b/src/lib/components/ui/sidebar/sidebar-group-content.svelte
@@ -0,0 +1,21 @@
+
+
+
+ {@render children?.()}
+
diff --git a/src/lib/components/ui/sidebar/sidebar-group-label.svelte b/src/lib/components/ui/sidebar/sidebar-group-label.svelte
new file mode 100644
index 0000000..95741a1
--- /dev/null
+++ b/src/lib/components/ui/sidebar/sidebar-group-label.svelte
@@ -0,0 +1,33 @@
+
+
+{#if child}
+ {@render child({ props: mergedProps })}
+{:else}
+
+ {@render children?.()}
+
+{/if}
diff --git a/src/lib/components/ui/sidebar/sidebar-group.svelte b/src/lib/components/ui/sidebar/sidebar-group.svelte
new file mode 100644
index 0000000..0302248
--- /dev/null
+++ b/src/lib/components/ui/sidebar/sidebar-group.svelte
@@ -0,0 +1,21 @@
+
+
+
+ {@render children?.()}
+
diff --git a/src/lib/components/ui/sidebar/sidebar-header.svelte b/src/lib/components/ui/sidebar/sidebar-header.svelte
new file mode 100644
index 0000000..7a0c266
--- /dev/null
+++ b/src/lib/components/ui/sidebar/sidebar-header.svelte
@@ -0,0 +1,21 @@
+
+
+
+ {@render children?.()}
+
diff --git a/src/lib/components/ui/sidebar/sidebar-input.svelte b/src/lib/components/ui/sidebar/sidebar-input.svelte
new file mode 100644
index 0000000..486bd97
--- /dev/null
+++ b/src/lib/components/ui/sidebar/sidebar-input.svelte
@@ -0,0 +1,21 @@
+
+
+
diff --git a/src/lib/components/ui/sidebar/sidebar-inset.svelte b/src/lib/components/ui/sidebar/sidebar-inset.svelte
new file mode 100644
index 0000000..3313c19
--- /dev/null
+++ b/src/lib/components/ui/sidebar/sidebar-inset.svelte
@@ -0,0 +1,20 @@
+
+
+
+ {@render children?.()}
+
diff --git a/src/lib/components/ui/sidebar/sidebar-menu-action.svelte b/src/lib/components/ui/sidebar/sidebar-menu-action.svelte
new file mode 100644
index 0000000..1de5c9d
--- /dev/null
+++ b/src/lib/components/ui/sidebar/sidebar-menu-action.svelte
@@ -0,0 +1,37 @@
+
+
+{#if child}
+ {@render child({ props: mergedProps })}
+{:else}
+
+{/if}
diff --git a/src/lib/components/ui/sidebar/sidebar-menu-badge.svelte b/src/lib/components/ui/sidebar/sidebar-menu-badge.svelte
new file mode 100644
index 0000000..2560802
--- /dev/null
+++ b/src/lib/components/ui/sidebar/sidebar-menu-badge.svelte
@@ -0,0 +1,24 @@
+
+
+
+ {@render children?.()}
+
diff --git a/src/lib/components/ui/sidebar/sidebar-menu-button.svelte b/src/lib/components/ui/sidebar/sidebar-menu-button.svelte
new file mode 100644
index 0000000..1e09a4f
--- /dev/null
+++ b/src/lib/components/ui/sidebar/sidebar-menu-button.svelte
@@ -0,0 +1,100 @@
+
+
+
+
+{#snippet Button({ props }: { props?: Record })}
+ {@const mergedProps = mergeProps(buttonProps, props)}
+ {#if child}
+ {@render child({ props: mergedProps })}
+ {:else}
+
+ {/if}
+{/snippet}
+
+{#if !tooltipContent}
+ {@render Button({})}
+{:else}
+
+
+ {#snippet child({ props })}
+ {@render Button({ props })}
+ {/snippet}
+
+
+ {#if typeof tooltipContent === "string"}
+ {tooltipContent}
+ {:else if tooltipContent}
+ {@render tooltipContent()}
+ {/if}
+
+
+{/if}
diff --git a/src/lib/components/ui/sidebar/sidebar-menu-item.svelte b/src/lib/components/ui/sidebar/sidebar-menu-item.svelte
new file mode 100644
index 0000000..0f5b24c
--- /dev/null
+++ b/src/lib/components/ui/sidebar/sidebar-menu-item.svelte
@@ -0,0 +1,21 @@
+
+
+
diff --git a/src/lib/components/ui/sidebar/sidebar-menu-skeleton.svelte b/src/lib/components/ui/sidebar/sidebar-menu-skeleton.svelte
new file mode 100644
index 0000000..7b29a62
--- /dev/null
+++ b/src/lib/components/ui/sidebar/sidebar-menu-skeleton.svelte
@@ -0,0 +1,36 @@
+
+
+
+ {#if showIcon}
+
+ {/if}
+
+ {@render children?.()}
+
diff --git a/src/lib/components/ui/sidebar/sidebar-menu-sub-button.svelte b/src/lib/components/ui/sidebar/sidebar-menu-sub-button.svelte
new file mode 100644
index 0000000..6ee065a
--- /dev/null
+++ b/src/lib/components/ui/sidebar/sidebar-menu-sub-button.svelte
@@ -0,0 +1,39 @@
+
+
+{#if child}
+ {@render child({ props: mergedProps })}
+{:else}
+
+ {@render children?.()}
+
+{/if}
diff --git a/src/lib/components/ui/sidebar/sidebar-menu-sub-item.svelte b/src/lib/components/ui/sidebar/sidebar-menu-sub-item.svelte
new file mode 100644
index 0000000..1f74381
--- /dev/null
+++ b/src/lib/components/ui/sidebar/sidebar-menu-sub-item.svelte
@@ -0,0 +1,21 @@
+
+
+
diff --git a/src/lib/components/ui/sidebar/sidebar-menu-sub.svelte b/src/lib/components/ui/sidebar/sidebar-menu-sub.svelte
new file mode 100644
index 0000000..3b6958c
--- /dev/null
+++ b/src/lib/components/ui/sidebar/sidebar-menu-sub.svelte
@@ -0,0 +1,25 @@
+
+
+
+ {@render children?.()}
+
diff --git a/src/lib/components/ui/sidebar/sidebar-menu.svelte b/src/lib/components/ui/sidebar/sidebar-menu.svelte
new file mode 100644
index 0000000..02805d2
--- /dev/null
+++ b/src/lib/components/ui/sidebar/sidebar-menu.svelte
@@ -0,0 +1,21 @@
+
+
+
+ {@render children?.()}
+
diff --git a/src/lib/components/ui/sidebar/sidebar-provider.svelte b/src/lib/components/ui/sidebar/sidebar-provider.svelte
new file mode 100644
index 0000000..7a2e0e4
--- /dev/null
+++ b/src/lib/components/ui/sidebar/sidebar-provider.svelte
@@ -0,0 +1,53 @@
+
+
+
+
+
+
+ {@render children?.()}
+
+
diff --git a/src/lib/components/ui/sidebar/sidebar-rail.svelte b/src/lib/components/ui/sidebar/sidebar-rail.svelte
new file mode 100644
index 0000000..79a2dba
--- /dev/null
+++ b/src/lib/components/ui/sidebar/sidebar-rail.svelte
@@ -0,0 +1,36 @@
+
+
+
diff --git a/src/lib/components/ui/sidebar/sidebar-separator.svelte b/src/lib/components/ui/sidebar/sidebar-separator.svelte
new file mode 100644
index 0000000..a7546e1
--- /dev/null
+++ b/src/lib/components/ui/sidebar/sidebar-separator.svelte
@@ -0,0 +1,19 @@
+
+
+
diff --git a/src/lib/components/ui/sidebar/sidebar-trigger.svelte b/src/lib/components/ui/sidebar/sidebar-trigger.svelte
new file mode 100644
index 0000000..d5497ce
--- /dev/null
+++ b/src/lib/components/ui/sidebar/sidebar-trigger.svelte
@@ -0,0 +1,36 @@
+
+
+
diff --git a/src/lib/components/ui/sidebar/sidebar.svelte b/src/lib/components/ui/sidebar/sidebar.svelte
new file mode 100644
index 0000000..0d86679
--- /dev/null
+++ b/src/lib/components/ui/sidebar/sidebar.svelte
@@ -0,0 +1,103 @@
+
+
+{#if collapsible === "none"}
+
+ {@render children?.()}
+
+{:else if sidebar.isMobile}
+ sidebar.openMobile, (v) => sidebar.setOpenMobile(v)} {...restProps}>
+ button]:hidden",
+ className
+ )}
+ style="--sidebar-width: {SIDEBAR_WIDTH_MOBILE};"
+ {side}
+ >
+
+ Sidebar
+ Displays the mobile sidebar.
+
+
+ {@render children?.()}
+
+
+
+{:else}
+
+{/if}
diff --git a/src/lib/components/ui/skeleton/index.ts b/src/lib/components/ui/skeleton/index.ts
new file mode 100644
index 0000000..186db21
--- /dev/null
+++ b/src/lib/components/ui/skeleton/index.ts
@@ -0,0 +1,7 @@
+import Root from "./skeleton.svelte";
+
+export {
+ Root,
+ //
+ Root as Skeleton,
+};
diff --git a/src/lib/components/ui/skeleton/skeleton.svelte b/src/lib/components/ui/skeleton/skeleton.svelte
new file mode 100644
index 0000000..d885b71
--- /dev/null
+++ b/src/lib/components/ui/skeleton/skeleton.svelte
@@ -0,0 +1,17 @@
+
+
+
diff --git a/src/lib/components/ui/table/index.ts b/src/lib/components/ui/table/index.ts
new file mode 100644
index 0000000..841ee58
--- /dev/null
+++ b/src/lib/components/ui/table/index.ts
@@ -0,0 +1,28 @@
+import Body from "./table-body.svelte";
+import Caption from "./table-caption.svelte";
+import Cell from "./table-cell.svelte";
+import Footer from "./table-footer.svelte";
+import Head from "./table-head.svelte";
+import Header from "./table-header.svelte";
+import Row from "./table-row.svelte";
+import Root from "./table.svelte";
+
+export {
+ Root,
+ Body,
+ Caption,
+ Cell,
+ Footer,
+ Head,
+ Header,
+ Row,
+ //
+ Root as Table,
+ Body as TableBody,
+ Caption as TableCaption,
+ Cell as TableCell,
+ Footer as TableFooter,
+ Head as TableHead,
+ Header as TableHeader,
+ Row as TableRow,
+};
diff --git a/src/lib/components/ui/table/table-body.svelte b/src/lib/components/ui/table/table-body.svelte
new file mode 100644
index 0000000..3d2254b
--- /dev/null
+++ b/src/lib/components/ui/table/table-body.svelte
@@ -0,0 +1,15 @@
+
+
+
+ {@render children?.()}
+
diff --git a/src/lib/components/ui/table/table-caption.svelte b/src/lib/components/ui/table/table-caption.svelte
new file mode 100644
index 0000000..8782558
--- /dev/null
+++ b/src/lib/components/ui/table/table-caption.svelte
@@ -0,0 +1,20 @@
+
+
+
+ {@render children?.()}
+
diff --git a/src/lib/components/ui/table/table-cell.svelte b/src/lib/components/ui/table/table-cell.svelte
new file mode 100644
index 0000000..794cf65
--- /dev/null
+++ b/src/lib/components/ui/table/table-cell.svelte
@@ -0,0 +1,15 @@
+
+
+
+ {@render children?.()}
+ |
diff --git a/src/lib/components/ui/table/table-footer.svelte b/src/lib/components/ui/table/table-footer.svelte
new file mode 100644
index 0000000..f56049a
--- /dev/null
+++ b/src/lib/components/ui/table/table-footer.svelte
@@ -0,0 +1,20 @@
+
+
+tr]:last:border-b-0", className)}
+ {...restProps}
+>
+ {@render children?.()}
+
diff --git a/src/lib/components/ui/table/table-head.svelte b/src/lib/components/ui/table/table-head.svelte
new file mode 100644
index 0000000..419e30b
--- /dev/null
+++ b/src/lib/components/ui/table/table-head.svelte
@@ -0,0 +1,15 @@
+
+
+
+ {@render children?.()}
+ |
diff --git a/src/lib/components/ui/table/table-header.svelte b/src/lib/components/ui/table/table-header.svelte
new file mode 100644
index 0000000..8864778
--- /dev/null
+++ b/src/lib/components/ui/table/table-header.svelte
@@ -0,0 +1,20 @@
+
+
+
+ {@render children?.()}
+
diff --git a/src/lib/components/ui/table/table-row.svelte b/src/lib/components/ui/table/table-row.svelte
new file mode 100644
index 0000000..5cbd53b
--- /dev/null
+++ b/src/lib/components/ui/table/table-row.svelte
@@ -0,0 +1,20 @@
+
+
+
+ {@render children?.()}
+
diff --git a/src/lib/components/ui/table/table.svelte b/src/lib/components/ui/table/table.svelte
new file mode 100644
index 0000000..fc78ac4
--- /dev/null
+++ b/src/lib/components/ui/table/table.svelte
@@ -0,0 +1,17 @@
+
+
+
+
+ {@render children?.()}
+
+
diff --git a/src/lib/components/ui/tabs/index.ts b/src/lib/components/ui/tabs/index.ts
new file mode 100644
index 0000000..581b188
--- /dev/null
+++ b/src/lib/components/ui/tabs/index.ts
@@ -0,0 +1,18 @@
+import Content from "./tabs-content.svelte";
+import Trigger from "./tabs-trigger.svelte";
+import Root from "./tabs.svelte";
+import List, { tabsListVariants, type TabsListVariant } from "./tabs-list.svelte";
+
+export {
+ Root,
+ Content,
+ List,
+ Trigger,
+ tabsListVariants,
+ type TabsListVariant,
+ //
+ Root as Tabs,
+ Content as TabsContent,
+ List as TabsList,
+ Trigger as TabsTrigger,
+};
diff --git a/src/lib/components/ui/tabs/tabs-content.svelte b/src/lib/components/ui/tabs/tabs-content.svelte
new file mode 100644
index 0000000..f1afa32
--- /dev/null
+++ b/src/lib/components/ui/tabs/tabs-content.svelte
@@ -0,0 +1,17 @@
+
+
+
diff --git a/src/lib/components/ui/tabs/tabs-list.svelte b/src/lib/components/ui/tabs/tabs-list.svelte
new file mode 100644
index 0000000..15c7096
--- /dev/null
+++ b/src/lib/components/ui/tabs/tabs-list.svelte
@@ -0,0 +1,40 @@
+
+
+
+
+
diff --git a/src/lib/components/ui/tabs/tabs-trigger.svelte b/src/lib/components/ui/tabs/tabs-trigger.svelte
new file mode 100644
index 0000000..2374e5f
--- /dev/null
+++ b/src/lib/components/ui/tabs/tabs-trigger.svelte
@@ -0,0 +1,23 @@
+
+
+
diff --git a/src/lib/components/ui/tabs/tabs.svelte b/src/lib/components/ui/tabs/tabs.svelte
new file mode 100644
index 0000000..eb78704
--- /dev/null
+++ b/src/lib/components/ui/tabs/tabs.svelte
@@ -0,0 +1,19 @@
+
+
+
diff --git a/src/lib/components/ui/toggle-group/index.ts b/src/lib/components/ui/toggle-group/index.ts
new file mode 100644
index 0000000..04cefa1
--- /dev/null
+++ b/src/lib/components/ui/toggle-group/index.ts
@@ -0,0 +1,10 @@
+import Item from "./toggle-group-item.svelte";
+import Root from "./toggle-group.svelte";
+
+export {
+ Root,
+ Item,
+ //
+ Root as ToggleGroup,
+ Item as ToggleGroupItem,
+};
diff --git a/src/lib/components/ui/toggle-group/toggle-group-item.svelte b/src/lib/components/ui/toggle-group/toggle-group-item.svelte
new file mode 100644
index 0000000..6857765
--- /dev/null
+++ b/src/lib/components/ui/toggle-group/toggle-group-item.svelte
@@ -0,0 +1,35 @@
+
+
+
diff --git a/src/lib/components/ui/toggle-group/toggle-group.svelte b/src/lib/components/ui/toggle-group/toggle-group.svelte
new file mode 100644
index 0000000..2c637b3
--- /dev/null
+++ b/src/lib/components/ui/toggle-group/toggle-group.svelte
@@ -0,0 +1,75 @@
+
+
+
+
+
+
diff --git a/src/lib/components/ui/toggle/index.ts b/src/lib/components/ui/toggle/index.ts
new file mode 100644
index 0000000..8cb2936
--- /dev/null
+++ b/src/lib/components/ui/toggle/index.ts
@@ -0,0 +1,13 @@
+import Root from "./toggle.svelte";
+export {
+ toggleVariants,
+ type ToggleSize,
+ type ToggleVariant,
+ type ToggleVariants,
+} from "./toggle.svelte";
+
+export {
+ Root,
+ //
+ Root as Toggle,
+};
diff --git a/src/lib/components/ui/toggle/toggle.svelte b/src/lib/components/ui/toggle/toggle.svelte
new file mode 100644
index 0000000..a19de8d
--- /dev/null
+++ b/src/lib/components/ui/toggle/toggle.svelte
@@ -0,0 +1,51 @@
+
+
+
+
+
diff --git a/src/lib/components/ui/tooltip/index.ts b/src/lib/components/ui/tooltip/index.ts
new file mode 100644
index 0000000..d7d2f13
--- /dev/null
+++ b/src/lib/components/ui/tooltip/index.ts
@@ -0,0 +1,19 @@
+import Content from "./tooltip-content.svelte";
+import Portal from "./tooltip-portal.svelte";
+import Provider from "./tooltip-provider.svelte";
+import Trigger from "./tooltip-trigger.svelte";
+import Root from "./tooltip.svelte";
+
+export {
+ Root,
+ Trigger,
+ Content,
+ Provider,
+ Portal,
+ //
+ Root as Tooltip,
+ Content as TooltipContent,
+ Trigger as TooltipTrigger,
+ Provider as TooltipProvider,
+ Portal as TooltipPortal,
+};
diff --git a/src/lib/components/ui/tooltip/tooltip-content.svelte b/src/lib/components/ui/tooltip/tooltip-content.svelte
new file mode 100644
index 0000000..9b7cfc8
--- /dev/null
+++ b/src/lib/components/ui/tooltip/tooltip-content.svelte
@@ -0,0 +1,48 @@
+
+
+
+
+ {@render children?.()}
+
+ {#snippet child({ props })}
+
+ {/snippet}
+
+
+
diff --git a/src/lib/components/ui/tooltip/tooltip-portal.svelte b/src/lib/components/ui/tooltip/tooltip-portal.svelte
new file mode 100644
index 0000000..d234f7d
--- /dev/null
+++ b/src/lib/components/ui/tooltip/tooltip-portal.svelte
@@ -0,0 +1,7 @@
+
+
+
diff --git a/src/lib/components/ui/tooltip/tooltip-provider.svelte b/src/lib/components/ui/tooltip/tooltip-provider.svelte
new file mode 100644
index 0000000..6dba9a6
--- /dev/null
+++ b/src/lib/components/ui/tooltip/tooltip-provider.svelte
@@ -0,0 +1,7 @@
+
+
+
diff --git a/src/lib/components/ui/tooltip/tooltip-trigger.svelte b/src/lib/components/ui/tooltip/tooltip-trigger.svelte
new file mode 100644
index 0000000..c4b21fc
--- /dev/null
+++ b/src/lib/components/ui/tooltip/tooltip-trigger.svelte
@@ -0,0 +1,7 @@
+
+
+
diff --git a/src/lib/components/ui/tooltip/tooltip.svelte b/src/lib/components/ui/tooltip/tooltip.svelte
new file mode 100644
index 0000000..03c9a3d
--- /dev/null
+++ b/src/lib/components/ui/tooltip/tooltip.svelte
@@ -0,0 +1,7 @@
+
+
+
diff --git a/src/lib/hooks/is-mobile.svelte.ts b/src/lib/hooks/is-mobile.svelte.ts
new file mode 100644
index 0000000..4829c00
--- /dev/null
+++ b/src/lib/hooks/is-mobile.svelte.ts
@@ -0,0 +1,9 @@
+import { MediaQuery } from "svelte/reactivity";
+
+const DEFAULT_MOBILE_BREAKPOINT = 768;
+
+export class IsMobile extends MediaQuery {
+ constructor(breakpoint: number = DEFAULT_MOBILE_BREAKPOINT) {
+ super(`max-width: ${breakpoint - 1}px`);
+ }
+}
diff --git a/src/routes/+page.svelte b/src/routes/+page.svelte
index ef2181c..d3051e0 100644
--- a/src/routes/+page.svelte
+++ b/src/routes/+page.svelte
@@ -4,4 +4,4 @@
import { Button } from "#lib/components/ui/button/index.js";
-
+
diff --git a/src/routes/dashboard-01/+page.svelte b/src/routes/dashboard-01/+page.svelte
new file mode 100644
index 0000000..c0e0772
--- /dev/null
+++ b/src/routes/dashboard-01/+page.svelte
@@ -0,0 +1,29 @@
+
+
+
+
+
+
+
+
+
diff --git a/src/routes/dashboard-01/data.ts b/src/routes/dashboard-01/data.ts
new file mode 100644
index 0000000..4a9d988
--- /dev/null
+++ b/src/routes/dashboard-01/data.ts
@@ -0,0 +1,614 @@
+export default [
+ {
+ id: 1,
+ header: "Cover page",
+ type: "Cover page",
+ status: "In Process",
+ target: "18",
+ limit: "5",
+ reviewer: "Eddie Lake",
+ },
+ {
+ id: 2,
+ header: "Table of contents",
+ type: "Table of contents",
+ status: "Done",
+ target: "29",
+ limit: "24",
+ reviewer: "Eddie Lake",
+ },
+ {
+ id: 3,
+ header: "Executive summary",
+ type: "Narrative",
+ status: "Done",
+ target: "10",
+ limit: "13",
+ reviewer: "Eddie Lake",
+ },
+ {
+ id: 4,
+ header: "Technical approach",
+ type: "Narrative",
+ status: "Done",
+ target: "27",
+ limit: "23",
+ reviewer: "Jamik Tashpulatov",
+ },
+ {
+ id: 5,
+ header: "Design",
+ type: "Narrative",
+ status: "In Process",
+ target: "2",
+ limit: "16",
+ reviewer: "Jamik Tashpulatov",
+ },
+ {
+ id: 6,
+ header: "Capabilities",
+ type: "Narrative",
+ status: "In Process",
+ target: "20",
+ limit: "8",
+ reviewer: "Jamik Tashpulatov",
+ },
+ {
+ id: 7,
+ header: "Integration with existing systems",
+ type: "Narrative",
+ status: "In Process",
+ target: "19",
+ limit: "21",
+ reviewer: "Jamik Tashpulatov",
+ },
+ {
+ id: 8,
+ header: "Innovation and Advantages",
+ type: "Narrative",
+ status: "Done",
+ target: "25",
+ limit: "26",
+ reviewer: "Assign reviewer",
+ },
+ {
+ id: 9,
+ header: "Overview of EMR's Innovative Solutions",
+ type: "Technical content",
+ status: "Done",
+ target: "7",
+ limit: "23",
+ reviewer: "Assign reviewer",
+ },
+ {
+ id: 10,
+ header: "Advanced Algorithms and Machine Learning",
+ type: "Narrative",
+ status: "Done",
+ target: "30",
+ limit: "28",
+ reviewer: "Assign reviewer",
+ },
+ {
+ id: 11,
+ header: "Adaptive Communication Protocols",
+ type: "Narrative",
+ status: "Done",
+ target: "9",
+ limit: "31",
+ reviewer: "Assign reviewer",
+ },
+ {
+ id: 12,
+ header: "Advantages Over Current Technologies",
+ type: "Narrative",
+ status: "Done",
+ target: "12",
+ limit: "0",
+ reviewer: "Assign reviewer",
+ },
+ {
+ id: 13,
+ header: "Past Performance",
+ type: "Narrative",
+ status: "Done",
+ target: "22",
+ limit: "33",
+ reviewer: "Assign reviewer",
+ },
+ {
+ id: 14,
+ header: "Customer Feedback and Satisfaction Levels",
+ type: "Narrative",
+ status: "Done",
+ target: "15",
+ limit: "34",
+ reviewer: "Assign reviewer",
+ },
+ {
+ id: 15,
+ header: "Implementation Challenges and Solutions",
+ type: "Narrative",
+ status: "Done",
+ target: "3",
+ limit: "35",
+ reviewer: "Assign reviewer",
+ },
+ {
+ id: 16,
+ header: "Security Measures and Data Protection Policies",
+ type: "Narrative",
+ status: "In Process",
+ target: "6",
+ limit: "36",
+ reviewer: "Assign reviewer",
+ },
+ {
+ id: 17,
+ header: "Scalability and Future Proofing",
+ type: "Narrative",
+ status: "Done",
+ target: "4",
+ limit: "37",
+ reviewer: "Assign reviewer",
+ },
+ {
+ id: 18,
+ header: "Cost-Benefit Analysis",
+ type: "Plain language",
+ status: "Done",
+ target: "14",
+ limit: "38",
+ reviewer: "Assign reviewer",
+ },
+ {
+ id: 19,
+ header: "User Training and Onboarding Experience",
+ type: "Narrative",
+ status: "Done",
+ target: "17",
+ limit: "39",
+ reviewer: "Assign reviewer",
+ },
+ {
+ id: 20,
+ header: "Future Development Roadmap",
+ type: "Narrative",
+ status: "Done",
+ target: "11",
+ limit: "40",
+ reviewer: "Assign reviewer",
+ },
+ {
+ id: 21,
+ header: "System Architecture Overview",
+ type: "Technical content",
+ status: "In Process",
+ target: "24",
+ limit: "18",
+ reviewer: "Maya Johnson",
+ },
+ {
+ id: 22,
+ header: "Risk Management Plan",
+ type: "Narrative",
+ status: "Done",
+ target: "15",
+ limit: "22",
+ reviewer: "Carlos Rodriguez",
+ },
+ {
+ id: 23,
+ header: "Compliance Documentation",
+ type: "Legal",
+ status: "In Process",
+ target: "31",
+ limit: "27",
+ reviewer: "Sarah Chen",
+ },
+ {
+ id: 24,
+ header: "API Documentation",
+ type: "Technical content",
+ status: "Done",
+ target: "8",
+ limit: "12",
+ reviewer: "Raj Patel",
+ },
+ {
+ id: 25,
+ header: "User Interface Mockups",
+ type: "Visual",
+ status: "In Process",
+ target: "19",
+ limit: "25",
+ reviewer: "Leila Ahmadi",
+ },
+ {
+ id: 26,
+ header: "Database Schema",
+ type: "Technical content",
+ status: "Done",
+ target: "22",
+ limit: "20",
+ reviewer: "Thomas Wilson",
+ },
+ {
+ id: 27,
+ header: "Testing Methodology",
+ type: "Technical content",
+ status: "In Process",
+ target: "17",
+ limit: "14",
+ reviewer: "Assign reviewer",
+ },
+ {
+ id: 28,
+ header: "Deployment Strategy",
+ type: "Narrative",
+ status: "Done",
+ target: "26",
+ limit: "30",
+ reviewer: "Eddie Lake",
+ },
+ {
+ id: 29,
+ header: "Budget Breakdown",
+ type: "Financial",
+ status: "In Process",
+ target: "13",
+ limit: "16",
+ reviewer: "Jamik Tashpulatov",
+ },
+ {
+ id: 30,
+ header: "Market Analysis",
+ type: "Research",
+ status: "Done",
+ target: "29",
+ limit: "32",
+ reviewer: "Sophia Martinez",
+ },
+ {
+ id: 31,
+ header: "Competitor Comparison",
+ type: "Research",
+ status: "In Process",
+ target: "21",
+ limit: "19",
+ reviewer: "Assign reviewer",
+ },
+ {
+ id: 32,
+ header: "Maintenance Plan",
+ type: "Technical content",
+ status: "Done",
+ target: "16",
+ limit: "23",
+ reviewer: "Alex Thompson",
+ },
+ {
+ id: 33,
+ header: "User Personas",
+ type: "Research",
+ status: "In Process",
+ target: "27",
+ limit: "24",
+ reviewer: "Nina Patel",
+ },
+ {
+ id: 34,
+ header: "Accessibility Compliance",
+ type: "Legal",
+ status: "Done",
+ target: "18",
+ limit: "21",
+ reviewer: "Assign reviewer",
+ },
+ {
+ id: 35,
+ header: "Performance Metrics",
+ type: "Technical content",
+ status: "In Process",
+ target: "23",
+ limit: "26",
+ reviewer: "David Kim",
+ },
+ {
+ id: 36,
+ header: "Disaster Recovery Plan",
+ type: "Technical content",
+ status: "Done",
+ target: "14",
+ limit: "17",
+ reviewer: "Jamik Tashpulatov",
+ },
+ {
+ id: 37,
+ header: "Third-party Integrations",
+ type: "Technical content",
+ status: "In Process",
+ target: "25",
+ limit: "28",
+ reviewer: "Eddie Lake",
+ },
+ {
+ id: 38,
+ header: "User Feedback Summary",
+ type: "Research",
+ status: "Done",
+ target: "20",
+ limit: "15",
+ reviewer: "Assign reviewer",
+ },
+ {
+ id: 39,
+ header: "Localization Strategy",
+ type: "Narrative",
+ status: "In Process",
+ target: "12",
+ limit: "19",
+ reviewer: "Maria Garcia",
+ },
+ {
+ id: 40,
+ header: "Mobile Compatibility",
+ type: "Technical content",
+ status: "Done",
+ target: "28",
+ limit: "31",
+ reviewer: "James Wilson",
+ },
+ {
+ id: 41,
+ header: "Data Migration Plan",
+ type: "Technical content",
+ status: "In Process",
+ target: "19",
+ limit: "22",
+ reviewer: "Assign reviewer",
+ },
+ {
+ id: 42,
+ header: "Quality Assurance Protocols",
+ type: "Technical content",
+ status: "Done",
+ target: "30",
+ limit: "33",
+ reviewer: "Priya Singh",
+ },
+ {
+ id: 43,
+ header: "Stakeholder Analysis",
+ type: "Research",
+ status: "In Process",
+ target: "11",
+ limit: "14",
+ reviewer: "Eddie Lake",
+ },
+ {
+ id: 44,
+ header: "Environmental Impact Assessment",
+ type: "Research",
+ status: "Done",
+ target: "24",
+ limit: "27",
+ reviewer: "Assign reviewer",
+ },
+ {
+ id: 45,
+ header: "Intellectual Property Rights",
+ type: "Legal",
+ status: "In Process",
+ target: "17",
+ limit: "20",
+ reviewer: "Sarah Johnson",
+ },
+ {
+ id: 46,
+ header: "Customer Support Framework",
+ type: "Narrative",
+ status: "Done",
+ target: "22",
+ limit: "25",
+ reviewer: "Jamik Tashpulatov",
+ },
+ {
+ id: 47,
+ header: "Version Control Strategy",
+ type: "Technical content",
+ status: "In Process",
+ target: "15",
+ limit: "18",
+ reviewer: "Assign reviewer",
+ },
+ {
+ id: 48,
+ header: "Continuous Integration Pipeline",
+ type: "Technical content",
+ status: "Done",
+ target: "26",
+ limit: "29",
+ reviewer: "Michael Chen",
+ },
+ {
+ id: 49,
+ header: "Regulatory Compliance",
+ type: "Legal",
+ status: "In Process",
+ target: "13",
+ limit: "16",
+ reviewer: "Assign reviewer",
+ },
+ {
+ id: 50,
+ header: "User Authentication System",
+ type: "Technical content",
+ status: "Done",
+ target: "28",
+ limit: "31",
+ reviewer: "Eddie Lake",
+ },
+ {
+ id: 51,
+ header: "Data Analytics Framework",
+ type: "Technical content",
+ status: "In Process",
+ target: "21",
+ limit: "24",
+ reviewer: "Jamik Tashpulatov",
+ },
+ {
+ id: 52,
+ header: "Cloud Infrastructure",
+ type: "Technical content",
+ status: "Done",
+ target: "16",
+ limit: "19",
+ reviewer: "Assign reviewer",
+ },
+ {
+ id: 53,
+ header: "Network Security Measures",
+ type: "Technical content",
+ status: "In Process",
+ target: "29",
+ limit: "32",
+ reviewer: "Lisa Wong",
+ },
+ {
+ id: 54,
+ header: "Project Timeline",
+ type: "Planning",
+ status: "Done",
+ target: "14",
+ limit: "17",
+ reviewer: "Eddie Lake",
+ },
+ {
+ id: 55,
+ header: "Resource Allocation",
+ type: "Planning",
+ status: "In Process",
+ target: "27",
+ limit: "30",
+ reviewer: "Assign reviewer",
+ },
+ {
+ id: 56,
+ header: "Team Structure and Roles",
+ type: "Planning",
+ status: "Done",
+ target: "20",
+ limit: "23",
+ reviewer: "Jamik Tashpulatov",
+ },
+ {
+ id: 57,
+ header: "Communication Protocols",
+ type: "Planning",
+ status: "In Process",
+ target: "15",
+ limit: "18",
+ reviewer: "Assign reviewer",
+ },
+ {
+ id: 58,
+ header: "Success Metrics",
+ type: "Planning",
+ status: "Done",
+ target: "30",
+ limit: "33",
+ reviewer: "Eddie Lake",
+ },
+ {
+ id: 59,
+ header: "Internationalization Support",
+ type: "Technical content",
+ status: "In Process",
+ target: "23",
+ limit: "26",
+ reviewer: "Jamik Tashpulatov",
+ },
+ {
+ id: 60,
+ header: "Backup and Recovery Procedures",
+ type: "Technical content",
+ status: "Done",
+ target: "18",
+ limit: "21",
+ reviewer: "Assign reviewer",
+ },
+ {
+ id: 61,
+ header: "Monitoring and Alerting System",
+ type: "Technical content",
+ status: "In Process",
+ target: "25",
+ limit: "28",
+ reviewer: "Daniel Park",
+ },
+ {
+ id: 62,
+ header: "Code Review Guidelines",
+ type: "Technical content",
+ status: "Done",
+ target: "12",
+ limit: "15",
+ reviewer: "Eddie Lake",
+ },
+ {
+ id: 63,
+ header: "Documentation Standards",
+ type: "Technical content",
+ status: "In Process",
+ target: "27",
+ limit: "30",
+ reviewer: "Jamik Tashpulatov",
+ },
+ {
+ id: 64,
+ header: "Release Management Process",
+ type: "Planning",
+ status: "Done",
+ target: "22",
+ limit: "25",
+ reviewer: "Assign reviewer",
+ },
+ {
+ id: 65,
+ header: "Feature Prioritization Matrix",
+ type: "Planning",
+ status: "In Process",
+ target: "19",
+ limit: "22",
+ reviewer: "Emma Davis",
+ },
+ {
+ id: 66,
+ header: "Technical Debt Assessment",
+ type: "Technical content",
+ status: "Done",
+ target: "24",
+ limit: "27",
+ reviewer: "Eddie Lake",
+ },
+ {
+ id: 67,
+ header: "Capacity Planning",
+ type: "Planning",
+ status: "In Process",
+ target: "21",
+ limit: "24",
+ reviewer: "Jamik Tashpulatov",
+ },
+ {
+ id: 68,
+ header: "Service Level Agreements",
+ type: "Legal",
+ status: "Done",
+ target: "26",
+ limit: "29",
+ reviewer: "Assign reviewer",
+ },
+];
diff --git a/src/routes/dashboard/+page.svelte b/src/routes/dashboard/+page.svelte
new file mode 100644
index 0000000..e69de29