@localhostdevs/sdk 0.13.0 → 0.15.0

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.
package/README.md CHANGED
@@ -22,11 +22,11 @@ const bot = new Bot({
22
22
  // apiKey: process.env.BOT_SECRET, // optional; auto-read from env if unset
23
23
  });
24
24
 
25
- bot.cmd('ping', async (ctx) => {
25
+ bot.cmd({ name: 'ping' }, async (ctx) => {
26
26
  await ctx.reply({ text: 'pong' });
27
27
  });
28
28
 
29
- bot.cmd('echo', async (ctx) => {
29
+ bot.cmd({ name: 'echo' }, async (ctx) => {
30
30
  await ctx.reply({ text: `echo: ${JSON.stringify(ctx.args)}` });
31
31
  });
32
32
 
@@ -53,15 +53,63 @@ The bot stays online for as long as the process runs. The gateway keeps the conn
53
53
  | `serverUrl` | `string` | `wss://bot-api.localhostdevs.com/bot` (override with `LHD_SERVER_URL`) | Production gateway is baked in — most users leave this alone. Only override for local dev or self-hosted gateways. |
54
54
  | `idempotencyLruSize` | `number` | `1024` | How many recent message IDs to remember for deduplication. |
55
55
 
56
- ### `bot.cmd(name, handler)`
56
+ ### `bot.cmd(def, handler)`
57
57
 
58
- Register a handler for a command. Must be called before `connect()`. Handler receives a `CommandContext`:
58
+ Register a handler for a command. Must be called before `connect()`. The first argument is a **command definition object** with the following fields:
59
+
60
+ | Field | Type | Notes |
61
+ | ------------- | ------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------- |
62
+ | `name` | `string` (required) | Command name consumers dispatch (e.g. `'ping'`, `'topic'`). |
63
+ | `description` | `string` | Human-readable description shown on the marketplace/workflow picker. |
64
+ | `args` | `Record<string, ArgSpec>` | Declare the expected arguments (see below). **Advertise-only** by default — fills the marketplace and workflow picker but does NOT validate at runtime unless `validate: true`. |
65
+ | `returns` | `{ kind: ReplyKind, data?: Record<string, 'string' \| 'number' \| 'boolean'> }` | Declare the reply kind. Enforced: the handler must call the matching reply method or the SDK throws (see Reply-kind enforcement below). |
66
+ | `validate` | `boolean` | When `true`, the SDK validates `ctx.args` against the declared `args` before running your handler. A bad dispatch is rejected with a structured `invalid_args` error. Also narrows TypeScript types: `required` fields become typed-present in `ctx.args`. Without `validate`, all arg fields are typed optional. |
67
+ | `streaming` | `boolean` | Override the bot-level streaming flag for this command only. |
68
+ | `mimeType` | `string` | MIME-type hint advertised in IDENTIFY (advertising-only, doesn't affect runtime). |
69
+
70
+ #### `ArgSpec` shape
71
+
72
+ ```ts
73
+ interface ArgSpec {
74
+ type: 'string' | 'number' | 'boolean' | 'enum';
75
+ required?: boolean;
76
+ description?: string;
77
+ values?: readonly string[]; // required when type === 'enum'
78
+ }
79
+ ```
80
+
81
+ #### `returns.kind` vocabulary
82
+
83
+ `'text'` | `'list'` | `'table'` | `'image'` | `'buttons'` | `'collect'`
84
+
85
+ The declared kind is **enforced at runtime**: if the handler calls a reply method that doesn't match the declaration (e.g. `returns: { kind: 'list' }` but the handler calls `ctx.reply()`), the SDK throws a hard error. TypeScript also narrows `ctx`'s available reply methods to just the ones valid for the declared kind.
86
+
87
+ #### Example
88
+
89
+ ```ts
90
+ bot.cmd({
91
+ name: 'topic',
92
+ description: 'Scrape trends for a query, then pick one',
93
+ args: {
94
+ query: { type: 'string', required: true, description: 'Search query' },
95
+ format: { type: 'string', description: 'e.g. short_30s' },
96
+ voice: { type: 'enum', values: ['on', 'off'] },
97
+ },
98
+ returns: { kind: 'list', data: { jobId: 'string', state: 'string' } },
99
+ validate: false, // opt-in: when true, args are validated AND required fields typed-present
100
+ }, async (ctx) => {
101
+ // ctx.args is typed from `args`; ctx reply methods are narrowed to returns.kind
102
+ await ctx.replyList([{ title: ctx.args.query ?? '' }]);
103
+ });
104
+ ```
105
+
106
+ Handler receives a `CommandContext`:
59
107
 
60
108
  ```ts
61
- bot.cmd('greet', async (ctx) => {
62
- // ctx.args: parsed args from the consumer
109
+ bot.cmd({ name: 'greet' }, async (ctx) => {
110
+ // ctx.args: parsed args from the consumer
63
111
  // ctx.command: 'greet'
64
- // ctx.msgId: unique id for this invocation
112
+ // ctx.msgId: unique id for this invocation
65
113
 
66
114
  await ctx.reply({ text: `Hello, ${ctx.args.name ?? 'world'}!` });
67
115
 
@@ -92,7 +140,7 @@ The gateway pings the bot every 30 seconds and the SDK responds. If the gateway
92
140
  A reply can carry a `dispatch` directive to chain a command to another bot:
93
141
 
94
142
  ```js
95
- bot.cmd('summary', async (ctx) => {
143
+ bot.cmd({ name: 'summary' }, async (ctx) => {
96
144
  await ctx.reply({
97
145
  text: 'fetching price first…',
98
146
  dispatch: { to: 'price-bot', command: 'price', args: { ticker: 'AAPL' } },
@@ -107,11 +155,14 @@ Chains run up to depth 5 with loop detection. The original consumer pays for eve
107
155
  By default `ctx.reply({ text })` sends a plain-text body — the consumer
108
156
  renders it as text. To get richer rendering (source-badge lists, striped
109
157
  tables) on the dashboard Test Console and the public Try widget, return a
110
- **kinded** body via the two new helpers:
158
+ **kinded** body via the helpers:
111
159
 
112
160
  ```js
113
161
  // List output
114
- bot.cmd('headlines', async (ctx) => {
162
+ bot.cmd({
163
+ name: 'headlines',
164
+ returns: { kind: 'list' },
165
+ }, async (ctx) => {
115
166
  await ctx.replyList(
116
167
  [
117
168
  { label: 'AP', title: 'Story one', secondary: '2m', href: '…' },
@@ -122,7 +173,10 @@ bot.cmd('headlines', async (ctx) => {
122
173
  });
123
174
 
124
175
  // Table output
125
- bot.cmd('top5', async (ctx) => {
176
+ bot.cmd({
177
+ name: 'top5',
178
+ returns: { kind: 'table' },
179
+ }, async (ctx) => {
126
180
  await ctx.replyTable({
127
181
  headers: ['ticker', 'price', 'change'],
128
182
  rows: [
@@ -159,10 +213,11 @@ guard flips, so if you catch the error you can still send a corrected
159
213
  further reply calls throw — the SDK guarantees exactly-one reply per
160
214
  command.
161
215
 
162
- **Pair with `output_kind`.** Declare the shape of each command on the bot
163
- detail page so the dashboard can pick the right renderer ahead of time
164
- (`text` / `list` / `table`). Mis-declarations soft-fall-back to text
165
- rendering they don't fail the dispatch.
216
+ **Reply-kind enforcement.** When `returns.kind` is declared on the command
217
+ definition, the SDK enforces it at runtime: calling a mismatched reply
218
+ method (e.g. `ctx.reply()` when `returns: { kind: 'list' }`) throws a hard
219
+ error. TypeScript also narrows `ctx`'s available reply methods to the ones
220
+ valid for the declared kind, so mismatches are caught at compile time.
166
221
 
167
222
  ## Streaming progress (`ctx.update`)
168
223
 
@@ -175,7 +230,7 @@ const bot = new Bot({
175
230
  streaming: true, // enables ctx.update across all commands
176
231
  });
177
232
 
178
- bot.cmd('analyze', async (ctx) => {
233
+ bot.cmd({ name: 'analyze' }, async (ctx) => {
179
234
  await ctx.update({ progress: 10, text: 'Fetching…' });
180
235
  await ctx.update({ progress: 60, text: 'Crunching…' });
181
236
  await ctx.reply({
@@ -186,11 +241,11 @@ bot.cmd('analyze', async (ctx) => {
186
241
  });
187
242
  ```
188
243
 
189
- Or per-command:
244
+ Or per-command using `streaming` in the definition:
190
245
 
191
246
  ```js
192
- bot.cmd('analyze', { streaming: true }, async (ctx) => { /* … */ });
193
- bot.cmd('ping', async (ctx) => { /* no ctx.update here */ });
247
+ bot.cmd({ name: 'analyze', streaming: true }, async (ctx) => { /* … */ });
248
+ bot.cmd({ name: 'ping' }, async (ctx) => { /* no ctx.update here */ });
194
249
  ```
195
250
 
196
251
  **Progress shapes** (use whichever fits the work):
@@ -218,15 +273,15 @@ Tell the platform what each command's reply looks like so the bot
218
273
  detail page can show consumers what to expect:
219
274
 
220
275
  ```js
221
- bot.cmd('chart', { streaming: true, mimeType: 'image/png' }, async (ctx) => {
276
+ bot.cmd({ name: 'chart', streaming: true, mimeType: 'image/png' }, async (ctx) => {
222
277
  await ctx.reply({ data: chartBytes, mimeType: 'image/png' });
223
278
  });
224
279
 
225
- bot.cmd('summarize', { mimeType: 'text/markdown' }, async (ctx) => {
280
+ bot.cmd({ name: 'summarize', mimeType: 'text/markdown' }, async (ctx) => {
226
281
  await ctx.reply({ text: '# Summary\n…', mimeType: 'text/markdown' });
227
282
  });
228
283
 
229
- bot.cmd('ping', async (ctx) => { // no opts — displays as text/plain
284
+ bot.cmd({ name: 'ping' }, async (ctx) => { // no mimeType — displays as text/plain
230
285
  await ctx.reply({ text: 'pong' });
231
286
  });
232
287
  ```
@@ -267,8 +322,7 @@ v0.4 is additive — nothing breaks for bots calling only `ctx.reply()`.
267
322
  New surface:
268
323
 
269
324
  - `new Bot({ …, streaming: true })` to enable `ctx.update()`
270
- - `bot.cmd(name, { streaming: true }, handler)` to flip the flag per
271
- command without touching bot-init
325
+ - `streaming: true` inside the command definition to flip the flag per command
272
326
  - `ctx.update({ progress?, text?, data?, mimeType? })` — send 1+
273
327
  intermediate frames before `ctx.reply()`
274
328
  - `mimeType` on `ctx.reply()` for the existing final-reply path
@@ -277,11 +331,25 @@ No env-var changes, no protocol breakage, no upstream re-auth.
277
331
 
278
332
  ## v0.4.0 → v0.4.1 (per-command mimeType)
279
333
 
280
- Additive — no breaking changes. The `mimeType?` field in
281
- `CommandHandlerOptions` is optional; bots that ignore it work exactly
282
- the same. The SDK auto-builds an IDENTIFY-time `commands` array from
283
- your registered handlers so the platform can display them on the bot
284
- detail page.
334
+ Additive — no breaking changes. The `mimeType?` field in the command definition
335
+ is optional; bots that ignore it work exactly the same. The SDK auto-builds an
336
+ IDENTIFY-time `commands` array from your registered handlers so the platform can
337
+ display them on the bot detail page.
338
+
339
+ ## v0.14 → v0.15 (object `cmd()`)
340
+
341
+ **Breaking.** See [MIGRATION.md](./MIGRATION.md) for the full guide.
342
+
343
+ `cmd()` now takes a **command definition object** as its first argument. The
344
+ string-form is removed.
345
+
346
+ ```diff
347
+ - bot.cmd("ping", async (ctx) => { … })
348
+ + bot.cmd({ name: "ping" }, async (ctx) => { … })
349
+
350
+ - bot.cmd("analyze", { streaming: true }, async (ctx) => { … })
351
+ + bot.cmd({ name: "analyze", streaming: true }, async (ctx) => { … })
352
+ ```
285
353
 
286
354
  ## License
287
355
 
@@ -0,0 +1,7 @@
1
+ import { type ZodType } from 'zod';
2
+ import type { ArgSpec, ReturnsSpec } from './types.js';
3
+ export declare function argsToJsonSchema(args: Record<string, ArgSpec>): Record<string, unknown>;
4
+ export declare function returnsDataToJsonSchema(data: ReturnsSpec['data']): Record<string, unknown> | undefined;
5
+ export declare function returnsDataToZod(data: ReturnsSpec['data']): ZodType | undefined;
6
+ export declare function argsToZod(args: Record<string, ArgSpec>): ZodType;
7
+ //# sourceMappingURL=argSchema.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"argSchema.d.ts","sourceRoot":"","sources":["../src/argSchema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAK,KAAK,OAAO,EAAE,MAAM,KAAK,CAAC;AACtC,OAAO,KAAK,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAavD,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAUvF;AAED,wBAAgB,uBAAuB,CACrC,IAAI,EAAE,WAAW,CAAC,MAAM,CAAC,GACxB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAKrC;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,WAAW,CAAC,MAAM,CAAC,GAAG,OAAO,GAAG,SAAS,CAO/E;AAED,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAkBhE"}
@@ -0,0 +1,63 @@
1
+ import { z } from 'zod';
2
+ function propSchema(s) {
3
+ if (s.type === 'enum') {
4
+ const p = { type: 'string', enum: [...(s.values ?? [])] };
5
+ if (s.description)
6
+ p.description = s.description;
7
+ return p;
8
+ }
9
+ const p = { type: s.type };
10
+ if (s.description)
11
+ p.description = s.description;
12
+ return p;
13
+ }
14
+ export function argsToJsonSchema(args) {
15
+ const properties = {};
16
+ const required = [];
17
+ for (const [name, spec] of Object.entries(args)) {
18
+ properties[name] = propSchema(spec);
19
+ if (spec.required)
20
+ required.push(name);
21
+ }
22
+ const out = { type: 'object', properties };
23
+ if (required.length)
24
+ out.required = required;
25
+ return out;
26
+ }
27
+ export function returnsDataToJsonSchema(data) {
28
+ if (!data)
29
+ return undefined;
30
+ const properties = {};
31
+ for (const [name, t] of Object.entries(data))
32
+ properties[name] = { type: t };
33
+ return { type: 'object', properties };
34
+ }
35
+ export function returnsDataToZod(data) {
36
+ if (!data)
37
+ return undefined;
38
+ const shape = {};
39
+ for (const [name, t] of Object.entries(data)) {
40
+ shape[name] = t === 'number' ? z.number() : t === 'boolean' ? z.boolean() : z.string();
41
+ }
42
+ return z.object(shape);
43
+ }
44
+ export function argsToZod(args) {
45
+ const shape = {};
46
+ for (const [name, spec] of Object.entries(args)) {
47
+ if (spec.type === 'enum' && (!spec.values || spec.values.length === 0)) {
48
+ throw new Error(`enum arg requires a non-empty \`values\` array`);
49
+ }
50
+ let field = spec.type === 'string'
51
+ ? z.string()
52
+ : spec.type === 'number'
53
+ ? z.number()
54
+ : spec.type === 'boolean'
55
+ ? z.boolean()
56
+ : z.enum([...(spec.values ?? [])]);
57
+ if (!spec.required)
58
+ field = field.optional();
59
+ shape[name] = field;
60
+ }
61
+ return z.object(shape);
62
+ }
63
+ //# sourceMappingURL=argSchema.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"argSchema.js","sourceRoot":"","sources":["../src/argSchema.ts"],"names":[],"mappings":"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"}
package/dist/bot.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { nanoid } from 'nanoid';
2
- import type { BotOptions, CommandHandler, CommandHandlerOptions } from './types.js';
2
+ import type { ArgsOf, BotOptions, CommandContext, CommandDef, CommandHandler, ReturnsOf } from './types.js';
3
3
  export { SDK_PACKAGE_VERSION } from './version.js';
4
4
  export declare class Bot {
5
5
  private readonly opts;
@@ -10,18 +10,18 @@ export declare class Bot {
10
10
  private readonly cmdOpts;
11
11
  private readonly seen;
12
12
  private readonly seenQueue;
13
- private readonly pollOpts;
14
- private pollStore;
15
- private pollTimer;
13
+ private readonly collectOpts;
14
+ private collectStore;
15
+ private collectTimer;
16
16
  private closing;
17
17
  private reconnectTimer;
18
18
  private reconnectAttempt;
19
19
  private cachedApiKey;
20
20
  constructor(opts: BotOptions);
21
- /** Register a handler with no per-command overrides. */
22
- cmd(name: string, handler: CommandHandler): this;
23
- /** Register a handler with per-command overrides. */
24
- cmd(name: string, opts: CommandHandlerOptions, handler: CommandHandler): this;
21
+ /** Register a command from its definition object. The ONLY public way to add a command. */
22
+ cmd<const D extends CommandDef>(def: D, handler: (ctx: CommandContext<ArgsOf<D>, ReturnsOf<D>>) => void | Promise<void>): this;
23
+ /** Internal: the single registration path. Not part of the public API. */
24
+ private registerHandler;
25
25
  /** Register an internal action handler (Interactive Prompts). Stored in the
26
26
  * same handler map `cmd()` uses — so dispatch routing is unchanged — but
27
27
  * flagged `internal: true` so it is EXCLUDED from the IDENTIFY advertised
@@ -49,13 +49,14 @@ export declare class Bot {
49
49
  * Users can override by calling cmd('commands', ...) themselves. */
50
50
  private replyWithCommandList;
51
51
  private dispatch;
52
- private resolvePollDbPath;
53
- /** Lazily open the poll store (node:sqlite) and start the close loop. */
54
- private ensurePollStore;
55
- /** The sink invoked when a poll closes: user callback if set, else log. Must
56
- * not throw — a throwing sink leaves the poll open for retry. */
57
- private pollSink;
58
- private startPollLoop;
52
+ private resolveCollectDbPath;
53
+ /** Lazily open the collect store (node:sqlite) and start the close loop. */
54
+ private ensureCollectStore;
55
+ /** The sink invoked when a collect closes: user callback if set, else push a
56
+ * frame / log. Must not throw — a throwing sink leaves the collect open for
57
+ * retry. */
58
+ private collectSink;
59
+ private startCollectLoop;
59
60
  private makeContext;
60
61
  private isDuplicate;
61
62
  private recordSeen;
package/dist/bot.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"bot.d.ts","sourceRoot":"","sources":["../src/bot.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAShC,OAAO,KAAK,EACV,UAAU,EAGV,cAAc,EACd,qBAAqB,EAOtB,MAAM,YAAY,CAAC;AAKpB,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AA8CnD,qBAAa,GAAG;IACd,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAqB;IAC1C,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAS;IACvC,OAAO,CAAC,SAAS,CAA0B;IAC3C,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAqC;IAC9D,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA4C;IACpE,OAAO,CAAC,QAAQ,CAAC,IAAI,CAA0B;IAC/C,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAgB;IAC1C,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAGvB;IACF,OAAO,CAAC,SAAS,CAA0B;IAC3C,OAAO,CAAC,SAAS,CAA+C;IAChE,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,cAAc,CAA8C;IACpE,OAAO,CAAC,gBAAgB,CAAK;IAC7B,OAAO,CAAC,YAAY,CAAuB;gBAE/B,IAAI,EAAE,UAAU;IAwC5B,wDAAwD;IACxD,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,cAAc,GAAG,IAAI;IAChD,qDAAqD;IACrD,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,qBAAqB,EAAE,OAAO,EAAE,cAAc,GAAG,IAAI;IA0B7E;;;;wEAIoE;IACpE,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,cAAc,GAAG,IAAI;IAIjD,OAAO,CAAC,cAAc;IAMtB,2FAA2F;IACrF,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAsB9B,iFAAiF;YACnE,aAAa;IAuD3B,OAAO,CAAC,iBAAiB;YAcX,YAAY;IAe1B;;;;;OAKG;YACW,aAAa;IAoB3B,0DAA0D;IACpD,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAoBjC;;yEAEqE;IACrE,OAAO,CAAC,oBAAoB;YAYd,QAAQ;IA6EtB,OAAO,CAAC,iBAAiB;IAQzB,yEAAyE;IACzE,OAAO,CAAC,eAAe;IAcvB;sEACkE;IAClE,OAAO,CAAC,QAAQ;IAUhB,OAAO,CAAC,aAAa;IAYrB,OAAO,CAAC,WAAW;IA+RnB,OAAO,CAAC,WAAW;IAInB,OAAO,CAAC,UAAU;CAQnB;AAGD,OAAO,EAAE,MAAM,EAAE,CAAC"}
1
+ {"version":3,"file":"bot.d.ts","sourceRoot":"","sources":["../src/bot.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAWhC,OAAO,KAAK,EACV,MAAM,EACN,UAAU,EAGV,cAAc,EACd,UAAU,EACV,cAAc,EAMd,SAAS,EAGV,MAAM,YAAY,CAAC;AAKpB,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AA8CnD,qBAAa,GAAG;IACd,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAqB;IAC1C,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAS;IACvC,OAAO,CAAC,SAAS,CAA0B;IAC3C,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAqC;IAC9D,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA4C;IACpE,OAAO,CAAC,QAAQ,CAAC,IAAI,CAA0B;IAC/C,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAgB;IAC1C,OAAO,CAAC,QAAQ,CAAC,WAAW,CAG1B;IACF,OAAO,CAAC,YAAY,CAA6B;IACjD,OAAO,CAAC,YAAY,CAA+C;IACnE,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,cAAc,CAA8C;IACpE,OAAO,CAAC,gBAAgB,CAAK;IAC7B,OAAO,CAAC,YAAY,CAAuB;gBAE/B,IAAI,EAAE,UAAU;IA2C5B,2FAA2F;IAC3F,GAAG,CAAC,KAAK,CAAC,CAAC,SAAS,UAAU,EAC5B,GAAG,EAAE,CAAC,EACN,OAAO,EAAE,CAAC,GAAG,EAAE,cAAc,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,GAC9E,IAAI;IAgCP,0EAA0E;IAC1E,OAAO,CAAC,eAAe;IASvB;;;;wEAIoE;IACpE,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,cAAc,GAAG,IAAI;IAIjD,OAAO,CAAC,cAAc;IAMtB,2FAA2F;IACrF,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAsB9B,iFAAiF;YACnE,aAAa;IAiE3B,OAAO,CAAC,iBAAiB;YAcX,YAAY;IAe1B;;;;;OAKG;YACW,aAAa;IAoB3B,0DAA0D;IACpD,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAoBjC;;yEAEqE;IACrE,OAAO,CAAC,oBAAoB;YAYd,QAAQ;IAgGtB,OAAO,CAAC,oBAAoB;IAQ5B,4EAA4E;IAC5E,OAAO,CAAC,kBAAkB;IAc1B;;iBAEa;IACb,OAAO,CAAC,WAAW;IAcnB,OAAO,CAAC,gBAAgB;IAYxB,OAAO,CAAC,WAAW;IA2WnB,OAAO,CAAC,WAAW;IAInB,OAAO,CAAC,UAAU;CAQnB;AAGD,OAAO,EAAE,MAAM,EAAE,CAAC"}