devflare 1.0.0-next.23 → 1.0.0-next.24

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. package/LLM.md +77 -2
  2. package/dist/account-5nm1xn0v.js +475 -0
  3. package/dist/browser.d.ts +22 -2
  4. package/dist/browser.d.ts.map +1 -1
  5. package/dist/build-vctfnmsf.js +54 -0
  6. package/dist/cli/commands/deploy/prepare.d.ts.map +1 -1
  7. package/dist/cli/commands/deploy.d.ts.map +1 -1
  8. package/dist/cli/index.js +1 -1
  9. package/dist/config/schema-env.d.ts +22 -2
  10. package/dist/config/schema-env.d.ts.map +1 -1
  11. package/dist/config/schema-runtime.d.ts +11 -1
  12. package/dist/config/schema-runtime.d.ts.map +1 -1
  13. package/dist/config/schema-types-runtime.d.ts +3 -0
  14. package/dist/config/schema-types-runtime.d.ts.map +1 -1
  15. package/dist/config/schema-types.d.ts +2 -2
  16. package/dist/config/schema.d.ts +33 -3
  17. package/dist/config/schema.d.ts.map +1 -1
  18. package/dist/config-rq32csms.js +105 -0
  19. package/dist/deploy-krj3k9zm.js +1055 -0
  20. package/dist/deploy-mem96qyn.js +1066 -0
  21. package/dist/dev-apkr7cfv.js +2597 -0
  22. package/dist/doctor-9asw8x18.js +259 -0
  23. package/dist/index-4j9ah79n.js +1033 -0
  24. package/dist/index-bfjpjs07.js +581 -0
  25. package/dist/index-cna43592.js +1573 -0
  26. package/dist/index-d00njc1f.js +147 -0
  27. package/dist/index-dgeamyfk.js +1426 -0
  28. package/dist/index-ftf7yqhs.js +74 -0
  29. package/dist/index-h332fg62.js +1205 -0
  30. package/dist/index-ja2rdbt0.js +476 -0
  31. package/dist/index-kc207nyr.js +52 -0
  32. package/dist/index-meq8ydc0.js +895 -0
  33. package/dist/index-myfjejs0.js +185 -0
  34. package/dist/index-qkfvd3cs.js +109 -0
  35. package/dist/index-rnz879kf.js +1426 -0
  36. package/dist/index-s96e5dd9.js +699 -0
  37. package/dist/index.js +3 -3
  38. package/dist/login-g9rb7dj3.js +77 -0
  39. package/dist/previews-ykamw25e.js +1337 -0
  40. package/dist/productions-4m1pd6ts.js +505 -0
  41. package/dist/secrets-gywxctdh.js +91 -0
  42. package/dist/sveltekit/index.js +3 -3
  43. package/dist/test/index.js +6 -6
  44. package/dist/types-17kkqw37.js +705 -0
  45. package/dist/vite/index.js +4 -4
  46. package/dist/worker-4fd49jm0.js +513 -0
  47. package/package.json +1 -1
