@dbx-tools/appkit-mastra 0.6.216 → 0.6.217

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.
@@ -0,0 +1,418 @@
1
+ /**
2
+ * Databricks Sandbox adapter for Mastra workspaces.
3
+ *
4
+ * Implements Mastra's foreground command surface over the Databricks Sandbox
5
+ * REST API. Sandboxes are created lazily, retain their home directory across
6
+ * inactivity stops, and execute untrusted shell commands outside the App
7
+ * container.
8
+ *
9
+ * @module
10
+ */
11
+ import { databricks } from "@dbx-tools/appkit";
12
+ import { async, error, log, string } from "@dbx-tools/shared-core";
13
+ import { z } from "zod";
14
+ import { MontySandbox } from "./monty-sandbox.js";
15
+ const SANDBOX_API_PATH = "/api/2.0/sandboxes";
16
+ const SANDBOX_EXEC_API_PATH = "/api/2.0/sandbox-exec/sandboxes";
17
+ const DEFAULT_INACTIVITY_TIMEOUT = "900s";
18
+ const DEFAULT_STARTUP_TIMEOUT_MS = 120_000;
19
+ const DEFAULT_COMMAND_TIMEOUT_MS = 30_000;
20
+ const SANDBOX_POLL_INTERVAL_MS = 500;
21
+ const logger = log.logger("mastra/sandbox");
22
+ const SandboxStateSchema = z.object({
23
+ state: z.string().optional(),
24
+ });
25
+ const SandboxResponseSchema = z.object({
26
+ name: z.string(),
27
+ display_name: z.string().optional(),
28
+ create_time: z.string().optional(),
29
+ update_time: z.string().optional(),
30
+ status: SandboxStateSchema.optional(),
31
+ });
32
+ const ExecuteResponseSchema = z.object({
33
+ exit_code: z.number().int().optional(),
34
+ status: z.string(),
35
+ stdout: z.string().optional(),
36
+ stderr: z.string().optional(),
37
+ command_id: z.string().optional(),
38
+ truncated: z.boolean().optional(),
39
+ });
40
+ /** Mastra sandbox backed by Databricks serverless Sandbox compute. */
41
+ export class DatabricksSandbox {
42
+ id;
43
+ name;
44
+ status = "pending";
45
+ error;
46
+ client;
47
+ displayName;
48
+ inactivityTimeout;
49
+ startupTimeoutMs;
50
+ commandTimeoutMs;
51
+ fallbackConfig;
52
+ createdAt = new Date();
53
+ remoteCreatedAt;
54
+ lastUsedAt;
55
+ activeFallback;
56
+ startPromise;
57
+ constructor(options) {
58
+ const id = string.trimToNull(options.sandboxId.replace(/^sandboxes\//, ""));
59
+ if (!id)
60
+ throw new TypeError("Databricks sandbox id must not be blank");
61
+ this.id = id;
62
+ this.name = options.displayName?.trim() || `Mastra sandbox ${id}`;
63
+ this.client = options.client;
64
+ this.displayName = this.name;
65
+ this.inactivityTimeout = options.inactivityTimeout ?? DEFAULT_INACTIVITY_TIMEOUT;
66
+ this.startupTimeoutMs = options.startupTimeoutMs ?? DEFAULT_STARTUP_TIMEOUT_MS;
67
+ this.commandTimeoutMs = options.commandTimeoutMs ?? DEFAULT_COMMAND_TIMEOUT_MS;
68
+ this.fallbackConfig = options.fallback ?? "monty";
69
+ }
70
+ get provider() {
71
+ return this.activeFallback?.provider ?? "databricks";
72
+ }
73
+ /** Ensure the remote sandbox exists and has reached its running state. */
74
+ async start() {
75
+ await this.startWithSignal();
76
+ }
77
+ async startWithSignal(signal) {
78
+ if (this.status === "running")
79
+ return;
80
+ if (this.startPromise) {
81
+ await this.startPromise;
82
+ return;
83
+ }
84
+ const pending = this.performStart(signal);
85
+ this.startPromise = pending;
86
+ try {
87
+ await pending;
88
+ }
89
+ finally {
90
+ if (this.startPromise === pending)
91
+ this.startPromise = undefined;
92
+ }
93
+ }
94
+ async performStart(signal) {
95
+ if (this.activeFallback) {
96
+ await this.activeFallback.start?.();
97
+ this.status = this.activeFallback.status;
98
+ return;
99
+ }
100
+ this.status = "starting";
101
+ this.error = undefined;
102
+ try {
103
+ let sandbox = await this.getOrCreate(signal);
104
+ if (sandbox.status?.state === "SANDBOX_STATE_STOPPED") {
105
+ sandbox = await this.mutate("start", signal);
106
+ }
107
+ if (sandbox.status?.state === "SANDBOX_STATE_STOPPING") {
108
+ await this.waitForState("SANDBOX_STATE_STOPPED", signal);
109
+ sandbox = await this.mutate("start", signal);
110
+ }
111
+ if (sandbox.status?.state !== "SANDBOX_STATE_RUNNING") {
112
+ await this.waitForState("SANDBOX_STATE_RUNNING", signal);
113
+ }
114
+ this.status = "running";
115
+ this.lastUsedAt = new Date();
116
+ }
117
+ catch (caught) {
118
+ if (this.fallbackConfig !== false && isDatabricksSandboxUnavailable(caught)) {
119
+ const fallback = resolveFallback(this.fallbackConfig);
120
+ logger.warn("Databricks Sandbox unavailable; using fallback", {
121
+ sandboxId: this.id,
122
+ fallback: fallback.provider,
123
+ error: error.errorMessage(caught),
124
+ });
125
+ await fallback.start?.();
126
+ this.activeFallback = fallback;
127
+ this.status = fallback.status;
128
+ this.error = fallback.error;
129
+ return;
130
+ }
131
+ this.status = "error";
132
+ this.error = error.errorMessage(caught);
133
+ throw caught;
134
+ }
135
+ }
136
+ /** Databricks home persistence is not a cloneable Mastra checkpoint. */
137
+ async snapshot() {
138
+ await this.activeFallback?.snapshot();
139
+ }
140
+ get supportsCheckpoints() {
141
+ return this.activeFallback?.supportsCheckpoints ?? false;
142
+ }
143
+ /** Stop compute while preserving the sandbox home directory. */
144
+ async stop() {
145
+ if (this.activeFallback) {
146
+ await this.activeFallback.stop?.();
147
+ this.status = this.activeFallback.status;
148
+ return;
149
+ }
150
+ if (this.status === "stopped" || this.status === "destroyed")
151
+ return;
152
+ this.status = "stopping";
153
+ try {
154
+ await this.mutate("stop");
155
+ this.status = "stopped";
156
+ }
157
+ catch (caught) {
158
+ if (isStatus(caught, 404)) {
159
+ this.status = "stopped";
160
+ return;
161
+ }
162
+ this.status = "error";
163
+ this.error = error.errorMessage(caught);
164
+ throw caught;
165
+ }
166
+ }
167
+ /** Permanently delete the sandbox and its persisted home directory. */
168
+ async destroy() {
169
+ if (this.activeFallback) {
170
+ await this.activeFallback.destroy?.();
171
+ this.status = this.activeFallback.status;
172
+ return;
173
+ }
174
+ if (this.status === "destroyed")
175
+ return;
176
+ this.status = "destroying";
177
+ try {
178
+ await this.request(`${this.resourcePath}`, "DELETE", z.object({}).passthrough());
179
+ this.status = "destroyed";
180
+ }
181
+ catch (caught) {
182
+ if (isStatus(caught, 404)) {
183
+ this.status = "destroyed";
184
+ return;
185
+ }
186
+ this.status = "error";
187
+ this.error = error.errorMessage(caught);
188
+ throw caught;
189
+ }
190
+ }
191
+ /** Execute one foreground shell command in the remote sandbox. */
192
+ async executeCommand(command, args = [], options = {}) {
193
+ await this.startWithSignal(options.abortSignal);
194
+ if (this.activeFallback) {
195
+ if (!this.activeFallback.executeCommand) {
196
+ return {
197
+ command,
198
+ args,
199
+ success: false,
200
+ exitCode: 1,
201
+ stdout: "",
202
+ stderr: `Fallback sandbox ${this.activeFallback.provider} does not support command execution.`,
203
+ executionTimeMs: 0,
204
+ };
205
+ }
206
+ return this.activeFallback.executeCommand(command, args, options);
207
+ }
208
+ const timeout = options.timeout ?? this.commandTimeoutMs;
209
+ const script = commandScript(command, args, options.cwd);
210
+ const started = performance.now();
211
+ const response = await this.request(`${SANDBOX_EXEC_API_PATH}/${encodeURIComponent(this.id)}/exec-sync`, "POST", ExecuteResponseSchema, {
212
+ payload: {
213
+ cmd: "/bin/bash",
214
+ args: ["-lc", script],
215
+ envs: definedEnvironment(options.env),
216
+ execution_timeout: `${Math.max(1, Math.ceil(timeout / 1_000))}s`,
217
+ },
218
+ signal: options.abortSignal,
219
+ });
220
+ const stdout = response.stdout ?? "";
221
+ const stderr = response.stderr ?? "";
222
+ options.onStdout?.(stdout);
223
+ options.onStderr?.(stderr);
224
+ this.lastUsedAt = new Date();
225
+ const timedOut = response.status === "EXECUTE_COMMAND_STATUS_TIMED_OUT";
226
+ const exitCode = response.exit_code ?? -1;
227
+ return {
228
+ command,
229
+ args,
230
+ success: response.status === "EXECUTE_COMMAND_STATUS_COMPLETED" && exitCode === 0,
231
+ exitCode,
232
+ stdout,
233
+ stderr,
234
+ executionTimeMs: performance.now() - started,
235
+ ...(timedOut ? { timedOut: true, killed: true } : {}),
236
+ ...(response.truncated
237
+ ? {
238
+ stdoutTruncated: true,
239
+ stderrTruncated: true,
240
+ }
241
+ : {}),
242
+ };
243
+ }
244
+ /** Whether the adapter currently knows the remote sandbox to be running. */
245
+ async isReady() {
246
+ if (this.activeFallback) {
247
+ return this.activeFallback.isReady?.() ?? this.activeFallback.status === "running";
248
+ }
249
+ if (this.status === "running")
250
+ return true;
251
+ try {
252
+ const sandbox = await this.get();
253
+ this.status =
254
+ sandbox.status?.state === "SANDBOX_STATE_RUNNING" ? "running" : remoteStatus(sandbox);
255
+ return this.status === "running";
256
+ }
257
+ catch (caught) {
258
+ if (isStatus(caught, 404))
259
+ return false;
260
+ throw caught;
261
+ }
262
+ }
263
+ /** Report Mastra-facing sandbox metadata. */
264
+ async getInfo() {
265
+ if (this.activeFallback) {
266
+ return ((await this.activeFallback.getInfo?.()) ?? {
267
+ id: this.activeFallback.id,
268
+ name: this.activeFallback.name,
269
+ provider: this.activeFallback.provider,
270
+ status: this.activeFallback.status,
271
+ createdAt: this.createdAt,
272
+ });
273
+ }
274
+ const sandbox = await this.get();
275
+ this.status = remoteStatus(sandbox);
276
+ return {
277
+ id: this.id,
278
+ name: sandbox.display_name ?? this.name,
279
+ provider: this.provider,
280
+ status: this.status,
281
+ createdAt: this.remoteCreatedAt ?? this.createdAt,
282
+ ...(this.lastUsedAt ? { lastUsedAt: this.lastUsedAt } : {}),
283
+ metadata: {
284
+ resourceName: sandbox.name,
285
+ remoteState: sandbox.status?.state,
286
+ updateTime: sandbox.update_time,
287
+ },
288
+ };
289
+ }
290
+ /** Explain the Databricks execution boundary to the agent. */
291
+ getInstructions() {
292
+ return [
293
+ "Commands run in a persistent Databricks serverless sandbox, not in the App container.",
294
+ "Use shell commands normally. The sandbox home directory survives inactivity stops.",
295
+ "If Databricks Sandbox is unavailable, commands fall back to Pydantic Monty and must be Python source.",
296
+ "Databricks Workspace filesystem mounts remain separate unless a command copies data explicitly.",
297
+ ].join(" ");
298
+ }
299
+ get resourcePath() {
300
+ return `${SANDBOX_API_PATH}/${encodeURIComponent(this.id)}`;
301
+ }
302
+ async getOrCreate(signal) {
303
+ try {
304
+ return await this.get(signal);
305
+ }
306
+ catch (caught) {
307
+ if (!isStatus(caught, 404))
308
+ throw caught;
309
+ }
310
+ try {
311
+ const sandbox = await this.request(SANDBOX_API_PATH, "POST", SandboxResponseSchema, {
312
+ query: { sandbox_id: this.id },
313
+ payload: {
314
+ display_name: this.displayName,
315
+ spec: {
316
+ compute: {
317
+ inactivity_timeout: this.inactivityTimeout,
318
+ },
319
+ },
320
+ },
321
+ signal,
322
+ });
323
+ this.rememberCreatedAt(sandbox.create_time);
324
+ return sandbox;
325
+ }
326
+ catch (caught) {
327
+ if (!isStatus(caught, 409))
328
+ throw caught;
329
+ return this.get(signal);
330
+ }
331
+ }
332
+ async get(signal) {
333
+ const sandbox = await this.request(this.resourcePath, "GET", SandboxResponseSchema, {
334
+ signal,
335
+ });
336
+ this.rememberCreatedAt(sandbox.create_time);
337
+ return sandbox;
338
+ }
339
+ mutate(operation, signal) {
340
+ return this.request(`${this.resourcePath}/${operation}`, "POST", SandboxResponseSchema, {
341
+ signal,
342
+ });
343
+ }
344
+ async waitForState(expected, signal) {
345
+ const deadline = Date.now() + this.startupTimeoutMs;
346
+ while (Date.now() < deadline) {
347
+ const sandbox = await this.get(signal);
348
+ if (sandbox.status?.state === expected)
349
+ return sandbox;
350
+ await async.sleep(SANDBOX_POLL_INTERVAL_MS, signal);
351
+ }
352
+ throw new Error(`Databricks sandbox ${this.id} did not reach ${expected} within ${this.startupTimeoutMs}ms`);
353
+ }
354
+ rememberCreatedAt(value) {
355
+ if (!value)
356
+ return;
357
+ const parsed = new Date(value);
358
+ if (!Number.isNaN(parsed.getTime()))
359
+ this.remoteCreatedAt = parsed;
360
+ }
361
+ async request(path, method, schema, options = {}) {
362
+ const response = await this.client.apiClient.request({
363
+ path,
364
+ method,
365
+ query: options.query,
366
+ headers: new Headers({
367
+ Accept: "application/json",
368
+ ...(options.payload === undefined ? {} : { "Content-Type": "application/json" }),
369
+ }),
370
+ raw: false,
371
+ ...(options.payload === undefined ? {} : { payload: options.payload }),
372
+ }, options.signal ? databricks.toContext(options.signal) : undefined);
373
+ return schema.parse(response);
374
+ }
375
+ }
376
+ function commandScript(command, args, cwd) {
377
+ const invocation = args.length ? [command, ...args].map(shellQuote).join(" ") : command;
378
+ return cwd ? `cd -- ${shellQuote(cwd)} && ${invocation}` : invocation;
379
+ }
380
+ function shellQuote(value) {
381
+ return `'${value.replaceAll("'", "'\\''")}'`;
382
+ }
383
+ function definedEnvironment(input) {
384
+ return Object.fromEntries(Object.entries(input ?? {}).filter((entry) => entry[1] !== undefined));
385
+ }
386
+ function isStatus(caught, status) {
387
+ return error.errorContext(caught).statusCode === status;
388
+ }
389
+ function remoteStatus(sandbox) {
390
+ switch (sandbox.status?.state) {
391
+ case "SANDBOX_STATE_RUNNING":
392
+ return "running";
393
+ case "SANDBOX_STATE_STOPPED":
394
+ return "stopped";
395
+ case "SANDBOX_STATE_STOPPING":
396
+ return "stopping";
397
+ case "SANDBOX_STATE_PENDING":
398
+ return "starting";
399
+ default:
400
+ return "pending";
401
+ }
402
+ }
403
+ function resolveFallback(configured) {
404
+ if (typeof configured === "object" && "provider" in configured && "status" in configured) {
405
+ return configured;
406
+ }
407
+ return new MontySandbox(configured === "monty" ? {} : configured);
408
+ }
409
+ function isDatabricksSandboxUnavailable(caught) {
410
+ const context = error.errorContext(caught);
411
+ return (context.statusCode === 404 ||
412
+ context.hasMessage("feature", "disabled") ||
413
+ context.hasMessage("sandbox", "not", "enabled") ||
414
+ context.hasMessage("preview", "not", "enabled") ||
415
+ context.hasMessage("preview", "unavailable") ||
416
+ context.hasMessage("preview", "disabled"));
417
+ }
418
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2FuZGJveC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9zYW5kYm94LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7Ozs7R0FTRztBQUdILE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQztBQUMvQyxPQUFPLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxHQUFHLEVBQUUsTUFBTSxFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFTbkUsT0FBTyxFQUFFLENBQUMsRUFBRSxNQUFNLEtBQUssQ0FBQztBQUN4QixPQUFPLEVBQUUsWUFBWSxFQUE0QixNQUFNLG9CQUFvQixDQUFDO0FBRTVFLE1BQU0sZ0JBQWdCLEdBQUcsb0JBQW9CLENBQUM7QUFDOUMsTUFBTSxxQkFBcUIsR0FBRyxpQ0FBaUMsQ0FBQztBQUNoRSxNQUFNLDBCQUEwQixHQUFHLE1BQU0sQ0FBQztBQUMxQyxNQUFNLDBCQUEwQixHQUFHLE9BQU8sQ0FBQztBQUMzQyxNQUFNLDBCQUEwQixHQUFHLE1BQU0sQ0FBQztBQUMxQyxNQUFNLHdCQUF3QixHQUFHLEdBQUcsQ0FBQztBQUNyQyxNQUFNLE1BQU0sR0FBRyxHQUFHLENBQUMsTUFBTSxDQUFDLGdCQUFnQixDQUFDLENBQUM7QUFFNUMsTUFBTSxrQkFBa0IsR0FBRyxDQUFDLENBQUMsTUFBTSxDQUFDO0lBQ2xDLEtBQUssRUFBRSxDQUFDLENBQUMsTUFBTSxFQUFFLENBQUMsUUFBUSxFQUFFO0NBQzdCLENBQUMsQ0FBQztBQUVILE1BQU0scUJBQXFCLEdBQUcsQ0FBQyxDQUFDLE1BQU0sQ0FBQztJQUNyQyxJQUFJLEVBQUUsQ0FBQyxDQUFDLE1BQU0sRUFBRTtJQUNoQixZQUFZLEVBQUUsQ0FBQyxDQUFDLE1BQU0sRUFBRSxDQUFDLFFBQVEsRUFBRTtJQUNuQyxXQUFXLEVBQUUsQ0FBQyxDQUFDLE1BQU0sRUFBRSxDQUFDLFFBQVEsRUFBRTtJQUNsQyxXQUFXLEVBQUUsQ0FBQyxDQUFD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UyxFQUFFLFVBQVUsQ0FBQztRQUN6QyxPQUFPLENBQUMsVUFBVSxDQUFDLFNBQVMsRUFBRSxLQUFLLEVBQUUsU0FBUyxDQUFDO1FBQy9DLE9BQU8sQ0FBQyxVQUFVLENBQUMsU0FBUyxFQUFFLEtBQUssRUFBRSxTQUFTLENBQUM7UUFDL0MsT0FBTyxDQUFDLFVBQVUsQ0FBQyxTQUFTLEVBQUUsYUFBYSxDQUFDO1FBQzVDLE9BQU8sQ0FBQyxVQUFVLENBQUMsU0FBUyxFQUFFLFVBQVUsQ0FBQyxDQUMxQyxDQUFDO0FBQ0osQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogRGF0YWJyaWNrcyBTYW5kYm94IGFkYXB0ZXIgZm9yIE1hc3RyYSB3b3Jrc3BhY2VzLlxuICpcbiAqIEltcGxlbWVudHMgTWFzdHJhJ3MgZm9yZWdyb3VuZCBjb21tYW5kIHN1cmZhY2Ugb3ZlciB0aGUgRGF0YWJyaWNrcyBTYW5kYm94XG4gKiBSRVNUIEFQSS4gU2FuZGJveGVzIGFyZSBjcmVhdGVkIGxhemlseSwgcmV0YWluIHRoZWlyIGhvbWUgZGlyZWN0b3J5IGFjcm9zc1xuICogaW5hY3Rpdml0eSBzdG9wcywgYW5kIGV4ZWN1dGUgdW50cnVzdGVkIHNoZWxsIGNvbW1hbmRzIG91dHNpZGUgdGhlIEFwcFxuICogY29udGFpbmVyLlxuICpcbiAqIEBtb2R1bGVcbiAqL1xuXG5pbXBvcnQgdHlwZSB7IFdvcmtzcGFjZUNsaWVudCB9IGZyb20gXCJAZGF0YWJyaWNrcy9hcHBraXRcIjtcbmltcG9ydCB7IGRhdGFicmlja3MgfSBmcm9tIFwiQGRieC10b29scy9hcHBraXRcIjtcbmltcG9ydCB7IGFzeW5jLCBlcnJvciwgbG9nLCBzdHJpbmcgfSBmcm9tIFwiQGRieC10b29scy9zaGFyZWQtY29yZVwiO1xuaW1wb3J0IHR5cGUgeyBSZXF1ZXN0Q29udGV4dCB9IGZyb20gXCJAbWFzdHJhL2NvcmUvcmVxdWVzdC1jb250ZXh0XCI7XG5pbXBvcnQgdHlwZSB7XG4gIENvbW1hbmRSZXN1bHQsXG4gIEV4ZWN1dGVDb21tYW5kT3B0aW9ucyxcbiAgUHJvdmlkZXJTdGF0dXMsXG4gIFNhbmRib3hJbmZvLFxuICBXb3Jrc3BhY2VTYW5kYm94LFxufSBmcm9tIFwiQG1hc3RyYS9jb3JlL3dvcmtzcGFjZVwiO1xuaW1wb3J0IHsgeiB9IGZyb20gXCJ6b2RcIjtcbmltcG9ydCB7IE1vbnR5U2FuZGJveCwgdHlwZSBNb250eVNhbmRib3hPcHRpb25zIH0gZnJvbSBcIi4vbW9udHktc2FuZGJveC50c1wiO1xuXG5jb25zdCBTQU5EQk9YX0FQSV9QQVRIID0gXCIvYXBpLzIuMC9zYW5kYm94ZXNcIjtcbmNvbnN0IFNBTkRCT1hfRVhFQ19BUElfUEFUSCA9IFwiL2FwaS8yLjAvc2FuZGJveC1leGVjL3NhbmRib3hlc1wiO1xuY29uc3QgREVGQVVMVF9JTkFDVElWSVRZX1RJTUVPVVQgPSBcIjkwMHNcIjtcbmNvbnN0IERFRkFVTFRfU1RBUlRVUF9USU1FT1VUX01TID0gMTIwXzAwMDtcbmNvbnN0IERFRkFVTFRfQ09NTUFORF9USU1FT1VUX01TID0gMzBfMDAwO1xuY29uc3QgU0FOREJPWF9QT0xMX0lOVEVSVkFMX01TID0gNTAwO1xuY29uc3QgbG9nZ2VyID0gbG9nLmxvZ2dlcihcIm1hc3RyYS9zYW5kYm94XCIpO1xuXG5jb25zdCBTYW5kYm94U3RhdGVTY2hlbWEgPSB6Lm9iamVjdCh7XG4gIHN0YXRlOiB6LnN0cmluZygpLm9wdGlvbmFsKCksXG59KTtcblxuY29uc3QgU2FuZGJveFJlc3BvbnNlU2NoZW1hID0gei5vYmplY3Qoe1xuICBuYW1lOiB6LnN0cmluZygpLFxuICBkaXNwbGF5X25hbWU6IHouc3RyaW5nKCkub3B0aW9uYWwoKSxcbiAgY3JlYXRlX3RpbWU6IHouc3RyaW5nKCkub3B0aW9uYWwoKSxcbiAgdXBkYXRlX3RpbWU6IHouc3RyaW5nKCkub3B0aW9uYWwoKSxcbiAgc3RhdHVzOiBTYW5kYm94U3RhdGVTY2hlbWEub3B0aW9uYWwoKSxcbn0pO1xuXG5jb25zdCBFeGVjdXRlUmVzcG9uc2VTY2hlbWEgPSB6Lm9iamVjdCh7XG4gIGV4aXRfY29kZTogei5udW1iZXIoKS5pbnQoKS5vcHRpb25hbCgpLFxuICBzdGF0dXM6IHouc3RyaW5nKCksXG4gIHN0ZG91dDogei5zdHJpbmcoKS5vcHRpb25hbCgpLFxuICBzdGRlcnI6IHouc3RyaW5nKCkub3B0aW9uYWwoKSxcbiAgY29tbWFuZF9pZDogei5zdHJpbmcoKS5vcHRpb25hbCgpLFxuICB0cnVuY2F0ZWQ6IHouYm9vbGVhbigpLm9wdGlvbmFsKCksXG59KTtcblxuLyoqIE9wdGlvbnMgZm9yIG9uZSBEYXRhYnJpY2tzLWJhY2tlZCBNYXN0cmEgc2FuZGJveC4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgRGF0YWJyaWNrc1NhbmRib3hPcHRpb25zIHtcbiAgLyoqIEFwcEtpdCB3b3Jrc3BhY2UgY2xpZW50IHVzZWQgZm9yIGV2ZXJ5IHNhbmRib3ggQVBJIGNhbGwuICovXG4gIGNsaWVudDogV29ya3NwYWNlQ2xpZW50O1xuICAvKiogUmVzb3VyY2UgaWQsIHdpdGggb3Igd2l0aG91dCB0aGUgYHNhbmRib3hlcy9gIHByZWZpeC4gKi9cbiAgc2FuZGJveElkOiBzdHJpbmc7XG4gIC8qKiBIdW1hbi1yZWFkYWJsZSBEYXRhYnJpY2tzIGxhYmVsLiAqL1xuICBkaXNwbGF5TmFtZT86IHN0cmluZztcbiAgLyoqIFNlcnZlci1zaWRlIGlkbGUgdGltZW91dCBpbiBwcm90b2J1ZiBkdXJhdGlvbiBmb3JtLiBEZWZhdWx0cyB0byBgOTAwc2AuICovXG4gIGluYWN0aXZpdHlUaW1lb3V0Pzogc3RyaW5nO1xuICAvKiogTWF4aW11bSB0aW1lIHRvIHdhaXQgZm9yIHRoZSBzYW5kYm94IHRvIGJlY29tZSBydW5uYWJsZS4gKi9cbiAgc3RhcnR1cFRpbWVvdXRNcz86IG51bWJlcjtcbiAgLyoqIERlZmF1bHQgY29tbWFuZCB0aW1lb3V0LiBQZXItY2FsbCBgb3B0aW9ucy50aW1lb3V0YCB3aW5zLiAqL1xuICBjb21tYW5kVGltZW91dE1zPzogbnVtYmVyO1xuICAvKipcbiAgICogUHJvdmlkZXIgdXNlZCBvbmx5IHdoZW4gRGF0YWJyaWNrcyBTYW5kYm94IGlzIGRlZmluaXRpdmVseSB1bmF2YWlsYWJsZS5cbiAgICogRGVmYXVsdHMgdG8gdGhlIE5vZGUgUHlkYW50aWMgTW9udHkgcnVudGltZTsgYGZhbHNlYCBmYWlscyBpbnN0ZWFkLlxuICAgKi9cbiAgZmFsbGJhY2s/OiBmYWxzZSB8IFwibW9udHlcIiB8IE1vbnR5U2FuZGJveE9wdGlvbnMgfCBXb3Jrc3BhY2VTYW5kYm94O1xufVxuXG4vKiogRGF0YWJyaWNrcyBvcHRpb25zIGFjY2VwdGVkIGJ5IHRoZSBoaWdoZXItbGV2ZWwgd29ya3NwYWNlIGZhY3RvcnkuICovXG5leHBvcnQgaW50ZXJmYWNlIERhdGFicmlja3NXb3Jrc3BhY2VTYW5kYm94T3B0aW9ucyBleHRlbmRzIE9taXQ8XG4gIERhdGFicmlja3NTYW5kYm94T3B0aW9ucyxcbiAgXCJjbGllbnRcIiB8IFwic2FuZGJveElkXCJcbj4ge1xuICAvKiogUHJvdmlkZXIgZGlzY3JpbWluYXRvci4gRGVmYXVsdHMgdG8gYGRhdGFicmlja3NgLiAqL1xuICBwcm92aWRlcj86IFwiZGF0YWJyaWNrc1wiO1xuICAvKipcbiAgICogQ3JlZGVudGlhbCBzb3VyY2UuIERlZmF1bHRzIHRvIGEgZnJlc2ggQXBwS2l0IGNsaWVudCB1c2luZyB0aGUgbm9ybWFsXG4gICAqIGVudmlyb25tZW50L3Byb2ZpbGUgY2hhaW4sIHdoaWNoIGlzIHRoZSBhcHAgc2VydmljZSBwcmluY2lwYWwgaW4gYVxuICAgKiBEYXRhYnJpY2tzIEFwcC5cbiAgICovXG4gIGNsaWVudD86IFdvcmtzcGFjZUNsaWVudCB8ICgoY29udGV4dDogeyByZXF1ZXN0Q29udGV4dDogUmVxdWVzdENvbnRleHQgfSkgPT4gV29ya3NwYWNlQ2xpZW50KTtcbiAgLyoqXG4gICAqIEZpeGVkIGlkIG9yIHBlci1yZXF1ZXN0IHJlc29sdmVyLiBPbWl0IHRvIGRlcml2ZSBhIHN0YWJsZSwgb3BhcXVlIGlkIGZyb21cbiAgICogdGhlIHdvcmtzcGFjZSBhbmQgYXR0cmlidXRlZCB1c2VyLlxuICAgKi9cbiAgc2FuZGJveElkPzogc3RyaW5nIHwgKChjb250ZXh0OiB7IHJlcXVlc3RDb250ZXh0OiBSZXF1ZXN0Q29udGV4dCB9KSA9PiBzdHJpbmcpO1xufVxuXG4vKiogTWFzdHJhIHNhbmRib3ggYmFja2VkIGJ5IERhdGFicmlja3Mgc2VydmVybGVzcyBTYW5kYm94IGNvbXB1dGUuICovXG5leHBvcnQgY2xhc3MgRGF0YWJyaWNrc1NhbmRib3ggaW1wbGVtZW50cyBXb3Jrc3BhY2VTYW5kYm94IHtcbiAgcmVhZG9ubHkgaWQ6IHN0cmluZztcbiAgcmVhZG9ubHkgbmFtZTogc3RyaW5nO1xuICBzdGF0dXM6IFByb3ZpZGVyU3RhdHVzID0gXCJwZW5kaW5nXCI7XG4gIGVycm9yPzogc3RyaW5nO1xuXG4gIHByaXZhdGUgcmVhZG9ubHkgY2xpZW50OiBXb3Jrc3BhY2VDbGllbnQ7XG4gIHByaXZhdGUgcmVhZG9ubHkgZGlzcGxheU5hbWU6IHN0cmluZztcbiAgcHJpdmF0ZSByZWFkb25seSBpbmFjdGl2aXR5VGltZW91dDogc3RyaW5nO1xuICBwcml2YXRlIHJlYWRvbmx5IHN0YXJ0dXBUaW1lb3V0TXM6IG51bWJlcjtcbiAgcHJpdmF0ZSByZWFkb25seSBjb21tYW5kVGltZW91dE1zOiBudW1iZXI7XG4gIHByaXZhdGUgcmVhZG9ubHkgZmFsbGJhY2tDb25maWc6IEV4Y2x1ZGU8RGF0YWJyaWNrc1NhbmRib3hPcHRpb25zW1wiZmFsbGJhY2tcIl0sIHVuZGVmaW5lZD47XG4gIHByaXZhdGUgcmVhZG9ubHkgY3JlYXRlZEF0ID0gbmV3IERhdGUoKTtcbiAgcHJpdmF0ZSByZW1vdGVDcmVhdGVkQXQ/OiBEYXRlO1xuICBwcml2YXRlIGxhc3RVc2VkQXQ/OiBEYXRlO1xuICBwcml2YXRlIGFjdGl2ZUZhbGxiYWNrPzogV29ya3NwYWNlU2FuZGJveDtcbiAgcHJpdmF0ZSBzdGFydFByb21pc2U/OiBQcm9taXNlPHZvaWQ+O1xuXG4gIGNvbnN0cnVjdG9yKG9wdGlvbnM6IERhdGFicmlja3NTYW5kYm94T3B0aW9ucykge1xuICAgIGNvbnN0IGlkID0gc3RyaW5nLnRyaW1Ub051bGwob3B0aW9ucy5zYW5kYm94SWQucmVwbGFjZSgvXnNhbmRib3hlc1xcLy8sIFwiXCIpKTtcbiAgICBpZiAoIWlkKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiRGF0YWJyaWNrcyBzYW5kYm94IGlkIG11c3Qgbm90IGJlIGJsYW5rXCIpO1xuICAgIHRoaXMuaWQgPSBpZDtcbiAgICB0aGlzLm5hbWUgPSBvcHRpb25zLmRpc3BsYXlOYW1lPy50cmltKCkgfHwgYE1hc3RyYSBzYW5kYm94ICR7aWR9YDtcbiAgICB0aGlzLmNsaWVudCA9IG9wdGlvbnMuY2xpZW50O1xuICAgIHRoaXMuZGlzcGxheU5hbWUgPSB0aGlzLm5hbWU7XG4gICAgdGhpcy5pbmFjdGl2aXR5VGltZW91dCA9IG9wdGlvbnMuaW5hY3Rpdml0eVRpbWVvdXQgPz8gREVGQVVMVF9JTkFDVElWSVRZX1RJTUVPVVQ7XG4gICAgdGhpcy5zdGFydHVwVGltZW91dE1zID0gb3B0aW9ucy5zdGFydHVwVGltZW91dE1zID8/IERFRkFVTFRfU1RBUlRVUF9USU1FT1VUX01TO1xuICAgIHRoaXMuY29tbWFuZFRpbWVvdXRNcyA9IG9wdGlvbnMuY29tbWFuZFRpbWVvdXRNcyA/PyBERUZBVUxUX0NPTU1BTkRfVElNRU9VVF9NUztcbiAgICB0aGlzLmZhbGxiYWNrQ29uZmlnID0gb3B0aW9ucy5mYWxsYmFjayA/PyBcIm1vbnR5XCI7XG4gIH1cblxuICBnZXQgcHJvdmlkZXIoKTogc3RyaW5nIHtcbiAgICByZXR1cm4gdGhpcy5hY3RpdmVGYWxsYmFjaz8ucHJvdmlkZXIgPz8gXCJkYXRhYnJpY2tzXCI7XG4gIH1cblxuICAvKiogRW5zdXJlIHRoZSByZW1vdGUgc2FuZGJveCBleGlzdHMgYW5kIGhhcyByZWFjaGVkIGl0cyBydW5uaW5nIHN0YXRlLiAqL1xuICBhc3luYyBzdGFydCgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBhd2FpdCB0aGlzLnN0YXJ0V2l0aFNpZ25hbCgpO1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBzdGFydFdpdGhTaWduYWwoc2lnbmFsPzogQWJvcnRTaWduYWwpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBpZiAodGhpcy5zdGF0dXMgPT09IFwicnVubmluZ1wiKSByZXR1cm47XG4gICAgaWYgKHRoaXMuc3RhcnRQcm9taXNlKSB7XG4gICAgICBhd2FpdCB0aGlzLnN0YXJ0UHJvbWlzZTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3QgcGVuZGluZyA9IHRoaXMucGVyZm9ybVN0YXJ0KHNpZ25hbCk7XG4gICAgdGhpcy5zdGFydFByb21pc2UgPSBwZW5kaW5nO1xuICAgIHRyeSB7XG4gICAgICBhd2FpdCBwZW5kaW5nO1xuICAgIH0gZmluYWxseSB7XG4gICAgICBpZiAodGhpcy5zdGFydFByb21pc2UgPT09IHBlbmRpbmcpIHRoaXMuc3RhcnRQcm9taXNlID0gdW5kZWZpbmVkO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgcGVyZm9ybVN0YXJ0KHNpZ25hbD86IEFib3J0U2lnbmFsKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgaWYgKHRoaXMuYWN0aXZlRmFsbGJhY2spIHtcbiAgICAgIGF3YWl0IHRoaXMuYWN0aXZlRmFsbGJhY2suc3RhcnQ/LigpO1xuICAgICAgdGhpcy5zdGF0dXMgPSB0aGlzLmFjdGl2ZUZhbGxiYWNrLnN0YXR1cztcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy5zdGF0dXMgPSBcInN0YXJ0aW5nXCI7XG4gICAgdGhpcy5lcnJvciA9IHVuZGVmaW5lZDtcbiAgICB0cnkge1xuICAgICAgbGV0IHNhbmRib3ggPSBhd2FpdCB0aGlzLmdldE9yQ3JlYXRlKHNpZ25hbCk7XG4gICAgICBpZiAoc2FuZGJveC5zdGF0dXM/LnN0YXRlID09PSBcIlNBTkRCT1hfU1RBVEVfU1RPUFBFRFwiKSB7XG4gICAgICAgIHNhbmRib3ggPSBhd2FpdCB0aGlzLm11dGF0ZShcInN0YXJ0XCIsIHNpZ25hbCk7XG4gICAgICB9XG4gICAgICBpZiAoc2FuZGJveC5zdGF0dXM/LnN0YXRlID09PSBcIlNBTkRCT1hfU1RBVEVfU1RPUFBJTkdcIikge1xuICAgICAgICBhd2FpdCB0aGlzLndhaXRGb3JTdGF0ZShcIlNBTkRCT1hfU1RBVEVfU1RPUFBFRFwiLCBzaWduYWwpO1xuICAgICAgICBzYW5kYm94ID0gYXdhaXQgdGhpcy5tdXRhdGUoXCJzdGFydFwiLCBzaWduYWwpO1xuICAgICAgfVxuICAgICAgaWYgKHNhbmRib3guc3RhdHVzPy5zdGF0ZSAhPT0gXCJTQU5EQk9YX1NUQVRFX1JVTk5JTkdcIikge1xuICAgICAgICBhd2FpdCB0aGlzLndhaXRGb3JTdGF0ZShcIlNBTkRCT1hfU1RBVEVfUlVOTklOR1wiLCBzaWduYWwpO1xuICAgICAgfVxuICAgICAgdGhpcy5zdGF0dXMgPSBcInJ1bm5pbmdcIjtcbiAgICAgIHRoaXMubGFzdFVzZWRBdCA9IG5ldyBEYXRlKCk7XG4gICAgfSBjYXRjaCAoY2F1Z2h0KSB7XG4gICAgICBpZiAodGhpcy5mYWxsYmFja0NvbmZpZyAhPT0gZmFsc2UgJiYgaXNEYXRhYnJpY2tzU2FuZGJveFVuYXZhaWxhYmxlKGNhdWdodCkpIHtcbiAgICAgICAgY29uc3QgZmFsbGJhY2sgPSByZXNvbHZlRmFsbGJhY2sodGhpcy5mYWxsYmFja0NvbmZpZyk7XG4gICAgICAgIGxvZ2dlci53YXJuKFwiRGF0YWJyaWNrcyBTYW5kYm94IHVuYXZhaWxhYmxlOyB1c2luZyBmYWxsYmFja1wiLCB7XG4gICAgICAgICAgc2FuZGJveElkOiB0aGlzLmlkLFxuICAgICAgICAgIGZhbGxiYWNrOiBmYWxsYmFjay5wcm92aWRlcixcbiAgICAgICAgICBlcnJvcjogZXJyb3IuZXJyb3JNZXNzYWdlKGNhdWdodCksXG4gICAgICAgIH0pO1xuICAgICAgICBhd2FpdCBmYWxsYmFjay5zdGFydD8uKCk7XG4gICAgICAgIHRoaXMuYWN0aXZlRmFsbGJhY2sgPSBmYWxsYmFjaztcbiAgICAgICAgdGhpcy5zdGF0dXMgPSBmYWxsYmFjay5zdGF0dXM7XG4gICAgICAgIHRoaXMuZXJyb3IgPSBmYWxsYmFjay5lcnJvcjtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgdGhpcy5zdGF0dXMgPSBcImVycm9yXCI7XG4gICAgICB0aGlzLmVycm9yID0gZXJyb3IuZXJyb3JNZXNzYWdlKGNhdWdodCk7XG4gICAgICB0aHJvdyBjYXVnaHQ7XG4gICAgfVxuICB9XG5cbiAgLyoqIERhdGFicmlja3MgaG9tZSBwZXJzaXN0ZW5jZSBpcyBub3QgYSBjbG9uZWFibGUgTWFzdHJhIGNoZWNrcG9pbnQuICovXG4gIGFzeW5jIHNuYXBzaG90KCk6IFByb21pc2U8dm9pZD4ge1xuICAgIGF3YWl0IHRoaXMuYWN0aXZlRmFsbGJhY2s/LnNuYXBzaG90KCk7XG4gIH1cblxuICBnZXQgc3VwcG9ydHNDaGVja3BvaW50cygpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5hY3RpdmVGYWxsYmFjaz8uc3VwcG9ydHNDaGVja3BvaW50cyA/PyBmYWxzZTtcbiAgfVxuXG4gIC8qKiBTdG9wIGNvbXB1dGUgd2hpbGUgcHJlc2VydmluZyB0aGUgc2FuZGJveCBob21lIGRpcmVjdG9yeS4gKi9cbiAgYXN5bmMgc3RvcCgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBpZiAodGhpcy5hY3RpdmVGYWxsYmFjaykge1xuICAgICAgYXdhaXQgdGhpcy5hY3RpdmVGYWxsYmFjay5zdG9wPy4oKTtcbiAgICAgIHRoaXMuc3RhdHVzID0gdGhpcy5hY3RpdmVGYWxsYmFjay5zdGF0dXM7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmICh0aGlzLnN0YXR1cyA9PT0gXCJzdG9wcGVkXCIgfHwgdGhpcy5zdGF0dXMgPT09IFwiZGVzdHJveWVkXCIpIHJldHVybjtcbiAgICB0aGlzLnN0YXR1cyA9IFwic3RvcHBpbmdcIjtcbiAgICB0cnkge1xuICAgICAgYXdhaXQgdGhpcy5tdXRhdGUoXCJzdG9wXCIpO1xuICAgICAgdGhpcy5zdGF0dXMgPSBcInN0b3BwZWRcIjtcbiAgICB9IGNhdGNoIChjYXVnaHQpIHtcbiAgICAgIGlmIChpc1N0YXR1cyhjYXVnaHQsIDQwNCkpIHtcbiAgICAgICAgdGhpcy5zdGF0dXMgPSBcInN0b3BwZWRcIjtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgdGhpcy5zdGF0dXMgPSBcImVycm9yXCI7XG4gICAgICB0aGlzLmVycm9yID0gZXJyb3IuZXJyb3JNZXNzYWdlKGNhdWdodCk7XG4gICAgICB0aHJvdyBjYXVnaHQ7XG4gICAgfVxuICB9XG5cbiAgLyoqIFBlcm1hbmVudGx5IGRlbGV0ZSB0aGUgc2FuZGJveCBhbmQgaXRzIHBlcnNpc3RlZCBob21lIGRpcmVjdG9yeS4gKi9cbiAgYXN5bmMgZGVzdHJveSgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBpZiAodGhpcy5hY3RpdmVGYWxsYmFjaykge1xuICAgICAgYXdhaXQgdGhpcy5hY3RpdmVGYWxsYmFjay5kZXN0cm95Py4oKTtcbiAgICAgIHRoaXMuc3RhdHVzID0gdGhpcy5hY3RpdmVGYWxsYmFjay5zdGF0dXM7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmICh0aGlzLnN0YXR1cyA9PT0gXCJkZXN0cm95ZWRcIikgcmV0dXJuO1xuICAgIHRoaXMuc3RhdHVzID0gXCJkZXN0cm95aW5nXCI7XG4gICAgdHJ5IHtcbiAgICAgIGF3YWl0IHRoaXMucmVxdWVzdChgJHt0aGlzLnJlc291cmNlUGF0aH1gLCBcIkRFTEVURVwiLCB6Lm9iamVjdCh7fSkucGFzc3Rocm91Z2goKSk7XG4gICAgICB0aGlzLnN0YXR1cyA9IFwiZGVzdHJveWVkXCI7XG4gICAgfSBjYXRjaCAoY2F1Z2h0KSB7XG4gICAgICBpZiAoaXNTdGF0dXMoY2F1Z2h0LCA0MDQpKSB7XG4gICAgICAgIHRoaXMuc3RhdHVzID0gXCJkZXN0cm95ZWRcIjtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgdGhpcy5zdGF0dXMgPSBcImVycm9yXCI7XG4gICAgICB0aGlzLmVycm9yID0gZXJyb3IuZXJyb3JNZXNzYWdlKGNhdWdodCk7XG4gICAgICB0aHJvdyBjYXVnaHQ7XG4gICAgfVxuICB9XG5cbiAgLyoqIEV4ZWN1dGUgb25lIGZvcmVncm91bmQgc2hlbGwgY29tbWFuZCBpbiB0aGUgcmVtb3RlIHNhbmRib3guICovXG4gIGFzeW5jIGV4ZWN1dGVDb21tYW5kKFxuICAgIGNvbW1hbmQ6IHN0cmluZyxcbiAgICBhcmdzOiBzdHJpbmdbXSA9IFtdLFxuICAgIG9wdGlvbnM6IEV4ZWN1dGVDb21tYW5kT3B0aW9ucyA9IHt9LFxuICApOiBQcm9taXNlPENvbW1hbmRSZXN1bHQ+IHtcbiAgICBhd2FpdCB0aGlzLnN0YXJ0V2l0aFNpZ25hbChvcHRpb25zLmFib3J0U2lnbmFsKTtcbiAgICBpZiAodGhpcy5hY3RpdmVGYWxsYmFjaykge1xuICAgICAgaWYgKCF0aGlzLmFjdGl2ZUZhbGxiYWNrLmV4ZWN1dGVDb21tYW5kKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgY29tbWFuZCxcbiAgICAgICAgICBhcmdzLFxuICAgICAgICAgIHN1Y2Nlc3M6IGZhbHNlLFxuICAgICAgICAgIGV4aXRDb2RlOiAxLFxuICAgICAgICAgIHN0ZG91dDogXCJcIixcbiAgICAgICAgICBzdGRlcnI6IGBGYWxsYmFjayBzYW5kYm94ICR7dGhpcy5hY3RpdmVGYWxsYmFjay5wcm92aWRlcn0gZG9lcyBub3Qgc3VwcG9ydCBjb21tYW5kIGV4ZWN1dGlvbi5gLFxuICAgICAgICAgIGV4ZWN1dGlvblRpbWVNczogMCxcbiAgICAgICAgfTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB0aGlzLmFjdGl2ZUZhbGxiYWNrLmV4ZWN1dGVDb21tYW5kKGNvbW1hbmQsIGFyZ3MsIG9wdGlvbnMpO1xuICAgIH1cbiAgICBjb25zdCB0aW1lb3V0ID0gb3B0aW9ucy50aW1lb3V0ID8/IHRoaXMuY29tbWFuZFRpbWVvdXRNcztcbiAgICBjb25zdCBzY3JpcHQgPSBjb21tYW5kU2NyaXB0KGNvbW1hbmQsIGFyZ3MsIG9wdGlvbnMuY3dkKTtcbiAgICBjb25zdCBzdGFydGVkID0gcGVyZm9ybWFuY2Uubm93KCk7XG4gICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCB0aGlzLnJlcXVlc3QoXG4gICAgICBgJHtTQU5EQk9YX0VYRUNfQVBJX1BBVEh9LyR7ZW5jb2RlVVJJQ29tcG9uZW50KHRoaXMuaWQpfS9leGVjLXN5bmNgLFxuICAgICAgXCJQT1NUXCIsXG4gICAgICBFeGVjdXRlUmVzcG9uc2VTY2hlbWEsXG4gICAgICB7XG4gICAgICAgIHBheWxvYWQ6IHtcbiAgICAgICAgICBjbWQ6IFwiL2Jpbi9iYXNoXCIsXG4gICAgICAgICAgYXJnczogW1wiLWxjXCIsIHNjcmlwdF0sXG4gICAgICAgICAgZW52czogZGVmaW5lZEVudmlyb25tZW50KG9wdGlvbnMuZW52KSxcbiAgICAgICAgICBleGVjdXRpb25fdGltZW91dDogYCR7TWF0aC5tYXgoMSwgTWF0aC5jZWlsKHRpbWVvdXQgLyAxXzAwMCkpfXNgLFxuICAgICAgICB9LFxuICAgICAgICBzaWduYWw6IG9wdGlvbnMuYWJvcnRTaWduYWwsXG4gICAgICB9LFxuICAgICk7XG4gICAgY29uc3Qgc3Rkb3V0ID0gcmVzcG9uc2Uuc3Rkb3V0ID8/IFwiXCI7XG4gICAgY29uc3Qgc3RkZXJyID0gcmVzcG9uc2Uuc3RkZXJyID8/IFwiXCI7XG4gICAgb3B0aW9ucy5vblN0ZG91dD8uKHN0ZG91dCk7XG4gICAgb3B0aW9ucy5vblN0ZGVycj8uKHN0ZGVycik7XG4gICAgdGhpcy5sYXN0VXNlZEF0ID0gbmV3IERhdGUoKTtcbiAgICBjb25zdCB0aW1lZE91dCA9IHJlc3BvbnNlLnN0YXR1cyA9PT0gXCJFWEVDVVRFX0NPTU1BTkRfU1RBVFVTX1RJTUVEX09VVFwiO1xuICAgIGNvbnN0IGV4aXRDb2RlID0gcmVzcG9uc2UuZXhpdF9jb2RlID8/IC0xO1xuICAgIHJldHVybiB7XG4gICAgICBjb21tYW5kLFxuICAgICAgYXJncyxcbiAgICAgIHN1Y2Nlc3M6IHJlc3BvbnNlLnN0YXR1cyA9PT0gXCJFWEVDVVRFX0NPTU1BTkRfU1RBVFVTX0NPTVBMRVRFRFwiICYmIGV4aXRDb2RlID09PSAwLFxuICAgICAgZXhpdENvZGUsXG4gICAgICBzdGRvdXQsXG4gICAgICBzdGRlcnIsXG4gICAgICBleGVjdXRpb25UaW1lTXM6IHBlcmZvcm1hbmNlLm5vdygpIC0gc3RhcnRlZCxcbiAgICAgIC4uLih0aW1lZE91dCA/IHsgdGltZWRPdXQ6IHRydWUsIGtpbGxlZDogdHJ1ZSB9IDoge30pLFxuICAgICAgLi4uKHJlc3BvbnNlLnRydW5jYXRlZFxuICAgICAgICA/IHtcbiAgICAgICAgICAgIHN0ZG91dFRydW5jYXRlZDogdHJ1ZSxcbiAgICAgICAgICAgIHN0ZGVyclRydW5jYXRlZDogdHJ1ZSxcbiAgICAgICAgICB9XG4gICAgICAgIDoge30pLFxuICAgIH07XG4gIH1cblxuICAvKiogV2hldGhlciB0aGUgYWRhcHRlciBjdXJyZW50bHkga25vd3MgdGhlIHJlbW90ZSBzYW5kYm94IHRvIGJlIHJ1bm5pbmcuICovXG4gIGFzeW5jIGlzUmVhZHkoKTogUHJvbWlzZTxib29sZWFuPiB7XG4gICAgaWYgKHRoaXMuYWN0aXZlRmFsbGJhY2spIHtcbiAgICAgIHJldHVybiB0aGlzLmFjdGl2ZUZhbGxiYWNrLmlzUmVhZHk/LigpID8/IHRoaXMuYWN0aXZlRmFsbGJhY2suc3RhdHVzID09PSBcInJ1bm5pbmdcIjtcbiAgICB9XG4gICAgaWYgKHRoaXMuc3RhdHVzID09PSBcInJ1bm5pbmdcIikgcmV0dXJuIHRydWU7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHNhbmRib3ggPSBhd2FpdCB0aGlzLmdldCgpO1xuICAgICAgdGhpcy5zdGF0dXMgPVxuICAgICAgICBzYW5kYm94LnN0YXR1cz8uc3RhdGUgPT09IFwiU0FOREJPWF9TVEFURV9SVU5OSU5HXCIgPyBcInJ1bm5pbmdcIiA6IHJlbW90ZVN0YXR1cyhzYW5kYm94KTtcbiAgICAgIHJldHVybiB0aGlzLnN0YXR1cyA9PT0gXCJydW5uaW5nXCI7XG4gICAgfSBjYXRjaCAoY2F1Z2h0KSB7XG4gICAgICBpZiAoaXNTdGF0dXMoY2F1Z2h0LCA0MDQpKSByZXR1cm4gZmFsc2U7XG4gICAgICB0aHJvdyBjYXVnaHQ7XG4gICAgfVxuICB9XG5cbiAgLyoqIFJlcG9ydCBNYXN0cmEtZmFjaW5nIHNhbmRib3ggbWV0YWRhdGEuICovXG4gIGFzeW5jIGdldEluZm8oKTogUHJvbWlzZTxTYW5kYm94SW5mbz4ge1xuICAgIGlmICh0aGlzLmFjdGl2ZUZhbGxiYWNrKSB7XG4gICAgICByZXR1cm4gKFxuICAgICAgICAoYXdhaXQgdGhpcy5hY3RpdmVGYWxsYmFjay5nZXRJbmZvPy4oKSkgPz8ge1xuICAgICAgICAgIGlkOiB0aGlzLmFjdGl2ZUZhbGxiYWNrLmlkLFxuICAgICAgICAgIG5hbWU6IHRoaXMuYWN0aXZlRmFsbGJhY2submFtZSxcbiAgICAgICAgICBwcm92aWRlcjogdGhpcy5hY3RpdmVGYWxsYmFjay5wcm92aWRlcixcbiAgICAgICAgICBzdGF0dXM6IHRoaXMuYWN0aXZlRmFsbGJhY2suc3RhdHVzLFxuICAgICAgICAgIGNyZWF0ZWRBdDogdGhpcy5jcmVhdGVkQXQsXG4gICAgICAgIH1cbiAgICAgICk7XG4gICAgfVxuICAgIGNvbnN0IHNhbmRib3ggPSBhd2FpdCB0aGlzLmdldCgpO1xuICAgIHRoaXMuc3RhdHVzID0gcmVtb3RlU3RhdHVzKHNhbmRib3gpO1xuICAgIHJldHVybiB7XG4gICAgICBpZDogdGhpcy5pZCxcbiAgICAgIG5hbWU6IHNhbmRib3guZGlzcGxheV9uYW1lID8/IHRoaXMubmFtZSxcbiAgICAgIHByb3ZpZGVyOiB0aGlzLnByb3ZpZGVyLFxuICAgICAgc3RhdHVzOiB0aGlzLnN0YXR1cyxcbiAgICAgIGNyZWF0ZWRBdDogdGhpcy5yZW1vdGVDcmVhdGVkQXQgPz8gdGhpcy5jcmVhdGVkQXQsXG4gICAgICAuLi4odGhpcy5sYXN0VXNlZEF0ID8geyBsYXN0VXNlZEF0OiB0aGlzLmxhc3RVc2VkQXQgfSA6IHt9KSxcbiAgICAgIG1ldGFkYXRhOiB7XG4gICAgICAgIHJlc291cmNlTmFtZTogc2FuZGJveC5uYW1lLFxuICAgICAgICByZW1vdGVTdGF0ZTogc2FuZGJveC5zdGF0dXM/LnN0YXRlLFxuICAgICAgICB1cGRhdGVUaW1lOiBzYW5kYm94LnVwZGF0ZV90aW1lLFxuICAgICAgfSxcbiAgICB9O1xuICB9XG5cbiAgLyoqIEV4cGxhaW4gdGhlIERhdGFicmlja3MgZXhlY3V0aW9uIGJvdW5kYXJ5IHRvIHRoZSBhZ2VudC4gKi9cbiAgZ2V0SW5zdHJ1Y3Rpb25zKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIFtcbiAgICAgIFwiQ29tbWFuZHMgcnVuIGluIGEgcGVyc2lzdGVudCBEYXRhYnJpY2tzIHNlcnZlcmxlc3Mgc2FuZGJveCwgbm90IGluIHRoZSBBcHAgY29udGFpbmVyLlwiLFxuICAgICAgXCJVc2Ugc2hlbGwgY29tbWFuZHMgbm9ybWFsbHkuIFRoZSBzYW5kYm94IGhvbWUgZGlyZWN0b3J5IHN1cnZpdmVzIGluYWN0aXZpdHkgc3RvcHMuXCIsXG4gICAgICBcIklmIERhdGFicmlja3MgU2FuZGJveCBpcyB1bmF2YWlsYWJsZSwgY29tbWFuZHMgZmFsbCBiYWNrIHRvIFB5ZGFudGljIE1vbnR5IGFuZCBtdXN0IGJlIFB5dGhvbiBzb3VyY2UuXCIsXG4gICAgICBcIkRhdGFicmlja3MgV29ya3NwYWNlIGZpbGVzeXN0ZW0gbW91bnRzIHJlbWFpbiBzZXBhcmF0ZSB1bmxlc3MgYSBjb21tYW5kIGNvcGllcyBkYXRhIGV4cGxpY2l0bHkuXCIsXG4gICAgXS5qb2luKFwiIFwiKTtcbiAgfVxuXG4gIHByaXZhdGUgZ2V0IHJlc291cmNlUGF0aCgpOiBzdHJpbmcge1xuICAgIHJldHVybiBgJHtTQU5EQk9YX0FQSV9QQVRIfS8ke2VuY29kZVVSSUNvbXBvbmVudCh0aGlzLmlkKX1gO1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBnZXRPckNyZWF0ZShzaWduYWw/OiBBYm9ydFNpZ25hbCkge1xuICAgIHRyeSB7XG4gICAgICByZXR1cm4gYXdhaXQgdGhpcy5nZXQoc2lnbmFsKTtcbiAgICB9IGNhdGNoIChjYXVnaHQpIHtcbiAgICAgIGlmICghaXNTdGF0dXMoY2F1Z2h0LCA0MDQpKSB0aHJvdyBjYXVnaHQ7XG4gICAgfVxuICAgIHRyeSB7XG4gICAgICBjb25zdCBzYW5kYm94ID0gYXdhaXQgdGhpcy5yZXF1ZXN0KFNBTkRCT1hfQVBJX1BBVEgsIFwiUE9TVFwiLCBTYW5kYm94UmVzcG9uc2VTY2hlbWEsIHtcbiAgICAgICAgcXVlcnk6IHsgc2FuZGJveF9pZDogdGhpcy5pZCB9LFxuICAgICAgICBwYXlsb2FkOiB7XG4gICAgICAgICAgZGlzcGxheV9uYW1lOiB0aGlzLmRpc3BsYXlOYW1lLFxuICAgICAgICAgIHNwZWM6IHtcbiAgICAgICAgICAgIGNvbXB1dGU6IHtcbiAgICAgICAgICAgICAgaW5hY3Rpdml0eV90aW1lb3V0OiB0aGlzLmluYWN0aXZpdHlUaW1lb3V0LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgICBzaWduYWwsXG4gICAgICB9KTtcbiAgICAgIHRoaXMucmVtZW1iZXJDcmVhdGVkQXQoc2FuZGJveC5jcmVhdGVfdGltZSk7XG4gICAgICByZXR1cm4gc2FuZGJveDtcbiAgICB9IGNhdGNoIChjYXVnaHQpIHtcbiAgICAgIGlmICghaXNTdGF0dXMoY2F1Z2h0LCA0MDkpKSB0aHJvdyBjYXVnaHQ7XG4gICAgICByZXR1cm4gdGhpcy5nZXQoc2lnbmFsKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIGdldChzaWduYWw/OiBBYm9ydFNpZ25hbCkge1xuICAgIGNvbnN0IHNhbmRib3ggPSBhd2FpdCB0aGlzLnJlcXVlc3QodGhpcy5yZXNvdXJjZVBhdGgsIFwiR0VUXCIsIFNhbmRib3hSZXNwb25zZVNjaGVtYSwge1xuICAgICAgc2lnbmFsLFxuICAgIH0pO1xuICAgIHRoaXMucmVtZW1iZXJDcmVhdGVkQXQoc2FuZGJveC5jcmVhdGVfdGltZSk7XG4gICAgcmV0dXJuIHNhbmRib3g7XG4gIH1cblxuICBwcml2YXRlIG11dGF0ZShvcGVyYXRpb246IFwic3RhcnRcIiB8IFwic3RvcFwiLCBzaWduYWw/OiBBYm9ydFNpZ25hbCkge1xuICAgIHJldHVybiB0aGlzLnJlcXVlc3QoYCR7dGhpcy5yZXNvdXJjZVBhdGh9LyR7b3BlcmF0aW9ufWAsIFwiUE9TVFwiLCBTYW5kYm94UmVzcG9uc2VTY2hlbWEsIHtcbiAgICAgIHNpZ25hbCxcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgd2FpdEZvclN0YXRlKGV4cGVjdGVkOiBzdHJpbmcsIHNpZ25hbD86IEFib3J0U2lnbmFsKSB7XG4gICAgY29uc3QgZGVhZGxpbmUgPSBEYXRlLm5vdygpICsgdGhpcy5zdGFydHVwVGltZW91dE1zO1xuICAgIHdoaWxlIChEYXRlLm5vdygpIDwgZGVhZGxpbmUpIHtcbiAgICAgIGNvbnN0IHNhbmRib3ggPSBhd2FpdCB0aGlzLmdldChzaWduYWwpO1xuICAgICAgaWYgKHNhbmRib3guc3RhdHVzPy5zdGF0ZSA9PT0gZXhwZWN0ZWQpIHJldHVybiBzYW5kYm94O1xuICAgICAgYXdhaXQgYXN5bmMuc2xlZXAoU0FOREJPWF9QT0xMX0lOVEVSVkFMX01TLCBzaWduYWwpO1xuICAgIH1cbiAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICBgRGF0YWJyaWNrcyBzYW5kYm94ICR7dGhpcy5pZH0gZGlkIG5vdCByZWFjaCAke2V4cGVjdGVkfSB3aXRoaW4gJHt0aGlzLnN0YXJ0dXBUaW1lb3V0TXN9bXNgLFxuICAgICk7XG4gIH1cblxuICBwcml2YXRlIHJlbWVtYmVyQ3JlYXRlZEF0KHZhbHVlOiBzdHJpbmcgfCB1bmRlZmluZWQpOiB2b2lkIHtcbiAgICBpZiAoIXZhbHVlKSByZXR1cm47XG4gICAgY29uc3QgcGFyc2VkID0gbmV3IERhdGUodmFsdWUpO1xuICAgIGlmICghTnVtYmVyLmlzTmFOKHBhcnNlZC5nZXRUaW1lKCkpKSB0aGlzLnJlbW90ZUNyZWF0ZWRBdCA9IHBhcnNlZDtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgcmVxdWVzdDxUPihcbiAgICBwYXRoOiBzdHJpbmcsXG4gICAgbWV0aG9kOiBcIkdFVFwiIHwgXCJQT1NUXCIgfCBcIkRFTEVURVwiLFxuICAgIHNjaGVtYTogei5ab2RUeXBlPFQ+LFxuICAgIG9wdGlvbnM6IHtcbiAgICAgIHBheWxvYWQ/OiB1bmtub3duO1xuICAgICAgcXVlcnk/OiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+O1xuICAgICAgc2lnbmFsPzogQWJvcnRTaWduYWw7XG4gICAgfSA9IHt9LFxuICApOiBQcm9taXNlPFQ+IHtcbiAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IHRoaXMuY2xpZW50LmFwaUNsaWVudC5yZXF1ZXN0KFxuICAgICAge1xuICAgICAgICBwYXRoLFxuICAgICAgICBtZXRob2QsXG4gICAgICAgIHF1ZXJ5OiBvcHRpb25zLnF1ZXJ5LFxuICAgICAgICBoZWFkZXJzOiBuZXcgSGVhZGVycyh7XG4gICAgICAgICAgQWNjZXB0OiBcImFwcGxpY2F0aW9uL2pzb25cIixcbiAgICAgICAgICAuLi4ob3B0aW9ucy5wYXlsb2FkID09PSB1bmRlZmluZWQgPyB7fSA6IHsgXCJDb250ZW50LVR5cGVcIjogXCJhcHBsaWNhdGlvbi9qc29uXCIgfSksXG4gICAgICAgIH0pLFxuICAgICAgICByYXc6IGZhbHNlLFxuICAgICAgICAuLi4ob3B0aW9ucy5wYXlsb2FkID09PSB1bmRlZmluZWQgPyB7fSA6IHsgcGF5bG9hZDogb3B0aW9ucy5wYXlsb2FkIH0pLFxuICAgICAgfSxcbiAgICAgIG9wdGlvbnMuc2lnbmFsID8gZGF0YWJyaWNrcy50b0NvbnRleHQob3B0aW9ucy5zaWduYWwpIDogdW5kZWZpbmVkLFxuICAgICk7XG4gICAgcmV0dXJuIHNjaGVtYS5wYXJzZShyZXNwb25zZSk7XG4gIH1cbn1cblxuZnVuY3Rpb24gY29tbWFuZFNjcmlwdChjb21tYW5kOiBzdHJpbmcsIGFyZ3M6IHJlYWRvbmx5IHN0cmluZ1tdLCBjd2Q6IHN0cmluZyB8IHVuZGVmaW5lZCk6IHN0cmluZyB7XG4gIGNvbnN0IGludm9jYXRpb24gPSBhcmdzLmxlbmd0aCA/IFtjb21tYW5kLCAuLi5hcmdzXS5tYXAoc2hlbGxRdW90ZSkuam9pbihcIiBcIikgOiBjb21tYW5kO1xuICByZXR1cm4gY3dkID8gYGNkIC0tICR7c2hlbGxRdW90ZShjd2QpfSAmJiAke2ludm9jYXRpb259YCA6IGludm9jYXRpb247XG59XG5cbmZ1bmN0aW9uIHNoZWxsUXVvdGUodmFsdWU6IHN0cmluZyk6IHN0cmluZyB7XG4gIHJldHVybiBgJyR7dmFsdWUucmVwbGFjZUFsbChcIidcIiwgXCInXFxcXCcnXCIpfSdgO1xufVxuXG5mdW5jdGlvbiBkZWZpbmVkRW52aXJvbm1lbnQoaW5wdXQ6IE5vZGVKUy5Qcm9jZXNzRW52IHwgdW5kZWZpbmVkKTogUmVjb3JkPHN0cmluZywgc3RyaW5nPiB7XG4gIHJldHVybiBPYmplY3QuZnJvbUVudHJpZXMoXG4gICAgT2JqZWN0LmVudHJpZXMoaW5wdXQgPz8ge30pLmZpbHRlcihcbiAgICAgIChlbnRyeSk6IGVudHJ5IGlzIFtzdHJpbmcsIHN0cmluZ10gPT4gZW50cnlbMV0gIT09IHVuZGVmaW5lZCxcbiAgICApLFxuICApO1xufVxuXG5mdW5jdGlvbiBpc1N0YXR1cyhjYXVnaHQ6IHVua25vd24sIHN0YXR1czogbnVtYmVyKTogYm9vbGVhbiB7XG4gIHJldHVybiBlcnJvci5lcnJvckNvbnRleHQoY2F1Z2h0KS5zdGF0dXNDb2RlID09PSBzdGF0dXM7XG59XG5cbmZ1bmN0aW9uIHJlbW90ZVN0YXR1cyhzYW5kYm94OiB6LmluZmVyPHR5cGVvZiBTYW5kYm94UmVzcG9uc2VTY2hlbWE+KTogUHJvdmlkZXJTdGF0dXMge1xuICBzd2l0Y2ggKHNhbmRib3guc3RhdHVzPy5zdGF0ZSkge1xuICAgIGNhc2UgXCJTQU5EQk9YX1NUQVRFX1JVTk5JTkdcIjpcbiAgICAgIHJldHVybiBcInJ1bm5pbmdcIjtcbiAgICBjYXNlIFwiU0FOREJPWF9TVEFURV9TVE9QUEVEXCI6XG4gICAgICByZXR1cm4gXCJzdG9wcGVkXCI7XG4gICAgY2FzZSBcIlNBTkRCT1hfU1RBVEVfU1RPUFBJTkdcIjpcbiAgICAgIHJldHVybiBcInN0b3BwaW5nXCI7XG4gICAgY2FzZSBcIlNBTkRCT1hfU1RBVEVfUEVORElOR1wiOlxuICAgICAgcmV0dXJuIFwic3RhcnRpbmdcIjtcbiAgICBkZWZhdWx0OlxuICAgICAgcmV0dXJuIFwicGVuZGluZ1wiO1xuICB9XG59XG5cbmZ1bmN0aW9uIHJlc29sdmVGYWxsYmFjayhcbiAgY29uZmlndXJlZDogRXhjbHVkZTxEYXRhYnJpY2tzU2FuZGJveE9wdGlvbnNbXCJmYWxsYmFja1wiXSwgZmFsc2UgfCB1bmRlZmluZWQ+LFxuKTogV29ya3NwYWNlU2FuZGJveCB7XG4gIGlmICh0eXBlb2YgY29uZmlndXJlZCA9PT0gXCJvYmplY3RcIiAmJiBcInByb3ZpZGVyXCIgaW4gY29uZmlndXJlZCAmJiBcInN0YXR1c1wiIGluIGNvbmZpZ3VyZWQpIHtcbiAgICByZXR1cm4gY29uZmlndXJlZDtcbiAgfVxuICByZXR1cm4gbmV3IE1vbnR5U2FuZGJveChjb25maWd1cmVkID09PSBcIm1vbnR5XCIgPyB7fSA6IGNvbmZpZ3VyZWQpO1xufVxuXG5mdW5jdGlvbiBpc0RhdGFicmlja3NTYW5kYm94VW5hdmFpbGFibGUoY2F1Z2h0OiB1bmtub3duKTogYm9vbGVhbiB7XG4gIGNvbnN0IGNvbnRleHQgPSBlcnJvci5lcnJvckNvbnRleHQoY2F1Z2h0KTtcbiAgcmV0dXJuIChcbiAgICBjb250ZXh0LnN0YXR1c0NvZGUgPT09IDQwNCB8fFxuICAgIGNvbnRleHQuaGFzTWVzc2FnZShcImZlYXR1cmVcIiwgXCJkaXNhYmxlZFwiKSB8fFxuICAgIGNvbnRleHQuaGFzTWVzc2FnZShcInNhbmRib3hcIiwgXCJub3RcIiwgXCJlbmFibGVkXCIpIHx8XG4gICAgY29udGV4dC5oYXNNZXNzYWdlKFwicHJldmlld1wiLCBcIm5vdFwiLCBcImVuYWJsZWRcIikgfHxcbiAgICBjb250ZXh0Lmhhc01lc3NhZ2UoXCJwcmV2aWV3XCIsIFwidW5hdmFpbGFibGVcIikgfHxcbiAgICBjb250ZXh0Lmhhc01lc3NhZ2UoXCJwcmV2aWV3XCIsIFwiZGlzYWJsZWRcIilcbiAgKTtcbn1cbiJdfQ==
@@ -5,7 +5,8 @@
5
5
  * Outbound ({@link rewriteServingBody}), because the transcript Mastra
6
6
  * persists is not always a transcript the provider will accept back:
7
7
  * Databricks-hosted Claude rejects replayed extended-thinking blocks and reads
8
- * a trailing assistant message as a prefill request.
8
+ * a trailing assistant message as a prefill request, while GPT Astra requires
9
+ * `reasoning_effort: "none"` when Chat Completions carries function tools.
9
10
  *
10
11
  * Inbound ({@link rewriteServingResponseBody} and
11
12
  * {@link rewriteServingResponseStream}), because Databricks-hosted Gemini and
@@ -38,6 +39,22 @@ export interface ServingChatMessage extends ChatMessage {
38
39
  * JSON or no rewrite was needed.
39
40
  */
40
41
  export declare function rewriteServingBody(body: string): string;
42
+ /** Prepared fetch arguments plus the post-sanitize body used for diagnostics. */
43
+ export interface RewrittenServingRequest {
44
+ input: Parameters<typeof fetch>[0];
45
+ init: Parameters<typeof fetch>[1];
46
+ body: string;
47
+ }
48
+ /**
49
+ * Read and rewrite a serving POST whether its JSON body lives on `init` or on
50
+ * a `Request`. A changed Request is rebuilt without stale byte headers.
51
+ */
52
+ export declare function rewriteServingRequest(input: Parameters<typeof fetch>[0], init?: Parameters<typeof fetch>[1]): Promise<RewrittenServingRequest>;
53
+ /**
54
+ * Add the Chat Completions option Databricks-hosted GPT Astra requires when
55
+ * function tools are present. An explicit caller value always wins.
56
+ */
57
+ export declare function applyAstraToolCompatibility(body: Record<string, unknown>): boolean;
41
58
  /**
42
59
  * Drop extended-thinking / reasoning blocks from a replayed transcript.
43
60
  *