@dbx-tools/shared-mastra 0.6.218 → 0.6.219

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/src/wire.ts CHANGED
@@ -112,189 +112,6 @@ export const ServingEndpointsResponseSchema = z.object({
112
112
  /** Available Databricks serving endpoints returned by the Mastra model route. */
113
113
  export type ServingEndpointsResponse = z.infer<typeof ServingEndpointsResponseSchema>;
114
114
 
115
- /* ----------------------------- chat history ----------------------------- */
116
-
117
- /**
118
- * Structural shape for an AI SDK V5 `UIMessage`. Defined locally
119
- * so the shared types package stays dependency-free (no `ai`
120
- * import). The runtime values returned by the `/route/history` endpoint
121
- * are produced by `toAISdkV5Messages` and are 1:1 compatible with
122
- * `UIMessage` from the `ai` package; clients can safely cast when
123
- * needed.
124
- */
125
- export const MastraHistoryUIMessageSchema = z.object({
126
- id: z.string(),
127
- role: z.enum(["system", "user", "assistant"]),
128
- parts: z.array(z.unknown()).readonly(),
129
- metadata: z.unknown().optional(),
130
- });
131
- /** Persisted chat message normalized into the browser UI message contract. */
132
- export type MastraHistoryUIMessage = z.infer<typeof MastraHistoryUIMessageSchema>;
133
-
134
- /**
135
- * JSON payload returned by `GET ${basePath}/route/history`.
136
- *
137
- * Fields:
138
- * - `uiMessages`: page of UI-formatted messages, oldest -> newest.
139
- * Always chronological regardless of the underlying pagination
140
- * order so the client can prepend the array to the live
141
- * transcript without sorting.
142
- * - `page`: zero-indexed page that produced this response.
143
- * - `perPage`: number of items requested per page.
144
- * - `total`: total number of messages in the thread.
145
- * - `hasMore`: true when at least one older page is still
146
- * available.
147
- */
148
- export const MastraHistoryResponseSchema = z.object({
149
- uiMessages: z.array(MastraHistoryUIMessageSchema),
150
- page: z.number(),
151
- perPage: z.number(),
152
- total: z.number(),
153
- hasMore: z.boolean(),
154
- });
155
- /** One cursor page of normalized messages for a Mastra thread. */
156
- export type MastraHistoryResponse = z.infer<typeof MastraHistoryResponseSchema>;
157
-
158
- /**
159
- * JSON payload returned by `DELETE ${basePath}/route/history`. Deletes
160
- * every persisted message + workflow snapshot tied to the caller's
161
- * thread, so the next chat turn starts from a clean slate. The
162
- * session cookie that anchors the thread id is preserved so the
163
- * caller doesn't lose its identity - only the contents go away.
164
- *
165
- * `ok` is always `true` on success; the response object is kept
166
- * as a struct (vs a bare 204) so future fields (e.g. `deletedAt`,
167
- * `messages`) can be added without bumping the contract.
168
- *
169
- * Fields:
170
- * - `ok`: literal `true` on success.
171
- * - `agentId`: agent whose history was cleared.
172
- * - `threadId`: thread id that was wiped.
173
- * - `cleared`: number of messages the thread held before
174
- * deletion. Useful for client-side "cleared 12 messages"
175
- * toasts; `0` is reported when the thread was already empty
176
- * (call is idempotent).
177
- */
178
- export const MastraClearHistoryResponseSchema = z.object({
179
- ok: z.literal(true),
180
- agentId: z.string(),
181
- threadId: z.string(),
182
- cleared: z.number(),
183
- });
184
- /** Result of clearing the messages owned by one Mastra thread. */
185
- export type MastraClearHistoryResponse = z.infer<typeof MastraClearHistoryResponseSchema>;
186
-
187
- /* -------------------------------- threads -------------------------------- */
188
-
189
- /**
190
- * A single conversation thread the resource (authenticated user) owns,
191
- * as returned by `GET ${basePath}/threads`. Mirrors Mastra's
192
- * `StorageThreadType` but with JSON-safe ISO-8601 timestamps (the wire
193
- * can't carry `Date`).
194
- *
195
- * Fields:
196
- * - `id`: thread id. Pass it back as the thread-selection header
197
- * (`THREAD_ID_HEADER`) on a stream / history / delete call to act
198
- * on this conversation.
199
- * - `title`: human-readable title. Present once the agent's memory
200
- * has auto-generated one (after the first turn); absent on a
201
- * brand-new thread, so the UI falls back to a placeholder.
202
- * - `resourceId`: owning resource (the user id). Always the caller's
203
- * own resource - the list route filters by it server-side.
204
- * - `createdAt` / `updatedAt`: ISO-8601 timestamps. `updatedAt` is
205
- * the natural sort key for "most recent conversations first".
206
- * - `metadata`: opaque thread metadata, passed through untouched.
207
- */
208
- export const MastraThreadSchema = z.object({
209
- id: z.string(),
210
- title: z.string().optional(),
211
- resourceId: z.string(),
212
- createdAt: z.string(),
213
- updatedAt: z.string(),
214
- metadata: z.unknown().optional(),
215
- });
216
- /** User-visible thread metadata, separate from the thread's message history. */
217
- export type MastraThread = z.infer<typeof MastraThreadSchema>;
218
-
219
- /**
220
- * JSON payload returned by `GET ${basePath}/threads`. One page of the
221
- * caller's conversation threads, newest (`updatedAt` DESC) first.
222
- *
223
- * Fields:
224
- * - `threads`: page of threads for the caller's resource.
225
- * - `page`: zero-indexed page that produced this response.
226
- * - `perPage`: number of items requested per page.
227
- * - `total`: total number of threads the resource owns.
228
- * - `hasMore`: true when at least one more page is available.
229
- */
230
- export const MastraThreadsResponseSchema = z.object({
231
- threads: z.array(MastraThreadSchema),
232
- page: z.number(),
233
- perPage: z.number(),
234
- total: z.number(),
235
- hasMore: z.boolean(),
236
- });
237
- /** One cursor page of Mastra threads owned by the active resource. */
238
- export type MastraThreadsResponse = z.infer<typeof MastraThreadsResponseSchema>;
239
-
240
- /**
241
- * JSON payload returned by `DELETE ${basePath}/threads` (thread id
242
- * supplied via the thread-selection header / `threadId` query). Wipes
243
- * the named thread and every message on it.
244
- *
245
- * Fields:
246
- * - `ok`: literal `true` on success.
247
- * - `agentId`: agent whose thread was deleted.
248
- * - `threadId`: thread id that was removed.
249
- * - `deleted`: `true` when a thread row existed and was removed,
250
- * `false` when it was already gone (call is idempotent).
251
- */
252
- export const MastraDeleteThreadResponseSchema = z.object({
253
- ok: z.literal(true),
254
- agentId: z.string(),
255
- threadId: z.string(),
256
- deleted: z.boolean(),
257
- });
258
- /** Result of deleting one thread and its associated memory records. */
259
- export type MastraDeleteThreadResponse = z.infer<typeof MastraDeleteThreadResponseSchema>;
260
-
261
- /** Longest thread title the rename route accepts (trimmed server-side). */
262
- export const MASTRA_THREAD_TITLE_MAX = 200;
263
-
264
- /**
265
- * JSON body for `PATCH ${basePath}/threads` (thread id supplied via the
266
- * thread-selection header / `threadId` query). Renames a single
267
- * conversation.
268
- *
269
- * Fields:
270
- * - `title`: the new human-readable title. Trimmed and capped at
271
- * {@link MASTRA_THREAD_TITLE_MAX} characters server-side; must be
272
- * non-empty after trimming.
273
- */
274
- export const MastraUpdateThreadRequestSchema = z.object({
275
- title: z.string().trim().min(1).max(MASTRA_THREAD_TITLE_MAX),
276
- });
277
- /** Validated mutable fields accepted when renaming a Mastra thread. */
278
- export type MastraUpdateThreadRequest = z.infer<typeof MastraUpdateThreadRequestSchema>;
279
-
280
- /**
281
- * JSON payload returned by `PATCH ${basePath}/threads`. Echoes the
282
- * renamed thread in its post-update wire shape so the client can reflect
283
- * the new title without a re-fetch.
284
- *
285
- * Fields:
286
- * - `ok`: literal `true` on success.
287
- * - `agentId`: agent whose thread was renamed.
288
- * - `thread`: the updated thread (carries the new `title`).
289
- */
290
- export const MastraUpdateThreadResponseSchema = z.object({
291
- ok: z.literal(true),
292
- agentId: z.string(),
293
- thread: MastraThreadSchema,
294
- });
295
- /** Updated thread returned after a successful rename. */
296
- export type MastraUpdateThreadResponse = z.infer<typeof MastraUpdateThreadResponseSchema>;
297
-
298
115
  /* ------------------------------ suggestions ------------------------------ */
299
116
 
300
117
  /**
@@ -470,25 +287,6 @@ export const StatementDataSchema = z.object({
470
287
  /** Tabular statement payload resolved from a `[data:<statement_id>]` embed marker. */
471
288
  export type StatementData = z.infer<typeof StatementDataSchema>;
472
289
 
473
- /* ----------------------------- writer surface ---------------------------- */
474
-
475
- /**
476
- * The `ToolStream`-shaped writer the Mastra Genie agent and chart
477
- * helpers publish events through. Defined here (vs imported from
478
- * `@mastra/core`) so helpers in `@dbx-tools/appkit-mastra` can
479
- * accept any object with a `.write` method without dragging
480
- * Mastra's full `ToolStream` (and its agent / tool typings) into
481
- * call sites. The actual Mastra `ctx.writer` is assignable to
482
- * this shape so callers pass it straight through.
483
- *
484
- * Kept as a plain TypeScript interface (vs a zod schema) because
485
- * the contract is a method - zod can only validate the shape via
486
- * `z.custom`, which adds noise without buying any runtime check.
487
- */
488
- export interface MastraWriter {
489
- write: (chunk: unknown) => unknown;
490
- }
491
-
492
290
  /* ---------------- mastra-only genie-agent events ---------------- */
493
291
 
494
292
  /**
@@ -635,6 +433,20 @@ export type GenieWriterEvent = z.infer<typeof GenieWriterEventSchema>;
635
433
  /** Discriminator type for {@link GenieWriterEvent}. */
636
434
  export type GenieWriterEventType = GenieWriterEvent["type"];
637
435
 
436
+ /** Native AI SDK custom data-part type carrying one Genie progress event. */
437
+ export const GENIE_PROGRESS_PART_TYPE = "data-genie-progress" as const;
438
+
439
+ /**
440
+ * Data attached to {@link GENIE_PROGRESS_PART_TYPE}. `toolCallId` associates
441
+ * progress with the native tool part that owns the request and result.
442
+ */
443
+ export const GenieProgressPartDataSchema = z.object({
444
+ toolCallId: z.string(),
445
+ event: GenieWriterEventSchema,
446
+ });
447
+ /** Validated payload carried by a native Genie progress data part. */
448
+ export type GenieProgressPartData = z.infer<typeof GenieProgressPartDataSchema>;
449
+
638
450
  /* ------------------------- summary + dataset ------------------------ */
639
451
 
640
452
  /**
@@ -1,162 +0,0 @@
1
- /**
2
- * Runtime-validated Mastra agent stream chunks shared by browser clients.
3
- *
4
- * Known event names are strict about the payload fields the UI consumes, so a
5
- * malformed upstream chunk fails before it reaches a state reducer. Unknown
6
- * event names remain forward-compatible through an explicit `unknown` variant
7
- * that preserves the original event name and payload.
8
- *
9
- * @module
10
- */
11
- import { z } from "zod";
12
- /** Known Mastra events consumed by the chat UI. */
13
- export declare const KnownMastraStreamChunkSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
14
- runId: z.ZodOptional<z.ZodString>;
15
- type: z.ZodLiteral<"text-start">;
16
- payload: z.ZodOptional<z.ZodUnknown>;
17
- }, z.core.$loose>, z.ZodObject<{
18
- runId: z.ZodOptional<z.ZodString>;
19
- type: z.ZodLiteral<"text-delta">;
20
- payload: z.ZodObject<{
21
- text: z.ZodString;
22
- }, z.core.$loose>;
23
- }, z.core.$loose>, z.ZodObject<{
24
- runId: z.ZodOptional<z.ZodString>;
25
- type: z.ZodLiteral<"text-end">;
26
- payload: z.ZodOptional<z.ZodUnknown>;
27
- }, z.core.$loose>, z.ZodObject<{
28
- runId: z.ZodOptional<z.ZodString>;
29
- type: z.ZodLiteral<"reasoning-delta">;
30
- payload: z.ZodObject<{
31
- text: z.ZodString;
32
- }, z.core.$loose>;
33
- }, z.core.$loose>, z.ZodObject<{
34
- runId: z.ZodOptional<z.ZodString>;
35
- type: z.ZodLiteral<"tool-call">;
36
- payload: z.ZodObject<{
37
- toolCallId: z.ZodString;
38
- toolName: z.ZodString;
39
- args: z.ZodOptional<z.ZodUnknown>;
40
- }, z.core.$loose>;
41
- }, z.core.$loose>, z.ZodObject<{
42
- runId: z.ZodOptional<z.ZodString>;
43
- type: z.ZodLiteral<"tool-call-approval">;
44
- payload: z.ZodObject<{
45
- toolCallId: z.ZodString;
46
- toolName: z.ZodString;
47
- args: z.ZodOptional<z.ZodUnknown>;
48
- runId: z.ZodOptional<z.ZodString>;
49
- }, z.core.$loose>;
50
- }, z.core.$loose>, z.ZodObject<{
51
- runId: z.ZodOptional<z.ZodString>;
52
- type: z.ZodLiteral<"tool-result">;
53
- payload: z.ZodObject<{
54
- toolCallId: z.ZodString;
55
- }, z.core.$loose>;
56
- }, z.core.$loose>, z.ZodObject<{
57
- runId: z.ZodOptional<z.ZodString>;
58
- type: z.ZodLiteral<"tool-error">;
59
- payload: z.ZodObject<{
60
- toolCallId: z.ZodString;
61
- }, z.core.$loose>;
62
- }, z.core.$loose>, z.ZodObject<{
63
- runId: z.ZodOptional<z.ZodString>;
64
- type: z.ZodLiteral<"tool-output">;
65
- payload: z.ZodObject<{
66
- toolCallId: z.ZodString;
67
- output: z.ZodUnknown;
68
- }, z.core.$loose>;
69
- }, z.core.$loose>, z.ZodObject<{
70
- runId: z.ZodOptional<z.ZodString>;
71
- type: z.ZodLiteral<"error">;
72
- payload: z.ZodOptional<z.ZodObject<{
73
- error: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodRecord<z.ZodString, z.ZodUnknown>]>>;
74
- message: z.ZodOptional<z.ZodString>;
75
- }, z.core.$loose>>;
76
- }, z.core.$loose>], "type">;
77
- /** A validated stream event whose name this client version does not consume. */
78
- export type UnknownMastraStreamChunk = {
79
- type: "unknown";
80
- eventType: string;
81
- payload?: unknown;
82
- runId?: string;
83
- };
84
- /**
85
- * Complete validated stream union. Known events retain their discriminant;
86
- * future event names normalize to the explicit `unknown` variant.
87
- */
88
- export declare const MastraStreamChunkSchema: z.ZodUnion<readonly [z.ZodDiscriminatedUnion<[z.ZodObject<{
89
- runId: z.ZodOptional<z.ZodString>;
90
- type: z.ZodLiteral<"text-start">;
91
- payload: z.ZodOptional<z.ZodUnknown>;
92
- }, z.core.$loose>, z.ZodObject<{
93
- runId: z.ZodOptional<z.ZodString>;
94
- type: z.ZodLiteral<"text-delta">;
95
- payload: z.ZodObject<{
96
- text: z.ZodString;
97
- }, z.core.$loose>;
98
- }, z.core.$loose>, z.ZodObject<{
99
- runId: z.ZodOptional<z.ZodString>;
100
- type: z.ZodLiteral<"text-end">;
101
- payload: z.ZodOptional<z.ZodUnknown>;
102
- }, z.core.$loose>, z.ZodObject<{
103
- runId: z.ZodOptional<z.ZodString>;
104
- type: z.ZodLiteral<"reasoning-delta">;
105
- payload: z.ZodObject<{
106
- text: z.ZodString;
107
- }, z.core.$loose>;
108
- }, z.core.$loose>, z.ZodObject<{
109
- runId: z.ZodOptional<z.ZodString>;
110
- type: z.ZodLiteral<"tool-call">;
111
- payload: z.ZodObject<{
112
- toolCallId: z.ZodString;
113
- toolName: z.ZodString;
114
- args: z.ZodOptional<z.ZodUnknown>;
115
- }, z.core.$loose>;
116
- }, z.core.$loose>, z.ZodObject<{
117
- runId: z.ZodOptional<z.ZodString>;
118
- type: z.ZodLiteral<"tool-call-approval">;
119
- payload: z.ZodObject<{
120
- toolCallId: z.ZodString;
121
- toolName: z.ZodString;
122
- args: z.ZodOptional<z.ZodUnknown>;
123
- runId: z.ZodOptional<z.ZodString>;
124
- }, z.core.$loose>;
125
- }, z.core.$loose>, z.ZodObject<{
126
- runId: z.ZodOptional<z.ZodString>;
127
- type: z.ZodLiteral<"tool-result">;
128
- payload: z.ZodObject<{
129
- toolCallId: z.ZodString;
130
- }, z.core.$loose>;
131
- }, z.core.$loose>, z.ZodObject<{
132
- runId: z.ZodOptional<z.ZodString>;
133
- type: z.ZodLiteral<"tool-error">;
134
- payload: z.ZodObject<{
135
- toolCallId: z.ZodString;
136
- }, z.core.$loose>;
137
- }, z.core.$loose>, z.ZodObject<{
138
- runId: z.ZodOptional<z.ZodString>;
139
- type: z.ZodLiteral<"tool-output">;
140
- payload: z.ZodObject<{
141
- toolCallId: z.ZodString;
142
- output: z.ZodUnknown;
143
- }, z.core.$loose>;
144
- }, z.core.$loose>, z.ZodObject<{
145
- runId: z.ZodOptional<z.ZodString>;
146
- type: z.ZodLiteral<"error">;
147
- payload: z.ZodOptional<z.ZodObject<{
148
- error: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodRecord<z.ZodString, z.ZodUnknown>]>>;
149
- message: z.ZodOptional<z.ZodString>;
150
- }, z.core.$loose>>;
151
- }, z.core.$loose>], "type">, z.ZodPipe<z.ZodObject<{
152
- runId: z.ZodOptional<z.ZodString>;
153
- type: z.ZodString;
154
- payload: z.ZodOptional<z.ZodUnknown>;
155
- }, z.core.$loose>, z.ZodTransform<UnknownMastraStreamChunk, {
156
- [x: string]: unknown;
157
- type: string;
158
- runId?: string | undefined;
159
- payload?: unknown;
160
- }>>]>;
161
- /** One runtime-validated event from a Mastra agent SSE stream. */
162
- export type MastraStreamChunk = z.output<typeof MastraStreamChunkSchema>;
package/lib/src/stream.js DELETED
@@ -1,135 +0,0 @@
1
- /**
2
- * Runtime-validated Mastra agent stream chunks shared by browser clients.
3
- *
4
- * Known event names are strict about the payload fields the UI consumes, so a
5
- * malformed upstream chunk fails before it reaches a state reducer. Unknown
6
- * event names remain forward-compatible through an explicit `unknown` variant
7
- * that preserves the original event name and payload.
8
- *
9
- * @module
10
- */
11
- import { z } from "zod";
12
- const runFields = {
13
- runId: z.string().min(1).optional(),
14
- };
15
- const EmptyStreamChunkSchema = (type) => z
16
- .object({
17
- type: z.literal(type),
18
- payload: z.unknown().optional(),
19
- ...runFields,
20
- })
21
- .passthrough();
22
- const TextDeltaStreamChunkSchema = z
23
- .object({
24
- type: z.literal("text-delta"),
25
- payload: z.object({ text: z.string() }).passthrough(),
26
- ...runFields,
27
- })
28
- .passthrough();
29
- const ReasoningDeltaStreamChunkSchema = z
30
- .object({
31
- type: z.literal("reasoning-delta"),
32
- payload: z.object({ text: z.string() }).passthrough(),
33
- ...runFields,
34
- })
35
- .passthrough();
36
- const ToolCallStreamChunkSchema = z
37
- .object({
38
- type: z.literal("tool-call"),
39
- payload: z
40
- .object({
41
- toolCallId: z.string().min(1),
42
- toolName: z.string().min(1),
43
- args: z.unknown().optional(),
44
- })
45
- .passthrough(),
46
- ...runFields,
47
- })
48
- .passthrough();
49
- const ToolCallApprovalStreamChunkSchema = z
50
- .object({
51
- type: z.literal("tool-call-approval"),
52
- payload: z
53
- .object({
54
- toolCallId: z.string().min(1),
55
- toolName: z.string().min(1),
56
- args: z.unknown().optional(),
57
- runId: z.string().min(1).optional(),
58
- })
59
- .passthrough(),
60
- ...runFields,
61
- })
62
- .passthrough();
63
- const ToolTerminalStreamChunkSchema = (type) => z
64
- .object({
65
- type: z.literal(type),
66
- payload: z.object({ toolCallId: z.string().min(1) }).passthrough(),
67
- ...runFields,
68
- })
69
- .passthrough();
70
- const ToolOutputStreamChunkSchema = z
71
- .object({
72
- type: z.literal("tool-output"),
73
- payload: z
74
- .object({
75
- toolCallId: z.string().min(1),
76
- output: z.unknown(),
77
- })
78
- .passthrough(),
79
- ...runFields,
80
- })
81
- .passthrough();
82
- const StreamErrorDetailSchema = z.union([z.string(), z.record(z.string(), z.unknown())]);
83
- const ErrorStreamChunkSchema = z
84
- .object({
85
- type: z.literal("error"),
86
- payload: z
87
- .object({
88
- error: StreamErrorDetailSchema.optional(),
89
- message: z.string().optional(),
90
- })
91
- .passthrough()
92
- .optional(),
93
- ...runFields,
94
- })
95
- .passthrough();
96
- /** Known Mastra events consumed by the chat UI. */
97
- export const KnownMastraStreamChunkSchema = z.discriminatedUnion("type", [
98
- EmptyStreamChunkSchema("text-start"),
99
- TextDeltaStreamChunkSchema,
100
- EmptyStreamChunkSchema("text-end"),
101
- ReasoningDeltaStreamChunkSchema,
102
- ToolCallStreamChunkSchema,
103
- ToolCallApprovalStreamChunkSchema,
104
- ToolTerminalStreamChunkSchema("tool-result"),
105
- ToolTerminalStreamChunkSchema("tool-error"),
106
- ToolOutputStreamChunkSchema,
107
- ErrorStreamChunkSchema,
108
- ]);
109
- const knownEventTypes = new Set(KnownMastraStreamChunkSchema.options.map((option) => option.shape.type.value));
110
- const UnknownMastraStreamChunkSchema = z
111
- .object({
112
- type: z.string().min(1),
113
- payload: z.unknown().optional(),
114
- ...runFields,
115
- })
116
- .passthrough()
117
- .refine((chunk) => !knownEventTypes.has(chunk.type), {
118
- path: ["type"],
119
- message: "known stream event has an invalid payload",
120
- })
121
- .transform((chunk) => ({
122
- type: "unknown",
123
- eventType: chunk.type,
124
- ...(chunk.payload !== undefined ? { payload: chunk.payload } : {}),
125
- ...(chunk.runId !== undefined ? { runId: chunk.runId } : {}),
126
- }));
127
- /**
128
- * Complete validated stream union. Known events retain their discriminant;
129
- * future event names normalize to the explicit `unknown` variant.
130
- */
131
- export const MastraStreamChunkSchema = z.union([
132
- KnownMastraStreamChunkSchema,
133
- UnknownMastraStreamChunkSchema,
134
- ]);
135
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RyZWFtLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3N0cmVhbS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7O0dBU0c7QUFFSCxPQUFPLEVBQUUsQ0FBQyxFQUFFLE1BQU0sS0FBSyxDQUFDO0FBRXhCLE1BQU0sU0FBUyxHQUFHO0lBQ2hCLEtBQUssRUFBRSxDQUFDLENBQUMsTUFBTSxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLFFBQVEsRUFBRTtDQUNwQyxDQUFDO0FBRUYsTUFBTSxzQkFBc0IsR0FBRyxDQUFzQixJQUFVLEVBQUUsRUFBRSxDQUNqRSxDQUFDO0tBQ0UsTUFBTSxDQUFDO0lBQ04sSUFBSSxFQUFFLENBQUMsQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDO0lBQ3JCLE9BQU8sRUFBRSxDQUFDLENBQUMsT0FBTyxFQUFFLENBQUMsUUFBUSxFQUFFO0lBQy9CLEdBQUcsU0FBUztDQUNiLENBQUM7S0FDRCxXQUFXLEVBQUUsQ0FBQztBQUVuQixNQUFNLDBCQUEwQixHQUFHLENBQUM7S0FDakMsTUFBTSxDQUFDO0lBQ04sSUFBSSxFQUFFLENBQUMsQ0FBQyxPQUFPLENBQUMsWUFBWSxDQUFDO0lBQzdCLE9BQU8sRUFBRSxDQUFDLENBQUMsTUFBTSxDQUFDLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQyxNQUFNLEVBQUUsRUFBRSxDQUFDLENBQUMsV0FBVyxFQUFFO0lBQ3JELEdBQUcsU0FBUztDQUNiLENBQUM7S0FDRCxXQUFXLEVBQUUsQ0FBQztBQUVqQixNQUFNLCtCQUErQixHQUFHLENBQUM7S0FDdEMsTUFBTSxDQUFDO0lBQ04sSUFBSSxFQUFFLENBQUMsQ0FBQyxPQUFPLENBQUMsaUJBQWlCLENBQUM7SUFDbEMsT0FBTyxFQUFFLENBQUMsQ0FBQyxNQUFNLENBQUMsRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDLE1BQU0sRUFBRSxFQUFFLENBQUMsQ0FBQyxXQUFXLEVBQUU7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NEIsRUFBRSxDQUFDLENBQUM7SUFDL0MsSUFBSSxFQUFFLFNBQVM7SUFDZixTQUFTLEVBQUUsS0FBSyxDQUFDLElBQUk7SUFDckIsR0FBRyxDQUFDLEtBQUssQ0FBQyxPQUFPLEtBQUssU0FBUyxDQUFDLENBQUMsQ0FBQyxFQUFFLE9BQU8sRUFBRSxLQUFLLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQztJQUNsRSxHQUFHLENBQUMsS0FBSyxDQUFDLEtBQUssS0FBSyxTQUFTLENBQUMsQ0FBQyxDQUFDLEVBQUUsS0FBSyxFQUFFLEtBQUssQ0FBQyxLQUFLLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDO0NBQzdELENBQUMsQ0FBQyxDQUFDO0FBRU47OztHQUdHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sdUJBQXVCLEdBQUcsQ0FBQyxDQUFDLEtBQUssQ0FBQztJQUM3Qyw0QkFBNEI7SUFDNUIsOEJBQThCO0NBQy9CLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogUnVudGltZS12YWxpZGF0ZWQgTWFzdHJhIGFnZW50IHN0cmVhbSBjaHVua3Mgc2hhcmVkIGJ5IGJyb3dzZXIgY2xpZW50cy5cbiAqXG4gKiBLbm93biBldmVudCBuYW1lcyBhcmUgc3RyaWN0IGFib3V0IHRoZSBwYXlsb2FkIGZpZWxkcyB0aGUgVUkgY29uc3VtZXMsIHNvIGFcbiAqIG1hbGZvcm1lZCB1cHN0cmVhbSBjaHVuayBmYWlscyBiZWZvcmUgaXQgcmVhY2hlcyBhIHN0YXRlIHJlZHVjZXIuIFVua25vd25cbiAqIGV2ZW50IG5hbWVzIHJlbWFpbiBmb3J3YXJkLWNvbXBhdGlibGUgdGhyb3VnaCBhbiBleHBsaWNpdCBgdW5rbm93bmAgdmFyaWFudFxuICogdGhhdCBwcmVzZXJ2ZXMgdGhlIG9yaWdpbmFsIGV2ZW50IG5hbWUgYW5kIHBheWxvYWQuXG4gKlxuICogQG1vZHVsZVxuICovXG5cbmltcG9ydCB7IHogfSBmcm9tIFwiem9kXCI7XG5cbmNvbnN0IHJ1bkZpZWxkcyA9IHtcbiAgcnVuSWQ6IHouc3RyaW5nKCkubWluKDEpLm9wdGlvbmFsKCksXG59O1xuXG5jb25zdCBFbXB0eVN0cmVhbUNodW5rU2NoZW1hID0gPFR5cGUgZXh0ZW5kcyBzdHJpbmc+KHR5cGU6IFR5cGUpID0+XG4gIHpcbiAgICAub2JqZWN0KHtcbiAgICAgIHR5cGU6IHoubGl0ZXJhbCh0eXBlKSxcbiAgICAgIHBheWxvYWQ6IHoudW5rbm93bigpLm9wdGlvbmFsKCksXG4gICAgICAuLi5ydW5GaWVsZHMsXG4gICAgfSlcbiAgICAucGFzc3Rocm91Z2goKTtcblxuY29uc3QgVGV4dERlbHRhU3RyZWFtQ2h1bmtTY2hlbWEgPSB6XG4gIC5vYmplY3Qoe1xuICAgIHR5cGU6IHoubGl0ZXJhbChcInRleHQtZGVsdGFcIiksXG4gICAgcGF5bG9hZDogei5vYmplY3QoeyB0ZXh0OiB6LnN0cmluZygpIH0pLnBhc3N0aHJvdWdoKCksXG4gICAgLi4ucnVuRmllbGRzLFxuICB9KVxuICAucGFzc3Rocm91Z2goKTtcblxuY29uc3QgUmVhc29uaW5nRGVsdGFTdHJlYW1DaHVua1NjaGVtYSA9IHpcbiAgLm9iamVjdCh7XG4gICAgdHlwZTogei5saXRlcmFsKFwicmVhc29uaW5nLWRlbHRhXCIpLFxuICAgIHBheWxvYWQ6IHoub2JqZWN0KHsgdGV4dDogei5zdHJpbmcoKSB9KS5wYXNzdGhyb3VnaCgpLFxuICAgIC4uLnJ1bkZpZWxkcyxcbiAgfSlcbiAgLnBhc3N0aHJvdWdoKCk7XG5cbmNvbnN0IFRvb2xDYWxsU3RyZWFtQ2h1bmtTY2hlbWEgPSB6XG4gIC5vYmplY3Qoe1xuICAgIHR5cGU6IHoubGl0ZXJhbChcInRvb2wtY2FsbFwiKSxcbiAgICBwYXlsb2FkOiB6XG4gICAgICAub2JqZWN0KHtcbiAgICAgICAgdG9vbENhbGxJZDogei5zdHJpbmcoKS5taW4oMSksXG4gICAgICAgIHRvb2xOYW1lOiB6LnN0cmluZygpLm1pbigxKSxcbiAgICAgICAgYXJnczogei51bmtub3duKCkub3B0aW9uYWwoKSxcbiAgICAgIH0pXG4gICAgICAucGFzc3Rocm91Z2goKSxcbiAgICAuLi5ydW5GaWVsZHMsXG4gIH0pXG4gIC5wYXNzdGhyb3VnaCgpO1xuXG5jb25zdCBUb29sQ2FsbEFwcHJvdmFsU3RyZWFtQ2h1bmtTY2hlbWEgPSB6XG4gIC5vYmplY3Qoe1xuICAgIHR5cGU6IHoubGl0ZXJhbChcInRvb2wtY2FsbC1hcHByb3ZhbFwiKSxcbiAgICBwYXlsb2FkOiB6XG4gICAgICAub2JqZWN0KHtcbiAgICAgICAgdG9vbENhbGxJZDogei5zdHJpbmcoKS5taW4oMSksXG4gICAgICAgIHRvb2xOYW1lOiB6LnN0cmluZygpLm1pbigxKSxcbiAgICAgICAgYXJnczogei51bmtub3duKCkub3B0aW9uYWwoKSxcbiAgICAgICAgcnVuSWQ6IHouc3RyaW5nKCkubWluKDEpLm9wdGlvbmFsKCksXG4gICAgICB9KVxuICAgICAgLnBhc3N0aHJvdWdoKCksXG4gICAgLi4ucnVuRmllbGRzLFxuICB9KVxuICAucGFzc3Rocm91Z2goKTtcblxuY29uc3QgVG9vbFRlcm1pbmFsU3RyZWFtQ2h1bmtTY2hlbWEgPSA8VHlwZSBleHRlbmRzIFwidG9vbC1yZXN1bHRcIiB8IFwidG9vbC1lcnJvclwiPih0eXBlOiBUeXBlKSA9PlxuICB6XG4gICAgLm9iamVjdCh7XG4gICAgICB0eXBlOiB6LmxpdGVyYWwodHlwZSksXG4gICAgICBwYXlsb2FkOiB6Lm9iamVjdCh7IHRvb2xDYWxsSWQ6IHouc3RyaW5nKCkubWluKDEpIH0pLnBhc3N0aHJvdWdoKCksXG4gICAgICAuLi5ydW5GaWVsZHMsXG4gICAgfSlcbiAgICAucGFzc3Rocm91Z2goKTtcblxuY29uc3QgVG9vbE91dHB1dFN0cmVhbUNodW5rU2NoZW1hID0gelxuICAub2JqZWN0KHtcbiAgICB0eXBlOiB6LmxpdGVyYWwoXCJ0b29sLW91dHB1dFwiKSxcbiAgICBwYXlsb2FkOiB6XG4gICAgICAub2JqZWN0KHtcbiAgICAgICAgdG9vbENhbGxJZDogei5zdHJpbmcoKS5taW4oMSksXG4gICAgICAgIG91dHB1dDogei51bmtub3duKCksXG4gICAgICB9KVxuICAgICAgLnBhc3N0aHJvdWdoKCksXG4gICAgLi4ucnVuRmllbGRzLFxuICB9KVxuICAucGFzc3Rocm91Z2goKTtcblxuY29uc3QgU3RyZWFtRXJyb3JEZXRhaWxTY2hlbWEgPSB6LnVuaW9uKFt6LnN0cmluZygpLCB6LnJlY29yZCh6LnN0cmluZygpLCB6LnVua25vd24oKSldKTtcblxuY29uc3QgRXJyb3JTdHJlYW1DaHVua1NjaGVtYSA9IHpcbiAgLm9iamVjdCh7XG4gICAgdHlwZTogei5saXRlcmFsKFwiZXJyb3JcIiksXG4gICAgcGF5bG9hZDogelxuICAgICAgLm9iamVjdCh7XG4gICAgICAgIGVycm9yOiBTdHJlYW1FcnJvckRldGFpbFNjaGVtYS5vcHRpb25hbCgpLFxuICAgICAgICBtZXNzYWdlOiB6LnN0cmluZygpLm9wdGlvbmFsKCksXG4gICAgICB9KVxuICAgICAgLnBhc3N0aHJvdWdoKClcbiAgICAgIC5vcHRpb25hbCgpLFxuICAgIC4uLnJ1bkZpZWxkcyxcbiAgfSlcbiAgLnBhc3N0aHJvdWdoKCk7XG5cbi8qKiBLbm93biBNYXN0cmEgZXZlbnRzIGNvbnN1bWVkIGJ5IHRoZSBjaGF0IFVJLiAqL1xuZXhwb3J0IGNvbnN0IEtub3duTWFzdHJhU3RyZWFtQ2h1bmtTY2hlbWEgPSB6LmRpc2NyaW1pbmF0ZWRVbmlvbihcInR5cGVcIiwgW1xuICBFbXB0eVN0cmVhbUNodW5rU2NoZW1hKFwidGV4dC1zdGFydFwiKSxcbiAgVGV4dERlbHRhU3RyZWFtQ2h1bmtTY2hlbWEsXG4gIEVtcHR5U3RyZWFtQ2h1bmtTY2hlbWEoXCJ0ZXh0LWVuZFwiKSxcbiAgUmVhc29uaW5nRGVsdGFTdHJlYW1DaHVua1NjaGVtYSxcbiAgVG9vbENhbGxTdHJlYW1DaHVua1NjaGVtYSxcbiAgVG9vbENhbGxBcHByb3ZhbFN0cmVhbUNodW5rU2NoZW1hLFxuICBUb29sVGVybWluYWxTdHJlYW1DaHVua1NjaGVtYShcInRvb2wtcmVzdWx0XCIpLFxuICBUb29sVGVybWluYWxTdHJlYW1DaHVua1NjaGVtYShcInRvb2wtZXJyb3JcIiksXG4gIFRvb2xPdXRwdXRTdHJlYW1DaHVua1NjaGVtYSxcbiAgRXJyb3JTdHJlYW1DaHVua1NjaGVtYSxcbl0pO1xuXG4vKiogQSB2YWxpZGF0ZWQgc3RyZWFtIGV2ZW50IHdob3NlIG5hbWUgdGhpcyBjbGllbnQgdmVyc2lvbiBkb2VzIG5vdCBjb25zdW1lLiAqL1xuZXhwb3J0IHR5cGUgVW5rbm93bk1hc3RyYVN0cmVhbUNodW5rID0ge1xuICB0eXBlOiBcInVua25vd25cIjtcbiAgZXZlbnRUeXBlOiBzdHJpbmc7XG4gIHBheWxvYWQ/OiB1bmtub3duO1xuICBydW5JZD86IHN0cmluZztcbn07XG5cbmNvbnN0IGtub3duRXZlbnRUeXBlczogUmVhZG9ubHlTZXQ8c3RyaW5nPiA9IG5ldyBTZXQoXG4gIEtub3duTWFzdHJhU3RyZWFtQ2h1bmtTY2hlbWEub3B0aW9ucy5tYXAoKG9wdGlvbikgPT4gb3B0aW9uLnNoYXBlLnR5cGUudmFsdWUpLFxuKTtcblxuY29uc3QgVW5rbm93bk1hc3RyYVN0cmVhbUNodW5rU2NoZW1hID0gelxuICAub2JqZWN0KHtcbiAgICB0eXBlOiB6LnN0cmluZygpLm1pbigxKSxcbiAgICBwYXlsb2FkOiB6LnVua25vd24oKS5vcHRpb25hbCgpLFxuICAgIC4uLnJ1bkZpZWxkcyxcbiAgfSlcbiAgLnBhc3N0aHJvdWdoKClcbiAgLnJlZmluZSgoY2h1bmspID0+ICFrbm93bkV2ZW50VHlwZXMuaGFzKGNodW5rLnR5cGUpLCB7XG4gICAgcGF0aDogW1widHlwZVwiXSxcbiAgICBtZXNzYWdlOiBcImtub3duIHN0cmVhbSBldmVudCBoYXMgYW4gaW52YWxpZCBwYXlsb2FkXCIsXG4gIH0pXG4gIC50cmFuc2Zvcm0oKGNodW5rKTogVW5rbm93bk1hc3RyYVN0cmVhbUNodW5rID0+ICh7XG4gICAgdHlwZTogXCJ1bmtub3duXCIsXG4gICAgZXZlbnRUeXBlOiBjaHVuay50eXBlLFxuICAgIC4uLihjaHVuay5wYXlsb2FkICE9PSB1bmRlZmluZWQgPyB7IHBheWxvYWQ6IGNodW5rLnBheWxvYWQgfSA6IHt9KSxcbiAgICAuLi4oY2h1bmsucnVuSWQgIT09IHVuZGVmaW5lZCA/IHsgcnVuSWQ6IGNodW5rLnJ1bklkIH0gOiB7fSksXG4gIH0pKTtcblxuLyoqXG4gKiBDb21wbGV0ZSB2YWxpZGF0ZWQgc3RyZWFtIHVuaW9uLiBLbm93biBldmVudHMgcmV0YWluIHRoZWlyIGRpc2NyaW1pbmFudDtcbiAqIGZ1dHVyZSBldmVudCBuYW1lcyBub3JtYWxpemUgdG8gdGhlIGV4cGxpY2l0IGB1bmtub3duYCB2YXJpYW50LlxuICovXG5leHBvcnQgY29uc3QgTWFzdHJhU3RyZWFtQ2h1bmtTY2hlbWEgPSB6LnVuaW9uKFtcbiAgS25vd25NYXN0cmFTdHJlYW1DaHVua1NjaGVtYSxcbiAgVW5rbm93bk1hc3RyYVN0cmVhbUNodW5rU2NoZW1hLFxuXSk7XG5cbi8qKiBPbmUgcnVudGltZS12YWxpZGF0ZWQgZXZlbnQgZnJvbSBhIE1hc3RyYSBhZ2VudCBTU0Ugc3RyZWFtLiAqL1xuZXhwb3J0IHR5cGUgTWFzdHJhU3RyZWFtQ2h1bmsgPSB6Lm91dHB1dDx0eXBlb2YgTWFzdHJhU3RyZWFtQ2h1bmtTY2hlbWE+O1xuIl19