Thomas G. Lopes commited on
Commit
43e26da
·
2 Parent(s): 5152615 d90a6b0

Merge branch 'main' into canvas

Browse files
Files changed (45) hide show
  1. .env.example +1 -1
  2. eslint.config.mts +2 -0
  3. package.json +16 -12
  4. pnpm-lock.yaml +828 -558
  5. src/app.css +1 -0
  6. src/lib/builders/local-toasts.svelte.ts +22 -29
  7. src/lib/components/avatar.svelte +11 -25
  8. src/lib/components/inference-playground/code-snippets.svelte +2 -3
  9. src/lib/components/inference-playground/generation-config.svelte +25 -5
  10. src/lib/components/inference-playground/mcp-card.svelte +110 -0
  11. src/lib/components/inference-playground/mcp-form.svelte +160 -0
  12. src/lib/components/inference-playground/mcp-modal.svelte +53 -0
  13. src/lib/components/inference-playground/message-textarea.svelte +30 -0
  14. src/lib/components/inference-playground/model-selector-modal.svelte +108 -50
  15. src/lib/components/inference-playground/provider-select.svelte +18 -31
  16. src/lib/components/inference-playground/structured-output-modal.svelte +1 -0
  17. src/lib/components/switch.svelte +57 -0
  18. src/lib/constants.ts +14 -0
  19. src/lib/data/context_length.json +269 -0
  20. src/lib/remote/avatar.remote.ts +25 -0
  21. src/{routes/api/models/+server.ts → lib/remote/models.remote.ts} +100 -59
  22. src/lib/spells/create-init.svelte.ts +3 -3
  23. src/lib/spells/virtual-scroll.svelte.ts +107 -0
  24. src/lib/state/conversations.svelte.ts +19 -18
  25. src/lib/state/mcps.svelte.ts +86 -0
  26. src/lib/state/models.svelte.ts +22 -14
  27. src/lib/state/pricing.svelte.ts +3 -12
  28. src/lib/state/projects.svelte.ts +11 -8
  29. src/lib/utils/business.svelte.ts +96 -138
  30. src/lib/utils/cache.ts +29 -0
  31. src/lib/utils/debug.ts +11 -0
  32. src/lib/utils/stream.ts +144 -0
  33. src/lib/utils/styles.ts +6 -0
  34. src/lib/utils/url.spec.ts +59 -0
  35. src/lib/utils/url.ts +40 -0
  36. src/routes/+layout.svelte +3 -1
  37. src/routes/+page.svelte +6 -2
  38. src/routes/+page.ts +0 -17
  39. src/routes/api/generate/+server.ts +202 -0
  40. src/routes/api/generate/adapter.ts +71 -0
  41. src/routes/api/generate/mcp.ts +106 -0
  42. src/routes/api/generate/types.ts +53 -0
  43. src/routes/api/generate/utils.ts +11 -0
  44. src/routes/usage/+page.svelte +0 -0
  45. svelte.config.js +3 -0
.env.example CHANGED
@@ -1,3 +1,4 @@
 
1
  HYPERBOLIC_API_KEY=
2
  COHERE_API_KEY=
3
  TOGETHER_API_KEY=
@@ -9,4 +10,3 @@ FAL_API_KEY=
9
  HF_TOKEN=
10
 
11
  MODELS_FILE=
12
-
 
1
+ PUBLIC_ENABLE_MCP=
2
  HYPERBOLIC_API_KEY=
3
  COHERE_API_KEY=
4
  TOGETHER_API_KEY=
 
10
  HF_TOKEN=
11
 
12
  MODELS_FILE=
 
eslint.config.mts CHANGED
@@ -66,6 +66,7 @@ export default ts.config(
66
  "object-shorthand": ["error", "always"],
67
  "svelte/no-at-html-tags": "off",
68
  "svelte/require-each-key": "off",
 
69
  "local/enforce-ext": [
70
  "error",
71
  {
@@ -92,6 +93,7 @@ export default ts.config(
92
  "**/package-lock.json",
93
  "**/yarn.lock",
94
  "context_length.json",
 
95
  ],
96
  },
97
  {
 
66
  "object-shorthand": ["error", "always"],
67
  "svelte/no-at-html-tags": "off",
68
  "svelte/require-each-key": "off",
69
+ "svelte/no-navigation-without-resolve": "off",
70
  "local/enforce-ext": [
71
  "error",
72
  {
 
93
  "**/package-lock.json",
94
  "**/yarn.lock",
95
  "context_length.json",
96
+ ".claude/**/*",
97
  ],
98
  },
99
  {
package.json CHANGED
@@ -12,8 +12,9 @@
12
  "lint": "prettier . --check . && eslint src/",
13
  "format": "prettier . --write .",
14
  "clean": "rm -rf ./node_modules/ && rm -rf ./.svelte-kit/ && ni && echo 'Project cleaned!'",
 
15
  "test:unit": "vitest --browser.headless",
16
- "test": "npm run test:unit",
17
  "test:e2e": "playwright test"
18
  },
19
  "devDependencies": {
@@ -25,16 +26,17 @@
25
  "@huggingface/tasks": "^0.19.26",
26
  "@huggingface/transformers": "^3.6.3",
27
  "@iconify-json/carbon": "^1.2.8",
 
28
  "@iconify-json/lucide": "^1.2.45",
29
  "@iconify-json/material-symbols": "^1.2.15",
30
  "@iconify-json/mingcute": "^1.2.5",
31
  "@playwright/test": "^1.49.1",
32
- "@ryoppippi/unplugin-typia": "^1.0.0",
33
- "@samchon/openapi": "^3.0.0",
34
- "@sveltejs/adapter-auto": "^3.2.2",
35
- "@sveltejs/adapter-node": "^5.2.0",
36
- "@sveltejs/kit": "^2.5.27",
37
- "@sveltejs/vite-plugin-svelte": "^4.0.0",
38
  "@tailwindcss/container-queries": "^0.1.1",
39
  "@tailwindcss/postcss": "^4.0.9",
40
  "@testing-library/jest-dom": "^6.6.3",
@@ -51,7 +53,7 @@
51
  "highlight.js": "^11.10.0",
52
  "jiti": "^2.4.2",
53
  "jsdom": "^26.0.0",
54
- "melt": "^0.36.0",
55
  "openai": "^4.90.0",
56
  "playwright": "^1.52.0",
57
  "postcss": "^8.4.38",
@@ -60,8 +62,8 @@
60
  "prettier-plugin-tailwindcss": "^0.6.11",
61
  "runed": "^0.25.0",
62
  "shiki": "^3.4.0",
63
- "svelte": "^5.36.16",
64
- "svelte-check": "^4.0.0",
65
  "tailwind-merge": "^3.0.2",
66
  "tailwindcss": "^4.0.9",
67
  "ts-patch": "^3.3.0",
@@ -75,13 +77,15 @@
75
  },
76
  "type": "module",
77
  "dependencies": {
 
78
  "@tailwindcss/typography": "^0.5.16",
79
  "@xyflow/svelte": "^1.2.4",
80
  "dequal": "^2.0.3",
81
- "eslint-plugin-svelte": "^3.11.0",
82
  "marked": "^16.1.2",
83
  "remult": "^3.0.2",
84
- "typia": "^8.0.0"
 
85
  },
86
  "pnpm": {
87
  "onlyBuiltDependencies": [
 
12
  "lint": "prettier . --check . && eslint src/",
13
  "format": "prettier . --write .",
14
  "clean": "rm -rf ./node_modules/ && rm -rf ./.svelte-kit/ && ni && echo 'Project cleaned!'",
15
+ "update-ctx-length": "jiti scripts/update-ctx-length.ts",
16
  "test:unit": "vitest --browser.headless",
17
+ "test": "npm run test:unit -- --run",
18
  "test:e2e": "playwright test"
19
  },
20
  "devDependencies": {
 
26
  "@huggingface/tasks": "^0.19.26",
27
  "@huggingface/transformers": "^3.6.3",
28
  "@iconify-json/carbon": "^1.2.8",
29
+ "@iconify-json/line-md": "^1.2.11",
30
  "@iconify-json/lucide": "^1.2.45",
31
  "@iconify-json/material-symbols": "^1.2.15",
32
  "@iconify-json/mingcute": "^1.2.5",
33
  "@playwright/test": "^1.49.1",
34
+ "@ryoppippi/unplugin-typia": "^2.6.5",
35
+ "@samchon/openapi": "^4.7.1",
36
+ "@sveltejs/adapter-auto": "^3.3.1",
37
+ "@sveltejs/adapter-node": "^5.3.1",
38
+ "@sveltejs/kit": "^2.37.1",
39
+ "@sveltejs/vite-plugin-svelte": "^4.0.4",
40
  "@tailwindcss/container-queries": "^0.1.1",
41
  "@tailwindcss/postcss": "^4.0.9",
42
  "@testing-library/jest-dom": "^6.6.3",
 
53
  "highlight.js": "^11.10.0",
54
  "jiti": "^2.4.2",
55
  "jsdom": "^26.0.0",
56
+ "melt": "^0.40.2",
57
  "openai": "^4.90.0",
58
  "playwright": "^1.52.0",
59
  "postcss": "^8.4.38",
 
62
  "prettier-plugin-tailwindcss": "^0.6.11",
63
  "runed": "^0.25.0",
64
  "shiki": "^3.4.0",
65
+ "svelte": "^5.38.7",
66
+ "svelte-check": "^4.3.1",
67
  "tailwind-merge": "^3.0.2",
68
  "tailwindcss": "^4.0.9",
69
  "ts-patch": "^3.3.0",
 
77
  },
78
  "type": "module",
79
  "dependencies": {
80
+ "@modelcontextprotocol/sdk": "^1.13.3",
81
  "@tailwindcss/typography": "^0.5.16",
82
  "@xyflow/svelte": "^1.2.4",
83
  "dequal": "^2.0.3",
84
+ "eslint-plugin-svelte": "^3.12.2",
85
  "marked": "^16.1.2",
86
  "remult": "^3.0.2",
87
+ "tailwindcss-spring": "^1.0.1",
88
+ "typia": "^9.7.2"
89
  },
90
  "pnpm": {
91
  "onlyBuiltDependencies": [
pnpm-lock.yaml CHANGED
@@ -8,27 +8,33 @@ importers:
8
 
9
  .:
10
  dependencies:
 
 
 
11
  '@tailwindcss/typography':
12
  specifier: ^0.5.16
13
  version: 0.5.16(tailwindcss@4.0.9)
14
  '@xyflow/svelte':
15
  specifier: ^1.2.4
16
- version: 1.2.4(svelte@5.36.16)
17
  dequal:
18
  specifier: ^2.0.3
19
  version: 2.0.3
20
  eslint-plugin-svelte:
21
- specifier: ^3.11.0
22
- version: 3.11.0(eslint@9.22.0(jiti@2.4.2))(svelte@5.36.16)
23
  marked:
24
  specifier: ^16.1.2
25
  version: 16.1.2
26
  remult:
27
  specifier: ^3.0.2
28
  version: 3.0.2
 
 
 
29
  typia:
30
- specifier: ^8.0.0
31
- version: 8.0.0(@samchon/openapi@3.0.0)(typescript@5.8.2)
32
  devDependencies:
33
  '@eslint/eslintrc':
34
  specifier: ^3.3.0
@@ -54,6 +60,9 @@ importers:
54
  '@iconify-json/carbon':
55
  specifier: ^1.2.8
56
  version: 1.2.8
 
 
 
57
  '@iconify-json/lucide':
58
  specifier: ^1.2.45
59
  version: 1.2.45
@@ -67,23 +76,23 @@ importers:
67
  specifier: ^1.49.1
68
  version: 1.52.0
69
  '@ryoppippi/unplugin-typia':
70
- specifier: ^1.0.0
71
- version: 1.2.0(@samchon/openapi@3.0.0)(@types/node@22.14.1)(jiti@2.4.2)(lightningcss@1.29.1)(rollup@4.34.9)(yaml@2.7.0)
72
  '@samchon/openapi':
73
- specifier: ^3.0.0
74
- version: 3.0.0
75
  '@sveltejs/adapter-auto':
76
- specifier: ^3.2.2
77
- version: 3.3.1(@sveltejs/kit@2.18.0(@sveltejs/vite-plugin-svelte@4.0.4(svelte@5.36.16)(vite@5.4.14(@types/node@22.14.1)(lightningcss@1.29.1)))(svelte@5.36.16)(vite@5.4.14(@types/node@22.14.1)(lightningcss@1.29.1)))
78
  '@sveltejs/adapter-node':
79
- specifier: ^5.2.0
80
- version: 5.2.12(@sveltejs/kit@2.18.0(@sveltejs/vite-plugin-svelte@4.0.4(svelte@5.36.16)(vite@5.4.14(@types/node@22.14.1)(lightningcss@1.29.1)))(svelte@5.36.16)(vite@5.4.14(@types/node@22.14.1)(lightningcss@1.29.1)))
81
  '@sveltejs/kit':
82
- specifier: ^2.5.27
83
- version: 2.18.0(@sveltejs/vite-plugin-svelte@4.0.4(svelte@5.36.16)(vite@5.4.14(@types/node@22.14.1)(lightningcss@1.29.1)))(svelte@5.36.16)(vite@5.4.14(@types/node@22.14.1)(lightningcss@1.29.1))
84
  '@sveltejs/vite-plugin-svelte':
85
- specifier: ^4.0.0
86
- version: 4.0.4(svelte@5.36.16)(vite@5.4.14(@types/node@22.14.1)(lightningcss@1.29.1))
87
  '@tailwindcss/container-queries':
88
  specifier: ^0.1.1
89
  version: 0.1.1(tailwindcss@4.0.9)
@@ -95,7 +104,7 @@ importers:
95
  version: 6.6.3
96
  '@testing-library/svelte':
97
  specifier: ^5.2.4
98
- version: 5.2.8(svelte@5.36.16)(vite@5.4.14(@types/node@22.14.1)(lightningcss@1.29.1))(vitest@3.1.4)
99
  '@types/node':
100
  specifier: ^22.14.1
101
  version: 22.14.1
@@ -133,11 +142,11 @@ importers:
133
  specifier: ^26.0.0
134
  version: 26.1.0
135
  melt:
136
- specifier: ^0.36.0
137
- version: 0.36.0(@floating-ui/dom@1.6.13)(svelte@5.36.16)
138
  openai:
139
  specifier: ^4.90.0
140
- version: 4.90.0(ws@8.18.2)
141
  playwright:
142
  specifier: ^1.52.0
143
  version: 1.52.0
@@ -149,22 +158,22 @@ importers:
149
  version: 3.5.3
150
  prettier-plugin-svelte:
151
  specifier: ^3.4.0
152
- version: 3.4.0(prettier@3.5.3)(svelte@5.36.16)
153
  prettier-plugin-tailwindcss:
154
  specifier: ^0.6.11
155
- version: 0.6.11(prettier-plugin-svelte@3.4.0(prettier@3.5.3)(svelte@5.36.16))(prettier@3.5.3)
156
  runed:
157
  specifier: ^0.25.0
158
- version: 0.25.0(svelte@5.36.16)
159
  shiki:
160
  specifier: ^3.4.0
161
  version: 3.4.0
162
  svelte:
163
- specifier: ^5.36.16
164
- version: 5.36.16
165
  svelte-check:
166
- specifier: ^4.0.0
167
- version: 4.1.5(picomatch@4.0.2)(svelte@5.36.16)(typescript@5.8.2)
168
  tailwind-merge:
169
  specifier: ^3.0.2
170
  version: 3.0.2
@@ -185,7 +194,7 @@ importers:
185
  version: 8.26.1(eslint@9.22.0(jiti@2.4.2))(typescript@5.8.2)
186
  unplugin-icons:
187
  specifier: ^22.1.0
188
- version: 22.1.0(svelte@5.36.16)
189
  vite:
190
  specifier: ^5.4.4
191
  version: 5.4.14(@types/node@22.14.1)(lightningcss@1.29.1)
@@ -194,7 +203,7 @@ importers:
194
  version: 3.1.4(@types/node@22.14.1)(@vitest/browser@3.1.4)(jsdom@26.1.0)(lightningcss@1.29.1)
195
  vitest-browser-svelte:
196
  specifier: ^0.1.0
197
- version: 0.1.0(@vitest/browser@3.1.4)(svelte@5.36.16)(vitest@3.1.4)
198
 
199
  packages:
200
 
@@ -205,10 +214,6 @@ packages:
205
  resolution: {integrity: sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==}
206
  engines: {node: '>=10'}
207
 
208
- '@ampproject/remapping@2.3.0':
209
- resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==}
210
- engines: {node: '>=6.0.0'}
211
-
212
  '@antfu/install-pkg@1.0.0':
213
  resolution: {integrity: sha512-xvX6P/lo1B3ej0OsaErAjqgFYzYVcJpamjLAFLYh9vRJngBrMoUG7aVnrGTeqM7yxbyTD5p3F2+0/QUEh8Vzhw==}
214
 
@@ -267,288 +272,138 @@ packages:
267
  cpu: [ppc64]
268
  os: [aix]
269
 
270
- '@esbuild/aix-ppc64@0.25.1':
271
- resolution: {integrity: sha512-kfYGy8IdzTGy+z0vFGvExZtxkFlA4zAxgKEahG9KE1ScBjpQnFsNOX8KTU5ojNru5ed5CVoJYXFtoxaq5nFbjQ==}
272
- engines: {node: '>=18'}
273
- cpu: [ppc64]
274
- os: [aix]
275
-
276
  '@esbuild/android-arm64@0.21.5':
277
  resolution: {integrity: sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==}
278
  engines: {node: '>=12'}
279
  cpu: [arm64]
280
  os: [android]
281
 
282
- '@esbuild/android-arm64@0.25.1':
283
- resolution: {integrity: sha512-50tM0zCJW5kGqgG7fQ7IHvQOcAn9TKiVRuQ/lN0xR+T2lzEFvAi1ZcS8DiksFcEpf1t/GYOeOfCAgDHFpkiSmA==}
284
- engines: {node: '>=18'}
285
- cpu: [arm64]
286
- os: [android]
287
-
288
  '@esbuild/android-arm@0.21.5':
289
  resolution: {integrity: sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==}
290
  engines: {node: '>=12'}
291
  cpu: [arm]
292
  os: [android]
293
 
294
- '@esbuild/android-arm@0.25.1':
295
- resolution: {integrity: sha512-dp+MshLYux6j/JjdqVLnMglQlFu+MuVeNrmT5nk6q07wNhCdSnB7QZj+7G8VMUGh1q+vj2Bq8kRsuyA00I/k+Q==}
296
- engines: {node: '>=18'}
297
- cpu: [arm]
298
- os: [android]
299
-
300
  '@esbuild/android-x64@0.21.5':
301
  resolution: {integrity: sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==}
302
  engines: {node: '>=12'}
303
  cpu: [x64]
304
  os: [android]
305
 
306
- '@esbuild/android-x64@0.25.1':
307
- resolution: {integrity: sha512-GCj6WfUtNldqUzYkN/ITtlhwQqGWu9S45vUXs7EIYf+7rCiiqH9bCloatO9VhxsL0Pji+PF4Lz2XXCES+Q8hDw==}
308
- engines: {node: '>=18'}
309
- cpu: [x64]
310
- os: [android]
311
-
312
  '@esbuild/darwin-arm64@0.21.5':
313
  resolution: {integrity: sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==}
314
  engines: {node: '>=12'}
315
  cpu: [arm64]
316
  os: [darwin]
317
 
318
- '@esbuild/darwin-arm64@0.25.1':
319
- resolution: {integrity: sha512-5hEZKPf+nQjYoSr/elb62U19/l1mZDdqidGfmFutVUjjUZrOazAtwK+Kr+3y0C/oeJfLlxo9fXb1w7L+P7E4FQ==}
320
- engines: {node: '>=18'}
321
- cpu: [arm64]
322
- os: [darwin]
323
-
324
  '@esbuild/darwin-x64@0.21.5':
325
  resolution: {integrity: sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==}
326
  engines: {node: '>=12'}
327
  cpu: [x64]
328
  os: [darwin]
329
 
330
- '@esbuild/darwin-x64@0.25.1':
331
- resolution: {integrity: sha512-hxVnwL2Dqs3fM1IWq8Iezh0cX7ZGdVhbTfnOy5uURtao5OIVCEyj9xIzemDi7sRvKsuSdtCAhMKarxqtlyVyfA==}
332
- engines: {node: '>=18'}
333
- cpu: [x64]
334
- os: [darwin]
335
-
336
  '@esbuild/freebsd-arm64@0.21.5':
337
  resolution: {integrity: sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==}
338
  engines: {node: '>=12'}
339
  cpu: [arm64]
340
  os: [freebsd]
341
 
342
- '@esbuild/freebsd-arm64@0.25.1':
343
- resolution: {integrity: sha512-1MrCZs0fZa2g8E+FUo2ipw6jw5qqQiH+tERoS5fAfKnRx6NXH31tXBKI3VpmLijLH6yriMZsxJtaXUyFt/8Y4A==}
344
- engines: {node: '>=18'}
345
- cpu: [arm64]
346
- os: [freebsd]
347
-
348
  '@esbuild/freebsd-x64@0.21.5':
349
  resolution: {integrity: sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==}
350
  engines: {node: '>=12'}
351
  cpu: [x64]
352
  os: [freebsd]
353
 
354
- '@esbuild/freebsd-x64@0.25.1':
355
- resolution: {integrity: sha512-0IZWLiTyz7nm0xuIs0q1Y3QWJC52R8aSXxe40VUxm6BB1RNmkODtW6LHvWRrGiICulcX7ZvyH6h5fqdLu4gkww==}
356
- engines: {node: '>=18'}
357
- cpu: [x64]
358
- os: [freebsd]
359
-
360
  '@esbuild/linux-arm64@0.21.5':
361
  resolution: {integrity: sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==}
362
  engines: {node: '>=12'}
363
  cpu: [arm64]
364
  os: [linux]
365
 
366
- '@esbuild/linux-arm64@0.25.1':
367
- resolution: {integrity: sha512-jaN3dHi0/DDPelk0nLcXRm1q7DNJpjXy7yWaWvbfkPvI+7XNSc/lDOnCLN7gzsyzgu6qSAmgSvP9oXAhP973uQ==}
368
- engines: {node: '>=18'}
369
- cpu: [arm64]
370
- os: [linux]
371
-
372
  '@esbuild/linux-arm@0.21.5':
373
  resolution: {integrity: sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==}
374
  engines: {node: '>=12'}
375
  cpu: [arm]
376
  os: [linux]
377
 
378
- '@esbuild/linux-arm@0.25.1':
379
- resolution: {integrity: sha512-NdKOhS4u7JhDKw9G3cY6sWqFcnLITn6SqivVArbzIaf3cemShqfLGHYMx8Xlm/lBit3/5d7kXvriTUGa5YViuQ==}
380
- engines: {node: '>=18'}
381
- cpu: [arm]
382
- os: [linux]
383
-
384
  '@esbuild/linux-ia32@0.21.5':
385
  resolution: {integrity: sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==}
386
  engines: {node: '>=12'}
387
  cpu: [ia32]
388
  os: [linux]
389
 
390
- '@esbuild/linux-ia32@0.25.1':
391
- resolution: {integrity: sha512-OJykPaF4v8JidKNGz8c/q1lBO44sQNUQtq1KktJXdBLn1hPod5rE/Hko5ugKKZd+D2+o1a9MFGUEIUwO2YfgkQ==}
392
- engines: {node: '>=18'}
393
- cpu: [ia32]
394
- os: [linux]
395
-
396
  '@esbuild/linux-loong64@0.21.5':
397
  resolution: {integrity: sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==}
398
  engines: {node: '>=12'}
399
  cpu: [loong64]
400
  os: [linux]
401
 
402
- '@esbuild/linux-loong64@0.25.1':
403
- resolution: {integrity: sha512-nGfornQj4dzcq5Vp835oM/o21UMlXzn79KobKlcs3Wz9smwiifknLy4xDCLUU0BWp7b/houtdrgUz7nOGnfIYg==}
404
- engines: {node: '>=18'}
405
- cpu: [loong64]
406
- os: [linux]
407
-
408
  '@esbuild/linux-mips64el@0.21.5':
409
  resolution: {integrity: sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==}
410
  engines: {node: '>=12'}
411
  cpu: [mips64el]
412
  os: [linux]
413
 
414
- '@esbuild/linux-mips64el@0.25.1':
415
- resolution: {integrity: sha512-1osBbPEFYwIE5IVB/0g2X6i1qInZa1aIoj1TdL4AaAb55xIIgbg8Doq6a5BzYWgr+tEcDzYH67XVnTmUzL+nXg==}
416
- engines: {node: '>=18'}
417
- cpu: [mips64el]
418
- os: [linux]
419
-
420
  '@esbuild/linux-ppc64@0.21.5':
421
  resolution: {integrity: sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==}
422
  engines: {node: '>=12'}
423
  cpu: [ppc64]
424
  os: [linux]
425
 
426
- '@esbuild/linux-ppc64@0.25.1':
427
- resolution: {integrity: sha512-/6VBJOwUf3TdTvJZ82qF3tbLuWsscd7/1w+D9LH0W/SqUgM5/JJD0lrJ1fVIfZsqB6RFmLCe0Xz3fmZc3WtyVg==}
428
- engines: {node: '>=18'}
429
- cpu: [ppc64]
430
- os: [linux]
431
-
432
  '@esbuild/linux-riscv64@0.21.5':
433
  resolution: {integrity: sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==}
434
  engines: {node: '>=12'}
435
  cpu: [riscv64]
436
  os: [linux]
437
 
438
- '@esbuild/linux-riscv64@0.25.1':
439
- resolution: {integrity: sha512-nSut/Mx5gnilhcq2yIMLMe3Wl4FK5wx/o0QuuCLMtmJn+WeWYoEGDN1ipcN72g1WHsnIbxGXd4i/MF0gTcuAjQ==}
440
- engines: {node: '>=18'}
441
- cpu: [riscv64]
442
- os: [linux]
443
-
444
  '@esbuild/linux-s390x@0.21.5':
445
  resolution: {integrity: sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==}
446
  engines: {node: '>=12'}
447
  cpu: [s390x]
448
  os: [linux]
449
 
450
- '@esbuild/linux-s390x@0.25.1':
451
- resolution: {integrity: sha512-cEECeLlJNfT8kZHqLarDBQso9a27o2Zd2AQ8USAEoGtejOrCYHNtKP8XQhMDJMtthdF4GBmjR2au3x1udADQQQ==}
452
- engines: {node: '>=18'}
453
- cpu: [s390x]
454
- os: [linux]
455
-
456
  '@esbuild/linux-x64@0.21.5':
457
  resolution: {integrity: sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==}
458
  engines: {node: '>=12'}
459
  cpu: [x64]
460
  os: [linux]
461
 
462
- '@esbuild/linux-x64@0.25.1':
463
- resolution: {integrity: sha512-xbfUhu/gnvSEg+EGovRc+kjBAkrvtk38RlerAzQxvMzlB4fXpCFCeUAYzJvrnhFtdeyVCDANSjJvOvGYoeKzFA==}
464
- engines: {node: '>=18'}
465
- cpu: [x64]
466
- os: [linux]
467
-
468
- '@esbuild/netbsd-arm64@0.25.1':
469
- resolution: {integrity: sha512-O96poM2XGhLtpTh+s4+nP7YCCAfb4tJNRVZHfIE7dgmax+yMP2WgMd2OecBuaATHKTHsLWHQeuaxMRnCsH8+5g==}
470
- engines: {node: '>=18'}
471
- cpu: [arm64]
472
- os: [netbsd]
473
-
474
  '@esbuild/netbsd-x64@0.21.5':
475
  resolution: {integrity: sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==}
476
  engines: {node: '>=12'}
477
  cpu: [x64]
478
  os: [netbsd]
479
 
480
- '@esbuild/netbsd-x64@0.25.1':
481
- resolution: {integrity: sha512-X53z6uXip6KFXBQ+Krbx25XHV/NCbzryM6ehOAeAil7X7oa4XIq+394PWGnwaSQ2WRA0KI6PUO6hTO5zeF5ijA==}
482
- engines: {node: '>=18'}
483
- cpu: [x64]
484
- os: [netbsd]
485
-
486
- '@esbuild/openbsd-arm64@0.25.1':
487
- resolution: {integrity: sha512-Na9T3szbXezdzM/Kfs3GcRQNjHzM6GzFBeU1/6IV/npKP5ORtp9zbQjvkDJ47s6BCgaAZnnnu/cY1x342+MvZg==}
488
- engines: {node: '>=18'}
489
- cpu: [arm64]
490
- os: [openbsd]
491
-
492
  '@esbuild/openbsd-x64@0.21.5':
493
  resolution: {integrity: sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==}
494
  engines: {node: '>=12'}
495
  cpu: [x64]
496
  os: [openbsd]
497
 
498
- '@esbuild/openbsd-x64@0.25.1':
499
- resolution: {integrity: sha512-T3H78X2h1tszfRSf+txbt5aOp/e7TAz3ptVKu9Oyir3IAOFPGV6O9c2naym5TOriy1l0nNf6a4X5UXRZSGX/dw==}
500
- engines: {node: '>=18'}
501
- cpu: [x64]
502
- os: [openbsd]
503
-
504
  '@esbuild/sunos-x64@0.21.5':
505
  resolution: {integrity: sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==}
506
  engines: {node: '>=12'}
507
  cpu: [x64]
508
  os: [sunos]
509
 
510
- '@esbuild/sunos-x64@0.25.1':
511
- resolution: {integrity: sha512-2H3RUvcmULO7dIE5EWJH8eubZAI4xw54H1ilJnRNZdeo8dTADEZ21w6J22XBkXqGJbe0+wnNJtw3UXRoLJnFEg==}
512
- engines: {node: '>=18'}
513
- cpu: [x64]
514
- os: [sunos]
515
-
516
  '@esbuild/win32-arm64@0.21.5':
517
  resolution: {integrity: sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==}
518
  engines: {node: '>=12'}
519
  cpu: [arm64]
520
  os: [win32]
521
 
522
- '@esbuild/win32-arm64@0.25.1':
523
- resolution: {integrity: sha512-GE7XvrdOzrb+yVKB9KsRMq+7a2U/K5Cf/8grVFRAGJmfADr/e/ODQ134RK2/eeHqYV5eQRFxb1hY7Nr15fv1NQ==}
524
- engines: {node: '>=18'}
525
- cpu: [arm64]
526
- os: [win32]
527
-
528
  '@esbuild/win32-ia32@0.21.5':
529
  resolution: {integrity: sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==}
530
  engines: {node: '>=12'}
531
  cpu: [ia32]
532
  os: [win32]
533
 
534
- '@esbuild/win32-ia32@0.25.1':
535
- resolution: {integrity: sha512-uOxSJCIcavSiT6UnBhBzE8wy3n0hOkJsBOzy7HDAuTDE++1DJMRRVCPGisULScHL+a/ZwdXPpXD3IyFKjA7K8A==}
536
- engines: {node: '>=18'}
537
- cpu: [ia32]
538
- os: [win32]
539
-
540
  '@esbuild/win32-x64@0.21.5':
541
  resolution: {integrity: sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==}
542
  engines: {node: '>=12'}
543
  cpu: [x64]
544
  os: [win32]
545
 
546
- '@esbuild/win32-x64@0.25.1':
547
- resolution: {integrity: sha512-Y1EQdcfwMSeQN/ujR5VayLOJ1BHaK+ssyk0AEzPjC+t1lITgsnccPqFjb6V+LsTp/9Iov4ysfjxLaGJ9RPtkVg==}
548
- engines: {node: '>=18'}
549
- cpu: [x64]
550
- os: [win32]
551
-
552
  '@eslint-community/eslint-utils@4.4.1':
553
  resolution: {integrity: sha512-s3O3waFUrMV8P/XaF/+ZTp1X9XBZW1a4B97ZnjQF2KYWaFD2A8KyFBsrsfSjEmjn3RGWAIuvlneuZm3CUK3jbA==}
554
  engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
@@ -644,6 +499,9 @@ packages:
644
  '@iconify-json/carbon@1.2.8':
645
  resolution: {integrity: sha512-6xh4YiFBz6qoSnB3XMe23WvjTJroDFXB17J1MbiT7nATFe+70+em1acRXr8hgP/gYpwFMHFc4IvjA/IPTPnTzg==}
646
 
 
 
 
647
  '@iconify-json/lucide@1.2.45':
648
  resolution: {integrity: sha512-izW3wk7Ll5HgNMc/m41eOKXb7nL1zFxXZdMyBOtqdwusHXPr8IWSC/ReSgWgxUF3xyNwiQsso5Ppkta2wsUrPg==}
649
 
@@ -775,6 +633,15 @@ packages:
775
  cpu: [x64]
776
  os: [win32]
777
 
 
 
 
 
 
 
 
 
 
778
  '@isaacs/fs-minipass@4.0.1':
779
  resolution: {integrity: sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==}
780
  engines: {node: '>=18.0.0'}
@@ -783,24 +650,32 @@ packages:
783
  resolution: {integrity: sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==}
784
  engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
785
 
786
- '@jridgewell/gen-mapping@0.3.8':
787
- resolution: {integrity: sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==}
788
- engines: {node: '>=6.0.0'}
 
 
789
 
790
  '@jridgewell/resolve-uri@3.1.2':
791
  resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==}
792
  engines: {node: '>=6.0.0'}
793
 
794
- '@jridgewell/set-array@1.2.1':
795
- resolution: {integrity: sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==}
796
- engines: {node: '>=6.0.0'}
797
-
798
  '@jridgewell/sourcemap-codec@1.5.0':
799
  resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==}
800
 
 
 
 
801
  '@jridgewell/trace-mapping@0.3.25':
802
  resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==}
803
 
 
 
 
 
 
 
 
804
  '@noble/hashes@1.8.0':
805
  resolution: {integrity: sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==}
806
  engines: {node: ^14.21.3 || >=16}
@@ -898,6 +773,15 @@ packages:
898
  rollup:
899
  optional: true
900
 
 
 
 
 
 
 
 
 
 
901
  '@rollup/rollup-android-arm-eabi@4.34.9':
902
  resolution: {integrity: sha512-qZdlImWXur0CFakn2BJ2znJOdqYZKiedEPEVNTBrpfPjc/YuTGcaYZcdmNFTkUj3DU0ZM/AElcM8Ybww3xVLzA==}
903
  cpu: [arm]
@@ -993,11 +877,22 @@ packages:
993
  cpu: [x64]
994
  os: [win32]
995
 
996
- '@ryoppippi/unplugin-typia@1.2.0':
997
- resolution: {integrity: sha512-TlrqL2WQie2HvSqJpmKPXrFsNPbMwU5Jw2Asx+E3E3Fuyya5mN1lqaeILwSZLmkCOMTQLazIrTWNOGs0V6XL6A==}
 
 
 
 
 
 
 
 
 
 
 
998
 
999
- '@samchon/openapi@3.0.0':
1000
- resolution: {integrity: sha512-eVQlyKRYv1/C2Mikc1xZr7c0jMjg1vjPkeY/gheKB4c5WOOWyTNZ1uvnXR+ETpPHwaQ54I9NrQZhoNk6BEGuuw==}
1001
 
1002
  '@shikijs/core@3.4.0':
1003
  resolution: {integrity: sha512-0YOzTSRDn/IAfQWtK791gs1u8v87HNGToU6IwcA3K7nPoVOrS2Dh6X6A6YfXgPTSkTwR5y6myk0MnI0htjnwrA==}
@@ -1023,6 +918,9 @@ packages:
1023
  '@sinclair/typebox@0.27.8':
1024
  resolution: {integrity: sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==}
1025
 
 
 
 
1026
  '@svelte-put/shortcut@4.1.0':
1027
  resolution: {integrity: sha512-wImNEIkbxAIWFqlfuhcbC+jRPDeRa/uJGIXHMEVVD+jqL9xCwWNnkGQJ6Qb2XVszuRLHlb8SGZDL3Io/h3vs8w==}
1028
  peerDependencies:
@@ -1038,19 +936,23 @@ packages:
1038
  peerDependencies:
1039
  '@sveltejs/kit': ^2.0.0
1040
 
1041
- '@sveltejs/adapter-node@5.2.12':
1042
- resolution: {integrity: sha512-0bp4Yb3jKIEcZWVcJC/L1xXp9zzJS4hDwfb4VITAkfT4OVdkspSHsx7YhqJDbb2hgLl6R9Vs7VQR+fqIVOxPUQ==}
1043
  peerDependencies:
1044
  '@sveltejs/kit': ^2.4.0
1045
 
1046
- '@sveltejs/kit@2.18.0':
1047
- resolution: {integrity: sha512-4DGCGiwNzgnPJySlMe/Qi6rKMK3ntphJaV95BTW+aggaTIAVZ5x3Bp+LURVLMxAEAtWAI5U449NafVxTS+kXbQ==}
1048
  engines: {node: '>=18.13'}
1049
  hasBin: true
1050
  peerDependencies:
1051
- '@sveltejs/vite-plugin-svelte': ^3.0.0 || ^4.0.0-next.1 || ^5.0.0
 
1052
  svelte: ^4.0.0 || ^5.0.0-next.0
1053
- vite: ^5.0.3 || ^6.0.0
 
 
 
1054
 
1055
  '@sveltejs/vite-plugin-svelte-inspector@3.0.1':
1056
  resolution: {integrity: sha512-2CKypmj1sM4GE7HjllT7UKmo4Q6L5xFRd7VMGEWhYnZ+wc6AUVU01IBd7yUi6WnFndEwWoMNOd6e8UjoN0nbvQ==}
@@ -1207,6 +1109,9 @@ packages:
1207
  '@types/estree@1.0.6':
1208
  resolution: {integrity: sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==}
1209
 
 
 
 
1210
  '@types/hast@3.0.4':
1211
  resolution: {integrity: sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==}
1212
 
@@ -1337,6 +1242,10 @@ packages:
1337
  resolution: {integrity: sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==}
1338
  engines: {node: '>=6.5'}
1339
 
 
 
 
 
1340
  acorn-jsx@5.3.2:
1341
  resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==}
1342
  peerDependencies:
@@ -1347,6 +1256,11 @@ packages:
1347
  engines: {node: '>=0.4.0'}
1348
  hasBin: true
1349
 
 
 
 
 
 
1350
  agent-base@7.1.3:
1351
  resolution: {integrity: sha512-jRR5wdylq8CkOe6hei19GGZnxM6rBGwFl3Bg0YItGDimvjGtAvdZk4Pu6Cl4u4Igsws4a1fd1Vq3ezrhn4KmFw==}
1352
  engines: {node: '>= 14'}
@@ -1411,6 +1325,10 @@ packages:
1411
  bl@4.1.0:
1412
  resolution: {integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==}
1413
 
 
 
 
 
1414
  boolean@3.2.0:
1415
  resolution: {integrity: sha512-d0II/GO9uf9lfUHH2BQsjxzRJZBdsjgsBiW4BvhWk/3qoKwQFjIDVN19PfX8F2D/r9PCMTtLWjYVCFrpeYUzsw==}
1416
  deprecated: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.
@@ -1428,6 +1346,13 @@ packages:
1428
  buffer@5.7.1:
1429
  resolution: {integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==}
1430
 
 
 
 
 
 
 
 
1431
  cac@6.7.14:
1432
  resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==}
1433
  engines: {node: '>=8'}
@@ -1436,6 +1361,10 @@ packages:
1436
  resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==}
1437
  engines: {node: '>= 0.4'}
1438
 
 
 
 
 
1439
  callsites@3.1.0:
1440
  resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==}
1441
  engines: {node: '>=6'}
@@ -1461,8 +1390,8 @@ packages:
1461
  character-entities-legacy@3.0.0:
1462
  resolution: {integrity: sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==}
1463
 
1464
- chardet@0.7.0:
1465
- resolution: {integrity: sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==}
1466
 
1467
  check-error@2.1.1:
1468
  resolution: {integrity: sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==}
@@ -1540,17 +1469,40 @@ packages:
1540
  confbox@0.2.1:
1541
  resolution: {integrity: sha512-hkT3yDPFbs95mNCy1+7qNKC6Pro+/ibzYxtM2iqEigpf0sVw+bg4Zh9/snjsBcf990vfIsg5+1U7VyiyBb3etg==}
1542
 
1543
- consola@3.4.0:
1544
- resolution: {integrity: sha512-EiPU8G6dQG0GFHNR8ljnZFki/8a+cQwEQ+7wpxdChl02Q8HXlwEZWD5lqAF8vC2sEC3Tehr8hy7vErz88LHyUA==}
 
 
 
1545
  engines: {node: ^14.18.0 || >=16.10.0}
1546
 
 
 
 
 
 
 
 
 
 
 
 
 
1547
  cookie@0.6.0:
1548
  resolution: {integrity: sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==}
1549
  engines: {node: '>= 0.6'}
1550
 
 
 
 
 
1551
  core-util-is@1.0.3:
1552
  resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==}
1553
 
 
 
 
 
1554
  cross-spawn@7.0.6:
1555
  resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==}
1556
  engines: {node: '>= 8'}
@@ -1650,6 +1602,10 @@ packages:
1650
  resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==}
1651
  engines: {node: '>=0.4.0'}
1652
 
 
 
 
 
1653
  dequal@2.0.3:
1654
  resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==}
1655
  engines: {node: '>=6'}
@@ -1666,14 +1622,14 @@ packages:
1666
  detect-node@2.1.0:
1667
  resolution: {integrity: sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==}
1668
 
1669
- devalue@5.1.1:
1670
- resolution: {integrity: sha512-maua5KUiapvEwiEAe+XnlZ3Rh0GD+qI1J/nb9vrJc3muPXvcF/8gXYTWF76+5DAqHyDUtOIImEuo0YKE9mshVw==}
1671
 
1672
  devlop@1.1.0:
1673
  resolution: {integrity: sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==}
1674
 
1675
- diff-match-patch@1.0.5:
1676
- resolution: {integrity: sha512-IayShXAgj/QMXgB0IWmKx+rOPuGMhqm5w6jvFxmVenXKIzRqTAAsbBPT3kWQeGANj3jGgvcvv4yK6SxqYmikgw==}
1677
 
1678
  diff-sequences@29.6.3:
1679
  resolution: {integrity: sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==}
@@ -1697,9 +1653,16 @@ packages:
1697
  resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==}
1698
  engines: {node: '>= 0.4'}
1699
 
 
 
 
1700
  emoji-regex@8.0.0:
1701
  resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==}
1702
 
 
 
 
 
1703
  enhanced-resolve@5.18.1:
1704
  resolution: {integrity: sha512-ZSW3ma5GkcQBIpwZTSRAI8N71Uuwgs93IezB7mf7R60tC8ZbJideoDNKjHn2O9KIlx6rkGTTEk1xUCK2E1Y2Yg==}
1705
  engines: {node: '>=10.13.0'}
@@ -1735,10 +1698,8 @@ packages:
1735
  engines: {node: '>=12'}
1736
  hasBin: true
1737
 
1738
- esbuild@0.25.1:
1739
- resolution: {integrity: sha512-BGO5LtrGC7vxnqucAe/rmvKdJllfGaYWdyABvyMoXQlfYMb2bbRuReWR5tEGE//4LcNJj9XrkovTqNYRFZHAMQ==}
1740
- engines: {node: '>=18'}
1741
- hasBin: true
1742
 
1743
  escape-string-regexp@1.0.5:
1744
  resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==}
@@ -1768,8 +1729,8 @@ packages:
1768
  eslint-config-prettier:
1769
  optional: true
1770
 
1771
- eslint-plugin-svelte@3.11.0:
1772
- resolution: {integrity: sha512-KliWlkieHyEa65aQIkRwUFfHzT5Cn4u3BQQsu3KlkJOs7c1u7ryn84EWaOjEzilbKgttT4OfBURA8Uc4JBSQIw==}
1773
  engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
1774
  peerDependencies:
1775
  eslint: ^8.57.1 || ^9.0.0
@@ -1837,20 +1798,41 @@ packages:
1837
  resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==}
1838
  engines: {node: '>=0.10.0'}
1839
 
 
 
 
 
1840
  event-target-shim@5.0.1:
1841
  resolution: {integrity: sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==}
1842
  engines: {node: '>=6'}
1843
 
 
 
 
 
 
 
 
 
1844
  expect-type@1.2.1:
1845
  resolution: {integrity: sha512-/kP8CAwxzLVEeFrMm4kMmy4CCDlpipyA7MYLVrdJIkV0fYF0UaigQHRsxHiuY/GEea+bh4KSv3TIlgr+2UL6bw==}
1846
  engines: {node: '>=12.0.0'}
1847
 
 
 
 
 
 
 
 
 
 
 
1848
  exsolve@1.0.4:
1849
  resolution: {integrity: sha512-xsZH6PXaER4XoV+NiT7JHp1bJodJVT+cxeSH1G0f0tlT0lJqYuHUP3bUx2HtfTDvOagMINYp8rsqusxud3RXhw==}
1850
 
1851
- external-editor@3.1.0:
1852
- resolution: {integrity: sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==}
1853
- engines: {node: '>=4'}
1854
 
1855
  fake-indexeddb@6.0.1:
1856
  resolution: {integrity: sha512-He2AjQGHe46svIFq5+L2Nx/eHDTI1oKgoevBP+TthnjymXiKkeJQ3+ITeWey99Y5+2OaPFbI1qEsx/5RsGtWnQ==}
@@ -1903,6 +1885,10 @@ packages:
1903
  resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==}
1904
  engines: {node: '>=8'}
1905
 
 
 
 
 
1906
  find-cache-dir@5.0.0:
1907
  resolution: {integrity: sha512-OuWNfjfP05JcpAP3JPgAKUhWefjMRfI5iAoSsvE24ANYWJaepAtlSgWECSVEuRgSXpyNEc9DJwG/TZpgcOqyig==}
1908
  engines: {node: '>=16'}
@@ -1925,6 +1911,9 @@ packages:
1925
  flatted@3.3.3:
1926
  resolution: {integrity: sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==}
1927
 
 
 
 
1928
  form-data-encoder@1.7.2:
1929
  resolution: {integrity: sha512-qfqtYan3rxrnCk1VYaA4H+Ms9xdpPqvLZa6xmMgFvhO32x7/3J/ExcTd6qpxM0vH2GdMI+poehyBZvqfMTto8A==}
1930
 
@@ -1936,6 +1925,14 @@ packages:
1936
  resolution: {integrity: sha512-0iirZp3uVDjVGt9p49aTaqjk84TrglENEDuqfdlZQ1roC9CWlPk6Avf8EEnZNcAqPonwkG35x4n3ww/1THYAeQ==}
1937
  engines: {node: '>= 12.20'}
1938
 
 
 
 
 
 
 
 
 
1939
  fsevents@2.3.2:
1940
  resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==}
1941
  engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
@@ -2042,6 +2039,10 @@ packages:
2042
  html-void-elements@3.0.0:
2043
  resolution: {integrity: sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==}
2044
 
 
 
 
 
2045
  http-proxy-agent@7.0.2:
2046
  resolution: {integrity: sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==}
2047
  engines: {node: '>= 14'}
@@ -2053,14 +2054,14 @@ packages:
2053
  humanize-ms@1.2.1:
2054
  resolution: {integrity: sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==}
2055
 
2056
- iconv-lite@0.4.24:
2057
- resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==}
2058
- engines: {node: '>=0.10.0'}
2059
-
2060
  iconv-lite@0.6.3:
2061
  resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==}
2062
  engines: {node: '>=0.10.0'}
2063
 
 
 
 
 
2064
  ieee754@1.2.1:
2065
  resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==}
2066
 
@@ -2090,10 +2091,14 @@ packages:
2090
  resolution: {integrity: sha512-X7rqawQBvfdjS10YU1y1YVreA3SsLrW9dX2CewP2EbBJM4ypVNLDkO5y04gejPwKIY9lR+7r9gn3rFPt/kmWFg==}
2091
  engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0}
2092
 
2093
- inquirer@8.2.6:
2094
- resolution: {integrity: sha512-M1WuAmb7pn9zdFRtQYk26ZBoY043Sse0wVDdk4Bppr+JOXyQYybdtvK+l9wUibhtjdjvtoiNy8tk+EgsYIUqKg==}
2095
  engines: {node: '>=12.0.0'}
2096
 
 
 
 
 
2097
  is-arrayish@0.3.2:
2098
  resolution: {integrity: sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==}
2099
 
@@ -2127,6 +2132,9 @@ packages:
2127
  is-potential-custom-element-name@1.0.1:
2128
  resolution: {integrity: sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==}
2129
 
 
 
 
2130
  is-reference@1.2.1:
2131
  resolution: {integrity: sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==}
2132
 
@@ -2328,6 +2336,9 @@ packages:
2328
  magic-string@0.30.17:
2329
  resolution: {integrity: sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==}
2330
 
 
 
 
2331
  marked@16.1.2:
2332
  resolution: {integrity: sha512-rNQt5EvRinalby7zJZu/mB+BvaAY2oz3wCuCjt1RDrWNpS1Pdf9xqMOeC9Hm5adBdcV/3XZPJpG58eT+WBc0XQ==}
2333
  engines: {node: '>= 20'}
@@ -2344,12 +2355,20 @@ packages:
2344
  mdast-util-to-hast@13.2.0:
2345
  resolution: {integrity: sha512-QGYKEuUsYT9ykKBCMOEDLsU5JRObWQusAolFMeko/tYPufNkRffBAQjIE+99jbA87xv6FgmjLtwjh9wBWajwAA==}
2346
 
2347
- melt@0.36.0:
2348
- resolution: {integrity: sha512-lJdUuPvsCZs7zpcL2iSvxerHxv3QuM91FoTbdsliOQ2+J3fR4ADqUN878J4kkQSzzHlWqyedQmEBDP6U3iEWgA==}
 
 
 
 
2349
  peerDependencies:
2350
  '@floating-ui/dom': ^1.6.0
2351
  svelte: ^5.30.1
2352
 
 
 
 
 
2353
  merge2@1.4.1:
2354
  resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==}
2355
  engines: {node: '>= 8'}
@@ -2377,10 +2396,18 @@ packages:
2377
  resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==}
2378
  engines: {node: '>= 0.6'}
2379
 
 
 
 
 
2380
  mime-types@2.1.35:
2381
  resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==}
2382
  engines: {node: '>= 0.6'}
2383
 
 
 
 
 
2384
  mimic-fn@2.1.0:
2385
  resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==}
2386
  engines: {node: '>=6'}
@@ -2434,14 +2461,13 @@ packages:
2434
  engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
2435
  hasBin: true
2436
 
2437
- nanoid@5.1.5:
2438
- resolution: {integrity: sha512-Ir/+ZpE9fDsNH0hQ3C68uyThDXzYcim2EqcZ8zn8Chtt1iylPT9xXJB0kPCnqzgcEGikO9RxSrh63MsmVCU7Fw==}
2439
- engines: {node: ^18 || >=20}
2440
- hasBin: true
2441
-
2442
  natural-compare@1.4.0:
2443
  resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==}
2444
 
 
 
 
 
2445
  node-domexception@1.0.0:
2446
  resolution: {integrity: sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==}
2447
  engines: {node: '>=10.5.0'}
@@ -2458,10 +2484,25 @@ packages:
2458
  nwsapi@2.2.20:
2459
  resolution: {integrity: sha512-/ieB+mDe4MrrKMT8z+mQL8klXydZWGR5Dowt4RAGKbJ3kIGEx3X4ljUo+6V73IXtUPWgfOlU5B9MlGxFO5T+cA==}
2460
 
 
 
 
 
 
 
 
 
2461
  object-keys@1.1.1:
2462
  resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==}
2463
  engines: {node: '>= 0.4'}
2464
 
 
 
 
 
 
 
 
2465
  onetime@5.1.2:
2466
  resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==}
2467
  engines: {node: '>=6'}
@@ -2505,10 +2546,6 @@ packages:
2505
  resolution: {integrity: sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==}
2506
  engines: {node: '>=10'}
2507
 
2508
- os-tmpdir@1.0.2:
2509
- resolution: {integrity: sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==}
2510
- engines: {node: '>=0.10.0'}
2511
-
2512
  p-limit@3.1.0:
2513
  resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==}
2514
  engines: {node: '>=10'}
@@ -2535,6 +2572,10 @@ packages:
2535
  parse5@7.3.0:
2536
  resolution: {integrity: sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==}
2537
 
 
 
 
 
2538
  path-exists@4.0.0:
2539
  resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==}
2540
  engines: {node: '>=8'}
@@ -2550,8 +2591,8 @@ packages:
2550
  path-parse@1.0.7:
2551
  resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==}
2552
 
2553
- pathe@1.1.2:
2554
- resolution: {integrity: sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==}
2555
 
2556
  pathe@2.0.3:
2557
  resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==}
@@ -2571,6 +2612,14 @@ packages:
2571
  resolution: {integrity: sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==}
2572
  engines: {node: '>=12'}
2573
 
 
 
 
 
 
 
 
 
2574
  pkg-dir@7.0.0:
2575
  resolution: {integrity: sha512-Ie9z/WINcxxLp27BKOCHGde4ITq9UklYKDzVo1nhk5sqGEXU3FpkwP5GM2voTGJkGd9B3Otl+Q4uwSOeSUtOBA==}
2576
  engines: {node: '>=14.16'}
@@ -2581,6 +2630,9 @@ packages:
2581
  pkg-types@2.1.0:
2582
  resolution: {integrity: sha512-wmJwA+8ihJixSoHKxZJRBQG1oY8Yr9pGLzRmSsNms0iNWyHHAlZCa7mmKiFR10YPZuz/2k169JiS/inOjBCZ2A==}
2583
 
 
 
 
2584
  platform@1.3.6:
2585
  resolution: {integrity: sha512-fnWVljUchTro6RiCFvCXBbNhJc2NijN7oIQxbwsyL0buWJPG85v81ehlHI9fXrJsMNgTofEoWIQeClKpgxFLrg==}
2586
 
@@ -2719,10 +2771,18 @@ packages:
2719
  resolution: {integrity: sha512-mRUWCc3KUU4w1jU8sGxICXH/gNS94DvI1gxqDvBzhj1JpcsimQkYiOJfwsPUykUI5ZaspFbSgmBLER8IrQ3tqw==}
2720
  engines: {node: '>=12.0.0'}
2721
 
 
 
 
 
2722
  punycode@2.3.1:
2723
  resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==}
2724
  engines: {node: '>=6'}
2725
 
 
 
 
 
2726
  quansync@0.2.8:
2727
  resolution: {integrity: sha512-4+saucphJMazjt7iOM27mbFCk+D9dd/zmgMDCzRZ8MEoBfYp7lAvoN38et/phRQF6wOPMy/OROBGgoWeSKyluA==}
2728
 
@@ -2733,6 +2793,14 @@ packages:
2733
  resolution: {integrity: sha512-U+5l2KrcMNOUPYvazA3h5ekF80FHTUG+87SEAmHZmolh1M+i/WyTCxVzmi+tidIa1tM4BSe8g2Y/D3loWDjj+w==}
2734
  engines: {node: '>=4'}
2735
 
 
 
 
 
 
 
 
 
2736
  react-is@17.0.2:
2737
  resolution: {integrity: sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==}
2738
 
@@ -2800,6 +2868,10 @@ packages:
2800
  engines: {node: '>=18.0.0', npm: '>=8.0.0'}
2801
  hasBin: true
2802
 
 
 
 
 
2803
  rrweb-cssom@0.8.0:
2804
  resolution: {integrity: sha512-guoltQEx+9aMf2gDZ0s62EcV8lsXR+0w8915TC3ITdn2YueuNjdAYh/levpU9nFaoChh9RUS5ZdQMrKfVEN9tw==}
2805
 
@@ -2850,13 +2922,24 @@ packages:
2850
  engines: {node: '>=10'}
2851
  hasBin: true
2852
 
 
 
 
 
2853
  serialize-error@7.0.1:
2854
  resolution: {integrity: sha512-8I8TjW5KMOKsZQTvoxjuSIa7foAwPWGOts+6o7sgjz41/qMD9VQHEDxi6PBvK2l0MXUmqZyNpUK+T2tQaaElvw==}
2855
  engines: {node: '>=10'}
2856
 
 
 
 
 
2857
  set-cookie-parser@2.7.1:
2858
  resolution: {integrity: sha512-IOc8uWeOZgnb3ptbCURJWNjWUPcO3ZnTTdzsurqERrP6nPyv+paC55vJM0LpOlT2ne+Ix+9+CRG1MNLlyZ4GjQ==}
2859
 
 
 
 
2860
  sharp@0.34.2:
2861
  resolution: {integrity: sha512-lszvBmB9QURERtyKT2bNmsgxXK0ShJrL/fvqlonCo7e6xBF8nT8xU6pW+PMIbLsz0RxQk3rgH9kd8UmvOzlMJg==}
2862
  engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
@@ -2872,6 +2955,22 @@ packages:
2872
  shiki@3.4.0:
2873
  resolution: {integrity: sha512-Ni80XHcqhOEXv5mmDAvf5p6PAJqbUc/RzFeaOqk+zP5DLvTPS3j0ckvA+MI87qoxTQ5RGJDVTbdl/ENLSyyAnQ==}
2874
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2875
  siginfo@2.0.0:
2876
  resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==}
2877
 
@@ -2898,6 +2997,14 @@ packages:
2898
  stackback@0.0.2:
2899
  resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==}
2900
 
 
 
 
 
 
 
 
 
2901
  std-env@3.9.0:
2902
  resolution: {integrity: sha512-UGvjygr6F6tpH7o2qyqR6QYpwraIjKSdtzyBdyytFOHmPZY917kwdwLG0RbOjWOnKmnm3PeHjaoLLMie7kPLQw==}
2903
 
@@ -2931,8 +3038,8 @@ packages:
2931
  resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==}
2932
  engines: {node: '>= 0.4'}
2933
 
2934
- svelte-check@4.1.5:
2935
- resolution: {integrity: sha512-Gb0T2IqBNe1tLB9EB1Qh+LOe+JB8wt2/rNBDGvkxQVvk8vNeAoG+vZgFB/3P5+zC7RWlyBlzm9dVjZFph/maIg==}
2936
  engines: {node: '>= 18.0.0'}
2937
  hasBin: true
2938
  peerDependencies:
@@ -2948,8 +3055,8 @@ packages:
2948
  svelte:
2949
  optional: true
2950
 
2951
- svelte@5.36.16:
2952
- resolution: {integrity: sha512-C7HnyISfvZEofs7T4p7+bmjrbQlhd6lZfgV2tLYg6Eb3nUFM/Zu9dGlSg+GWbUBU/WPw6zDPOFNZAx9qXsoCkg==}
2953
  engines: {node: '>=18'}
2954
 
2955
  symbol-tree@3.2.4:
@@ -2959,9 +3066,17 @@ packages:
2959
  resolution: {integrity: sha512-vrozgXDQwYO72vHjUb/HnFbQx1exDjoKzqx23aXEg2a9VIg2TSFZ8FmeZpTjUCFMYw7mpX4BE2SFu8wI7asYsw==}
2960
  engines: {node: ^14.18.0 || >=16.0.0}
2961
 
 
 
 
2962
  tailwind-merge@3.0.2:
2963
  resolution: {integrity: sha512-l7z+OYZ7mu3DTqrL88RiKrKIqO3NcpEO8V/Od04bNpvk0kiIFndGEoqfuzvj4yuhRkHKjRkII2z+KS2HfPcSxw==}
2964
 
 
 
 
 
 
2965
  tailwindcss@4.0.9:
2966
  resolution: {integrity: sha512-12laZu+fv1ONDRoNR9ipTOpUD7RN9essRVkX36sjxuRUInpN7hIiHN4lBd/SIFjbISvnXzp8h/hXzmU8SQQYhw==}
2967
 
@@ -3005,14 +3120,14 @@ packages:
3005
  resolution: {integrity: sha512-WMi/OQ2axVTf/ykqCQgXiIct+mSQDFdH2fkwhPwgEwvJ1kSzZRiinb0zF2Xb8u4+OqPChmyI6MEu4EezNJz+FQ==}
3006
  hasBin: true
3007
 
3008
- tmp@0.0.33:
3009
- resolution: {integrity: sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==}
3010
- engines: {node: '>=0.6.0'}
3011
-
3012
  to-regex-range@5.0.1:
3013
  resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==}
3014
  engines: {node: '>=8.0'}
3015
 
 
 
 
 
3016
  totalist@3.0.1:
3017
  resolution: {integrity: sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==}
3018
  engines: {node: '>=6'}
@@ -3056,10 +3171,14 @@ packages:
3056
  resolution: {integrity: sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==}
3057
  engines: {node: '>=10'}
3058
 
3059
- type-fest@4.37.0:
3060
- resolution: {integrity: sha512-S/5/0kFftkq27FPNye0XM1e2NsnoD/3FS+pBmbjmmtLT6I+i344KoOf7pvXreaFsDamWeaJX55nczA1m5PsBDg==}
3061
  engines: {node: '>=16'}
3062
 
 
 
 
 
3063
  typescript-eslint@8.26.1:
3064
  resolution: {integrity: sha512-t/oIs9mYyrwZGRpDv3g+3K6nZ5uhKEMt2oNmAPwaY4/ye0+EH4nXIPYNtkYFS6QHm+1DFg34DbglYBz5P9Xysg==}
3065
  engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
@@ -3067,29 +3186,16 @@ packages:
3067
  eslint: ^8.57.0 || ^9.0.0
3068
  typescript: '>=4.8.4 <5.9.0'
3069
 
3070
- typescript@5.6.3:
3071
- resolution: {integrity: sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==}
3072
- engines: {node: '>=14.17'}
3073
- hasBin: true
3074
-
3075
  typescript@5.8.2:
3076
  resolution: {integrity: sha512-aJn6wq13/afZp/jT9QZmwEjDqqvSGp1VT5GVg+f/t6/oVyrgXM6BY1h9BRh/O5p3PlUPAe+WuiEZOmb/49RqoQ==}
3077
  engines: {node: '>=14.17'}
3078
  hasBin: true
3079
 
3080
- typia@7.6.4:
3081
- resolution: {integrity: sha512-Z3AcvGBjS7Dc7+iAG2VhsT0NIv3HMoXVTJ3F7Pgth8z7rhQu1JnyS8GGqqWdKk5ROvOgALEVEWmWv3Lym2eBIg==}
3082
  hasBin: true
3083
  peerDependencies:
3084
- '@samchon/openapi': '>=2.4.2 <3.0.0'
3085
- typescript: '>=4.8.0 <5.8.0'
3086
-
3087
- typia@8.0.0:
3088
- resolution: {integrity: sha512-ulYqugl0rXStArmFBxTxwC796gW4KkRas7wy7hOYwtRulxfBOJlurZMZ9MA8lN9LrgOpX/bnW0bW3w75ws6wIA==}
3089
- hasBin: true
3090
- peerDependencies:
3091
- '@samchon/openapi': '>=3.0.0 <4.0.0'
3092
- typescript: '>=4.8.0 <5.9.0'
3093
 
3094
  ufo@1.5.4:
3095
  resolution: {integrity: sha512-UsUk3byDzKd04EyoZ7U4DOlxQaD14JUKQl6/P7wiX4FNvUfm3XL246n9W5AmqwW5RSFJ27NAuM0iLscAOYUiGQ==}
@@ -3115,6 +3221,10 @@ packages:
3115
  unist-util-visit@5.0.0:
3116
  resolution: {integrity: sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==}
3117
 
 
 
 
 
3118
  unplugin-icons@22.1.0:
3119
  resolution: {integrity: sha512-ect2ZNtk1Zgwb0NVHd0C1IDW/MV+Jk/xaq4t8o6rYdVS3+L660ZdD5kTSQZvsgdwCvquRw+/wYn75hsweRjoIA==}
3120
  peerDependencies:
@@ -3138,14 +3248,14 @@ packages:
3138
  vue-template-es2015-compiler:
3139
  optional: true
3140
 
3141
- unplugin@1.16.1:
3142
- resolution: {integrity: sha512-4/u/j4FrCKdi17jaxuJA0jClGxB1AvU2hw/IuayPc4ay1XGaJs/rbb4v5WKwAjNifjmXK9PIFyuPiaK8azyR9w==}
3143
- engines: {node: '>=14.0.0'}
3144
-
3145
  unplugin@2.2.0:
3146
  resolution: {integrity: sha512-m1ekpSwuOT5hxkJeZGRxO7gXbXT3gF26NjQ7GdVHoLoF8/nopLcd/QfPigpCy7i51oFHiRJg/CyHhj4vs2+KGw==}
3147
  engines: {node: '>=18.12.0'}
3148
 
 
 
 
 
3149
  uri-js@4.4.1:
3150
  resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==}
3151
 
@@ -3156,6 +3266,10 @@ packages:
3156
  resolution: {integrity: sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==}
3157
  hasBin: true
3158
 
 
 
 
 
3159
  vfile-message@4.0.2:
3160
  resolution: {integrity: sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw==}
3161
 
@@ -3198,46 +3312,6 @@ packages:
3198
  terser:
3199
  optional: true
3200
 
3201
- vite@6.2.1:
3202
- resolution: {integrity: sha512-n2GnqDb6XPhlt9B8olZPrgMD/es/Nd1RdChF6CBD/fHW6pUyUTt2sQW2fPRX5GiD9XEa6+8A6A4f2vT6pSsE7Q==}
3203
- engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0}
3204
- hasBin: true
3205
- peerDependencies:
3206
- '@types/node': ^18.0.0 || ^20.0.0 || >=22.0.0
3207
- jiti: '>=1.21.0'
3208
- less: '*'
3209
- lightningcss: ^1.21.0
3210
- sass: '*'
3211
- sass-embedded: '*'
3212
- stylus: '*'
3213
- sugarss: '*'
3214
- terser: ^5.16.0
3215
- tsx: ^4.8.1
3216
- yaml: ^2.4.2
3217
- peerDependenciesMeta:
3218
- '@types/node':
3219
- optional: true
3220
- jiti:
3221
- optional: true
3222
- less:
3223
- optional: true
3224
- lightningcss:
3225
- optional: true
3226
- sass:
3227
- optional: true
3228
- sass-embedded:
3229
- optional: true
3230
- stylus:
3231
- optional: true
3232
- sugarss:
3233
- optional: true
3234
- terser:
3235
- optional: true
3236
- tsx:
3237
- optional: true
3238
- yaml:
3239
- optional: true
3240
-
3241
  vitefu@1.0.6:
3242
  resolution: {integrity: sha512-+Rex1GlappUyNN6UfwbVZne/9cYC4+R2XDk9xkNXBKMw6HQagdX9PgZ8V2v1WUSK1wfBLp7qbI1+XSNIlB1xmA==}
3243
  peerDependencies:
@@ -3341,6 +3415,9 @@ packages:
3341
  resolution: {integrity: sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==}
3342
  engines: {node: '>=8'}
3343
 
 
 
 
3344
  ws@8.18.2:
3345
  resolution: {integrity: sha512-DMricUmwGZUVr++AEAe2uiVM7UoO9MAVZMDu05UQOaUII0lp+zOzLLU4Xqh/JvTqklB1T4uELaaPBKyjE1r4fQ==}
3346
  engines: {node: '>=10.0.0'}
@@ -3368,22 +3445,25 @@ packages:
3368
  resolution: {integrity: sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==}
3369
  engines: {node: '>= 6'}
3370
 
3371
- yaml@2.7.0:
3372
- resolution: {integrity: sha512-+hSoy/QHluxmC9kCIJyL/uyFmLmc+e5CFR5Wa+bpIhIj85LVb9ZH2nVnqrHoSvKogwODv0ClqZkmiSSaIH5LTA==}
3373
- engines: {node: '>= 14'}
3374
- hasBin: true
3375
-
3376
  yocto-queue@0.1.0:
3377
  resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==}
3378
  engines: {node: '>=10'}
3379
 
3380
- yocto-queue@1.2.0:
3381
- resolution: {integrity: sha512-KHBC7z61OJeaMGnF3wqNZj+GGNXOyypZviiKpQeiHirG5Ib1ImwcLBH70rbMSkKfSmUNBsdf2PwaEJtKvgmkNw==}
3382
  engines: {node: '>=12.20'}
3383
 
3384
  zimmerframe@1.1.2:
3385
  resolution: {integrity: sha512-rAbqEGa8ovJy4pyBxZM70hg4pE6gDgaQ0Sl9M3enG3I0d6H4XSAM3GeNGLKnsBpuijUow064sf7ww1nutC5/3w==}
3386
 
 
 
 
 
 
 
 
 
3387
  zwitch@2.0.4:
3388
  resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==}
3389
 
@@ -3393,11 +3473,6 @@ snapshots:
3393
 
3394
  '@alloc/quick-lru@5.2.0': {}
3395
 
3396
- '@ampproject/remapping@2.3.0':
3397
- dependencies:
3398
- '@jridgewell/gen-mapping': 0.3.8
3399
- '@jridgewell/trace-mapping': 0.3.25
3400
-
3401
  '@antfu/install-pkg@1.0.0':
3402
  dependencies:
3403
  package-manager-detector: 0.2.11
@@ -3451,147 +3526,72 @@ snapshots:
3451
  '@esbuild/aix-ppc64@0.21.5':
3452
  optional: true
3453
 
3454
- '@esbuild/aix-ppc64@0.25.1':
3455
- optional: true
3456
-
3457
  '@esbuild/android-arm64@0.21.5':
3458
  optional: true
3459
 
3460
- '@esbuild/android-arm64@0.25.1':
3461
- optional: true
3462
-
3463
  '@esbuild/android-arm@0.21.5':
3464
  optional: true
3465
 
3466
- '@esbuild/android-arm@0.25.1':
3467
- optional: true
3468
-
3469
  '@esbuild/android-x64@0.21.5':
3470
  optional: true
3471
 
3472
- '@esbuild/android-x64@0.25.1':
3473
- optional: true
3474
-
3475
  '@esbuild/darwin-arm64@0.21.5':
3476
  optional: true
3477
 
3478
- '@esbuild/darwin-arm64@0.25.1':
3479
- optional: true
3480
-
3481
  '@esbuild/darwin-x64@0.21.5':
3482
  optional: true
3483
 
3484
- '@esbuild/darwin-x64@0.25.1':
3485
- optional: true
3486
-
3487
  '@esbuild/freebsd-arm64@0.21.5':
3488
  optional: true
3489
 
3490
- '@esbuild/freebsd-arm64@0.25.1':
3491
- optional: true
3492
-
3493
  '@esbuild/freebsd-x64@0.21.5':
3494
  optional: true
3495
 
3496
- '@esbuild/freebsd-x64@0.25.1':
3497
- optional: true
3498
-
3499
  '@esbuild/linux-arm64@0.21.5':
3500
  optional: true
3501
 
3502
- '@esbuild/linux-arm64@0.25.1':
3503
- optional: true
3504
-
3505
  '@esbuild/linux-arm@0.21.5':
3506
  optional: true
3507
 
3508
- '@esbuild/linux-arm@0.25.1':
3509
- optional: true
3510
-
3511
  '@esbuild/linux-ia32@0.21.5':
3512
  optional: true
3513
 
3514
- '@esbuild/linux-ia32@0.25.1':
3515
- optional: true
3516
-
3517
  '@esbuild/linux-loong64@0.21.5':
3518
  optional: true
3519
 
3520
- '@esbuild/linux-loong64@0.25.1':
3521
- optional: true
3522
-
3523
  '@esbuild/linux-mips64el@0.21.5':
3524
  optional: true
3525
 
3526
- '@esbuild/linux-mips64el@0.25.1':
3527
- optional: true
3528
-
3529
  '@esbuild/linux-ppc64@0.21.5':
3530
  optional: true
3531
 
3532
- '@esbuild/linux-ppc64@0.25.1':
3533
- optional: true
3534
-
3535
  '@esbuild/linux-riscv64@0.21.5':
3536
  optional: true
3537
 
3538
- '@esbuild/linux-riscv64@0.25.1':
3539
- optional: true
3540
-
3541
  '@esbuild/linux-s390x@0.21.5':
3542
  optional: true
3543
 
3544
- '@esbuild/linux-s390x@0.25.1':
3545
- optional: true
3546
-
3547
  '@esbuild/linux-x64@0.21.5':
3548
  optional: true
3549
 
3550
- '@esbuild/linux-x64@0.25.1':
3551
- optional: true
3552
-
3553
- '@esbuild/netbsd-arm64@0.25.1':
3554
- optional: true
3555
-
3556
  '@esbuild/netbsd-x64@0.21.5':
3557
  optional: true
3558
 
3559
- '@esbuild/netbsd-x64@0.25.1':
3560
- optional: true
3561
-
3562
- '@esbuild/openbsd-arm64@0.25.1':
3563
- optional: true
3564
-
3565
  '@esbuild/openbsd-x64@0.21.5':
3566
  optional: true
3567
 
3568
- '@esbuild/openbsd-x64@0.25.1':
3569
- optional: true
3570
-
3571
  '@esbuild/sunos-x64@0.21.5':
3572
  optional: true
3573
 
3574
- '@esbuild/sunos-x64@0.25.1':
3575
- optional: true
3576
-
3577
  '@esbuild/win32-arm64@0.21.5':
3578
  optional: true
3579
 
3580
- '@esbuild/win32-arm64@0.25.1':
3581
- optional: true
3582
-
3583
  '@esbuild/win32-ia32@0.21.5':
3584
  optional: true
3585
 
3586
- '@esbuild/win32-ia32@0.25.1':
3587
- optional: true
3588
-
3589
  '@esbuild/win32-x64@0.21.5':
3590
  optional: true
3591
 
3592
- '@esbuild/win32-x64@0.25.1':
3593
- optional: true
3594
-
3595
  '@eslint-community/eslint-utils@4.4.1(eslint@9.22.0(jiti@2.4.2))':
3596
  dependencies:
3597
  eslint: 9.22.0(jiti@2.4.2)
@@ -3689,6 +3689,10 @@ snapshots:
3689
  dependencies:
3690
  '@iconify/types': 2.0.0
3691
 
 
 
 
 
3692
  '@iconify-json/lucide@1.2.45':
3693
  dependencies:
3694
  '@iconify/types': 2.0.0
@@ -3797,6 +3801,13 @@ snapshots:
3797
  '@img/sharp-win32-x64@0.34.2':
3798
  optional: true
3799
 
 
 
 
 
 
 
 
3800
  '@isaacs/fs-minipass@4.0.1':
3801
  dependencies:
3802
  minipass: 7.1.2
@@ -3805,23 +3816,49 @@ snapshots:
3805
  dependencies:
3806
  '@sinclair/typebox': 0.27.8
3807
 
3808
- '@jridgewell/gen-mapping@0.3.8':
3809
  dependencies:
3810
- '@jridgewell/set-array': 1.2.1
3811
  '@jridgewell/sourcemap-codec': 1.5.0
3812
- '@jridgewell/trace-mapping': 0.3.25
3813
 
3814
- '@jridgewell/resolve-uri@3.1.2': {}
 
 
 
3815
 
3816
- '@jridgewell/set-array@1.2.1': {}
3817
 
3818
  '@jridgewell/sourcemap-codec@1.5.0': {}
3819
 
 
 
3820
  '@jridgewell/trace-mapping@0.3.25':
3821
  dependencies:
3822
  '@jridgewell/resolve-uri': 3.1.2
3823
  '@jridgewell/sourcemap-codec': 1.5.0
3824
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3825
  '@noble/hashes@1.8.0': {}
3826
 
3827
  '@nodelib/fs.scandir@2.1.5':
@@ -3907,6 +3944,14 @@ snapshots:
3907
  optionalDependencies:
3908
  rollup: 4.34.9
3909
 
 
 
 
 
 
 
 
 
3910
  '@rollup/rollup-android-arm-eabi@4.34.9':
3911
  optional: true
3912
 
@@ -3964,37 +4009,28 @@ snapshots:
3964
  '@rollup/rollup-win32-x64-msvc@4.34.9':
3965
  optional: true
3966
 
3967
- '@ryoppippi/unplugin-typia@1.2.0(@samchon/openapi@3.0.0)(@types/node@22.14.1)(jiti@2.4.2)(lightningcss@1.29.1)(rollup@4.34.9)(yaml@2.7.0)':
3968
  dependencies:
3969
- '@rollup/pluginutils': 5.1.4(rollup@4.34.9)
3970
- consola: 3.4.0
 
3971
  defu: 6.1.4
3972
- diff-match-patch: 1.0.5
3973
  find-cache-dir: 5.0.0
3974
- magic-string: 0.30.17
3975
- pathe: 1.1.2
3976
- pkg-types: 1.3.1
3977
- type-fest: 4.37.0
3978
- typescript: 5.6.3
3979
- typia: 7.6.4(@samchon/openapi@3.0.0)(typescript@5.6.3)
3980
- unplugin: 1.16.1
3981
- vite: 6.2.1(@types/node@22.14.1)(jiti@2.4.2)(lightningcss@1.29.1)(yaml@2.7.0)
 
 
3982
  transitivePeerDependencies:
3983
- - '@samchon/openapi'
3984
- - '@types/node'
3985
- - jiti
3986
- - less
3987
- - lightningcss
3988
  - rollup
3989
- - sass
3990
- - sass-embedded
3991
- - stylus
3992
- - sugarss
3993
- - terser
3994
- - tsx
3995
- - yaml
3996
 
3997
- '@samchon/openapi@3.0.0': {}
3998
 
3999
  '@shikijs/core@3.4.0':
4000
  dependencies:
@@ -4031,61 +4067,69 @@ snapshots:
4031
 
4032
  '@sinclair/typebox@0.27.8': {}
4033
 
4034
- '@svelte-put/shortcut@4.1.0(svelte@5.36.16)':
 
 
4035
  dependencies:
4036
- svelte: 5.36.16
4037
 
4038
  '@sveltejs/acorn-typescript@1.0.5(acorn@8.14.0)':
4039
  dependencies:
4040
  acorn: 8.14.0
4041
 
4042
- '@sveltejs/adapter-auto@3.3.1(@sveltejs/kit@2.18.0(@sveltejs/vite-plugin-svelte@4.0.4(svelte@5.36.16)(vite@5.4.14(@types/node@22.14.1)(lightningcss@1.29.1)))(svelte@5.36.16)(vite@5.4.14(@types/node@22.14.1)(lightningcss@1.29.1)))':
 
 
 
 
4043
  dependencies:
4044
- '@sveltejs/kit': 2.18.0(@sveltejs/vite-plugin-svelte@4.0.4(svelte@5.36.16)(vite@5.4.14(@types/node@22.14.1)(lightningcss@1.29.1)))(svelte@5.36.16)(vite@5.4.14(@types/node@22.14.1)(lightningcss@1.29.1))
4045
  import-meta-resolve: 4.1.0
4046
 
4047
- '@sveltejs/adapter-node@5.2.12(@sveltejs/kit@2.18.0(@sveltejs/vite-plugin-svelte@4.0.4(svelte@5.36.16)(vite@5.4.14(@types/node@22.14.1)(lightningcss@1.29.1)))(svelte@5.36.16)(vite@5.4.14(@types/node@22.14.1)(lightningcss@1.29.1)))':
4048
  dependencies:
4049
  '@rollup/plugin-commonjs': 28.0.2(rollup@4.34.9)
4050
  '@rollup/plugin-json': 6.1.0(rollup@4.34.9)
4051
  '@rollup/plugin-node-resolve': 16.0.0(rollup@4.34.9)
4052
- '@sveltejs/kit': 2.18.0(@sveltejs/vite-plugin-svelte@4.0.4(svelte@5.36.16)(vite@5.4.14(@types/node@22.14.1)(lightningcss@1.29.1)))(svelte@5.36.16)(vite@5.4.14(@types/node@22.14.1)(lightningcss@1.29.1))
4053
  rollup: 4.34.9
4054
 
4055
- '@sveltejs/kit@2.18.0(@sveltejs/vite-plugin-svelte@4.0.4(svelte@5.36.16)(vite@5.4.14(@types/node@22.14.1)(lightningcss@1.29.1)))(svelte@5.36.16)(vite@5.4.14(@types/node@22.14.1)(lightningcss@1.29.1))':
4056
  dependencies:
4057
- '@sveltejs/vite-plugin-svelte': 4.0.4(svelte@5.36.16)(vite@5.4.14(@types/node@22.14.1)(lightningcss@1.29.1))
 
 
4058
  '@types/cookie': 0.6.0
 
4059
  cookie: 0.6.0
4060
- devalue: 5.1.1
4061
  esm-env: 1.2.2
4062
- import-meta-resolve: 4.1.0
4063
  kleur: 4.1.5
4064
  magic-string: 0.30.17
4065
  mrmime: 2.0.1
4066
  sade: 1.8.1
4067
  set-cookie-parser: 2.7.1
4068
  sirv: 3.0.1
4069
- svelte: 5.36.16
4070
  vite: 5.4.14(@types/node@22.14.1)(lightningcss@1.29.1)
4071
 
4072
- '@sveltejs/vite-plugin-svelte-inspector@3.0.1(@sveltejs/vite-plugin-svelte@4.0.4(svelte@5.36.16)(vite@5.4.14(@types/node@22.14.1)(lightningcss@1.29.1)))(svelte@5.36.16)(vite@5.4.14(@types/node@22.14.1)(lightningcss@1.29.1))':
4073
  dependencies:
4074
- '@sveltejs/vite-plugin-svelte': 4.0.4(svelte@5.36.16)(vite@5.4.14(@types/node@22.14.1)(lightningcss@1.29.1))
4075
  debug: 4.4.0
4076
- svelte: 5.36.16
4077
  vite: 5.4.14(@types/node@22.14.1)(lightningcss@1.29.1)
4078
  transitivePeerDependencies:
4079
  - supports-color
4080
 
4081
- '@sveltejs/vite-plugin-svelte@4.0.4(svelte@5.36.16)(vite@5.4.14(@types/node@22.14.1)(lightningcss@1.29.1))':
4082
  dependencies:
4083
- '@sveltejs/vite-plugin-svelte-inspector': 3.0.1(@sveltejs/vite-plugin-svelte@4.0.4(svelte@5.36.16)(vite@5.4.14(@types/node@22.14.1)(lightningcss@1.29.1)))(svelte@5.36.16)(vite@5.4.14(@types/node@22.14.1)(lightningcss@1.29.1))
4084
  debug: 4.4.0
4085
  deepmerge: 4.3.1
4086
  kleur: 4.1.5
4087
  magic-string: 0.30.17
4088
- svelte: 5.36.16
4089
  vite: 5.4.14(@types/node@22.14.1)(lightningcss@1.29.1)
4090
  vitefu: 1.0.6(vite@5.4.14(@types/node@22.14.1)(lightningcss@1.29.1))
4091
  transitivePeerDependencies:
@@ -4186,10 +4230,10 @@ snapshots:
4186
  lodash: 4.17.21
4187
  redent: 3.0.0
4188
 
4189
- '@testing-library/svelte@5.2.8(svelte@5.36.16)(vite@5.4.14(@types/node@22.14.1)(lightningcss@1.29.1))(vitest@3.1.4)':
4190
  dependencies:
4191
  '@testing-library/dom': 10.4.0
4192
- svelte: 5.36.16
4193
  optionalDependencies:
4194
  vite: 5.4.14(@types/node@22.14.1)(lightningcss@1.29.1)
4195
  vitest: 3.1.4(@types/node@22.14.1)(@vitest/browser@3.1.4)(jsdom@26.1.0)(lightningcss@1.29.1)
@@ -4225,6 +4269,8 @@ snapshots:
4225
 
4226
  '@types/estree@1.0.6': {}
4227
 
 
 
4228
  '@types/hast@3.0.4':
4229
  dependencies:
4230
  '@types/unist': 3.0.3
@@ -4390,11 +4436,11 @@ snapshots:
4390
  loupe: 3.1.3
4391
  tinyrainbow: 2.0.0
4392
 
4393
- '@xyflow/svelte@1.2.4(svelte@5.36.16)':
4394
  dependencies:
4395
- '@svelte-put/shortcut': 4.1.0(svelte@5.36.16)
4396
  '@xyflow/system': 0.0.68
4397
- svelte: 5.36.16
4398
 
4399
  '@xyflow/system@0.0.68':
4400
  dependencies:
@@ -4412,12 +4458,19 @@ snapshots:
4412
  dependencies:
4413
  event-target-shim: 5.0.1
4414
 
 
 
 
 
 
4415
  acorn-jsx@5.3.2(acorn@8.14.0):
4416
  dependencies:
4417
  acorn: 8.14.0
4418
 
4419
  acorn@8.14.0: {}
4420
 
 
 
4421
  agent-base@7.1.3: {}
4422
 
4423
  agentkeepalive@4.6.0:
@@ -4471,6 +4524,20 @@ snapshots:
4471
  inherits: 2.0.4
4472
  readable-stream: 3.6.2
4473
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4474
  boolean@3.2.0: {}
4475
 
4476
  brace-expansion@1.1.11:
@@ -4491,6 +4558,10 @@ snapshots:
4491
  base64-js: 1.5.1
4492
  ieee754: 1.2.1
4493
 
 
 
 
 
4494
  cac@6.7.14: {}
4495
 
4496
  call-bind-apply-helpers@1.0.2:
@@ -4498,6 +4569,11 @@ snapshots:
4498
  es-errors: 1.3.0
4499
  function-bind: 1.1.2
4500
 
 
 
 
 
 
4501
  callsites@3.1.0: {}
4502
 
4503
  ccount@2.0.1: {}
@@ -4524,7 +4600,7 @@ snapshots:
4524
 
4525
  character-entities-legacy@3.0.0: {}
4526
 
4527
- chardet@0.7.0: {}
4528
 
4529
  check-error@2.1.1: {}
4530
 
@@ -4588,12 +4664,29 @@ snapshots:
4588
 
4589
  confbox@0.2.1: {}
4590
 
4591
- consola@3.4.0: {}
 
 
 
 
 
 
 
 
 
 
4592
 
4593
  cookie@0.6.0: {}
4594
 
 
 
4595
  core-util-is@1.0.3: {}
4596
 
 
 
 
 
 
4597
  cross-spawn@7.0.6:
4598
  dependencies:
4599
  path-key: 3.1.1
@@ -4682,6 +4775,8 @@ snapshots:
4682
 
4683
  delayed-stream@1.0.0: {}
4684
 
 
 
4685
  dequal@2.0.3: {}
4686
 
4687
  detect-libc@1.0.3: {}
@@ -4690,13 +4785,13 @@ snapshots:
4690
 
4691
  detect-node@2.1.0: {}
4692
 
4693
- devalue@5.1.1: {}
4694
 
4695
  devlop@1.1.0:
4696
  dependencies:
4697
  dequal: 2.0.3
4698
 
4699
- diff-match-patch@1.0.5: {}
4700
 
4701
  diff-sequences@29.6.3: {}
4702
 
@@ -4714,8 +4809,12 @@ snapshots:
4714
  es-errors: 1.3.0
4715
  gopd: 1.2.0
4716
 
 
 
4717
  emoji-regex@8.0.0: {}
4718
 
 
 
4719
  enhanced-resolve@5.18.1:
4720
  dependencies:
4721
  graceful-fs: 4.2.11
@@ -4768,33 +4867,7 @@ snapshots:
4768
  '@esbuild/win32-ia32': 0.21.5
4769
  '@esbuild/win32-x64': 0.21.5
4770
 
4771
- esbuild@0.25.1:
4772
- optionalDependencies:
4773
- '@esbuild/aix-ppc64': 0.25.1
4774
- '@esbuild/android-arm': 0.25.1
4775
- '@esbuild/android-arm64': 0.25.1
4776
- '@esbuild/android-x64': 0.25.1
4777
- '@esbuild/darwin-arm64': 0.25.1
4778
- '@esbuild/darwin-x64': 0.25.1
4779
- '@esbuild/freebsd-arm64': 0.25.1
4780
- '@esbuild/freebsd-x64': 0.25.1
4781
- '@esbuild/linux-arm': 0.25.1
4782
- '@esbuild/linux-arm64': 0.25.1
4783
- '@esbuild/linux-ia32': 0.25.1
4784
- '@esbuild/linux-loong64': 0.25.1
4785
- '@esbuild/linux-mips64el': 0.25.1
4786
- '@esbuild/linux-ppc64': 0.25.1
4787
- '@esbuild/linux-riscv64': 0.25.1
4788
- '@esbuild/linux-s390x': 0.25.1
4789
- '@esbuild/linux-x64': 0.25.1
4790
- '@esbuild/netbsd-arm64': 0.25.1
4791
- '@esbuild/netbsd-x64': 0.25.1
4792
- '@esbuild/openbsd-arm64': 0.25.1
4793
- '@esbuild/openbsd-x64': 0.25.1
4794
- '@esbuild/sunos-x64': 0.25.1
4795
- '@esbuild/win32-arm64': 0.25.1
4796
- '@esbuild/win32-ia32': 0.25.1
4797
- '@esbuild/win32-x64': 0.25.1
4798
 
4799
  escape-string-regexp@1.0.5: {}
4800
 
@@ -4813,7 +4886,7 @@ snapshots:
4813
  optionalDependencies:
4814
  eslint-config-prettier: 10.1.1(eslint@9.22.0(jiti@2.4.2))
4815
 
4816
- eslint-plugin-svelte@3.11.0(eslint@9.22.0(jiti@2.4.2))(svelte@5.36.16):
4817
  dependencies:
4818
  '@eslint-community/eslint-utils': 4.7.0(eslint@9.22.0(jiti@2.4.2))
4819
  '@jridgewell/sourcemap-codec': 1.5.0
@@ -4825,9 +4898,9 @@ snapshots:
4825
  postcss-load-config: 3.1.4(postcss@8.5.3)
4826
  postcss-safe-parser: 7.0.1(postcss@8.5.3)
4827
  semver: 7.7.2
4828
- svelte-eslint-parser: 1.3.0(svelte@5.36.16)
4829
  optionalDependencies:
4830
- svelte: 5.36.16
4831
  transitivePeerDependencies:
4832
  - ts-node
4833
 
@@ -4914,17 +4987,57 @@ snapshots:
4914
 
4915
  esutils@2.0.3: {}
4916
 
 
 
4917
  event-target-shim@5.0.1: {}
4918
 
 
 
 
 
 
 
4919
  expect-type@1.2.1: {}
4920
 
4921
- exsolve@1.0.4: {}
 
 
4922
 
4923
- external-editor@3.1.0:
4924
  dependencies:
4925
- chardet: 0.7.0
4926
- iconv-lite: 0.4.24
4927
- tmp: 0.0.33
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4928
 
4929
  fake-indexeddb@6.0.1: {}
4930
 
@@ -4968,6 +5081,17 @@ snapshots:
4968
  dependencies:
4969
  to-regex-range: 5.0.1
4970
 
 
 
 
 
 
 
 
 
 
 
 
4971
  find-cache-dir@5.0.0:
4972
  dependencies:
4973
  common-path-prefix: 3.0.0
@@ -4992,6 +5116,10 @@ snapshots:
4992
 
4993
  flatted@3.3.3: {}
4994
 
 
 
 
 
4995
  form-data-encoder@1.7.2: {}
4996
 
4997
  form-data@4.0.2:
@@ -5006,6 +5134,10 @@ snapshots:
5006
  node-domexception: 1.0.0
5007
  web-streams-polyfill: 4.0.0-beta.3
5008
 
 
 
 
 
5009
  fsevents@2.3.2:
5010
  optional: true
5011
 
@@ -5118,6 +5250,14 @@ snapshots:
5118
 
5119
  html-void-elements@3.0.0: {}
5120
 
 
 
 
 
 
 
 
 
5121
  http-proxy-agent@7.0.2:
5122
  dependencies:
5123
  agent-base: 7.1.3
@@ -5136,11 +5276,11 @@ snapshots:
5136
  dependencies:
5137
  ms: 2.1.3
5138
 
5139
- iconv-lite@0.4.24:
5140
  dependencies:
5141
  safer-buffer: 2.1.2
5142
 
5143
- iconv-lite@0.6.3:
5144
  dependencies:
5145
  safer-buffer: 2.1.2
5146
 
@@ -5163,13 +5303,13 @@ snapshots:
5163
 
5164
  ini@4.1.3: {}
5165
 
5166
- inquirer@8.2.6:
5167
  dependencies:
 
5168
  ansi-escapes: 4.3.2
5169
  chalk: 4.1.2
5170
  cli-cursor: 3.1.0
5171
  cli-width: 3.0.0
5172
- external-editor: 3.1.0
5173
  figures: 3.2.0
5174
  lodash: 4.17.21
5175
  mute-stream: 0.0.8
@@ -5180,6 +5320,10 @@ snapshots:
5180
  strip-ansi: 6.0.1
5181
  through: 2.3.8
5182
  wrap-ansi: 6.2.0
 
 
 
 
5183
 
5184
  is-arrayish@0.3.2: {}
5185
 
@@ -5203,6 +5347,8 @@ snapshots:
5203
 
5204
  is-potential-custom-element-name@1.0.1: {}
5205
 
 
 
5206
  is-reference@1.2.1:
5207
  dependencies:
5208
  '@types/estree': 1.0.6
@@ -5386,7 +5532,11 @@ snapshots:
5386
 
5387
  magic-string@0.30.17:
5388
  dependencies:
5389
- '@jridgewell/sourcemap-codec': 1.5.0
 
 
 
 
5390
 
5391
  marked@16.1.2: {}
5392
 
@@ -5408,14 +5558,18 @@ snapshots:
5408
  unist-util-visit: 5.0.0
5409
  vfile: 6.0.3
5410
 
5411
- melt@0.36.0(@floating-ui/dom@1.6.13)(svelte@5.36.16):
 
 
5412
  dependencies:
5413
  '@floating-ui/dom': 1.6.13
5414
  dequal: 2.0.3
 
5415
  jest-axe: 9.0.0
5416
- nanoid: 5.1.5
5417
- runed: 0.23.4(svelte@5.36.16)
5418
- svelte: 5.36.16
 
5419
 
5420
  merge2@1.4.1: {}
5421
 
@@ -5443,10 +5597,16 @@ snapshots:
5443
 
5444
  mime-db@1.52.0: {}
5445
 
 
 
5446
  mime-types@2.1.35:
5447
  dependencies:
5448
  mime-db: 1.52.0
5449
 
 
 
 
 
5450
  mimic-fn@2.1.0: {}
5451
 
5452
  min-indent@1.0.1: {}
@@ -5486,10 +5646,10 @@ snapshots:
5486
 
5487
  nanoid@3.3.8: {}
5488
 
5489
- nanoid@5.1.5: {}
5490
-
5491
  natural-compare@1.4.0: {}
5492
 
 
 
5493
  node-domexception@1.0.0: {}
5494
 
5495
  node-fetch@2.7.0:
@@ -5498,8 +5658,20 @@ snapshots:
5498
 
5499
  nwsapi@2.2.20: {}
5500
 
 
 
 
 
5501
  object-keys@1.1.1: {}
5502
 
 
 
 
 
 
 
 
 
5503
  onetime@5.1.2:
5504
  dependencies:
5505
  mimic-fn: 2.1.0
@@ -5531,7 +5703,7 @@ snapshots:
5531
  platform: 1.3.6
5532
  protobufjs: 7.4.0
5533
 
5534
- openai@4.90.0(ws@8.18.2):
5535
  dependencies:
5536
  '@types/node': 18.19.84
5537
  '@types/node-fetch': 2.6.12
@@ -5542,6 +5714,7 @@ snapshots:
5542
  node-fetch: 2.7.0
5543
  optionalDependencies:
5544
  ws: 8.18.2
 
5545
  transitivePeerDependencies:
5546
  - encoding
5547
 
@@ -5566,15 +5739,13 @@ snapshots:
5566
  strip-ansi: 6.0.1
5567
  wcwidth: 1.0.1
5568
 
5569
- os-tmpdir@1.0.2: {}
5570
-
5571
  p-limit@3.1.0:
5572
  dependencies:
5573
  yocto-queue: 0.1.0
5574
 
5575
  p-limit@4.0.0:
5576
  dependencies:
5577
- yocto-queue: 1.2.0
5578
 
5579
  p-locate@5.0.0:
5580
  dependencies:
@@ -5596,6 +5767,8 @@ snapshots:
5596
  dependencies:
5597
  entities: 6.0.0
5598
 
 
 
5599
  path-exists@4.0.0: {}
5600
 
5601
  path-exists@5.0.0: {}
@@ -5604,7 +5777,7 @@ snapshots:
5604
 
5605
  path-parse@1.0.7: {}
5606
 
5607
- pathe@1.1.2: {}
5608
 
5609
  pathe@2.0.3: {}
5610
 
@@ -5616,6 +5789,10 @@ snapshots:
5616
 
5617
  picomatch@4.0.2: {}
5618
 
 
 
 
 
5619
  pkg-dir@7.0.0:
5620
  dependencies:
5621
  find-up: 6.3.0
@@ -5632,6 +5809,12 @@ snapshots:
5632
  exsolve: 1.0.4
5633
  pathe: 2.0.3
5634
 
 
 
 
 
 
 
5635
  platform@1.3.6: {}
5636
 
5637
  playwright-core@1.52.0: {}
@@ -5679,16 +5862,16 @@ snapshots:
5679
  dependencies:
5680
  fast-diff: 1.3.0
5681
 
5682
- prettier-plugin-svelte@3.4.0(prettier@3.5.3)(svelte@5.36.16):
5683
  dependencies:
5684
  prettier: 3.5.3
5685
- svelte: 5.36.16
5686
 
5687
- prettier-plugin-tailwindcss@0.6.11(prettier-plugin-svelte@3.4.0(prettier@3.5.3)(svelte@5.36.16))(prettier@3.5.3):
5688
  dependencies:
5689
  prettier: 3.5.3
5690
  optionalDependencies:
5691
- prettier-plugin-svelte: 3.4.0(prettier@3.5.3)(svelte@5.36.16)
5692
 
5693
  prettier@3.5.3: {}
5694
 
@@ -5721,8 +5904,17 @@ snapshots:
5721
  '@types/node': 22.14.1
5722
  long: 5.3.1
5723
 
 
 
 
 
 
5724
  punycode@2.3.1: {}
5725
 
 
 
 
 
5726
  quansync@0.2.8: {}
5727
 
5728
  queue-microtask@1.2.3: {}
@@ -5732,6 +5924,15 @@ snapshots:
5732
  drange: 1.1.1
5733
  ret: 0.2.2
5734
 
 
 
 
 
 
 
 
 
 
5735
  react-is@17.0.2: {}
5736
 
5737
  react-is@18.3.1: {}
@@ -5821,6 +6022,16 @@ snapshots:
5821
  '@rollup/rollup-win32-x64-msvc': 4.34.9
5822
  fsevents: 2.3.3
5823
 
 
 
 
 
 
 
 
 
 
 
5824
  rrweb-cssom@0.8.0: {}
5825
 
5826
  run-async@2.4.1: {}
@@ -5829,15 +6040,15 @@ snapshots:
5829
  dependencies:
5830
  queue-microtask: 1.2.3
5831
 
5832
- runed@0.23.4(svelte@5.36.16):
5833
  dependencies:
5834
  esm-env: 1.2.2
5835
- svelte: 5.36.16
5836
 
5837
- runed@0.25.0(svelte@5.36.16):
5838
  dependencies:
5839
  esm-env: 1.2.2
5840
- svelte: 5.36.16
5841
 
5842
  rxjs@7.8.2:
5843
  dependencies:
@@ -5861,12 +6072,39 @@ snapshots:
5861
 
5862
  semver@7.7.2: {}
5863
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5864
  serialize-error@7.0.1:
5865
  dependencies:
5866
  type-fest: 0.13.1
5867
 
 
 
 
 
 
 
 
 
 
5868
  set-cookie-parser@2.7.1: {}
5869
 
 
 
5870
  sharp@0.34.2:
5871
  dependencies:
5872
  color: 4.2.3
@@ -5912,6 +6150,34 @@ snapshots:
5912
  '@shikijs/vscode-textmate': 10.0.2
5913
  '@types/hast': 3.0.4
5914
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5915
  siginfo@2.0.0: {}
5916
 
5917
  signal-exit@3.0.7: {}
@@ -5934,6 +6200,10 @@ snapshots:
5934
 
5935
  stackback@0.0.2: {}
5936
 
 
 
 
 
5937
  std-env@3.9.0: {}
5938
 
5939
  string-width@4.2.3:
@@ -5967,19 +6237,19 @@ snapshots:
5967
 
5968
  supports-preserve-symlinks-flag@1.0.0: {}
5969
 
5970
- svelte-check@4.1.5(picomatch@4.0.2)(svelte@5.36.16)(typescript@5.8.2):
5971
  dependencies:
5972
  '@jridgewell/trace-mapping': 0.3.25
5973
  chokidar: 4.0.3
5974
  fdir: 6.4.3(picomatch@4.0.2)
5975
  picocolors: 1.1.1
5976
  sade: 1.8.1
5977
- svelte: 5.36.16
5978
  typescript: 5.8.2
5979
  transitivePeerDependencies:
5980
  - picomatch
5981
 
5982
- svelte-eslint-parser@1.3.0(svelte@5.36.16):
5983
  dependencies:
5984
  eslint-scope: 8.3.0
5985
  eslint-visitor-keys: 4.2.0
@@ -5988,11 +6258,11 @@ snapshots:
5988
  postcss-scss: 4.0.9(postcss@8.5.3)
5989
  postcss-selector-parser: 7.1.0
5990
  optionalDependencies:
5991
- svelte: 5.36.16
5992
 
5993
- svelte@5.36.16:
5994
  dependencies:
5995
- '@ampproject/remapping': 2.3.0
5996
  '@jridgewell/sourcemap-codec': 1.5.0
5997
  '@sveltejs/acorn-typescript': 1.0.5(acorn@8.14.0)
5998
  '@types/estree': 1.0.6
@@ -6014,8 +6284,14 @@ snapshots:
6014
  '@pkgr/core': 0.1.1
6015
  tslib: 2.8.1
6016
 
 
 
6017
  tailwind-merge@3.0.2: {}
6018
 
 
 
 
 
6019
  tailwindcss@4.0.9: {}
6020
 
6021
  tapable@2.2.1: {}
@@ -6052,14 +6328,12 @@ snapshots:
6052
  dependencies:
6053
  tldts-core: 6.1.86
6054
 
6055
- tmp@0.0.33:
6056
- dependencies:
6057
- os-tmpdir: 1.0.2
6058
-
6059
  to-regex-range@5.0.1:
6060
  dependencies:
6061
  is-number: 7.0.0
6062
 
 
 
6063
  totalist@3.0.1: {}
6064
 
6065
  tough-cookie@5.1.2:
@@ -6097,7 +6371,13 @@ snapshots:
6097
 
6098
  type-fest@0.21.3: {}
6099
 
6100
- type-fest@4.37.0: {}
 
 
 
 
 
 
6101
 
6102
  typescript-eslint@8.26.1(eslint@9.22.0(jiti@2.4.2))(typescript@5.8.2):
6103
  dependencies:
@@ -6109,29 +6389,20 @@ snapshots:
6109
  transitivePeerDependencies:
6110
  - supports-color
6111
 
6112
- typescript@5.6.3: {}
6113
-
6114
  typescript@5.8.2: {}
6115
 
6116
- typia@7.6.4(@samchon/openapi@3.0.0)(typescript@5.6.3):
6117
  dependencies:
6118
- '@samchon/openapi': 3.0.0
 
6119
  commander: 10.0.1
6120
  comment-json: 4.2.5
6121
- inquirer: 8.2.6
6122
- package-manager-detector: 0.2.11
6123
- randexp: 0.5.3
6124
- typescript: 5.6.3
6125
-
6126
- typia@8.0.0(@samchon/openapi@3.0.0)(typescript@5.8.2):
6127
- dependencies:
6128
- '@samchon/openapi': 3.0.0
6129
- commander: 10.0.1
6130
- comment-json: 4.2.5
6131
- inquirer: 8.2.6
6132
  package-manager-detector: 0.2.11
6133
  randexp: 0.5.3
6134
  typescript: 5.8.2
 
 
6135
 
6136
  ufo@1.5.4: {}
6137
 
@@ -6162,7 +6433,9 @@ snapshots:
6162
  unist-util-is: 6.0.0
6163
  unist-util-visit-parents: 6.0.1
6164
 
6165
- unplugin-icons@22.1.0(svelte@5.36.16):
 
 
6166
  dependencies:
6167
  '@antfu/install-pkg': 1.0.0
6168
  '@iconify/utils': 2.3.0
@@ -6170,18 +6443,20 @@ snapshots:
6170
  local-pkg: 1.1.1
6171
  unplugin: 2.2.0
6172
  optionalDependencies:
6173
- svelte: 5.36.16
6174
  transitivePeerDependencies:
6175
  - supports-color
6176
 
6177
- unplugin@1.16.1:
6178
  dependencies:
6179
  acorn: 8.14.0
6180
  webpack-virtual-modules: 0.6.2
6181
 
6182
- unplugin@2.2.0:
6183
  dependencies:
6184
- acorn: 8.14.0
 
 
6185
  webpack-virtual-modules: 0.6.2
6186
 
6187
  uri-js@4.4.1:
@@ -6192,6 +6467,8 @@ snapshots:
6192
 
6193
  uuid@8.3.2: {}
6194
 
 
 
6195
  vfile-message@4.0.2:
6196
  dependencies:
6197
  '@types/unist': 3.0.3
@@ -6230,26 +6507,14 @@ snapshots:
6230
  fsevents: 2.3.3
6231
  lightningcss: 1.29.1
6232
 
6233
- vite@6.2.1(@types/node@22.14.1)(jiti@2.4.2)(lightningcss@1.29.1)(yaml@2.7.0):
6234
- dependencies:
6235
- esbuild: 0.25.1
6236
- postcss: 8.5.3
6237
- rollup: 4.34.9
6238
- optionalDependencies:
6239
- '@types/node': 22.14.1
6240
- fsevents: 2.3.3
6241
- jiti: 2.4.2
6242
- lightningcss: 1.29.1
6243
- yaml: 2.7.0
6244
-
6245
  vitefu@1.0.6(vite@5.4.14(@types/node@22.14.1)(lightningcss@1.29.1)):
6246
  optionalDependencies:
6247
  vite: 5.4.14(@types/node@22.14.1)(lightningcss@1.29.1)
6248
 
6249
- vitest-browser-svelte@0.1.0(@vitest/browser@3.1.4)(svelte@5.36.16)(vitest@3.1.4):
6250
  dependencies:
6251
  '@vitest/browser': 3.1.4(playwright@1.52.0)(vite@5.4.14(@types/node@22.14.1)(lightningcss@1.29.1))(vitest@3.1.4)
6252
- svelte: 5.36.16
6253
  vitest: 3.1.4(@types/node@22.14.1)(@vitest/browser@3.1.4)(jsdom@26.1.0)(lightningcss@1.29.1)
6254
 
6255
  vitest@3.1.4(@types/node@22.14.1)(@vitest/browser@3.1.4)(jsdom@26.1.0)(lightningcss@1.29.1):
@@ -6343,6 +6608,8 @@ snapshots:
6343
  string-width: 4.2.3
6344
  strip-ansi: 6.0.1
6345
 
 
 
6346
  ws@8.18.2: {}
6347
 
6348
  xml-name-validator@5.0.0: {}
@@ -6353,13 +6620,16 @@ snapshots:
6353
 
6354
  yaml@1.10.2: {}
6355
 
6356
- yaml@2.7.0:
6357
- optional: true
6358
-
6359
  yocto-queue@0.1.0: {}
6360
 
6361
- yocto-queue@1.2.0: {}
6362
 
6363
  zimmerframe@1.1.2: {}
6364
 
 
 
 
 
 
 
6365
  zwitch@2.0.4: {}
 
8
 
9
  .:
10
  dependencies:
11
+ '@modelcontextprotocol/sdk':
12
+ specifier: ^1.13.3
13
+ version: 1.17.5
14
  '@tailwindcss/typography':
15
  specifier: ^0.5.16
16
  version: 0.5.16(tailwindcss@4.0.9)
17
  '@xyflow/svelte':
18
  specifier: ^1.2.4
19
+ version: 1.2.4(svelte@5.38.7)
20
  dequal:
21
  specifier: ^2.0.3
22
  version: 2.0.3
23
  eslint-plugin-svelte:
24
+ specifier: ^3.12.2
25
+ version: 3.12.2(eslint@9.22.0(jiti@2.4.2))(svelte@5.38.7)
26
  marked:
27
  specifier: ^16.1.2
28
  version: 16.1.2
29
  remult:
30
  specifier: ^3.0.2
31
  version: 3.0.2
32
+ tailwindcss-spring:
33
+ specifier: ^1.0.1
34
+ version: 1.0.1(tailwindcss@4.0.9)
35
  typia:
36
+ specifier: ^9.7.2
37
+ version: 9.7.2(@types/node@22.14.1)(typescript@5.8.2)
38
  devDependencies:
39
  '@eslint/eslintrc':
40
  specifier: ^3.3.0
 
60
  '@iconify-json/carbon':
61
  specifier: ^1.2.8
62
  version: 1.2.8
63
+ '@iconify-json/line-md':
64
+ specifier: ^1.2.11
65
+ version: 1.2.11
66
  '@iconify-json/lucide':
67
  specifier: ^1.2.45
68
  version: 1.2.45
 
76
  specifier: ^1.49.1
77
  version: 1.52.0
78
  '@ryoppippi/unplugin-typia':
79
+ specifier: ^2.6.5
80
+ version: 2.6.5(rollup@4.34.9)(svelte@5.38.7)(typescript@5.8.2)(typia@9.7.2(@types/node@22.14.1)(typescript@5.8.2))(vite@5.4.14(@types/node@22.14.1)(lightningcss@1.29.1))
81
  '@samchon/openapi':
82
+ specifier: ^4.7.1
83
+ version: 4.7.1
84
  '@sveltejs/adapter-auto':
85
+ specifier: ^3.3.1
86
+ version: 3.3.1(@sveltejs/kit@2.37.1(@sveltejs/vite-plugin-svelte@4.0.4(svelte@5.38.7)(vite@5.4.14(@types/node@22.14.1)(lightningcss@1.29.1)))(svelte@5.38.7)(vite@5.4.14(@types/node@22.14.1)(lightningcss@1.29.1)))
87
  '@sveltejs/adapter-node':
88
+ specifier: ^5.3.1
89
+ version: 5.3.1(@sveltejs/kit@2.37.1(@sveltejs/vite-plugin-svelte@4.0.4(svelte@5.38.7)(vite@5.4.14(@types/node@22.14.1)(lightningcss@1.29.1)))(svelte@5.38.7)(vite@5.4.14(@types/node@22.14.1)(lightningcss@1.29.1)))
90
  '@sveltejs/kit':
91
+ specifier: ^2.37.1
92
+ version: 2.37.1(@sveltejs/vite-plugin-svelte@4.0.4(svelte@5.38.7)(vite@5.4.14(@types/node@22.14.1)(lightningcss@1.29.1)))(svelte@5.38.7)(vite@5.4.14(@types/node@22.14.1)(lightningcss@1.29.1))
93
  '@sveltejs/vite-plugin-svelte':
94
+ specifier: ^4.0.4
95
+ version: 4.0.4(svelte@5.38.7)(vite@5.4.14(@types/node@22.14.1)(lightningcss@1.29.1))
96
  '@tailwindcss/container-queries':
97
  specifier: ^0.1.1
98
  version: 0.1.1(tailwindcss@4.0.9)
 
104
  version: 6.6.3
105
  '@testing-library/svelte':
106
  specifier: ^5.2.4
107
+ version: 5.2.8(svelte@5.38.7)(vite@5.4.14(@types/node@22.14.1)(lightningcss@1.29.1))(vitest@3.1.4)
108
  '@types/node':
109
  specifier: ^22.14.1
110
  version: 22.14.1
 
142
  specifier: ^26.0.0
143
  version: 26.1.0
144
  melt:
145
+ specifier: ^0.40.2
146
+ version: 0.40.2(@floating-ui/dom@1.6.13)(svelte@5.38.7)
147
  openai:
148
  specifier: ^4.90.0
149
+ version: 4.90.0(ws@8.18.2)(zod@3.25.76)
150
  playwright:
151
  specifier: ^1.52.0
152
  version: 1.52.0
 
158
  version: 3.5.3
159
  prettier-plugin-svelte:
160
  specifier: ^3.4.0
161
+ version: 3.4.0(prettier@3.5.3)(svelte@5.38.7)
162
  prettier-plugin-tailwindcss:
163
  specifier: ^0.6.11
164
+ version: 0.6.11(prettier-plugin-svelte@3.4.0(prettier@3.5.3)(svelte@5.38.7))(prettier@3.5.3)
165
  runed:
166
  specifier: ^0.25.0
167
+ version: 0.25.0(svelte@5.38.7)
168
  shiki:
169
  specifier: ^3.4.0
170
  version: 3.4.0
171
  svelte:
172
+ specifier: ^5.38.7
173
+ version: 5.38.7
174
  svelte-check:
175
+ specifier: ^4.3.1
176
+ version: 4.3.1(picomatch@4.0.2)(svelte@5.38.7)(typescript@5.8.2)
177
  tailwind-merge:
178
  specifier: ^3.0.2
179
  version: 3.0.2
 
194
  version: 8.26.1(eslint@9.22.0(jiti@2.4.2))(typescript@5.8.2)
195
  unplugin-icons:
196
  specifier: ^22.1.0
197
+ version: 22.1.0(svelte@5.38.7)
198
  vite:
199
  specifier: ^5.4.4
200
  version: 5.4.14(@types/node@22.14.1)(lightningcss@1.29.1)
 
203
  version: 3.1.4(@types/node@22.14.1)(@vitest/browser@3.1.4)(jsdom@26.1.0)(lightningcss@1.29.1)
204
  vitest-browser-svelte:
205
  specifier: ^0.1.0
206
+ version: 0.1.0(@vitest/browser@3.1.4)(svelte@5.38.7)(vitest@3.1.4)
207
 
208
  packages:
209
 
 
214
  resolution: {integrity: sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==}
215
  engines: {node: '>=10'}
216
 
 
 
 
 
217
  '@antfu/install-pkg@1.0.0':
218
  resolution: {integrity: sha512-xvX6P/lo1B3ej0OsaErAjqgFYzYVcJpamjLAFLYh9vRJngBrMoUG7aVnrGTeqM7yxbyTD5p3F2+0/QUEh8Vzhw==}
219
 
 
272
  cpu: [ppc64]
273
  os: [aix]
274
 
 
 
 
 
 
 
275
  '@esbuild/android-arm64@0.21.5':
276
  resolution: {integrity: sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==}
277
  engines: {node: '>=12'}
278
  cpu: [arm64]
279
  os: [android]
280
 
 
 
 
 
 
 
281
  '@esbuild/android-arm@0.21.5':
282
  resolution: {integrity: sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==}
283
  engines: {node: '>=12'}
284
  cpu: [arm]
285
  os: [android]
286
 
 
 
 
 
 
 
287
  '@esbuild/android-x64@0.21.5':
288
  resolution: {integrity: sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==}
289
  engines: {node: '>=12'}
290
  cpu: [x64]
291
  os: [android]
292
 
 
 
 
 
 
 
293
  '@esbuild/darwin-arm64@0.21.5':
294
  resolution: {integrity: sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==}
295
  engines: {node: '>=12'}
296
  cpu: [arm64]
297
  os: [darwin]
298
 
 
 
 
 
 
 
299
  '@esbuild/darwin-x64@0.21.5':
300
  resolution: {integrity: sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==}
301
  engines: {node: '>=12'}
302
  cpu: [x64]
303
  os: [darwin]
304
 
 
 
 
 
 
 
305
  '@esbuild/freebsd-arm64@0.21.5':
306
  resolution: {integrity: sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==}
307
  engines: {node: '>=12'}
308
  cpu: [arm64]
309
  os: [freebsd]
310
 
 
 
 
 
 
 
311
  '@esbuild/freebsd-x64@0.21.5':
312
  resolution: {integrity: sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==}
313
  engines: {node: '>=12'}
314
  cpu: [x64]
315
  os: [freebsd]
316
 
 
 
 
 
 
 
317
  '@esbuild/linux-arm64@0.21.5':
318
  resolution: {integrity: sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==}
319
  engines: {node: '>=12'}
320
  cpu: [arm64]
321
  os: [linux]
322
 
 
 
 
 
 
 
323
  '@esbuild/linux-arm@0.21.5':
324
  resolution: {integrity: sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==}
325
  engines: {node: '>=12'}
326
  cpu: [arm]
327
  os: [linux]
328
 
 
 
 
 
 
 
329
  '@esbuild/linux-ia32@0.21.5':
330
  resolution: {integrity: sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==}
331
  engines: {node: '>=12'}
332
  cpu: [ia32]
333
  os: [linux]
334
 
 
 
 
 
 
 
335
  '@esbuild/linux-loong64@0.21.5':
336
  resolution: {integrity: sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==}
337
  engines: {node: '>=12'}
338
  cpu: [loong64]
339
  os: [linux]
340
 
 
 
 
 
 
 
341
  '@esbuild/linux-mips64el@0.21.5':
342
  resolution: {integrity: sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==}
343
  engines: {node: '>=12'}
344
  cpu: [mips64el]
345
  os: [linux]
346
 
 
 
 
 
 
 
347
  '@esbuild/linux-ppc64@0.21.5':
348
  resolution: {integrity: sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==}
349
  engines: {node: '>=12'}
350
  cpu: [ppc64]
351
  os: [linux]
352
 
 
 
 
 
 
 
353
  '@esbuild/linux-riscv64@0.21.5':
354
  resolution: {integrity: sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==}
355
  engines: {node: '>=12'}
356
  cpu: [riscv64]
357
  os: [linux]
358
 
 
 
 
 
 
 
359
  '@esbuild/linux-s390x@0.21.5':
360
  resolution: {integrity: sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==}
361
  engines: {node: '>=12'}
362
  cpu: [s390x]
363
  os: [linux]
364
 
 
 
 
 
 
 
365
  '@esbuild/linux-x64@0.21.5':
366
  resolution: {integrity: sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==}
367
  engines: {node: '>=12'}
368
  cpu: [x64]
369
  os: [linux]
370
 
 
 
 
 
 
 
 
 
 
 
 
 
371
  '@esbuild/netbsd-x64@0.21.5':
372
  resolution: {integrity: sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==}
373
  engines: {node: '>=12'}
374
  cpu: [x64]
375
  os: [netbsd]
376
 
 
 
 
 
 
 
 
 
 
 
 
 
377
  '@esbuild/openbsd-x64@0.21.5':
378
  resolution: {integrity: sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==}
379
  engines: {node: '>=12'}
380
  cpu: [x64]
381
  os: [openbsd]
382
 
 
 
 
 
 
 
383
  '@esbuild/sunos-x64@0.21.5':
384
  resolution: {integrity: sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==}
385
  engines: {node: '>=12'}
386
  cpu: [x64]
387
  os: [sunos]
388
 
 
 
 
 
 
 
389
  '@esbuild/win32-arm64@0.21.5':
390
  resolution: {integrity: sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==}
391
  engines: {node: '>=12'}
392
  cpu: [arm64]
393
  os: [win32]
394
 
 
 
 
 
 
 
395
  '@esbuild/win32-ia32@0.21.5':
396
  resolution: {integrity: sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==}
397
  engines: {node: '>=12'}
398
  cpu: [ia32]
399
  os: [win32]
400
 
 
 
 
 
 
 
401
  '@esbuild/win32-x64@0.21.5':
402
  resolution: {integrity: sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==}
403
  engines: {node: '>=12'}
404
  cpu: [x64]
405
  os: [win32]
406
 
 
 
 
 
 
 
407
  '@eslint-community/eslint-utils@4.4.1':
408
  resolution: {integrity: sha512-s3O3waFUrMV8P/XaF/+ZTp1X9XBZW1a4B97ZnjQF2KYWaFD2A8KyFBsrsfSjEmjn3RGWAIuvlneuZm3CUK3jbA==}
409
  engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
 
499
  '@iconify-json/carbon@1.2.8':
500
  resolution: {integrity: sha512-6xh4YiFBz6qoSnB3XMe23WvjTJroDFXB17J1MbiT7nATFe+70+em1acRXr8hgP/gYpwFMHFc4IvjA/IPTPnTzg==}
501
 
502
+ '@iconify-json/line-md@1.2.11':
503
+ resolution: {integrity: sha512-JYczKuKvTq/Pf9rSCoxwdBbAiWqceNrb3EtM3acD4YkzCAdp3co+CdNE/pb5lTURGbIA9GrGuqentHqVwXyVWA==}
504
+
505
  '@iconify-json/lucide@1.2.45':
506
  resolution: {integrity: sha512-izW3wk7Ll5HgNMc/m41eOKXb7nL1zFxXZdMyBOtqdwusHXPr8IWSC/ReSgWgxUF3xyNwiQsso5Ppkta2wsUrPg==}
507
 
 
633
  cpu: [x64]
634
  os: [win32]
635
 
636
+ '@inquirer/external-editor@1.0.1':
637
+ resolution: {integrity: sha512-Oau4yL24d2B5IL4ma4UpbQigkVhzPDXLoqy1ggK4gnHg/stmkffJE4oOXHXF3uz0UEpywG68KcyXsyYpA1Re/Q==}
638
+ engines: {node: '>=18'}
639
+ peerDependencies:
640
+ '@types/node': '>=18'
641
+ peerDependenciesMeta:
642
+ '@types/node':
643
+ optional: true
644
+
645
  '@isaacs/fs-minipass@4.0.1':
646
  resolution: {integrity: sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==}
647
  engines: {node: '>=18.0.0'}
 
650
  resolution: {integrity: sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==}
651
  engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
652
 
653
+ '@jridgewell/gen-mapping@0.3.13':
654
+ resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==}
655
+
656
+ '@jridgewell/remapping@2.3.5':
657
+ resolution: {integrity: sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==}
658
 
659
  '@jridgewell/resolve-uri@3.1.2':
660
  resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==}
661
  engines: {node: '>=6.0.0'}
662
 
 
 
 
 
663
  '@jridgewell/sourcemap-codec@1.5.0':
664
  resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==}
665
 
666
+ '@jridgewell/sourcemap-codec@1.5.5':
667
+ resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==}
668
+
669
  '@jridgewell/trace-mapping@0.3.25':
670
  resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==}
671
 
672
+ '@jridgewell/trace-mapping@0.3.30':
673
+ resolution: {integrity: sha512-GQ7Nw5G2lTu/BtHTKfXhKHok2WGetd4XYcVKGx00SjAk8GMwgJM3zr6zORiPGuOE+/vkc90KtTosSSvaCjKb2Q==}
674
+
675
+ '@modelcontextprotocol/sdk@1.17.5':
676
+ resolution: {integrity: sha512-QakrKIGniGuRVfWBdMsDea/dx1PNE739QJ7gCM41s9q+qaCYTHCdsIBXQVVXry3mfWAiaM9kT22Hyz53Uw8mfg==}
677
+ engines: {node: '>=18'}
678
+
679
  '@noble/hashes@1.8.0':
680
  resolution: {integrity: sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==}
681
  engines: {node: ^14.21.3 || >=16}
 
773
  rollup:
774
  optional: true
775
 
776
+ '@rollup/pluginutils@5.3.0':
777
+ resolution: {integrity: sha512-5EdhGZtnu3V88ces7s53hhfK5KSASnJZv8Lulpc04cWO3REESroJXg73DFsOmgbU2BhwV0E20bu2IDZb3VKW4Q==}
778
+ engines: {node: '>=14.0.0'}
779
+ peerDependencies:
780
+ rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0
781
+ peerDependenciesMeta:
782
+ rollup:
783
+ optional: true
784
+
785
  '@rollup/rollup-android-arm-eabi@4.34.9':
786
  resolution: {integrity: sha512-qZdlImWXur0CFakn2BJ2znJOdqYZKiedEPEVNTBrpfPjc/YuTGcaYZcdmNFTkUj3DU0ZM/AElcM8Ybww3xVLzA==}
787
  cpu: [arm]
 
877
  cpu: [x64]
878
  os: [win32]
879
 
880
+ '@ryoppippi/unplugin-typia@2.6.5':
881
+ resolution: {integrity: sha512-Lg7Rho00E6Jn00Gle/Rn6ZWhUJj9U0J0iahfBUqqiXWrLWZdjXbeMCW1+82/7qnVQaqhlgz69hbd3JWYCtYivQ==}
882
+ deprecated: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.
883
+ peerDependencies:
884
+ svelte: ^5.28.2
885
+ typescript: '>=4.8.0 <5.9.0'
886
+ typia: '>=9.3.0'
887
+ vite: '>=3.0.0'
888
+ peerDependenciesMeta:
889
+ svelte:
890
+ optional: true
891
+ vite:
892
+ optional: true
893
 
894
+ '@samchon/openapi@4.7.1':
895
+ resolution: {integrity: sha512-+rkMlSKMt7l3KGWJVWUle1CXEm0vA8FIF2rufHl+T1gN/gGrTEhL1gDK3FHYf8Nl5XReK0r1vL6Q2QTMwQN7xQ==}
896
 
897
  '@shikijs/core@3.4.0':
898
  resolution: {integrity: sha512-0YOzTSRDn/IAfQWtK791gs1u8v87HNGToU6IwcA3K7nPoVOrS2Dh6X6A6YfXgPTSkTwR5y6myk0MnI0htjnwrA==}
 
918
  '@sinclair/typebox@0.27.8':
919
  resolution: {integrity: sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==}
920
 
921
+ '@standard-schema/spec@1.0.0':
922
+ resolution: {integrity: sha512-m2bOd0f2RT9k8QJx1JN85cZYyH1RqFBdlwtkSlf4tBDYLCiiZnv1fIIwacK6cqwXavOydf0NPToMQgpKq+dVlA==}
923
+
924
  '@svelte-put/shortcut@4.1.0':
925
  resolution: {integrity: sha512-wImNEIkbxAIWFqlfuhcbC+jRPDeRa/uJGIXHMEVVD+jqL9xCwWNnkGQJ6Qb2XVszuRLHlb8SGZDL3Io/h3vs8w==}
926
  peerDependencies:
 
936
  peerDependencies:
937
  '@sveltejs/kit': ^2.0.0
938
 
939
+ '@sveltejs/adapter-node@5.3.1':
940
+ resolution: {integrity: sha512-PSoGfa9atkmuixe7jvuS2tsUohVZF20So87ASzfMRGTTNqEd8s48KAodlv3CzHwq9XO/BM8KsQLpqqsr/6dmuA==}
941
  peerDependencies:
942
  '@sveltejs/kit': ^2.4.0
943
 
944
+ '@sveltejs/kit@2.37.1':
945
+ resolution: {integrity: sha512-4T9rF2Roe7RGvHfcn6+n92Yc2NF88k7ljFz9+wE0jWxyencqRpadr2/CvlcQbbTXf1ozmFxgMO6af+qm+1mPFw==}
946
  engines: {node: '>=18.13'}
947
  hasBin: true
948
  peerDependencies:
949
+ '@opentelemetry/api': ^1.0.0
950
+ '@sveltejs/vite-plugin-svelte': ^3.0.0 || ^4.0.0-next.1 || ^5.0.0 || ^6.0.0-next.0
951
  svelte: ^4.0.0 || ^5.0.0-next.0
952
+ vite: ^5.0.3 || ^6.0.0 || ^7.0.0-beta.0
953
+ peerDependenciesMeta:
954
+ '@opentelemetry/api':
955
+ optional: true
956
 
957
  '@sveltejs/vite-plugin-svelte-inspector@3.0.1':
958
  resolution: {integrity: sha512-2CKypmj1sM4GE7HjllT7UKmo4Q6L5xFRd7VMGEWhYnZ+wc6AUVU01IBd7yUi6WnFndEwWoMNOd6e8UjoN0nbvQ==}
 
1109
  '@types/estree@1.0.6':
1110
  resolution: {integrity: sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==}
1111
 
1112
+ '@types/estree@1.0.8':
1113
+ resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==}
1114
+
1115
  '@types/hast@3.0.4':
1116
  resolution: {integrity: sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==}
1117
 
 
1242
  resolution: {integrity: sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==}
1243
  engines: {node: '>=6.5'}
1244
 
1245
+ accepts@2.0.0:
1246
+ resolution: {integrity: sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==}
1247
+ engines: {node: '>= 0.6'}
1248
+
1249
  acorn-jsx@5.3.2:
1250
  resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==}
1251
  peerDependencies:
 
1256
  engines: {node: '>=0.4.0'}
1257
  hasBin: true
1258
 
1259
+ acorn@8.15.0:
1260
+ resolution: {integrity: sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==}
1261
+ engines: {node: '>=0.4.0'}
1262
+ hasBin: true
1263
+
1264
  agent-base@7.1.3:
1265
  resolution: {integrity: sha512-jRR5wdylq8CkOe6hei19GGZnxM6rBGwFl3Bg0YItGDimvjGtAvdZk4Pu6Cl4u4Igsws4a1fd1Vq3ezrhn4KmFw==}
1266
  engines: {node: '>= 14'}
 
1325
  bl@4.1.0:
1326
  resolution: {integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==}
1327
 
1328
+ body-parser@2.2.0:
1329
+ resolution: {integrity: sha512-02qvAaxv8tp7fBa/mw1ga98OGm+eCbqzJOKoRt70sLmfEEi+jyBYVTDGfCL/k06/4EMk/z01gCe7HoCH/f2LTg==}
1330
+ engines: {node: '>=18'}
1331
+
1332
  boolean@3.2.0:
1333
  resolution: {integrity: sha512-d0II/GO9uf9lfUHH2BQsjxzRJZBdsjgsBiW4BvhWk/3qoKwQFjIDVN19PfX8F2D/r9PCMTtLWjYVCFrpeYUzsw==}
1334
  deprecated: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.
 
1346
  buffer@5.7.1:
1347
  resolution: {integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==}
1348
 
1349
+ bun-only@0.0.1:
1350
+ resolution: {integrity: sha512-eQdy3eKF3MPcrwhvDq/7BykQ9kpl9Lu/zJ9IcL1AsjZ4vct68Du8reZisptp7YL8b65iImMf9j06xmGUNsc2rQ==}
1351
+
1352
+ bytes@3.1.2:
1353
+ resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==}
1354
+ engines: {node: '>= 0.8'}
1355
+
1356
  cac@6.7.14:
1357
  resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==}
1358
  engines: {node: '>=8'}
 
1361
  resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==}
1362
  engines: {node: '>= 0.4'}
1363
 
1364
+ call-bound@1.0.4:
1365
+ resolution: {integrity: sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==}
1366
+ engines: {node: '>= 0.4'}
1367
+
1368
  callsites@3.1.0:
1369
  resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==}
1370
  engines: {node: '>=6'}
 
1390
  character-entities-legacy@3.0.0:
1391
  resolution: {integrity: sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==}
1392
 
1393
+ chardet@2.1.0:
1394
+ resolution: {integrity: sha512-bNFETTG/pM5ryzQ9Ad0lJOTa6HWD/YsScAR3EnCPZRPlQh77JocYktSHOUHelyhm8IARL+o4c4F1bP5KVOjiRA==}
1395
 
1396
  check-error@2.1.1:
1397
  resolution: {integrity: sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==}
 
1469
  confbox@0.2.1:
1470
  resolution: {integrity: sha512-hkT3yDPFbs95mNCy1+7qNKC6Pro+/ibzYxtM2iqEigpf0sVw+bg4Zh9/snjsBcf990vfIsg5+1U7VyiyBb3etg==}
1471
 
1472
+ confbox@0.2.2:
1473
+ resolution: {integrity: sha512-1NB+BKqhtNipMsov4xI/NnhCKp9XG9NamYp5PVm9klAT0fsrNPjaFICsCFhNhwZJKNh7zB/3q8qXz0E9oaMNtQ==}
1474
+
1475
+ consola@3.4.2:
1476
+ resolution: {integrity: sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==}
1477
  engines: {node: ^14.18.0 || >=16.10.0}
1478
 
1479
+ content-disposition@1.0.0:
1480
+ resolution: {integrity: sha512-Au9nRL8VNUut/XSzbQA38+M78dzP4D+eqg3gfJHMIHHYa3bg067xj1KxMUWj+VULbiZMowKngFFbKczUrNJ1mg==}
1481
+ engines: {node: '>= 0.6'}
1482
+
1483
+ content-type@1.0.5:
1484
+ resolution: {integrity: sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==}
1485
+ engines: {node: '>= 0.6'}
1486
+
1487
+ cookie-signature@1.2.2:
1488
+ resolution: {integrity: sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==}
1489
+ engines: {node: '>=6.6.0'}
1490
+
1491
  cookie@0.6.0:
1492
  resolution: {integrity: sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==}
1493
  engines: {node: '>= 0.6'}
1494
 
1495
+ cookie@0.7.2:
1496
+ resolution: {integrity: sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==}
1497
+ engines: {node: '>= 0.6'}
1498
+
1499
  core-util-is@1.0.3:
1500
  resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==}
1501
 
1502
+ cors@2.8.5:
1503
+ resolution: {integrity: sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==}
1504
+ engines: {node: '>= 0.10'}
1505
+
1506
  cross-spawn@7.0.6:
1507
  resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==}
1508
  engines: {node: '>= 8'}
 
1602
  resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==}
1603
  engines: {node: '>=0.4.0'}
1604
 
1605
+ depd@2.0.0:
1606
+ resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==}
1607
+ engines: {node: '>= 0.8'}
1608
+
1609
  dequal@2.0.3:
1610
  resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==}
1611
  engines: {node: '>=6'}
 
1622
  detect-node@2.1.0:
1623
  resolution: {integrity: sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==}
1624
 
1625
+ devalue@5.3.2:
1626
+ resolution: {integrity: sha512-UDsjUbpQn9kvm68slnrs+mfxwFkIflOhkanmyabZ8zOYk8SMEIbJ3TK+88g70hSIeytu4y18f0z/hYHMTrXIWw==}
1627
 
1628
  devlop@1.1.0:
1629
  resolution: {integrity: sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==}
1630
 
1631
+ diff-match-patch-es@1.0.1:
1632
+ resolution: {integrity: sha512-KhSofrZDERg/NE6Nd+TK53knp2qz0o2Ix8rhkXd3Chfm7Wlo58Eq/juNmkyS6bS+3xS26L3Pstz3BdY/q+e9UQ==}
1633
 
1634
  diff-sequences@29.6.3:
1635
  resolution: {integrity: sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==}
 
1653
  resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==}
1654
  engines: {node: '>= 0.4'}
1655
 
1656
+ ee-first@1.1.1:
1657
+ resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==}
1658
+
1659
  emoji-regex@8.0.0:
1660
  resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==}
1661
 
1662
+ encodeurl@2.0.0:
1663
+ resolution: {integrity: sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==}
1664
+ engines: {node: '>= 0.8'}
1665
+
1666
  enhanced-resolve@5.18.1:
1667
  resolution: {integrity: sha512-ZSW3ma5GkcQBIpwZTSRAI8N71Uuwgs93IezB7mf7R60tC8ZbJideoDNKjHn2O9KIlx6rkGTTEk1xUCK2E1Y2Yg==}
1668
  engines: {node: '>=10.13.0'}
 
1698
  engines: {node: '>=12'}
1699
  hasBin: true
1700
 
1701
+ escape-html@1.0.3:
1702
+ resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==}
 
 
1703
 
1704
  escape-string-regexp@1.0.5:
1705
  resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==}
 
1729
  eslint-config-prettier:
1730
  optional: true
1731
 
1732
+ eslint-plugin-svelte@3.12.2:
1733
+ resolution: {integrity: sha512-NDYltSWcDybvnXD5P3NtrLAfdrgr2lklZsXpyIoSlQfg2d80p/E853XXccu+uVn+w4+Q/iHy4oRw00GJH9I/Cg==}
1734
  engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
1735
  peerDependencies:
1736
  eslint: ^8.57.1 || ^9.0.0
 
1798
  resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==}
1799
  engines: {node: '>=0.10.0'}
1800
 
1801
+ etag@1.8.1:
1802
+ resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==}
1803
+ engines: {node: '>= 0.6'}
1804
+
1805
  event-target-shim@5.0.1:
1806
  resolution: {integrity: sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==}
1807
  engines: {node: '>=6'}
1808
 
1809
+ eventsource-parser@3.0.6:
1810
+ resolution: {integrity: sha512-Vo1ab+QXPzZ4tCa8SwIHJFaSzy4R6SHf7BY79rFBDf0idraZWAkYrDjDj8uWaSm3S2TK+hJ7/t1CEmZ7jXw+pg==}
1811
+ engines: {node: '>=18.0.0'}
1812
+
1813
+ eventsource@3.0.7:
1814
+ resolution: {integrity: sha512-CRT1WTyuQoD771GW56XEZFQ/ZoSfWid1alKGDYMmkt2yl8UXrVR4pspqWNEcqKvVIzg6PAltWjxcSSPrboA4iA==}
1815
+ engines: {node: '>=18.0.0'}
1816
+
1817
  expect-type@1.2.1:
1818
  resolution: {integrity: sha512-/kP8CAwxzLVEeFrMm4kMmy4CCDlpipyA7MYLVrdJIkV0fYF0UaigQHRsxHiuY/GEea+bh4KSv3TIlgr+2UL6bw==}
1819
  engines: {node: '>=12.0.0'}
1820
 
1821
+ express-rate-limit@7.5.1:
1822
+ resolution: {integrity: sha512-7iN8iPMDzOMHPUYllBEsQdWVB6fPDMPqwjBaFrgr4Jgr/+okjvzAy+UHlYYL/Vs0OsOrMkwS6PJDkFlJwoxUnw==}
1823
+ engines: {node: '>= 16'}
1824
+ peerDependencies:
1825
+ express: '>= 4.11'
1826
+
1827
+ express@5.1.0:
1828
+ resolution: {integrity: sha512-DT9ck5YIRU+8GYzzU5kT3eHGA5iL+1Zd0EutOmTE9Dtk+Tvuzd23VBU+ec7HPNSTxXYO55gPV/hq4pSBJDjFpA==}
1829
+ engines: {node: '>= 18'}
1830
+
1831
  exsolve@1.0.4:
1832
  resolution: {integrity: sha512-xsZH6PXaER4XoV+NiT7JHp1bJodJVT+cxeSH1G0f0tlT0lJqYuHUP3bUx2HtfTDvOagMINYp8rsqusxud3RXhw==}
1833
 
1834
+ exsolve@1.0.7:
1835
+ resolution: {integrity: sha512-VO5fQUzZtI6C+vx4w/4BWJpg3s/5l+6pRQEHzFRM8WFi4XffSP1Z+4qi7GbjWbvRQEbdIco5mIMq+zX4rPuLrw==}
 
1836
 
1837
  fake-indexeddb@6.0.1:
1838
  resolution: {integrity: sha512-He2AjQGHe46svIFq5+L2Nx/eHDTI1oKgoevBP+TthnjymXiKkeJQ3+ITeWey99Y5+2OaPFbI1qEsx/5RsGtWnQ==}
 
1885
  resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==}
1886
  engines: {node: '>=8'}
1887
 
1888
+ finalhandler@2.1.0:
1889
+ resolution: {integrity: sha512-/t88Ty3d5JWQbWYgaOGCCYfXRwV1+be02WqYYlL6h0lEiUAMPM8o8qKGO01YIkOHzka2up08wvgYD0mDiI+q3Q==}
1890
+ engines: {node: '>= 0.8'}
1891
+
1892
  find-cache-dir@5.0.0:
1893
  resolution: {integrity: sha512-OuWNfjfP05JcpAP3JPgAKUhWefjMRfI5iAoSsvE24ANYWJaepAtlSgWECSVEuRgSXpyNEc9DJwG/TZpgcOqyig==}
1894
  engines: {node: '>=16'}
 
1911
  flatted@3.3.3:
1912
  resolution: {integrity: sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==}
1913
 
1914
+ focus-trap@7.6.5:
1915
+ resolution: {integrity: sha512-7Ke1jyybbbPZyZXFxEftUtxFGLMpE2n6A+z//m4CRDlj0hW+o3iYSmh8nFlYMurOiJVDmJRilUQtJr08KfIxlg==}
1916
+
1917
  form-data-encoder@1.7.2:
1918
  resolution: {integrity: sha512-qfqtYan3rxrnCk1VYaA4H+Ms9xdpPqvLZa6xmMgFvhO32x7/3J/ExcTd6qpxM0vH2GdMI+poehyBZvqfMTto8A==}
1919
 
 
1925
  resolution: {integrity: sha512-0iirZp3uVDjVGt9p49aTaqjk84TrglENEDuqfdlZQ1roC9CWlPk6Avf8EEnZNcAqPonwkG35x4n3ww/1THYAeQ==}
1926
  engines: {node: '>= 12.20'}
1927
 
1928
+ forwarded@0.2.0:
1929
+ resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==}
1930
+ engines: {node: '>= 0.6'}
1931
+
1932
+ fresh@2.0.0:
1933
+ resolution: {integrity: sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==}
1934
+ engines: {node: '>= 0.8'}
1935
+
1936
  fsevents@2.3.2:
1937
  resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==}
1938
  engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
 
2039
  html-void-elements@3.0.0:
2040
  resolution: {integrity: sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==}
2041
 
2042
+ http-errors@2.0.0:
2043
+ resolution: {integrity: sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==}
2044
+ engines: {node: '>= 0.8'}
2045
+
2046
  http-proxy-agent@7.0.2:
2047
  resolution: {integrity: sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==}
2048
  engines: {node: '>= 14'}
 
2054
  humanize-ms@1.2.1:
2055
  resolution: {integrity: sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==}
2056
 
 
 
 
 
2057
  iconv-lite@0.6.3:
2058
  resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==}
2059
  engines: {node: '>=0.10.0'}
2060
 
2061
+ iconv-lite@0.7.0:
2062
+ resolution: {integrity: sha512-cf6L2Ds3h57VVmkZe+Pn+5APsT7FpqJtEhhieDCvrE2MK5Qk9MyffgQyuxQTm6BChfeZNtcOLHp9IcWRVcIcBQ==}
2063
+ engines: {node: '>=0.10.0'}
2064
+
2065
  ieee754@1.2.1:
2066
  resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==}
2067
 
 
2091
  resolution: {integrity: sha512-X7rqawQBvfdjS10YU1y1YVreA3SsLrW9dX2CewP2EbBJM4ypVNLDkO5y04gejPwKIY9lR+7r9gn3rFPt/kmWFg==}
2092
  engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0}
2093
 
2094
+ inquirer@8.2.7:
2095
+ resolution: {integrity: sha512-UjOaSel/iddGZJ5xP/Eixh6dY1XghiBw4XK13rCCIJcJfyhhoul/7KhLLUGtebEj6GDYM6Vnx/mVsjx2L/mFIA==}
2096
  engines: {node: '>=12.0.0'}
2097
 
2098
+ ipaddr.js@1.9.1:
2099
+ resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==}
2100
+ engines: {node: '>= 0.10'}
2101
+
2102
  is-arrayish@0.3.2:
2103
  resolution: {integrity: sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==}
2104
 
 
2132
  is-potential-custom-element-name@1.0.1:
2133
  resolution: {integrity: sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==}
2134
 
2135
+ is-promise@4.0.0:
2136
+ resolution: {integrity: sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==}
2137
+
2138
  is-reference@1.2.1:
2139
  resolution: {integrity: sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==}
2140
 
 
2336
  magic-string@0.30.17:
2337
  resolution: {integrity: sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==}
2338
 
2339
+ magic-string@0.30.19:
2340
+ resolution: {integrity: sha512-2N21sPY9Ws53PZvsEpVtNuSW+ScYbQdp4b9qUaL+9QkHUrGFKo56Lg9Emg5s9V/qrtNBmiR01sYhUOwu3H+VOw==}
2341
+
2342
  marked@16.1.2:
2343
  resolution: {integrity: sha512-rNQt5EvRinalby7zJZu/mB+BvaAY2oz3wCuCjt1RDrWNpS1Pdf9xqMOeC9Hm5adBdcV/3XZPJpG58eT+WBc0XQ==}
2344
  engines: {node: '>= 20'}
 
2355
  mdast-util-to-hast@13.2.0:
2356
  resolution: {integrity: sha512-QGYKEuUsYT9ykKBCMOEDLsU5JRObWQusAolFMeko/tYPufNkRffBAQjIE+99jbA87xv6FgmjLtwjh9wBWajwAA==}
2357
 
2358
+ media-typer@1.1.0:
2359
+ resolution: {integrity: sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==}
2360
+ engines: {node: '>= 0.8'}
2361
+
2362
+ melt@0.40.2:
2363
+ resolution: {integrity: sha512-lmf17KdERiDZ4Fefx4B/nrvMptG8QqUexMuRlaxT9AlbX7zbjaqPfJz31ekRvkcw6pgYOuYmQPmhY6jlUDVqSw==}
2364
  peerDependencies:
2365
  '@floating-ui/dom': ^1.6.0
2366
  svelte: ^5.30.1
2367
 
2368
+ merge-descriptors@2.0.0:
2369
+ resolution: {integrity: sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==}
2370
+ engines: {node: '>=18'}
2371
+
2372
  merge2@1.4.1:
2373
  resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==}
2374
  engines: {node: '>= 8'}
 
2396
  resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==}
2397
  engines: {node: '>= 0.6'}
2398
 
2399
+ mime-db@1.54.0:
2400
+ resolution: {integrity: sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==}
2401
+ engines: {node: '>= 0.6'}
2402
+
2403
  mime-types@2.1.35:
2404
  resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==}
2405
  engines: {node: '>= 0.6'}
2406
 
2407
+ mime-types@3.0.1:
2408
+ resolution: {integrity: sha512-xRc4oEhT6eaBpU1XF7AjpOFD+xQmXNB5OVKwp4tqCuBpHLS/ZbBDrc07mYTDqVMg6PfxUjjNp85O6Cd2Z/5HWA==}
2409
+ engines: {node: '>= 0.6'}
2410
+
2411
  mimic-fn@2.1.0:
2412
  resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==}
2413
  engines: {node: '>=6'}
 
2461
  engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
2462
  hasBin: true
2463
 
 
 
 
 
 
2464
  natural-compare@1.4.0:
2465
  resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==}
2466
 
2467
+ negotiator@1.0.0:
2468
+ resolution: {integrity: sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==}
2469
+ engines: {node: '>= 0.6'}
2470
+
2471
  node-domexception@1.0.0:
2472
  resolution: {integrity: sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==}
2473
  engines: {node: '>=10.5.0'}
 
2484
  nwsapi@2.2.20:
2485
  resolution: {integrity: sha512-/ieB+mDe4MrrKMT8z+mQL8klXydZWGR5Dowt4RAGKbJ3kIGEx3X4ljUo+6V73IXtUPWgfOlU5B9MlGxFO5T+cA==}
2486
 
2487
+ object-assign@4.1.1:
2488
+ resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==}
2489
+ engines: {node: '>=0.10.0'}
2490
+
2491
+ object-inspect@1.13.4:
2492
+ resolution: {integrity: sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==}
2493
+ engines: {node: '>= 0.4'}
2494
+
2495
  object-keys@1.1.1:
2496
  resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==}
2497
  engines: {node: '>= 0.4'}
2498
 
2499
+ on-finished@2.4.1:
2500
+ resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==}
2501
+ engines: {node: '>= 0.8'}
2502
+
2503
+ once@1.4.0:
2504
+ resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==}
2505
+
2506
  onetime@5.1.2:
2507
  resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==}
2508
  engines: {node: '>=6'}
 
2546
  resolution: {integrity: sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==}
2547
  engines: {node: '>=10'}
2548
 
 
 
 
 
2549
  p-limit@3.1.0:
2550
  resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==}
2551
  engines: {node: '>=10'}
 
2572
  parse5@7.3.0:
2573
  resolution: {integrity: sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==}
2574
 
2575
+ parseurl@1.3.3:
2576
+ resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==}
2577
+ engines: {node: '>= 0.8'}
2578
+
2579
  path-exists@4.0.0:
2580
  resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==}
2581
  engines: {node: '>=8'}
 
2591
  path-parse@1.0.7:
2592
  resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==}
2593
 
2594
+ path-to-regexp@8.3.0:
2595
+ resolution: {integrity: sha512-7jdwVIRtsP8MYpdXSwOS0YdD0Du+qOoF/AEPIt88PcCFrZCzx41oxku1jD88hZBwbNUIEfpqvuhjFaMAqMTWnA==}
2596
 
2597
  pathe@2.0.3:
2598
  resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==}
 
2612
  resolution: {integrity: sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==}
2613
  engines: {node: '>=12'}
2614
 
2615
+ picomatch@4.0.3:
2616
+ resolution: {integrity: sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==}
2617
+ engines: {node: '>=12'}
2618
+
2619
+ pkce-challenge@5.0.0:
2620
+ resolution: {integrity: sha512-ueGLflrrnvwB3xuo/uGob5pd5FN7l0MsLf0Z87o/UQmRtwjvfylfc9MurIxRAWywCYTgrvpXBcqjV4OfCYGCIQ==}
2621
+ engines: {node: '>=16.20.0'}
2622
+
2623
  pkg-dir@7.0.0:
2624
  resolution: {integrity: sha512-Ie9z/WINcxxLp27BKOCHGde4ITq9UklYKDzVo1nhk5sqGEXU3FpkwP5GM2voTGJkGd9B3Otl+Q4uwSOeSUtOBA==}
2625
  engines: {node: '>=14.16'}
 
2630
  pkg-types@2.1.0:
2631
  resolution: {integrity: sha512-wmJwA+8ihJixSoHKxZJRBQG1oY8Yr9pGLzRmSsNms0iNWyHHAlZCa7mmKiFR10YPZuz/2k169JiS/inOjBCZ2A==}
2632
 
2633
+ pkg-types@2.3.0:
2634
+ resolution: {integrity: sha512-SIqCzDRg0s9npO5XQ3tNZioRY1uK06lA41ynBC1YmFTmnY6FjUjVt6s4LoADmwoig1qqD0oK8h1p/8mlMx8Oig==}
2635
+
2636
  platform@1.3.6:
2637
  resolution: {integrity: sha512-fnWVljUchTro6RiCFvCXBbNhJc2NijN7oIQxbwsyL0buWJPG85v81ehlHI9fXrJsMNgTofEoWIQeClKpgxFLrg==}
2638
 
 
2771
  resolution: {integrity: sha512-mRUWCc3KUU4w1jU8sGxICXH/gNS94DvI1gxqDvBzhj1JpcsimQkYiOJfwsPUykUI5ZaspFbSgmBLER8IrQ3tqw==}
2772
  engines: {node: '>=12.0.0'}
2773
 
2774
+ proxy-addr@2.0.7:
2775
+ resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==}
2776
+ engines: {node: '>= 0.10'}
2777
+
2778
  punycode@2.3.1:
2779
  resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==}
2780
  engines: {node: '>=6'}
2781
 
2782
+ qs@6.14.0:
2783
+ resolution: {integrity: sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==}
2784
+ engines: {node: '>=0.6'}
2785
+
2786
  quansync@0.2.8:
2787
  resolution: {integrity: sha512-4+saucphJMazjt7iOM27mbFCk+D9dd/zmgMDCzRZ8MEoBfYp7lAvoN38et/phRQF6wOPMy/OROBGgoWeSKyluA==}
2788
 
 
2793
  resolution: {integrity: sha512-U+5l2KrcMNOUPYvazA3h5ekF80FHTUG+87SEAmHZmolh1M+i/WyTCxVzmi+tidIa1tM4BSe8g2Y/D3loWDjj+w==}
2794
  engines: {node: '>=4'}
2795
 
2796
+ range-parser@1.2.1:
2797
+ resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==}
2798
+ engines: {node: '>= 0.6'}
2799
+
2800
+ raw-body@3.0.1:
2801
+ resolution: {integrity: sha512-9G8cA+tuMS75+6G/TzW8OtLzmBDMo8p1JRxN5AZ+LAp8uxGA8V8GZm4GQ4/N5QNQEnLmg6SS7wyuSmbKepiKqA==}
2802
+ engines: {node: '>= 0.10'}
2803
+
2804
  react-is@17.0.2:
2805
  resolution: {integrity: sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==}
2806
 
 
2868
  engines: {node: '>=18.0.0', npm: '>=8.0.0'}
2869
  hasBin: true
2870
 
2871
+ router@2.2.0:
2872
+ resolution: {integrity: sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==}
2873
+ engines: {node: '>= 18'}
2874
+
2875
  rrweb-cssom@0.8.0:
2876
  resolution: {integrity: sha512-guoltQEx+9aMf2gDZ0s62EcV8lsXR+0w8915TC3ITdn2YueuNjdAYh/levpU9nFaoChh9RUS5ZdQMrKfVEN9tw==}
2877
 
 
2922
  engines: {node: '>=10'}
2923
  hasBin: true
2924
 
2925
+ send@1.2.0:
2926
+ resolution: {integrity: sha512-uaW0WwXKpL9blXE2o0bRhoL2EGXIrZxQ2ZQ4mgcfoBxdFmQold+qWsD2jLrfZ0trjKL6vOw0j//eAwcALFjKSw==}
2927
+ engines: {node: '>= 18'}
2928
+
2929
  serialize-error@7.0.1:
2930
  resolution: {integrity: sha512-8I8TjW5KMOKsZQTvoxjuSIa7foAwPWGOts+6o7sgjz41/qMD9VQHEDxi6PBvK2l0MXUmqZyNpUK+T2tQaaElvw==}
2931
  engines: {node: '>=10'}
2932
 
2933
+ serve-static@2.2.0:
2934
+ resolution: {integrity: sha512-61g9pCh0Vnh7IutZjtLGGpTA355+OPn2TyDv/6ivP2h/AdAVX9azsoxmg2/M6nZeQZNYBEwIcsne1mJd9oQItQ==}
2935
+ engines: {node: '>= 18'}
2936
+
2937
  set-cookie-parser@2.7.1:
2938
  resolution: {integrity: sha512-IOc8uWeOZgnb3ptbCURJWNjWUPcO3ZnTTdzsurqERrP6nPyv+paC55vJM0LpOlT2ne+Ix+9+CRG1MNLlyZ4GjQ==}
2939
 
2940
+ setprototypeof@1.2.0:
2941
+ resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==}
2942
+
2943
  sharp@0.34.2:
2944
  resolution: {integrity: sha512-lszvBmB9QURERtyKT2bNmsgxXK0ShJrL/fvqlonCo7e6xBF8nT8xU6pW+PMIbLsz0RxQk3rgH9kd8UmvOzlMJg==}
2945
  engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
 
2955
  shiki@3.4.0:
2956
  resolution: {integrity: sha512-Ni80XHcqhOEXv5mmDAvf5p6PAJqbUc/RzFeaOqk+zP5DLvTPS3j0ckvA+MI87qoxTQ5RGJDVTbdl/ENLSyyAnQ==}
2957
 
2958
+ side-channel-list@1.0.0:
2959
+ resolution: {integrity: sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==}
2960
+ engines: {node: '>= 0.4'}
2961
+
2962
+ side-channel-map@1.0.1:
2963
+ resolution: {integrity: sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==}
2964
+ engines: {node: '>= 0.4'}
2965
+
2966
+ side-channel-weakmap@1.0.2:
2967
+ resolution: {integrity: sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==}
2968
+ engines: {node: '>= 0.4'}
2969
+
2970
+ side-channel@1.1.0:
2971
+ resolution: {integrity: sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==}
2972
+ engines: {node: '>= 0.4'}
2973
+
2974
  siginfo@2.0.0:
2975
  resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==}
2976
 
 
2997
  stackback@0.0.2:
2998
  resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==}
2999
 
3000
+ statuses@2.0.1:
3001
+ resolution: {integrity: sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==}
3002
+ engines: {node: '>= 0.8'}
3003
+
3004
+ statuses@2.0.2:
3005
+ resolution: {integrity: sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==}
3006
+ engines: {node: '>= 0.8'}
3007
+
3008
  std-env@3.9.0:
3009
  resolution: {integrity: sha512-UGvjygr6F6tpH7o2qyqR6QYpwraIjKSdtzyBdyytFOHmPZY917kwdwLG0RbOjWOnKmnm3PeHjaoLLMie7kPLQw==}
3010
 
 
3038
  resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==}
3039
  engines: {node: '>= 0.4'}
3040
 
3041
+ svelte-check@4.3.1:
3042
+ resolution: {integrity: sha512-lkh8gff5gpHLjxIV+IaApMxQhTGnir2pNUAqcNgeKkvK5bT/30Ey/nzBxNLDlkztCH4dP7PixkMt9SWEKFPBWg==}
3043
  engines: {node: '>= 18.0.0'}
3044
  hasBin: true
3045
  peerDependencies:
 
3055
  svelte:
3056
  optional: true
3057
 
3058
+ svelte@5.38.7:
3059
+ resolution: {integrity: sha512-1ld9TPZSdUS3EtYGQzisU2nhwXoIzNQcZ71IOU9fEmltaUofQnVfW5CQuhgM/zFsZ43arZXS1BRKi0MYgUV91w==}
3060
  engines: {node: '>=18'}
3061
 
3062
  symbol-tree@3.2.4:
 
3066
  resolution: {integrity: sha512-vrozgXDQwYO72vHjUb/HnFbQx1exDjoKzqx23aXEg2a9VIg2TSFZ8FmeZpTjUCFMYw7mpX4BE2SFu8wI7asYsw==}
3067
  engines: {node: ^14.18.0 || >=16.0.0}
3068
 
3069
+ tabbable@6.2.0:
3070
+ resolution: {integrity: sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew==}
3071
+
3072
  tailwind-merge@3.0.2:
3073
  resolution: {integrity: sha512-l7z+OYZ7mu3DTqrL88RiKrKIqO3NcpEO8V/Od04bNpvk0kiIFndGEoqfuzvj4yuhRkHKjRkII2z+KS2HfPcSxw==}
3074
 
3075
+ tailwindcss-spring@1.0.1:
3076
+ resolution: {integrity: sha512-v8ibKyVCgbFcHzP9EFSbsvR0vH7Vk2Skl9JnJ9HUrnA16NhjvI4SlV9Y4SkinL+4bNrm1XpftZwX1DAD1mNZFA==}
3077
+ peerDependencies:
3078
+ tailwindcss: '>=3.0.0 || insiders'
3079
+
3080
  tailwindcss@4.0.9:
3081
  resolution: {integrity: sha512-12laZu+fv1ONDRoNR9ipTOpUD7RN9essRVkX36sjxuRUInpN7hIiHN4lBd/SIFjbISvnXzp8h/hXzmU8SQQYhw==}
3082
 
 
3120
  resolution: {integrity: sha512-WMi/OQ2axVTf/ykqCQgXiIct+mSQDFdH2fkwhPwgEwvJ1kSzZRiinb0zF2Xb8u4+OqPChmyI6MEu4EezNJz+FQ==}
3121
  hasBin: true
3122
 
 
 
 
 
3123
  to-regex-range@5.0.1:
3124
  resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==}
3125
  engines: {node: '>=8.0'}
3126
 
3127
+ toidentifier@1.0.1:
3128
+ resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==}
3129
+ engines: {node: '>=0.6'}
3130
+
3131
  totalist@3.0.1:
3132
  resolution: {integrity: sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==}
3133
  engines: {node: '>=6'}
 
3171
  resolution: {integrity: sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==}
3172
  engines: {node: '>=10'}
3173
 
3174
+ type-fest@4.41.0:
3175
+ resolution: {integrity: sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==}
3176
  engines: {node: '>=16'}
3177
 
3178
+ type-is@2.0.1:
3179
+ resolution: {integrity: sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==}
3180
+ engines: {node: '>= 0.6'}
3181
+
3182
  typescript-eslint@8.26.1:
3183
  resolution: {integrity: sha512-t/oIs9mYyrwZGRpDv3g+3K6nZ5uhKEMt2oNmAPwaY4/ye0+EH4nXIPYNtkYFS6QHm+1DFg34DbglYBz5P9Xysg==}
3184
  engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
 
3186
  eslint: ^8.57.0 || ^9.0.0
3187
  typescript: '>=4.8.4 <5.9.0'
3188
 
 
 
 
 
 
3189
  typescript@5.8.2:
3190
  resolution: {integrity: sha512-aJn6wq13/afZp/jT9QZmwEjDqqvSGp1VT5GVg+f/t6/oVyrgXM6BY1h9BRh/O5p3PlUPAe+WuiEZOmb/49RqoQ==}
3191
  engines: {node: '>=14.17'}
3192
  hasBin: true
3193
 
3194
+ typia@9.7.2:
3195
+ resolution: {integrity: sha512-eLIKd0KHZtSvbsA+FYwX+Y0ZBt0BwVGz3GgODQX+6GfGL4DOzKW02LEx62oUZg6vCQX1BL5xyiPXAIdW+Hc51g==}
3196
  hasBin: true
3197
  peerDependencies:
3198
+ typescript: '>=4.8.0 <5.10.0'
 
 
 
 
 
 
 
 
3199
 
3200
  ufo@1.5.4:
3201
  resolution: {integrity: sha512-UsUk3byDzKd04EyoZ7U4DOlxQaD14JUKQl6/P7wiX4FNvUfm3XL246n9W5AmqwW5RSFJ27NAuM0iLscAOYUiGQ==}
 
3221
  unist-util-visit@5.0.0:
3222
  resolution: {integrity: sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==}
3223
 
3224
+ unpipe@1.0.0:
3225
+ resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==}
3226
+ engines: {node: '>= 0.8'}
3227
+
3228
  unplugin-icons@22.1.0:
3229
  resolution: {integrity: sha512-ect2ZNtk1Zgwb0NVHd0C1IDW/MV+Jk/xaq4t8o6rYdVS3+L660ZdD5kTSQZvsgdwCvquRw+/wYn75hsweRjoIA==}
3230
  peerDependencies:
 
3248
  vue-template-es2015-compiler:
3249
  optional: true
3250
 
 
 
 
 
3251
  unplugin@2.2.0:
3252
  resolution: {integrity: sha512-m1ekpSwuOT5hxkJeZGRxO7gXbXT3gF26NjQ7GdVHoLoF8/nopLcd/QfPigpCy7i51oFHiRJg/CyHhj4vs2+KGw==}
3253
  engines: {node: '>=18.12.0'}
3254
 
3255
+ unplugin@2.3.10:
3256
+ resolution: {integrity: sha512-6NCPkv1ClwH+/BGE9QeoTIl09nuiAt0gS28nn1PvYXsGKRwM2TCbFA2QiilmehPDTXIe684k4rZI1yl3A1PCUw==}
3257
+ engines: {node: '>=18.12.0'}
3258
+
3259
  uri-js@4.4.1:
3260
  resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==}
3261
 
 
3266
  resolution: {integrity: sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==}
3267
  hasBin: true
3268
 
3269
+ vary@1.1.2:
3270
+ resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==}
3271
+ engines: {node: '>= 0.8'}
3272
+
3273
  vfile-message@4.0.2:
3274
  resolution: {integrity: sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw==}
3275
 
 
3312
  terser:
3313
  optional: true
3314
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3315
  vitefu@1.0.6:
3316
  resolution: {integrity: sha512-+Rex1GlappUyNN6UfwbVZne/9cYC4+R2XDk9xkNXBKMw6HQagdX9PgZ8V2v1WUSK1wfBLp7qbI1+XSNIlB1xmA==}
3317
  peerDependencies:
 
3415
  resolution: {integrity: sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==}
3416
  engines: {node: '>=8'}
3417
 
3418
+ wrappy@1.0.2:
3419
+ resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==}
3420
+
3421
  ws@8.18.2:
3422
  resolution: {integrity: sha512-DMricUmwGZUVr++AEAe2uiVM7UoO9MAVZMDu05UQOaUII0lp+zOzLLU4Xqh/JvTqklB1T4uELaaPBKyjE1r4fQ==}
3423
  engines: {node: '>=10.0.0'}
 
3445
  resolution: {integrity: sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==}
3446
  engines: {node: '>= 6'}
3447
 
 
 
 
 
 
3448
  yocto-queue@0.1.0:
3449
  resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==}
3450
  engines: {node: '>=10'}
3451
 
3452
+ yocto-queue@1.2.1:
3453
+ resolution: {integrity: sha512-AyeEbWOu/TAXdxlV9wmGcR0+yh2j3vYPGOECcIj2S7MkrLyC7ne+oye2BKTItt0ii2PHk4cDy+95+LshzbXnGg==}
3454
  engines: {node: '>=12.20'}
3455
 
3456
  zimmerframe@1.1.2:
3457
  resolution: {integrity: sha512-rAbqEGa8ovJy4pyBxZM70hg4pE6gDgaQ0Sl9M3enG3I0d6H4XSAM3GeNGLKnsBpuijUow064sf7ww1nutC5/3w==}
3458
 
3459
+ zod-to-json-schema@3.24.6:
3460
+ resolution: {integrity: sha512-h/z3PKvcTcTetyjl1fkj79MHNEjm+HpD6NXheWjzOekY7kV+lwDYnHw+ivHkijnCSMz1yJaWBD9vu/Fcmk+vEg==}
3461
+ peerDependencies:
3462
+ zod: ^3.24.1
3463
+
3464
+ zod@3.25.76:
3465
+ resolution: {integrity: sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==}
3466
+
3467
  zwitch@2.0.4:
3468
  resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==}
3469
 
 
3473
 
3474
  '@alloc/quick-lru@5.2.0': {}
3475
 
 
 
 
 
 
3476
  '@antfu/install-pkg@1.0.0':
3477
  dependencies:
3478
  package-manager-detector: 0.2.11
 
3526
  '@esbuild/aix-ppc64@0.21.5':
3527
  optional: true
3528
 
 
 
 
3529
  '@esbuild/android-arm64@0.21.5':
3530
  optional: true
3531
 
 
 
 
3532
  '@esbuild/android-arm@0.21.5':
3533
  optional: true
3534
 
 
 
 
3535
  '@esbuild/android-x64@0.21.5':
3536
  optional: true
3537
 
 
 
 
3538
  '@esbuild/darwin-arm64@0.21.5':
3539
  optional: true
3540
 
 
 
 
3541
  '@esbuild/darwin-x64@0.21.5':
3542
  optional: true
3543
 
 
 
 
3544
  '@esbuild/freebsd-arm64@0.21.5':
3545
  optional: true
3546
 
 
 
 
3547
  '@esbuild/freebsd-x64@0.21.5':
3548
  optional: true
3549
 
 
 
 
3550
  '@esbuild/linux-arm64@0.21.5':
3551
  optional: true
3552
 
 
 
 
3553
  '@esbuild/linux-arm@0.21.5':
3554
  optional: true
3555
 
 
 
 
3556
  '@esbuild/linux-ia32@0.21.5':
3557
  optional: true
3558
 
 
 
 
3559
  '@esbuild/linux-loong64@0.21.5':
3560
  optional: true
3561
 
 
 
 
3562
  '@esbuild/linux-mips64el@0.21.5':
3563
  optional: true
3564
 
 
 
 
3565
  '@esbuild/linux-ppc64@0.21.5':
3566
  optional: true
3567
 
 
 
 
3568
  '@esbuild/linux-riscv64@0.21.5':
3569
  optional: true
3570
 
 
 
 
3571
  '@esbuild/linux-s390x@0.21.5':
3572
  optional: true
3573
 
 
 
 
3574
  '@esbuild/linux-x64@0.21.5':
3575
  optional: true
3576
 
 
 
 
 
 
 
3577
  '@esbuild/netbsd-x64@0.21.5':
3578
  optional: true
3579
 
 
 
 
 
 
 
3580
  '@esbuild/openbsd-x64@0.21.5':
3581
  optional: true
3582
 
 
 
 
3583
  '@esbuild/sunos-x64@0.21.5':
3584
  optional: true
3585
 
 
 
 
3586
  '@esbuild/win32-arm64@0.21.5':
3587
  optional: true
3588
 
 
 
 
3589
  '@esbuild/win32-ia32@0.21.5':
3590
  optional: true
3591
 
 
 
 
3592
  '@esbuild/win32-x64@0.21.5':
3593
  optional: true
3594
 
 
 
 
3595
  '@eslint-community/eslint-utils@4.4.1(eslint@9.22.0(jiti@2.4.2))':
3596
  dependencies:
3597
  eslint: 9.22.0(jiti@2.4.2)
 
3689
  dependencies:
3690
  '@iconify/types': 2.0.0
3691
 
3692
+ '@iconify-json/line-md@1.2.11':
3693
+ dependencies:
3694
+ '@iconify/types': 2.0.0
3695
+
3696
  '@iconify-json/lucide@1.2.45':
3697
  dependencies:
3698
  '@iconify/types': 2.0.0
 
3801
  '@img/sharp-win32-x64@0.34.2':
3802
  optional: true
3803
 
3804
+ '@inquirer/external-editor@1.0.1(@types/node@22.14.1)':
3805
+ dependencies:
3806
+ chardet: 2.1.0
3807
+ iconv-lite: 0.6.3
3808
+ optionalDependencies:
3809
+ '@types/node': 22.14.1
3810
+
3811
  '@isaacs/fs-minipass@4.0.1':
3812
  dependencies:
3813
  minipass: 7.1.2
 
3816
  dependencies:
3817
  '@sinclair/typebox': 0.27.8
3818
 
3819
+ '@jridgewell/gen-mapping@0.3.13':
3820
  dependencies:
 
3821
  '@jridgewell/sourcemap-codec': 1.5.0
3822
+ '@jridgewell/trace-mapping': 0.3.30
3823
 
3824
+ '@jridgewell/remapping@2.3.5':
3825
+ dependencies:
3826
+ '@jridgewell/gen-mapping': 0.3.13
3827
+ '@jridgewell/trace-mapping': 0.3.30
3828
 
3829
+ '@jridgewell/resolve-uri@3.1.2': {}
3830
 
3831
  '@jridgewell/sourcemap-codec@1.5.0': {}
3832
 
3833
+ '@jridgewell/sourcemap-codec@1.5.5': {}
3834
+
3835
  '@jridgewell/trace-mapping@0.3.25':
3836
  dependencies:
3837
  '@jridgewell/resolve-uri': 3.1.2
3838
  '@jridgewell/sourcemap-codec': 1.5.0
3839
 
3840
+ '@jridgewell/trace-mapping@0.3.30':
3841
+ dependencies:
3842
+ '@jridgewell/resolve-uri': 3.1.2
3843
+ '@jridgewell/sourcemap-codec': 1.5.0
3844
+
3845
+ '@modelcontextprotocol/sdk@1.17.5':
3846
+ dependencies:
3847
+ ajv: 6.12.6
3848
+ content-type: 1.0.5
3849
+ cors: 2.8.5
3850
+ cross-spawn: 7.0.6
3851
+ eventsource: 3.0.7
3852
+ eventsource-parser: 3.0.6
3853
+ express: 5.1.0
3854
+ express-rate-limit: 7.5.1(express@5.1.0)
3855
+ pkce-challenge: 5.0.0
3856
+ raw-body: 3.0.1
3857
+ zod: 3.25.76
3858
+ zod-to-json-schema: 3.24.6(zod@3.25.76)
3859
+ transitivePeerDependencies:
3860
+ - supports-color
3861
+
3862
  '@noble/hashes@1.8.0': {}
3863
 
3864
  '@nodelib/fs.scandir@2.1.5':
 
3944
  optionalDependencies:
3945
  rollup: 4.34.9
3946
 
3947
+ '@rollup/pluginutils@5.3.0(rollup@4.34.9)':
3948
+ dependencies:
3949
+ '@types/estree': 1.0.8
3950
+ estree-walker: 2.0.2
3951
+ picomatch: 4.0.3
3952
+ optionalDependencies:
3953
+ rollup: 4.34.9
3954
+
3955
  '@rollup/rollup-android-arm-eabi@4.34.9':
3956
  optional: true
3957
 
 
4009
  '@rollup/rollup-win32-x64-msvc@4.34.9':
4010
  optional: true
4011
 
4012
+ '@ryoppippi/unplugin-typia@2.6.5(rollup@4.34.9)(svelte@5.38.7)(typescript@5.8.2)(typia@9.7.2(@types/node@22.14.1)(typescript@5.8.2))(vite@5.4.14(@types/node@22.14.1)(lightningcss@1.29.1))':
4013
  dependencies:
4014
+ '@rollup/pluginutils': 5.3.0(rollup@4.34.9)
4015
+ bun-only: 0.0.1
4016
+ consola: 3.4.2
4017
  defu: 6.1.4
4018
+ diff-match-patch-es: 1.0.1
4019
  find-cache-dir: 5.0.0
4020
+ magic-string: 0.30.19
4021
+ pathe: 2.0.3
4022
+ pkg-types: 2.3.0
4023
+ type-fest: 4.41.0
4024
+ typescript: 5.8.2
4025
+ typia: 9.7.2(@types/node@22.14.1)(typescript@5.8.2)
4026
+ unplugin: 2.3.10
4027
+ optionalDependencies:
4028
+ svelte: 5.38.7
4029
+ vite: 5.4.14(@types/node@22.14.1)(lightningcss@1.29.1)
4030
  transitivePeerDependencies:
 
 
 
 
 
4031
  - rollup
 
 
 
 
 
 
 
4032
 
4033
+ '@samchon/openapi@4.7.1': {}
4034
 
4035
  '@shikijs/core@3.4.0':
4036
  dependencies:
 
4067
 
4068
  '@sinclair/typebox@0.27.8': {}
4069
 
4070
+ '@standard-schema/spec@1.0.0': {}
4071
+
4072
+ '@svelte-put/shortcut@4.1.0(svelte@5.38.7)':
4073
  dependencies:
4074
+ svelte: 5.38.7
4075
 
4076
  '@sveltejs/acorn-typescript@1.0.5(acorn@8.14.0)':
4077
  dependencies:
4078
  acorn: 8.14.0
4079
 
4080
+ '@sveltejs/acorn-typescript@1.0.5(acorn@8.15.0)':
4081
+ dependencies:
4082
+ acorn: 8.15.0
4083
+
4084
+ '@sveltejs/adapter-auto@3.3.1(@sveltejs/kit@2.37.1(@sveltejs/vite-plugin-svelte@4.0.4(svelte@5.38.7)(vite@5.4.14(@types/node@22.14.1)(lightningcss@1.29.1)))(svelte@5.38.7)(vite@5.4.14(@types/node@22.14.1)(lightningcss@1.29.1)))':
4085
  dependencies:
4086
+ '@sveltejs/kit': 2.37.1(@sveltejs/vite-plugin-svelte@4.0.4(svelte@5.38.7)(vite@5.4.14(@types/node@22.14.1)(lightningcss@1.29.1)))(svelte@5.38.7)(vite@5.4.14(@types/node@22.14.1)(lightningcss@1.29.1))
4087
  import-meta-resolve: 4.1.0
4088
 
4089
+ '@sveltejs/adapter-node@5.3.1(@sveltejs/kit@2.37.1(@sveltejs/vite-plugin-svelte@4.0.4(svelte@5.38.7)(vite@5.4.14(@types/node@22.14.1)(lightningcss@1.29.1)))(svelte@5.38.7)(vite@5.4.14(@types/node@22.14.1)(lightningcss@1.29.1)))':
4090
  dependencies:
4091
  '@rollup/plugin-commonjs': 28.0.2(rollup@4.34.9)
4092
  '@rollup/plugin-json': 6.1.0(rollup@4.34.9)
4093
  '@rollup/plugin-node-resolve': 16.0.0(rollup@4.34.9)
4094
+ '@sveltejs/kit': 2.37.1(@sveltejs/vite-plugin-svelte@4.0.4(svelte@5.38.7)(vite@5.4.14(@types/node@22.14.1)(lightningcss@1.29.1)))(svelte@5.38.7)(vite@5.4.14(@types/node@22.14.1)(lightningcss@1.29.1))
4095
  rollup: 4.34.9
4096
 
4097
+ '@sveltejs/kit@2.37.1(@sveltejs/vite-plugin-svelte@4.0.4(svelte@5.38.7)(vite@5.4.14(@types/node@22.14.1)(lightningcss@1.29.1)))(svelte@5.38.7)(vite@5.4.14(@types/node@22.14.1)(lightningcss@1.29.1))':
4098
  dependencies:
4099
+ '@standard-schema/spec': 1.0.0
4100
+ '@sveltejs/acorn-typescript': 1.0.5(acorn@8.15.0)
4101
+ '@sveltejs/vite-plugin-svelte': 4.0.4(svelte@5.38.7)(vite@5.4.14(@types/node@22.14.1)(lightningcss@1.29.1))
4102
  '@types/cookie': 0.6.0
4103
+ acorn: 8.15.0
4104
  cookie: 0.6.0
4105
+ devalue: 5.3.2
4106
  esm-env: 1.2.2
 
4107
  kleur: 4.1.5
4108
  magic-string: 0.30.17
4109
  mrmime: 2.0.1
4110
  sade: 1.8.1
4111
  set-cookie-parser: 2.7.1
4112
  sirv: 3.0.1
4113
+ svelte: 5.38.7
4114
  vite: 5.4.14(@types/node@22.14.1)(lightningcss@1.29.1)
4115
 
4116
+ '@sveltejs/vite-plugin-svelte-inspector@3.0.1(@sveltejs/vite-plugin-svelte@4.0.4(svelte@5.38.7)(vite@5.4.14(@types/node@22.14.1)(lightningcss@1.29.1)))(svelte@5.38.7)(vite@5.4.14(@types/node@22.14.1)(lightningcss@1.29.1))':
4117
  dependencies:
4118
+ '@sveltejs/vite-plugin-svelte': 4.0.4(svelte@5.38.7)(vite@5.4.14(@types/node@22.14.1)(lightningcss@1.29.1))
4119
  debug: 4.4.0
4120
+ svelte: 5.38.7
4121
  vite: 5.4.14(@types/node@22.14.1)(lightningcss@1.29.1)
4122
  transitivePeerDependencies:
4123
  - supports-color
4124
 
4125
+ '@sveltejs/vite-plugin-svelte@4.0.4(svelte@5.38.7)(vite@5.4.14(@types/node@22.14.1)(lightningcss@1.29.1))':
4126
  dependencies:
4127
+ '@sveltejs/vite-plugin-svelte-inspector': 3.0.1(@sveltejs/vite-plugin-svelte@4.0.4(svelte@5.38.7)(vite@5.4.14(@types/node@22.14.1)(lightningcss@1.29.1)))(svelte@5.38.7)(vite@5.4.14(@types/node@22.14.1)(lightningcss@1.29.1))
4128
  debug: 4.4.0
4129
  deepmerge: 4.3.1
4130
  kleur: 4.1.5
4131
  magic-string: 0.30.17
4132
+ svelte: 5.38.7
4133
  vite: 5.4.14(@types/node@22.14.1)(lightningcss@1.29.1)
4134
  vitefu: 1.0.6(vite@5.4.14(@types/node@22.14.1)(lightningcss@1.29.1))
4135
  transitivePeerDependencies:
 
4230
  lodash: 4.17.21
4231
  redent: 3.0.0
4232
 
4233
+ '@testing-library/svelte@5.2.8(svelte@5.38.7)(vite@5.4.14(@types/node@22.14.1)(lightningcss@1.29.1))(vitest@3.1.4)':
4234
  dependencies:
4235
  '@testing-library/dom': 10.4.0
4236
+ svelte: 5.38.7
4237
  optionalDependencies:
4238
  vite: 5.4.14(@types/node@22.14.1)(lightningcss@1.29.1)
4239
  vitest: 3.1.4(@types/node@22.14.1)(@vitest/browser@3.1.4)(jsdom@26.1.0)(lightningcss@1.29.1)
 
4269
 
4270
  '@types/estree@1.0.6': {}
4271
 
4272
+ '@types/estree@1.0.8': {}
4273
+
4274
  '@types/hast@3.0.4':
4275
  dependencies:
4276
  '@types/unist': 3.0.3
 
4436
  loupe: 3.1.3
4437
  tinyrainbow: 2.0.0
4438
 
4439
+ '@xyflow/svelte@1.2.4(svelte@5.38.7)':
4440
  dependencies:
4441
+ '@svelte-put/shortcut': 4.1.0(svelte@5.38.7)
4442
  '@xyflow/system': 0.0.68
4443
+ svelte: 5.38.7
4444
 
4445
  '@xyflow/system@0.0.68':
4446
  dependencies:
 
4458
  dependencies:
4459
  event-target-shim: 5.0.1
4460
 
4461
+ accepts@2.0.0:
4462
+ dependencies:
4463
+ mime-types: 3.0.1
4464
+ negotiator: 1.0.0
4465
+
4466
  acorn-jsx@5.3.2(acorn@8.14.0):
4467
  dependencies:
4468
  acorn: 8.14.0
4469
 
4470
  acorn@8.14.0: {}
4471
 
4472
+ acorn@8.15.0: {}
4473
+
4474
  agent-base@7.1.3: {}
4475
 
4476
  agentkeepalive@4.6.0:
 
4524
  inherits: 2.0.4
4525
  readable-stream: 3.6.2
4526
 
4527
+ body-parser@2.2.0:
4528
+ dependencies:
4529
+ bytes: 3.1.2
4530
+ content-type: 1.0.5
4531
+ debug: 4.4.0
4532
+ http-errors: 2.0.0
4533
+ iconv-lite: 0.6.3
4534
+ on-finished: 2.4.1
4535
+ qs: 6.14.0
4536
+ raw-body: 3.0.1
4537
+ type-is: 2.0.1
4538
+ transitivePeerDependencies:
4539
+ - supports-color
4540
+
4541
  boolean@3.2.0: {}
4542
 
4543
  brace-expansion@1.1.11:
 
4558
  base64-js: 1.5.1
4559
  ieee754: 1.2.1
4560
 
4561
+ bun-only@0.0.1: {}
4562
+
4563
+ bytes@3.1.2: {}
4564
+
4565
  cac@6.7.14: {}
4566
 
4567
  call-bind-apply-helpers@1.0.2:
 
4569
  es-errors: 1.3.0
4570
  function-bind: 1.1.2
4571
 
4572
+ call-bound@1.0.4:
4573
+ dependencies:
4574
+ call-bind-apply-helpers: 1.0.2
4575
+ get-intrinsic: 1.3.0
4576
+
4577
  callsites@3.1.0: {}
4578
 
4579
  ccount@2.0.1: {}
 
4600
 
4601
  character-entities-legacy@3.0.0: {}
4602
 
4603
+ chardet@2.1.0: {}
4604
 
4605
  check-error@2.1.1: {}
4606
 
 
4664
 
4665
  confbox@0.2.1: {}
4666
 
4667
+ confbox@0.2.2: {}
4668
+
4669
+ consola@3.4.2: {}
4670
+
4671
+ content-disposition@1.0.0:
4672
+ dependencies:
4673
+ safe-buffer: 5.2.1
4674
+
4675
+ content-type@1.0.5: {}
4676
+
4677
+ cookie-signature@1.2.2: {}
4678
 
4679
  cookie@0.6.0: {}
4680
 
4681
+ cookie@0.7.2: {}
4682
+
4683
  core-util-is@1.0.3: {}
4684
 
4685
+ cors@2.8.5:
4686
+ dependencies:
4687
+ object-assign: 4.1.1
4688
+ vary: 1.1.2
4689
+
4690
  cross-spawn@7.0.6:
4691
  dependencies:
4692
  path-key: 3.1.1
 
4775
 
4776
  delayed-stream@1.0.0: {}
4777
 
4778
+ depd@2.0.0: {}
4779
+
4780
  dequal@2.0.3: {}
4781
 
4782
  detect-libc@1.0.3: {}
 
4785
 
4786
  detect-node@2.1.0: {}
4787
 
4788
+ devalue@5.3.2: {}
4789
 
4790
  devlop@1.1.0:
4791
  dependencies:
4792
  dequal: 2.0.3
4793
 
4794
+ diff-match-patch-es@1.0.1: {}
4795
 
4796
  diff-sequences@29.6.3: {}
4797
 
 
4809
  es-errors: 1.3.0
4810
  gopd: 1.2.0
4811
 
4812
+ ee-first@1.1.1: {}
4813
+
4814
  emoji-regex@8.0.0: {}
4815
 
4816
+ encodeurl@2.0.0: {}
4817
+
4818
  enhanced-resolve@5.18.1:
4819
  dependencies:
4820
  graceful-fs: 4.2.11
 
4867
  '@esbuild/win32-ia32': 0.21.5
4868
  '@esbuild/win32-x64': 0.21.5
4869
 
4870
+ escape-html@1.0.3: {}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4871
 
4872
  escape-string-regexp@1.0.5: {}
4873
 
 
4886
  optionalDependencies:
4887
  eslint-config-prettier: 10.1.1(eslint@9.22.0(jiti@2.4.2))
4888
 
4889
+ eslint-plugin-svelte@3.12.2(eslint@9.22.0(jiti@2.4.2))(svelte@5.38.7):
4890
  dependencies:
4891
  '@eslint-community/eslint-utils': 4.7.0(eslint@9.22.0(jiti@2.4.2))
4892
  '@jridgewell/sourcemap-codec': 1.5.0
 
4898
  postcss-load-config: 3.1.4(postcss@8.5.3)
4899
  postcss-safe-parser: 7.0.1(postcss@8.5.3)
4900
  semver: 7.7.2
4901
+ svelte-eslint-parser: 1.3.0(svelte@5.38.7)
4902
  optionalDependencies:
4903
+ svelte: 5.38.7
4904
  transitivePeerDependencies:
4905
  - ts-node
4906
 
 
4987
 
4988
  esutils@2.0.3: {}
4989
 
4990
+ etag@1.8.1: {}
4991
+
4992
  event-target-shim@5.0.1: {}
4993
 
4994
+ eventsource-parser@3.0.6: {}
4995
+
4996
+ eventsource@3.0.7:
4997
+ dependencies:
4998
+ eventsource-parser: 3.0.6
4999
+
5000
  expect-type@1.2.1: {}
5001
 
5002
+ express-rate-limit@7.5.1(express@5.1.0):
5003
+ dependencies:
5004
+ express: 5.1.0
5005
 
5006
+ express@5.1.0:
5007
  dependencies:
5008
+ accepts: 2.0.0
5009
+ body-parser: 2.2.0
5010
+ content-disposition: 1.0.0
5011
+ content-type: 1.0.5
5012
+ cookie: 0.7.2
5013
+ cookie-signature: 1.2.2
5014
+ debug: 4.4.0
5015
+ encodeurl: 2.0.0
5016
+ escape-html: 1.0.3
5017
+ etag: 1.8.1
5018
+ finalhandler: 2.1.0
5019
+ fresh: 2.0.0
5020
+ http-errors: 2.0.0
5021
+ merge-descriptors: 2.0.0
5022
+ mime-types: 3.0.1
5023
+ on-finished: 2.4.1
5024
+ once: 1.4.0
5025
+ parseurl: 1.3.3
5026
+ proxy-addr: 2.0.7
5027
+ qs: 6.14.0
5028
+ range-parser: 1.2.1
5029
+ router: 2.2.0
5030
+ send: 1.2.0
5031
+ serve-static: 2.2.0
5032
+ statuses: 2.0.2
5033
+ type-is: 2.0.1
5034
+ vary: 1.1.2
5035
+ transitivePeerDependencies:
5036
+ - supports-color
5037
+
5038
+ exsolve@1.0.4: {}
5039
+
5040
+ exsolve@1.0.7: {}
5041
 
5042
  fake-indexeddb@6.0.1: {}
5043
 
 
5081
  dependencies:
5082
  to-regex-range: 5.0.1
5083
 
5084
+ finalhandler@2.1.0:
5085
+ dependencies:
5086
+ debug: 4.4.0
5087
+ encodeurl: 2.0.0
5088
+ escape-html: 1.0.3
5089
+ on-finished: 2.4.1
5090
+ parseurl: 1.3.3
5091
+ statuses: 2.0.2
5092
+ transitivePeerDependencies:
5093
+ - supports-color
5094
+
5095
  find-cache-dir@5.0.0:
5096
  dependencies:
5097
  common-path-prefix: 3.0.0
 
5116
 
5117
  flatted@3.3.3: {}
5118
 
5119
+ focus-trap@7.6.5:
5120
+ dependencies:
5121
+ tabbable: 6.2.0
5122
+
5123
  form-data-encoder@1.7.2: {}
5124
 
5125
  form-data@4.0.2:
 
5134
  node-domexception: 1.0.0
5135
  web-streams-polyfill: 4.0.0-beta.3
5136
 
5137
+ forwarded@0.2.0: {}
5138
+
5139
+ fresh@2.0.0: {}
5140
+
5141
  fsevents@2.3.2:
5142
  optional: true
5143
 
 
5250
 
5251
  html-void-elements@3.0.0: {}
5252
 
5253
+ http-errors@2.0.0:
5254
+ dependencies:
5255
+ depd: 2.0.0
5256
+ inherits: 2.0.4
5257
+ setprototypeof: 1.2.0
5258
+ statuses: 2.0.1
5259
+ toidentifier: 1.0.1
5260
+
5261
  http-proxy-agent@7.0.2:
5262
  dependencies:
5263
  agent-base: 7.1.3
 
5276
  dependencies:
5277
  ms: 2.1.3
5278
 
5279
+ iconv-lite@0.6.3:
5280
  dependencies:
5281
  safer-buffer: 2.1.2
5282
 
5283
+ iconv-lite@0.7.0:
5284
  dependencies:
5285
  safer-buffer: 2.1.2
5286
 
 
5303
 
5304
  ini@4.1.3: {}
5305
 
5306
+ inquirer@8.2.7(@types/node@22.14.1):
5307
  dependencies:
5308
+ '@inquirer/external-editor': 1.0.1(@types/node@22.14.1)
5309
  ansi-escapes: 4.3.2
5310
  chalk: 4.1.2
5311
  cli-cursor: 3.1.0
5312
  cli-width: 3.0.0
 
5313
  figures: 3.2.0
5314
  lodash: 4.17.21
5315
  mute-stream: 0.0.8
 
5320
  strip-ansi: 6.0.1
5321
  through: 2.3.8
5322
  wrap-ansi: 6.2.0
5323
+ transitivePeerDependencies:
5324
+ - '@types/node'
5325
+
5326
+ ipaddr.js@1.9.1: {}
5327
 
5328
  is-arrayish@0.3.2: {}
5329
 
 
5347
 
5348
  is-potential-custom-element-name@1.0.1: {}
5349
 
5350
+ is-promise@4.0.0: {}
5351
+
5352
  is-reference@1.2.1:
5353
  dependencies:
5354
  '@types/estree': 1.0.6
 
5532
 
5533
  magic-string@0.30.17:
5534
  dependencies:
5535
+ '@jridgewell/sourcemap-codec': 1.5.5
5536
+
5537
+ magic-string@0.30.19:
5538
+ dependencies:
5539
+ '@jridgewell/sourcemap-codec': 1.5.5
5540
 
5541
  marked@16.1.2: {}
5542
 
 
5558
  unist-util-visit: 5.0.0
5559
  vfile: 6.0.3
5560
 
5561
+ media-typer@1.1.0: {}
5562
+
5563
+ melt@0.40.2(@floating-ui/dom@1.6.13)(svelte@5.38.7):
5564
  dependencies:
5565
  '@floating-ui/dom': 1.6.13
5566
  dequal: 2.0.3
5567
+ focus-trap: 7.6.5
5568
  jest-axe: 9.0.0
5569
+ runed: 0.23.4(svelte@5.38.7)
5570
+ svelte: 5.38.7
5571
+
5572
+ merge-descriptors@2.0.0: {}
5573
 
5574
  merge2@1.4.1: {}
5575
 
 
5597
 
5598
  mime-db@1.52.0: {}
5599
 
5600
+ mime-db@1.54.0: {}
5601
+
5602
  mime-types@2.1.35:
5603
  dependencies:
5604
  mime-db: 1.52.0
5605
 
5606
+ mime-types@3.0.1:
5607
+ dependencies:
5608
+ mime-db: 1.54.0
5609
+
5610
  mimic-fn@2.1.0: {}
5611
 
5612
  min-indent@1.0.1: {}
 
5646
 
5647
  nanoid@3.3.8: {}
5648
 
 
 
5649
  natural-compare@1.4.0: {}
5650
 
5651
+ negotiator@1.0.0: {}
5652
+
5653
  node-domexception@1.0.0: {}
5654
 
5655
  node-fetch@2.7.0:
 
5658
 
5659
  nwsapi@2.2.20: {}
5660
 
5661
+ object-assign@4.1.1: {}
5662
+
5663
+ object-inspect@1.13.4: {}
5664
+
5665
  object-keys@1.1.1: {}
5666
 
5667
+ on-finished@2.4.1:
5668
+ dependencies:
5669
+ ee-first: 1.1.1
5670
+
5671
+ once@1.4.0:
5672
+ dependencies:
5673
+ wrappy: 1.0.2
5674
+
5675
  onetime@5.1.2:
5676
  dependencies:
5677
  mimic-fn: 2.1.0
 
5703
  platform: 1.3.6
5704
  protobufjs: 7.4.0
5705
 
5706
+ openai@4.90.0(ws@8.18.2)(zod@3.25.76):
5707
  dependencies:
5708
  '@types/node': 18.19.84
5709
  '@types/node-fetch': 2.6.12
 
5714
  node-fetch: 2.7.0
5715
  optionalDependencies:
5716
  ws: 8.18.2
5717
+ zod: 3.25.76
5718
  transitivePeerDependencies:
5719
  - encoding
5720
 
 
5739
  strip-ansi: 6.0.1
5740
  wcwidth: 1.0.1
5741
 
 
 
5742
  p-limit@3.1.0:
5743
  dependencies:
5744
  yocto-queue: 0.1.0
5745
 
5746
  p-limit@4.0.0:
5747
  dependencies:
5748
+ yocto-queue: 1.2.1
5749
 
5750
  p-locate@5.0.0:
5751
  dependencies:
 
5767
  dependencies:
5768
  entities: 6.0.0
5769
 
5770
+ parseurl@1.3.3: {}
5771
+
5772
  path-exists@4.0.0: {}
5773
 
5774
  path-exists@5.0.0: {}
 
5777
 
5778
  path-parse@1.0.7: {}
5779
 
5780
+ path-to-regexp@8.3.0: {}
5781
 
5782
  pathe@2.0.3: {}
5783
 
 
5789
 
5790
  picomatch@4.0.2: {}
5791
 
5792
+ picomatch@4.0.3: {}
5793
+
5794
+ pkce-challenge@5.0.0: {}
5795
+
5796
  pkg-dir@7.0.0:
5797
  dependencies:
5798
  find-up: 6.3.0
 
5809
  exsolve: 1.0.4
5810
  pathe: 2.0.3
5811
 
5812
+ pkg-types@2.3.0:
5813
+ dependencies:
5814
+ confbox: 0.2.2
5815
+ exsolve: 1.0.7
5816
+ pathe: 2.0.3
5817
+
5818
  platform@1.3.6: {}
5819
 
5820
  playwright-core@1.52.0: {}
 
5862
  dependencies:
5863
  fast-diff: 1.3.0
5864
 
5865
+ prettier-plugin-svelte@3.4.0(prettier@3.5.3)(svelte@5.38.7):
5866
  dependencies:
5867
  prettier: 3.5.3
5868
+ svelte: 5.38.7
5869
 
5870
+ prettier-plugin-tailwindcss@0.6.11(prettier-plugin-svelte@3.4.0(prettier@3.5.3)(svelte@5.38.7))(prettier@3.5.3):
5871
  dependencies:
5872
  prettier: 3.5.3
5873
  optionalDependencies:
5874
+ prettier-plugin-svelte: 3.4.0(prettier@3.5.3)(svelte@5.38.7)
5875
 
5876
  prettier@3.5.3: {}
5877
 
 
5904
  '@types/node': 22.14.1
5905
  long: 5.3.1
5906
 
5907
+ proxy-addr@2.0.7:
5908
+ dependencies:
5909
+ forwarded: 0.2.0
5910
+ ipaddr.js: 1.9.1
5911
+
5912
  punycode@2.3.1: {}
5913
 
5914
+ qs@6.14.0:
5915
+ dependencies:
5916
+ side-channel: 1.1.0
5917
+
5918
  quansync@0.2.8: {}
5919
 
5920
  queue-microtask@1.2.3: {}
 
5924
  drange: 1.1.1
5925
  ret: 0.2.2
5926
 
5927
+ range-parser@1.2.1: {}
5928
+
5929
+ raw-body@3.0.1:
5930
+ dependencies:
5931
+ bytes: 3.1.2
5932
+ http-errors: 2.0.0
5933
+ iconv-lite: 0.7.0
5934
+ unpipe: 1.0.0
5935
+
5936
  react-is@17.0.2: {}
5937
 
5938
  react-is@18.3.1: {}
 
6022
  '@rollup/rollup-win32-x64-msvc': 4.34.9
6023
  fsevents: 2.3.3
6024
 
6025
+ router@2.2.0:
6026
+ dependencies:
6027
+ debug: 4.4.0
6028
+ depd: 2.0.0
6029
+ is-promise: 4.0.0
6030
+ parseurl: 1.3.3
6031
+ path-to-regexp: 8.3.0
6032
+ transitivePeerDependencies:
6033
+ - supports-color
6034
+
6035
  rrweb-cssom@0.8.0: {}
6036
 
6037
  run-async@2.4.1: {}
 
6040
  dependencies:
6041
  queue-microtask: 1.2.3
6042
 
6043
+ runed@0.23.4(svelte@5.38.7):
6044
  dependencies:
6045
  esm-env: 1.2.2
6046
+ svelte: 5.38.7
6047
 
6048
+ runed@0.25.0(svelte@5.38.7):
6049
  dependencies:
6050
  esm-env: 1.2.2
6051
+ svelte: 5.38.7
6052
 
6053
  rxjs@7.8.2:
6054
  dependencies:
 
6072
 
6073
  semver@7.7.2: {}
6074
 
6075
+ send@1.2.0:
6076
+ dependencies:
6077
+ debug: 4.4.0
6078
+ encodeurl: 2.0.0
6079
+ escape-html: 1.0.3
6080
+ etag: 1.8.1
6081
+ fresh: 2.0.0
6082
+ http-errors: 2.0.0
6083
+ mime-types: 3.0.1
6084
+ ms: 2.1.3
6085
+ on-finished: 2.4.1
6086
+ range-parser: 1.2.1
6087
+ statuses: 2.0.2
6088
+ transitivePeerDependencies:
6089
+ - supports-color
6090
+
6091
  serialize-error@7.0.1:
6092
  dependencies:
6093
  type-fest: 0.13.1
6094
 
6095
+ serve-static@2.2.0:
6096
+ dependencies:
6097
+ encodeurl: 2.0.0
6098
+ escape-html: 1.0.3
6099
+ parseurl: 1.3.3
6100
+ send: 1.2.0
6101
+ transitivePeerDependencies:
6102
+ - supports-color
6103
+
6104
  set-cookie-parser@2.7.1: {}
6105
 
6106
+ setprototypeof@1.2.0: {}
6107
+
6108
  sharp@0.34.2:
6109
  dependencies:
6110
  color: 4.2.3
 
6150
  '@shikijs/vscode-textmate': 10.0.2
6151
  '@types/hast': 3.0.4
6152
 
6153
+ side-channel-list@1.0.0:
6154
+ dependencies:
6155
+ es-errors: 1.3.0
6156
+ object-inspect: 1.13.4
6157
+
6158
+ side-channel-map@1.0.1:
6159
+ dependencies:
6160
+ call-bound: 1.0.4
6161
+ es-errors: 1.3.0
6162
+ get-intrinsic: 1.3.0
6163
+ object-inspect: 1.13.4
6164
+
6165
+ side-channel-weakmap@1.0.2:
6166
+ dependencies:
6167
+ call-bound: 1.0.4
6168
+ es-errors: 1.3.0
6169
+ get-intrinsic: 1.3.0
6170
+ object-inspect: 1.13.4
6171
+ side-channel-map: 1.0.1
6172
+
6173
+ side-channel@1.1.0:
6174
+ dependencies:
6175
+ es-errors: 1.3.0
6176
+ object-inspect: 1.13.4
6177
+ side-channel-list: 1.0.0
6178
+ side-channel-map: 1.0.1
6179
+ side-channel-weakmap: 1.0.2
6180
+
6181
  siginfo@2.0.0: {}
6182
 
6183
  signal-exit@3.0.7: {}
 
6200
 
6201
  stackback@0.0.2: {}
6202
 
6203
+ statuses@2.0.1: {}
6204
+
6205
+ statuses@2.0.2: {}
6206
+
6207
  std-env@3.9.0: {}
6208
 
6209
  string-width@4.2.3:
 
6237
 
6238
  supports-preserve-symlinks-flag@1.0.0: {}
6239
 
6240
+ svelte-check@4.3.1(picomatch@4.0.2)(svelte@5.38.7)(typescript@5.8.2):
6241
  dependencies:
6242
  '@jridgewell/trace-mapping': 0.3.25
6243
  chokidar: 4.0.3
6244
  fdir: 6.4.3(picomatch@4.0.2)
6245
  picocolors: 1.1.1
6246
  sade: 1.8.1
6247
+ svelte: 5.38.7
6248
  typescript: 5.8.2
6249
  transitivePeerDependencies:
6250
  - picomatch
6251
 
6252
+ svelte-eslint-parser@1.3.0(svelte@5.38.7):
6253
  dependencies:
6254
  eslint-scope: 8.3.0
6255
  eslint-visitor-keys: 4.2.0
 
6258
  postcss-scss: 4.0.9(postcss@8.5.3)
6259
  postcss-selector-parser: 7.1.0
6260
  optionalDependencies:
6261
+ svelte: 5.38.7
6262
 
6263
+ svelte@5.38.7:
6264
  dependencies:
6265
+ '@jridgewell/remapping': 2.3.5
6266
  '@jridgewell/sourcemap-codec': 1.5.0
6267
  '@sveltejs/acorn-typescript': 1.0.5(acorn@8.14.0)
6268
  '@types/estree': 1.0.6
 
6284
  '@pkgr/core': 0.1.1
6285
  tslib: 2.8.1
6286
 
6287
+ tabbable@6.2.0: {}
6288
+
6289
  tailwind-merge@3.0.2: {}
6290
 
6291
+ tailwindcss-spring@1.0.1(tailwindcss@4.0.9):
6292
+ dependencies:
6293
+ tailwindcss: 4.0.9
6294
+
6295
  tailwindcss@4.0.9: {}
6296
 
6297
  tapable@2.2.1: {}
 
6328
  dependencies:
6329
  tldts-core: 6.1.86
6330
 
 
 
 
 
6331
  to-regex-range@5.0.1:
6332
  dependencies:
6333
  is-number: 7.0.0
6334
 
6335
+ toidentifier@1.0.1: {}
6336
+
6337
  totalist@3.0.1: {}
6338
 
6339
  tough-cookie@5.1.2:
 
6371
 
6372
  type-fest@0.21.3: {}
6373
 
6374
+ type-fest@4.41.0: {}
6375
+
6376
+ type-is@2.0.1:
6377
+ dependencies:
6378
+ content-type: 1.0.5
6379
+ media-typer: 1.1.0
6380
+ mime-types: 3.0.1
6381
 
6382
  typescript-eslint@8.26.1(eslint@9.22.0(jiti@2.4.2))(typescript@5.8.2):
6383
  dependencies:
 
6389
  transitivePeerDependencies:
6390
  - supports-color
6391
 
 
 
6392
  typescript@5.8.2: {}
6393
 
6394
+ typia@9.7.2(@types/node@22.14.1)(typescript@5.8.2):
6395
  dependencies:
6396
+ '@samchon/openapi': 4.7.1
6397
+ '@standard-schema/spec': 1.0.0
6398
  commander: 10.0.1
6399
  comment-json: 4.2.5
6400
+ inquirer: 8.2.7(@types/node@22.14.1)
 
 
 
 
 
 
 
 
 
 
6401
  package-manager-detector: 0.2.11
6402
  randexp: 0.5.3
6403
  typescript: 5.8.2
6404
+ transitivePeerDependencies:
6405
+ - '@types/node'
6406
 
6407
  ufo@1.5.4: {}
6408
 
 
6433
  unist-util-is: 6.0.0
6434
  unist-util-visit-parents: 6.0.1
6435
 
6436
+ unpipe@1.0.0: {}
6437
+
6438
+ unplugin-icons@22.1.0(svelte@5.38.7):
6439
  dependencies:
6440
  '@antfu/install-pkg': 1.0.0
6441
  '@iconify/utils': 2.3.0
 
6443
  local-pkg: 1.1.1
6444
  unplugin: 2.2.0
6445
  optionalDependencies:
6446
+ svelte: 5.38.7
6447
  transitivePeerDependencies:
6448
  - supports-color
6449
 
6450
+ unplugin@2.2.0:
6451
  dependencies:
6452
  acorn: 8.14.0
6453
  webpack-virtual-modules: 0.6.2
6454
 
6455
+ unplugin@2.3.10:
6456
  dependencies:
6457
+ '@jridgewell/remapping': 2.3.5
6458
+ acorn: 8.15.0
6459
+ picomatch: 4.0.3
6460
  webpack-virtual-modules: 0.6.2
6461
 
6462
  uri-js@4.4.1:
 
6467
 
6468
  uuid@8.3.2: {}
6469
 
6470
+ vary@1.1.2: {}
6471
+
6472
  vfile-message@4.0.2:
6473
  dependencies:
6474
  '@types/unist': 3.0.3
 
6507
  fsevents: 2.3.3
6508
  lightningcss: 1.29.1
6509
 
 
 
 
 
 
 
 
 
 
 
 
 
6510
  vitefu@1.0.6(vite@5.4.14(@types/node@22.14.1)(lightningcss@1.29.1)):
6511
  optionalDependencies:
6512
  vite: 5.4.14(@types/node@22.14.1)(lightningcss@1.29.1)
6513
 
6514
+ vitest-browser-svelte@0.1.0(@vitest/browser@3.1.4)(svelte@5.38.7)(vitest@3.1.4):
6515
  dependencies:
6516
  '@vitest/browser': 3.1.4(playwright@1.52.0)(vite@5.4.14(@types/node@22.14.1)(lightningcss@1.29.1))(vitest@3.1.4)
6517
+ svelte: 5.38.7
6518
  vitest: 3.1.4(@types/node@22.14.1)(@vitest/browser@3.1.4)(jsdom@26.1.0)(lightningcss@1.29.1)
6519
 
6520
  vitest@3.1.4(@types/node@22.14.1)(@vitest/browser@3.1.4)(jsdom@26.1.0)(lightningcss@1.29.1):
 
6608
  string-width: 4.2.3
6609
  strip-ansi: 6.0.1
6610
 
6611
+ wrappy@1.0.2: {}
6612
+
6613
  ws@8.18.2: {}
6614
 
6615
  xml-name-validator@5.0.0: {}
 
6620
 
6621
  yaml@1.10.2: {}
6622
 
 
 
 
6623
  yocto-queue@0.1.0: {}
6624
 
6625
+ yocto-queue@1.2.1: {}
6626
 
6627
  zimmerframe@1.1.2: {}
6628
 
6629
+ zod-to-json-schema@3.24.6(zod@3.25.76):
6630
+ dependencies:
6631
+ zod: 3.25.76
6632
+
6633
+ zod@3.25.76: {}
6634
+
6635
  zwitch@2.0.4: {}
src/app.css CHANGED
@@ -2,6 +2,7 @@
2
  @import "tailwindcss";
3
 
4
  @plugin '@tailwindcss/container-queries';
 
5
  @plugin '@tailwindcss/typography';
6
 
7
  @custom-variant dark (&:where(.dark, .dark *));
 
2
  @import "tailwindcss";
3
 
4
  @plugin '@tailwindcss/container-queries';
5
+ @plugin 'tailwindcss-spring';
6
  @plugin '@tailwindcss/typography';
7
 
8
  @custom-variant dark (&:where(.dark, .dark *));
src/lib/builders/local-toasts.svelte.ts CHANGED
@@ -72,8 +72,8 @@ export class LocalToasts {
72
  }).then(({ x, y, placement: _placement }) => {
73
  placement = _placement;
74
  Object.assign(node.style, {
75
- left: placement === "top" ? `${x}px` : `${x - 4}px`,
76
- top: placement === "top" ? `${y - 6}px` : `${y}px`,
77
  });
78
 
79
  // Animate
@@ -82,19 +82,16 @@ export class LocalToasts {
82
 
83
  // Determine animation direction based on placement
84
  let keyframes: Keyframe[] = [];
85
- switch (placement) {
86
- case "top":
87
- keyframes = [
88
- { opacity: 0, transform: "translateY(8px)", scale: "0.8" },
89
- { opacity: 1, transform: "translateY(0)", scale: "1" },
90
- ];
91
- break;
92
- case "left":
93
- keyframes = [
94
- { opacity: 0, transform: "translateX(8px)", scale: "0.8" },
95
- { opacity: 1, transform: "translateX(0)", scale: "1" },
96
- ];
97
- break;
98
  }
99
 
100
  node.animate(keyframes, {
@@ -123,21 +120,17 @@ export class LocalToasts {
123
 
124
  // Determine animation direction based on placement
125
  let keyframes: Keyframe[] = [];
126
- switch (placement) {
127
- case "top":
128
- keyframes = [
129
- { opacity: 1, transform: "translateY(0)" },
130
- { opacity: 0, transform: "translateY(-8px)" },
131
- ];
132
- break;
133
- case "left":
134
- keyframes = [
135
- { opacity: 1, transform: "translateX(0)" },
136
- { opacity: 0, transform: "translateX(-8px)" },
137
- ];
138
- break;
139
  }
140
-
141
  await cloned.animate(keyframes, {
142
  duration: 400,
143
  easing: "cubic-bezier(0.22, 1, 0.36, 1)",
 
72
  }).then(({ x, y, placement: _placement }) => {
73
  placement = _placement;
74
  Object.assign(node.style, {
75
+ left: placement.startsWith("top") ? `${x}px` : `${x - 4}px`,
76
+ top: placement.startsWith("top") ? `${y - 6}px` : `${y}px`,
77
  });
78
 
79
  // Animate
 
82
 
83
  // Determine animation direction based on placement
84
  let keyframes: Keyframe[] = [];
85
+ if (placement.startsWith("top")) {
86
+ keyframes = [
87
+ { opacity: 0, transform: "translateX(var(--tx, 0)) translateY(8px)", scale: "0.8" },
88
+ { opacity: 1, transform: "translateX(var(--tx, 0)) translateY(0)", scale: "1" },
89
+ ];
90
+ } else if (placement.startsWith("left")) {
91
+ keyframes = [
92
+ { opacity: 0, transform: "translateX(8px)", scale: "0.8" },
93
+ { opacity: 1, transform: "translateX(0)", scale: "1" },
94
+ ];
 
 
 
95
  }
96
 
97
  node.animate(keyframes, {
 
120
 
121
  // Determine animation direction based on placement
122
  let keyframes: Keyframe[] = [];
123
+ if (placement.startsWith("top")) {
124
+ keyframes = [
125
+ { opacity: 1, transform: "translateX(var(--tx, 0)) translateY(0)" },
126
+ { opacity: 0, transform: "translateX(var(--tx, 0)) translateY(-8px)" },
127
+ ];
128
+ } else if (placement.startsWith("left")) {
129
+ keyframes = [
130
+ { opacity: 1, transform: "translateX(0)" },
131
+ { opacity: 0, transform: "translateX(-8px)" },
132
+ ];
 
 
 
133
  }
 
134
  await cloned.animate(keyframes, {
135
  duration: 400,
136
  easing: "cubic-bezier(0.22, 1, 0.36, 1)",
src/lib/components/avatar.svelte CHANGED
@@ -1,4 +1,5 @@
1
  <script lang="ts">
 
2
  import { isCustomModel, type CustomModel, type Model } from "$lib/types.js";
3
  import IconCube from "~icons/carbon/cube";
4
 
@@ -8,24 +9,17 @@
8
  size?: "sm" | "md";
9
  }
10
 
11
- let { model, orgName = undefined, size = "md" }: Props = $props();
12
 
13
  let sizeClass = $derived(size === "sm" ? "size-3" : "size-4");
14
  let isCustom = $derived(isCustomModel(model));
15
- let _orgName = $derived(orgName ?? (!isCustom ? model.id.split("/")[0] : undefined));
 
16
 
17
- async function getAvatarUrl(orgName?: string) {
18
- if (!orgName) return;
19
- const url = `https://huggingface.co/api/organizations/${orgName}/avatar`;
20
- const res = await fetch(url);
21
- if (!res.ok) {
22
- console.error(`Error getting avatar url for org: ${orgName}`, res.status, res.statusText);
23
- return;
24
- }
25
- const json = await res.json();
26
- const { avatarUrl } = json;
27
- return avatarUrl;
28
- }
29
  </script>
30
 
31
  {#if isCustom}
@@ -34,16 +28,8 @@
34
  >
35
  <IconCube class="size-full p-0.5" />
36
  </div>
 
 
37
  {:else}
38
- {#await getAvatarUrl(_orgName)}
39
- <div class="{sizeClass} flex-none rounded-sm bg-gray-200"></div>
40
- {:then avatarUrl}
41
- {#if avatarUrl}
42
- <img class="{sizeClass} flex-none rounded-sm bg-gray-200 object-cover" src={avatarUrl} alt="{_orgName} avatar" />
43
- {:else}
44
- <div class="{sizeClass} flex-none rounded-sm bg-gray-200"></div>
45
- {/if}
46
- {:catch}
47
- <div class="{sizeClass} flex-none rounded-sm bg-gray-200"></div>
48
- {/await}
49
  {/if}
 
1
  <script lang="ts">
2
+ import { getAvatarUrl } from "$lib/remote/avatar.remote";
3
  import { isCustomModel, type CustomModel, type Model } from "$lib/types.js";
4
  import IconCube from "~icons/carbon/cube";
5
 
 
9
  size?: "sm" | "md";
10
  }
11
 
12
+ let { model, orgName: _orgName = undefined, size = "md" }: Props = $props();
13
 
14
  let sizeClass = $derived(size === "sm" ? "size-3" : "size-4");
15
  let isCustom = $derived(isCustomModel(model));
16
+ let orgName = $derived(_orgName ?? (!isCustom ? model.id.split("/")[0] : undefined));
17
+ let avatarUrl = $state<string>();
18
 
19
+ $effect.pre(() => {
20
+ avatarUrl = undefined;
21
+ getAvatarUrl(orgName).then(url => (avatarUrl = url));
22
+ });
 
 
 
 
 
 
 
 
23
  </script>
24
 
25
  {#if isCustom}
 
28
  >
29
  <IconCube class="size-full p-0.5" />
30
  </div>
31
+ {:else if avatarUrl}
32
+ <img class="{sizeClass} flex-none rounded-sm bg-gray-200 object-cover" src={avatarUrl} alt="{orgName} avatar" />
33
  {:else}
34
+ <div class="{sizeClass} flex-none rounded-sm bg-gray-200"></div>
 
 
 
 
 
 
 
 
 
 
35
  {/if}
src/lib/components/inference-playground/code-snippets.svelte CHANGED
@@ -1,6 +1,5 @@
1
  <script lang="ts">
2
  import { type ConversationClass } from "$lib/state/conversations.svelte";
3
- import { structuredForbiddenProviders } from "$lib/state/models.svelte";
4
  import { token } from "$lib/state/token.svelte.js";
5
  import { billing } from "$lib/state/billing.svelte";
6
  import { isCustomModel } from "$lib/types.js";
@@ -58,8 +57,7 @@
58
  billTo: billing.organization || undefined,
59
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
60
  } as any;
61
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
62
- if (data.structuredOutput && !structuredForbiddenProviders.includes(conversation.data.provider as any)) {
63
  opts.structured_output = data.structuredOutput;
64
  }
65
 
@@ -208,6 +206,7 @@
208
  <a
209
  href={installInstructions.docs}
210
  target="_blank"
 
211
  class="relative -bottom-[1px] flex items-center gap-1 text-sm font-normal text-gray-500 hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-300"
212
  >
213
  <IconExternal class="text-xs" />
 
1
  <script lang="ts">
2
  import { type ConversationClass } from "$lib/state/conversations.svelte";
 
3
  import { token } from "$lib/state/token.svelte.js";
4
  import { billing } from "$lib/state/billing.svelte";
5
  import { isCustomModel } from "$lib/types.js";
 
57
  billTo: billing.organization || undefined,
58
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
59
  } as any;
60
+ if (data.structuredOutput && conversation.isStructuredOutputAllowed) {
 
61
  opts.structured_output = data.structuredOutput;
62
  }
63
 
 
206
  <a
207
  href={installInstructions.docs}
208
  target="_blank"
209
+ rel="external"
210
  class="relative -bottom-[1px] flex items-center gap-1 text-sm font-normal text-gray-500 hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-300"
211
  >
212
  <IconExternal class="text-xs" />
src/lib/components/inference-playground/generation-config.svelte CHANGED
@@ -1,15 +1,16 @@
1
  <script lang="ts">
2
  import type { ConversationClass } from "$lib/state/conversations.svelte.js";
3
- import { structuredForbiddenProviders } from "$lib/state/models.svelte.js";
4
  import { maxAllowedTokens } from "$lib/utils/business.svelte.js";
 
5
  import { isNumber } from "$lib/utils/is.js";
6
  import { watch } from "runed";
7
  import IconX from "~icons/carbon/close";
 
8
  import { GENERATION_CONFIG_KEYS, GENERATION_CONFIG_SETTINGS } from "./generation-config-settings.js";
 
9
  import StructuredOutputModal, { openStructuredOutputModal } from "./structured-output-modal.svelte";
10
- import ExtraParamsModal, { openExtraParamsModal } from "./extra-params-modal.svelte";
11
- import { cn } from "$lib/utils/cn.js";
12
-
13
  interface Props {
14
  conversation: ConversationClass;
15
  classNames?: string;
@@ -44,6 +45,7 @@
44
  });
45
  }
46
 
 
47
  const extraParamsLen = $derived(Object.keys(conversation.data.extraParams ?? {}).length);
48
  </script>
49
 
@@ -103,7 +105,7 @@
103
  </label>
104
 
105
  <!-- eslint-disable-next-line @typescript-eslint/no-explicit-any -->
106
- {#if !structuredForbiddenProviders.includes(conversation.data.provider as any)}
107
  <label class="mt-2 flex cursor-pointer items-center justify-between" for="structured-output">
108
  <span class="text-sm font-medium text-gray-900 dark:text-gray-300">Structured Output</span>
109
  <div class="flex items-center gap-2">
@@ -125,6 +127,21 @@
125
  </label>
126
  {/if}
127
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
128
  <div class="mt-2 flex items-center gap-2">
129
  <span class="text-sm font-medium text-gray-900 dark:text-gray-300">Extra parameters</span>
130
  <span
@@ -153,3 +170,6 @@
153
 
154
  <StructuredOutputModal {conversation} />
155
  <ExtraParamsModal {conversation} />
 
 
 
 
1
  <script lang="ts">
2
  import type { ConversationClass } from "$lib/state/conversations.svelte.js";
 
3
  import { maxAllowedTokens } from "$lib/utils/business.svelte.js";
4
+ import { cn } from "$lib/utils/cn.js";
5
  import { isNumber } from "$lib/utils/is.js";
6
  import { watch } from "runed";
7
  import IconX from "~icons/carbon/close";
8
+ import ExtraParamsModal, { openExtraParamsModal } from "./extra-params-modal.svelte";
9
  import { GENERATION_CONFIG_KEYS, GENERATION_CONFIG_SETTINGS } from "./generation-config-settings.js";
10
+ import MCPModal from "./mcp-modal.svelte";
11
  import StructuredOutputModal, { openStructuredOutputModal } from "./structured-output-modal.svelte";
12
+ import { mcpServers } from "$lib/state/mcps.svelte.js";
13
+ import { isMcpEnabled } from "$lib/constants.js";
 
14
  interface Props {
15
  conversation: ConversationClass;
16
  classNames?: string;
 
45
  });
46
  }
47
 
48
+ let editingMCP = $state(false);
49
  const extraParamsLen = $derived(Object.keys(conversation.data.extraParams ?? {}).length);
50
  </script>
51
 
 
105
  </label>
106
 
107
  <!-- eslint-disable-next-line @typescript-eslint/no-explicit-any -->
108
+ {#if conversation.isStructuredOutputAllowed}
109
  <label class="mt-2 flex cursor-pointer items-center justify-between" for="structured-output">
110
  <span class="text-sm font-medium text-gray-900 dark:text-gray-300">Structured Output</span>
111
  <div class="flex items-center gap-2">
 
127
  </label>
128
  {/if}
129
 
130
+ <!-- MCP Servers -->
131
+ {#if isMcpEnabled()}
132
+ <div class="mt-2 flex cursor-pointer items-center justify-between">
133
+ <span class="text-sm font-medium text-gray-900 dark:text-gray-300">MCP Servers</span>
134
+ <div class="flex items-center gap-2">
135
+ {#if mcpServers.enabled.length > 0}
136
+ <span class="rounded-full bg-blue-100 px-2 py-1 text-xs text-blue-800 dark:bg-blue-900 dark:text-blue-200">
137
+ {mcpServers.enabled.length} enabled
138
+ </span>
139
+ {/if}
140
+ <button class="btn-mini" type="button" onclick={() => (editingMCP = true)}> configure </button>
141
+ </div>
142
+ </div>
143
+ {/if}
144
+
145
  <div class="mt-2 flex items-center gap-2">
146
  <span class="text-sm font-medium text-gray-900 dark:text-gray-300">Extra parameters</span>
147
  <span
 
170
 
171
  <StructuredOutputModal {conversation} />
172
  <ExtraParamsModal {conversation} />
173
+ {#if isMcpEnabled()}
174
+ <MCPModal bind:open={editingMCP} />
175
+ {/if}
src/lib/components/inference-playground/mcp-card.svelte ADDED
@@ -0,0 +1,110 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <script lang="ts">
2
+ import { mcpServers, type MCPServerEntity, type MCPFormData } from "$lib/state/mcps.svelte.js";
3
+ import { projects } from "$lib/state/projects.svelte.js";
4
+ import { extractDomain } from "$lib/utils/url.js";
5
+ import IconEdit from "~icons/carbon/edit";
6
+ import IconDelete from "~icons/carbon/trash-can";
7
+ import Switch from "../switch.svelte";
8
+ import McpForm from "./mcp-form.svelte";
9
+
10
+ interface Props {
11
+ server: MCPServerEntity;
12
+ }
13
+
14
+ let { server }: Props = $props();
15
+
16
+ let editing = $state(false);
17
+
18
+ async function deleteServer() {
19
+ await mcpServers.delete(server.id);
20
+
21
+ // Remove from project's enabled MCPs if it was enabled
22
+ const currentProject = projects.current;
23
+ if (!currentProject?.enabledMCPs?.includes(server.id)) return;
24
+ await projects.update({
25
+ ...currentProject,
26
+ enabledMCPs: currentProject.enabledMCPs.filter(mcpId => mcpId !== server.id),
27
+ });
28
+ }
29
+
30
+ async function setEnabled(enabled: boolean) {
31
+ const currentProject = projects.current;
32
+ if (!currentProject) return;
33
+
34
+ const enabledMCPs = currentProject.enabledMCPs || [];
35
+ const newEnabledMCPs = enabled ? [...enabledMCPs, server.id] : enabledMCPs.filter(id => id !== server.id);
36
+
37
+ await projects.update({
38
+ ...currentProject,
39
+ enabledMCPs: newEnabledMCPs,
40
+ });
41
+ }
42
+
43
+ const isEnabled = $derived(projects.current?.enabledMCPs?.includes(server.id) || false);
44
+
45
+ async function saveServer(formData: MCPFormData) {
46
+ await mcpServers.update({
47
+ ...server,
48
+ ...formData,
49
+ });
50
+ editing = false;
51
+ }
52
+
53
+ function getFaviconUrl(url: string): string {
54
+ const domain = extractDomain(url);
55
+ return `https://www.google.com/s2/favicons?domain=https://${domain}&sz=64`;
56
+ }
57
+
58
+ function urlWithoutSubpaths(url: string): string {
59
+ const urlObj = new URL(url);
60
+ return urlObj.origin;
61
+ }
62
+ </script>
63
+
64
+ <div class="rounded-lg border border-gray-200 p-3 dark:border-gray-700">
65
+ <div class="flex justify-between">
66
+ <div>
67
+ <div class="flex items-center gap-1">
68
+ <img src={getFaviconUrl(server.url)} alt="Server Icon" class="size-4 rounded p-0.5 dark:bg-gray-500" />
69
+ <span class="font-bold">{server.name}</span>
70
+ </div>
71
+ <p class="mt-1 truncate text-sm dark:text-neutral-300">
72
+ <span class="rounded bg-blue-900 px-0.75 py-0.25 uppercase">
73
+ {server.protocol}
74
+ </span>
75
+ <span>
76
+ {urlWithoutSubpaths(server.url)}
77
+ </span>
78
+ </p>
79
+ {#if server.headers && Object.keys(server.headers).length > 0}
80
+ <p class="mt-1 text-xs dark:text-neutral-400">
81
+ Headers: {Object.keys(server.headers).length} configured
82
+ </p>
83
+ {/if}
84
+ </div>
85
+ <div class="flex flex-col items-end justify-between gap-2">
86
+ <Switch bind:value={() => isEnabled, v => setEnabled(v)} />
87
+ <div class="flex items-center gap-2">
88
+ {#if !editing}
89
+ <button class="btn-mini" onclick={() => (editing = true)}>
90
+ <IconEdit class="h-4 w-4" />
91
+ <span>Edit</span>
92
+ </button>
93
+ <button
94
+ class="btn-mini text-red-600 hover:bg-red-50 dark:text-red-400 dark:hover:bg-red-900/20"
95
+ onclick={() => deleteServer()}
96
+ >
97
+ <IconDelete class="h-4 w-4" />
98
+ <span>Delete</span>
99
+ </button>
100
+ {/if}
101
+ </div>
102
+ </div>
103
+ </div>
104
+
105
+ {#if editing}
106
+ <div class="mt-2 border-t border-neutral-500 pt-2 dark:border-neutral-700">
107
+ <McpForm {server} onSubmit={saveServer} onCancel={() => (editing = false)} />
108
+ </div>
109
+ {/if}
110
+ </div>
src/lib/components/inference-playground/mcp-form.svelte ADDED
@@ -0,0 +1,160 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <script lang="ts">
2
+ import { type MCPProtocol, type MCPServerEntity, type MCPFormData } from "$lib/state/mcps.svelte.js";
3
+ import { createFieldValidation } from "$lib/utils/form.svelte";
4
+ import { entries } from "$lib/utils/object.svelte";
5
+ import { isValidURL } from "$lib/utils/url.js";
6
+ import IconAdd from "~icons/carbon/add";
7
+ import IconCheck from "~icons/carbon/checkmark";
8
+ import IconDelete from "~icons/carbon/trash-can";
9
+
10
+ interface Props {
11
+ server?: MCPServerEntity;
12
+ onSubmit: (formData: MCPFormData) => Promise<void>;
13
+ onCancel: () => void;
14
+ submitLabel?: string;
15
+ }
16
+
17
+ let { server, onSubmit, onCancel, submitLabel = "Save" }: Props = $props();
18
+
19
+ let formState = $state({
20
+ name: server?.name || "",
21
+ url: server?.url || "",
22
+ protocol: (server?.protocol || "sse") as MCPProtocol,
23
+ headers: entries(server?.headers || {}),
24
+ });
25
+
26
+ const protocolOptions: MCPProtocol[] = ["sse", "http"];
27
+
28
+ const nameField = createFieldValidation({
29
+ validate: v => {
30
+ if (!v) return "Server name is required";
31
+ if (v.trim().length === 0) return "Server name cannot be empty";
32
+ },
33
+ });
34
+
35
+ const urlField = createFieldValidation({
36
+ validate: v => {
37
+ if (!v) return "Server URL is required";
38
+ if (v.trim().length === 0) return "Server URL cannot be empty";
39
+ if (!isValidURL(v)) return "Invalid URL";
40
+ },
41
+ });
42
+
43
+ const disabled = $derived(!nameField.valid || !urlField.valid);
44
+
45
+ async function handleSubmit(e: SubmitEvent) {
46
+ e.preventDefault();
47
+ if (!nameField.valid || !urlField.valid) return;
48
+
49
+ await onSubmit({
50
+ ...formState,
51
+ headers: formState.headers.reduce((acc, [key, value]) => ({ ...acc, [key]: value }), {}),
52
+ });
53
+ }
54
+ </script>
55
+
56
+ <form class="space-y-3" onsubmit={handleSubmit}>
57
+ <label class="flex flex-col gap-2">
58
+ <p class="block text-sm font-medium text-gray-900 dark:text-white">
59
+ Server Name <span class="text-red-800 dark:text-red-300">*</span>
60
+ </p>
61
+ <input
62
+ type="text"
63
+ bind:value={formState.name}
64
+ class="input block w-full"
65
+ placeholder="My MCP Server"
66
+ {...nameField.attrs}
67
+ required
68
+ />
69
+ <p class="text-xs text-red-300">{nameField.msg}</p>
70
+ </label>
71
+
72
+ <label class="flex flex-col gap-2">
73
+ <p class="block text-sm font-medium text-gray-900 dark:text-white">
74
+ Server URL <span class="text-red-800 dark:text-red-300">*</span>
75
+ </p>
76
+ <input
77
+ type="url"
78
+ bind:value={formState.url}
79
+ class="input block w-full"
80
+ placeholder="https://mcp.example.com/sse"
81
+ {...urlField.attrs}
82
+ required
83
+ />
84
+ <p class="text-xs text-red-300">{urlField.msg}</p>
85
+ </label>
86
+
87
+ <div class="flex flex-col gap-2">
88
+ <p class="block text-sm font-medium text-gray-900 dark:text-white">Protocol</p>
89
+ <div class="flex rounded-lg bg-gray-100 p-1 dark:bg-gray-700" role="radiogroup" aria-label="Server Protocol">
90
+ {#each protocolOptions as protocol}
91
+ <label class="relative flex-1 cursor-pointer">
92
+ <input
93
+ type="radio"
94
+ name="protocol-option"
95
+ value={protocol}
96
+ bind:group={formState.protocol}
97
+ class="peer sr-only"
98
+ />
99
+ <div
100
+ class="flex items-center justify-center rounded-md px-3 py-2 text-sm font-medium text-gray-600 transition-colors duration-200 ease-in-out peer-checked:bg-white peer-checked:text-gray-900 peer-checked:shadow dark:text-gray-300 dark:peer-checked:bg-gray-800 dark:peer-checked:text-white"
101
+ >
102
+ {protocol.toUpperCase()}
103
+ </div>
104
+ <span
105
+ aria-hidden="true"
106
+ class="absolute inset-0 z-0 rounded-md transition-all duration-200 ease-in-out peer-focus:ring-2 peer-focus:ring-blue-500 peer-focus:ring-offset-2 peer-focus:ring-offset-gray-100 dark:peer-focus:ring-offset-gray-700"
107
+ ></span>
108
+ </label>
109
+ {/each}
110
+ </div>
111
+ </div>
112
+
113
+ <div class="flex flex-col gap-2">
114
+ <p class="block text-sm font-medium text-gray-900 dark:text-white">Headers</p>
115
+ {#each formState.headers || [] as _, i (i)}
116
+ <div class="flex items-center gap-2">
117
+ <input
118
+ type="text"
119
+ bind:value={formState.headers[i]![0]}
120
+ class="flex-1 rounded-md border border-gray-300 bg-gray-50 px-3 py-2 text-sm dark:border-gray-600 dark:bg-gray-700 dark:text-gray-100"
121
+ placeholder="Header name"
122
+ />
123
+ <span class="text-gray-500">:</span>
124
+ <input
125
+ type="text"
126
+ bind:value={formState.headers[i]![1]}
127
+ class="flex-1 rounded-md border border-gray-300 bg-gray-50 px-3 py-2 text-sm dark:border-gray-600 dark:bg-gray-700 dark:text-gray-100"
128
+ placeholder="Header value"
129
+ />
130
+ <button
131
+ class="btn-sm !h-auto self-stretch text-red-600 hover:bg-red-50 dark:text-red-400 dark:hover:bg-red-900/20"
132
+ onclick={() => {
133
+ formState.headers.splice(i, 1);
134
+ }}
135
+ type="button"
136
+ >
137
+ <IconDelete class="h-4 w-4" />
138
+ </button>
139
+ </div>
140
+ {/each}
141
+ <button
142
+ class="btn-sm self-start"
143
+ type="button"
144
+ onclick={() => {
145
+ formState.headers.push(["", ""]);
146
+ formState = formState;
147
+ }}
148
+ >
149
+ <IconAdd class="size-4" />
150
+ Add Header
151
+ </button>
152
+ </div>
153
+
154
+ <div class="flex items-center gap-2">
155
+ <button class="btn-sm" {disabled}>
156
+ <IconCheck /><span>{submitLabel}</span>
157
+ </button>
158
+ <button class="btn-sm" type="button" onclick={onCancel}> Cancel </button>
159
+ </div>
160
+ </form>
src/lib/components/inference-playground/mcp-modal.svelte ADDED
@@ -0,0 +1,53 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <script lang="ts">
2
+ import { mcpServers, type MCPFormData } from "$lib/state/mcps.svelte.js";
3
+ import IconPlus from "~icons/carbon/add";
4
+ import Dialog from "../dialog.svelte";
5
+ import McpCard from "./mcp-card.svelte";
6
+ import McpForm from "./mcp-form.svelte";
7
+
8
+ interface Props {
9
+ open: boolean;
10
+ }
11
+
12
+ let { open = $bindable(false) }: Props = $props();
13
+ let showAddForm = $state(false);
14
+
15
+ async function addServer(formData: MCPFormData) {
16
+ await mcpServers.create(formData);
17
+ showAddForm = false;
18
+ }
19
+ </script>
20
+
21
+ <Dialog
22
+ class="!w-2xl max-w-[90vw]"
23
+ title="MCP Servers"
24
+ {open}
25
+ onClose={() => {
26
+ open = false;
27
+ }}
28
+ >
29
+ <!-- Server List -->
30
+ <div class="space-y-4">
31
+ {#if mcpServers.all.length === 0}
32
+ <p class="text-sm text-gray-500">No MCP servers configured yet.</p>
33
+ {:else}
34
+ <div class="space-y-2">
35
+ {#each mcpServers.all as server (server.id)}
36
+ <McpCard {server} />
37
+ {/each}
38
+ </div>
39
+ {/if}
40
+ </div>
41
+
42
+ {#if showAddForm}
43
+ <div class="mt-4 border-t border-gray-200 pt-4 dark:border-gray-700">
44
+ <h3 class="mb-3 text-lg font-medium">Add New Server</h3>
45
+ <McpForm onSubmit={addServer} onCancel={() => (showAddForm = false)} submitLabel="Add Server" />
46
+ </div>
47
+ {:else}
48
+ <button class="btn-sm mt-2 flex w-full items-center gap-2" onclick={() => (showAddForm = true)}>
49
+ <IconPlus class="h-4 w-4" />
50
+ Add Server
51
+ </button>
52
+ {/if}
53
+ </Dialog>
src/lib/components/inference-playground/message-textarea.svelte CHANGED
@@ -1,5 +1,6 @@
1
  <script lang="ts">
2
  import { autofocus } from "$lib/attachments/autofocus.js";
 
3
  import { TextareaAutosize } from "$lib/spells/textarea-autosize.svelte.js";
4
  import { conversations } from "$lib/state/conversations.svelte";
5
  import { images } from "$lib/state/images.svelte";
@@ -19,6 +20,8 @@
19
 
20
  let input = $state("");
21
 
 
 
22
  async function onKeydown(event: KeyboardEvent) {
23
  if (loading) return;
24
  const ctrlOrMeta = event.ctrlKey || event.metaKey;
@@ -42,7 +45,27 @@
42
 
43
  async function sendMessage() {
44
  const c = conversations.active;
 
 
 
 
 
 
 
 
45
 
 
 
 
 
 
 
 
 
 
 
 
 
46
  let images: string[] | undefined;
47
  if (canUploadImgs) {
48
  images = await uploadImages();
@@ -128,6 +151,7 @@
128
  loading && "bg-red-900 hover:bg-red-800 dark:bg-red-600 dark:hover:bg-red-700",
129
  !loading && "bg-black hover:bg-gray-900 dark:bg-blue-600 dark:hover:bg-blue-700",
130
  ]}
 
131
  >
132
  {#if loading}
133
  <div class="flex flex-none items-center gap-[3px]">
@@ -182,4 +206,10 @@
182
  {/each}
183
  </div>
184
  </label>
 
 
 
 
 
 
185
  </div>
 
1
  <script lang="ts">
2
  import { autofocus } from "$lib/attachments/autofocus.js";
3
+ import { LocalToasts } from "$lib/builders/local-toasts.svelte.js";
4
  import { TextareaAutosize } from "$lib/spells/textarea-autosize.svelte.js";
5
  import { conversations } from "$lib/state/conversations.svelte";
6
  import { images } from "$lib/state/images.svelte";
 
20
 
21
  let input = $state("");
22
 
23
+ const localToasts = new LocalToasts({ placement: "top" });
24
+
25
  async function onKeydown(event: KeyboardEvent) {
26
  if (loading) return;
27
  const ctrlOrMeta = event.ctrlKey || event.metaKey;
 
45
 
46
  async function sendMessage() {
47
  const c = conversations.active;
48
+ const hasEmptyInput = input.trim() === "" && fileUpload.selected.size === 0;
49
+ const lastMessageIsUser = c.some(conv => conv.data.messages?.at(-1)?.role === "user");
50
+
51
+ // If input is empty and last message is user, just re-run the conversation
52
+ if (hasEmptyInput && lastMessageIsUser) {
53
+ conversations.genNextMessages();
54
+ return;
55
+ }
56
 
57
+ // If input is empty but last message is not user, show warning
58
+ if (hasEmptyInput) {
59
+ localToasts.addToast({
60
+ data: {
61
+ content: "Please enter a message",
62
+ variant: "danger",
63
+ },
64
+ });
65
+ return;
66
+ }
67
+
68
+ // Normal flow: add user message and generate response
69
  let images: string[] | undefined;
70
  if (canUploadImgs) {
71
  images = await uploadImages();
 
151
  loading && "bg-red-900 hover:bg-red-800 dark:bg-red-600 dark:hover:bg-red-700",
152
  !loading && "bg-black hover:bg-gray-900 dark:bg-blue-600 dark:hover:bg-blue-700",
153
  ]}
154
+ {...localToasts.trigger}
155
  >
156
  {#if loading}
157
  <div class="flex flex-none items-center gap-[3px]">
 
206
  {/each}
207
  </div>
208
  </label>
209
+
210
+ {#each localToasts.toasts as toast (toast.id)}
211
+ <div class={toast.class} {...toast.attrs} style="--tx: -10px; {toast.attrs.style}">
212
+ {toast.data.content}
213
+ </div>
214
+ {/each}
215
  </div>
src/lib/components/inference-playground/model-selector-modal.svelte CHANGED
@@ -2,6 +2,7 @@
2
  import { autofocus } from "$lib/attachments/autofocus.js";
3
  import type { ConversationClass } from "$lib/state/conversations.svelte";
4
  import { models } from "$lib/state/models.svelte.js";
 
5
  import type { CustomModel, Model } from "$lib/types.js";
6
  import { noop } from "$lib/utils/noop.js";
7
  import fuzzysearch from "$lib/utils/search.js";
@@ -26,6 +27,56 @@
26
 
27
  let { onModelSelect, onClose, conversation }: Props = $props();
28
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
29
  const combobox = new Combobox<string | undefined>({
30
  onOpenChange(o) {
31
  if (!o) onClose?.();
@@ -40,6 +91,35 @@
40
  onModelSelect?.(modelId);
41
  onClose?.();
42
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
43
  });
44
  $effect(() => {
45
  untrack(() => combobox.highlight(conversation.model.id));
@@ -48,25 +128,6 @@
48
  combobox.open = true;
49
  });
50
  });
51
-
52
- let backdropEl = $state<HTMLDivElement>();
53
- let query = $state("");
54
-
55
- const trending = $derived(fuzzysearch({ needle: query, haystack: models.trending, property: "id" }));
56
- const other = $derived(fuzzysearch({ needle: query, haystack: models.nonTrending, property: "id" }));
57
- const custom = $derived(fuzzysearch({ needle: query, haystack: models.custom, property: "id" }));
58
-
59
- function handleBackdropClick(event: MouseEvent) {
60
- event.stopPropagation();
61
- if (window?.getSelection()?.toString()) {
62
- return;
63
- }
64
- if (event.target === backdropEl) {
65
- onClose?.();
66
- }
67
- }
68
-
69
- const isCustom = typia.createIs<CustomModel>();
70
  </script>
71
 
72
  <!-- svelte-ignore a11y_no_static_element_interactions -->
@@ -91,6 +152,7 @@
91
  class="max-h-[220px] overflow-x-hidden overflow-y-auto md:max-h-[300px]"
92
  {...combobox.content}
93
  popover={undefined}
 
94
  >
95
  {#snippet modelEntry(model: Model | CustomModel, trending?: boolean)}
96
  {@const [nameSpace, modelName] = model.id.split("/")}
@@ -168,38 +230,34 @@
168
  {/if}
169
  </div>
170
  {/snippet}
171
- {#if trending.length > 0}
172
- <div class="px-2 py-1.5 text-xs font-medium text-gray-500">Trending</div>
173
- {#each trending as model}
174
- {@render modelEntry(model, true)}
175
- {/each}
176
- {/if}
177
- <div class="px-2 py-1.5 text-xs font-medium text-gray-500">Custom endpoints</div>
178
- {#if custom.length > 0}
179
- {#each custom as model}
180
- {@render modelEntry(model, false)}
181
- {/each}
182
- {/if}
183
- <div
184
- class="flex w-full cursor-pointer items-center gap-2 px-2 py-1.5 text-sm text-gray-500 data-[highlighted]:bg-blue-500/15 data-[highlighted]:text-blue-600 dark:text-gray-400 dark:data-[highlighted]:text-blue-300"
185
- {...combobox.getOption("__custom__", "custom", () => {
186
- onClose?.();
187
- openCustomModelConfig({
188
- onSubmit: model => {
189
- onModelSelect?.(model.id);
190
- },
191
- });
192
- })}
193
- >
194
- <IconAdd class="rounded bg-blue-500/10 text-blue-600" />
195
- Add a custom endpoint
 
 
196
  </div>
197
- {#if other.length > 0}
198
- <div class="px-2 py-1.5 text-xs font-medium text-gray-500">Other models</div>
199
- {#each other as model}
200
- {@render modelEntry(model, false)}
201
- {/each}
202
- {/if}
203
  </div>
204
  </div>
205
  </div>
 
2
  import { autofocus } from "$lib/attachments/autofocus.js";
3
  import type { ConversationClass } from "$lib/state/conversations.svelte";
4
  import { models } from "$lib/state/models.svelte.js";
5
+ import { VirtualScroll } from "$lib/spells/virtual-scroll.svelte.js";
6
  import type { CustomModel, Model } from "$lib/types.js";
7
  import { noop } from "$lib/utils/noop.js";
8
  import fuzzysearch from "$lib/utils/search.js";
 
27
 
28
  let { onModelSelect, onClose, conversation }: Props = $props();
29
 
30
+ let backdropEl = $state<HTMLDivElement>();
31
+ let query = $state("");
32
+
33
+ const trending = $derived(fuzzysearch({ needle: query, haystack: models.trending, property: "id" }));
34
+ const other = $derived(fuzzysearch({ needle: query, haystack: models.nonTrending, property: "id" }));
35
+ const custom = $derived(fuzzysearch({ needle: query, haystack: models.custom, property: "id" }));
36
+
37
+ // Combine all filtered models into sections for virtualization
38
+ type SectionItem =
39
+ | { type: "header"; content: string }
40
+ | { type: "model"; content: Model | CustomModel | "__custom__"; trending?: boolean };
41
+
42
+ const allFilteredModels = $derived.by((): SectionItem[] => {
43
+ const sections: SectionItem[] = [];
44
+
45
+ if (trending.length > 0) {
46
+ sections.push({ type: "header", content: "Trending" });
47
+ trending.forEach(model => sections.push({ type: "model", content: model, trending: true }));
48
+ }
49
+
50
+ sections.push({ type: "header", content: "Custom endpoints" });
51
+ custom.forEach(model => sections.push({ type: "model", content: model }));
52
+ sections.push({ type: "model", content: "__custom__" }); // Add custom button
53
+
54
+ if (other.length > 0) {
55
+ sections.push({ type: "header", content: "Other models" });
56
+ other.forEach(model => sections.push({ type: "model", content: model }));
57
+ }
58
+
59
+ return sections;
60
+ });
61
+
62
+ const virtualScroll = new VirtualScroll({
63
+ itemHeight: 30, // Approximate height of each item
64
+ overscan: 5,
65
+ totalItems: () => allFilteredModels.length,
66
+ });
67
+
68
+ function handleBackdropClick(event: MouseEvent) {
69
+ event.stopPropagation();
70
+ if (window?.getSelection()?.toString()) {
71
+ return;
72
+ }
73
+ if (event.target === backdropEl) {
74
+ onClose?.();
75
+ }
76
+ }
77
+
78
+ const isCustom = typia.createIs<CustomModel>();
79
+
80
  const combobox = new Combobox<string | undefined>({
81
  onOpenChange(o) {
82
  if (!o) onClose?.();
 
91
  onModelSelect?.(modelId);
92
  onClose?.();
93
  },
94
+ onNavigate(current, direction) {
95
+ if (current === "__custom__") return null;
96
+ const modelItems = allFilteredModels.filter(item => item.type === "model");
97
+ const currIdx = modelItems.findIndex(item => typeof item.content === "object" && item.content.id === current);
98
+
99
+ let nextIdx: number;
100
+ if (direction === "next") {
101
+ nextIdx = currIdx === -1 ? 0 : (currIdx + 1) % modelItems.length;
102
+ } else {
103
+ nextIdx = currIdx === -1 ? modelItems.length - 1 : (currIdx - 1 + modelItems.length) % modelItems.length;
104
+ }
105
+
106
+ const nextItem = modelItems[nextIdx];
107
+ if (!nextItem) return null;
108
+
109
+ // Scroll to the item
110
+ const allItems = allFilteredModels;
111
+ const actualIdx = allItems.findIndex(item => item === nextItem);
112
+ if (actualIdx !== -1) {
113
+ virtualScroll.scrollToIndex(actualIdx);
114
+ }
115
+
116
+ // Return the content for highlighting
117
+ return nextItem.content === "__custom__"
118
+ ? "__custom__"
119
+ : typeof nextItem.content === "object"
120
+ ? nextItem.content.id
121
+ : null;
122
+ },
123
  });
124
  $effect(() => {
125
  untrack(() => combobox.highlight(conversation.model.id));
 
128
  combobox.open = true;
129
  });
130
  });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
131
  </script>
132
 
133
  <!-- svelte-ignore a11y_no_static_element_interactions -->
 
152
  class="max-h-[220px] overflow-x-hidden overflow-y-auto md:max-h-[300px]"
153
  {...combobox.content}
154
  popover={undefined}
155
+ {...virtualScroll.container}
156
  >
157
  {#snippet modelEntry(model: Model | CustomModel, trending?: boolean)}
158
  {@const [nameSpace, modelName] = model.id.split("/")}
 
230
  {/if}
231
  </div>
232
  {/snippet}
233
+
234
+ <!-- Virtual scroll container -->
235
+ <div style="height: {virtualScroll.totalHeight}px; position: relative;">
236
+ <div style="transform: translateY({virtualScroll.offsetY}px);">
237
+ {#each virtualScroll.getVisibleItems(allFilteredModels) as { item }}
238
+ {#if item.type === "header"}
239
+ <div class="px-2 py-1.5 text-xs font-medium text-gray-500">{item.content}</div>
240
+ {:else if item.content === "__custom__"}
241
+ <div
242
+ class="flex w-full cursor-pointer items-center gap-2 px-2 py-1.5 text-sm text-gray-500 data-[highlighted]:bg-blue-500/15 data-[highlighted]:text-blue-600 dark:text-gray-400 dark:data-[highlighted]:text-blue-300"
243
+ {...combobox.getOption("__custom__", "custom", () => {
244
+ onClose?.();
245
+ openCustomModelConfig({
246
+ onSubmit: model => {
247
+ onModelSelect?.(model.id);
248
+ },
249
+ });
250
+ })}
251
+ >
252
+ <IconAdd class="rounded bg-blue-500/10 text-blue-600" />
253
+ Add a custom endpoint
254
+ </div>
255
+ {:else}
256
+ {@render modelEntry(item.content, item.trending)}
257
+ {/if}
258
+ {/each}
259
+ </div>
260
  </div>
 
 
 
 
 
 
261
  </div>
262
  </div>
263
  </div>
src/lib/components/inference-playground/provider-select.svelte CHANGED
@@ -82,16 +82,24 @@
82
  const pd = pricing.getPricing(conversation.model.id, provider);
83
  return pricing.formatPricing(pd);
84
  }
85
- const providerPricing = $derived(getProviderPricing(conversation.data.provider ?? ""));
86
  </script>
87
 
88
- <div class="flex flex-col gap-2">
89
- <!--
90
- <label class="flex items-baseline gap-2 text-sm font-medium text-gray-900 dark:text-white">
91
- Providers<span class="text-xs font-normal text-gray-400"></span>
92
- </label>
93
- -->
 
 
 
 
 
 
 
 
94
 
 
95
  <button
96
  {...select.trigger}
97
  class={cn(
@@ -100,17 +108,7 @@
100
  classes,
101
  )}
102
  >
103
- <div class="flex items-center gap-2 text-sm">
104
- <IconProvider provider={conversation.data.provider} />
105
- <div class="flex flex-col items-start">
106
- <span>{getProviderName(conversation.data.provider ?? "") ?? "loading"}</span>
107
- {#if providerPricing}
108
- <span class="text-xs text-gray-500 dark:text-gray-400">
109
- In: {providerPricing.input} • Out: {providerPricing.output}
110
- </span>
111
- {/if}
112
- </div>
113
- </div>
114
  <div
115
  class="absolute right-2 grid size-4 flex-none place-items-center rounded-sm bg-gray-100 text-xs dark:bg-gray-600"
116
  >
@@ -120,22 +118,11 @@
120
 
121
  <div {...select.content} class="rounded-lg border bg-gray-100 dark:border-gray-700 dark:bg-gray-800">
122
  {#snippet option(provider: string)}
123
- {@const providerPricing = getProviderPricing(provider)}
124
  <div {...select.getOption(provider)} class="group block w-full p-1 text-sm dark:text-white">
125
  <div
126
- class="flex items-center gap-2 rounded-md px-2 py-1.5 group-data-[highlighted]:bg-gray-200 dark:group-data-[highlighted]:bg-gray-700"
127
  >
128
- <IconProvider {provider} />
129
- <div class="flex flex-col">
130
- <span>{getProviderName(provider)}</span>
131
- {#if providerPricing}
132
- <div class="flex flex-col">
133
- <span class="text-xs text-gray-500 dark:text-gray-400">
134
- In: {providerPricing.input} • Out: {providerPricing.output}
135
- </span>
136
- </div>
137
- {/if}
138
- </div>
139
  </div>
140
  </div>
141
  {/snippet}
 
82
  const pd = pricing.getPricing(conversation.model.id, provider);
83
  return pricing.formatPricing(pd);
84
  }
 
85
  </script>
86
 
87
+ {#snippet providerDisplay(provider: string)}
88
+ {@const providerPricing = getProviderPricing(provider)}
89
+ <div class="flex flex-col items-start gap-0.5">
90
+ <div class="flex items-center gap-2 text-sm">
91
+ <IconProvider {provider} />
92
+ <span>{getProviderName(provider) ?? "loading"}</span>
93
+ </div>
94
+ {#if providerPricing}
95
+ <span class="text-xs text-gray-500 dark:text-gray-400">
96
+ In: {providerPricing.input} • Out: {providerPricing.output}
97
+ </span>
98
+ {/if}
99
+ </div>
100
+ {/snippet}
101
 
102
+ <div class="flex flex-col gap-2">
103
  <button
104
  {...select.trigger}
105
  class={cn(
 
108
  classes,
109
  )}
110
  >
111
+ {@render providerDisplay(conversation.data.provider ?? "")}
 
 
 
 
 
 
 
 
 
 
112
  <div
113
  class="absolute right-2 grid size-4 flex-none place-items-center rounded-sm bg-gray-100 text-xs dark:bg-gray-600"
114
  >
 
118
 
119
  <div {...select.content} class="rounded-lg border bg-gray-100 dark:border-gray-700 dark:bg-gray-800">
120
  {#snippet option(provider: string)}
 
121
  <div {...select.getOption(provider)} class="group block w-full p-1 text-sm dark:text-white">
122
  <div
123
+ class="rounded-md px-2 py-1.5 group-data-[highlighted]:bg-gray-200 dark:group-data-[highlighted]:bg-gray-700"
124
  >
125
+ {@render providerDisplay(provider)}
 
 
 
 
 
 
 
 
 
 
126
  </div>
127
  </div>
128
  {/snippet}
src/lib/components/inference-playground/structured-output-modal.svelte CHANGED
@@ -31,6 +31,7 @@
31
  const modes = ["form", "code"] as const;
32
  const radioGroup = new RadioGroup({
33
  value: modes[0],
 
34
  });
35
 
36
  type Schema = {
 
31
  const modes = ["form", "code"] as const;
32
  const radioGroup = new RadioGroup({
33
  value: modes[0],
34
+ orientation: "horizontal",
35
  });
36
 
37
  type Schema = {
src/lib/components/switch.svelte ADDED
@@ -0,0 +1,57 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <script lang="ts">
2
+ import { classes } from "$lib/utils/styles.js";
3
+ import { type ComponentProps } from "melt";
4
+ import { Toggle, type ToggleProps } from "melt/builders";
5
+ import { ElementSize } from "runed";
6
+
7
+ let {
8
+ class: className,
9
+ value = $bindable(false),
10
+ ...rest
11
+ }: ComponentProps<ToggleProps> & { class?: string } = $props();
12
+
13
+ const toggle = new Toggle({
14
+ value: () => value ?? false,
15
+ onValueChange: v => (value = v),
16
+ ...rest,
17
+ });
18
+
19
+ let trigger = $state<HTMLButtonElement>();
20
+ const triggerSize = new ElementSize(() => trigger);
21
+ let thumb = $state<HTMLSpanElement>();
22
+ const thumbSize = new ElementSize(() => thumb);
23
+ const padding = 2;
24
+
25
+ const thumbX = $derived.by(() => {
26
+ if (toggle.value) {
27
+ return triggerSize.width - thumbSize.width - padding;
28
+ }
29
+ return padding;
30
+ });
31
+
32
+ let mounted = $state(false);
33
+ $effect(() => {
34
+ setTimeout(() => {
35
+ mounted = true;
36
+ });
37
+ });
38
+ </script>
39
+
40
+ <button
41
+ bind:this={trigger}
42
+ {...toggle.trigger}
43
+ class={classes(
44
+ "relative h-5 w-10 shrink-0 rounded-full bg-neutral-500 transition-all",
45
+ { "bg-blue-500": toggle.value },
46
+ className,
47
+ )}
48
+ >
49
+ <span
50
+ bind:this={thumb}
51
+ class={classes("spring-bounce-20 spring-duration-200 absolute top-0.5 left-0 h-4 w-4 rounded-full bg-neutral-900", {
52
+ "bg-white": toggle.value,
53
+ "!duration-0": !mounted,
54
+ })}
55
+ style="transform: translateX({thumbX}px)"
56
+ ></span>
57
+ </button>
src/lib/constants.ts CHANGED
@@ -1,3 +1,5 @@
 
 
1
  export enum TEST_IDS {
2
  checkpoints_trigger,
3
  checkpoints_menu,
@@ -7,3 +9,15 @@ export enum TEST_IDS {
7
 
8
  message,
9
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { env } from "$env/dynamic/public";
2
+
3
  export enum TEST_IDS {
4
  checkpoints_trigger,
5
  checkpoints_menu,
 
9
 
10
  message,
11
  }
12
+
13
+ export function isMcpEnabled(): boolean {
14
+ const envEnabled = env.PUBLIC_ENABLE_MCP === "true";
15
+ if (envEnabled) return true;
16
+
17
+ if (typeof window === "undefined") return false;
18
+
19
+ const urlParams = new URLSearchParams(window.location.search);
20
+ const hasQueryParam = urlParams.has("mcp") || urlParams.has("enable-mcp");
21
+
22
+ return hasQueryParam;
23
+ }
src/lib/data/context_length.json ADDED
@@ -0,0 +1,269 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "replicate": {},
3
+ "sambanova": {
4
+ "DeepSeek-R1-0528": 32768,
5
+ "DeepSeek-R1-Distill-Llama-70B": 131072,
6
+ "DeepSeek-V3-0324": 32768,
7
+ "E5-Mistral-7B-Instruct": 4096,
8
+ "Llama-4-Maverick-17B-128E-Instruct": 131072,
9
+ "Meta-Llama-3.1-8B-Instruct": 16384,
10
+ "Meta-Llama-3.3-70B-Instruct": 131072,
11
+ "Qwen3-32B": 32768,
12
+ "Whisper-Large-v3": 4096
13
+ },
14
+ "nebius": {
15
+ "meta-llama/Meta-Llama-3.1-8B-Instruct-fast": 131072,
16
+ "meta-llama/Meta-Llama-3.1-8B-Instruct": 131072,
17
+ "meta-llama/Meta-Llama-3.1-70B-Instruct": 131072,
18
+ "meta-llama/Meta-Llama-3.1-405B-Instruct": 131072,
19
+ "meta-llama/Llama-Guard-3-8B": 131072,
20
+ "nvidia/Llama-3_1-Nemotron-Ultra-253B-v1": 131072,
21
+ "mistralai/Mistral-Nemo-Instruct-2407": 128000,
22
+ "google/gemma-2-2b-it": 8192,
23
+ "google/gemma-2-9b-it-fast": 8192,
24
+ "Qwen/Qwen2.5-Coder-7B-fast": 32768,
25
+ "Qwen/Qwen2.5-Coder-7B": 32768,
26
+ "Qwen/Qwen2.5-Coder-32B-Instruct-fast": 131072,
27
+ "Qwen/Qwen2.5-Coder-32B-Instruct": 131072,
28
+ "Qwen/Qwen2.5-32B-Instruct-fast": 131072,
29
+ "Qwen/Qwen2.5-32B-Instruct": 131072,
30
+ "Qwen/Qwen2.5-72B-Instruct-fast": 131072,
31
+ "Qwen/Qwen2.5-72B-Instruct": 131072,
32
+ "Qwen/Qwen2-VL-72B-Instruct": 32768,
33
+ "aaditya/Llama3-OpenBioLLM-70B": 8192,
34
+ "BAAI/bge-en-icl": 32768,
35
+ "BAAI/bge-multilingual-gemma2": 8192,
36
+ "intfloat/e5-mistral-7b-instruct": 32768,
37
+ "meta-llama/Llama-3.3-70B-Instruct": 131072,
38
+ "meta-llama/Llama-3.3-70B-Instruct-fast": 131072,
39
+ "microsoft/phi-4": 16384,
40
+ "deepseek-ai/DeepSeek-V3": 163840,
41
+ "deepseek-ai/DeepSeek-R1": 163840,
42
+ "deepseek-ai/DeepSeek-R1-0528": 131072,
43
+ "NousResearch/Hermes-3-Llama-405B": 131072,
44
+ "deepseek-ai/DeepSeek-R1-Distill-Llama-70B": 131072,
45
+ "deepseek-ai/DeepSeek-R1-fast": 163840,
46
+ "Qwen/QwQ-32B-fast": 131072,
47
+ "Qwen/QwQ-32B": 131072,
48
+ "Qwen/Qwen3-235B-A22B": 40960,
49
+ "Qwen/Qwen3-30B-A3B": 40960,
50
+ "Qwen/Qwen3-30B-A3B-fast": 40960,
51
+ "Qwen/Qwen3-32B": 40960,
52
+ "Qwen/Qwen3-32B-fast": 40960,
53
+ "Qwen/Qwen3-14B": 40960,
54
+ "Qwen/Qwen3-4B-fast": 40960,
55
+ "nvidia/Llama-3_3-Nemotron-Super-49B-v1": 131072,
56
+ "mistralai/Mistral-Small-3.1-24B-Instruct-2503": 131072,
57
+ "mistralai/Devstral-Small-2505": 128000,
58
+ "google/gemma-3-27b-it": 110000,
59
+ "google/gemma-3-27b-it-fast": 110000,
60
+ "Qwen/Qwen2.5-VL-72B-Instruct": 32000,
61
+ "Qwen/Qwen3-Embedding-8B": 40960,
62
+ "deepseek-ai/DeepSeek-V3-0324": 163840,
63
+ "deepseek-ai/DeepSeek-V3-0324-fast": 163840,
64
+ "black-forest-labs/flux-dev": 0,
65
+ "black-forest-labs/flux-schnell": 0,
66
+ "stability-ai/sdxl": 0
67
+ },
68
+ "novita": {
69
+ "deepseek/deepseek-r1-0528": 163840,
70
+ "deepseek/deepseek-v3-0324": 163840,
71
+ "baidu/ernie-4.5-vl-424b-a47b": 123000,
72
+ "baidu/ernie-4.5-300b-a47b-paddle": 123000,
73
+ "qwen/qwen3-30b-a3b-fp8": 40960,
74
+ "minimaxai/minimax-m1-80k": 128000,
75
+ "deepseek/deepseek-r1-0528-qwen3-8b": 128000,
76
+ "qwen/qwen3-32b-fp8": 40960,
77
+ "qwen/qwen2.5-vl-72b-instruct": 32768,
78
+ "qwen/qwen3-235b-a22b-fp8": 40960,
79
+ "deepseek/deepseek-v3-turbo": 64000,
80
+ "meta-llama/llama-4-maverick-17b-128e-instruct-fp8": 1048576,
81
+ "google/gemma-3-27b-it": 32000,
82
+ "deepseek/deepseek-r1-turbo": 64000,
83
+ "Sao10K/L3-8B-Stheno-v3.2": 8192,
84
+ "gryphe/mythomax-l2-13b": 4096,
85
+ "deepseek/deepseek-prover-v2-671b": 160000,
86
+ "meta-llama/llama-4-scout-17b-16e-instruct": 131072,
87
+ "deepseek/deepseek-r1-distill-llama-8b": 32000,
88
+ "meta-llama/llama-3.1-8b-instruct": 16384,
89
+ "deepseek/deepseek-r1-distill-qwen-14b": 64000,
90
+ "meta-llama/llama-3.3-70b-instruct": 131072,
91
+ "qwen/qwen-2.5-72b-instruct": 32000,
92
+ "mistralai/mistral-nemo": 60288,
93
+ "deepseek/deepseek-r1-distill-qwen-32b": 64000,
94
+ "meta-llama/llama-3-8b-instruct": 8192,
95
+ "microsoft/wizardlm-2-8x22b": 65535,
96
+ "deepseek/deepseek-r1-distill-llama-70b": 32000,
97
+ "mistralai/mistral-7b-instruct": 32768,
98
+ "meta-llama/llama-3-70b-instruct": 8192,
99
+ "nousresearch/hermes-2-pro-llama-3-8b": 8192,
100
+ "sao10k/l3-70b-euryale-v2.1": 8192,
101
+ "cognitivecomputations/dolphin-mixtral-8x22b": 16000,
102
+ "sophosympatheia/midnight-rose-70b": 4096,
103
+ "sao10k/l3-8b-lunaris": 8192,
104
+ "baidu/ernie-4.5-vl-28b-a3b": 30000,
105
+ "baidu/ernie-4.5-21B-a3b": 120000,
106
+ "baidu/ernie-4.5-0.3b": 120000,
107
+ "google/gemma-3-1b-it": 32768,
108
+ "qwen/qwen3-8b-fp8": 128000,
109
+ "qwen/qwen3-4b-fp8": 128000,
110
+ "thudm/glm-4-32b-0414": 32000,
111
+ "qwen/qwen2.5-7b-instruct": 32000,
112
+ "meta-llama/llama-3.2-1b-instruct": 131000,
113
+ "meta-llama/llama-3.2-3b-instruct": 32768,
114
+ "meta-llama/llama-3.1-8b-instruct-bf16": 8192,
115
+ "sao10k/l31-70b-euryale-v2.2": 8192
116
+ },
117
+ "fal": {
118
+ "fal/model-name": 4096
119
+ },
120
+ "cerebras": {
121
+ "cerebras/model-name": 8192
122
+ },
123
+ "hf-inference": {
124
+ "google/gemma-2-9b-it": 8192,
125
+ "meta-llama/Meta-Llama-3-8B-Instruct": 8192
126
+ },
127
+ "hyperbolic": {
128
+ "Qwen/Qwen2.5-72B-Instruct": 131072,
129
+ "Qwen/Qwen2.5-VL-72B-Instruct": 32768,
130
+ "meta-llama/Meta-Llama-3-70B-Instruct": 8192,
131
+ "deepseek-ai/DeepSeek-V3": 131072,
132
+ "deepseek-ai/DeepSeek-V3-0324": 163840,
133
+ "meta-llama/Llama-3.3-70B-Instruct": 131072,
134
+ "Qwen/Qwen2.5-Coder-32B-Instruct": 32768,
135
+ "meta-llama/Llama-3.2-3B-Instruct": 131072,
136
+ "NousResearch/Hermes-3-Llama-3.1-70B": 12288,
137
+ "meta-llama/Meta-Llama-3.1-405B-Instruct": 131000,
138
+ "meta-llama/Meta-Llama-3.1-70B-Instruct": 131072,
139
+ "meta-llama/Meta-Llama-3.1-8B-Instruct": 131072,
140
+ "mistralai/Pixtral-12B-2409": 32768,
141
+ "Qwen/Qwen2.5-VL-7B-Instruct": 32768,
142
+ "meta-llama/Meta-Llama-3.1-405B-FP8": 32768,
143
+ "deepseek-ai/DeepSeek-R1": 163840,
144
+ "Qwen/QwQ-32B": 131072
145
+ },
146
+ "cohere": {
147
+ "embed-english-light-v3.0": 512,
148
+ "embed-multilingual-v2.0": 256,
149
+ "rerank-v3.5": 4096,
150
+ "embed-v4.0": 8192,
151
+ "rerank-english-v3.0": 4096,
152
+ "command-r-08-2024": 132096,
153
+ "embed-english-light-v3.0-image": 0,
154
+ "embed-english-v3.0-image": 0,
155
+ "command-nightly": 288000,
156
+ "command-a-03-2025": 288000,
157
+ "command-r-plus-08-2024": 132096,
158
+ "c4ai-aya-vision-32b": 16384,
159
+ "command-r": 132096,
160
+ "command-r7b-12-2024": 132000,
161
+ "command-r7b-arabic-02-2025": 128000,
162
+ "command-light-nightly": 4096,
163
+ "embed-english-v3.0": 512,
164
+ "embed-multilingual-light-v3.0-image": 0,
165
+ "embed-multilingual-v3.0-image": 0,
166
+ "c4ai-aya-expanse-32b": 128000,
167
+ "command": 4096
168
+ },
169
+ "together": {
170
+ "togethercomputer/m2-bert-80M-32k-retrieval": 32768,
171
+ "cartesia/sonic": 0,
172
+ "meta-llama/Meta-Llama-3-8B-Instruct-Lite": 8192,
173
+ "intfloat/multilingual-e5-large-instruct": 514,
174
+ "Alibaba-NLP/gte-modernbert-base": 8192,
175
+ "meta-llama/Llama-4-Scout-17B-16E-Instruct": 1048576,
176
+ "meta-llama/LlamaGuard-2-8b": 8192,
177
+ "Qwen/Qwen2.5-Coder-32B-Instruct": 16384,
178
+ "cartesia/sonic-2": 0,
179
+ "Qwen/Qwen3-235B-A22B-fp8-tput": 40960,
180
+ "togethercomputer/MoA-1": 32768,
181
+ "meta-llama/Meta-Llama-3-70B-Instruct-Turbo": 8192,
182
+ "meta-llama/Meta-Llama-3.1-8B-Instruct-Turbo": 131072,
183
+ "meta-llama/Meta-Llama-3.1-70B-Instruct-Turbo": 131072,
184
+ "meta-llama/Meta-Llama-Guard-3-8B": 8192,
185
+ "arcee_ai/arcee-spotlight": 131072,
186
+ "google/gemma-3-27b-it": 65536,
187
+ "arcee-ai/AFM-4.5B-Preview": 65536,
188
+ "deepseek-ai/DeepSeek-V3": 131072,
189
+ "lgai/exaone-3-5-32b-instruct": 32768,
190
+ "deepseek-ai/DeepSeek-R1-0528-tput": 163840,
191
+ "mistralai/Mixtral-8x7B-Instruct-v0.1": 32768,
192
+ "meta-llama/Llama-Vision-Free": 131072,
193
+ "meta-llama/Llama-3-8b-chat-hf": 8192,
194
+ "mistralai/Mistral-7B-Instruct-v0.1": 32768,
195
+ "Qwen/QwQ-32B": 131072,
196
+ "meta-llama/Llama-2-70b-hf": 4096,
197
+ "togethercomputer/MoA-1-Turbo": 32768,
198
+ "black-forest-labs/FLUX.1-kontext-max": 0,
199
+ "perplexity-ai/r1-1776": 163840,
200
+ "mistralai/Mistral-7B-Instruct-v0.2": 32768,
201
+ "deepseek-ai/DeepSeek-V3-p-dp": 131072,
202
+ "Qwen/Qwen2-72B-Instruct": 32768,
203
+ "mistralai/Mistral-7B-Instruct-v0.3": 32768,
204
+ "NousResearch/Nous-Hermes-2-Mixtral-8x7B-DPO": 32768,
205
+ "meta-llama/Llama-Guard-3-11B-Vision-Turbo": 131072,
206
+ "Qwen/Qwen2-VL-72B-Instruct": 32768,
207
+ "scb10x/scb10x-llama3-1-typhoon2-70b-instruct": 8192,
208
+ "arcee-ai/maestro-reasoning": 131072,
209
+ "meta-llama/Llama-3.2-3B-Instruct-Turbo": 131072,
210
+ "arcee-ai/virtuoso-medium-v2": 131072,
211
+ "arcee-ai/coder-large": 32768,
212
+ "meta-llama/Llama-Guard-4-12B": 1048576,
213
+ "deepseek-ai/DeepSeek-R1-Distill-Qwen-14B": 131072,
214
+ "arcee-ai/virtuoso-large": 131072,
215
+ "deepseek-ai/DeepSeek-R1-Distill-Qwen-1.5B": 131072,
216
+ "deepseek-ai/DeepSeek-R1-Distill-Llama-70B": 131072,
217
+ "nvidia/Llama-3.1-Nemotron-70B-Instruct-HF": 32768,
218
+ "deepseek-ai/DeepSeek-R1-Distill-Llama-70B-free": 8192,
219
+ "meta-llama/Llama-4-Maverick-17B-128E-Instruct-FP8": 1048576,
220
+ "togethercomputer/Refuel-Llm-V2-Small": 8192,
221
+ "togethercomputer/Refuel-Llm-V2": 16384,
222
+ "Qwen/Qwen2.5-VL-72B-Instruct": 32768,
223
+ "meta-llama/Meta-Llama-3.1-405B-Instruct-Turbo": 130815,
224
+ "scb10x/scb10x-typhoon-2-1-gemma3-12b": 131072,
225
+ "arcee-ai/caller": 32768,
226
+ "lgai/exaone-deep-32b": 32768,
227
+ "black-forest-labs/FLUX.1-kontext-pro": 0,
228
+ "google/gemma-3n-E4B-it": 32768,
229
+ "deepseek-ai/DeepSeek-R1": 163840,
230
+ "Qwen/Qwen2.5-72B-Instruct-Turbo": 131072,
231
+ "meta-llama/Llama-3.2-90B-Vision-Instruct-Turbo": 131072,
232
+ "arcee-ai/arcee-blitz": 32768,
233
+ "meta-llama/Llama-3.2-11B-Vision-Instruct-Turbo": 131072,
234
+ "meta-llama/Llama-3-70b-chat-hf": 8192,
235
+ "google/gemma-2-27b-it": 8192,
236
+ "meta-llama/Llama-3.3-70B-Instruct-Turbo-Free": 131072,
237
+ "Qwen/Qwen2.5-7B-Instruct-Turbo": 32768,
238
+ "mistralai/Mistral-Small-24B-Instruct-2501": 32768,
239
+ "Salesforce/Llama-Rank-V1": 8192,
240
+ "meta-llama/Llama-3.3-70B-Instruct-Turbo": 131072,
241
+ "marin-community/marin-8b-instruct": 4096,
242
+ "Qwen/Qwen3-32B-FP8": 0
243
+ },
244
+ "fireworks-ai": {
245
+ "accounts/perplexity/models/r1-1776": 163840,
246
+ "accounts/fireworks/models/deepseek-r1-0528": 163840,
247
+ "accounts/fireworks/models/qwen3-30b-a3b": 40000,
248
+ "accounts/fireworks/models/llama-guard-3-8b": 131072,
249
+ "accounts/fireworks/models/llama4-scout-instruct-basic": 10485760,
250
+ "accounts/fireworks/models/llama4-maverick-instruct-basic": 1048576,
251
+ "accounts/fireworks/models/llama-v3p1-8b-instruct": 131072,
252
+ "accounts/fireworks/models/firesearch-ocr-v6": 8192,
253
+ "accounts/fireworks/models/llama-v3p1-405b-instruct": 131072,
254
+ "accounts/fireworks/models/qwen2-vl-72b-instruct": 32768,
255
+ "accounts/fireworks/models/mixtral-8x22b-instruct": 65536,
256
+ "accounts/fireworks/models/qwen2p5-72b-instruct": 32768,
257
+ "accounts/fireworks/models/deepseek-r1-basic": 163840,
258
+ "accounts/fireworks/models/llama-v3p1-70b-instruct": 131072,
259
+ "accounts/fireworks/models/qwen3-235b-a22b": 128000,
260
+ "accounts/fireworks/models/llama-v3p3-70b-instruct": 131072,
261
+ "accounts/fireworks/models/deepseek-r1": 163840,
262
+ "accounts/sentientfoundation/models/dobby-unhinged-llama-3-3-70b-new": 131072,
263
+ "accounts/sentientfoundation-serverless/models/dobby-mini-unhinged-plus-llama-3-1-8b": 131072,
264
+ "accounts/fireworks/models/deepseek-v3": 131072,
265
+ "accounts/fireworks/models/deepseek-v3-0324": 163840,
266
+ "accounts/fireworks/models/qwq-32b": 131072,
267
+ "accounts/fireworks/models/qwen2p5-vl-32b-instruct": 128000
268
+ }
269
+ }
src/lib/remote/avatar.remote.ts ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { query } from "$app/server";
2
+ import { withCache } from "$lib/utils/cache.js";
3
+ import typia from "typia";
4
+
5
+ type AvatarJson = {
6
+ avatarUrl: string;
7
+ };
8
+
9
+ export const getAvatarUrl = query(
10
+ typia.createValidate<string | undefined>(),
11
+ withCache(async (orgName): Promise<string | undefined> => {
12
+ if (!orgName) return;
13
+ const url = `https://huggingface.co/api/organizations/${orgName}/avatar`;
14
+
15
+ const res = await fetch(url);
16
+ if (!res.ok) {
17
+ throw new Error(`Error getting avatar url for org: ${orgName}`);
18
+ }
19
+
20
+ const json = await res.json();
21
+ typia.assert<AvatarJson>(json);
22
+ const { avatarUrl } = json;
23
+ return avatarUrl;
24
+ }),
25
+ );
src/{routes/api/models/+server.ts → lib/remote/models.remote.ts} RENAMED
@@ -1,6 +1,40 @@
1
- import type { Model } from "$lib/types.js";
2
- import { json } from "@sveltejs/kit";
3
- import type { RequestHandler } from "./$types.js";
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4
 
5
  enum CacheStatus {
6
  SUCCESS = "success",
@@ -12,8 +46,7 @@ type Cache = {
12
  data: Model[] | undefined;
13
  timestamp: number;
14
  status: CacheStatus;
15
- // Track failed models to selectively refetch them
16
- failedTokenizers: string[]; // Using array instead of Set for serialization compatibility
17
  failedApiCalls: {
18
  textGeneration: boolean;
19
  imageTextToText: boolean;
@@ -31,9 +64,8 @@ const cache: Cache = {
31
  },
32
  };
33
 
34
- // The time between cache refreshes
35
  const FULL_CACHE_REFRESH = 1000 * 60 * 60; // 1 hour
36
- const PARTIAL_CACHE_REFRESH = 1000 * 60 * 15; // 15 minutes (shorter for partial results)
37
 
38
  const headers: HeadersInit = {
39
  "Upgrade-Insecure-Requests": "1",
@@ -57,14 +89,14 @@ interface ApiQueryParams {
57
  pipeline_tag?: "text-generation" | "image-text-to-text";
58
  filter: string;
59
  inference_provider: string;
60
- limit: number;
 
61
  expand: string[];
62
  }
63
 
64
  const queryParams: ApiQueryParams = {
65
  filter: "conversational",
66
  inference_provider: "all",
67
- limit: 100,
68
  expand: ["inferenceProviderMapping", "config", "library_name", "pipeline_tag", "tags", "mask_token", "trendingScore"],
69
  };
70
 
@@ -73,14 +105,12 @@ const baseUrl = "https://huggingface.co/api/models";
73
  function buildApiUrl(params: ApiQueryParams): string {
74
  const url = new URL(baseUrl);
75
 
76
- // Add simple params
77
  Object.entries(params).forEach(([key, value]) => {
78
- if (!Array.isArray(value)) {
79
  url.searchParams.append(key, String(value));
80
  }
81
  });
82
 
83
- // Handle array params specially
84
  params.expand.forEach(item => {
85
  url.searchParams.append("expand[]", item);
86
  });
@@ -88,33 +118,55 @@ function buildApiUrl(params: ApiQueryParams): string {
88
  return url.toString();
89
  }
90
 
91
- export type ApiModelsResponse = {
92
- models: Model[];
93
- };
 
 
 
 
 
 
 
 
 
94
 
95
- function createResponse(data: ApiModelsResponse): Response {
96
- return json(data);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
97
  }
98
 
99
- export const GET: RequestHandler = async ({ fetch }) => {
100
  const timestamp = Date.now();
101
 
102
- // Determine if cache is valid
103
  const elapsed = timestamp - cache.timestamp;
104
  const cacheRefreshTime = cache.status === CacheStatus.SUCCESS ? FULL_CACHE_REFRESH : PARTIAL_CACHE_REFRESH;
105
 
106
- // Use cache if it's still valid and has data
107
  if (elapsed < cacheRefreshTime && cache.data?.length) {
108
- console.log(`Using ${cache.status} cache (${Math.floor(elapsed / 1000 / 60)} min old)`);
109
- return createResponse({ models: cache.data });
110
  }
111
 
112
  try {
113
- // Determine which API calls we need to make based on cache status
114
  const needTextGenFetch = elapsed >= FULL_CACHE_REFRESH || cache.failedApiCalls.textGeneration;
115
  const needImgTextFetch = elapsed >= FULL_CACHE_REFRESH || cache.failedApiCalls.imageTextToText;
116
 
117
- // Track the existing models we'll keep
118
  const existingModels = new Map<string, Model>();
119
  if (cache.data) {
120
  cache.data.forEach(model => {
@@ -122,49 +174,44 @@ export const GET: RequestHandler = async ({ fetch }) => {
122
  });
123
  }
124
 
125
- // Initialize new tracking for failed requests
126
  const newFailedTokenizers: string[] = [];
127
  const newFailedApiCalls = {
128
  textGeneration: false,
129
  imageTextToText: false,
130
  };
131
 
132
- // Fetch models as needed
133
  let textGenModels: Model[] = [];
134
  let imgText2TextModels: Model[] = [];
135
 
136
- // Make the needed API calls in parallel
137
- const apiPromises: Promise<Response | void>[] = [];
138
  if (needTextGenFetch) {
139
- const url = buildApiUrl({ ...queryParams, pipeline_tag: "text-generation" });
140
  apiPromises.push(
141
- fetch(url, requestInit).then(async response => {
142
- if (!response.ok) {
143
- console.error(`Error fetching text-generation models`, response.status, response.statusText);
 
 
 
144
  newFailedApiCalls.textGeneration = true;
145
- } else {
146
- textGenModels = await response.json();
147
- }
148
- }),
149
  );
150
  }
151
 
152
  if (needImgTextFetch) {
153
  apiPromises.push(
154
- fetch(buildApiUrl({ ...queryParams, pipeline_tag: "image-text-to-text" }), requestInit).then(async response => {
155
- if (!response.ok) {
156
- console.error(`Error fetching image-text-to-text models`, response.status, response.statusText);
 
 
 
157
  newFailedApiCalls.imageTextToText = true;
158
- } else {
159
- imgText2TextModels = await response.json();
160
- }
161
- }),
162
  );
163
  }
164
 
165
  await Promise.all(apiPromises);
166
 
167
- // If both needed API calls failed and we have cached data, use it
168
  if (
169
  needTextGenFetch &&
170
  newFailedApiCalls.textGeneration &&
@@ -172,14 +219,13 @@ export const GET: RequestHandler = async ({ fetch }) => {
172
  newFailedApiCalls.imageTextToText &&
173
  cache.data?.length
174
  ) {
175
- console.log("All API requests failed. Using existing cache as fallback.");
176
  cache.status = CacheStatus.ERROR;
177
- cache.timestamp = timestamp; // Update timestamp to avoid rapid retry loops
178
  cache.failedApiCalls = newFailedApiCalls;
179
- return createResponse({ models: cache.data });
180
  }
181
 
182
- // For API calls we didn't need to make, use cached models
183
  if (!needTextGenFetch && cache.data) {
184
  textGenModels = cache.data.filter(model => model.pipeline_tag === "text-generation").map(model => model as Model);
185
  }
@@ -195,9 +241,7 @@ export const GET: RequestHandler = async ({ fetch }) => {
195
  );
196
  models.sort((a, b) => a.id.toLowerCase().localeCompare(b.id.toLowerCase()));
197
 
198
- // Determine cache status based on failures
199
  const hasApiFailures = newFailedApiCalls.textGeneration || newFailedApiCalls.imageTextToText;
200
-
201
  const cacheStatus = hasApiFailures ? CacheStatus.PARTIAL : CacheStatus.SUCCESS;
202
 
203
  cache.data = models;
@@ -206,34 +250,31 @@ export const GET: RequestHandler = async ({ fetch }) => {
206
  cache.failedTokenizers = newFailedTokenizers;
207
  cache.failedApiCalls = newFailedApiCalls;
208
 
209
- console.log(
210
  `Cache updated: ${models.length} models, status: ${cacheStatus}, ` +
211
  `failed tokenizers: ${newFailedTokenizers.length}, ` +
212
  `API failures: text=${newFailedApiCalls.textGeneration}, img=${newFailedApiCalls.imageTextToText}`,
213
  );
214
 
215
- return createResponse({ models });
216
  } catch (error) {
217
- console.error("Error fetching models:", error);
218
 
219
- // If we have cached data, use it as fallback
220
  if (cache.data?.length) {
221
  cache.status = CacheStatus.ERROR;
222
- // Mark all API calls as failed so we retry them next time
223
  cache.failedApiCalls = {
224
  textGeneration: true,
225
  imageTextToText: true,
226
  };
227
- return createResponse({ models: cache.data });
228
  }
229
 
230
- // No cache available, return empty array
231
  cache.status = CacheStatus.ERROR;
232
  cache.timestamp = timestamp;
233
  cache.failedApiCalls = {
234
  textGeneration: true,
235
  imageTextToText: true,
236
  };
237
- return createResponse({ models: [] });
238
  }
239
- };
 
1
+ import { query } from "$app/server";
2
+ import type { Provider, Model } from "$lib/types.js";
3
+ import { debugError, debugLog } from "$lib/utils/debug.js";
4
+
5
+ export type RouterData = {
6
+ object: string;
7
+ data: Datum[];
8
+ };
9
+
10
+ type Datum = {
11
+ id: string;
12
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
13
+ object: any;
14
+ created: number;
15
+ owned_by: string;
16
+ providers: ProviderElement[];
17
+ };
18
+
19
+ type ProviderElement = {
20
+ provider: Provider;
21
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
22
+ status: any;
23
+ context_length?: number;
24
+ pricing?: Pricing;
25
+ supports_tools?: boolean;
26
+ supports_structured_output?: boolean;
27
+ };
28
+
29
+ type Pricing = {
30
+ input: number;
31
+ output: number;
32
+ };
33
+
34
+ export const getRouterData = query(async (): Promise<RouterData> => {
35
+ const res = await fetch("https://router.huggingface.co/v1/models");
36
+ return res.json();
37
+ });
38
 
39
  enum CacheStatus {
40
  SUCCESS = "success",
 
46
  data: Model[] | undefined;
47
  timestamp: number;
48
  status: CacheStatus;
49
+ failedTokenizers: string[];
 
50
  failedApiCalls: {
51
  textGeneration: boolean;
52
  imageTextToText: boolean;
 
64
  },
65
  };
66
 
 
67
  const FULL_CACHE_REFRESH = 1000 * 60 * 60; // 1 hour
68
+ const PARTIAL_CACHE_REFRESH = 1000 * 60 * 15; // 15 minutes
69
 
70
  const headers: HeadersInit = {
71
  "Upgrade-Insecure-Requests": "1",
 
89
  pipeline_tag?: "text-generation" | "image-text-to-text";
90
  filter: string;
91
  inference_provider: string;
92
+ limit?: number;
93
+ skip?: number;
94
  expand: string[];
95
  }
96
 
97
  const queryParams: ApiQueryParams = {
98
  filter: "conversational",
99
  inference_provider: "all",
 
100
  expand: ["inferenceProviderMapping", "config", "library_name", "pipeline_tag", "tags", "mask_token", "trendingScore"],
101
  };
102
 
 
105
  function buildApiUrl(params: ApiQueryParams): string {
106
  const url = new URL(baseUrl);
107
 
 
108
  Object.entries(params).forEach(([key, value]) => {
109
+ if (!Array.isArray(value) && value !== undefined) {
110
  url.searchParams.append(key, String(value));
111
  }
112
  });
113
 
 
114
  params.expand.forEach(item => {
115
  url.searchParams.append("expand[]", item);
116
  });
 
118
  return url.toString();
119
  }
120
 
121
+ async function fetchAllModelsWithPagination(pipeline_tag: "text-generation" | "image-text-to-text"): Promise<Model[]> {
122
+ const allModels: Model[] = [];
123
+ let skip = 0;
124
+ const batchSize = 1000;
125
+
126
+ while (true) {
127
+ const url = buildApiUrl({
128
+ ...queryParams,
129
+ pipeline_tag,
130
+ limit: batchSize,
131
+ skip,
132
+ });
133
 
134
+ const response = await fetch(url, requestInit);
135
+
136
+ if (!response.ok) {
137
+ break;
138
+ }
139
+
140
+ const models: Model[] = await response.json();
141
+
142
+ if (models.length === 0) {
143
+ break;
144
+ }
145
+
146
+ allModels.push(...models);
147
+ skip += batchSize;
148
+
149
+ await new Promise(resolve => setTimeout(resolve, 100));
150
+ }
151
+
152
+ return allModels;
153
  }
154
 
155
+ export const getModels = query(async (): Promise<Model[]> => {
156
  const timestamp = Date.now();
157
 
 
158
  const elapsed = timestamp - cache.timestamp;
159
  const cacheRefreshTime = cache.status === CacheStatus.SUCCESS ? FULL_CACHE_REFRESH : PARTIAL_CACHE_REFRESH;
160
 
 
161
  if (elapsed < cacheRefreshTime && cache.data?.length) {
162
+ debugLog(`Using ${cache.status} cache (${Math.floor(elapsed / 1000 / 60)} min old)`);
163
+ return cache.data;
164
  }
165
 
166
  try {
 
167
  const needTextGenFetch = elapsed >= FULL_CACHE_REFRESH || cache.failedApiCalls.textGeneration;
168
  const needImgTextFetch = elapsed >= FULL_CACHE_REFRESH || cache.failedApiCalls.imageTextToText;
169
 
 
170
  const existingModels = new Map<string, Model>();
171
  if (cache.data) {
172
  cache.data.forEach(model => {
 
174
  });
175
  }
176
 
 
177
  const newFailedTokenizers: string[] = [];
178
  const newFailedApiCalls = {
179
  textGeneration: false,
180
  imageTextToText: false,
181
  };
182
 
 
183
  let textGenModels: Model[] = [];
184
  let imgText2TextModels: Model[] = [];
185
 
186
+ const apiPromises: Promise<void>[] = [];
 
187
  if (needTextGenFetch) {
 
188
  apiPromises.push(
189
+ fetchAllModelsWithPagination("text-generation")
190
+ .then(models => {
191
+ textGenModels = models;
192
+ })
193
+ .catch(error => {
194
+ debugError(`Error fetching text-generation models:`, error);
195
  newFailedApiCalls.textGeneration = true;
196
+ }),
 
 
 
197
  );
198
  }
199
 
200
  if (needImgTextFetch) {
201
  apiPromises.push(
202
+ fetchAllModelsWithPagination("image-text-to-text")
203
+ .then(models => {
204
+ imgText2TextModels = models;
205
+ })
206
+ .catch(error => {
207
+ debugError(`Error fetching image-text-to-text models:`, error);
208
  newFailedApiCalls.imageTextToText = true;
209
+ }),
 
 
 
210
  );
211
  }
212
 
213
  await Promise.all(apiPromises);
214
 
 
215
  if (
216
  needTextGenFetch &&
217
  newFailedApiCalls.textGeneration &&
 
219
  newFailedApiCalls.imageTextToText &&
220
  cache.data?.length
221
  ) {
222
+ debugLog("All API requests failed. Using existing cache as fallback.");
223
  cache.status = CacheStatus.ERROR;
224
+ cache.timestamp = timestamp;
225
  cache.failedApiCalls = newFailedApiCalls;
226
+ return cache.data;
227
  }
228
 
 
229
  if (!needTextGenFetch && cache.data) {
230
  textGenModels = cache.data.filter(model => model.pipeline_tag === "text-generation").map(model => model as Model);
231
  }
 
241
  );
242
  models.sort((a, b) => a.id.toLowerCase().localeCompare(b.id.toLowerCase()));
243
 
 
244
  const hasApiFailures = newFailedApiCalls.textGeneration || newFailedApiCalls.imageTextToText;
 
245
  const cacheStatus = hasApiFailures ? CacheStatus.PARTIAL : CacheStatus.SUCCESS;
246
 
247
  cache.data = models;
 
250
  cache.failedTokenizers = newFailedTokenizers;
251
  cache.failedApiCalls = newFailedApiCalls;
252
 
253
+ debugLog(
254
  `Cache updated: ${models.length} models, status: ${cacheStatus}, ` +
255
  `failed tokenizers: ${newFailedTokenizers.length}, ` +
256
  `API failures: text=${newFailedApiCalls.textGeneration}, img=${newFailedApiCalls.imageTextToText}`,
257
  );
258
 
259
+ return models;
260
  } catch (error) {
261
+ debugError("Error fetching models:", error);
262
 
 
263
  if (cache.data?.length) {
264
  cache.status = CacheStatus.ERROR;
 
265
  cache.failedApiCalls = {
266
  textGeneration: true,
267
  imageTextToText: true,
268
  };
269
+ return cache.data;
270
  }
271
 
 
272
  cache.status = CacheStatus.ERROR;
273
  cache.timestamp = timestamp;
274
  cache.failedApiCalls = {
275
  textGeneration: true,
276
  imageTextToText: true,
277
  };
278
+ return [];
279
  }
280
+ });
src/lib/spells/create-init.svelte.ts CHANGED
@@ -1,10 +1,10 @@
1
- export function createInit(cb: () => void) {
2
  let called = $state(false);
3
 
4
- function init() {
5
  if (called) return;
6
  called = true;
7
- cb();
8
  }
9
 
10
  return Object.defineProperties(init, {
 
1
+ export function createInit(cb: () => void | Promise<void>) {
2
  let called = $state(false);
3
 
4
+ async function init() {
5
  if (called) return;
6
  called = true;
7
+ await cb();
8
  }
9
 
10
  return Object.defineProperties(init, {
src/lib/spells/virtual-scroll.svelte.ts ADDED
@@ -0,0 +1,107 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import type { MaybeGetter } from "$lib/types.js";
2
+ import { ElementSize } from "runed";
3
+ import { createAttachmentKey } from "svelte/attachments";
4
+ import type { HTMLAttributes } from "svelte/elements";
5
+ import { extract } from "./extract.svelte";
6
+
7
+ interface VirtualScrollOptions {
8
+ totalItems?: MaybeGetter<number>;
9
+ itemHeight: MaybeGetter<number>;
10
+ overscan?: MaybeGetter<number | undefined>;
11
+ }
12
+
13
+ export class VirtualScroll {
14
+ #options: VirtualScrollOptions;
15
+ itemHeight = $derived.by(() => extract(this.#options.itemHeight));
16
+ overscan = $derived.by(() => extract(this.#options.overscan, 10));
17
+ totalItems = $derived.by(() => extract(this.#options.totalItems, 0));
18
+
19
+ #scrollTop = $state(0);
20
+
21
+ #containerEl = $state<HTMLElement>();
22
+ #containerSize = new ElementSize(() => this.#containerEl);
23
+
24
+ constructor(options: VirtualScrollOptions) {
25
+ this.#options = options;
26
+ }
27
+
28
+ get scrollTop() {
29
+ return this.#scrollTop;
30
+ }
31
+
32
+ set scrollTop(value: number) {
33
+ this.#scrollTop = value;
34
+ }
35
+
36
+ get visibleRange() {
37
+ const startIndex = Math.floor(this.#scrollTop / this.itemHeight);
38
+ const endIndex = Math.min(
39
+ startIndex + Math.ceil(this.#containerSize.height / this.itemHeight),
40
+ this.totalItems - 1,
41
+ );
42
+
43
+ return {
44
+ start: Math.max(0, startIndex - this.overscan),
45
+ end: Math.min(this.totalItems - 1, endIndex + this.overscan),
46
+ };
47
+ }
48
+
49
+ get totalHeight() {
50
+ return this.totalItems * this.itemHeight;
51
+ }
52
+
53
+ get offsetY() {
54
+ return this.visibleRange.start * this.itemHeight;
55
+ }
56
+
57
+ getVisibleItems<T>(items: T[]): Array<{ item: T; index: number }> {
58
+ const { start, end } = this.visibleRange;
59
+ return items.slice(start, end + 1).map((item, i) => ({
60
+ item,
61
+ index: start + i,
62
+ }));
63
+ }
64
+
65
+ scrollToIndex(index: number) {
66
+ const { start, end } = this.visibleRange;
67
+
68
+ // Only scroll if the index is not currently visible
69
+ if (index >= start && index <= end) {
70
+ return; // Already visible, no need to scroll
71
+ }
72
+
73
+ let targetScrollTop: number;
74
+
75
+ if (index < start) {
76
+ // Scrolling up - position item at top with some buffer
77
+ targetScrollTop = (index - this.overscan) * this.itemHeight;
78
+ } else {
79
+ // Scrolling down - position item at bottom with some buffer
80
+ const visibleItems = Math.floor(this.#containerSize.height / this.itemHeight);
81
+ targetScrollTop = (index - visibleItems + 1 + this.overscan) * this.itemHeight;
82
+ }
83
+
84
+ const maxScrollTop = this.totalHeight - this.#containerSize.height;
85
+ this.#scrollTop = Math.max(0, Math.min(targetScrollTop, maxScrollTop));
86
+
87
+ // Update the actual scroll container
88
+ if (this.#containerEl) {
89
+ this.#containerEl.scrollTop = this.#scrollTop;
90
+ }
91
+ }
92
+
93
+ #attachmentKey = createAttachmentKey();
94
+ get container() {
95
+ return {
96
+ onscroll: e => {
97
+ this.scrollTop = e.currentTarget.scrollTop;
98
+ },
99
+ [this.#attachmentKey]: node => {
100
+ this.#containerEl = node;
101
+ return () => {
102
+ this.#containerEl = undefined;
103
+ };
104
+ },
105
+ } as const satisfies HTMLAttributes<HTMLElement>;
106
+ }
107
+ }
src/lib/state/conversations.svelte.ts CHANGED
@@ -4,10 +4,10 @@ import {
4
  } from "$lib/components/inference-playground/generation-config-settings.js";
5
  import { addToast } from "$lib/components/toaster.svelte.js";
6
  import { AbortManager } from "$lib/spells/abort-manager.svelte";
7
- import { PipelineTag, Provider, type ConversationMessage, type GenerationStatistics, type Model } from "$lib/types.js";
8
  import { handleNonStreamingResponse, handleStreamingResponse, estimateTokens } from "$lib/utils/business.svelte.js";
9
  import { omit, snapshot } from "$lib/utils/object.svelte";
10
- import { models, structuredForbiddenProviders } from "./models.svelte";
11
  import { pricing } from "./pricing.svelte.js";
12
  import { DEFAULT_PROJECT_ID, ProjectEntity, projects } from "./projects.svelte";
13
  import { token } from "./token.svelte";
@@ -107,9 +107,7 @@ export class ConversationClass {
107
  }
108
 
109
  get isStructuredOutputAllowed() {
110
- const forbiddenProvider =
111
- this.data.provider && structuredForbiddenProviders.includes(this.data.provider as Provider);
112
- return !forbiddenProvider;
113
  }
114
 
115
  get isStructuredOutputEnabled() {
@@ -285,7 +283,19 @@ class Conversations {
285
 
286
  #active = $derived.by(() => this.for(projects.activeId));
287
 
288
- init = createInit(() => {
 
 
 
 
 
 
 
 
 
 
 
 
289
  const searchParams = new URLSearchParams(window.location.search);
290
  const searchProvider = searchParams.get("provider") ?? "";
291
  const searchModelId = searchParams.get("modelId") ?? "";
@@ -293,7 +303,7 @@ class Conversations {
293
  const searchModel = models.remote.find(m => m.id === searchModelId);
294
  if (!searchModel) return;
295
 
296
- conversationsRepo
297
  .upsert({
298
  where: { projectId: DEFAULT_PROJECT_ID },
299
  set: {
@@ -304,6 +314,8 @@ class Conversations {
304
  .then(res => {
305
  this.#conversations = { ...this.#conversations, [DEFAULT_PROJECT_ID]: [new ConversationClass(res)] };
306
  });
 
 
307
  });
308
 
309
  get conversations() {
@@ -338,17 +350,6 @@ class Conversations {
338
  };
339
 
340
  for = (projectId: ProjectEntity["id"]): ConversationClass[] => {
341
- // Async load from db
342
- if (!this.#conversations[projectId]?.length) {
343
- conversationsRepo.find({ where: { projectId } }).then(c => {
344
- if (!c.length) {
345
- const dc = conversationsRepo.create(getDefaultConversation(projectId));
346
- c.push(dc);
347
- }
348
- this.#conversations = { ...this.#conversations, [projectId]: c.map(c => new ConversationClass(c)) };
349
- });
350
- }
351
-
352
  let res = this.#conversations[projectId];
353
  if (res?.length === 0 || !res) {
354
  // We set id to -1 because it is temporary, there should always be a conversation.
 
4
  } from "$lib/components/inference-playground/generation-config-settings.js";
5
  import { addToast } from "$lib/components/toaster.svelte.js";
6
  import { AbortManager } from "$lib/spells/abort-manager.svelte";
7
+ import { PipelineTag, type ConversationMessage, type GenerationStatistics, type Model } from "$lib/types.js";
8
  import { handleNonStreamingResponse, handleStreamingResponse, estimateTokens } from "$lib/utils/business.svelte.js";
9
  import { omit, snapshot } from "$lib/utils/object.svelte";
10
+ import { models } from "./models.svelte";
11
  import { pricing } from "./pricing.svelte.js";
12
  import { DEFAULT_PROJECT_ID, ProjectEntity, projects } from "./projects.svelte";
13
  import { token } from "./token.svelte";
 
107
  }
108
 
109
  get isStructuredOutputAllowed() {
110
+ return models.supportsStructuredOutput(this.model, this.data.provider);
 
 
111
  }
112
 
113
  get isStructuredOutputEnabled() {
 
283
 
284
  #active = $derived.by(() => this.for(projects.activeId));
285
 
286
+ init = createInit(async () => {
287
+ // Load all conversations from all projects
288
+ await Promise.all(
289
+ projects.all.map(async p => {
290
+ const c = await conversationsRepo.find({ where: { projectId: p.id } });
291
+ if (!c.length) {
292
+ const dc = conversationsRepo.create(getDefaultConversation(p.id));
293
+ c.push(dc);
294
+ }
295
+ this.#conversations = { ...this.#conversations, [p.id]: c.map(c => new ConversationClass(c)) };
296
+ }),
297
+ );
298
+
299
  const searchParams = new URLSearchParams(window.location.search);
300
  const searchProvider = searchParams.get("provider") ?? "";
301
  const searchModelId = searchParams.get("modelId") ?? "";
 
303
  const searchModel = models.remote.find(m => m.id === searchModelId);
304
  if (!searchModel) return;
305
 
306
+ await conversationsRepo
307
  .upsert({
308
  where: { projectId: DEFAULT_PROJECT_ID },
309
  set: {
 
314
  .then(res => {
315
  this.#conversations = { ...this.#conversations, [DEFAULT_PROJECT_ID]: [new ConversationClass(res)] };
316
  });
317
+
318
+ projects.activeId = DEFAULT_PROJECT_ID;
319
  });
320
 
321
  get conversations() {
 
350
  };
351
 
352
  for = (projectId: ProjectEntity["id"]): ConversationClass[] => {
 
 
 
 
 
 
 
 
 
 
 
353
  let res = this.#conversations[projectId];
354
  if (res?.length === 0 || !res) {
355
  // We set id to -1 because it is temporary, there should always be a conversation.
src/lib/state/mcps.svelte.ts ADDED
@@ -0,0 +1,86 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { idb } from "$lib/remult.js";
2
+ import { dequal } from "dequal";
3
+ import { Entity, Fields, repo, type MembersOnly } from "remult";
4
+ import { projects } from "./projects.svelte";
5
+
6
+ export type MCPProtocol = "sse" | "http";
7
+
8
+ export interface MCPServer {
9
+ id: string;
10
+ name: string;
11
+ url: string;
12
+ protocol: MCPProtocol;
13
+ headers?: Record<string, string>;
14
+ }
15
+
16
+ @Entity("mcp_server")
17
+ export class MCPServerEntity {
18
+ @Fields.cuid()
19
+ id!: string;
20
+
21
+ @Fields.string()
22
+ name!: string;
23
+
24
+ @Fields.string()
25
+ url!: string;
26
+
27
+ @Fields.string()
28
+ protocol: MCPProtocol = "sse";
29
+
30
+ @Fields.json()
31
+ headers?: Record<string, string>;
32
+ }
33
+
34
+ export type MCPServerEntityMembers = MembersOnly<MCPServerEntity>;
35
+
36
+ export type MCPFormData = {
37
+ name: string;
38
+ url: string;
39
+ protocol: MCPProtocol;
40
+ headers: Record<string, string>;
41
+ };
42
+
43
+ const mcpServersRepo = repo(MCPServerEntity, idb);
44
+
45
+ class MCPServers {
46
+ #servers: Record<MCPServerEntity["id"], MCPServerEntity> = $state({});
47
+
48
+ constructor() {
49
+ mcpServersRepo.find().then(res => {
50
+ res.forEach(server => {
51
+ if (dequal(this.#servers[server.id], server)) return;
52
+ this.#servers[server.id] = server;
53
+ });
54
+ });
55
+ }
56
+
57
+ async create(args: Omit<MCPServerEntity, "id">): Promise<string> {
58
+ const server = await mcpServersRepo.save({ ...args });
59
+ this.#servers[server.id] = server;
60
+ return server.id;
61
+ }
62
+
63
+ get all() {
64
+ return Object.values(this.#servers);
65
+ }
66
+
67
+ get enabled() {
68
+ const currentProject = projects.current;
69
+ if (!currentProject) return [];
70
+ return this.all.filter(server => currentProject.enabledMCPs?.includes(server.id));
71
+ }
72
+
73
+ async update(data: MCPServerEntity) {
74
+ if (!data.id) return;
75
+ await mcpServersRepo.upsert({ where: { id: data.id }, set: data });
76
+ this.#servers[data.id] = { ...data };
77
+ }
78
+
79
+ async delete(id: string) {
80
+ if (!id) return;
81
+ await mcpServersRepo.delete(id);
82
+ delete this.#servers[id];
83
+ }
84
+ }
85
+
86
+ export const mcpServers = new MCPServers();
src/lib/state/models.svelte.ts CHANGED
@@ -1,26 +1,19 @@
1
- import { page } from "$app/state";
2
- import { Provider, type CustomModel } from "$lib/types.js";
3
  import { edit, randomPick } from "$lib/utils/array.js";
4
  import { safeParse } from "$lib/utils/json.js";
5
  import typia from "typia";
6
- import type { PageData } from "../../routes/$types.js";
7
  import { conversations } from "./conversations.svelte";
 
8
 
9
  const LOCAL_STORAGE_KEY = "hf_inference_playground_custom_models";
10
 
11
- const pageData = $derived(page.data as PageData);
12
-
13
- export const structuredForbiddenProviders: Provider[] = [
14
- Provider.Hyperbolic,
15
- Provider.Nebius,
16
- Provider.Novita,
17
- Provider.Sambanova,
18
- ];
19
 
20
  class Models {
21
- remote = $derived(pageData.models);
22
- trending = $derived(this.remote.toSorted((a, b) => b.trendingScore - a.trendingScore).slice(0, 5));
23
- nonTrending = $derived(this.remote.filter(m => !this.trending.includes(m)));
 
24
  all = $derived([...this.remote, ...this.custom]);
25
 
26
  constructor() {
@@ -36,6 +29,13 @@ class Models {
36
  }
37
  }
38
 
 
 
 
 
 
 
 
39
  #custom = $state.raw<CustomModel[]>([]);
40
 
41
  get custom() {
@@ -74,6 +74,14 @@ class Models {
74
  c.update({ modelId: randomPick(models.trending)?.id });
75
  });
76
  }
 
 
 
 
 
 
 
 
77
  }
78
 
79
  export const models = new Models();
 
1
+ import { type CustomModel, type Model } from "$lib/types.js";
 
2
  import { edit, randomPick } from "$lib/utils/array.js";
3
  import { safeParse } from "$lib/utils/json.js";
4
  import typia from "typia";
 
5
  import { conversations } from "./conversations.svelte";
6
+ import { getModels, getRouterData, type RouterData } from "$lib/remote/models.remote";
7
 
8
  const LOCAL_STORAGE_KEY = "hf_inference_playground_custom_models";
9
 
10
+ const trendingSort = (a: Model, b: Model) => b.trendingScore - a.trendingScore;
 
 
 
 
 
 
 
11
 
12
  class Models {
13
+ routerData = $state<RouterData>();
14
+ remote: Model[] = $state([]);
15
+ trending = $derived(this.remote.toSorted(trendingSort).slice(0, 5));
16
+ nonTrending = $derived(this.remote.filter(m => !this.trending.includes(m)).toSorted(trendingSort));
17
  all = $derived([...this.remote, ...this.custom]);
18
 
19
  constructor() {
 
29
  }
30
  }
31
 
32
+ async load() {
33
+ await Promise.all([getModels(), getRouterData()]).then(([models, data]) => {
34
+ this.remote = models;
35
+ this.routerData = data;
36
+ });
37
+ }
38
+
39
  #custom = $state.raw<CustomModel[]>([]);
40
 
41
  get custom() {
 
74
  c.update({ modelId: randomPick(models.trending)?.id });
75
  });
76
  }
77
+
78
+ supportsStructuredOutput(model: Model | CustomModel, provider?: string) {
79
+ if (!this.routerData) return false;
80
+ if (typia.is<CustomModel>(model)) return true;
81
+ const routerDataEntry = this.routerData?.data.find(d => d.id === model.id);
82
+ if (!routerDataEntry) return false;
83
+ return routerDataEntry.providers.find(p => p.provider === provider)?.supports_structured_output ?? false;
84
+ }
85
  }
86
 
87
  export const models = new Models();
src/lib/state/pricing.svelte.ts CHANGED
@@ -1,6 +1,5 @@
1
- import { page } from "$app/state";
2
  import { atLeastNDecimals } from "$lib/utils/number.js";
3
- import type { PageData } from "../../routes/$types.js";
4
 
5
  interface RouterProvider {
6
  provider: string;
@@ -19,17 +18,9 @@ interface RouterModel {
19
  providers: RouterProvider[];
20
  }
21
 
22
- interface RouterData {
23
- data: RouterModel[];
24
- }
25
-
26
- const pageData = $derived(page.data as PageData & { routerData: RouterData });
27
-
28
  class Pricing {
29
- routerData = $derived(pageData.routerData as RouterData);
30
-
31
  getPricing(modelId: string, provider: string) {
32
- const model = this.routerData?.data?.find((m: RouterModel) => m.id === modelId);
33
  if (!model) return null;
34
 
35
  const providerData = model.providers.find((p: RouterProvider) => p.provider === provider);
@@ -37,7 +28,7 @@ class Pricing {
37
  }
38
 
39
  getContextLength(modelId: string, provider: string) {
40
- const model = this.routerData?.data?.find((m: RouterModel) => m.id === modelId);
41
  if (!model) return null;
42
 
43
  const providerData = model.providers.find((p: RouterProvider) => p.provider === provider);
 
 
1
  import { atLeastNDecimals } from "$lib/utils/number.js";
2
+ import { models } from "./models.svelte.js";
3
 
4
  interface RouterProvider {
5
  provider: string;
 
18
  providers: RouterProvider[];
19
  }
20
 
 
 
 
 
 
 
21
  class Pricing {
 
 
22
  getPricing(modelId: string, provider: string) {
23
+ const model = models.routerData?.data?.find((m: RouterModel) => m.id === modelId);
24
  if (!model) return null;
25
 
26
  const providerData = model.providers.find((p: RouterProvider) => p.provider === provider);
 
28
  }
29
 
30
  getContextLength(modelId: string, provider: string) {
31
+ const model = models.routerData?.data?.find((m: RouterModel) => m.id === modelId);
32
  if (!model) return null;
33
 
34
  const providerData = model.providers.find((p: RouterProvider) => p.provider === provider);
src/lib/state/projects.svelte.ts CHANGED
@@ -4,6 +4,7 @@ import { Entity, Fields, repo, type MembersOnly } from "remult";
4
  import { PersistedState } from "runed";
5
  import { checkpoints } from "./checkpoints.svelte";
6
  import { conversations } from "./conversations.svelte";
 
7
 
8
  @Entity("project")
9
  export class ProjectEntity {
@@ -16,6 +17,9 @@ export class ProjectEntity {
16
  @Fields.string()
17
  systemMessage?: string;
18
 
 
 
 
19
  @Fields.string()
20
  branchedFromId?: string | null;
21
 
@@ -43,16 +47,15 @@ class Projects {
43
  this.#activeId.current = id;
44
  }
45
 
46
- constructor() {
47
- projectsRepo.find().then(res => {
48
- if (!res.some(p => p.id === this.activeId)) this.activeId === DEFAULT_PROJECT_ID;
49
 
50
- res.forEach(p => {
51
- if (dequal(this.#projects[p.id], p)) return;
52
- this.#projects[p.id] = p;
53
- });
54
  });
55
- }
56
 
57
  async create(args: Omit<ProjectEntity, "id">): Promise<string> {
58
  const p = await projectsRepo.save({ ...args });
 
4
  import { PersistedState } from "runed";
5
  import { checkpoints } from "./checkpoints.svelte";
6
  import { conversations } from "./conversations.svelte";
7
+ import { createInit } from "$lib/spells/create-init.svelte";
8
 
9
  @Entity("project")
10
  export class ProjectEntity {
 
17
  @Fields.string()
18
  systemMessage?: string;
19
 
20
+ @Fields.json()
21
+ enabledMCPs?: string[];
22
+
23
  @Fields.string()
24
  branchedFromId?: string | null;
25
 
 
47
  this.#activeId.current = id;
48
  }
49
 
50
+ init = createInit(async () => {
51
+ const res = await projectsRepo.find();
52
+ if (!res.some(p => p.id === this.activeId)) this.activeId === DEFAULT_PROJECT_ID;
53
 
54
+ res.forEach(p => {
55
+ if (dequal(this.#projects[p.id], p)) return;
56
+ this.#projects[p.id] = p;
 
57
  });
58
+ });
59
 
60
  async create(args: Omit<ProjectEntity, "id">): Promise<string> {
61
  const p = await projectsRepo.save({ ...args });
src/lib/utils/business.svelte.ts CHANGED
@@ -6,11 +6,12 @@
6
  *
7
  **/
8
 
 
9
  import { pricing } from "$lib/state/pricing.svelte.js";
10
- import { InferenceClient, snippets } from "@huggingface/inference";
11
  import { ConversationClass, type ConversationEntityMembers } from "$lib/state/conversations.svelte";
12
  import { token } from "$lib/state/token.svelte";
13
- import { billing } from "$lib/state/billing.svelte";
14
  import {
15
  isCustomModel,
16
  isHFModel,
@@ -25,11 +26,12 @@ import { omit } from "$lib/utils/object.svelte.js";
25
  import type { ChatCompletionInputMessage, InferenceSnippet } from "@huggingface/tasks";
26
  import { type ChatCompletionOutputMessage } from "@huggingface/tasks";
27
  import { AutoTokenizer, PreTrainedTokenizer } from "@huggingface/transformers";
28
- import OpenAI from "openai";
29
  import { images } from "$lib/state/images.svelte.js";
30
  import { projects } from "$lib/state/projects.svelte.js";
31
- import { structuredForbiddenProviders } from "$lib/state/models.svelte.js";
32
  import { modifySnippet } from "$lib/utils/snippets.js";
 
 
33
 
34
  type ChatCompletionInputMessageChunk =
35
  NonNullable<ChatCompletionInputMessage["content"]> extends string | (infer U)[] ? U : never;
@@ -56,20 +58,6 @@ async function parseMessage(message: ConversationMessage): Promise<ChatCompletio
56
  };
57
  }
58
 
59
- type HFCompletionMetadata = {
60
- type: "huggingface";
61
- client: InferenceClient;
62
- args: Parameters<InferenceClient["chatCompletion"]>[0];
63
- };
64
-
65
- type OpenAICompletionMetadata = {
66
- type: "openai";
67
- client: OpenAI;
68
- args: OpenAI.ChatCompletionCreateParams;
69
- };
70
-
71
- type CompletionMetadata = HFCompletionMetadata | OpenAICompletionMetadata;
72
-
73
  export function maxAllowedTokens(conversation: ConversationClass) {
74
  const model = conversation.model;
75
  const { provider } = conversation.data;
@@ -78,18 +66,35 @@ export function maxAllowedTokens(conversation: ConversationClass) {
78
  return customMaxTokens[conversation.model.id] ?? 100000;
79
  }
80
 
81
- // Try to get context length from router data
82
  const ctxLength = pricing.getContextLength(model.id, provider);
 
 
 
 
 
 
 
 
 
 
 
 
 
83
 
84
- if (!ctxLength) return customMaxTokens[conversation.model.id] ?? 100000;
85
- return ctxLength;
 
 
 
 
 
86
  }
87
 
88
  function getResponseFormatObj(conversation: ConversationClass | Conversation) {
89
  const data = conversation instanceof ConversationClass ? conversation.data : conversation;
90
  const json = safeParse(data.structuredOutput?.schema ?? "");
91
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
92
- if (json && data.structuredOutput?.enabled && !structuredForbiddenProviders.includes(data.provider as any)) {
93
  switch (data.provider) {
94
  case "cohere": {
95
  return {
@@ -113,10 +118,11 @@ function getResponseFormatObj(conversation: ConversationClass | Conversation) {
113
  }
114
  }
115
 
116
- async function getCompletionMetadata(
117
  conversation: ConversationClass | Conversation,
118
- signal?: AbortSignal,
119
- ): Promise<CompletionMetadata> {
 
120
  const data = conversation instanceof ConversationClass ? conversation.data : conversation;
121
  const model = conversation.model;
122
  const systemMessage = projects.current?.systemMessage;
@@ -127,98 +133,38 @@ async function getCompletionMetadata(
127
  ];
128
  const parsed = await Promise.all(messages.map(parseMessage));
129
 
130
- const extraParams = data.extraParams
131
- ? Object.fromEntries(
132
- Object.entries(data.extraParams).map(([key, value]) => {
133
- try {
134
- return [key, JSON.parse(value as string)];
135
- } catch {
136
- return [key, value];
137
- }
138
- }),
139
- )
140
- : {};
141
-
142
- const baseArgs = {
143
- ...data.config,
144
- ...extraParams,
145
  messages: parsed,
146
- model: model.id,
147
- response_format: getResponseFormatObj(conversation),
148
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
149
- } as any;
150
-
151
- // Handle OpenAI-compatible models
152
- if (isCustomModel(model)) {
153
- const openai = new OpenAI({
154
- apiKey: model.accessToken,
155
- baseURL: model.endpointUrl,
156
- dangerouslyAllowBrowser: true,
157
- fetch: (...args: Parameters<typeof fetch>) => {
158
- return fetch(args[0], { ...args[1], signal });
159
- },
160
- });
161
-
162
- const args = {
163
- ...baseArgs,
164
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
165
- } as any;
166
-
167
- return {
168
- type: "openai",
169
- client: openai,
170
- args,
171
- };
172
- }
173
- const args = {
174
- ...baseArgs,
175
  provider: data.provider,
176
- // max_tokens: maxAllowedTokens(conversation) - currTokens,
177
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
178
- } as any;
179
-
180
- // Handle HuggingFace models
181
- const clientOptions: ConstructorParameters<typeof InferenceClient>[1] = {};
182
- if (billing.organization) {
183
- clientOptions.billTo = billing.organization;
184
- }
185
-
186
- return {
187
- type: "huggingface",
188
- client: new InferenceClient(token.value, clientOptions),
189
- args,
190
  };
191
- }
192
 
193
- export async function handleStreamingResponse(
194
- conversation: ConversationClass | Conversation,
195
- onChunk: (content: string) => void,
196
- abortController: AbortController,
197
- ): Promise<void> {
198
- const metadata = await getCompletionMetadata(conversation, abortController.signal);
199
-
200
- if (metadata.type === "openai") {
201
- const stream = await metadata.client.chat.completions.create({
202
- ...metadata.args,
203
- stream: true,
204
- } as OpenAI.ChatCompletionCreateParamsStreaming);
205
-
206
- let out = "";
207
- for await (const chunk of stream) {
208
- if (chunk.choices[0]?.delta?.content) {
209
- out += chunk.choices[0].delta.content;
210
- onChunk(out);
211
- }
212
- }
213
- return;
214
- }
215
 
216
- // HuggingFace streaming
217
  let out = "";
218
- for await (const chunk of metadata.client.chatCompletionStream(metadata.args, { signal: abortController.signal })) {
219
- if (chunk.choices && chunk.choices.length > 0 && chunk.choices[0]?.delta?.content) {
220
- out += chunk.choices[0].delta.content;
221
  onChunk(out);
 
 
222
  }
223
  }
224
  }
@@ -226,34 +172,46 @@ export async function handleStreamingResponse(
226
  export async function handleNonStreamingResponse(
227
  conversation: ConversationClass | Conversation,
228
  ): Promise<{ message: ChatCompletionOutputMessage; completion_tokens: number }> {
229
- const metadata = await getCompletionMetadata(conversation);
230
-
231
- if (metadata.type === "openai") {
232
- const response = await metadata.client.chat.completions.create({
233
- ...metadata.args,
234
- stream: false,
235
- } as OpenAI.ChatCompletionCreateParamsNonStreaming);
236
-
237
- if (response.choices && response.choices.length > 0 && response.choices[0]?.message) {
238
- return {
239
- message: {
240
- role: "assistant",
241
- content: response.choices[0].message.content || "",
242
- },
243
- completion_tokens: response.usage?.completion_tokens || 0,
244
- };
245
- }
246
- throw new Error("No response from the model");
247
- }
248
 
249
- // HuggingFace non-streaming
250
- const response = await metadata.client.chatCompletion(metadata.args);
251
- if (response.choices && response.choices.length > 0) {
252
- const { message } = response.choices[0]!;
253
- const { completion_tokens } = response.usage;
254
- return { message, completion_tokens };
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
255
  }
256
- throw new Error("No response from the model");
 
257
  }
258
 
259
  export function isSystemPromptSupported(model: Model | CustomModel) {
@@ -366,7 +324,7 @@ export function getInferenceSnippet(
366
  if (
367
  opts?.structured_output?.schema &&
368
  opts.structured_output.enabled &&
369
- !structuredForbiddenProviders.includes(provider as Provider)
370
  ) {
371
  return {
372
  ...s,
 
6
  *
7
  **/
8
 
9
+ import ctxLengthData from "$lib/data/context_length.json";
10
  import { pricing } from "$lib/state/pricing.svelte.js";
11
+ import { snippets } from "@huggingface/inference";
12
  import { ConversationClass, type ConversationEntityMembers } from "$lib/state/conversations.svelte";
13
  import { token } from "$lib/state/token.svelte";
14
+ import { isMcpEnabled } from "$lib/constants.js";
15
  import {
16
  isCustomModel,
17
  isHFModel,
 
26
  import type { ChatCompletionInputMessage, InferenceSnippet } from "@huggingface/tasks";
27
  import { type ChatCompletionOutputMessage } from "@huggingface/tasks";
28
  import { AutoTokenizer, PreTrainedTokenizer } from "@huggingface/transformers";
 
29
  import { images } from "$lib/state/images.svelte.js";
30
  import { projects } from "$lib/state/projects.svelte.js";
31
+ import { mcpServers } from "$lib/state/mcps.svelte.js";
32
  import { modifySnippet } from "$lib/utils/snippets.js";
33
+ import { models } from "$lib/state/models.svelte";
34
+ import { StreamReader } from "$lib/utils/stream.js";
35
 
36
  type ChatCompletionInputMessageChunk =
37
  NonNullable<ChatCompletionInputMessage["content"]> extends string | (infer U)[] ? U : never;
 
58
  };
59
  }
60
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
61
  export function maxAllowedTokens(conversation: ConversationClass) {
62
  const model = conversation.model;
63
  const { provider } = conversation.data;
 
66
  return customMaxTokens[conversation.model.id] ?? 100000;
67
  }
68
 
69
+ // Try to get context length from pricing/router data first
70
  const ctxLength = pricing.getContextLength(model.id, provider);
71
+ if (ctxLength) return ctxLength;
72
+
73
+ // Fall back to local context length data if available
74
+ const providerData = ctxLengthData[provider as keyof typeof ctxLengthData] as Record<string, number> | undefined;
75
+ const localCtxLength = providerData?.[model.id];
76
+ if (localCtxLength) return localCtxLength;
77
+
78
+ // Final fallback to custom max tokens
79
+ return customMaxTokens[conversation.model.id] ?? 100000;
80
+ }
81
+
82
+ function getEnabledMCPs() {
83
+ if (!isMcpEnabled()) return [];
84
 
85
+ return mcpServers.enabled.map(server => ({
86
+ id: server.id,
87
+ name: server.name,
88
+ url: server.url,
89
+ protocol: server.protocol,
90
+ headers: server.headers,
91
+ }));
92
  }
93
 
94
  function getResponseFormatObj(conversation: ConversationClass | Conversation) {
95
  const data = conversation instanceof ConversationClass ? conversation.data : conversation;
96
  const json = safeParse(data.structuredOutput?.schema ?? "");
97
+ if (json && data.structuredOutput?.enabled && models.supportsStructuredOutput(conversation.model, data.provider)) {
 
98
  switch (data.provider) {
99
  case "cohere": {
100
  return {
 
118
  }
119
  }
120
 
121
+ export async function handleStreamingResponse(
122
  conversation: ConversationClass | Conversation,
123
+ onChunk: (content: string) => void,
124
+ abortController: AbortController,
125
+ ): Promise<void> {
126
  const data = conversation instanceof ConversationClass ? conversation.data : conversation;
127
  const model = conversation.model;
128
  const systemMessage = projects.current?.systemMessage;
 
133
  ];
134
  const parsed = await Promise.all(messages.map(parseMessage));
135
 
136
+ const requestBody = {
137
+ model: {
138
+ id: model.id,
139
+ isCustom: isCustomModel(model),
140
+ accessToken: isCustomModel(model) ? model.accessToken : undefined,
141
+ endpointUrl: isCustomModel(model) ? model.endpointUrl : undefined,
142
+ },
 
 
 
 
 
 
 
 
143
  messages: parsed,
144
+ config: data.config,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
145
  provider: data.provider,
146
+ streaming: true,
147
+ response_format: getResponseFormatObj(conversation),
148
+ accessToken: token.value,
149
+ enabledMCPs: getEnabledMCPs(),
 
 
 
 
 
 
 
 
 
 
150
  };
 
151
 
152
+ const reader = await StreamReader.fromFetch("/api/generate", {
153
+ method: "POST",
154
+ headers: {
155
+ "Content-Type": "application/json",
156
+ },
157
+ body: JSON.stringify(requestBody),
158
+ signal: abortController.signal,
159
+ });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
160
 
 
161
  let out = "";
162
+ for await (const chunk of reader.read()) {
163
+ if (chunk.type === "chunk" && chunk.content) {
164
+ out += chunk.content;
165
  onChunk(out);
166
+ } else if (chunk.type === "error") {
167
+ throw new Error(chunk.error || "Stream error");
168
  }
169
  }
170
  }
 
172
  export async function handleNonStreamingResponse(
173
  conversation: ConversationClass | Conversation,
174
  ): Promise<{ message: ChatCompletionOutputMessage; completion_tokens: number }> {
175
+ const data = conversation instanceof ConversationClass ? conversation.data : conversation;
176
+ const model = conversation.model;
177
+ const systemMessage = projects.current?.systemMessage;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
178
 
179
+ const messages: ConversationMessage[] = [
180
+ ...(isSystemPromptSupported(model) && systemMessage?.length ? [{ role: "system", content: systemMessage }] : []),
181
+ ...(data.messages || []),
182
+ ];
183
+ const parsed = await Promise.all(messages.map(parseMessage));
184
+
185
+ const requestBody = {
186
+ model: {
187
+ id: model.id,
188
+ isCustom: isCustomModel(model),
189
+ accessToken: isCustomModel(model) ? model.accessToken : undefined,
190
+ endpointUrl: isCustomModel(model) ? model.endpointUrl : undefined,
191
+ },
192
+ messages: parsed,
193
+ config: data.config,
194
+ provider: data.provider,
195
+ streaming: false,
196
+ response_format: getResponseFormatObj(conversation),
197
+ accessToken: token.value,
198
+ enabledMCPs: getEnabledMCPs(),
199
+ };
200
+
201
+ const response = await fetch("/api/generate", {
202
+ method: "POST",
203
+ headers: {
204
+ "Content-Type": "application/json",
205
+ },
206
+ body: JSON.stringify(requestBody),
207
+ });
208
+
209
+ if (!response.ok) {
210
+ const error = await response.json();
211
+ throw new Error(error.error || "Failed to generate response");
212
  }
213
+
214
+ return await response.json();
215
  }
216
 
217
  export function isSystemPromptSupported(model: Model | CustomModel) {
 
324
  if (
325
  opts?.structured_output?.schema &&
326
  opts.structured_output.enabled &&
327
+ models.supportsStructuredOutput(conversation.model, provider)
328
  ) {
329
  return {
330
  ...s,
src/lib/utils/cache.ts ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ type WithCacheOptions = {
2
+ // Lifespan of the cache in milliseconds
3
+ // @default 10 minutes
4
+ lifespan?: number;
5
+ };
6
+
7
+ export function withCache<Args extends unknown[], Return>(
8
+ fn: (...args: Args) => Return,
9
+ options?: WithCacheOptions,
10
+ ): (...args: Args) => Return {
11
+ const { lifespan = 1000 * 60 * 10 } = options ?? {};
12
+
13
+ const cache = new Map<string, Return>();
14
+
15
+ return (...args: Args) => {
16
+ const key = JSON.stringify(args);
17
+ if (cache.has(key)) {
18
+ return cache.get(key) as Return;
19
+ }
20
+
21
+ const value = fn(...args);
22
+ cache.set(key, value);
23
+ setTimeout(() => {
24
+ cache.delete(key);
25
+ }, lifespan);
26
+
27
+ return value;
28
+ };
29
+ }
src/lib/utils/debug.ts ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ const DEBUG_LOG = true;
2
+
3
+ export const debugLog = (...args: unknown[]) => {
4
+ if (!DEBUG_LOG) return;
5
+ console.log("[LOG DEBUG]", ...args);
6
+ };
7
+
8
+ export const debugError = (...args: unknown[]) => {
9
+ if (!DEBUG_LOG) return;
10
+ console.error("[LOG DEBUG]", ...args);
11
+ };
src/lib/utils/stream.ts ADDED
@@ -0,0 +1,144 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ export interface StreamChunk {
2
+ type: "chunk" | "done" | "error";
3
+ content?: string;
4
+ error?: string;
5
+ }
6
+
7
+ export class StreamReader {
8
+ private decoder = new TextDecoder();
9
+ private buffer = "";
10
+
11
+ constructor(private response: Response) {
12
+ if (!response.body) {
13
+ throw new Error("Response has no body");
14
+ }
15
+ }
16
+
17
+ async *read(): AsyncGenerator<StreamChunk, void, unknown> {
18
+ const reader = this.response.body!.getReader();
19
+
20
+ try {
21
+ while (true) {
22
+ const { done, value } = await reader.read();
23
+ if (done) break;
24
+
25
+ this.buffer += this.decoder.decode(value, { stream: true });
26
+ const lines = this.buffer.split("\n");
27
+ this.buffer = lines.pop() || "";
28
+
29
+ for (const line of lines) {
30
+ if (line.startsWith("data: ")) {
31
+ const data = line.slice(6).trim();
32
+ if (!data) continue;
33
+
34
+ try {
35
+ const parsed = JSON.parse(data) as StreamChunk;
36
+ yield parsed;
37
+ if (parsed.type === "done") return;
38
+ } catch {
39
+ // Ignore malformed JSON
40
+ }
41
+ }
42
+ }
43
+ }
44
+ } finally {
45
+ reader.releaseLock();
46
+ }
47
+ }
48
+
49
+ static async fromFetch(url: string, options?: RequestInit): Promise<StreamReader> {
50
+ const response = await fetch(url, options);
51
+ if (!response.ok) {
52
+ const error = await response.json();
53
+ throw new Error(error.error || "Request failed");
54
+ }
55
+ return new StreamReader(response);
56
+ }
57
+ }
58
+
59
+ export class StreamWriter {
60
+ private encoder = new TextEncoder();
61
+ private controller?: ReadableStreamDefaultController<Uint8Array>;
62
+ public readonly stream: ReadableStream<Uint8Array>;
63
+
64
+ constructor() {
65
+ this.stream = new ReadableStream({
66
+ start: controller => {
67
+ this.controller = controller;
68
+ },
69
+ });
70
+ }
71
+
72
+ write(chunk: StreamChunk): void {
73
+ if (!this.controller) {
74
+ return;
75
+ }
76
+
77
+ try {
78
+ const data = JSON.stringify(chunk);
79
+ this.controller.enqueue(this.encoder.encode(`data: ${data}\n\n`));
80
+ } catch {
81
+ // Controller might be closed
82
+ }
83
+ }
84
+
85
+ writeChunk(content: string): void {
86
+ this.write({ type: "chunk", content });
87
+ }
88
+
89
+ writeError(error: string): void {
90
+ this.write({ type: "error", error });
91
+ }
92
+
93
+ end(): void {
94
+ if (!this.controller) return;
95
+ try {
96
+ this.write({ type: "done" });
97
+ this.controller.close();
98
+ } catch {
99
+ // Controller might already be closed
100
+ }
101
+ this.controller = undefined;
102
+ }
103
+
104
+ error(error: Error): void {
105
+ if (!this.controller) return;
106
+ try {
107
+ this.writeError(error.message);
108
+ this.controller.close();
109
+ } catch {
110
+ // Controller might already be closed
111
+ }
112
+ this.controller = undefined;
113
+ }
114
+
115
+ createResponse(): Response {
116
+ return new Response(this.stream, {
117
+ headers: {
118
+ "Content-Type": "text/event-stream",
119
+ "Cache-Control": "no-cache",
120
+ "Connection": "keep-alive",
121
+ },
122
+ });
123
+ }
124
+ }
125
+
126
+ export async function streamFromAsyncIterable<T>(
127
+ iterable: AsyncIterable<T>,
128
+ transform: (item: T) => StreamChunk,
129
+ ): Promise<ReadableStream<Uint8Array>> {
130
+ const writer = new StreamWriter();
131
+
132
+ (async () => {
133
+ try {
134
+ for await (const item of iterable) {
135
+ writer.write(transform(item));
136
+ }
137
+ writer.end();
138
+ } catch (error) {
139
+ writer.error(error instanceof Error ? error : new Error(String(error)));
140
+ }
141
+ })();
142
+
143
+ return writer.stream;
144
+ }
src/lib/utils/styles.ts ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ import { type ClassValue, clsx } from "clsx";
2
+ import { twMerge } from "tailwind-merge";
3
+
4
+ export function classes(...inputs: ClassValue[]) {
5
+ return twMerge(clsx(inputs));
6
+ }
src/lib/utils/url.spec.ts ADDED
@@ -0,0 +1,59 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { describe, expect, it } from "vitest";
2
+ import { extractDomain } from "./url.js";
3
+
4
+ describe("extractDomain", () => {
5
+ it("should handle regular domains", () => {
6
+ expect(extractDomain("https://example.com")).toBe("example.com");
7
+ });
8
+
9
+ it("should handle single subdomains", () => {
10
+ expect(extractDomain("https://sub.example.com")).toBe("example.com");
11
+ });
12
+
13
+ it("should handle multiple subdomains", () => {
14
+ expect(extractDomain("https://sub1.sub2.example.com")).toBe("example.com");
15
+ expect(extractDomain("https://deep.sub.domain.co.uk")).toBe("domain.co.uk");
16
+ expect(extractDomain("https://a.b.c.d.e.f.g.example.net")).toBe("example.net");
17
+ });
18
+
19
+ it("should handle special TLDs like co.uk", () => {
20
+ expect(extractDomain("https://domain.co.uk")).toBe("domain.co.uk");
21
+ expect(extractDomain("https://sub.domain.co.uk")).toBe("domain.co.uk");
22
+ expect(extractDomain("https://another.domain.com.au")).toBe("domain.com.au");
23
+ });
24
+
25
+ it("should handle localhost", () => {
26
+ expect(extractDomain("http://localhost:3000")).toBe("localhost");
27
+ expect(extractDomain("http://localhost")).toBe("localhost");
28
+ });
29
+
30
+ it("should handle non-HTTP/HTTPS protocols", () => {
31
+ expect(extractDomain("ftp://files.example.com")).toBe("example.com");
32
+ expect(extractDomain("ws://websocket.example.com")).toBe("example.com");
33
+ });
34
+
35
+ it("should handle non-string values", () => {
36
+ expect(extractDomain(12345)).toBeNull();
37
+ expect(extractDomain({})).toBeNull();
38
+ expect(extractDomain(["https://example.com"])).toBeNull();
39
+ expect(extractDomain(true)).toBeNull();
40
+ });
41
+
42
+ it("should handle URL instances", () => {
43
+ expect(extractDomain(new URL("https://test.example.com"))).toBe("example.com");
44
+ expect(extractDomain(new URL("https://deeply.nested.subdomain.example.org"))).toBe("example.org");
45
+ });
46
+
47
+ it("should handle invalid URLs gracefully", () => {
48
+ expect(extractDomain("not-a-url")).toBeNull();
49
+ expect(extractDomain("htt:invalid-url")).toBeNull();
50
+ expect(extractDomain("example")).toBeNull();
51
+ expect(extractDomain("http://")).toBeNull();
52
+ });
53
+
54
+ it("should handle tricky but valid URLs", () => {
55
+ expect(extractDomain("https://example.com#hash")).toBe("example.com");
56
+ expect(extractDomain("https://example.com/path")).toBe("example.com");
57
+ expect(extractDomain("https://example.com/path?query=string")).toBe("example.com");
58
+ });
59
+ });
src/lib/utils/url.ts CHANGED
@@ -6,3 +6,43 @@ export function isValidURL(url: string): boolean {
6
  return false;
7
  }
8
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6
  return false;
7
  }
8
  }
9
+
10
+ export const extractDomain = (value: unknown) => {
11
+ const url = toURL(value);
12
+
13
+ if (!url) {
14
+ return null;
15
+ }
16
+
17
+ const hostnameParts = url.hostname.split(".");
18
+
19
+ // Determine typical hostnames like "domain.com" or "domain.org"
20
+ if (hostnameParts.length <= 2) {
21
+ return url.hostname;
22
+ }
23
+
24
+ // Determine two-part TLD if second last part of the hostname matches one of the prefixes
25
+ const prefixes = ["com", "co", "org", "net", "gov", "edu"];
26
+ const potentialTwoPartTLD = `${hostnameParts[hostnameParts.length - 2]}.${hostnameParts[hostnameParts.length - 1]}`;
27
+
28
+ return prefixes.includes(hostnameParts[hostnameParts.length - 2]!)
29
+ ? `${hostnameParts[hostnameParts.length - 3]}.${potentialTwoPartTLD}`
30
+ : hostnameParts.slice(-2).join("."); // Fallback to last two parts of hostname
31
+ };
32
+
33
+ const toURL = (value: unknown) => {
34
+ if (value instanceof URL) {
35
+ return value;
36
+ }
37
+
38
+ if (typeof value !== "string" || !value) {
39
+ return null;
40
+ }
41
+
42
+ try {
43
+ const url = new URL(value);
44
+ return url.hostname ? url : null;
45
+ } catch {
46
+ return null;
47
+ }
48
+ };
src/routes/+layout.svelte CHANGED
@@ -1,4 +1,5 @@
1
  <script lang="ts">
 
2
  import "../app.css";
3
 
4
  interface Props {
@@ -11,6 +12,7 @@
11
  <svelte:boundary>
12
  {@render children?.()}
13
  {#snippet pending()}
14
- <!-- pending -->
 
15
  {/snippet}
16
  </svelte:boundary>
 
1
  <script lang="ts">
2
+ import IconLoadingLoop from "~icons/line-md/loading-loop";
3
  import "../app.css";
4
 
5
  interface Props {
 
12
  <svelte:boundary>
13
  {@render children?.()}
14
  {#snippet pending()}
15
+ <p class="abs-center absolute dark:text-white">🤗</p>
16
+ <IconLoadingLoop class="abs-center absolute text-6xl dark:text-blue-300" />
17
  {/snippet}
18
  </svelte:boundary>
src/routes/+page.svelte CHANGED
@@ -5,10 +5,14 @@
5
  import Prompts from "$lib/components/prompts.svelte";
6
  import QuotaModal from "$lib/components/quota-modal.svelte";
7
  import ShareModal from "$lib/components/share-modal.svelte";
8
- import { conversations } from "$lib/state/conversations.svelte";
9
  import Playground from "$lib/components/inference-playground/playground.svelte";
 
 
 
10
 
11
- conversations.init();
 
 
12
  </script>
13
 
14
  <Playground />
 
5
  import Prompts from "$lib/components/prompts.svelte";
6
  import QuotaModal from "$lib/components/quota-modal.svelte";
7
  import ShareModal from "$lib/components/share-modal.svelte";
 
8
  import Playground from "$lib/components/inference-playground/playground.svelte";
9
+ import { conversations } from "$lib/state/conversations.svelte";
10
+ import { models } from "$lib/state/models.svelte";
11
+ import { projects } from "$lib/state/projects.svelte";
12
 
13
+ await models.load();
14
+ await projects.init();
15
+ await conversations.init();
16
  </script>
17
 
18
  <Playground />
src/routes/+page.ts DELETED
@@ -1,17 +0,0 @@
1
- import type { PageLoad } from "./$types.js";
2
- import type { ApiModelsResponse } from "./api/models/+server.js";
3
-
4
- export const load: PageLoad = async ({ fetch }) => {
5
- const [modelsRes, routerRes] = await Promise.all([
6
- fetch("/api/models"),
7
- fetch("https://router.huggingface.co/v1/models"),
8
- ]);
9
-
10
- const models: ApiModelsResponse = await modelsRes.json();
11
- const routerData = await routerRes.json();
12
-
13
- return {
14
- ...models,
15
- routerData,
16
- };
17
- };
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/routes/api/generate/+server.ts ADDED
@@ -0,0 +1,202 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { last } from "$lib/utils/array.js";
2
+ import { StreamWriter } from "$lib/utils/stream.js";
3
+ import { json } from "@sveltejs/kit";
4
+ import type { ChatCompletionMessage } from "openai/resources/index.mjs";
5
+ import type { RequestHandler } from "./$types.js";
6
+ import { createAdapter, type GenerationArgs } from "./adapter.js";
7
+ import { connectToMCPServers, executeMcpTool, type MCPServerConnection } from "./mcp.js";
8
+ import type { FinishReason, GenerateRequest } from "./types.js";
9
+ import { debugLog } from "./utils.js";
10
+
11
+ type AssistantResponse = { message: ChatCompletionMessage; finish_reason: FinishReason };
12
+
13
+ type GenerateLoopArgs = {
14
+ args: GenerationArgs;
15
+ getAssistantResponse: (args: GenerationArgs) => Promise<AssistantResponse>;
16
+ connections: MCPServerConnection[];
17
+ };
18
+
19
+ async function generateLoop({ args, getAssistantResponse, connections }: GenerateLoopArgs) {
20
+ let finish_reason: FinishReason | null = null;
21
+ const abortReasons: FinishReason[] = ["stop", "content_filter", "length"];
22
+
23
+ while (!abortReasons.includes(finish_reason)) {
24
+ debugLog("finish reason", finish_reason);
25
+ switch (finish_reason) {
26
+ case null: {
27
+ const res = await getAssistantResponse(args);
28
+ args.messages.push(res.message);
29
+ finish_reason = res.finish_reason;
30
+ break;
31
+ }
32
+ case "tool_calls": {
33
+ const toolCalls = last(args.messages)?.tool_calls;
34
+ if (!toolCalls) {
35
+ debugLog("No tool calls found");
36
+ finish_reason = null;
37
+ break;
38
+ }
39
+
40
+ debugLog("Executing tool calls");
41
+ debugLog(JSON.stringify(toolCalls, null, 2));
42
+
43
+ await Promise.allSettled(
44
+ toolCalls.map(async toolCall => {
45
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
46
+ const response = await executeMcpTool(connections, toolCall as any);
47
+ debugLog("Tool call response", response);
48
+ args.messages.push(response);
49
+ }),
50
+ );
51
+
52
+ finish_reason = null;
53
+
54
+ break;
55
+ }
56
+ default: {
57
+ finish_reason = "stop";
58
+ break;
59
+ }
60
+ }
61
+ }
62
+ }
63
+
64
+ export const POST: RequestHandler = async ({ request }) => {
65
+ try {
66
+ const body: GenerateRequest = await request.json();
67
+ const { model, messages, config, provider, streaming, response_format, enabledMCPs } = body;
68
+
69
+ if (enabledMCPs?.length === 0) {
70
+ debugLog(`MCP: Enabled MCP servers: ${enabledMCPs?.join(", ")}`);
71
+ }
72
+
73
+ // Connect to enabled MCP servers
74
+ const connections = await connectToMCPServers(enabledMCPs || []);
75
+ const tools = connections.flatMap(conn => conn.tools);
76
+
77
+ debugLog(`MCP: Connected to ${connections.length} servers with ${tools.length} tools available`);
78
+
79
+ const adapter = createAdapter(body);
80
+
81
+ const args = {
82
+ model: model.id,
83
+ messages,
84
+ provider,
85
+ ...config,
86
+ tools,
87
+ response_format,
88
+ stream: streaming,
89
+ };
90
+
91
+ if (streaming) {
92
+ const writer = new StreamWriter();
93
+
94
+ generateLoop({
95
+ args,
96
+ connections,
97
+ getAssistantResponse: async args => {
98
+ debugLog("Generating streaming response");
99
+ const res: AssistantResponse = {
100
+ message: {
101
+ role: "assistant",
102
+ content: "",
103
+ // refusal: null,
104
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
105
+ } as any,
106
+ finish_reason: null,
107
+ };
108
+
109
+ try {
110
+ const adapterStream = await adapter.stream(args);
111
+ for await (const chunk of adapterStream) {
112
+ const choice = chunk.choices[0];
113
+ if (!choice) continue;
114
+
115
+ if (choice.delta.content) {
116
+ res.message.content += choice.delta.content;
117
+ writer.writeChunk(choice.delta.content || "");
118
+ }
119
+ if (choice.delta.tool_calls) {
120
+ res.message.tool_calls = res.message.tool_calls ?? [];
121
+
122
+ for (const toolCall of choice.delta.tool_calls) {
123
+ res.message.tool_calls[toolCall.index] = res.message.tool_calls[toolCall.index] ?? {
124
+ id: toolCall.id ?? "",
125
+ type: "function",
126
+ function: {
127
+ name: "",
128
+ arguments: "",
129
+ },
130
+ };
131
+
132
+ if (toolCall.function?.name) {
133
+ res.message.tool_calls[toolCall.index]!.function.name += toolCall.function.name;
134
+ }
135
+ if (toolCall.function?.arguments) {
136
+ res.message.tool_calls[toolCall.index]!.function.arguments += toolCall.function.arguments;
137
+ }
138
+ }
139
+ }
140
+ if (choice.finish_reason) {
141
+ res.finish_reason = choice.finish_reason;
142
+ }
143
+ }
144
+ } catch (error) {
145
+ console.error("stream error", error);
146
+ writer.error(error instanceof Error ? error : new Error(String(error)));
147
+ res.finish_reason = "stop";
148
+ return res;
149
+ }
150
+
151
+ debugLog("Generated message");
152
+ debugLog(JSON.stringify(res.message, null, 2));
153
+ return res;
154
+ },
155
+ })
156
+ .then(() => writer.end())
157
+ .catch(error => {
158
+ console.error("Generation loop error:", error);
159
+ writer.error(error instanceof Error ? error : new Error(String(error)));
160
+ });
161
+
162
+ debugLog("Creating response...");
163
+
164
+ return writer.createResponse();
165
+ }
166
+
167
+ const message: ChatCompletionMessage = {
168
+ role: "assistant",
169
+ content: "",
170
+ // refusal: null,
171
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
172
+ } as any;
173
+
174
+ await generateLoop({
175
+ args,
176
+ connections,
177
+ getAssistantResponse: async args => {
178
+ debugLog("Generating non-streaming response");
179
+ const response = await adapter.generate(args);
180
+ debugLog("Generated the response");
181
+ debugLog(JSON.stringify(response, null, 2));
182
+
183
+ if (response.choices && response.choices.length > 0) {
184
+ message.content += response.choices[0]!.message.content ?? "";
185
+ // const { completion_tokens } = response.usage || { completion_tokens: 0 };
186
+
187
+ return {
188
+ message: response.choices[0]!.message,
189
+ finish_reason: response.choices[0]!.finish_reason,
190
+ };
191
+ }
192
+ throw new Error("No response from the model");
193
+ },
194
+ });
195
+
196
+ return json({ message /* ,completion_tokens */ });
197
+ } catch (error) {
198
+ debugLog(JSON.stringify(error, null, 2));
199
+ console.error("Generation error:", error);
200
+ return json({ error: error instanceof Error ? error.message : "Unknown error occurred" }, { status: 500 });
201
+ }
202
+ };
src/routes/api/generate/adapter.ts ADDED
@@ -0,0 +1,71 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* eslint-disable @typescript-eslint/no-explicit-any -- Sorry */
2
+ import { omit } from "$lib/utils/object.svelte.js";
3
+ import { InferenceClient } from "@huggingface/inference";
4
+ import type { ChatCompletionInputMessage } from "@huggingface/tasks";
5
+ import OpenAI from "openai";
6
+ import type { Stream } from "openai/streaming.mjs";
7
+ import type { GenerateRequest, OpenAIFunctionSchema } from "./types.js";
8
+ import type { ChatCompletionMessage } from "openai/resources/index.mjs";
9
+
10
+ export type GenerationArgs = {
11
+ model: string;
12
+ messages: Array<ChatCompletionInputMessage | ChatCompletionMessage>;
13
+ provider?: string;
14
+ config?: Record<string, unknown>;
15
+ tools?: OpenAIFunctionSchema[];
16
+ response_format?: unknown;
17
+ };
18
+
19
+ export interface Adapter {
20
+ stream: (args: GenerationArgs) => Promise<Stream<OpenAI.Chat.Completions.ChatCompletionChunk>>;
21
+ generate: (args: GenerationArgs) => Promise<OpenAI.Chat.Completions.ChatCompletion>;
22
+ }
23
+
24
+ function createCustomAdapter({ model }: GenerateRequest): Adapter {
25
+ // Handle OpenAI-compatible custom models
26
+ const openai = new OpenAI({
27
+ apiKey: model.accessToken,
28
+ baseURL: model.endpointUrl,
29
+ });
30
+
31
+ return {
32
+ stream: async (args: GenerationArgs) => {
33
+ return await openai.chat.completions.create({
34
+ ...omit(args, "provider"),
35
+ stream: true,
36
+ } as OpenAI.ChatCompletionCreateParamsStreaming);
37
+ },
38
+ generate: (args: GenerationArgs) => {
39
+ return openai.chat.completions.create({
40
+ ...omit(args, "provider"),
41
+ stream: false,
42
+ } as OpenAI.ChatCompletionCreateParamsNonStreaming);
43
+ },
44
+ };
45
+ }
46
+
47
+ function createHFAdapter({ accessToken }: GenerateRequest): Adapter {
48
+ const client = new InferenceClient(accessToken);
49
+ return {
50
+ stream: (args: GenerationArgs) => {
51
+ return client.chatCompletionStream({
52
+ ...args,
53
+ provider: args.provider as any,
54
+ response_format: args.response_format as any,
55
+ tools: args.tools as any,
56
+ } as any) as any;
57
+ },
58
+ generate: (args: GenerationArgs) => {
59
+ return client.chatCompletion(args as any) as any;
60
+ },
61
+ };
62
+ }
63
+
64
+ export function createAdapter(body: GenerateRequest): Adapter {
65
+ const { model } = body;
66
+
67
+ if (model.isCustom) {
68
+ return createCustomAdapter(body);
69
+ }
70
+ return createHFAdapter(body);
71
+ }
src/routes/api/generate/mcp.ts ADDED
@@ -0,0 +1,106 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { Client } from "@modelcontextprotocol/sdk/client/index.js";
2
+ import type { MCPServerConfig, McpToolSchema, OpenAIFunctionSchema } from "./types.js";
3
+ import { debugError, debugLog } from "./utils.js";
4
+ import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
5
+ import { SSEClientTransport } from "@modelcontextprotocol/sdk/client/sse.js";
6
+
7
+ export const mcpToolToOpenAIFunction = (tool: McpToolSchema): OpenAIFunctionSchema => {
8
+ return {
9
+ type: "function",
10
+ function: {
11
+ name: tool.name,
12
+ description: tool.name,
13
+ parameters: tool.inputSchema,
14
+ strict: true,
15
+ },
16
+ };
17
+ };
18
+
19
+ export type MCPServerConnection = { client: Client; tools: OpenAIFunctionSchema[] };
20
+
21
+ export const connectToMCPServers = async (servers: MCPServerConfig[]): Promise<MCPServerConnection[]> => {
22
+ const connections: MCPServerConnection[] = [];
23
+
24
+ await Promise.allSettled(
25
+ servers.map(async server => {
26
+ try {
27
+ const conn: MCPServerConnection = {
28
+ client: new Client({
29
+ name: "playground-client" + crypto.randomUUID(),
30
+ version: "0.0.1",
31
+ }),
32
+ tools: [],
33
+ };
34
+
35
+ debugLog(`Connecting to MCP server: ${server.name} (${server.url})`);
36
+
37
+ let transport;
38
+ const url = new URL(server.url);
39
+ if (server.protocol === "sse") {
40
+ transport = new SSEClientTransport(url);
41
+ } else {
42
+ transport = new StreamableHTTPClientTransport(url);
43
+ }
44
+
45
+ await conn.client.connect(transport);
46
+
47
+ const { tools: mcpTools } = await conn.client.listTools();
48
+ const serverTools = mcpTools.map(mcpToolToOpenAIFunction);
49
+ conn.tools.push(...serverTools);
50
+ debugLog(`Connected to ${server.name} with ${mcpTools.length} tools`);
51
+ connections.push(conn);
52
+ } catch (error) {
53
+ debugError(`Failed to connect to MCP server ${server.name}:`, error);
54
+ }
55
+ }),
56
+ );
57
+
58
+ return connections;
59
+ };
60
+
61
+ export const executeMcpTool = async (
62
+ connections: MCPServerConnection[],
63
+ toolCall: { id: string; function: { name: string; arguments: string } },
64
+ ) => {
65
+ try {
66
+ debugLog(`Executing tool: ${toolCall.function.name}`);
67
+ debugLog(`Tool arguments:`, JSON.parse(toolCall.function.arguments));
68
+
69
+ // Try to find the tool in any of the connected clients
70
+ let result = null;
71
+ for (const conn of connections) {
72
+ try {
73
+ const toolExists = conn.tools.some(tool => tool.function?.name === toolCall.function.name);
74
+ if (!toolExists) continue;
75
+ debugLog(`Found tool ${toolCall.function.name}`);
76
+ result = await conn.client.callTool({
77
+ name: toolCall.function.name,
78
+ arguments: JSON.parse(toolCall.function.arguments),
79
+ });
80
+ } catch (clientError) {
81
+ debugError(`Failed to execute tool on client:`, clientError);
82
+ continue;
83
+ }
84
+ }
85
+
86
+ if (!result) {
87
+ throw new Error(`Tool ${toolCall.function.name} not found in any connected MCP server`);
88
+ }
89
+
90
+ // mcpLog(`Tool result:`, result.content);
91
+
92
+ return {
93
+ tool_call_id: toolCall.id,
94
+ role: "tool" as const,
95
+ content: JSON.stringify(result.content),
96
+ };
97
+ } catch (error) {
98
+ debugError(`Tool execution failed:`, error);
99
+
100
+ return {
101
+ tool_call_id: toolCall.id,
102
+ role: "tool" as const,
103
+ content: JSON.stringify({ error: error instanceof Error ? error.message : "Tool execution failed" }),
104
+ };
105
+ }
106
+ };
src/routes/api/generate/types.ts ADDED
@@ -0,0 +1,53 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import type { ChatCompletionInputMessage } from "@huggingface/tasks";
2
+ import type { ChatCompletionChunk } from "openai/resources/index.mjs";
3
+
4
+ export interface MCPServerConfig {
5
+ id: string;
6
+ name: string;
7
+ url: string;
8
+ protocol: "sse" | "http";
9
+ headers?: Record<string, string>;
10
+ }
11
+
12
+ export interface GenerateRequest {
13
+ model: {
14
+ id: string;
15
+ isCustom?: boolean;
16
+ accessToken?: string;
17
+ endpointUrl?: string;
18
+ };
19
+ messages: ChatCompletionInputMessage[];
20
+ config: Record<string, unknown>;
21
+ provider?: string;
22
+ streaming?: boolean;
23
+ response_format?: unknown;
24
+ accessToken: string;
25
+ enabledMCPs?: MCPServerConfig[];
26
+ }
27
+
28
+ export interface OpenAIFunctionSchema {
29
+ type?: string;
30
+ function?: {
31
+ name?: string;
32
+ description?: string;
33
+ parameters?: {
34
+ type?: string;
35
+ required?: string[];
36
+ additionalProperties?: boolean;
37
+ [key: string]: unknown;
38
+ };
39
+ strict?: boolean;
40
+ };
41
+ }
42
+
43
+ export type McpToolSchema = {
44
+ name: string;
45
+ inputSchema: {
46
+ type: string;
47
+ required?: string[];
48
+ additionalProperties?: boolean;
49
+ [key: string]: unknown;
50
+ };
51
+ };
52
+
53
+ export type FinishReason = ChatCompletionChunk.Choice["finish_reason"];
src/routes/api/generate/utils.ts ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ const DEBUG_LOG = true;
2
+
3
+ export const debugLog = (...args: unknown[]) => {
4
+ if (!DEBUG_LOG) return;
5
+ console.log("[LOG DEBUG]", ...args);
6
+ };
7
+
8
+ export const debugError = (...args: unknown[]) => {
9
+ if (!DEBUG_LOG) return;
10
+ console.error("[LOG DEBUG]", ...args);
11
+ };
src/routes/usage/+page.svelte DELETED
File without changes
svelte.config.js CHANGED
@@ -12,6 +12,9 @@ const config = {
12
  // If your environment is not supported, or you settled on a specific environment, switch out the adapter.
13
  // See https://kit.svelte.dev/docs/adapters for more information about adapters.
14
  adapter: adapter(),
 
 
 
15
  },
16
 
17
  compilerOptions: {
 
12
  // If your environment is not supported, or you settled on a specific environment, switch out the adapter.
13
  // See https://kit.svelte.dev/docs/adapters for more information about adapters.
14
  adapter: adapter(),
15
+ experimental: {
16
+ remoteFunctions: true,
17
+ },
18
  },
19
 
20
  compilerOptions: {