burtenshaw commited on
Commit
ea3f4d3
·
0 Parent(s):

first commit

Browse files
.gitignore ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /build
2
+ /node_modules
3
+ /.svelte-kit
4
+ /package
5
+ .env
6
+ .env.*
7
+ !.env.example
8
+ !.env.example.*
9
+
10
+ # Optional npm cache directory
11
+ .npm
12
+
13
+ # Optional eslint cache
14
+ .eslintcache
15
+
16
+ # Optional REPL history
17
+ .node_repl_history
18
+
19
+ # Output of 'npm pack'
20
+ *.tgz
21
+
22
+ # Yarn Integrity file
23
+ .yarn-integrity
24
+
25
+ # dotenv environment variables file
26
+ .env
27
+
28
+ # SvelteKit Generated Files
29
+ .svelte-kit/
.vscode/launch.json ADDED
@@ -0,0 +1,66 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "version": "0.2.0",
3
+ "configurations": [
4
+ {
5
+ "name": "Launch SvelteKit Dev Server",
6
+ "type": "node-terminal",
7
+ "request": "launch",
8
+ "command": "npm run dev",
9
+ "cwd": "${workspaceFolder}",
10
+ "envFile": "${workspaceFolder}/.env", // Keep consistent env loading
11
+ "serverReadyAction": {
12
+ "pattern": "Local:\\\\s+(http://localhost:\\\\d+)", // Pattern to detect server ready
13
+ "uriFormat": "%s",
14
+ "action": "debugWithChrome" // Launch Chrome debugger when ready
15
+ },
16
+ "presentation": {
17
+ "hidden": false,
18
+ "group": "SvelteKit",
19
+ "order": 0 // Put it first
20
+ }
21
+ },
22
+ {
23
+ "name": "Attach to SvelteKit Dev Server",
24
+ "type": "node", // Use 'node' for attaching
25
+ "request": "attach",
26
+ "port": 9229, // Default Node.js inspect port, Vite might need config to use this
27
+ "skipFiles": [
28
+ "<node_internals>/**",
29
+ "**/node_modules/**"
30
+ ],
31
+ "sourceMaps": true, // Enable source maps for debugging TS/Svelte
32
+ "smartStep": true,
33
+ // Ensure environment variables from .env are loaded by the process you attach to
34
+ // (npm run dev usually handles this via Vite's dotenv support)
35
+ "envFile": "${workspaceFolder}/.env", // Correct for project at root
36
+ "restart": true, // Automatically try to re-attach
37
+ "presentation": {
38
+ "hidden": false,
39
+ "group": "SvelteKit",
40
+ "order": 1
41
+ }
42
+ },
43
+ {
44
+ "name": "Launch Chrome against localhost",
45
+ "type": "chrome",
46
+ "request": "launch",
47
+ "url": "http://localhost:5173", // Default Vite port
48
+ "webRoot": "${workspaceFolder}/src", // Corrected webRoot
49
+ "sourceMaps": true,
50
+ "presentation": {
51
+ "hidden": false,
52
+ "group": "SvelteKit",
53
+ "order": 2
54
+ }
55
+ }
56
+ ],
57
+ "compounds": [
58
+ {
59
+ "name": "SvelteKit: Full Stack Debug",
60
+ "configurations": [
61
+ "Attach to SvelteKit Dev Server",
62
+ "Launch Chrome against localhost"
63
+ ]
64
+ }
65
+ ]
66
+ }
package-lock.json ADDED
@@ -0,0 +1,1492 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "image_gen_agent",
3
+ "lockfileVersion": 3,
4
+ "requires": true,
5
+ "packages": {
6
+ "": {
7
+ "dependencies": {
8
+ "@huggingface/inference": "^3.9.2"
9
+ },
10
+ "devDependencies": {
11
+ "@sveltejs/adapter-auto": "^6.0.0",
12
+ "@sveltejs/kit": "^2.20.7",
13
+ "@sveltejs/vite-plugin-svelte": "^5.0.3",
14
+ "svelte": "^5.28.2",
15
+ "vite": "^6.3.3"
16
+ }
17
+ },
18
+ "node_modules/@ampproject/remapping": {
19
+ "version": "2.3.0",
20
+ "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz",
21
+ "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==",
22
+ "dev": true,
23
+ "license": "Apache-2.0",
24
+ "dependencies": {
25
+ "@jridgewell/gen-mapping": "^0.3.5",
26
+ "@jridgewell/trace-mapping": "^0.3.24"
27
+ },
28
+ "engines": {
29
+ "node": ">=6.0.0"
30
+ }
31
+ },
32
+ "node_modules/@esbuild/aix-ppc64": {
33
+ "version": "0.25.3",
34
+ "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.3.tgz",
35
+ "integrity": "sha512-W8bFfPA8DowP8l//sxjJLSLkD8iEjMc7cBVyP+u4cEv9sM7mdUCkgsj+t0n/BWPFtv7WWCN5Yzj0N6FJNUUqBQ==",
36
+ "cpu": [
37
+ "ppc64"
38
+ ],
39
+ "dev": true,
40
+ "license": "MIT",
41
+ "optional": true,
42
+ "os": [
43
+ "aix"
44
+ ],
45
+ "engines": {
46
+ "node": ">=18"
47
+ }
48
+ },
49
+ "node_modules/@esbuild/android-arm": {
50
+ "version": "0.25.3",
51
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.3.tgz",
52
+ "integrity": "sha512-PuwVXbnP87Tcff5I9ngV0lmiSu40xw1At6i3GsU77U7cjDDB4s0X2cyFuBiDa1SBk9DnvWwnGvVaGBqoFWPb7A==",
53
+ "cpu": [
54
+ "arm"
55
+ ],
56
+ "dev": true,
57
+ "license": "MIT",
58
+ "optional": true,
59
+ "os": [
60
+ "android"
61
+ ],
62
+ "engines": {
63
+ "node": ">=18"
64
+ }
65
+ },
66
+ "node_modules/@esbuild/android-arm64": {
67
+ "version": "0.25.3",
68
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.3.tgz",
69
+ "integrity": "sha512-XelR6MzjlZuBM4f5z2IQHK6LkK34Cvv6Rj2EntER3lwCBFdg6h2lKbtRjpTTsdEjD/WSe1q8UyPBXP1x3i/wYQ==",
70
+ "cpu": [
71
+ "arm64"
72
+ ],
73
+ "dev": true,
74
+ "license": "MIT",
75
+ "optional": true,
76
+ "os": [
77
+ "android"
78
+ ],
79
+ "engines": {
80
+ "node": ">=18"
81
+ }
82
+ },
83
+ "node_modules/@esbuild/android-x64": {
84
+ "version": "0.25.3",
85
+ "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.3.tgz",
86
+ "integrity": "sha512-ogtTpYHT/g1GWS/zKM0cc/tIebFjm1F9Aw1boQ2Y0eUQ+J89d0jFY//s9ei9jVIlkYi8AfOjiixcLJSGNSOAdQ==",
87
+ "cpu": [
88
+ "x64"
89
+ ],
90
+ "dev": true,
91
+ "license": "MIT",
92
+ "optional": true,
93
+ "os": [
94
+ "android"
95
+ ],
96
+ "engines": {
97
+ "node": ">=18"
98
+ }
99
+ },
100
+ "node_modules/@esbuild/darwin-arm64": {
101
+ "version": "0.25.3",
102
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.3.tgz",
103
+ "integrity": "sha512-eESK5yfPNTqpAmDfFWNsOhmIOaQA59tAcF/EfYvo5/QWQCzXn5iUSOnqt3ra3UdzBv073ykTtmeLJZGt3HhA+w==",
104
+ "cpu": [
105
+ "arm64"
106
+ ],
107
+ "dev": true,
108
+ "license": "MIT",
109
+ "optional": true,
110
+ "os": [
111
+ "darwin"
112
+ ],
113
+ "engines": {
114
+ "node": ">=18"
115
+ }
116
+ },
117
+ "node_modules/@esbuild/darwin-x64": {
118
+ "version": "0.25.3",
119
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.3.tgz",
120
+ "integrity": "sha512-Kd8glo7sIZtwOLcPbW0yLpKmBNWMANZhrC1r6K++uDR2zyzb6AeOYtI6udbtabmQpFaxJ8uduXMAo1gs5ozz8A==",
121
+ "cpu": [
122
+ "x64"
123
+ ],
124
+ "dev": true,
125
+ "license": "MIT",
126
+ "optional": true,
127
+ "os": [
128
+ "darwin"
129
+ ],
130
+ "engines": {
131
+ "node": ">=18"
132
+ }
133
+ },
134
+ "node_modules/@esbuild/freebsd-arm64": {
135
+ "version": "0.25.3",
136
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.3.tgz",
137
+ "integrity": "sha512-EJiyS70BYybOBpJth3M0KLOus0n+RRMKTYzhYhFeMwp7e/RaajXvP+BWlmEXNk6uk+KAu46j/kaQzr6au+JcIw==",
138
+ "cpu": [
139
+ "arm64"
140
+ ],
141
+ "dev": true,
142
+ "license": "MIT",
143
+ "optional": true,
144
+ "os": [
145
+ "freebsd"
146
+ ],
147
+ "engines": {
148
+ "node": ">=18"
149
+ }
150
+ },
151
+ "node_modules/@esbuild/freebsd-x64": {
152
+ "version": "0.25.3",
153
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.3.tgz",
154
+ "integrity": "sha512-Q+wSjaLpGxYf7zC0kL0nDlhsfuFkoN+EXrx2KSB33RhinWzejOd6AvgmP5JbkgXKmjhmpfgKZq24pneodYqE8Q==",
155
+ "cpu": [
156
+ "x64"
157
+ ],
158
+ "dev": true,
159
+ "license": "MIT",
160
+ "optional": true,
161
+ "os": [
162
+ "freebsd"
163
+ ],
164
+ "engines": {
165
+ "node": ">=18"
166
+ }
167
+ },
168
+ "node_modules/@esbuild/linux-arm": {
169
+ "version": "0.25.3",
170
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.3.tgz",
171
+ "integrity": "sha512-dUOVmAUzuHy2ZOKIHIKHCm58HKzFqd+puLaS424h6I85GlSDRZIA5ycBixb3mFgM0Jdh+ZOSB6KptX30DD8YOQ==",
172
+ "cpu": [
173
+ "arm"
174
+ ],
175
+ "dev": true,
176
+ "license": "MIT",
177
+ "optional": true,
178
+ "os": [
179
+ "linux"
180
+ ],
181
+ "engines": {
182
+ "node": ">=18"
183
+ }
184
+ },
185
+ "node_modules/@esbuild/linux-arm64": {
186
+ "version": "0.25.3",
187
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.3.tgz",
188
+ "integrity": "sha512-xCUgnNYhRD5bb1C1nqrDV1PfkwgbswTTBRbAd8aH5PhYzikdf/ddtsYyMXFfGSsb/6t6QaPSzxtbfAZr9uox4A==",
189
+ "cpu": [
190
+ "arm64"
191
+ ],
192
+ "dev": true,
193
+ "license": "MIT",
194
+ "optional": true,
195
+ "os": [
196
+ "linux"
197
+ ],
198
+ "engines": {
199
+ "node": ">=18"
200
+ }
201
+ },
202
+ "node_modules/@esbuild/linux-ia32": {
203
+ "version": "0.25.3",
204
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.3.tgz",
205
+ "integrity": "sha512-yplPOpczHOO4jTYKmuYuANI3WhvIPSVANGcNUeMlxH4twz/TeXuzEP41tGKNGWJjuMhotpGabeFYGAOU2ummBw==",
206
+ "cpu": [
207
+ "ia32"
208
+ ],
209
+ "dev": true,
210
+ "license": "MIT",
211
+ "optional": true,
212
+ "os": [
213
+ "linux"
214
+ ],
215
+ "engines": {
216
+ "node": ">=18"
217
+ }
218
+ },
219
+ "node_modules/@esbuild/linux-loong64": {
220
+ "version": "0.25.3",
221
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.3.tgz",
222
+ "integrity": "sha512-P4BLP5/fjyihmXCELRGrLd793q/lBtKMQl8ARGpDxgzgIKJDRJ/u4r1A/HgpBpKpKZelGct2PGI4T+axcedf6g==",
223
+ "cpu": [
224
+ "loong64"
225
+ ],
226
+ "dev": true,
227
+ "license": "MIT",
228
+ "optional": true,
229
+ "os": [
230
+ "linux"
231
+ ],
232
+ "engines": {
233
+ "node": ">=18"
234
+ }
235
+ },
236
+ "node_modules/@esbuild/linux-mips64el": {
237
+ "version": "0.25.3",
238
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.3.tgz",
239
+ "integrity": "sha512-eRAOV2ODpu6P5divMEMa26RRqb2yUoYsuQQOuFUexUoQndm4MdpXXDBbUoKIc0iPa4aCO7gIhtnYomkn2x+bag==",
240
+ "cpu": [
241
+ "mips64el"
242
+ ],
243
+ "dev": true,
244
+ "license": "MIT",
245
+ "optional": true,
246
+ "os": [
247
+ "linux"
248
+ ],
249
+ "engines": {
250
+ "node": ">=18"
251
+ }
252
+ },
253
+ "node_modules/@esbuild/linux-ppc64": {
254
+ "version": "0.25.3",
255
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.3.tgz",
256
+ "integrity": "sha512-ZC4jV2p7VbzTlnl8nZKLcBkfzIf4Yad1SJM4ZMKYnJqZFD4rTI+pBG65u8ev4jk3/MPwY9DvGn50wi3uhdaghg==",
257
+ "cpu": [
258
+ "ppc64"
259
+ ],
260
+ "dev": true,
261
+ "license": "MIT",
262
+ "optional": true,
263
+ "os": [
264
+ "linux"
265
+ ],
266
+ "engines": {
267
+ "node": ">=18"
268
+ }
269
+ },
270
+ "node_modules/@esbuild/linux-riscv64": {
271
+ "version": "0.25.3",
272
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.3.tgz",
273
+ "integrity": "sha512-LDDODcFzNtECTrUUbVCs6j9/bDVqy7DDRsuIXJg6so+mFksgwG7ZVnTruYi5V+z3eE5y+BJZw7VvUadkbfg7QA==",
274
+ "cpu": [
275
+ "riscv64"
276
+ ],
277
+ "dev": true,
278
+ "license": "MIT",
279
+ "optional": true,
280
+ "os": [
281
+ "linux"
282
+ ],
283
+ "engines": {
284
+ "node": ">=18"
285
+ }
286
+ },
287
+ "node_modules/@esbuild/linux-s390x": {
288
+ "version": "0.25.3",
289
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.3.tgz",
290
+ "integrity": "sha512-s+w/NOY2k0yC2p9SLen+ymflgcpRkvwwa02fqmAwhBRI3SC12uiS10edHHXlVWwfAagYSY5UpmT/zISXPMW3tQ==",
291
+ "cpu": [
292
+ "s390x"
293
+ ],
294
+ "dev": true,
295
+ "license": "MIT",
296
+ "optional": true,
297
+ "os": [
298
+ "linux"
299
+ ],
300
+ "engines": {
301
+ "node": ">=18"
302
+ }
303
+ },
304
+ "node_modules/@esbuild/linux-x64": {
305
+ "version": "0.25.3",
306
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.3.tgz",
307
+ "integrity": "sha512-nQHDz4pXjSDC6UfOE1Fw9Q8d6GCAd9KdvMZpfVGWSJztYCarRgSDfOVBY5xwhQXseiyxapkiSJi/5/ja8mRFFA==",
308
+ "cpu": [
309
+ "x64"
310
+ ],
311
+ "dev": true,
312
+ "license": "MIT",
313
+ "optional": true,
314
+ "os": [
315
+ "linux"
316
+ ],
317
+ "engines": {
318
+ "node": ">=18"
319
+ }
320
+ },
321
+ "node_modules/@esbuild/netbsd-arm64": {
322
+ "version": "0.25.3",
323
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.3.tgz",
324
+ "integrity": "sha512-1QaLtOWq0mzK6tzzp0jRN3eccmN3hezey7mhLnzC6oNlJoUJz4nym5ZD7mDnS/LZQgkrhEbEiTn515lPeLpgWA==",
325
+ "cpu": [
326
+ "arm64"
327
+ ],
328
+ "dev": true,
329
+ "license": "MIT",
330
+ "optional": true,
331
+ "os": [
332
+ "netbsd"
333
+ ],
334
+ "engines": {
335
+ "node": ">=18"
336
+ }
337
+ },
338
+ "node_modules/@esbuild/netbsd-x64": {
339
+ "version": "0.25.3",
340
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.3.tgz",
341
+ "integrity": "sha512-i5Hm68HXHdgv8wkrt+10Bc50zM0/eonPb/a/OFVfB6Qvpiirco5gBA5bz7S2SHuU+Y4LWn/zehzNX14Sp4r27g==",
342
+ "cpu": [
343
+ "x64"
344
+ ],
345
+ "dev": true,
346
+ "license": "MIT",
347
+ "optional": true,
348
+ "os": [
349
+ "netbsd"
350
+ ],
351
+ "engines": {
352
+ "node": ">=18"
353
+ }
354
+ },
355
+ "node_modules/@esbuild/openbsd-arm64": {
356
+ "version": "0.25.3",
357
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.3.tgz",
358
+ "integrity": "sha512-zGAVApJEYTbOC6H/3QBr2mq3upG/LBEXr85/pTtKiv2IXcgKV0RT0QA/hSXZqSvLEpXeIxah7LczB4lkiYhTAQ==",
359
+ "cpu": [
360
+ "arm64"
361
+ ],
362
+ "dev": true,
363
+ "license": "MIT",
364
+ "optional": true,
365
+ "os": [
366
+ "openbsd"
367
+ ],
368
+ "engines": {
369
+ "node": ">=18"
370
+ }
371
+ },
372
+ "node_modules/@esbuild/openbsd-x64": {
373
+ "version": "0.25.3",
374
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.3.tgz",
375
+ "integrity": "sha512-fpqctI45NnCIDKBH5AXQBsD0NDPbEFczK98hk/aa6HJxbl+UtLkJV2+Bvy5hLSLk3LHmqt0NTkKNso1A9y1a4w==",
376
+ "cpu": [
377
+ "x64"
378
+ ],
379
+ "dev": true,
380
+ "license": "MIT",
381
+ "optional": true,
382
+ "os": [
383
+ "openbsd"
384
+ ],
385
+ "engines": {
386
+ "node": ">=18"
387
+ }
388
+ },
389
+ "node_modules/@esbuild/sunos-x64": {
390
+ "version": "0.25.3",
391
+ "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.3.tgz",
392
+ "integrity": "sha512-ROJhm7d8bk9dMCUZjkS8fgzsPAZEjtRJqCAmVgB0gMrvG7hfmPmz9k1rwO4jSiblFjYmNvbECL9uhaPzONMfgA==",
393
+ "cpu": [
394
+ "x64"
395
+ ],
396
+ "dev": true,
397
+ "license": "MIT",
398
+ "optional": true,
399
+ "os": [
400
+ "sunos"
401
+ ],
402
+ "engines": {
403
+ "node": ">=18"
404
+ }
405
+ },
406
+ "node_modules/@esbuild/win32-arm64": {
407
+ "version": "0.25.3",
408
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.3.tgz",
409
+ "integrity": "sha512-YWcow8peiHpNBiIXHwaswPnAXLsLVygFwCB3A7Bh5jRkIBFWHGmNQ48AlX4xDvQNoMZlPYzjVOQDYEzWCqufMQ==",
410
+ "cpu": [
411
+ "arm64"
412
+ ],
413
+ "dev": true,
414
+ "license": "MIT",
415
+ "optional": true,
416
+ "os": [
417
+ "win32"
418
+ ],
419
+ "engines": {
420
+ "node": ">=18"
421
+ }
422
+ },
423
+ "node_modules/@esbuild/win32-ia32": {
424
+ "version": "0.25.3",
425
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.3.tgz",
426
+ "integrity": "sha512-qspTZOIGoXVS4DpNqUYUs9UxVb04khS1Degaw/MnfMe7goQ3lTfQ13Vw4qY/Nj0979BGvMRpAYbs/BAxEvU8ew==",
427
+ "cpu": [
428
+ "ia32"
429
+ ],
430
+ "dev": true,
431
+ "license": "MIT",
432
+ "optional": true,
433
+ "os": [
434
+ "win32"
435
+ ],
436
+ "engines": {
437
+ "node": ">=18"
438
+ }
439
+ },
440
+ "node_modules/@esbuild/win32-x64": {
441
+ "version": "0.25.3",
442
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.3.tgz",
443
+ "integrity": "sha512-ICgUR+kPimx0vvRzf+N/7L7tVSQeE3BYY+NhHRHXS1kBuPO7z2+7ea2HbhDyZdTephgvNvKrlDDKUexuCVBVvg==",
444
+ "cpu": [
445
+ "x64"
446
+ ],
447
+ "dev": true,
448
+ "license": "MIT",
449
+ "optional": true,
450
+ "os": [
451
+ "win32"
452
+ ],
453
+ "engines": {
454
+ "node": ">=18"
455
+ }
456
+ },
457
+ "node_modules/@huggingface/inference": {
458
+ "version": "3.9.2",
459
+ "resolved": "https://registry.npmjs.org/@huggingface/inference/-/inference-3.9.2.tgz",
460
+ "integrity": "sha512-7EpMgaELUJArqhFpinkyikO1iXza4lEBYcUF8HMDVabwI2QxCXmxb6coCgYmerHEfRRxsvqogwNrdxiUfcSvDg==",
461
+ "license": "MIT",
462
+ "dependencies": {
463
+ "@huggingface/jinja": "^0.3.4",
464
+ "@huggingface/tasks": "^0.18.11"
465
+ },
466
+ "engines": {
467
+ "node": ">=18"
468
+ }
469
+ },
470
+ "node_modules/@huggingface/jinja": {
471
+ "version": "0.3.4",
472
+ "resolved": "https://registry.npmjs.org/@huggingface/jinja/-/jinja-0.3.4.tgz",
473
+ "integrity": "sha512-kFFQWJiWwvxezKQnvH1X7GjsECcMljFx+UZK9hx6P26aVHwwidJVTB0ptLfRVZQvVkOGHoMmTGvo4nT0X9hHOA==",
474
+ "license": "MIT",
475
+ "engines": {
476
+ "node": ">=18"
477
+ }
478
+ },
479
+ "node_modules/@huggingface/tasks": {
480
+ "version": "0.18.11",
481
+ "resolved": "https://registry.npmjs.org/@huggingface/tasks/-/tasks-0.18.11.tgz",
482
+ "integrity": "sha512-KSGMkOi86Ap2xTWGxwnSj8cE+glYhhwyHMdGDJn4dsOz1LzWq8kQF0epeZRkjBgwdTSBFpCk3+3FGdi6tXch7A==",
483
+ "license": "MIT"
484
+ },
485
+ "node_modules/@jridgewell/gen-mapping": {
486
+ "version": "0.3.8",
487
+ "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.8.tgz",
488
+ "integrity": "sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==",
489
+ "dev": true,
490
+ "license": "MIT",
491
+ "dependencies": {
492
+ "@jridgewell/set-array": "^1.2.1",
493
+ "@jridgewell/sourcemap-codec": "^1.4.10",
494
+ "@jridgewell/trace-mapping": "^0.3.24"
495
+ },
496
+ "engines": {
497
+ "node": ">=6.0.0"
498
+ }
499
+ },
500
+ "node_modules/@jridgewell/resolve-uri": {
501
+ "version": "3.1.2",
502
+ "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
503
+ "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
504
+ "dev": true,
505
+ "license": "MIT",
506
+ "engines": {
507
+ "node": ">=6.0.0"
508
+ }
509
+ },
510
+ "node_modules/@jridgewell/set-array": {
511
+ "version": "1.2.1",
512
+ "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz",
513
+ "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==",
514
+ "dev": true,
515
+ "license": "MIT",
516
+ "engines": {
517
+ "node": ">=6.0.0"
518
+ }
519
+ },
520
+ "node_modules/@jridgewell/sourcemap-codec": {
521
+ "version": "1.5.0",
522
+ "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz",
523
+ "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==",
524
+ "dev": true,
525
+ "license": "MIT"
526
+ },
527
+ "node_modules/@jridgewell/trace-mapping": {
528
+ "version": "0.3.25",
529
+ "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz",
530
+ "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==",
531
+ "dev": true,
532
+ "license": "MIT",
533
+ "dependencies": {
534
+ "@jridgewell/resolve-uri": "^3.1.0",
535
+ "@jridgewell/sourcemap-codec": "^1.4.14"
536
+ }
537
+ },
538
+ "node_modules/@polka/url": {
539
+ "version": "1.0.0-next.29",
540
+ "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.29.tgz",
541
+ "integrity": "sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww==",
542
+ "dev": true,
543
+ "license": "MIT"
544
+ },
545
+ "node_modules/@rollup/rollup-android-arm-eabi": {
546
+ "version": "4.40.1",
547
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.40.1.tgz",
548
+ "integrity": "sha512-kxz0YeeCrRUHz3zyqvd7n+TVRlNyTifBsmnmNPtk3hQURUyG9eAB+usz6DAwagMusjx/zb3AjvDUvhFGDAexGw==",
549
+ "cpu": [
550
+ "arm"
551
+ ],
552
+ "dev": true,
553
+ "license": "MIT",
554
+ "optional": true,
555
+ "os": [
556
+ "android"
557
+ ]
558
+ },
559
+ "node_modules/@rollup/rollup-android-arm64": {
560
+ "version": "4.40.1",
561
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.40.1.tgz",
562
+ "integrity": "sha512-PPkxTOisoNC6TpnDKatjKkjRMsdaWIhyuMkA4UsBXT9WEZY4uHezBTjs6Vl4PbqQQeu6oION1w2voYZv9yquCw==",
563
+ "cpu": [
564
+ "arm64"
565
+ ],
566
+ "dev": true,
567
+ "license": "MIT",
568
+ "optional": true,
569
+ "os": [
570
+ "android"
571
+ ]
572
+ },
573
+ "node_modules/@rollup/rollup-darwin-arm64": {
574
+ "version": "4.40.1",
575
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.40.1.tgz",
576
+ "integrity": "sha512-VWXGISWFY18v/0JyNUy4A46KCFCb9NVsH+1100XP31lud+TzlezBbz24CYzbnA4x6w4hx+NYCXDfnvDVO6lcAA==",
577
+ "cpu": [
578
+ "arm64"
579
+ ],
580
+ "dev": true,
581
+ "license": "MIT",
582
+ "optional": true,
583
+ "os": [
584
+ "darwin"
585
+ ]
586
+ },
587
+ "node_modules/@rollup/rollup-darwin-x64": {
588
+ "version": "4.40.1",
589
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.40.1.tgz",
590
+ "integrity": "sha512-nIwkXafAI1/QCS7pxSpv/ZtFW6TXcNUEHAIA9EIyw5OzxJZQ1YDrX+CL6JAIQgZ33CInl1R6mHet9Y/UZTg2Bw==",
591
+ "cpu": [
592
+ "x64"
593
+ ],
594
+ "dev": true,
595
+ "license": "MIT",
596
+ "optional": true,
597
+ "os": [
598
+ "darwin"
599
+ ]
600
+ },
601
+ "node_modules/@rollup/rollup-freebsd-arm64": {
602
+ "version": "4.40.1",
603
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.40.1.tgz",
604
+ "integrity": "sha512-BdrLJ2mHTrIYdaS2I99mriyJfGGenSaP+UwGi1kB9BLOCu9SR8ZpbkmmalKIALnRw24kM7qCN0IOm6L0S44iWw==",
605
+ "cpu": [
606
+ "arm64"
607
+ ],
608
+ "dev": true,
609
+ "license": "MIT",
610
+ "optional": true,
611
+ "os": [
612
+ "freebsd"
613
+ ]
614
+ },
615
+ "node_modules/@rollup/rollup-freebsd-x64": {
616
+ "version": "4.40.1",
617
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.40.1.tgz",
618
+ "integrity": "sha512-VXeo/puqvCG8JBPNZXZf5Dqq7BzElNJzHRRw3vjBE27WujdzuOPecDPc/+1DcdcTptNBep3861jNq0mYkT8Z6Q==",
619
+ "cpu": [
620
+ "x64"
621
+ ],
622
+ "dev": true,
623
+ "license": "MIT",
624
+ "optional": true,
625
+ "os": [
626
+ "freebsd"
627
+ ]
628
+ },
629
+ "node_modules/@rollup/rollup-linux-arm-gnueabihf": {
630
+ "version": "4.40.1",
631
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.40.1.tgz",
632
+ "integrity": "sha512-ehSKrewwsESPt1TgSE/na9nIhWCosfGSFqv7vwEtjyAqZcvbGIg4JAcV7ZEh2tfj/IlfBeZjgOXm35iOOjadcg==",
633
+ "cpu": [
634
+ "arm"
635
+ ],
636
+ "dev": true,
637
+ "license": "MIT",
638
+ "optional": true,
639
+ "os": [
640
+ "linux"
641
+ ]
642
+ },
643
+ "node_modules/@rollup/rollup-linux-arm-musleabihf": {
644
+ "version": "4.40.1",
645
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.40.1.tgz",
646
+ "integrity": "sha512-m39iO/aaurh5FVIu/F4/Zsl8xppd76S4qoID8E+dSRQvTyZTOI2gVk3T4oqzfq1PtcvOfAVlwLMK3KRQMaR8lg==",
647
+ "cpu": [
648
+ "arm"
649
+ ],
650
+ "dev": true,
651
+ "license": "MIT",
652
+ "optional": true,
653
+ "os": [
654
+ "linux"
655
+ ]
656
+ },
657
+ "node_modules/@rollup/rollup-linux-arm64-gnu": {
658
+ "version": "4.40.1",
659
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.40.1.tgz",
660
+ "integrity": "sha512-Y+GHnGaku4aVLSgrT0uWe2o2Rq8te9hi+MwqGF9r9ORgXhmHK5Q71N757u0F8yU1OIwUIFy6YiJtKjtyktk5hg==",
661
+ "cpu": [
662
+ "arm64"
663
+ ],
664
+ "dev": true,
665
+ "license": "MIT",
666
+ "optional": true,
667
+ "os": [
668
+ "linux"
669
+ ]
670
+ },
671
+ "node_modules/@rollup/rollup-linux-arm64-musl": {
672
+ "version": "4.40.1",
673
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.40.1.tgz",
674
+ "integrity": "sha512-jEwjn3jCA+tQGswK3aEWcD09/7M5wGwc6+flhva7dsQNRZZTe30vkalgIzV4tjkopsTS9Jd7Y1Bsj6a4lzz8gQ==",
675
+ "cpu": [
676
+ "arm64"
677
+ ],
678
+ "dev": true,
679
+ "license": "MIT",
680
+ "optional": true,
681
+ "os": [
682
+ "linux"
683
+ ]
684
+ },
685
+ "node_modules/@rollup/rollup-linux-loongarch64-gnu": {
686
+ "version": "4.40.1",
687
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.40.1.tgz",
688
+ "integrity": "sha512-ySyWikVhNzv+BV/IDCsrraOAZ3UaC8SZB67FZlqVwXwnFhPihOso9rPOxzZbjp81suB1O2Topw+6Ug3JNegejQ==",
689
+ "cpu": [
690
+ "loong64"
691
+ ],
692
+ "dev": true,
693
+ "license": "MIT",
694
+ "optional": true,
695
+ "os": [
696
+ "linux"
697
+ ]
698
+ },
699
+ "node_modules/@rollup/rollup-linux-powerpc64le-gnu": {
700
+ "version": "4.40.1",
701
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.40.1.tgz",
702
+ "integrity": "sha512-BvvA64QxZlh7WZWqDPPdt0GH4bznuL6uOO1pmgPnnv86rpUpc8ZxgZwcEgXvo02GRIZX1hQ0j0pAnhwkhwPqWg==",
703
+ "cpu": [
704
+ "ppc64"
705
+ ],
706
+ "dev": true,
707
+ "license": "MIT",
708
+ "optional": true,
709
+ "os": [
710
+ "linux"
711
+ ]
712
+ },
713
+ "node_modules/@rollup/rollup-linux-riscv64-gnu": {
714
+ "version": "4.40.1",
715
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.40.1.tgz",
716
+ "integrity": "sha512-EQSP+8+1VuSulm9RKSMKitTav89fKbHymTf25n5+Yr6gAPZxYWpj3DzAsQqoaHAk9YX2lwEyAf9S4W8F4l3VBQ==",
717
+ "cpu": [
718
+ "riscv64"
719
+ ],
720
+ "dev": true,
721
+ "license": "MIT",
722
+ "optional": true,
723
+ "os": [
724
+ "linux"
725
+ ]
726
+ },
727
+ "node_modules/@rollup/rollup-linux-riscv64-musl": {
728
+ "version": "4.40.1",
729
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.40.1.tgz",
730
+ "integrity": "sha512-n/vQ4xRZXKuIpqukkMXZt9RWdl+2zgGNx7Uda8NtmLJ06NL8jiHxUawbwC+hdSq1rrw/9CghCpEONor+l1e2gA==",
731
+ "cpu": [
732
+ "riscv64"
733
+ ],
734
+ "dev": true,
735
+ "license": "MIT",
736
+ "optional": true,
737
+ "os": [
738
+ "linux"
739
+ ]
740
+ },
741
+ "node_modules/@rollup/rollup-linux-s390x-gnu": {
742
+ "version": "4.40.1",
743
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.40.1.tgz",
744
+ "integrity": "sha512-h8d28xzYb98fMQKUz0w2fMc1XuGzLLjdyxVIbhbil4ELfk5/orZlSTpF/xdI9C8K0I8lCkq+1En2RJsawZekkg==",
745
+ "cpu": [
746
+ "s390x"
747
+ ],
748
+ "dev": true,
749
+ "license": "MIT",
750
+ "optional": true,
751
+ "os": [
752
+ "linux"
753
+ ]
754
+ },
755
+ "node_modules/@rollup/rollup-linux-x64-gnu": {
756
+ "version": "4.40.1",
757
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.40.1.tgz",
758
+ "integrity": "sha512-XiK5z70PEFEFqcNj3/zRSz/qX4bp4QIraTy9QjwJAb/Z8GM7kVUsD0Uk8maIPeTyPCP03ChdI+VVmJriKYbRHQ==",
759
+ "cpu": [
760
+ "x64"
761
+ ],
762
+ "dev": true,
763
+ "license": "MIT",
764
+ "optional": true,
765
+ "os": [
766
+ "linux"
767
+ ]
768
+ },
769
+ "node_modules/@rollup/rollup-linux-x64-musl": {
770
+ "version": "4.40.1",
771
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.40.1.tgz",
772
+ "integrity": "sha512-2BRORitq5rQ4Da9blVovzNCMaUlyKrzMSvkVR0D4qPuOy/+pMCrh1d7o01RATwVy+6Fa1WBw+da7QPeLWU/1mQ==",
773
+ "cpu": [
774
+ "x64"
775
+ ],
776
+ "dev": true,
777
+ "license": "MIT",
778
+ "optional": true,
779
+ "os": [
780
+ "linux"
781
+ ]
782
+ },
783
+ "node_modules/@rollup/rollup-win32-arm64-msvc": {
784
+ "version": "4.40.1",
785
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.40.1.tgz",
786
+ "integrity": "sha512-b2bcNm9Kbde03H+q+Jjw9tSfhYkzrDUf2d5MAd1bOJuVplXvFhWz7tRtWvD8/ORZi7qSCy0idW6tf2HgxSXQSg==",
787
+ "cpu": [
788
+ "arm64"
789
+ ],
790
+ "dev": true,
791
+ "license": "MIT",
792
+ "optional": true,
793
+ "os": [
794
+ "win32"
795
+ ]
796
+ },
797
+ "node_modules/@rollup/rollup-win32-ia32-msvc": {
798
+ "version": "4.40.1",
799
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.40.1.tgz",
800
+ "integrity": "sha512-DfcogW8N7Zg7llVEfpqWMZcaErKfsj9VvmfSyRjCyo4BI3wPEfrzTtJkZG6gKP/Z92wFm6rz2aDO7/JfiR/whA==",
801
+ "cpu": [
802
+ "ia32"
803
+ ],
804
+ "dev": true,
805
+ "license": "MIT",
806
+ "optional": true,
807
+ "os": [
808
+ "win32"
809
+ ]
810
+ },
811
+ "node_modules/@rollup/rollup-win32-x64-msvc": {
812
+ "version": "4.40.1",
813
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.40.1.tgz",
814
+ "integrity": "sha512-ECyOuDeH3C1I8jH2MK1RtBJW+YPMvSfT0a5NN0nHfQYnDSJ6tUiZH3gzwVP5/Kfh/+Tt7tpWVF9LXNTnhTJ3kA==",
815
+ "cpu": [
816
+ "x64"
817
+ ],
818
+ "dev": true,
819
+ "license": "MIT",
820
+ "optional": true,
821
+ "os": [
822
+ "win32"
823
+ ]
824
+ },
825
+ "node_modules/@sveltejs/acorn-typescript": {
826
+ "version": "1.0.5",
827
+ "resolved": "https://registry.npmjs.org/@sveltejs/acorn-typescript/-/acorn-typescript-1.0.5.tgz",
828
+ "integrity": "sha512-IwQk4yfwLdibDlrXVE04jTZYlLnwsTT2PIOQQGNLWfjavGifnk1JD1LcZjZaBTRcxZu2FfPfNLOE04DSu9lqtQ==",
829
+ "dev": true,
830
+ "license": "MIT",
831
+ "peerDependencies": {
832
+ "acorn": "^8.9.0"
833
+ }
834
+ },
835
+ "node_modules/@sveltejs/adapter-auto": {
836
+ "version": "6.0.0",
837
+ "resolved": "https://registry.npmjs.org/@sveltejs/adapter-auto/-/adapter-auto-6.0.0.tgz",
838
+ "integrity": "sha512-7mR2/G7vlXakaOj6QBSG9dwBfTgWjV+UnEMB5Z6Xu0ZbdXda6c0su1fNkg0ab0zlilSkloMA2NjCna02/DR7sA==",
839
+ "dev": true,
840
+ "license": "MIT",
841
+ "dependencies": {
842
+ "import-meta-resolve": "^4.1.0"
843
+ },
844
+ "peerDependencies": {
845
+ "@sveltejs/kit": "^2.0.0"
846
+ }
847
+ },
848
+ "node_modules/@sveltejs/kit": {
849
+ "version": "2.20.7",
850
+ "resolved": "https://registry.npmjs.org/@sveltejs/kit/-/kit-2.20.7.tgz",
851
+ "integrity": "sha512-dVbLMubpJJSLI4OYB+yWYNHGAhgc2bVevWuBjDj8jFUXIJOAnLwYP3vsmtcgoxNGUXoq0rHS5f7MFCsryb6nzg==",
852
+ "dev": true,
853
+ "license": "MIT",
854
+ "dependencies": {
855
+ "@types/cookie": "^0.6.0",
856
+ "cookie": "^0.6.0",
857
+ "devalue": "^5.1.0",
858
+ "esm-env": "^1.2.2",
859
+ "import-meta-resolve": "^4.1.0",
860
+ "kleur": "^4.1.5",
861
+ "magic-string": "^0.30.5",
862
+ "mrmime": "^2.0.0",
863
+ "sade": "^1.8.1",
864
+ "set-cookie-parser": "^2.6.0",
865
+ "sirv": "^3.0.0"
866
+ },
867
+ "bin": {
868
+ "svelte-kit": "svelte-kit.js"
869
+ },
870
+ "engines": {
871
+ "node": ">=18.13"
872
+ },
873
+ "peerDependencies": {
874
+ "@sveltejs/vite-plugin-svelte": "^3.0.0 || ^4.0.0-next.1 || ^5.0.0",
875
+ "svelte": "^4.0.0 || ^5.0.0-next.0",
876
+ "vite": "^5.0.3 || ^6.0.0"
877
+ }
878
+ },
879
+ "node_modules/@sveltejs/vite-plugin-svelte": {
880
+ "version": "5.0.3",
881
+ "resolved": "https://registry.npmjs.org/@sveltejs/vite-plugin-svelte/-/vite-plugin-svelte-5.0.3.tgz",
882
+ "integrity": "sha512-MCFS6CrQDu1yGwspm4qtli0e63vaPCehf6V7pIMP15AsWgMKrqDGCPFF/0kn4SP0ii4aySu4Pa62+fIRGFMjgw==",
883
+ "dev": true,
884
+ "license": "MIT",
885
+ "dependencies": {
886
+ "@sveltejs/vite-plugin-svelte-inspector": "^4.0.1",
887
+ "debug": "^4.4.0",
888
+ "deepmerge": "^4.3.1",
889
+ "kleur": "^4.1.5",
890
+ "magic-string": "^0.30.15",
891
+ "vitefu": "^1.0.4"
892
+ },
893
+ "engines": {
894
+ "node": "^18.0.0 || ^20.0.0 || >=22"
895
+ },
896
+ "peerDependencies": {
897
+ "svelte": "^5.0.0",
898
+ "vite": "^6.0.0"
899
+ }
900
+ },
901
+ "node_modules/@sveltejs/vite-plugin-svelte-inspector": {
902
+ "version": "4.0.1",
903
+ "resolved": "https://registry.npmjs.org/@sveltejs/vite-plugin-svelte-inspector/-/vite-plugin-svelte-inspector-4.0.1.tgz",
904
+ "integrity": "sha512-J/Nmb2Q2y7mck2hyCX4ckVHcR5tu2J+MtBEQqpDrrgELZ2uvraQcK/ioCV61AqkdXFgriksOKIceDcQmqnGhVw==",
905
+ "dev": true,
906
+ "license": "MIT",
907
+ "dependencies": {
908
+ "debug": "^4.3.7"
909
+ },
910
+ "engines": {
911
+ "node": "^18.0.0 || ^20.0.0 || >=22"
912
+ },
913
+ "peerDependencies": {
914
+ "@sveltejs/vite-plugin-svelte": "^5.0.0",
915
+ "svelte": "^5.0.0",
916
+ "vite": "^6.0.0"
917
+ }
918
+ },
919
+ "node_modules/@types/cookie": {
920
+ "version": "0.6.0",
921
+ "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.6.0.tgz",
922
+ "integrity": "sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==",
923
+ "dev": true,
924
+ "license": "MIT"
925
+ },
926
+ "node_modules/@types/estree": {
927
+ "version": "1.0.7",
928
+ "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.7.tgz",
929
+ "integrity": "sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ==",
930
+ "dev": true,
931
+ "license": "MIT"
932
+ },
933
+ "node_modules/acorn": {
934
+ "version": "8.14.1",
935
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.1.tgz",
936
+ "integrity": "sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg==",
937
+ "dev": true,
938
+ "license": "MIT",
939
+ "bin": {
940
+ "acorn": "bin/acorn"
941
+ },
942
+ "engines": {
943
+ "node": ">=0.4.0"
944
+ }
945
+ },
946
+ "node_modules/aria-query": {
947
+ "version": "5.3.2",
948
+ "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.2.tgz",
949
+ "integrity": "sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==",
950
+ "dev": true,
951
+ "license": "Apache-2.0",
952
+ "engines": {
953
+ "node": ">= 0.4"
954
+ }
955
+ },
956
+ "node_modules/axobject-query": {
957
+ "version": "4.1.0",
958
+ "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-4.1.0.tgz",
959
+ "integrity": "sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==",
960
+ "dev": true,
961
+ "license": "Apache-2.0",
962
+ "engines": {
963
+ "node": ">= 0.4"
964
+ }
965
+ },
966
+ "node_modules/clsx": {
967
+ "version": "2.1.1",
968
+ "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz",
969
+ "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==",
970
+ "dev": true,
971
+ "license": "MIT",
972
+ "engines": {
973
+ "node": ">=6"
974
+ }
975
+ },
976
+ "node_modules/cookie": {
977
+ "version": "0.6.0",
978
+ "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz",
979
+ "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==",
980
+ "dev": true,
981
+ "license": "MIT",
982
+ "engines": {
983
+ "node": ">= 0.6"
984
+ }
985
+ },
986
+ "node_modules/debug": {
987
+ "version": "4.4.0",
988
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz",
989
+ "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==",
990
+ "dev": true,
991
+ "license": "MIT",
992
+ "dependencies": {
993
+ "ms": "^2.1.3"
994
+ },
995
+ "engines": {
996
+ "node": ">=6.0"
997
+ },
998
+ "peerDependenciesMeta": {
999
+ "supports-color": {
1000
+ "optional": true
1001
+ }
1002
+ }
1003
+ },
1004
+ "node_modules/deepmerge": {
1005
+ "version": "4.3.1",
1006
+ "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz",
1007
+ "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==",
1008
+ "dev": true,
1009
+ "license": "MIT",
1010
+ "engines": {
1011
+ "node": ">=0.10.0"
1012
+ }
1013
+ },
1014
+ "node_modules/devalue": {
1015
+ "version": "5.1.1",
1016
+ "resolved": "https://registry.npmjs.org/devalue/-/devalue-5.1.1.tgz",
1017
+ "integrity": "sha512-maua5KUiapvEwiEAe+XnlZ3Rh0GD+qI1J/nb9vrJc3muPXvcF/8gXYTWF76+5DAqHyDUtOIImEuo0YKE9mshVw==",
1018
+ "dev": true,
1019
+ "license": "MIT"
1020
+ },
1021
+ "node_modules/esbuild": {
1022
+ "version": "0.25.3",
1023
+ "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.3.tgz",
1024
+ "integrity": "sha512-qKA6Pvai73+M2FtftpNKRxJ78GIjmFXFxd/1DVBqGo/qNhLSfv+G12n9pNoWdytJC8U00TrViOwpjT0zgqQS8Q==",
1025
+ "dev": true,
1026
+ "hasInstallScript": true,
1027
+ "license": "MIT",
1028
+ "bin": {
1029
+ "esbuild": "bin/esbuild"
1030
+ },
1031
+ "engines": {
1032
+ "node": ">=18"
1033
+ },
1034
+ "optionalDependencies": {
1035
+ "@esbuild/aix-ppc64": "0.25.3",
1036
+ "@esbuild/android-arm": "0.25.3",
1037
+ "@esbuild/android-arm64": "0.25.3",
1038
+ "@esbuild/android-x64": "0.25.3",
1039
+ "@esbuild/darwin-arm64": "0.25.3",
1040
+ "@esbuild/darwin-x64": "0.25.3",
1041
+ "@esbuild/freebsd-arm64": "0.25.3",
1042
+ "@esbuild/freebsd-x64": "0.25.3",
1043
+ "@esbuild/linux-arm": "0.25.3",
1044
+ "@esbuild/linux-arm64": "0.25.3",
1045
+ "@esbuild/linux-ia32": "0.25.3",
1046
+ "@esbuild/linux-loong64": "0.25.3",
1047
+ "@esbuild/linux-mips64el": "0.25.3",
1048
+ "@esbuild/linux-ppc64": "0.25.3",
1049
+ "@esbuild/linux-riscv64": "0.25.3",
1050
+ "@esbuild/linux-s390x": "0.25.3",
1051
+ "@esbuild/linux-x64": "0.25.3",
1052
+ "@esbuild/netbsd-arm64": "0.25.3",
1053
+ "@esbuild/netbsd-x64": "0.25.3",
1054
+ "@esbuild/openbsd-arm64": "0.25.3",
1055
+ "@esbuild/openbsd-x64": "0.25.3",
1056
+ "@esbuild/sunos-x64": "0.25.3",
1057
+ "@esbuild/win32-arm64": "0.25.3",
1058
+ "@esbuild/win32-ia32": "0.25.3",
1059
+ "@esbuild/win32-x64": "0.25.3"
1060
+ }
1061
+ },
1062
+ "node_modules/esm-env": {
1063
+ "version": "1.2.2",
1064
+ "resolved": "https://registry.npmjs.org/esm-env/-/esm-env-1.2.2.tgz",
1065
+ "integrity": "sha512-Epxrv+Nr/CaL4ZcFGPJIYLWFom+YeV1DqMLHJoEd9SYRxNbaFruBwfEX/kkHUJf55j2+TUbmDcmuilbP1TmXHA==",
1066
+ "dev": true,
1067
+ "license": "MIT"
1068
+ },
1069
+ "node_modules/esrap": {
1070
+ "version": "1.4.6",
1071
+ "resolved": "https://registry.npmjs.org/esrap/-/esrap-1.4.6.tgz",
1072
+ "integrity": "sha512-F/D2mADJ9SHY3IwksD4DAXjTt7qt7GWUf3/8RhCNWmC/67tyb55dpimHmy7EplakFaflV0R/PC+fdSPqrRHAQw==",
1073
+ "dev": true,
1074
+ "license": "MIT",
1075
+ "dependencies": {
1076
+ "@jridgewell/sourcemap-codec": "^1.4.15"
1077
+ }
1078
+ },
1079
+ "node_modules/fdir": {
1080
+ "version": "6.4.4",
1081
+ "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.4.tgz",
1082
+ "integrity": "sha512-1NZP+GK4GfuAv3PqKvxQRDMjdSRZjnkq7KfhlNrCNNlZ0ygQFpebfrnfnq/W7fpUnAv9aGWmY1zKx7FYL3gwhg==",
1083
+ "dev": true,
1084
+ "license": "MIT",
1085
+ "peerDependencies": {
1086
+ "picomatch": "^3 || ^4"
1087
+ },
1088
+ "peerDependenciesMeta": {
1089
+ "picomatch": {
1090
+ "optional": true
1091
+ }
1092
+ }
1093
+ },
1094
+ "node_modules/fsevents": {
1095
+ "version": "2.3.3",
1096
+ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
1097
+ "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
1098
+ "dev": true,
1099
+ "hasInstallScript": true,
1100
+ "license": "MIT",
1101
+ "optional": true,
1102
+ "os": [
1103
+ "darwin"
1104
+ ],
1105
+ "engines": {
1106
+ "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
1107
+ }
1108
+ },
1109
+ "node_modules/import-meta-resolve": {
1110
+ "version": "4.1.0",
1111
+ "resolved": "https://registry.npmjs.org/import-meta-resolve/-/import-meta-resolve-4.1.0.tgz",
1112
+ "integrity": "sha512-I6fiaX09Xivtk+THaMfAwnA3MVA5Big1WHF1Dfx9hFuvNIWpXnorlkzhcQf6ehrqQiiZECRt1poOAkPmer3ruw==",
1113
+ "dev": true,
1114
+ "license": "MIT",
1115
+ "funding": {
1116
+ "type": "github",
1117
+ "url": "https://github.com/sponsors/wooorm"
1118
+ }
1119
+ },
1120
+ "node_modules/is-reference": {
1121
+ "version": "3.0.3",
1122
+ "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-3.0.3.tgz",
1123
+ "integrity": "sha512-ixkJoqQvAP88E6wLydLGGqCJsrFUnqoH6HnaczB8XmDH1oaWU+xxdptvikTgaEhtZ53Ky6YXiBuUI2WXLMCwjw==",
1124
+ "dev": true,
1125
+ "license": "MIT",
1126
+ "dependencies": {
1127
+ "@types/estree": "^1.0.6"
1128
+ }
1129
+ },
1130
+ "node_modules/kleur": {
1131
+ "version": "4.1.5",
1132
+ "resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz",
1133
+ "integrity": "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==",
1134
+ "dev": true,
1135
+ "license": "MIT",
1136
+ "engines": {
1137
+ "node": ">=6"
1138
+ }
1139
+ },
1140
+ "node_modules/locate-character": {
1141
+ "version": "3.0.0",
1142
+ "resolved": "https://registry.npmjs.org/locate-character/-/locate-character-3.0.0.tgz",
1143
+ "integrity": "sha512-SW13ws7BjaeJ6p7Q6CO2nchbYEc3X3J6WrmTTDto7yMPqVSZTUyY5Tjbid+Ab8gLnATtygYtiDIJGQRRn2ZOiA==",
1144
+ "dev": true,
1145
+ "license": "MIT"
1146
+ },
1147
+ "node_modules/magic-string": {
1148
+ "version": "0.30.17",
1149
+ "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.17.tgz",
1150
+ "integrity": "sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==",
1151
+ "dev": true,
1152
+ "license": "MIT",
1153
+ "dependencies": {
1154
+ "@jridgewell/sourcemap-codec": "^1.5.0"
1155
+ }
1156
+ },
1157
+ "node_modules/mri": {
1158
+ "version": "1.2.0",
1159
+ "resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz",
1160
+ "integrity": "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==",
1161
+ "dev": true,
1162
+ "license": "MIT",
1163
+ "engines": {
1164
+ "node": ">=4"
1165
+ }
1166
+ },
1167
+ "node_modules/mrmime": {
1168
+ "version": "2.0.1",
1169
+ "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.1.tgz",
1170
+ "integrity": "sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==",
1171
+ "dev": true,
1172
+ "license": "MIT",
1173
+ "engines": {
1174
+ "node": ">=10"
1175
+ }
1176
+ },
1177
+ "node_modules/ms": {
1178
+ "version": "2.1.3",
1179
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
1180
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
1181
+ "dev": true,
1182
+ "license": "MIT"
1183
+ },
1184
+ "node_modules/nanoid": {
1185
+ "version": "3.3.11",
1186
+ "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz",
1187
+ "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==",
1188
+ "dev": true,
1189
+ "funding": [
1190
+ {
1191
+ "type": "github",
1192
+ "url": "https://github.com/sponsors/ai"
1193
+ }
1194
+ ],
1195
+ "license": "MIT",
1196
+ "bin": {
1197
+ "nanoid": "bin/nanoid.cjs"
1198
+ },
1199
+ "engines": {
1200
+ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
1201
+ }
1202
+ },
1203
+ "node_modules/picocolors": {
1204
+ "version": "1.1.1",
1205
+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
1206
+ "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
1207
+ "dev": true,
1208
+ "license": "ISC"
1209
+ },
1210
+ "node_modules/picomatch": {
1211
+ "version": "4.0.2",
1212
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz",
1213
+ "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==",
1214
+ "dev": true,
1215
+ "license": "MIT",
1216
+ "engines": {
1217
+ "node": ">=12"
1218
+ },
1219
+ "funding": {
1220
+ "url": "https://github.com/sponsors/jonschlinkert"
1221
+ }
1222
+ },
1223
+ "node_modules/postcss": {
1224
+ "version": "8.5.3",
1225
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.3.tgz",
1226
+ "integrity": "sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A==",
1227
+ "dev": true,
1228
+ "funding": [
1229
+ {
1230
+ "type": "opencollective",
1231
+ "url": "https://opencollective.com/postcss/"
1232
+ },
1233
+ {
1234
+ "type": "tidelift",
1235
+ "url": "https://tidelift.com/funding/github/npm/postcss"
1236
+ },
1237
+ {
1238
+ "type": "github",
1239
+ "url": "https://github.com/sponsors/ai"
1240
+ }
1241
+ ],
1242
+ "license": "MIT",
1243
+ "dependencies": {
1244
+ "nanoid": "^3.3.8",
1245
+ "picocolors": "^1.1.1",
1246
+ "source-map-js": "^1.2.1"
1247
+ },
1248
+ "engines": {
1249
+ "node": "^10 || ^12 || >=14"
1250
+ }
1251
+ },
1252
+ "node_modules/rollup": {
1253
+ "version": "4.40.1",
1254
+ "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.40.1.tgz",
1255
+ "integrity": "sha512-C5VvvgCCyfyotVITIAv+4efVytl5F7wt+/I2i9q9GZcEXW9BP52YYOXC58igUi+LFZVHukErIIqQSWwv/M3WRw==",
1256
+ "dev": true,
1257
+ "license": "MIT",
1258
+ "dependencies": {
1259
+ "@types/estree": "1.0.7"
1260
+ },
1261
+ "bin": {
1262
+ "rollup": "dist/bin/rollup"
1263
+ },
1264
+ "engines": {
1265
+ "node": ">=18.0.0",
1266
+ "npm": ">=8.0.0"
1267
+ },
1268
+ "optionalDependencies": {
1269
+ "@rollup/rollup-android-arm-eabi": "4.40.1",
1270
+ "@rollup/rollup-android-arm64": "4.40.1",
1271
+ "@rollup/rollup-darwin-arm64": "4.40.1",
1272
+ "@rollup/rollup-darwin-x64": "4.40.1",
1273
+ "@rollup/rollup-freebsd-arm64": "4.40.1",
1274
+ "@rollup/rollup-freebsd-x64": "4.40.1",
1275
+ "@rollup/rollup-linux-arm-gnueabihf": "4.40.1",
1276
+ "@rollup/rollup-linux-arm-musleabihf": "4.40.1",
1277
+ "@rollup/rollup-linux-arm64-gnu": "4.40.1",
1278
+ "@rollup/rollup-linux-arm64-musl": "4.40.1",
1279
+ "@rollup/rollup-linux-loongarch64-gnu": "4.40.1",
1280
+ "@rollup/rollup-linux-powerpc64le-gnu": "4.40.1",
1281
+ "@rollup/rollup-linux-riscv64-gnu": "4.40.1",
1282
+ "@rollup/rollup-linux-riscv64-musl": "4.40.1",
1283
+ "@rollup/rollup-linux-s390x-gnu": "4.40.1",
1284
+ "@rollup/rollup-linux-x64-gnu": "4.40.1",
1285
+ "@rollup/rollup-linux-x64-musl": "4.40.1",
1286
+ "@rollup/rollup-win32-arm64-msvc": "4.40.1",
1287
+ "@rollup/rollup-win32-ia32-msvc": "4.40.1",
1288
+ "@rollup/rollup-win32-x64-msvc": "4.40.1",
1289
+ "fsevents": "~2.3.2"
1290
+ }
1291
+ },
1292
+ "node_modules/sade": {
1293
+ "version": "1.8.1",
1294
+ "resolved": "https://registry.npmjs.org/sade/-/sade-1.8.1.tgz",
1295
+ "integrity": "sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==",
1296
+ "dev": true,
1297
+ "license": "MIT",
1298
+ "dependencies": {
1299
+ "mri": "^1.1.0"
1300
+ },
1301
+ "engines": {
1302
+ "node": ">=6"
1303
+ }
1304
+ },
1305
+ "node_modules/set-cookie-parser": {
1306
+ "version": "2.7.1",
1307
+ "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.7.1.tgz",
1308
+ "integrity": "sha512-IOc8uWeOZgnb3ptbCURJWNjWUPcO3ZnTTdzsurqERrP6nPyv+paC55vJM0LpOlT2ne+Ix+9+CRG1MNLlyZ4GjQ==",
1309
+ "dev": true,
1310
+ "license": "MIT"
1311
+ },
1312
+ "node_modules/sirv": {
1313
+ "version": "3.0.1",
1314
+ "resolved": "https://registry.npmjs.org/sirv/-/sirv-3.0.1.tgz",
1315
+ "integrity": "sha512-FoqMu0NCGBLCcAkS1qA+XJIQTR6/JHfQXl+uGteNCQ76T91DMUjPa9xfmeqMY3z80nLSg9yQmNjK0Px6RWsH/A==",
1316
+ "dev": true,
1317
+ "license": "MIT",
1318
+ "dependencies": {
1319
+ "@polka/url": "^1.0.0-next.24",
1320
+ "mrmime": "^2.0.0",
1321
+ "totalist": "^3.0.0"
1322
+ },
1323
+ "engines": {
1324
+ "node": ">=18"
1325
+ }
1326
+ },
1327
+ "node_modules/source-map-js": {
1328
+ "version": "1.2.1",
1329
+ "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
1330
+ "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
1331
+ "dev": true,
1332
+ "license": "BSD-3-Clause",
1333
+ "engines": {
1334
+ "node": ">=0.10.0"
1335
+ }
1336
+ },
1337
+ "node_modules/svelte": {
1338
+ "version": "5.28.2",
1339
+ "resolved": "https://registry.npmjs.org/svelte/-/svelte-5.28.2.tgz",
1340
+ "integrity": "sha512-FbWBxgWOpQfhKvoGJv/TFwzqb4EhJbwCD17dB0tEpQiw1XyUEKZJtgm4nA4xq3LLsMo7hu5UY/BOFmroAxKTMg==",
1341
+ "dev": true,
1342
+ "license": "MIT",
1343
+ "dependencies": {
1344
+ "@ampproject/remapping": "^2.3.0",
1345
+ "@jridgewell/sourcemap-codec": "^1.5.0",
1346
+ "@sveltejs/acorn-typescript": "^1.0.5",
1347
+ "@types/estree": "^1.0.5",
1348
+ "acorn": "^8.12.1",
1349
+ "aria-query": "^5.3.1",
1350
+ "axobject-query": "^4.1.0",
1351
+ "clsx": "^2.1.1",
1352
+ "esm-env": "^1.2.1",
1353
+ "esrap": "^1.4.6",
1354
+ "is-reference": "^3.0.3",
1355
+ "locate-character": "^3.0.0",
1356
+ "magic-string": "^0.30.11",
1357
+ "zimmerframe": "^1.1.2"
1358
+ },
1359
+ "engines": {
1360
+ "node": ">=18"
1361
+ }
1362
+ },
1363
+ "node_modules/tinyglobby": {
1364
+ "version": "0.2.13",
1365
+ "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.13.tgz",
1366
+ "integrity": "sha512-mEwzpUgrLySlveBwEVDMKk5B57bhLPYovRfPAXD5gA/98Opn0rCDj3GtLwFvCvH5RK9uPCExUROW5NjDwvqkxw==",
1367
+ "dev": true,
1368
+ "license": "MIT",
1369
+ "dependencies": {
1370
+ "fdir": "^6.4.4",
1371
+ "picomatch": "^4.0.2"
1372
+ },
1373
+ "engines": {
1374
+ "node": ">=12.0.0"
1375
+ },
1376
+ "funding": {
1377
+ "url": "https://github.com/sponsors/SuperchupuDev"
1378
+ }
1379
+ },
1380
+ "node_modules/totalist": {
1381
+ "version": "3.0.1",
1382
+ "resolved": "https://registry.npmjs.org/totalist/-/totalist-3.0.1.tgz",
1383
+ "integrity": "sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==",
1384
+ "dev": true,
1385
+ "license": "MIT",
1386
+ "engines": {
1387
+ "node": ">=6"
1388
+ }
1389
+ },
1390
+ "node_modules/vite": {
1391
+ "version": "6.3.3",
1392
+ "resolved": "https://registry.npmjs.org/vite/-/vite-6.3.3.tgz",
1393
+ "integrity": "sha512-5nXH+QsELbFKhsEfWLkHrvgRpTdGJzqOZ+utSdmPTvwHmvU6ITTm3xx+mRusihkcI8GeC7lCDyn3kDtiki9scw==",
1394
+ "dev": true,
1395
+ "license": "MIT",
1396
+ "dependencies": {
1397
+ "esbuild": "^0.25.0",
1398
+ "fdir": "^6.4.4",
1399
+ "picomatch": "^4.0.2",
1400
+ "postcss": "^8.5.3",
1401
+ "rollup": "^4.34.9",
1402
+ "tinyglobby": "^0.2.13"
1403
+ },
1404
+ "bin": {
1405
+ "vite": "bin/vite.js"
1406
+ },
1407
+ "engines": {
1408
+ "node": "^18.0.0 || ^20.0.0 || >=22.0.0"
1409
+ },
1410
+ "funding": {
1411
+ "url": "https://github.com/vitejs/vite?sponsor=1"
1412
+ },
1413
+ "optionalDependencies": {
1414
+ "fsevents": "~2.3.3"
1415
+ },
1416
+ "peerDependencies": {
1417
+ "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0",
1418
+ "jiti": ">=1.21.0",
1419
+ "less": "*",
1420
+ "lightningcss": "^1.21.0",
1421
+ "sass": "*",
1422
+ "sass-embedded": "*",
1423
+ "stylus": "*",
1424
+ "sugarss": "*",
1425
+ "terser": "^5.16.0",
1426
+ "tsx": "^4.8.1",
1427
+ "yaml": "^2.4.2"
1428
+ },
1429
+ "peerDependenciesMeta": {
1430
+ "@types/node": {
1431
+ "optional": true
1432
+ },
1433
+ "jiti": {
1434
+ "optional": true
1435
+ },
1436
+ "less": {
1437
+ "optional": true
1438
+ },
1439
+ "lightningcss": {
1440
+ "optional": true
1441
+ },
1442
+ "sass": {
1443
+ "optional": true
1444
+ },
1445
+ "sass-embedded": {
1446
+ "optional": true
1447
+ },
1448
+ "stylus": {
1449
+ "optional": true
1450
+ },
1451
+ "sugarss": {
1452
+ "optional": true
1453
+ },
1454
+ "terser": {
1455
+ "optional": true
1456
+ },
1457
+ "tsx": {
1458
+ "optional": true
1459
+ },
1460
+ "yaml": {
1461
+ "optional": true
1462
+ }
1463
+ }
1464
+ },
1465
+ "node_modules/vitefu": {
1466
+ "version": "1.0.6",
1467
+ "resolved": "https://registry.npmjs.org/vitefu/-/vitefu-1.0.6.tgz",
1468
+ "integrity": "sha512-+Rex1GlappUyNN6UfwbVZne/9cYC4+R2XDk9xkNXBKMw6HQagdX9PgZ8V2v1WUSK1wfBLp7qbI1+XSNIlB1xmA==",
1469
+ "dev": true,
1470
+ "license": "MIT",
1471
+ "workspaces": [
1472
+ "tests/deps/*",
1473
+ "tests/projects/*"
1474
+ ],
1475
+ "peerDependencies": {
1476
+ "vite": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0"
1477
+ },
1478
+ "peerDependenciesMeta": {
1479
+ "vite": {
1480
+ "optional": true
1481
+ }
1482
+ }
1483
+ },
1484
+ "node_modules/zimmerframe": {
1485
+ "version": "1.1.2",
1486
+ "resolved": "https://registry.npmjs.org/zimmerframe/-/zimmerframe-1.1.2.tgz",
1487
+ "integrity": "sha512-rAbqEGa8ovJy4pyBxZM70hg4pE6gDgaQ0Sl9M3enG3I0d6H4XSAM3GeNGLKnsBpuijUow064sf7ww1nutC5/3w==",
1488
+ "dev": true,
1489
+ "license": "MIT"
1490
+ }
1491
+ }
1492
+ }
package.json ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "type": "module",
3
+ "dependencies": {
4
+ "@huggingface/inference": "^3.9.2"
5
+ },
6
+ "scripts": {
7
+ "dev": "vite dev",
8
+ "build": "vite build",
9
+ "preview": "vite preview"
10
+ },
11
+ "devDependencies": {
12
+ "@sveltejs/adapter-auto": "^6.0.0",
13
+ "@sveltejs/kit": "^2.20.7",
14
+ "@sveltejs/vite-plugin-svelte": "^5.0.3",
15
+ "svelte": "^5.28.2",
16
+ "vite": "^6.3.3"
17
+ }
18
+ }
src/app.html ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="utf-8" />
5
+ <link rel="icon" href="%sveltekit.assets%/favicon.png" />
6
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
7
+ %sveltekit.head%
8
+ </head>
9
+ <body data-sveltekit-preload-data="hover">
10
+ <div style="display: contents">%sveltekit.body%</div>
11
+ </body>
12
+ </html>
src/routes/+page.svelte ADDED
@@ -0,0 +1,765 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <script>
2
+ import { onDestroy, tick } from 'svelte';
3
+
4
+ // Core state
5
+ let mainPrompt = '';
6
+ let loraSearchQuery = '';
7
+ let foundLoras = []; // Array to store {id: string, author: string}
8
+ let selectedLoraId = '';
9
+ let generatedImageUrl = '';
10
+
11
+ // Status flags
12
+ let isSearchingLoras = false;
13
+ let isGeneratingImage = false;
14
+ let searchError = '';
15
+ let generationError = '';
16
+
17
+ // Interaction state
18
+ let showLoraSearch = false; // Controls visibility of LoRA search section
19
+ let debounceTimeout;
20
+ let animatedLoadingText = ''; // For animated text during generation
21
+ let loadingIntervalId = null;
22
+
23
+ // --- Phases (Derived Reactively) ---
24
+ $: isInPromptPhase = !showLoraSearch && !isGeneratingImage && !generatedImageUrl;
25
+ $: isInLoraSearchPhase = showLoraSearch && !selectedLoraId && !isGeneratingImage && !generatedImageUrl;
26
+ $: isInLoraSelectedPhase = showLoraSearch && selectedLoraId && !isGeneratingImage && !generatedImageUrl;
27
+ $: isInGeneratingPhase = isGeneratingImage;
28
+ $: isInResultPhase = generatedImageUrl && !isGeneratingImage;
29
+
30
+ // --- Debounced LoRA Search ---
31
+ function debounce(func, delay) {
32
+ return function(...args) {
33
+ clearTimeout(debounceTimeout);
34
+ debounceTimeout = setTimeout(() => {
35
+ func.apply(this, args);
36
+ }, delay);
37
+ };
38
+ }
39
+
40
+ async function searchLoras(query) {
41
+ if (!query || query.trim().length < 3) {
42
+ foundLoras = [];
43
+ searchError = query.trim().length > 0 ? 'Enter at least 3 characters.' : '';
44
+ isSearchingLoras = false;
45
+ // Don't reset selection if query becomes too short temporarily
46
+ // selectedLoraId = '';
47
+ return;
48
+ }
49
+
50
+ isSearchingLoras = true;
51
+ searchError = '';
52
+ // Don't clear foundLoras immediately, prevents flicker
53
+ // foundLoras = [];
54
+ // selectedLoraId = ''; // Reset selection on new search? Maybe not, allow refinement.
55
+ generationError = ''; // Clear generation error
56
+
57
+ console.log(`Searching for: ${query}`);
58
+
59
+ try {
60
+ const response = await fetch('/api/search-loras', {
61
+ method: 'POST',
62
+ headers: { 'Content-Type': 'application/json' },
63
+ body: JSON.stringify({ query: query })
64
+ });
65
+
66
+ if (!response.ok) {
67
+ const errorData = await response.json();
68
+ throw new Error(errorData.message || `HTTP error ${response.status}`);
69
+ }
70
+
71
+ const results = await response.json();
72
+
73
+ console.log('Found LoRAs:', results.length, results); // Log results received
74
+
75
+ // Check if the previously selected LoRA is still valid in the new results
76
+ let previousSelectionStillValid = selectedLoraId && results.some(lora => lora.id === selectedLoraId);
77
+
78
+ foundLoras = results;
79
+
80
+ // If the previous selection is no longer valid, or if nothing was selected,
81
+ // automatically select the first result if available.
82
+ if (!previousSelectionStillValid && foundLoras.length > 0) {
83
+ selectedLoraId = foundLoras[0].id;
84
+ // Clear any generation error since we made a selection
85
+ generationError = '';
86
+ } else if (!previousSelectionStillValid) {
87
+ // If previous selection invalid AND no new results, clear selection
88
+ selectedLoraId = '';
89
+ }
90
+ // If previousSelectionStillValid is true, selectedLoraId remains unchanged.
91
+
92
+ if (foundLoras.length === 0) {
93
+ searchError = 'No matching LoRAs found.';
94
+ }
95
+ } catch (err) {
96
+ console.error('Search error:', err);
97
+ searchError = err.message || 'Failed to search.';
98
+ selectedLoraId = ''; // Reset selection on error
99
+ foundLoras = []; // Clear results on error
100
+ } finally {
101
+ isSearchingLoras = false;
102
+ }
103
+ }
104
+
105
+ const debouncedSearchLoras = debounce(searchLoras, 400); // 400ms delay
106
+
107
+ function handleLoraSearchInput(event) {
108
+ const query = event.target.value;
109
+ loraSearchQuery = query;
110
+ selectedLoraId = ''; // Clear selection when search query changes
111
+ searchError = '';
112
+ isSearchingLoras = query.trim().length >= 3;
113
+ debouncedSearchLoras(query);
114
+ }
115
+
116
+ function handleLoraSelection(loraId) {
117
+ selectedLoraId = loraId;
118
+ generationError = ''; // Clear error on selection
119
+ // No automatic generation, wait for button click
120
+ }
121
+
122
+ // --- Image Generation ---
123
+ async function generateImage() {
124
+ if (!selectedLoraId || !mainPrompt || isGeneratingImage) {
125
+ generationError = 'Prompt and LoRA style must be selected.';
126
+ return;
127
+ }
128
+
129
+ isGeneratingImage = true;
130
+ generationError = '';
131
+ showLoraSearch = false; // Hide search during generation
132
+ // Clean up previous object URL if it exists
133
+ if (generatedImageUrl.startsWith('blob:')) {
134
+ URL.revokeObjectURL(generatedImageUrl);
135
+ generatedImageUrl = '';
136
+ }
137
+
138
+ try {
139
+ const response = await fetch('/api/generate-image', {
140
+ method: 'POST',
141
+ headers: { 'Content-Type': 'application/json' },
142
+ body: JSON.stringify({ loraModelId: selectedLoraId, prompt: mainPrompt })
143
+ });
144
+
145
+ if (!response.ok) {
146
+ let errorMsg = `Generation failed (${response.status})`;
147
+ try {
148
+ const errorData = await response.json();
149
+ errorMsg = errorData.message || errorMsg;
150
+ } catch (e) { /* Ignore */ }
151
+ throw new Error(errorMsg);
152
+ }
153
+
154
+ const imageBlob = await response.blob();
155
+ generatedImageUrl = URL.createObjectURL(imageBlob);
156
+ } catch (err) {
157
+ console.error('Generation error:', err);
158
+ generationError = err.message || 'Failed to generate image.';
159
+ generatedImageUrl = ''; // Ensure no broken image shows
160
+ } finally {
161
+ isGeneratingImage = false;
162
+ // Stay in result phase (or error)
163
+ }
164
+ }
165
+
166
+ // --- Keyboard Handling ---
167
+ function handlePromptKeydown(event) {
168
+ if (event.key === 'Enter' && !event.shiftKey && mainPrompt.trim()) {
169
+ event.preventDefault(); // Prevent newline
170
+ proceedFromPrompt();
171
+ }
172
+ }
173
+
174
+ // --- Actions ---
175
+ function proceedFromPrompt() {
176
+ if (mainPrompt.trim()) {
177
+ showLoraSearch = true;
178
+ // Reset LoRA search state if needed
179
+ loraSearchQuery = '';
180
+ foundLoras = [];
181
+ selectedLoraId = '';
182
+ searchError = '';
183
+ generationError = '';
184
+ // Focus the LoRA input shortly after it appears
185
+ tick().then(() => {
186
+ const loraInput = document.querySelector('.lora-search-input');
187
+ if (loraInput) loraInput.focus();
188
+ });
189
+ }
190
+ }
191
+
192
+ function goBackToPrompt() {
193
+ showLoraSearch = false;
194
+ generationError = '';
195
+ searchError = '';
196
+ // Keep prompt value
197
+ // Focus prompt input
198
+ tick().then(() => {
199
+ const promptInput = document.querySelector('.prompt-input');
200
+ if (promptInput) promptInput.focus();
201
+ });
202
+ }
203
+
204
+ function startOver() {
205
+ mainPrompt = '';
206
+ loraSearchQuery = '';
207
+ foundLoras = [];
208
+ selectedLoraId = '';
209
+ if (generatedImageUrl.startsWith('blob:')) {
210
+ URL.revokeObjectURL(generatedImageUrl);
211
+ }
212
+ generatedImageUrl = '';
213
+ isSearchingLoras = false;
214
+ isGeneratingImage = false;
215
+ searchError = '';
216
+ generationError = '';
217
+ showLoraSearch = false;
218
+ // Focus prompt input
219
+ tick().then(() => {
220
+ const promptInput = document.querySelector('.prompt-input');
221
+ if (promptInput) promptInput.focus();
222
+ });
223
+ }
224
+
225
+ // --- Single Button Logic ---
226
+ $: buttonText = (() => {
227
+ if (isInGeneratingPhase) return 'Generating...';
228
+ if (isInResultPhase) return 'Start Over';
229
+ if (isInLoraSelectedPhase) return 'Generate Image';
230
+ if (isInLoraSearchPhase) return 'Select a Style'; // Or maybe disabled?
231
+ if (isInPromptPhase) return 'Choose Style →';
232
+ return '...'; // Default/fallback
233
+ })();
234
+
235
+ $: isButtonDisabled = (() => {
236
+ if (isInGeneratingPhase) return true;
237
+ if (isInResultPhase) return false; // Always allow start over
238
+ if (isInLoraSelectedPhase) return false; // Ready to generate
239
+ if (isInLoraSearchPhase) return !selectedLoraId; // Disabled until selection (or enable to go back?) No, separate back button is better
240
+ if (isInPromptPhase) return !mainPrompt.trim();
241
+ return true;
242
+ })();
243
+
244
+ function handleButtonClick() {
245
+ if (isInGeneratingPhase) return; // Should be disabled anyway
246
+ if (isInResultPhase) {
247
+ startOver();
248
+ } else if (isInLoraSelectedPhase) {
249
+ generateImage();
250
+ } else if (isInLoraSearchPhase) {
251
+ // Button should ideally be disabled here until selection. If clicked, do nothing or maybe focus input.
252
+ } else if (isInPromptPhase) {
253
+ proceedFromPrompt();
254
+ }
255
+ }
256
+
257
+
258
+ // --- Image Error Handling ---
259
+ function handleImageError(event) {
260
+ // Hide the broken image
261
+ event.target.style.display = 'none';
262
+ // Find and show the error message paragraph that should be right after the image
263
+ const errorMsgElement = event.target.nextElementSibling;
264
+ if (errorMsgElement && errorMsgElement.classList.contains('image-load-error')) {
265
+ errorMsgElement.style.display = 'block';
266
+ }
267
+ }
268
+
269
+ // --- Reactive Animation Logic ---
270
+ $: {
271
+ if (isGeneratingImage && !loadingIntervalId) {
272
+ const steps = [
273
+ `Prompt: ${mainPrompt}`,
274
+ `Style: ${selectedLoraId}`,
275
+ 'Generating...'
276
+ ];
277
+ let currentStepIndex = 0;
278
+
279
+ // Set initial text immediately
280
+ animatedLoadingText = steps[currentStepIndex];
281
+
282
+ loadingIntervalId = setInterval(() => {
283
+ currentStepIndex = (currentStepIndex + 1) % steps.length;
284
+ animatedLoadingText = steps[currentStepIndex];
285
+ }, 1000); // Change text every 1 second
286
+ } else if (!isGeneratingImage && loadingIntervalId) {
287
+ clearInterval(loadingIntervalId);
288
+ loadingIntervalId = null;
289
+ animatedLoadingText = ''; // Clear text when done
290
+ }
291
+ }
292
+
293
+ // --- Lifecycle ---
294
+ onDestroy(() => {
295
+ clearTimeout(debounceTimeout);
296
+ if (loadingIntervalId) {
297
+ clearInterval(loadingIntervalId); // Ensure cleanup on destroy
298
+ }
299
+ if (generatedImageUrl.startsWith('blob:')) {
300
+ URL.revokeObjectURL(generatedImageUrl);
301
+ }
302
+ });
303
+ </script>
304
+
305
+ <svelte:head>
306
+ <title>Image Generator</title>
307
+ </svelte:head>
308
+
309
+ <main class="app-container">
310
+
311
+ <!-- Prompt Input -->
312
+ {#if isInPromptPhase || isInLoraSearchPhase || isInLoraSelectedPhase}
313
+ <section class="prompt-section" class:hidden={!isInPromptPhase}>
314
+ <textarea
315
+ class="prompt-input"
316
+ bind:value={mainPrompt}
317
+ placeholder="Describe your image..."
318
+ rows="3"
319
+ on:keydown={handlePromptKeydown}
320
+ disabled={!isInPromptPhase}
321
+ ></textarea>
322
+ </section>
323
+ {/if}
324
+
325
+ <!-- LoRA Search & Selection -->
326
+ {#if showLoraSearch && !isInGeneratingPhase && !isInResultPhase}
327
+ <section class="lora-section">
328
+ <button class="back-button" on:click={goBackToPrompt} title="Back to Prompt">&larr; Edit Prompt</button>
329
+ <div class="search-container">
330
+ <input
331
+ type="search"
332
+ class="lora-search-input"
333
+ bind:value={loraSearchQuery}
334
+ on:input={handleLoraSearchInput}
335
+ placeholder="Search for a style (e.g., watercolor)..."
336
+ disabled={isGeneratingImage}
337
+ />
338
+ {#if isSearchingLoras}<div class="spinner"></div>{/if}
339
+ </div>
340
+
341
+ {#if searchError}<p class="error-message">{searchError}</p>{/if}
342
+
343
+ {#if !isSearchingLoras && foundLoras.length > 0}
344
+ <ul class="lora-list">
345
+ {#each foundLoras as lora (lora.id)}
346
+ <li>
347
+ <button
348
+ class="lora-item"
349
+ class:selected={selectedLoraId === lora.id}
350
+ on:click={() => handleLoraSelection(lora.id)}
351
+ title={lora.id}
352
+ >
353
+ {#if lora.thumbnail}
354
+ <img
355
+ src={lora.thumbnail}
356
+ alt="{lora.id} thumbnail"
357
+ class="lora-thumbnail"
358
+ loading="lazy"
359
+ />
360
+ {:else}
361
+ <div class="lora-thumbnail-placeholder"></div>
362
+ {/if}
363
+ <div class="lora-info">
364
+ <span class="lora-name">{lora.id.split('/').pop()}</span>
365
+ <span class="lora-author">by {lora.author}</span>
366
+ </div>
367
+ </button>
368
+ </li>
369
+ {/each}
370
+ </ul>
371
+ {:else if !isSearchingLoras && loraSearchQuery.trim().length >= 3 && !searchError}
372
+ <p class="info-message">No styles found matching "{loraSearchQuery}".</p>
373
+ {/if}
374
+ </section>
375
+ {/if}
376
+
377
+ <!-- Generating State -->
378
+ {#if isInGeneratingPhase}
379
+ <section class="generating-section">
380
+ <div class="spinner large"></div>
381
+ {#key animatedLoadingText} <!-- Use key block for animation trigger -->
382
+ <p class="loading-text" in:fade={{ duration: 300 }} out:fade={{ duration: 300 }}>
383
+ {animatedLoadingText}
384
+ </p>
385
+ {/key}
386
+ </section>
387
+ {/if}
388
+
389
+
390
+ <!-- Result Display -->
391
+ {#if isInResultPhase}
392
+ <section class="result-section">
393
+ {#if generationError}
394
+ <p class="error-message fatal">{generationError}</p>
395
+ {/if}
396
+ {#if generatedImageUrl}
397
+ <img
398
+ class="result-image"
399
+ src={generatedImageUrl}
400
+ alt="Generated: {mainPrompt}"
401
+ on:error={handleImageError}
402
+ />
403
+ <p class="error-message image-load-error" style="display: none;">Failed to load generated image.</p>
404
+ {/if}
405
+ </section>
406
+ {/if}
407
+
408
+
409
+ <!-- Action Button -->
410
+ <div class="action-button-container">
411
+ {#if !isInGeneratingPhase}
412
+ <button
413
+ class="action-button"
414
+ on:click={handleButtonClick}
415
+ disabled={isButtonDisabled}
416
+ >
417
+ {buttonText}
418
+ </button>
419
+ {/if}
420
+ </div>
421
+
422
+ </main>
423
+
424
+ <style>
425
+ :root {
426
+ --bg-color: #121212; /* Dark background */
427
+ --primary-color: #bb86fc; /* Purple accent */
428
+ --primary-variant: #3700b3;
429
+ --secondary-color: #03dac6; /* Teal accent */
430
+ --text-color: #e0e0e0; /* Light text */
431
+ --text-secondary: #a0a0a0; /* Dimmer text */
432
+ --surface-color: #1e1e1e; /* Slightly lighter surface */
433
+ --error-color: #cf6679;
434
+ --border-color: #333;
435
+ --input-bg: #2a2a2a;
436
+ --selected-bg: rgba(187, 134, 252, 0.2); /* Semi-transparent primary */
437
+ }
438
+
439
+ /* Basic Reset & Body */
440
+ * {
441
+ box-sizing: border-box;
442
+ margin: 0;
443
+ padding: 0;
444
+ }
445
+
446
+ html, body {
447
+ height: 100%;
448
+ background-color: var(--bg-color);
449
+ color: var(--text-color);
450
+ font-family: 'Inter', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
451
+ font-size: 16px;
452
+ line-height: 1.6;
453
+ overflow: hidden; /* Prevent body scroll */
454
+ }
455
+
456
+ /* Main App Container */
457
+ .app-container {
458
+ display: flex;
459
+ flex-direction: column;
460
+ height: 100vh; /* Full viewport height */
461
+ width: 100vw; /* Full viewport width */
462
+ padding: 2rem;
463
+ padding-bottom: 8rem; /* Space for action button */
464
+ overflow-y: auto; /* Allow content scrolling if needed */
465
+ position: relative;
466
+ }
467
+
468
+ /* Sections */
469
+ section {
470
+ width: 100%;
471
+ max-width: 800px; /* Limit content width */
472
+ margin: 0 auto; /* Center content */
473
+ padding: 1rem 0;
474
+ }
475
+
476
+ section.hidden {
477
+ display: none;
478
+ }
479
+
480
+ /* Prompt Input */
481
+ .prompt-section {
482
+ flex-grow: 1; /* Takes up space initially */
483
+ display: flex;
484
+ align-items: center; /* Vertically center */
485
+ justify-content: center;
486
+ }
487
+ .prompt-input {
488
+ width: 100%;
489
+ padding: 1.5rem;
490
+ border: 1px solid var(--border-color);
491
+ border-radius: 8px;
492
+ font-size: 1.5rem; /* Larger font */
493
+ line-height: 1.4;
494
+ background-color: var(--input-bg);
495
+ color: var(--text-color);
496
+ resize: none; /* Disable manual resize */
497
+ transition: all 0.2s ease;
498
+ min-height: 100px; /* Ensure decent initial height */
499
+ }
500
+ .prompt-input:focus {
501
+ outline: none;
502
+ border-color: var(--primary-color);
503
+ box-shadow: 0 0 0 3px rgba(187, 134, 252, 0.3);
504
+ }
505
+ .prompt-input:disabled {
506
+ opacity: 0.5;
507
+ background-color: #333;
508
+ }
509
+
510
+ /* LoRA Section */
511
+ .lora-section {
512
+ position: relative; /* For back button positioning */
513
+ padding-top: 0; /* Reduce top padding */
514
+ }
515
+ .back-button {
516
+ position: absolute;
517
+ top: -10px; /* Adjust as needed */
518
+ left: 0;
519
+ background: none;
520
+ border: none;
521
+ color: var(--text-secondary);
522
+ padding: 0.5rem;
523
+ cursor: pointer;
524
+ font-size: 0.9rem;
525
+ }
526
+ .back-button:hover {
527
+ color: var(--primary-color);
528
+ }
529
+
530
+ .search-container {
531
+ position: relative;
532
+ margin-bottom: 1rem;
533
+ }
534
+ .lora-search-input {
535
+ width: 100%;
536
+ padding: 1rem 1.5rem;
537
+ padding-right: 3rem; /* Space for spinner */
538
+ border: 1px solid var(--border-color);
539
+ border-radius: 8px;
540
+ font-size: 1.2rem;
541
+ background-color: var(--input-bg);
542
+ color: var(--text-color);
543
+ transition: all 0.2s ease;
544
+ }
545
+ .lora-search-input:focus {
546
+ outline: none;
547
+ border-color: var(--primary-color);
548
+ box-shadow: 0 0 0 3px rgba(187, 134, 252, 0.3);
549
+ }
550
+
551
+ .lora-list {
552
+ list-style: none;
553
+ max-height: calc(100vh - 260px); /* Increased height */
554
+ overflow-y: auto;
555
+ border: 1px solid var(--border-color);
556
+ border-radius: 8px;
557
+ background-color: var(--surface-color);
558
+ }
559
+ .lora-list li {
560
+ border-bottom: 1px solid var(--border-color);
561
+ }
562
+ .lora-list li:last-child {
563
+ border-bottom: none;
564
+ }
565
+
566
+ .lora-item {
567
+ display: flex;
568
+ justify-content: space-between;
569
+ align-items: center;
570
+ width: 100%;
571
+ padding: 0.8rem 1.2rem;
572
+ background: none;
573
+ border: none;
574
+ color: var(--text-color);
575
+ cursor: pointer;
576
+ text-align: left;
577
+ transition: background-color 0.15s ease;
578
+ font-size: 1rem;
579
+ }
580
+ .lora-item:hover {
581
+ background-color: rgba(255, 255, 255, 0.05);
582
+ }
583
+ .lora-item.selected {
584
+ background-color: var(--selected-bg);
585
+ /* font-weight: 600; */ /* Removed to avoid layout shift */
586
+ /* color: var(--primary-color); */ /* Color applied below */
587
+ }
588
+ .lora-thumbnail,
589
+ .lora-thumbnail-placeholder {
590
+ width: 40px;
591
+ height: 40px;
592
+ border-radius: 4px;
593
+ margin-right: 12px;
594
+ object-fit: cover;
595
+ flex-shrink: 0; /* Prevent shrinking */
596
+ background-color: var(--input-bg); /* Placeholder bg */
597
+ }
598
+ .lora-thumbnail-placeholder {
599
+ border: 1px dashed var(--border-color);
600
+ }
601
+ .lora-info {
602
+ display: flex;
603
+ flex-direction: column;
604
+ overflow: hidden; /* Prevent text overflow */
605
+ flex-grow: 1;
606
+ }
607
+ .lora-item.selected .lora-info .lora-name {
608
+ color: var(--primary-color);
609
+ font-weight: 600;
610
+ }
611
+ .lora-name {
612
+ white-space: nowrap;
613
+ overflow: hidden;
614
+ text-overflow: ellipsis;
615
+ /* margin-right: 1rem; */ /* Removed as info is now a column */
616
+ font-size: 1rem;
617
+ margin-bottom: 2px; /* Small space between name and author */
618
+ }
619
+ .lora-author {
620
+ font-size: 0.85rem;
621
+ color: var(--text-secondary);
622
+ white-space: nowrap;
623
+ flex-shrink: 0; /* Prevent author from shrinking */
624
+ }
625
+
626
+
627
+ /* Generating & Result */
628
+ .generating-section, .result-section {
629
+ flex-grow: 1;
630
+ display: flex;
631
+ flex-direction: column;
632
+ align-items: center;
633
+ justify-content: center;
634
+ text-align: center;
635
+ }
636
+
637
+ .result-image {
638
+ max-width: 100%;
639
+ max-height: calc(100vh - 12rem); /* Adjust based on padding/button */
640
+ height: auto;
641
+ border-radius: 8px;
642
+ object-fit: contain;
643
+ background-color: var(--input-bg); /* Placeholder BG */
644
+ margin-bottom: 1rem; /* Space before button if image fails */
645
+ }
646
+
647
+ .generating-prompt, .generating-lora {
648
+ color: var(--text-secondary);
649
+ font-size: 0.9rem;
650
+ max-width: 90%;
651
+ overflow: hidden;
652
+ text-overflow: ellipsis;
653
+ white-space: nowrap;
654
+ }
655
+
656
+
657
+ /* Action Button Container */
658
+ .action-button-container {
659
+ position: fixed; /* Stick to bottom */
660
+ bottom: 0;
661
+ left: 0;
662
+ width: 100%;
663
+ padding: 1.5rem 2rem;
664
+ display: flex;
665
+ justify-content: center;
666
+ background: linear-gradient(to top, var(--bg-color) 60%, transparent); /* Fade background */
667
+ z-index: 10;
668
+ }
669
+
670
+ .action-button {
671
+ padding: 1rem 2.5rem;
672
+ background-color: var(--primary-color);
673
+ color: #000; /* Black text on primary */
674
+ border: none;
675
+ border-radius: 30px; /* Pill shape */
676
+ font-size: 1.2rem;
677
+ font-weight: 600;
678
+ cursor: pointer;
679
+ transition: all 0.2s ease;
680
+ box-shadow: 0 4px 15px rgba(0, 0, 0, 0.2);
681
+ }
682
+ .action-button:hover:not(:disabled) {
683
+ background-color: var(--secondary-color);
684
+ box-shadow: 0 6px 20px rgba(0, 0, 0, 0.3);
685
+ transform: translateY(-2px);
686
+ }
687
+ .action-button:disabled {
688
+ background-color: #555;
689
+ color: #999;
690
+ cursor: not-allowed;
691
+ opacity: 0.6;
692
+ box-shadow: none;
693
+ }
694
+
695
+ /* Spinner */
696
+ .spinner {
697
+ border: 3px solid rgba(255, 255, 255, 0.3);
698
+ border-radius: 50%;
699
+ border-top-color: var(--secondary-color); /* Teal spinner */
700
+ width: 20px;
701
+ height: 20px;
702
+ animation: spin 1s linear infinite;
703
+ position: absolute;
704
+ right: 1rem;
705
+ top: 50%;
706
+ transform: translateY(-50%);
707
+ }
708
+ .spinner.large {
709
+ width: 50px;
710
+ height: 50px;
711
+ border-width: 5px;
712
+ position: static; /* Reset position */
713
+ transform: none;
714
+ margin-bottom: 1rem;
715
+ }
716
+
717
+ @keyframes spin {
718
+ to { transform: translateY(-50%) rotate(360deg); }
719
+ }
720
+ @keyframes spin-large {
721
+ to { transform: rotate(360deg); }
722
+ }
723
+ .spinner.large {
724
+ animation-name: spin-large;
725
+ transform: none; /* Override */
726
+ }
727
+
728
+
729
+ /* Error/Info Messages */
730
+ .error-message, .info-message {
731
+ padding: 0.8rem 1.2rem;
732
+ border-radius: 6px;
733
+ margin: 1rem auto;
734
+ text-align: center;
735
+ max-width: 600px;
736
+ font-size: 0.95rem;
737
+ }
738
+ .error-message {
739
+ background-color: rgba(207, 102, 121, 0.2); /* Error bg */
740
+ color: var(--error-color);
741
+ border: 1px solid var(--error-color);
742
+ }
743
+ .error-message.fatal { /* For generation errors */
744
+ font-size: 1.1rem;
745
+ margin-bottom: 1rem;
746
+ }
747
+ .info-message {
748
+ background-color: rgba(3, 218, 198, 0.1); /* Secondary color bg */
749
+ color: var(--secondary-color);
750
+ border: 1px solid var(--secondary-color);
751
+ }
752
+
753
+ /* Animated Loading Text */
754
+ .loading-text {
755
+ margin-top: 1rem;
756
+ font-size: 1.1rem;
757
+ color: var(--text-secondary);
758
+ min-height: 1.5em; /* Prevent layout jump */
759
+ white-space: nowrap;
760
+ overflow: hidden;
761
+ text-overflow: ellipsis;
762
+ max-width: 90%; /* Ensure it doesn't overflow container */
763
+ }
764
+
765
+ </style>
src/routes/api/generate-image/+server.js ADDED
@@ -0,0 +1,51 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { HF_TOKEN } from "$env/static/private";
2
+ import { error } from "@sveltejs/kit";
3
+ import * as HfInference from "@huggingface/inference";
4
+
5
+ if (!HF_TOKEN) {
6
+ console.error("HF_TOKEN environment variable not set.");
7
+ throw error(500, "Server configuration error: Missing API Token");
8
+ }
9
+
10
+ const client = new HfInference.InferenceClient(HF_TOKEN);
11
+
12
+ /** @type {import('./$types').RequestHandler} */
13
+ export async function POST({ request }) {
14
+ const { loraModelId, prompt } = await request.json();
15
+
16
+ if (!loraModelId) {
17
+ throw error(400, "Missing loraModelId in request body");
18
+ }
19
+ if (!prompt) {
20
+ throw error(400, "Missing prompt in request body");
21
+ }
22
+
23
+ console.log(
24
+ `API: Generating image with Fal.ai - LoRA: "${loraModelId}", Prompt: "${prompt}"`
25
+ );
26
+
27
+ try {
28
+ // Call Fal AI provider using textToImage
29
+ const imageBlob = await client.textToImage({
30
+ provider: "fal-ai", // Specify Fal AI as the provider
31
+ model: loraModelId, // Use the provided loraModelId as the model
32
+ inputs: prompt, // Use the provided prompt as the input
33
+ // Optional parameters can be added here if needed
34
+ });
35
+
36
+ console.log("Fal AI image generation successful. Returning Blob.");
37
+
38
+ // Return the Blob directly in the response
39
+ return new Response(imageBlob, {
40
+ headers: {
41
+ "Content-Type": imageBlob.type, // Set correct content type (e.g., image/png)
42
+ },
43
+ });
44
+ } catch (err) {
45
+ console.error("Error during Fal AI textToImage call:", err);
46
+ // Check if the error object has specific properties for better reporting
47
+ const message = err.message || "Unknown error during image generation";
48
+ const status = err.status || 500;
49
+ throw error(status, `Error generating image via Fal AI: ${message}`);
50
+ }
51
+ }
src/routes/api/search-loras/+server.js ADDED
@@ -0,0 +1,78 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { HF_TOKEN } from "$env/static/private";
2
+ import { json, error } from "@sveltejs/kit";
3
+
4
+ if (!HF_TOKEN) {
5
+ console.error("HF_TOKEN environment variable not set.");
6
+ throw error(500, "Server configuration error: Missing API Token");
7
+ }
8
+
9
+ /** @type {import('./$types').RequestHandler} */
10
+ export async function POST({ request }) {
11
+ const { query } = await request.json();
12
+ if (!query) {
13
+ throw error(400, "Missing search query in request body");
14
+ }
15
+
16
+ console.log(`API: Searching Fal LoRAs for query: "${query}"`);
17
+ const searchParams = new URLSearchParams({
18
+ filter: "lora",
19
+ limit: "1000", // Increase limit slightly for UI
20
+ config: "false",
21
+ full: "true",
22
+ inference_provider: "fal-ai",
23
+ search: query,
24
+ });
25
+ const url = `https://huggingface.co/api/models?${searchParams.toString()}`;
26
+
27
+ try {
28
+ const response = await fetch(url, {
29
+ method: "GET",
30
+ headers: { Authorization: `Bearer ${HF_TOKEN}` },
31
+ });
32
+
33
+ if (!response.ok) {
34
+ const errorText = await response.text();
35
+ console.error(`Hugging Face API Error: ${response.status} ${errorText}`);
36
+ throw error(
37
+ response.status,
38
+ `Error fetching LoRAs from Hugging Face: ${errorText}`
39
+ );
40
+ }
41
+
42
+ const data = await response.json();
43
+ const loras = data.map((model) => {
44
+ // Find the first image file in siblings for the thumbnail
45
+ const imageSibling = model.siblings?.find((sibling) =>
46
+ /\.(png|jpg|jpeg|webp)$/i.test(sibling.rfilename)
47
+ );
48
+
49
+ const thumbnailUrl = imageSibling
50
+ ? `https://huggingface.co/${model.modelId}/resolve/main/${imageSibling.rfilename}`
51
+ : null; // Or a default placeholder image URL
52
+
53
+ if (!thumbnailUrl) {
54
+ const thumbnailUrl =
55
+ "https://huggingface.co/front/assets/huggingface_logo-noborder.svg";
56
+ }
57
+
58
+ return {
59
+ id: model.modelId,
60
+ author: model.author,
61
+ thumbnail: thumbnailUrl,
62
+ // Add other fields if needed later
63
+ };
64
+ });
65
+
66
+ console.log(
67
+ "API: Returning LoRAs:",
68
+ JSON.stringify(loras.slice(0, 5), null, 2)
69
+ ); // Log first 5 results
70
+
71
+ return json(loras);
72
+ } catch (err) {
73
+ console.error("Error in /api/search-loras:", err);
74
+ // Throw SvelteKit error to ensure proper HTTP response
75
+ if (err.status) throw err; // Re-throw SvelteKit errors
76
+ throw error(500, "Internal Server Error");
77
+ }
78
+ }
svelte.config.js ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import adapter from "@sveltejs/adapter-auto";
2
+ import { vitePreprocess } from "@sveltejs/vite-plugin-svelte";
3
+
4
+ /** @type {import('@sveltejs/kit').Config} */
5
+ const config = {
6
+ // Consult https://kit.svelte.dev/docs/integrations#preprocessors
7
+ // for more information about preprocessors
8
+ preprocess: vitePreprocess(),
9
+
10
+ kit: {
11
+ // adapter-auto only supports some environments, see https://kit.svelte.dev/docs/adapter-auto for a list.
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
+
18
+ export default config;
vite.config.js ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ import { sveltekit } from "@sveltejs/kit/vite";
2
+ import { defineConfig } from "vite";
3
+
4
+ export default defineConfig({
5
+ plugins: [sveltekit()],
6
+ });