package/LLM.md CHANGED
@@ -2309,7 +2309,7 @@ export default defineConfig({
2309
2309
  },
2310
2310
  routes: [
2311
2311
  {
2312
- pattern: 'docs.example.com/*',
2312
+ pattern: 'docs.example.com',
2313
2313
  custom_domain: true
2314
2314
  }
2315
2315
  ],
@@ -3248,12 +3248,83 @@ The important habit is that runtime posture should be reviewable in source contr
3248
3248
  >
3249
3249
  > Devflare already includes `nodejs_compat` and `nodejs_als`. Keep `compatibilityFlags` focused on the extra posture your package actually needs.
3250
3250
 
3251
+ #### Choose the Cloudflare endpoint model first
3252
+
3253
+ Cloudflare documents three inbound endpoint models for Workers: Custom Domains, normal Workers routes, and the automatic `workers.dev` route. They are not interchangeable, and Devflare keeps that distinction in the top-level `routes` config instead of inventing a second routing vocabulary.
3254
+
3255
+ Use a Custom Domain when the Worker is the origin for a whole hostname. Use a normal Workers route when a Worker should sit in front of an existing proxied hostname, match a wildcard host, or match a path prefix. Use `workers.dev` for getting started or preview-style reachability, and disable it when production should only be reachable through your own domain.
3256
+
3257
+ ##### Reference table
3258
+
3259
+ | Goal | Devflare config shape | Cloudflare behavior |
3260
+ | --- | --- | --- |
3261
+ | Worker owns every path on one hostname | `routes: [{ pattern: "app.example.com", custom_domain: true }]` | Custom Domains match the exact hostname; paths and query strings do not participate in the match. |
3262
+ | Worker intercepts a path or wildcard host in a Cloudflare zone | `routes: [{ pattern: "app.example.com/api/*", zone_name: "example.com" }]` | Normal routes use route patterns, may include `*`, and the most specific matching route wins. |
3263
+ | Worker remains reachable on the account subdomain | Default generated Wrangler config keeps `workers_dev: true`. | Cloudflare assigns `<worker>.<account>.workers.dev`; Cloudflare recommends routes or custom domains for production. |
3264
+
3265
+ > **Note — Routes can sit in front of Custom Domains**
3266
+ >
3267
+ > Cloudflare treats a Worker on a Custom Domain as an origin. A more specific normal route on the same hostname can run first, then call `fetch(request)` to invoke the Custom Domain Worker behind it.
3268
+
3269
+ > **Warning — Same-zone fetch is different for routes and Custom Domains**
3270
+ >
3271
+ > Cloudflare documents that Custom Domains can be invoked by same-zone `fetch()`, while normal routes cannot be the target of same-zone `fetch()` and should use service bindings for Worker-to-Worker calls.
3272
+
3273
+ ##### Example — Custom Domain for a Worker-owned hostname
3274
+
3275
+ ```ts
3276
+ import { defineConfig } from 'devflare/config'
3277
+
3278
+ export default defineConfig({
3279
+ name: 'app-worker',
3280
+ routes: [
3281
+ {
3282
+ pattern: 'app.example.com',
3283
+ custom_domain: true
3284
+ }
3285
+ ]
3286
+ })
3287
+ ```
3288
+
3289
+ ##### Example — Workers route for path or wildcard matching
3290
+
3291
+ ```ts
3292
+ import { defineConfig } from 'devflare/config'
3293
+
3294
+ export default defineConfig({
3295
+ name: 'api-proxy-worker',
3296
+ routes: [
3297
+ {
3298
+ pattern: 'app.example.com/api/*',
3299
+ zone_name: 'example.com'
3300
+ }
3301
+ ]
3302
+ })
3303
+ ```
3304
+
3305
+ ##### Example — Disable workers.dev when only custom endpoints should serve production
3306
+
3307
+ ```ts
3308
+ import { defineConfig } from 'devflare/config'
3309
+
3310
+ export default defineConfig({
3311
+ name: 'scratch-worker',
3312
+ wrangler: {
3313
+ passthrough: {
3314
+ workers_dev: false
3315
+ }
3316
+ }
3317
+ })
3318
+ ```
3319
+
3251
3320
  #### Keep deployment shape in config, not in app routing or shell scripts
3252
3321
 
3253
3322
  Several config keys answer deployment questions rather than application-routing questions. Keeping those lanes separate is what stops app URLs, Cloudflare routes, and dev-only WebSocket proxy behavior from collapsing into one blurry story.
3254
3323
 
3255
3324
  If the package serves static assets, mounts a custom domain, or proxies Durable Object WebSockets in development, that shape should live in config beside the rest of the deployment contract.
3256
3325
 
3326
+ Custom Domains are host-only: use `custom_domain: true` with a bare hostname such as `docs.example.com`. For wildcard or path matching such as `docs.example.com/*` or `docs.example.com/api/*`, use a normal Workers route with `zone_name` or `zone_id` instead.
3327
+
3257
3328
  ##### Reference table
3258
3329
 
3259
3330
  | Key | What it controls | Common use |
@@ -3266,6 +3337,10 @@ If the package serves static assets, mounts a custom domain, or proxies Durable
3266
3337
  >
3267
3338
  > `files.routes` controls your app route tree. Top-level `routes` controls Cloudflare deployment routing. Keep those ideas separate so the package stays reviewable.
3268
3339
 
3340
+ > **Warning — Custom Domains are not wildcard routes**
3341
+ >
3342
+ > Cloudflare Custom Domains match the hostname exactly and ignore paths. Do not add `/*` when `custom_domain: true`; a request to any path on that hostname will already invoke the Worker.
3343
+
3269
3344
  ##### Example — One place for runtime posture and deployment-facing settings
3270
3345
 
3271
3346
  ```ts
@@ -3280,7 +3355,7 @@ export default defineConfig({
3280
3355
  binding: 'ASSETS'
3281
3356
  },
3282
3357
  routes: [
3283
- { pattern: 'docs.example.com/*', custom_domain: true }
3358
+ { pattern: 'docs.example.com', custom_domain: true }
3284
3359
  ],
3285
3360
  wsRoutes: [
3286
3361
  {
@@ -0,0 +1,475 @@
1
+ import {
2
+ getConfiguredAccountId
3
+ } from "./index-ftf7yqhs.js";
4
+ import {
5
+ account
6
+ } from "./index-0m6e4mxz.js";
7
+ import"./index-k7m5f1dg.js";
8
+ import"./index-3jme4hgw.js";
9
+ import {
10
+ bold,
11
+ createCliTheme,
12
+ dim,
13
+ formatCommand,
14
+ formatLabelValue,
15
+ green,
16
+ logLine,
17
+ logTable,
18
+ whiteDim,
19
+ yellow
20
+ } from "./index-stgn34cr.js";
21
+ import {
22
+ CYAN,
23
+ CYAN_BOLD,
24
+ DIM,
25
+ RESET
26
+ } from "./index-3t6rypgc.js";
27
+ import"./index-15fpa5tx.js";
28
+ import"./index-cna43592.js";
29
+ import {
30
+ getGlobalDefaultAccountId,
31
+ getWorkspaceAccountId,
32
+ setGlobalDefaultAccountId,
33
+ setWorkspaceAccountId
34
+ } from "./index-1d4jg11n.js";
35
+ import {
36
+ AuthenticationError,
37
+ CloudflareAPIError
38
+ } from "./index-mg8vwqxf.js";
39
+ import"./index-c8p4njqy.js";
40
+ import"./index-37x76zdn.js";
41
+
42
+ // src/cli/commands/account.ts
43
+ var ACCOUNT_SUBCOMMANDS = [
44
+ "info",
45
+ "workers",
46
+ "kv",
47
+ "d1",
48
+ "r2",
49
+ "vectorize",
50
+ "limits",
51
+ "usage",
52
+ "global",
53
+ "workspace"
54
+ ];
55
+ function isAccountSubcommand(value) {
56
+ return ACCOUNT_SUBCOMMANDS.includes(value);
57
+ }
58
+ var CLI_API_OPTIONS = { timeout: 1e4 };
59
+ function formatDate(date) {
60
+ if (!date)
61
+ return "N/A";
62
+ return date.toLocaleDateString("en-US", {
63
+ year: "numeric",
64
+ month: "short",
65
+ day: "numeric"
66
+ });
67
+ }
68
+ function formatPercent(value) {
69
+ if (value === undefined)
70
+ return "N/A";
71
+ return `${value.toFixed(1)}%`;
72
+ }
73
+ function logSection(logger, title, theme, count, accent = "cyan") {
74
+ logLine(logger);
75
+ const heading = accent === "yellow" ? yellow(title, theme) : accent === "green" ? green(title, theme) : bold(title, theme);
76
+ logLine(logger, `${heading}${count === undefined ? "" : ` ${dim(`(${count})`, theme)}`}`);
77
+ }
78
+ function logEmptyState(logger, message, theme) {
79
+ logLine(logger);
80
+ logLine(logger, dim(message, theme));
81
+ logLine(logger);
82
+ return { exitCode: 0 };
83
+ }
84
+ async function runAccountCommand(parsed, logger, options) {
85
+ const theme = createCliTheme(parsed.options);
86
+ const isAuth = await account.isAuthenticated();
87
+ if (!isAuth) {
88
+ logger.error("Not authenticated with Cloudflare");
89
+ logLine(logger, dim("Run: devflare login", theme));
90
+ return { exitCode: 1 };
91
+ }
92
+ const subcommand = parsed.args[0];
93
+ const rawSubcommand = parsed.args[0];
94
+ if (rawSubcommand && !isAccountSubcommand(rawSubcommand)) {
95
+ logger.error(`Unknown account subcommand: ${rawSubcommand}`);
96
+ logLine(logger, dim(`Available account subcommands: ${ACCOUNT_SUBCOMMANDS.join(", ")}`, theme));
97
+ return { exitCode: 1 };
98
+ }
99
+ if (subcommand === "global") {
100
+ return await selectGlobalAccount(logger, theme);
101
+ }
102
+ if (subcommand === "workspace") {
103
+ return await selectWorkspaceAccount(logger, theme);
104
+ }
105
+ try {
106
+ let accountId = parsed.options.account;
107
+ if (!accountId) {
108
+ accountId = await getConfiguredAccountId(options.cwd ?? process.cwd());
109
+ }
110
+ if (!accountId) {
111
+ const primary = await account.getPrimaryAccount();
112
+ if (!primary) {
113
+ logger.error("No Cloudflare accounts found");
114
+ return { exitCode: 1 };
115
+ }
116
+ accountId = primary.id;
117
+ }
118
+ switch (subcommand) {
119
+ case "workers":
120
+ return await showWorkers(accountId, logger, theme);
121
+ case "kv":
122
+ return await showKV(accountId, logger, theme);
123
+ case "d1":
124
+ return await showD1(accountId, logger, theme);
125
+ case "r2":
126
+ return await showR2(accountId, logger, theme);
127
+ case "vectorize":
128
+ return await showVectorize(accountId, logger, theme);
129
+ case "limits":
130
+ return await handleLimits(accountId, parsed, logger, theme);
131
+ case "usage":
132
+ return await showUsage(accountId, logger, theme);
133
+ case "info":
134
+ default:
135
+ return await showAccountOverview(accountId, logger, theme);
136
+ }
137
+ } catch (error) {
138
+ if (error instanceof AuthenticationError) {
139
+ logger.error(error.message);
140
+ return { exitCode: 1 };
141
+ }
142
+ if (error instanceof CloudflareAPIError) {
143
+ logger.error(`API Error: ${error.message}`);
144
+ return { exitCode: 1 };
145
+ }
146
+ if (error instanceof Error) {
147
+ if (error.name === "AbortError" || error.message.includes("timed out")) {
148
+ logger.error("Request timed out. The Cloudflare API is slow or unavailable.");
149
+ return { exitCode: 1 };
150
+ }
151
+ logger.error(`Error: ${error.message}`);
152
+ return { exitCode: 1 };
153
+ }
154
+ throw error;
155
+ }
156
+ }
157
+ async function showAccountOverview(accountId, logger, theme) {
158
+ logSection(logger, "Accounts", theme);
159
+ let accounts = [];
160
+ let limitedAccountView = false;
161
+ try {
162
+ accounts = await account.getAccounts();
163
+ } catch {
164
+ const fallbackAccount = await account.getAccountById(accountId);
165
+ if (!fallbackAccount) {
166
+ logger.error("Could not inspect Cloudflare accounts with the current credentials");
167
+ return { exitCode: 1 };
168
+ }
169
+ accounts = [fallbackAccount];
170
+ limitedAccountView = true;
171
+ }
172
+ if (accounts.length === 0) {
173
+ logger.error("No Cloudflare accounts found");
174
+ return { exitCode: 1 };
175
+ }
176
+ const workspaceId = getWorkspaceAccountId();
177
+ const globalId = await getGlobalDefaultAccountId(accountId);
178
+ if (limitedAccountView) {
179
+ logLine(logger, dim("Using the configured account directly because the current credentials cannot enumerate all Cloudflare accounts.", theme));
180
+ }
181
+ for (let i = 0;i < accounts.length; i++) {
182
+ const acc = accounts[i];
183
+ const isWorkspace = acc.id === workspaceId;
184
+ const isGlobal = acc.id === globalId;
185
+ let badge = "";
186
+ if (isWorkspace) {
187
+ badge = ` ${CYAN_BOLD}(workspace)${RESET}`;
188
+ } else if (isGlobal) {
189
+ badge = workspaceId ? ` ${DIM}(global)${RESET}` : ` ${CYAN}(global)${RESET}`;
190
+ }
191
+ if (i > 0) {
192
+ logLine(logger);
193
+ }
194
+ logLine(logger, `${dim("account", theme)} ${green(acc.name, theme)}${badge}`);
195
+ logLine(logger, formatLabelValue("id", whiteDim(acc.id, theme), theme, 10));
196
+ logLine(logger, formatLabelValue("type", acc.type, theme, 10));
197
+ }
198
+ logSection(logger, "Commands", theme);
199
+ logLine(logger, formatCommand("devflare account global", "Set global default account", theme));
200
+ logLine(logger, formatCommand("devflare account workspace", "Set workspace account", theme));
201
+ logLine(logger, formatCommand("devflare account workers", "List Workers", theme));
202
+ logLine(logger, formatCommand("devflare account kv", "List KV namespaces", theme));
203
+ logLine(logger, formatCommand("devflare account d1", "List D1 databases", theme));
204
+ logLine(logger, formatCommand("devflare account r2", "List R2 buckets", theme));
205
+ logLine(logger, formatCommand("devflare account vectorize", "List Vectorize indexes", theme));
206
+ logLine(logger, formatCommand("devflare account limits", "View or set usage limits", theme));
207
+ logLine(logger, formatCommand("devflare account usage", "View detailed usage", theme));
208
+ logLine(logger, formatCommand("devflare ai", "View AI models and pricing", theme));
209
+ logLine(logger);
210
+ return { exitCode: 0 };
211
+ }
212
+ async function selectGlobalAccount(logger, theme) {
213
+ const accounts = await account.getAccounts();
214
+ if (accounts.length === 0) {
215
+ logger.error("No Cloudflare accounts found");
216
+ return { exitCode: 1 };
217
+ }
218
+ if (accounts.length === 1) {
219
+ await setGlobalDefaultAccountId(accounts[0].id);
220
+ logger.success(`Global default set to: ${accounts[0].name}`);
221
+ return { exitCode: 0 };
222
+ }
223
+ const currentGlobal = await getGlobalDefaultAccountId(accounts[0].id);
224
+ const options = accounts.map((acc) => {
225
+ const isCurrent = acc.id === currentGlobal;
226
+ return {
227
+ label: isCurrent ? `${acc.name} ${CYAN}(default)${RESET}` : acc.name,
228
+ value: acc.id,
229
+ hint: acc.id.substring(0, 8) + "..."
230
+ };
231
+ });
232
+ const selected = await logger.prompt("Select global default account:", {
233
+ type: "select",
234
+ options,
235
+ initial: currentGlobal ?? accounts[0].id
236
+ });
237
+ if (!selected || typeof selected === "symbol") {
238
+ logLine(logger, dim("Cancelled", theme));
239
+ return { exitCode: 0 };
240
+ }
241
+ await setGlobalDefaultAccountId(selected, accounts[0].id);
242
+ const selectedAccount = accounts.find((a) => a.id === selected);
243
+ logger.success(`Global default set to: ${selectedAccount?.name}`);
244
+ logLine(logger, `${dim("saved to", theme)} ~/.devflare/preferences.json + cloud KV`);
245
+ return { exitCode: 0 };
246
+ }
247
+ async function selectWorkspaceAccount(logger, theme) {
248
+ const accounts = await account.getAccounts();
249
+ if (accounts.length === 0) {
250
+ logger.error("No Cloudflare accounts found");
251
+ return { exitCode: 1 };
252
+ }
253
+ if (accounts.length === 1) {
254
+ const pkgPath2 = setWorkspaceAccountId(accounts[0].id);
255
+ logger.success(`Workspace account set to: ${accounts[0].name}`);
256
+ logLine(logger, `${dim("saved to", theme)} ${pkgPath2}`);
257
+ return { exitCode: 0 };
258
+ }
259
+ const currentWorkspace = getWorkspaceAccountId();
260
+ const options = accounts.map((acc) => {
261
+ const isCurrent = acc.id === currentWorkspace;
262
+ return {
263
+ label: isCurrent ? `${acc.name} ${CYAN}(workspace)${RESET}` : acc.name,
264
+ value: acc.id,
265
+ hint: acc.id.substring(0, 8) + "..."
266
+ };
267
+ });
268
+ const selected = await logger.prompt("Select workspace account:", {
269
+ type: "select",
270
+ options,
271
+ initial: currentWorkspace ?? accounts[0].id
272
+ });
273
+ if (!selected || typeof selected === "symbol") {
274
+ logLine(logger, dim("Cancelled", theme));
275
+ return { exitCode: 0 };
276
+ }
277
+ const pkgPath = setWorkspaceAccountId(selected);
278
+ const selectedAccount = accounts.find((a) => a.id === selected);
279
+ logger.success(`Workspace account set to: ${selectedAccount?.name}`);
280
+ logLine(logger, `${dim("saved to", theme)} ${pkgPath}`);
281
+ return { exitCode: 0 };
282
+ }
283
+ async function showWorkers(accountId, logger, theme) {
284
+ const workers = await account.workers(accountId, CLI_API_OPTIONS);
285
+ if (workers.length === 0) {
286
+ return logEmptyState(logger, "No Workers found", theme);
287
+ }
288
+ logSection(logger, "Workers", theme, workers.length, "green");
289
+ logTable(logger, {
290
+ title: "Worker list",
291
+ rows: workers,
292
+ columns: [
293
+ { label: "Name", width: 30, value: (worker) => worker.name },
294
+ { label: "Modified", width: 20, value: (worker) => whiteDim(formatDate(worker.modifiedOn), theme) }
295
+ ],
296
+ theme,
297
+ titleAccent: "green"
298
+ });
299
+ logLine(logger);
300
+ return { exitCode: 0 };
301
+ }
302
+ async function showKV(accountId, logger, theme) {
303
+ const namespaces = await account.kv(accountId, CLI_API_OPTIONS);
304
+ if (namespaces.length === 0) {
305
+ return logEmptyState(logger, "No KV namespaces found", theme);
306
+ }
307
+ logSection(logger, "KV namespaces", theme, namespaces.length);
308
+ logTable(logger, {
309
+ title: "Namespace list",
310
+ rows: namespaces,
311
+ columns: [
312
+ { label: "Name", width: 35, value: (ns) => ns.name },
313
+ { label: "ID", width: 35, value: (ns) => whiteDim(ns.id, theme) }
314
+ ],
315
+ theme,
316
+ titleAccent: "cyan"
317
+ });
318
+ logLine(logger);
319
+ return { exitCode: 0 };
320
+ }
321
+ async function showD1(accountId, logger, theme) {
322
+ const databases = await account.d1(accountId, CLI_API_OPTIONS);
323
+ if (databases.length === 0) {
324
+ return logEmptyState(logger, "No D1 databases found", theme);
325
+ }
326
+ logSection(logger, "D1 databases", theme, databases.length, "yellow");
327
+ logTable(logger, {
328
+ title: "Database list",
329
+ rows: databases,
330
+ columns: [
331
+ { label: "Name", width: 25, value: (db) => db.name },
332
+ { label: "ID", width: 40, value: (db) => whiteDim(db.id, theme) },
333
+ { label: "Tables", width: 8, value: (db) => String(db.tableCount ?? "N/A") }
334
+ ],
335
+ theme,
336
+ titleAccent: "yellow"
337
+ });
338
+ logLine(logger);
339
+ return { exitCode: 0 };
340
+ }
341
+ async function showR2(accountId, logger, theme) {
342
+ const buckets = await account.r2(accountId, CLI_API_OPTIONS);
343
+ if (buckets.length === 0) {
344
+ return logEmptyState(logger, "No R2 buckets found", theme);
345
+ }
346
+ logSection(logger, "R2 buckets", theme, buckets.length, "green");
347
+ logTable(logger, {
348
+ title: "Bucket list",
349
+ rows: buckets,
350
+ columns: [
351
+ { label: "Name", width: 30, value: (bucket) => bucket.name },
352
+ { label: "Created", width: 20, value: (bucket) => whiteDim(formatDate(bucket.createdOn), theme) },
353
+ { label: "Location", width: 10, value: (bucket) => bucket.location ?? "auto" }
354
+ ],
355
+ theme,
356
+ titleAccent: "green"
357
+ });
358
+ logLine(logger);
359
+ return { exitCode: 0 };
360
+ }
361
+ async function showVectorize(accountId, logger, theme) {
362
+ const indexes = await account.vectorize(accountId, CLI_API_OPTIONS);
363
+ if (indexes.length === 0) {
364
+ return logEmptyState(logger, "No Vectorize indexes found", theme);
365
+ }
366
+ logSection(logger, "Vectorize indexes", theme, indexes.length, "yellow");
367
+ logTable(logger, {
368
+ title: "Index list",
369
+ rows: indexes,
370
+ columns: [
371
+ { label: "Name", width: 25, value: (idx) => idx.name },
372
+ { label: "Dimensions", width: 12, value: (idx) => String(idx.dimensions) },
373
+ { label: "Metric", width: 15, value: (idx) => idx.metric }
374
+ ],
375
+ theme,
376
+ titleAccent: "yellow"
377
+ });
378
+ logLine(logger);
379
+ return { exitCode: 0 };
380
+ }
381
+ async function showUsage(accountId, logger, theme) {
382
+ const usages = await account.getAllUsageSummaries(accountId);
383
+ const limits = await account.getLimits(accountId);
384
+ logSection(logger, "Usage", theme, undefined, "yellow");
385
+ logLine(logger, formatLabelValue("limits", limits.enabled ? green("enabled", theme) : dim("disabled", theme), theme, 12));
386
+ if (usages.length === 0) {
387
+ return logEmptyState(logger, "No usage tracked yet", theme);
388
+ }
389
+ logTable(logger, {
390
+ title: "Usage by service",
391
+ rows: usages,
392
+ columns: [
393
+ { label: "Service", width: 15, value: (usage) => usage.service },
394
+ { label: "Today", width: 10, value: (usage) => String(usage.today) },
395
+ { label: "Limit", width: 10, value: (usage) => usage.limit?.toString() ?? "∞" },
396
+ { label: "%", width: 10, value: (usage) => formatPercent(usage.percentUsed) },
397
+ { label: "Status", width: 10, value: (usage) => usage.withinLimit ? green("ok", theme) : yellow("limit", theme) }
398
+ ],
399
+ theme,
400
+ titleAccent: "yellow"
401
+ });
402
+ logLine(logger);
403
+ return { exitCode: 0 };
404
+ }
405
+ async function handleLimits(accountId, parsed, logger, theme) {
406
+ const action = parsed.args[1];
407
+ switch (action) {
408
+ case "set":
409
+ return await setLimit(accountId, parsed, logger, theme);
410
+ case "enable":
411
+ await account.setLimitsEnabled(accountId, true);
412
+ logger.success("Usage limits enabled");
413
+ return { exitCode: 0 };
414
+ case "disable":
415
+ await account.setLimitsEnabled(accountId, false);
416
+ logger.success("Usage limits disabled");
417
+ return { exitCode: 0 };
418
+ default:
419
+ return await showLimits(accountId, logger, theme);
420
+ }
421
+ }
422
+ async function showLimits(accountId, logger, theme) {
423
+ const limits = await account.getLimits(accountId);
424
+ logSection(logger, "Usage limits", theme, undefined, "yellow");
425
+ logLine(logger, formatLabelValue("status", limits.enabled ? green("enabled", theme) : dim("disabled", theme), theme, 16));
426
+ logLine(logger);
427
+ logLine(logger, dim("current limits", theme));
428
+ logLine(logger, formatLabelValue("AI Requests/Day", String(limits.aiRequestsPerDay ?? "Unlimited"), theme, 18));
429
+ logLine(logger, formatLabelValue("AI Tokens/Day", String(limits.aiTokensPerDay ?? "Unlimited"), theme, 18));
430
+ logLine(logger, formatLabelValue("Vectorize Ops/Day", String(limits.vectorizeOpsPerDay ?? "Unlimited"), theme, 18));
431
+ logSection(logger, "Commands", theme);
432
+ logLine(logger, formatCommand("devflare account limits set ai-requests 50", "Set the AI request daily limit", theme));
433
+ logLine(logger, formatCommand("devflare account limits set ai-tokens 5000", "Set the AI token daily limit", theme));
434
+ logLine(logger, formatCommand("devflare account limits set vectorize-ops 500", "Set the Vectorize daily limit", theme));
435
+ logLine(logger, formatCommand("devflare account limits enable", "Enable usage limits", theme));
436
+ logLine(logger, formatCommand("devflare account limits disable", "Disable usage limits", theme));
437
+ logLine(logger);
438
+ return { exitCode: 0 };
439
+ }
440
+ async function setLimit(accountId, parsed, logger, theme) {
441
+ const limitName = parsed.args[2];
442
+ const limitValue = parsed.args[3];
443
+ if (!limitName || !limitValue) {
444
+ logger.error("Usage: devflare account limits set <limit-name> <value>");
445
+ logLine(logger, dim("Limit names: ai-requests, ai-tokens, vectorize-ops", theme));
446
+ return { exitCode: 1 };
447
+ }
448
+ const value = parseInt(limitValue, 10);
449
+ if (isNaN(value) || value < 0) {
450
+ logger.error("Limit value must be a positive number");
451
+ return { exitCode: 1 };
452
+ }
453
+ switch (limitName) {
454
+ case "ai-requests":
455
+ await account.setLimits(accountId, { aiRequestsPerDay: value });
456
+ logger.success(`AI requests limit set to ${value}/day`);
457
+ break;
458
+ case "ai-tokens":
459
+ await account.setLimits(accountId, { aiTokensPerDay: value });
460
+ logger.success(`AI tokens limit set to ${value}/day`);
461
+ break;
462
+ case "vectorize-ops":
463
+ await account.setLimits(accountId, { vectorizeOpsPerDay: value });
464
+ logger.success(`Vectorize ops limit set to ${value}/day`);
465
+ break;
466
+ default:
467
+ logger.error(`Unknown limit: ${limitName}`);
468
+ logLine(logger, dim("Valid limits: ai-requests, ai-tokens, vectorize-ops", theme));
469
+ return { exitCode: 1 };
470
+ }
471
+ return { exitCode: 0 };
472
+ }
473
+ export {
474
+ runAccountCommand
475
+ };
package/dist/browser.d.ts CHANGED
@@ -731,7 +731,7 @@ export declare const configSchema: import("zod").ZodEffects<import("zod").ZodObj
731
731
  }, {
732
732
  required?: boolean | undefined;
733
733
  }>>>;
734
- routes: import("zod").ZodOptional<import("zod").ZodArray<import("zod").ZodObject<{
734
+ routes: import("zod").ZodOptional<import("zod").ZodArray<import("zod").ZodEffects<import("zod").ZodObject<{
735
735
  pattern: import("zod").ZodString;
736
736
  zone_name: import("zod").ZodOptional<import("zod").ZodString>;
737
737
  zone_id: import("zod").ZodOptional<import("zod").ZodString>;
@@ -746,6 +746,16 @@ export declare const configSchema: import("zod").ZodEffects<import("zod").ZodObj
746
746
  zone_name?: string | undefined;
747
747
  zone_id?: string | undefined;
748
748
  custom_domain?: boolean | undefined;
749
+ }>, {
750
+ pattern: string;
751
+ zone_name?: string | undefined;
752
+ zone_id?: string | undefined;
753
+ custom_domain?: boolean | undefined;
754
+ }, {
755
+ pattern: string;
756
+ zone_name?: string | undefined;
757
+ zone_id?: string | undefined;
758
+ custom_domain?: boolean | undefined;
749
759
  }>, "many">>;
750
760
  wsRoutes: import("zod").ZodOptional<import("zod").ZodArray<import("zod").ZodObject<{
751
761
  pattern: import("zod").ZodString;
@@ -1716,7 +1726,7 @@ export declare const configSchema: import("zod").ZodEffects<import("zod").ZodObj
1716
1726
  }, {
1717
1727
  required?: boolean | undefined;
1718
1728
  }>>>>;
1719
- readonly routes: import("zod").ZodOptional<import("zod").ZodOptional<import("zod").ZodArray<import("zod").ZodObject<{
1729
+ readonly routes: import("zod").ZodOptional<import("zod").ZodOptional<import("zod").ZodArray<import("zod").ZodEffects<import("zod").ZodObject<{
1720
1730
  pattern: import("zod").ZodString;
1721
1731
  zone_name: import("zod").ZodOptional<import("zod").ZodString>;
1722
1732
  zone_id: import("zod").ZodOptional<import("zod").ZodString>;
@@ -1731,6 +1741,16 @@ export declare const configSchema: import("zod").ZodEffects<import("zod").ZodObj
1731
1741
  zone_name?: string | undefined;
1732
1742
  zone_id?: string | undefined;
1733
1743
  custom_domain?: boolean | undefined;
1744
+ }>, {
1745
+ pattern: string;
1746
+ zone_name?: string | undefined;
1747
+ zone_id?: string | undefined;
1748
+ custom_domain?: boolean | undefined;
1749
+ }, {
1750
+ pattern: string;
1751
+ zone_name?: string | undefined;
1752
+ zone_id?: string | undefined;
1753
+ custom_domain?: boolean | undefined;
1734
1754
  }>, "many">>>;
1735
1755
  readonly assets: import("zod").ZodOptional<import("zod").ZodOptional<import("zod").ZodObject<{
1736
1756
  directory: import("zod").ZodString;
@@ -1 +1 @@
1
- {"version":3,"file":"browser.d.ts","sourceRoot":"","sources":["../src/browser.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAA;AAC9C,OAAO,EAAE,GAAG,EAAE,MAAM,cAAc,CAAA;AAGlC,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AACzC,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,OAAO,CAAA;AAGjC,OAAO,EACN,eAAe,EACf,cAAc,EACd,OAAO,EACP,MAAM,gBAAgB,CAAA;AACvB,YAAY,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAA;AACnE,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AACzD,YAAY,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAA;AAG1D,OAAO,EACN,aAAa,EACb,uBAAuB,EACvB,KAAK,oBAAoB,EACzB,MAAM,cAAc,CAAA;AAGrB,KAAK,YAAY,GAAG,cAAc,UAAU,CAAC,CAAA;AAM7C,KAAK,uBAAuB,GAAG,qBAAqB,CAAC,YAAY,CAAC,qBAAqB,CAAC,CAAC,CAAA;AACzF,KAAK,yBAAyB,GAAG,qBAAqB,CAAC,YAAY,CAAC,uBAAuB,CAAC,CAAC,CAAA;AAC7F,KAAK,iCAAiC,GAAG,qBAAqB,CAAC,YAAY,CAAC,+BAA+B,CAAC,CAAC,CAAA;AAkC7G,eAAO,MAAM,UAAU,sCAAgE,CAAA;AACvF,eAAO,MAAM,kBAAkB,8CAAgF,CAAA;AAE/G,eAAO,MAAM,aAAa,yCAAsE,CAAA;AAChG,eAAO,MAAM,eAAe,2CAA0E,CAAA;AACtG,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAAwE,CAAA;AAEjG,qBAAa,mBAAoB,SAAQ,KAAK;IAC7C,QAAQ,CAAC,IAAI,sBAAqB;IAElC,YAAY,GAAG,KAAK,EAAE,uBAAuB,EAG5C;CACD;AAED,qBAAa,qBAAsB,SAAQ,KAAK;IAC/C,QAAQ,CAAC,IAAI,6BAA4B;IAEzC,YAAY,GAAG,KAAK,EAAE,yBAAyB,EAG9C;CACD;AAED,qBAAa,6BAA8B,SAAQ,KAAK;IACvD,QAAQ,CAAC,IAAI,sCAAqC;IAElD,YAAY,GAAG,KAAK,EAAE,iCAAiC,EAGtD;CACD;AAED,eAAO,MAAM,MAAM,+BAAqD,CAAA;AACxE,eAAO,MAAM,SAAS,kCAA2D,CAAA;AAEjF,eAAO,MAAM,wBAAwB,uDAA+F,CAAA;AACpI,eAAO,MAAM,gCAAgC,uDAAuG,CAAA;AACpJ,eAAO,MAAM,eAAe,8CAA6E,CAAA;AACzG,eAAO,MAAM,sBAAsB,qDAA2F,CAAA;AAC9H,eAAO,MAAM,yBAAyB,wDAAiG,CAAA;AACvI,eAAO,MAAM,qBAAqB,oDAAyF,CAAA;AAC3H,eAAO,MAAM,qBAAqB,oDAAyF,CAAA;AAC3H,eAAO,MAAM,oBAAoB,mDAAuF,CAAA;AAExH,eAAO,MAAM,cAAc,0CAA2E,CAAA;AACtG,eAAO,MAAM,wBAAwB,oDAA+F,CAAA;AACpI,eAAO,MAAM,YAAY,wCAAuE,CAAA;AAChG,eAAO,MAAM,aAAa,yCAAyE,CAAA;AACnG,eAAO,MAAM,OAAO;;CAAoE,CAAA;AAExF,eAAO,MAAM,iBAAiB,2CAA4E,CAAA;AAC1G,eAAO,MAAM,qBAAqB,+CAAoF,CAAA;AACtH,eAAO,MAAM,YAAY,sCAAkE,CAAA;AAC3F,eAAO,MAAM,YAAY,sCAAkE,CAAA;AAC3F,eAAO,MAAM,YAAY,sCAAkE,CAAA;AAC3F,eAAO,MAAM,eAAe,yCAAwE,CAAA;AACpG,eAAO,MAAM,aAAa,uCAAoE,CAAA;AAC9F,eAAO,MAAM,eAAe,yCAAwE,CAAA;AAEpG,OAAO,EAAE,YAAY,IAAI,OAAO,EAAE,MAAM,iBAAiB,CAAA"}
1
+ {"version":3,"file":"browser.d.ts","sourceRoot":"","sources":["../src/browser.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAA;AAC9C,OAAO,EAAE,GAAG,EAAE,MAAM,cAAc,CAAA;AAGlC,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AACzC,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,OAAO,CAAA;AAGjC,OAAO,EACN,eAAe,EACf,cAAc,EACd,OAAO,EACP,MAAM,gBAAgB,CAAA;AACvB,YAAY,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAA;AACnE,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AACzD,YAAY,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAA;AAG1D,OAAO,EACN,aAAa,EACb,uBAAuB,EACvB,KAAK,oBAAoB,EACzB,MAAM,cAAc,CAAA;AAGrB,KAAK,YAAY,GAAG,cAAc,UAAU,CAAC,CAAA;AAM7C,KAAK,uBAAuB,GAAG,qBAAqB,CAAC,YAAY,CAAC,qBAAqB,CAAC,CAAC,CAAA;AACzF,KAAK,yBAAyB,GAAG,qBAAqB,CAAC,YAAY,CAAC,uBAAuB,CAAC,CAAC,CAAA;AAC7F,KAAK,iCAAiC,GAAG,qBAAqB,CAAC,YAAY,CAAC,+BAA+B,CAAC,CAAC,CAAA;AAkC7G,eAAO,MAAM,UAAU,sCAAgE,CAAA;AACvF,eAAO,MAAM,kBAAkB,8CAAgF,CAAA;AAE/G,eAAO,MAAM,aAAa,yCAAsE,CAAA;AAChG,eAAO,MAAM,eAAe,2CAA0E,CAAA;AACtG,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAAwE,CAAA;AAEjG,qBAAa,mBAAoB,SAAQ,KAAK;IAC7C,QAAQ,CAAC,IAAI,sBAAqB;IAElC,YAAY,GAAG,KAAK,EAAE,uBAAuB,EAG5C;CACD;AAED,qBAAa,qBAAsB,SAAQ,KAAK;IAC/C,QAAQ,CAAC,IAAI,6BAA4B;IAEzC,YAAY,GAAG,KAAK,EAAE,yBAAyB,EAG9C;CACD;AAED,qBAAa,6BAA8B,SAAQ,KAAK;IACvD,QAAQ,CAAC,IAAI,sCAAqC;IAElD,YAAY,GAAG,KAAK,EAAE,iCAAiC,EAGtD;CACD;AAED,eAAO,MAAM,MAAM,+BAAqD,CAAA;AACxE,eAAO,MAAM,SAAS,kCAA2D,CAAA;AAEjF,eAAO,MAAM,wBAAwB,uDAA+F,CAAA;AACpI,eAAO,MAAM,gCAAgC,uDAAuG,CAAA;AACpJ,eAAO,MAAM,eAAe,8CAA6E,CAAA;AACzG,eAAO,MAAM,sBAAsB,qDAA2F,CAAA;AAC9H,eAAO,MAAM,yBAAyB,wDAAiG,CAAA;AACvI,eAAO,MAAM,qBAAqB,oDAAyF,CAAA;AAC3H,eAAO,MAAM,qBAAqB,oDAAyF,CAAA;AAC3H,eAAO,MAAM,oBAAoB,mDAAuF,CAAA;AAExH,eAAO,MAAM,cAAc,0CAA2E,CAAA;AACtG,eAAO,MAAM,wBAAwB,oDAA+F,CAAA;AACpI,eAAO,MAAM,YAAY,wCAAuE,CAAA;AAChG,eAAO,MAAM,aAAa,yCAAyE,CAAA;AACnG,eAAO,MAAM,OAAO;;CAAoE,CAAA;AAExF,eAAO,MAAM,iBAAiB,2CAA4E,CAAA;AAC1G,eAAO,MAAM,qBAAqB,+CAAoF,CAAA;AACtH,eAAO,MAAM,YAAY,sCAAkE,CAAA;AAC3F,eAAO,MAAM,YAAY,sCAAkE,CAAA;AAC3F,eAAO,MAAM,YAAY,sCAAkE,CAAA;AAC3F,eAAO,MAAM,eAAe,yCAAwE,CAAA;AACpG,eAAO,MAAM,aAAa,uCAAoE,CAAA;AAC9F,eAAO,MAAM,eAAe,yCAAwE,CAAA;AAEpG,OAAO,EAAE,YAAY,IAAI,OAAO,EAAE,MAAM,iBAAiB,CAAA"}