experimental-agent 0.0.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 +243 -0
- package/dist/agent-workflow.d.mts +21 -0
- package/dist/agent-workflow.d.ts +21 -0
- package/dist/agent-workflow.js +2659 -0
- package/dist/agent-workflow.mjs +9 -0
- package/dist/chunk-2YI7MQGZ.mjs +261 -0
- package/dist/chunk-36X6L7SK.mjs +1 -0
- package/dist/chunk-DPPQO7DA.mjs +343 -0
- package/dist/chunk-JQPR6M7D.mjs +649 -0
- package/dist/chunk-MR4UWCJT.mjs +878 -0
- package/dist/client-FCFZYOOB.mjs +9 -0
- package/dist/client-RRX3GDQD.mjs +9 -0
- package/dist/index.d.mts +128 -0
- package/dist/index.d.ts +128 -0
- package/dist/index.js +3078 -0
- package/dist/index.mjs +421 -0
- package/dist/lifecycle-workflow-steps-6BLGTYVB.mjs +20 -0
- package/dist/lifecycle-workflow.d.mts +17 -0
- package/dist/lifecycle-workflow.d.ts +17 -0
- package/dist/lifecycle-workflow.js +1690 -0
- package/dist/lifecycle-workflow.mjs +44 -0
- package/dist/local-J6QFWSWB.mjs +244 -0
- package/dist/process-manager-H2HF6G4G.mjs +153 -0
- package/dist/sandbox-Y3ENCNUA.mjs +10 -0
- package/dist/storage-QSTSE2ZB.mjs +27 -0
- package/dist/types-Lwut_0_u.d.mts +80 -0
- package/dist/types-ctZeJ3iQ.d.ts +80 -0
- package/dist/types-vRxN1Qz1.d.mts +805 -0
- package/dist/types-vRxN1Qz1.d.ts +805 -0
- package/dist/vercel-2CFDMEHB.mjs +18 -0
- package/package.json +59 -0
|
@@ -0,0 +1,1690 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __esm = (fn, res) => function __init() {
|
|
9
|
+
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
10
|
+
};
|
|
11
|
+
var __export = (target, all) => {
|
|
12
|
+
for (var name in all)
|
|
13
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
14
|
+
};
|
|
15
|
+
var __copyProps = (to, from, except, desc) => {
|
|
16
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
17
|
+
for (let key of __getOwnPropNames(from))
|
|
18
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
19
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
20
|
+
}
|
|
21
|
+
return to;
|
|
22
|
+
};
|
|
23
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
24
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
25
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
26
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
27
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
28
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
29
|
+
mod
|
|
30
|
+
));
|
|
31
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
32
|
+
|
|
33
|
+
// src/errors.ts
|
|
34
|
+
var errore, SessionNotFoundError, SessionError, SandboxNotFoundError, StorageError, SandboxError, MessageNotFoundError;
|
|
35
|
+
var init_errors = __esm({
|
|
36
|
+
"src/errors.ts"() {
|
|
37
|
+
"use strict";
|
|
38
|
+
errore = __toESM(require("errore"));
|
|
39
|
+
SessionNotFoundError = class extends errore.createTaggedError({
|
|
40
|
+
name: "SessionNotFoundError",
|
|
41
|
+
message: "Session $id not found"
|
|
42
|
+
}) {
|
|
43
|
+
};
|
|
44
|
+
SessionError = class extends errore.createTaggedError({
|
|
45
|
+
name: "SessionError",
|
|
46
|
+
message: "Session $id failed: $reason"
|
|
47
|
+
}) {
|
|
48
|
+
};
|
|
49
|
+
SandboxNotFoundError = class extends errore.createTaggedError({
|
|
50
|
+
name: "SandboxNotFoundError",
|
|
51
|
+
message: "Sandbox $id not found"
|
|
52
|
+
}) {
|
|
53
|
+
};
|
|
54
|
+
StorageError = class extends errore.createTaggedError({
|
|
55
|
+
name: "StorageError",
|
|
56
|
+
message: "$reason"
|
|
57
|
+
}) {
|
|
58
|
+
};
|
|
59
|
+
SandboxError = class extends errore.createTaggedError({
|
|
60
|
+
name: "SandboxError",
|
|
61
|
+
message: "$reason"
|
|
62
|
+
}) {
|
|
63
|
+
};
|
|
64
|
+
MessageNotFoundError = class extends errore.createTaggedError({
|
|
65
|
+
name: "MessageNotFoundError",
|
|
66
|
+
message: "Message $id not found"
|
|
67
|
+
}) {
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
// src/utils/paginate.ts
|
|
73
|
+
function paginate(opts) {
|
|
74
|
+
const { items, cursor, limit = 50 } = opts;
|
|
75
|
+
const startIndex = cursor ? items.findIndex((m) => m.id === cursor) + 1 : 0;
|
|
76
|
+
const sliced = items.slice(startIndex, startIndex + limit);
|
|
77
|
+
const nextCursor = startIndex + limit < items.length ? sliced.at(-1)?.id ?? null : null;
|
|
78
|
+
return { items: sliced, nextCursor };
|
|
79
|
+
}
|
|
80
|
+
var init_paginate = __esm({
|
|
81
|
+
"src/utils/paginate.ts"() {
|
|
82
|
+
"use strict";
|
|
83
|
+
}
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
// src/storage/bindings/local-fs-handlers.ts
|
|
87
|
+
function createFilesystemHandlers(basePath) {
|
|
88
|
+
const sessionDir = (0, import_node_path.join)(basePath, "session");
|
|
89
|
+
const messageDir = (0, import_node_path.join)(basePath, "message");
|
|
90
|
+
const partDir = (0, import_node_path.join)(basePath, "part");
|
|
91
|
+
const sandboxDir = (0, import_node_path.join)(basePath, "sandbox");
|
|
92
|
+
const commandDir = (0, import_node_path.join)(basePath, "command");
|
|
93
|
+
async function ensureDir(dir) {
|
|
94
|
+
await (0, import_promises.mkdir)(dir, { recursive: true });
|
|
95
|
+
}
|
|
96
|
+
async function readJson(filePath) {
|
|
97
|
+
try {
|
|
98
|
+
const content = await (0, import_promises.readFile)(filePath, "utf-8");
|
|
99
|
+
return JSON.parse(content);
|
|
100
|
+
} catch {
|
|
101
|
+
return null;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
async function writeJsonFile(filePath, data) {
|
|
105
|
+
await ensureDir((0, import_node_path.dirname)(filePath));
|
|
106
|
+
await (0, import_promises.writeFile)(filePath, JSON.stringify(data, null, 2));
|
|
107
|
+
}
|
|
108
|
+
async function readAllFromDir(dir) {
|
|
109
|
+
try {
|
|
110
|
+
const files = await (0, import_promises.readdir)(dir);
|
|
111
|
+
const results = await Promise.all(
|
|
112
|
+
files.filter((f) => f.endsWith(".json")).map((f) => readJson((0, import_node_path.join)(dir, f)))
|
|
113
|
+
);
|
|
114
|
+
return results.filter((r) => r !== null);
|
|
115
|
+
} catch {
|
|
116
|
+
return [];
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
return {
|
|
120
|
+
"session.get": async ({ id }) => {
|
|
121
|
+
const session = await readJson((0, import_node_path.join)(sessionDir, `${id}.json`));
|
|
122
|
+
return session ?? null;
|
|
123
|
+
},
|
|
124
|
+
"session.set": async (session) => {
|
|
125
|
+
const now = Date.now();
|
|
126
|
+
const sessionPath = (0, import_node_path.join)(sessionDir, `${session.id}.json`);
|
|
127
|
+
const existing = await readJson(sessionPath);
|
|
128
|
+
const newSession = {
|
|
129
|
+
...session,
|
|
130
|
+
tags: session.tags ?? existing?.tags ?? {},
|
|
131
|
+
createdAt: existing?.createdAt ?? session.createdAt ?? now,
|
|
132
|
+
updatedAt: now
|
|
133
|
+
};
|
|
134
|
+
await writeJsonFile(sessionPath, newSession);
|
|
135
|
+
return newSession;
|
|
136
|
+
},
|
|
137
|
+
"session.list": async ({ tags, cursor, limit }) => {
|
|
138
|
+
const allSessions = await readAllFromDir(sessionDir);
|
|
139
|
+
let filtered = allSessions;
|
|
140
|
+
if (tags && Object.keys(tags).length > 0) {
|
|
141
|
+
filtered = filtered.filter((s) => {
|
|
142
|
+
const sessionTags = s.tags ?? {};
|
|
143
|
+
return Object.entries(tags).every(
|
|
144
|
+
([key, value]) => sessionTags[key] === value
|
|
145
|
+
);
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
filtered.sort((a, b) => a.createdAt - b.createdAt);
|
|
149
|
+
return paginate({ items: filtered, cursor, limit });
|
|
150
|
+
},
|
|
151
|
+
"session.listBySandbox": async ({ sandboxId, tags, cursor, limit }) => {
|
|
152
|
+
const allSessions = await readAllFromDir(sessionDir);
|
|
153
|
+
let filtered = allSessions.filter((s) => s.sandboxId === sandboxId);
|
|
154
|
+
if (tags && Object.keys(tags).length > 0) {
|
|
155
|
+
filtered = filtered.filter((s) => {
|
|
156
|
+
const sessionTags = s.tags ?? {};
|
|
157
|
+
return Object.entries(tags).every(
|
|
158
|
+
([key, value]) => sessionTags[key] === value
|
|
159
|
+
);
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
filtered.sort((a, b) => a.createdAt - b.createdAt);
|
|
163
|
+
return paginate({ items: filtered, cursor, limit });
|
|
164
|
+
},
|
|
165
|
+
"session.tag.set": async ({ sessionId, tags }) => {
|
|
166
|
+
const sessionPath = (0, import_node_path.join)(sessionDir, `${sessionId}.json`);
|
|
167
|
+
const existing = await readJson(sessionPath);
|
|
168
|
+
if (!existing) {
|
|
169
|
+
throw new Error(`Session ${sessionId} not found`);
|
|
170
|
+
}
|
|
171
|
+
const mergedTags = { ...existing.tags, ...tags };
|
|
172
|
+
const now = Date.now();
|
|
173
|
+
const updatedSession = {
|
|
174
|
+
...existing,
|
|
175
|
+
tags: mergedTags,
|
|
176
|
+
updatedAt: now
|
|
177
|
+
};
|
|
178
|
+
await writeJsonFile(sessionPath, updatedSession);
|
|
179
|
+
return updatedSession;
|
|
180
|
+
},
|
|
181
|
+
"message.get": async ({ id }) => {
|
|
182
|
+
return await readJson((0, import_node_path.join)(messageDir, `${id}.json`));
|
|
183
|
+
},
|
|
184
|
+
"message.set": async (message) => {
|
|
185
|
+
await writeJsonFile((0, import_node_path.join)(messageDir, `${message.id}.json`), message);
|
|
186
|
+
return message;
|
|
187
|
+
},
|
|
188
|
+
"message.list": async ({ sessionId, cursor, limit }) => {
|
|
189
|
+
const allMessages = await readAllFromDir(messageDir);
|
|
190
|
+
const filtered = allMessages.filter((m) => m.sessionId === sessionId).sort((a, b) => a.createdAt - b.createdAt);
|
|
191
|
+
return paginate({ items: filtered, cursor, limit });
|
|
192
|
+
},
|
|
193
|
+
"part.listByMessage": async ({ messageId, cursor, limit }) => {
|
|
194
|
+
const allParts = await readAllFromDir(partDir);
|
|
195
|
+
const filtered = allParts.filter((p) => p.messageId === messageId).sort((a, b) => a.index - b.index);
|
|
196
|
+
return paginate({ items: filtered, cursor, limit });
|
|
197
|
+
},
|
|
198
|
+
"part.listBySession": async ({ sessionId, cursor, limit }) => {
|
|
199
|
+
const allParts = await readAllFromDir(partDir);
|
|
200
|
+
const filtered = allParts.filter((p) => p.sessionId === sessionId).sort((a, b) => {
|
|
201
|
+
if (a.messageId !== b.messageId) {
|
|
202
|
+
return a.messageId.localeCompare(b.messageId);
|
|
203
|
+
}
|
|
204
|
+
return a.index - b.index;
|
|
205
|
+
});
|
|
206
|
+
return paginate({ items: filtered, cursor, limit });
|
|
207
|
+
},
|
|
208
|
+
"part.set": async (part) => {
|
|
209
|
+
await writeJsonFile((0, import_node_path.join)(partDir, `${part.id}.json`), part);
|
|
210
|
+
return part;
|
|
211
|
+
},
|
|
212
|
+
"sandbox.get": async ({ key }) => {
|
|
213
|
+
const safeName = Buffer.from(key).toString("base64url");
|
|
214
|
+
const sandboxPath = (0, import_node_path.join)(sandboxDir, `${safeName}.json`);
|
|
215
|
+
const data = await readJson(sandboxPath);
|
|
216
|
+
if (!data) {
|
|
217
|
+
return null;
|
|
218
|
+
}
|
|
219
|
+
return data;
|
|
220
|
+
},
|
|
221
|
+
"sandbox.set": async (record) => {
|
|
222
|
+
const safeName = Buffer.from(record.id).toString("base64url");
|
|
223
|
+
const sandboxPath = (0, import_node_path.join)(sandboxDir, `${safeName}.json`);
|
|
224
|
+
await writeJsonFile(sandboxPath, record);
|
|
225
|
+
},
|
|
226
|
+
"sandbox.getBySession": async ({ sessionId }) => {
|
|
227
|
+
const allSandboxes = await readAllFromDir(sandboxDir);
|
|
228
|
+
const matching = allSandboxes.filter(
|
|
229
|
+
(s) => s.id.startsWith(`${sessionId}-`)
|
|
230
|
+
);
|
|
231
|
+
if (matching.length === 0) {
|
|
232
|
+
return null;
|
|
233
|
+
}
|
|
234
|
+
matching.sort(
|
|
235
|
+
(a, b) => (b.lastActivityAt ?? 0) - (a.lastActivityAt ?? 0)
|
|
236
|
+
);
|
|
237
|
+
return matching[0];
|
|
238
|
+
},
|
|
239
|
+
"command.get": async ({ id }) => {
|
|
240
|
+
return await readJson((0, import_node_path.join)(commandDir, `${id}.json`));
|
|
241
|
+
},
|
|
242
|
+
"command.set": async (command) => {
|
|
243
|
+
await writeJsonFile((0, import_node_path.join)(commandDir, `${command.id}.json`), command);
|
|
244
|
+
return command;
|
|
245
|
+
},
|
|
246
|
+
"command.list": async ({ sessionId, includeFinished, cursor, limit }) => {
|
|
247
|
+
const allCommands = await readAllFromDir(commandDir);
|
|
248
|
+
let filtered = allCommands.filter((c) => c.sessionId === sessionId);
|
|
249
|
+
if (!includeFinished) {
|
|
250
|
+
filtered = filtered.filter((c) => c.status === "running");
|
|
251
|
+
}
|
|
252
|
+
filtered.sort((a, b) => a.startedAt - b.startedAt);
|
|
253
|
+
return paginate({ items: filtered, cursor, limit });
|
|
254
|
+
}
|
|
255
|
+
};
|
|
256
|
+
}
|
|
257
|
+
var import_promises, import_node_path;
|
|
258
|
+
var init_local_fs_handlers = __esm({
|
|
259
|
+
"src/storage/bindings/local-fs-handlers.ts"() {
|
|
260
|
+
"use strict";
|
|
261
|
+
import_promises = require("fs/promises");
|
|
262
|
+
import_node_path = require("path");
|
|
263
|
+
init_paginate();
|
|
264
|
+
}
|
|
265
|
+
});
|
|
266
|
+
|
|
267
|
+
// src/storage/bindings/local.ts
|
|
268
|
+
var local_exports = {};
|
|
269
|
+
__export(local_exports, {
|
|
270
|
+
startLocalStorage: () => startLocalStorage,
|
|
271
|
+
stopLocalStorage: () => stopLocalStorage
|
|
272
|
+
});
|
|
273
|
+
function startLocalStorage(opts) {
|
|
274
|
+
if (startPromise) {
|
|
275
|
+
return startPromise;
|
|
276
|
+
}
|
|
277
|
+
startPromise = new Promise((resolve) => {
|
|
278
|
+
const handlers = createFilesystemHandlers(
|
|
279
|
+
opts?.path ?? DEFAULT_STORAGE_DIR
|
|
280
|
+
);
|
|
281
|
+
const app = new import_hono.Hono();
|
|
282
|
+
app.post("/", async (c) => {
|
|
283
|
+
const body = await c.req.json();
|
|
284
|
+
const response = await handleStorageRpc(body, handlers);
|
|
285
|
+
return c.json(response);
|
|
286
|
+
});
|
|
287
|
+
const port = opts?.port ?? 0;
|
|
288
|
+
const server = (0, import_node_server.serve)({
|
|
289
|
+
fetch: app.fetch,
|
|
290
|
+
port
|
|
291
|
+
});
|
|
292
|
+
server.on("listening", () => {
|
|
293
|
+
const address = server.address();
|
|
294
|
+
const actualPort = typeof address === "object" ? address?.port : port;
|
|
295
|
+
const url = `http://localhost:${actualPort}`;
|
|
296
|
+
serverInstance = { url, server };
|
|
297
|
+
console.log(`[agent] Local storage server started at ${url}`);
|
|
298
|
+
resolve(url);
|
|
299
|
+
});
|
|
300
|
+
});
|
|
301
|
+
return startPromise;
|
|
302
|
+
}
|
|
303
|
+
function stopLocalStorage() {
|
|
304
|
+
if (serverInstance) {
|
|
305
|
+
serverInstance.server.close();
|
|
306
|
+
serverInstance = null;
|
|
307
|
+
startPromise = null;
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
var import_node_server, import_hono, DEFAULT_STORAGE_DIR, startPromise, serverInstance;
|
|
311
|
+
var init_local = __esm({
|
|
312
|
+
"src/storage/bindings/local.ts"() {
|
|
313
|
+
"use strict";
|
|
314
|
+
import_node_server = require("@hono/node-server");
|
|
315
|
+
import_hono = require("hono");
|
|
316
|
+
init_storage();
|
|
317
|
+
init_local_fs_handlers();
|
|
318
|
+
DEFAULT_STORAGE_DIR = ".agent-storage";
|
|
319
|
+
startPromise = null;
|
|
320
|
+
serverInstance = null;
|
|
321
|
+
if (typeof process !== "undefined") {
|
|
322
|
+
process.on("SIGTERM", stopLocalStorage);
|
|
323
|
+
process.on("SIGINT", stopLocalStorage);
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
});
|
|
327
|
+
|
|
328
|
+
// src/storage/bindings/vercel.ts
|
|
329
|
+
var vercel_exports = {};
|
|
330
|
+
__export(vercel_exports, {
|
|
331
|
+
getVercelStorageConfig: () => getVercelStorageConfig
|
|
332
|
+
});
|
|
333
|
+
async function getVercelStorageConfig() {
|
|
334
|
+
let token = null;
|
|
335
|
+
try {
|
|
336
|
+
const { getVercelOidcToken } = await import("@vercel/oidc");
|
|
337
|
+
token = await getVercelOidcToken();
|
|
338
|
+
} catch {
|
|
339
|
+
}
|
|
340
|
+
return {
|
|
341
|
+
url: VERCEL_STORAGE_URL,
|
|
342
|
+
headers: token ? { Authorization: `Bearer ${token}` } : {}
|
|
343
|
+
};
|
|
344
|
+
}
|
|
345
|
+
var VERCEL_STORAGE_URL;
|
|
346
|
+
var init_vercel = __esm({
|
|
347
|
+
"src/storage/bindings/vercel.ts"() {
|
|
348
|
+
"use strict";
|
|
349
|
+
VERCEL_STORAGE_URL = "https://agent-sdk-storage-nine.labs.vercel.dev/api/storage";
|
|
350
|
+
}
|
|
351
|
+
});
|
|
352
|
+
|
|
353
|
+
// src/storage/client.ts
|
|
354
|
+
function getStorageClient({ url, headers }) {
|
|
355
|
+
async function rpc(method, params) {
|
|
356
|
+
const res = await fetch(url, {
|
|
357
|
+
method: "POST",
|
|
358
|
+
headers: { "Content-Type": "application/json", ...headers },
|
|
359
|
+
body: JSON.stringify({ method, params })
|
|
360
|
+
});
|
|
361
|
+
if (!res.ok) {
|
|
362
|
+
throw new StorageError({
|
|
363
|
+
reason: `HTTP ${res.status}: ${res.statusText}`
|
|
364
|
+
});
|
|
365
|
+
}
|
|
366
|
+
const json = await res.json();
|
|
367
|
+
if ("error" in json) {
|
|
368
|
+
throw new StorageError({ reason: json.error.message });
|
|
369
|
+
}
|
|
370
|
+
return json.result;
|
|
371
|
+
}
|
|
372
|
+
return {
|
|
373
|
+
session: {
|
|
374
|
+
get: async (id) => {
|
|
375
|
+
try {
|
|
376
|
+
const result = await rpc("session.get", { id });
|
|
377
|
+
if (result === null) {
|
|
378
|
+
return new SessionNotFoundError({ id });
|
|
379
|
+
}
|
|
380
|
+
return result;
|
|
381
|
+
} catch (e) {
|
|
382
|
+
if (e instanceof StorageError) {
|
|
383
|
+
return e;
|
|
384
|
+
}
|
|
385
|
+
return new StorageError({ reason: String(e), cause: e });
|
|
386
|
+
}
|
|
387
|
+
},
|
|
388
|
+
set: async (session) => {
|
|
389
|
+
try {
|
|
390
|
+
return await rpc("session.set", session);
|
|
391
|
+
} catch (e) {
|
|
392
|
+
if (e instanceof StorageError) {
|
|
393
|
+
return e;
|
|
394
|
+
}
|
|
395
|
+
return new StorageError({ reason: String(e), cause: e });
|
|
396
|
+
}
|
|
397
|
+
},
|
|
398
|
+
list: async (opts) => {
|
|
399
|
+
try {
|
|
400
|
+
return await rpc("session.list", {
|
|
401
|
+
tags: opts?.tags,
|
|
402
|
+
order: opts?.order,
|
|
403
|
+
cursor: opts?.cursor,
|
|
404
|
+
limit: opts?.limit
|
|
405
|
+
});
|
|
406
|
+
} catch (e) {
|
|
407
|
+
if (e instanceof StorageError) {
|
|
408
|
+
return e;
|
|
409
|
+
}
|
|
410
|
+
return new StorageError({ reason: String(e), cause: e });
|
|
411
|
+
}
|
|
412
|
+
},
|
|
413
|
+
tag: {
|
|
414
|
+
set: async ({ sessionId, tags }) => {
|
|
415
|
+
try {
|
|
416
|
+
return await rpc("session.tag.set", { sessionId, tags });
|
|
417
|
+
} catch (e) {
|
|
418
|
+
if (e instanceof StorageError) {
|
|
419
|
+
return e;
|
|
420
|
+
}
|
|
421
|
+
return new StorageError({ reason: String(e), cause: e });
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
},
|
|
426
|
+
message: {
|
|
427
|
+
list: async (sessionId, opts) => {
|
|
428
|
+
try {
|
|
429
|
+
return await rpc("message.list", {
|
|
430
|
+
sessionId,
|
|
431
|
+
cursor: opts?.cursor,
|
|
432
|
+
limit: opts?.limit
|
|
433
|
+
});
|
|
434
|
+
} catch (e) {
|
|
435
|
+
if (e instanceof StorageError) {
|
|
436
|
+
return e;
|
|
437
|
+
}
|
|
438
|
+
return new StorageError({ reason: String(e), cause: e });
|
|
439
|
+
}
|
|
440
|
+
},
|
|
441
|
+
get: async (id) => {
|
|
442
|
+
try {
|
|
443
|
+
const result = await rpc("message.get", { id });
|
|
444
|
+
if (result === null) {
|
|
445
|
+
return new MessageNotFoundError({ id });
|
|
446
|
+
}
|
|
447
|
+
return result;
|
|
448
|
+
} catch (e) {
|
|
449
|
+
if (e instanceof StorageError) {
|
|
450
|
+
return e;
|
|
451
|
+
}
|
|
452
|
+
return new StorageError({ reason: String(e), cause: e });
|
|
453
|
+
}
|
|
454
|
+
},
|
|
455
|
+
set: async (message) => {
|
|
456
|
+
try {
|
|
457
|
+
return await rpc("message.set", message);
|
|
458
|
+
} catch (e) {
|
|
459
|
+
if (e instanceof StorageError) {
|
|
460
|
+
return e;
|
|
461
|
+
}
|
|
462
|
+
return new StorageError({ reason: String(e), cause: e });
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
},
|
|
466
|
+
part: {
|
|
467
|
+
listByMessage: async (messageId, opts) => {
|
|
468
|
+
try {
|
|
469
|
+
const result = await rpc("part.listByMessage", {
|
|
470
|
+
messageId,
|
|
471
|
+
cursor: opts?.cursor,
|
|
472
|
+
limit: opts?.limit
|
|
473
|
+
});
|
|
474
|
+
return result;
|
|
475
|
+
} catch (e) {
|
|
476
|
+
if (e instanceof StorageError) {
|
|
477
|
+
return e;
|
|
478
|
+
}
|
|
479
|
+
return new StorageError({ reason: String(e), cause: e });
|
|
480
|
+
}
|
|
481
|
+
},
|
|
482
|
+
listBySession: async (sessionId, opts) => {
|
|
483
|
+
try {
|
|
484
|
+
const result = await rpc("part.listBySession", {
|
|
485
|
+
sessionId,
|
|
486
|
+
cursor: opts?.cursor,
|
|
487
|
+
limit: opts?.limit
|
|
488
|
+
});
|
|
489
|
+
return result;
|
|
490
|
+
} catch (e) {
|
|
491
|
+
if (e instanceof StorageError) {
|
|
492
|
+
return e;
|
|
493
|
+
}
|
|
494
|
+
return new StorageError({ reason: String(e), cause: e });
|
|
495
|
+
}
|
|
496
|
+
},
|
|
497
|
+
set: async (part) => {
|
|
498
|
+
try {
|
|
499
|
+
return await rpc("part.set", part);
|
|
500
|
+
} catch (e) {
|
|
501
|
+
if (e instanceof StorageError) {
|
|
502
|
+
return e;
|
|
503
|
+
}
|
|
504
|
+
return new StorageError({ reason: String(e), cause: e });
|
|
505
|
+
}
|
|
506
|
+
}
|
|
507
|
+
},
|
|
508
|
+
sandbox: {
|
|
509
|
+
get: async (key) => {
|
|
510
|
+
try {
|
|
511
|
+
const result = await rpc("sandbox.get", { key });
|
|
512
|
+
if (result === null) {
|
|
513
|
+
return new SandboxNotFoundError({ id: key });
|
|
514
|
+
}
|
|
515
|
+
return result;
|
|
516
|
+
} catch (e) {
|
|
517
|
+
if (e instanceof StorageError) {
|
|
518
|
+
return e;
|
|
519
|
+
}
|
|
520
|
+
return new StorageError({ reason: String(e), cause: e });
|
|
521
|
+
}
|
|
522
|
+
},
|
|
523
|
+
getBySession: async (sessionId) => {
|
|
524
|
+
try {
|
|
525
|
+
const result = await rpc("sandbox.getBySession", { sessionId });
|
|
526
|
+
if (result === null) {
|
|
527
|
+
return new SandboxNotFoundError({ id: sessionId });
|
|
528
|
+
}
|
|
529
|
+
return result;
|
|
530
|
+
} catch (e) {
|
|
531
|
+
if (e instanceof StorageError) {
|
|
532
|
+
return e;
|
|
533
|
+
}
|
|
534
|
+
return new StorageError({ reason: String(e), cause: e });
|
|
535
|
+
}
|
|
536
|
+
},
|
|
537
|
+
set: async (record) => {
|
|
538
|
+
try {
|
|
539
|
+
await rpc("sandbox.set", record);
|
|
540
|
+
return record;
|
|
541
|
+
} catch (e) {
|
|
542
|
+
if (e instanceof StorageError) {
|
|
543
|
+
return e;
|
|
544
|
+
}
|
|
545
|
+
return new StorageError({ reason: String(e), cause: e });
|
|
546
|
+
}
|
|
547
|
+
}
|
|
548
|
+
},
|
|
549
|
+
command: {
|
|
550
|
+
get: async (id) => {
|
|
551
|
+
try {
|
|
552
|
+
return await rpc("command.get", { id });
|
|
553
|
+
} catch (e) {
|
|
554
|
+
if (e instanceof StorageError) {
|
|
555
|
+
return e;
|
|
556
|
+
}
|
|
557
|
+
return new StorageError({ reason: String(e), cause: e });
|
|
558
|
+
}
|
|
559
|
+
},
|
|
560
|
+
set: async (command) => {
|
|
561
|
+
try {
|
|
562
|
+
return await rpc("command.set", command);
|
|
563
|
+
} catch (e) {
|
|
564
|
+
if (e instanceof StorageError) {
|
|
565
|
+
return e;
|
|
566
|
+
}
|
|
567
|
+
return new StorageError({ reason: String(e), cause: e });
|
|
568
|
+
}
|
|
569
|
+
},
|
|
570
|
+
list: async (sessionId, opts) => {
|
|
571
|
+
try {
|
|
572
|
+
const result = await rpc("command.list", {
|
|
573
|
+
sessionId,
|
|
574
|
+
includeFinished: opts?.includeFinished,
|
|
575
|
+
cursor: opts?.cursor,
|
|
576
|
+
limit: opts?.limit
|
|
577
|
+
});
|
|
578
|
+
return result;
|
|
579
|
+
} catch (e) {
|
|
580
|
+
if (e instanceof StorageError) {
|
|
581
|
+
return e;
|
|
582
|
+
}
|
|
583
|
+
return new StorageError({ reason: String(e), cause: e });
|
|
584
|
+
}
|
|
585
|
+
}
|
|
586
|
+
}
|
|
587
|
+
};
|
|
588
|
+
}
|
|
589
|
+
async function resolveStorageUrl(config) {
|
|
590
|
+
switch (config.type) {
|
|
591
|
+
case "local": {
|
|
592
|
+
const { startLocalStorage: startLocalStorage2 } = await Promise.resolve().then(() => (init_local(), local_exports));
|
|
593
|
+
return { url: await startLocalStorage2({ path: config.path }) };
|
|
594
|
+
}
|
|
595
|
+
case "vercel": {
|
|
596
|
+
const { getVercelStorageConfig: getVercelStorageConfig2 } = await Promise.resolve().then(() => (init_vercel(), vercel_exports));
|
|
597
|
+
return getVercelStorageConfig2();
|
|
598
|
+
}
|
|
599
|
+
case "custom": {
|
|
600
|
+
return { url: config.url, headers: config.headers };
|
|
601
|
+
}
|
|
602
|
+
default: {
|
|
603
|
+
config;
|
|
604
|
+
throw new Error(
|
|
605
|
+
`Unknown storage type: ${config.type}`
|
|
606
|
+
);
|
|
607
|
+
}
|
|
608
|
+
}
|
|
609
|
+
}
|
|
610
|
+
function getStorage(storageConfig) {
|
|
611
|
+
let clientPromise = null;
|
|
612
|
+
const getClient = () => {
|
|
613
|
+
if (!clientPromise) {
|
|
614
|
+
clientPromise = resolveStorageUrl(storageConfig).then(
|
|
615
|
+
(resolved) => getStorageClient(resolved)
|
|
616
|
+
);
|
|
617
|
+
}
|
|
618
|
+
return clientPromise;
|
|
619
|
+
};
|
|
620
|
+
return {
|
|
621
|
+
session: {
|
|
622
|
+
get: async (id) => (await getClient()).session.get(id),
|
|
623
|
+
set: async (session) => (await getClient()).session.set(session),
|
|
624
|
+
list: async (opts) => (await getClient()).session.list(opts),
|
|
625
|
+
tag: {
|
|
626
|
+
set: async (opts) => (await getClient()).session.tag.set(opts)
|
|
627
|
+
}
|
|
628
|
+
},
|
|
629
|
+
message: {
|
|
630
|
+
list: async (sessionId, opts) => (await getClient()).message.list(sessionId, opts),
|
|
631
|
+
get: async (id) => (await getClient()).message.get(id),
|
|
632
|
+
set: async (message) => (await getClient()).message.set(message)
|
|
633
|
+
},
|
|
634
|
+
part: {
|
|
635
|
+
listByMessage: async (messageId, opts) => (await getClient()).part.listByMessage(messageId, opts),
|
|
636
|
+
listBySession: async (sessionId, opts) => (await getClient()).part.listBySession(sessionId, opts),
|
|
637
|
+
set: async (part) => (await getClient()).part.set(part)
|
|
638
|
+
},
|
|
639
|
+
sandbox: {
|
|
640
|
+
get: async (key) => (await getClient()).sandbox.get(key),
|
|
641
|
+
set: async (opts) => (await getClient()).sandbox.set(opts),
|
|
642
|
+
getBySession: async (sessionId) => (await getClient()).sandbox.getBySession(sessionId)
|
|
643
|
+
},
|
|
644
|
+
command: {
|
|
645
|
+
get: async (id) => (await getClient()).command.get(id),
|
|
646
|
+
set: async (command) => (await getClient()).command.set(command),
|
|
647
|
+
list: async (sessionId, opts) => (await getClient()).command.list(sessionId, opts)
|
|
648
|
+
}
|
|
649
|
+
};
|
|
650
|
+
}
|
|
651
|
+
var init_client = __esm({
|
|
652
|
+
"src/storage/client.ts"() {
|
|
653
|
+
"use strict";
|
|
654
|
+
init_errors();
|
|
655
|
+
}
|
|
656
|
+
});
|
|
657
|
+
|
|
658
|
+
// src/storage/rpc.ts
|
|
659
|
+
function ListResultSchema(itemSchema) {
|
|
660
|
+
return import_zod.z.object({
|
|
661
|
+
items: import_zod.z.array(itemSchema),
|
|
662
|
+
nextCursor: import_zod.z.string().nullable()
|
|
663
|
+
});
|
|
664
|
+
}
|
|
665
|
+
var import_zod, VercelLifecycleConfigSchema, SandboxConfigSchema, SessionSchema, MessageSchema, PartSchema, CommandResultSchema, SandboxRecordSchema, CommandBaseSchema, CommandSchema, methods;
|
|
666
|
+
var init_rpc = __esm({
|
|
667
|
+
"src/storage/rpc.ts"() {
|
|
668
|
+
"use strict";
|
|
669
|
+
import_zod = require("zod");
|
|
670
|
+
VercelLifecycleConfigSchema = import_zod.z.object({
|
|
671
|
+
stopAfterInactiveMs: import_zod.z.number().optional(),
|
|
672
|
+
snapshotBeforeTimeoutMs: import_zod.z.number().optional(),
|
|
673
|
+
snapshotId: import_zod.z.string().optional(),
|
|
674
|
+
autoStart: import_zod.z.boolean().optional()
|
|
675
|
+
});
|
|
676
|
+
SandboxConfigSchema = import_zod.z.discriminatedUnion("type", [
|
|
677
|
+
import_zod.z.object({
|
|
678
|
+
type: import_zod.z.literal("vercel"),
|
|
679
|
+
resources: import_zod.z.object({ vcpus: import_zod.z.number() }).optional(),
|
|
680
|
+
ports: import_zod.z.array(import_zod.z.number()).optional(),
|
|
681
|
+
lifecycle: VercelLifecycleConfigSchema.optional()
|
|
682
|
+
}),
|
|
683
|
+
import_zod.z.object({
|
|
684
|
+
type: import_zod.z.literal("local"),
|
|
685
|
+
path: import_zod.z.string().optional()
|
|
686
|
+
}),
|
|
687
|
+
import_zod.z.object({
|
|
688
|
+
type: import_zod.z.literal("custom"),
|
|
689
|
+
url: import_zod.z.string(),
|
|
690
|
+
headers: import_zod.z.record(import_zod.z.string(), import_zod.z.string()).optional()
|
|
691
|
+
})
|
|
692
|
+
]);
|
|
693
|
+
SessionSchema = import_zod.z.object({
|
|
694
|
+
id: import_zod.z.string(),
|
|
695
|
+
createdAt: import_zod.z.number(),
|
|
696
|
+
updatedAt: import_zod.z.number(),
|
|
697
|
+
runId: import_zod.z.string().nullable(),
|
|
698
|
+
lastMessageId: import_zod.z.string().nullable(),
|
|
699
|
+
tags: import_zod.z.record(import_zod.z.string(), import_zod.z.unknown()).nullable(),
|
|
700
|
+
instructions: import_zod.z.string().nullable(),
|
|
701
|
+
model: import_zod.z.string().nullable(),
|
|
702
|
+
mcp: import_zod.z.unknown().nullable(),
|
|
703
|
+
// TODO
|
|
704
|
+
sandboxId: import_zod.z.string().nullable(),
|
|
705
|
+
skillsDir: import_zod.z.array(import_zod.z.string()).nullable(),
|
|
706
|
+
hookToken: import_zod.z.string().nullable()
|
|
707
|
+
});
|
|
708
|
+
MessageSchema = import_zod.z.object({
|
|
709
|
+
id: import_zod.z.string(),
|
|
710
|
+
sessionId: import_zod.z.string(),
|
|
711
|
+
role: import_zod.z.enum(["user", "assistant", "system"]),
|
|
712
|
+
createdAt: import_zod.z.number(),
|
|
713
|
+
completedAt: import_zod.z.number().nullable(),
|
|
714
|
+
mcpContext: import_zod.z.unknown().nullable()
|
|
715
|
+
});
|
|
716
|
+
PartSchema = import_zod.z.object({
|
|
717
|
+
id: import_zod.z.string(),
|
|
718
|
+
messageId: import_zod.z.string(),
|
|
719
|
+
sessionId: import_zod.z.string(),
|
|
720
|
+
index: import_zod.z.number(),
|
|
721
|
+
part: import_zod.z.unknown()
|
|
722
|
+
});
|
|
723
|
+
CommandResultSchema = import_zod.z.object({
|
|
724
|
+
stdout: import_zod.z.string(),
|
|
725
|
+
stderr: import_zod.z.string(),
|
|
726
|
+
exitCode: import_zod.z.number(),
|
|
727
|
+
completedAt: import_zod.z.number()
|
|
728
|
+
});
|
|
729
|
+
SandboxRecordSchema = import_zod.z.object({
|
|
730
|
+
id: import_zod.z.string(),
|
|
731
|
+
config: SandboxConfigSchema,
|
|
732
|
+
createdAt: import_zod.z.number().nullable(),
|
|
733
|
+
lastActivityAt: import_zod.z.number().nullable(),
|
|
734
|
+
acquiringLockId: import_zod.z.string().nullable(),
|
|
735
|
+
acquiringLockAt: import_zod.z.number().nullable(),
|
|
736
|
+
providerMetadata: import_zod.z.discriminatedUnion("provider", [
|
|
737
|
+
import_zod.z.object({
|
|
738
|
+
provider: import_zod.z.literal("vercel"),
|
|
739
|
+
sandboxId: import_zod.z.string().nullable(),
|
|
740
|
+
snapshotId: import_zod.z.string().nullable()
|
|
741
|
+
})
|
|
742
|
+
]).optional()
|
|
743
|
+
});
|
|
744
|
+
CommandBaseSchema = import_zod.z.object({
|
|
745
|
+
id: import_zod.z.string(),
|
|
746
|
+
sessionId: import_zod.z.string(),
|
|
747
|
+
command: import_zod.z.string(),
|
|
748
|
+
args: import_zod.z.array(import_zod.z.string()).optional(),
|
|
749
|
+
startedAt: import_zod.z.number()
|
|
750
|
+
});
|
|
751
|
+
CommandSchema = import_zod.z.discriminatedUnion("status", [
|
|
752
|
+
CommandBaseSchema.extend({ status: import_zod.z.literal("running") }),
|
|
753
|
+
CommandBaseSchema.extend({
|
|
754
|
+
status: import_zod.z.literal("completed"),
|
|
755
|
+
result: CommandResultSchema
|
|
756
|
+
}),
|
|
757
|
+
CommandBaseSchema.extend({
|
|
758
|
+
status: import_zod.z.literal("killed"),
|
|
759
|
+
result: CommandResultSchema.optional()
|
|
760
|
+
}),
|
|
761
|
+
CommandBaseSchema.extend({
|
|
762
|
+
status: import_zod.z.literal("failed"),
|
|
763
|
+
result: CommandResultSchema
|
|
764
|
+
})
|
|
765
|
+
]);
|
|
766
|
+
methods = {
|
|
767
|
+
"session.get": {
|
|
768
|
+
params: import_zod.z.object({ id: import_zod.z.string() }),
|
|
769
|
+
result: SessionSchema.nullable()
|
|
770
|
+
},
|
|
771
|
+
"session.set": {
|
|
772
|
+
params: SessionSchema,
|
|
773
|
+
result: SessionSchema
|
|
774
|
+
},
|
|
775
|
+
"session.list": {
|
|
776
|
+
params: import_zod.z.object({
|
|
777
|
+
tags: import_zod.z.record(import_zod.z.string(), import_zod.z.unknown()).optional(),
|
|
778
|
+
order: import_zod.z.enum([
|
|
779
|
+
"createdAt_asc",
|
|
780
|
+
"createdAt_desc",
|
|
781
|
+
"updatedAt_asc",
|
|
782
|
+
"updatedAt_desc"
|
|
783
|
+
]).optional(),
|
|
784
|
+
cursor: import_zod.z.string().optional(),
|
|
785
|
+
limit: import_zod.z.number().optional()
|
|
786
|
+
}),
|
|
787
|
+
result: ListResultSchema(SessionSchema)
|
|
788
|
+
},
|
|
789
|
+
"session.listBySandbox": {
|
|
790
|
+
params: import_zod.z.object({
|
|
791
|
+
sandboxId: import_zod.z.string(),
|
|
792
|
+
tags: import_zod.z.record(import_zod.z.string(), import_zod.z.unknown()).optional(),
|
|
793
|
+
order: import_zod.z.enum([
|
|
794
|
+
"createdAt_asc",
|
|
795
|
+
"createdAt_desc",
|
|
796
|
+
"updatedAt_asc",
|
|
797
|
+
"updatedAt_desc"
|
|
798
|
+
]).optional(),
|
|
799
|
+
cursor: import_zod.z.string().optional(),
|
|
800
|
+
limit: import_zod.z.number().optional()
|
|
801
|
+
}),
|
|
802
|
+
result: ListResultSchema(SessionSchema)
|
|
803
|
+
},
|
|
804
|
+
"session.tag.set": {
|
|
805
|
+
params: import_zod.z.object({
|
|
806
|
+
sessionId: import_zod.z.string(),
|
|
807
|
+
tags: import_zod.z.record(import_zod.z.string(), import_zod.z.unknown())
|
|
808
|
+
}),
|
|
809
|
+
result: SessionSchema
|
|
810
|
+
},
|
|
811
|
+
"message.get": {
|
|
812
|
+
params: import_zod.z.object({ id: import_zod.z.string() }),
|
|
813
|
+
result: MessageSchema.nullable()
|
|
814
|
+
},
|
|
815
|
+
"message.set": {
|
|
816
|
+
params: MessageSchema,
|
|
817
|
+
result: MessageSchema
|
|
818
|
+
},
|
|
819
|
+
"message.list": {
|
|
820
|
+
params: import_zod.z.object({
|
|
821
|
+
sessionId: import_zod.z.string(),
|
|
822
|
+
cursor: import_zod.z.string().optional(),
|
|
823
|
+
limit: import_zod.z.number().optional()
|
|
824
|
+
}),
|
|
825
|
+
result: ListResultSchema(MessageSchema)
|
|
826
|
+
},
|
|
827
|
+
"part.listByMessage": {
|
|
828
|
+
params: import_zod.z.object({
|
|
829
|
+
messageId: import_zod.z.string(),
|
|
830
|
+
cursor: import_zod.z.string().optional(),
|
|
831
|
+
limit: import_zod.z.number().optional()
|
|
832
|
+
}),
|
|
833
|
+
result: ListResultSchema(PartSchema)
|
|
834
|
+
},
|
|
835
|
+
"part.listBySession": {
|
|
836
|
+
params: import_zod.z.object({
|
|
837
|
+
sessionId: import_zod.z.string(),
|
|
838
|
+
cursor: import_zod.z.string().optional(),
|
|
839
|
+
limit: import_zod.z.number().optional()
|
|
840
|
+
}),
|
|
841
|
+
result: ListResultSchema(PartSchema)
|
|
842
|
+
},
|
|
843
|
+
"part.set": {
|
|
844
|
+
params: PartSchema,
|
|
845
|
+
result: PartSchema
|
|
846
|
+
},
|
|
847
|
+
"sandbox.get": {
|
|
848
|
+
params: import_zod.z.object({ key: import_zod.z.string() }),
|
|
849
|
+
result: SandboxRecordSchema.nullable()
|
|
850
|
+
},
|
|
851
|
+
"sandbox.getBySession": {
|
|
852
|
+
params: import_zod.z.object({ sessionId: import_zod.z.string() }),
|
|
853
|
+
result: SandboxRecordSchema.nullable()
|
|
854
|
+
},
|
|
855
|
+
"sandbox.set": {
|
|
856
|
+
params: SandboxRecordSchema,
|
|
857
|
+
result: import_zod.z.void()
|
|
858
|
+
},
|
|
859
|
+
"command.get": {
|
|
860
|
+
params: import_zod.z.object({ id: import_zod.z.string() }),
|
|
861
|
+
result: CommandSchema.nullable()
|
|
862
|
+
},
|
|
863
|
+
"command.set": {
|
|
864
|
+
params: CommandSchema,
|
|
865
|
+
result: CommandSchema
|
|
866
|
+
},
|
|
867
|
+
"command.list": {
|
|
868
|
+
params: import_zod.z.object({
|
|
869
|
+
sessionId: import_zod.z.string(),
|
|
870
|
+
includeFinished: import_zod.z.boolean().optional(),
|
|
871
|
+
cursor: import_zod.z.string().optional(),
|
|
872
|
+
limit: import_zod.z.number().optional()
|
|
873
|
+
}),
|
|
874
|
+
result: ListResultSchema(CommandSchema)
|
|
875
|
+
}
|
|
876
|
+
};
|
|
877
|
+
}
|
|
878
|
+
});
|
|
879
|
+
|
|
880
|
+
// src/storage/handler.ts
|
|
881
|
+
async function handleStorageRpc(body, handlers) {
|
|
882
|
+
const { method, params } = body;
|
|
883
|
+
if (!(method in methods)) {
|
|
884
|
+
return {
|
|
885
|
+
error: { code: "METHOD_NOT_FOUND", message: `Unknown method: ${method}` }
|
|
886
|
+
};
|
|
887
|
+
}
|
|
888
|
+
const methodName = method;
|
|
889
|
+
const schema = methods[methodName].params;
|
|
890
|
+
const parsed = schema.safeParse(params);
|
|
891
|
+
if (!parsed.success) {
|
|
892
|
+
return {
|
|
893
|
+
error: {
|
|
894
|
+
code: "INVALID_PARAMS",
|
|
895
|
+
message: parsed.error.issues.map((i) => `${i.path.join(".")}: ${i.message}`).join(", ")
|
|
896
|
+
}
|
|
897
|
+
};
|
|
898
|
+
}
|
|
899
|
+
try {
|
|
900
|
+
const handler = handlers[methodName];
|
|
901
|
+
const result = await handler(parsed.data);
|
|
902
|
+
return { result };
|
|
903
|
+
} catch (e) {
|
|
904
|
+
return {
|
|
905
|
+
error: {
|
|
906
|
+
code: "INTERNAL_ERROR",
|
|
907
|
+
message: e instanceof Error ? e.message : String(e)
|
|
908
|
+
}
|
|
909
|
+
};
|
|
910
|
+
}
|
|
911
|
+
}
|
|
912
|
+
var init_handler = __esm({
|
|
913
|
+
"src/storage/handler.ts"() {
|
|
914
|
+
"use strict";
|
|
915
|
+
init_rpc();
|
|
916
|
+
}
|
|
917
|
+
});
|
|
918
|
+
|
|
919
|
+
// src/storage/index.ts
|
|
920
|
+
var storage_exports = {};
|
|
921
|
+
__export(storage_exports, {
|
|
922
|
+
CommandResultSchema: () => CommandResultSchema,
|
|
923
|
+
CommandSchema: () => CommandSchema,
|
|
924
|
+
MessageSchema: () => MessageSchema,
|
|
925
|
+
PartSchema: () => PartSchema,
|
|
926
|
+
SandboxConfigSchema: () => SandboxConfigSchema,
|
|
927
|
+
SandboxRecordSchema: () => SandboxRecordSchema,
|
|
928
|
+
SessionSchema: () => SessionSchema,
|
|
929
|
+
getStorage: () => getStorage,
|
|
930
|
+
handleStorageRpc: () => handleStorageRpc,
|
|
931
|
+
methods: () => methods
|
|
932
|
+
});
|
|
933
|
+
var init_storage = __esm({
|
|
934
|
+
"src/storage/index.ts"() {
|
|
935
|
+
"use strict";
|
|
936
|
+
init_client();
|
|
937
|
+
init_handler();
|
|
938
|
+
init_rpc();
|
|
939
|
+
}
|
|
940
|
+
});
|
|
941
|
+
|
|
942
|
+
// src/sandbox/write-files.ts
|
|
943
|
+
async function writeFiles(opts) {
|
|
944
|
+
const { sandbox, files, destPath } = opts;
|
|
945
|
+
if (files.length === 0) {
|
|
946
|
+
return;
|
|
947
|
+
}
|
|
948
|
+
const filePaths = files.map((file) => path.posix.join(destPath, file.path));
|
|
949
|
+
const parentDirs = [...new Set(filePaths.map((p) => path.posix.dirname(p)))];
|
|
950
|
+
const shellScripts = filePaths.filter((p) => p.endsWith(".sh"));
|
|
951
|
+
const mkdirResult = await sandbox.exec({
|
|
952
|
+
command: "mkdir",
|
|
953
|
+
args: ["-p", ...parentDirs]
|
|
954
|
+
});
|
|
955
|
+
if (mkdirResult instanceof Error) {
|
|
956
|
+
throw mkdirResult;
|
|
957
|
+
}
|
|
958
|
+
await mkdirResult.result;
|
|
959
|
+
const CHUNK_SIZE = 5e4;
|
|
960
|
+
for (let i = 0; i < files.length; i++) {
|
|
961
|
+
const file = files[i];
|
|
962
|
+
const fullPath = filePaths[i];
|
|
963
|
+
const base64Content = toBase64(file.content);
|
|
964
|
+
if (base64Content.length < CHUNK_SIZE) {
|
|
965
|
+
const marker = `EOF_${i}`;
|
|
966
|
+
const execResult = await sandbox.exec({
|
|
967
|
+
command: "bash",
|
|
968
|
+
args: [
|
|
969
|
+
"-c",
|
|
970
|
+
`base64 -d > ${quote(fullPath)} << '${marker}'
|
|
971
|
+
${base64Content}
|
|
972
|
+
${marker}`
|
|
973
|
+
]
|
|
974
|
+
});
|
|
975
|
+
if (execResult instanceof Error) {
|
|
976
|
+
throw execResult;
|
|
977
|
+
}
|
|
978
|
+
const { exitCode, stderr } = await execResult.result;
|
|
979
|
+
if (exitCode !== 0) {
|
|
980
|
+
throw new Error(
|
|
981
|
+
`writeFiles failed with exit code ${exitCode}: ${stderr}`
|
|
982
|
+
);
|
|
983
|
+
}
|
|
984
|
+
} else {
|
|
985
|
+
const tempB64 = `/tmp/chunk-${Date.now()}-${i}.b64`;
|
|
986
|
+
const clearResult = await sandbox.exec({
|
|
987
|
+
command: "bash",
|
|
988
|
+
args: ["-c", `> ${quote(tempB64)}`]
|
|
989
|
+
});
|
|
990
|
+
if (clearResult instanceof Error) {
|
|
991
|
+
throw clearResult;
|
|
992
|
+
}
|
|
993
|
+
await clearResult.result;
|
|
994
|
+
for (let offset = 0; offset < base64Content.length; offset += CHUNK_SIZE) {
|
|
995
|
+
const chunk = base64Content.slice(offset, offset + CHUNK_SIZE);
|
|
996
|
+
const marker = `CHUNK_${offset}`;
|
|
997
|
+
const appendResult = await sandbox.exec({
|
|
998
|
+
command: "bash",
|
|
999
|
+
args: [
|
|
1000
|
+
"-c",
|
|
1001
|
+
`cat >> ${quote(tempB64)} << '${marker}'
|
|
1002
|
+
${chunk}
|
|
1003
|
+
${marker}`
|
|
1004
|
+
]
|
|
1005
|
+
});
|
|
1006
|
+
if (appendResult instanceof Error) {
|
|
1007
|
+
throw appendResult;
|
|
1008
|
+
}
|
|
1009
|
+
const { exitCode: exitCode2, stderr: stderr2 } = await appendResult.result;
|
|
1010
|
+
if (exitCode2 !== 0) {
|
|
1011
|
+
throw new Error(
|
|
1012
|
+
`writeFiles chunk failed with exit code ${exitCode2}: ${stderr2}`
|
|
1013
|
+
);
|
|
1014
|
+
}
|
|
1015
|
+
}
|
|
1016
|
+
const decodeResult = await sandbox.exec({
|
|
1017
|
+
command: "bash",
|
|
1018
|
+
args: [
|
|
1019
|
+
"-c",
|
|
1020
|
+
`base64 -d < ${quote(tempB64)} > ${quote(fullPath)} && rm -f ${quote(tempB64)}`
|
|
1021
|
+
]
|
|
1022
|
+
});
|
|
1023
|
+
if (decodeResult instanceof Error) {
|
|
1024
|
+
throw decodeResult;
|
|
1025
|
+
}
|
|
1026
|
+
const { exitCode, stderr } = await decodeResult.result;
|
|
1027
|
+
if (exitCode !== 0) {
|
|
1028
|
+
throw new Error(
|
|
1029
|
+
`writeFiles decode failed with exit code ${exitCode}: ${stderr}`
|
|
1030
|
+
);
|
|
1031
|
+
}
|
|
1032
|
+
}
|
|
1033
|
+
}
|
|
1034
|
+
if (shellScripts.length > 0) {
|
|
1035
|
+
const chmodResult = await sandbox.exec({
|
|
1036
|
+
command: "chmod",
|
|
1037
|
+
args: ["+x", ...shellScripts]
|
|
1038
|
+
});
|
|
1039
|
+
if (chmodResult instanceof Error) {
|
|
1040
|
+
throw chmodResult;
|
|
1041
|
+
}
|
|
1042
|
+
await chmodResult.result;
|
|
1043
|
+
}
|
|
1044
|
+
}
|
|
1045
|
+
function toBase64(content) {
|
|
1046
|
+
if (typeof content === "string") {
|
|
1047
|
+
return Buffer.from(content).toString("base64");
|
|
1048
|
+
}
|
|
1049
|
+
return content.toString("base64");
|
|
1050
|
+
}
|
|
1051
|
+
function quote(s) {
|
|
1052
|
+
return `'${s.replace(/'/g, "'\\''")}'`;
|
|
1053
|
+
}
|
|
1054
|
+
var path;
|
|
1055
|
+
var init_write_files = __esm({
|
|
1056
|
+
"src/sandbox/write-files.ts"() {
|
|
1057
|
+
"use strict";
|
|
1058
|
+
path = __toESM(require("path"));
|
|
1059
|
+
}
|
|
1060
|
+
});
|
|
1061
|
+
|
|
1062
|
+
// src/sandbox/bindings/local.ts
|
|
1063
|
+
var import_node_child_process, errore2, import_ulid, localSandbox;
|
|
1064
|
+
var init_local2 = __esm({
|
|
1065
|
+
"src/sandbox/bindings/local.ts"() {
|
|
1066
|
+
"use strict";
|
|
1067
|
+
import_node_child_process = require("child_process");
|
|
1068
|
+
errore2 = __toESM(require("errore"));
|
|
1069
|
+
import_ulid = require("ulid");
|
|
1070
|
+
init_errors();
|
|
1071
|
+
init_write_files();
|
|
1072
|
+
localSandbox = ({
|
|
1073
|
+
sandboxRecord
|
|
1074
|
+
}) => {
|
|
1075
|
+
const config = sandboxRecord.config;
|
|
1076
|
+
const basePath = config.path ?? process.cwd();
|
|
1077
|
+
const processes = /* @__PURE__ */ new Map();
|
|
1078
|
+
const sandbox = {
|
|
1079
|
+
id: sandboxRecord.id,
|
|
1080
|
+
config: sandboxRecord.config,
|
|
1081
|
+
exec: ({ command, args, signal }) => {
|
|
1082
|
+
return errore2.tryAsync({
|
|
1083
|
+
try: () => {
|
|
1084
|
+
const commandId = `command_${(0, import_ulid.ulid)()}`;
|
|
1085
|
+
const child = (0, import_node_child_process.spawn)(command, args, {
|
|
1086
|
+
cwd: basePath,
|
|
1087
|
+
signal
|
|
1088
|
+
});
|
|
1089
|
+
processes.set(commandId, child);
|
|
1090
|
+
let stdout = "";
|
|
1091
|
+
let stderr = "";
|
|
1092
|
+
const logQueue = [];
|
|
1093
|
+
let logResolve = null;
|
|
1094
|
+
let closed = false;
|
|
1095
|
+
child.stdout.on("data", (data) => {
|
|
1096
|
+
const str = String(data);
|
|
1097
|
+
stdout += str;
|
|
1098
|
+
logQueue.push({ stream: "stdout", data: str });
|
|
1099
|
+
logResolve?.();
|
|
1100
|
+
});
|
|
1101
|
+
child.stderr.on("data", (data) => {
|
|
1102
|
+
const str = String(data);
|
|
1103
|
+
stderr += str;
|
|
1104
|
+
logQueue.push({ stream: "stderr", data: str });
|
|
1105
|
+
logResolve?.();
|
|
1106
|
+
});
|
|
1107
|
+
const result = new Promise((resolve, reject) => {
|
|
1108
|
+
child.on("error", (err) => {
|
|
1109
|
+
processes.delete(commandId);
|
|
1110
|
+
closed = true;
|
|
1111
|
+
logResolve?.();
|
|
1112
|
+
reject(err);
|
|
1113
|
+
});
|
|
1114
|
+
child.on("close", (code) => {
|
|
1115
|
+
processes.delete(commandId);
|
|
1116
|
+
closed = true;
|
|
1117
|
+
logResolve?.();
|
|
1118
|
+
resolve({ stdout, stderr, exitCode: code ?? 0 });
|
|
1119
|
+
});
|
|
1120
|
+
});
|
|
1121
|
+
async function* logs() {
|
|
1122
|
+
while (!closed || logQueue.length > 0) {
|
|
1123
|
+
const entry = logQueue.shift();
|
|
1124
|
+
if (entry) {
|
|
1125
|
+
yield entry;
|
|
1126
|
+
} else if (!closed) {
|
|
1127
|
+
await new Promise((resolve) => {
|
|
1128
|
+
logResolve = resolve;
|
|
1129
|
+
});
|
|
1130
|
+
logResolve = null;
|
|
1131
|
+
}
|
|
1132
|
+
}
|
|
1133
|
+
}
|
|
1134
|
+
return Promise.resolve({ commandId, logs, result });
|
|
1135
|
+
},
|
|
1136
|
+
catch: (e) => new SandboxError({ reason: String(e), cause: e })
|
|
1137
|
+
});
|
|
1138
|
+
},
|
|
1139
|
+
getDomain: (port) => {
|
|
1140
|
+
return Promise.resolve(`http://localhost:${port}`);
|
|
1141
|
+
},
|
|
1142
|
+
kill: async ({ commandId, storage }) => {
|
|
1143
|
+
const child = processes.get(commandId);
|
|
1144
|
+
if (!child) {
|
|
1145
|
+
return new SandboxError({
|
|
1146
|
+
reason: `Command ${commandId} not found or already finished`
|
|
1147
|
+
});
|
|
1148
|
+
}
|
|
1149
|
+
child.kill("SIGTERM");
|
|
1150
|
+
const cmd = await storage.command.get(commandId);
|
|
1151
|
+
if (cmd instanceof Error) {
|
|
1152
|
+
return new SandboxError({ reason: cmd.message, cause: cmd });
|
|
1153
|
+
}
|
|
1154
|
+
if (cmd && cmd.status === "running") {
|
|
1155
|
+
const result = await storage.command.set({
|
|
1156
|
+
...cmd,
|
|
1157
|
+
status: "killed"
|
|
1158
|
+
});
|
|
1159
|
+
if (result instanceof Error) {
|
|
1160
|
+
return new SandboxError({ reason: result.message, cause: result });
|
|
1161
|
+
}
|
|
1162
|
+
}
|
|
1163
|
+
},
|
|
1164
|
+
writeFiles: (opts) => writeFiles({ sandbox, ...opts })
|
|
1165
|
+
};
|
|
1166
|
+
return sandbox;
|
|
1167
|
+
};
|
|
1168
|
+
}
|
|
1169
|
+
});
|
|
1170
|
+
|
|
1171
|
+
// src/sandbox/bindings/vercel.ts
|
|
1172
|
+
var errore3, import_sandbox, VERCEL_MAX_TIMEOUT_MS, LOCK_TIMEOUT_MS, LOCK_POLL_INTERVAL_MS, getTestCredentials, createPromises, ACTIVITY_THROTTLE_MS, lastActivitySent, DEFAULT_VCPUS, vercelSandbox;
|
|
1173
|
+
var init_vercel2 = __esm({
|
|
1174
|
+
"src/sandbox/bindings/vercel.ts"() {
|
|
1175
|
+
"use strict";
|
|
1176
|
+
errore3 = __toESM(require("errore"));
|
|
1177
|
+
import_sandbox = require("sandbox");
|
|
1178
|
+
init_errors();
|
|
1179
|
+
init_storage();
|
|
1180
|
+
init_write_files();
|
|
1181
|
+
VERCEL_MAX_TIMEOUT_MS = 5 * 60 * 60 * 1e3;
|
|
1182
|
+
LOCK_TIMEOUT_MS = 3e4;
|
|
1183
|
+
LOCK_POLL_INTERVAL_MS = 200;
|
|
1184
|
+
getTestCredentials = () => process.env.NODE_ENV === "test" ? {
|
|
1185
|
+
token: process.env.TEST_VERCEL_TOKEN,
|
|
1186
|
+
teamId: process.env.TEST_VERCEL_TEAM_ID,
|
|
1187
|
+
projectId: process.env.TEST_VERCEL_PROJECT_ID
|
|
1188
|
+
} : {};
|
|
1189
|
+
createPromises = /* @__PURE__ */ new Map();
|
|
1190
|
+
ACTIVITY_THROTTLE_MS = 1e4;
|
|
1191
|
+
lastActivitySent = /* @__PURE__ */ new Map();
|
|
1192
|
+
DEFAULT_VCPUS = 2;
|
|
1193
|
+
vercelSandbox = ({
|
|
1194
|
+
sandboxRecord,
|
|
1195
|
+
storageConfig,
|
|
1196
|
+
enableLifecycleWorkflow = true,
|
|
1197
|
+
storage: storageOverride
|
|
1198
|
+
}) => {
|
|
1199
|
+
const { id, config } = sandboxRecord;
|
|
1200
|
+
const vcpus = config.resources?.vcpus ?? DEFAULT_VCPUS;
|
|
1201
|
+
const ports = config.ports;
|
|
1202
|
+
const storage = storageOverride ?? getStorage(storageConfig);
|
|
1203
|
+
const initialVercel = sandboxRecord.providerMetadata?.provider === "vercel" ? sandboxRecord.providerMetadata : null;
|
|
1204
|
+
let sandboxPromise = null;
|
|
1205
|
+
async function pollForSandboxId() {
|
|
1206
|
+
const deadline = Date.now() + LOCK_TIMEOUT_MS;
|
|
1207
|
+
while (Date.now() < deadline) {
|
|
1208
|
+
await new Promise((r) => setTimeout(r, LOCK_POLL_INTERVAL_MS));
|
|
1209
|
+
const record = await storage.sandbox.get(id);
|
|
1210
|
+
if (record instanceof Error) {
|
|
1211
|
+
return new SandboxError({ reason: record.message, cause: record });
|
|
1212
|
+
}
|
|
1213
|
+
const vercelSandboxId = record?.providerMetadata?.provider === "vercel" ? record.providerMetadata.sandboxId : null;
|
|
1214
|
+
if (vercelSandboxId) {
|
|
1215
|
+
return vercelSandboxId;
|
|
1216
|
+
}
|
|
1217
|
+
if (!record?.acquiringLockAt) {
|
|
1218
|
+
break;
|
|
1219
|
+
}
|
|
1220
|
+
}
|
|
1221
|
+
return new SandboxError({
|
|
1222
|
+
reason: "Timed out waiting for sandbox creation by another process"
|
|
1223
|
+
});
|
|
1224
|
+
}
|
|
1225
|
+
async function createSandboxFromSnapshot(snapshotId) {
|
|
1226
|
+
return await errore3.tryAsync({
|
|
1227
|
+
try: async () => {
|
|
1228
|
+
const sandbox2 = await import_sandbox.Sandbox.create({
|
|
1229
|
+
source: { type: "snapshot", snapshotId },
|
|
1230
|
+
resources: { vcpus },
|
|
1231
|
+
timeout: VERCEL_MAX_TIMEOUT_MS,
|
|
1232
|
+
ports,
|
|
1233
|
+
...getTestCredentials()
|
|
1234
|
+
});
|
|
1235
|
+
const now = Date.now();
|
|
1236
|
+
await storage.sandbox.set({
|
|
1237
|
+
id,
|
|
1238
|
+
config,
|
|
1239
|
+
createdAt: now,
|
|
1240
|
+
lastActivityAt: now,
|
|
1241
|
+
acquiringLockId: null,
|
|
1242
|
+
acquiringLockAt: null,
|
|
1243
|
+
providerMetadata: {
|
|
1244
|
+
provider: "vercel",
|
|
1245
|
+
sandboxId: sandbox2.sandboxId,
|
|
1246
|
+
snapshotId
|
|
1247
|
+
}
|
|
1248
|
+
});
|
|
1249
|
+
return sandbox2.sandboxId;
|
|
1250
|
+
},
|
|
1251
|
+
catch: (e) => new SandboxError({ reason: String(e), cause: e })
|
|
1252
|
+
});
|
|
1253
|
+
}
|
|
1254
|
+
async function createFreshSandbox() {
|
|
1255
|
+
return await errore3.tryAsync({
|
|
1256
|
+
try: async () => {
|
|
1257
|
+
const sandbox2 = await import_sandbox.Sandbox.create({
|
|
1258
|
+
resources: { vcpus },
|
|
1259
|
+
timeout: VERCEL_MAX_TIMEOUT_MS,
|
|
1260
|
+
ports,
|
|
1261
|
+
...getTestCredentials()
|
|
1262
|
+
});
|
|
1263
|
+
const now = Date.now();
|
|
1264
|
+
await storage.sandbox.set({
|
|
1265
|
+
id,
|
|
1266
|
+
config,
|
|
1267
|
+
createdAt: now,
|
|
1268
|
+
lastActivityAt: now,
|
|
1269
|
+
acquiringLockId: null,
|
|
1270
|
+
acquiringLockAt: null,
|
|
1271
|
+
providerMetadata: {
|
|
1272
|
+
provider: "vercel",
|
|
1273
|
+
sandboxId: sandbox2.sandboxId,
|
|
1274
|
+
snapshotId: null
|
|
1275
|
+
}
|
|
1276
|
+
});
|
|
1277
|
+
return sandbox2.sandboxId;
|
|
1278
|
+
},
|
|
1279
|
+
catch: (e) => new SandboxError({ reason: String(e), cause: e })
|
|
1280
|
+
});
|
|
1281
|
+
}
|
|
1282
|
+
async function doGetOrCreateSandboxId() {
|
|
1283
|
+
if (initialVercel?.sandboxId) {
|
|
1284
|
+
return initialVercel.sandboxId;
|
|
1285
|
+
}
|
|
1286
|
+
const existing = await storage.sandbox.get(id);
|
|
1287
|
+
if (existing instanceof Error) {
|
|
1288
|
+
return new SandboxError({ reason: existing.message, cause: existing });
|
|
1289
|
+
}
|
|
1290
|
+
const existingVercel = existing?.providerMetadata?.provider === "vercel" ? existing.providerMetadata : null;
|
|
1291
|
+
if (existingVercel?.sandboxId) {
|
|
1292
|
+
return existingVercel.sandboxId;
|
|
1293
|
+
}
|
|
1294
|
+
const hasActiveLock = existing?.acquiringLockId && existing.acquiringLockAt && Date.now() - existing.acquiringLockAt < LOCK_TIMEOUT_MS;
|
|
1295
|
+
if (hasActiveLock) {
|
|
1296
|
+
return pollForSandboxId();
|
|
1297
|
+
}
|
|
1298
|
+
const lockId = crypto.randomUUID();
|
|
1299
|
+
const now = Date.now();
|
|
1300
|
+
await storage.sandbox.set({
|
|
1301
|
+
id,
|
|
1302
|
+
config,
|
|
1303
|
+
createdAt: existing?.createdAt ?? sandboxRecord.createdAt,
|
|
1304
|
+
lastActivityAt: existing?.lastActivityAt ?? sandboxRecord.lastActivityAt,
|
|
1305
|
+
acquiringLockId: lockId,
|
|
1306
|
+
acquiringLockAt: now,
|
|
1307
|
+
providerMetadata: {
|
|
1308
|
+
provider: "vercel",
|
|
1309
|
+
sandboxId: null,
|
|
1310
|
+
snapshotId: existingVercel?.snapshotId ?? initialVercel?.snapshotId ?? null
|
|
1311
|
+
}
|
|
1312
|
+
});
|
|
1313
|
+
const afterLock = await storage.sandbox.get(id);
|
|
1314
|
+
if (afterLock instanceof Error) {
|
|
1315
|
+
return new SandboxError({ reason: afterLock.message, cause: afterLock });
|
|
1316
|
+
}
|
|
1317
|
+
if (afterLock?.acquiringLockId !== lockId) {
|
|
1318
|
+
return pollForSandboxId();
|
|
1319
|
+
}
|
|
1320
|
+
const snapshotId = existingVercel?.snapshotId ?? initialVercel?.snapshotId ?? config.lifecycle?.snapshotId;
|
|
1321
|
+
if (snapshotId) {
|
|
1322
|
+
const result = await createSandboxFromSnapshot(snapshotId);
|
|
1323
|
+
if (!(result instanceof Error)) {
|
|
1324
|
+
return result;
|
|
1325
|
+
}
|
|
1326
|
+
}
|
|
1327
|
+
return createFreshSandbox();
|
|
1328
|
+
}
|
|
1329
|
+
function getOrCreateSandboxId() {
|
|
1330
|
+
const cached = createPromises.get(id);
|
|
1331
|
+
if (cached) {
|
|
1332
|
+
return cached;
|
|
1333
|
+
}
|
|
1334
|
+
const promise = doGetOrCreateSandboxId().finally(() => {
|
|
1335
|
+
createPromises.delete(id);
|
|
1336
|
+
});
|
|
1337
|
+
createPromises.set(id, promise);
|
|
1338
|
+
return promise;
|
|
1339
|
+
}
|
|
1340
|
+
async function doGetSandbox() {
|
|
1341
|
+
const vercelSandboxId = await getOrCreateSandboxId();
|
|
1342
|
+
if (vercelSandboxId instanceof Error) {
|
|
1343
|
+
return vercelSandboxId;
|
|
1344
|
+
}
|
|
1345
|
+
return errore3.tryAsync({
|
|
1346
|
+
try: () => import_sandbox.Sandbox.get({
|
|
1347
|
+
sandboxId: vercelSandboxId,
|
|
1348
|
+
...getTestCredentials()
|
|
1349
|
+
}),
|
|
1350
|
+
catch: (e) => new SandboxError({ reason: String(e), cause: e })
|
|
1351
|
+
});
|
|
1352
|
+
}
|
|
1353
|
+
function getSandbox2() {
|
|
1354
|
+
if (!sandboxPromise) {
|
|
1355
|
+
sandboxPromise = doGetSandbox();
|
|
1356
|
+
}
|
|
1357
|
+
return sandboxPromise;
|
|
1358
|
+
}
|
|
1359
|
+
async function updateLastActivity() {
|
|
1360
|
+
const now = Date.now();
|
|
1361
|
+
const lastSent = lastActivitySent.get(id);
|
|
1362
|
+
if (lastSent && now - lastSent < ACTIVITY_THROTTLE_MS) {
|
|
1363
|
+
return;
|
|
1364
|
+
}
|
|
1365
|
+
lastActivitySent.set(id, now);
|
|
1366
|
+
const existing = await storage.sandbox.get(id);
|
|
1367
|
+
if (existing instanceof Error || !existing) {
|
|
1368
|
+
return;
|
|
1369
|
+
}
|
|
1370
|
+
const existingVercel = existing.providerMetadata?.provider === "vercel" ? existing.providerMetadata : null;
|
|
1371
|
+
await storage.sandbox.set({
|
|
1372
|
+
id: existing.id,
|
|
1373
|
+
config: existing.config,
|
|
1374
|
+
createdAt: existing.createdAt,
|
|
1375
|
+
lastActivityAt: now,
|
|
1376
|
+
acquiringLockId: null,
|
|
1377
|
+
acquiringLockAt: null,
|
|
1378
|
+
providerMetadata: existingVercel ?? {
|
|
1379
|
+
provider: "vercel",
|
|
1380
|
+
sandboxId: null,
|
|
1381
|
+
snapshotId: null
|
|
1382
|
+
}
|
|
1383
|
+
});
|
|
1384
|
+
if (enableLifecycleWorkflow) {
|
|
1385
|
+
}
|
|
1386
|
+
}
|
|
1387
|
+
const lifecycle = {
|
|
1388
|
+
start: async () => {
|
|
1389
|
+
const sandbox2 = await getSandbox2();
|
|
1390
|
+
if (sandbox2 instanceof Error) {
|
|
1391
|
+
return sandbox2;
|
|
1392
|
+
}
|
|
1393
|
+
await updateLastActivity();
|
|
1394
|
+
return sandbox2.status;
|
|
1395
|
+
},
|
|
1396
|
+
snapshot: async () => {
|
|
1397
|
+
const sandbox2 = await getSandbox2();
|
|
1398
|
+
if (sandbox2 instanceof Error) {
|
|
1399
|
+
return sandbox2;
|
|
1400
|
+
}
|
|
1401
|
+
return errore3.tryAsync({
|
|
1402
|
+
try: async () => {
|
|
1403
|
+
const existing = await storage.sandbox.get(id);
|
|
1404
|
+
const snapshot = await sandbox2.snapshot();
|
|
1405
|
+
await storage.sandbox.set({
|
|
1406
|
+
id,
|
|
1407
|
+
config,
|
|
1408
|
+
createdAt: existing instanceof Error ? null : existing?.createdAt ?? null,
|
|
1409
|
+
lastActivityAt: existing instanceof Error ? null : existing?.lastActivityAt ?? null,
|
|
1410
|
+
acquiringLockId: null,
|
|
1411
|
+
acquiringLockAt: null,
|
|
1412
|
+
providerMetadata: {
|
|
1413
|
+
provider: "vercel",
|
|
1414
|
+
sandboxId: null,
|
|
1415
|
+
snapshotId: snapshot.snapshotId
|
|
1416
|
+
}
|
|
1417
|
+
});
|
|
1418
|
+
return { snapshotId: snapshot.snapshotId };
|
|
1419
|
+
},
|
|
1420
|
+
catch: (e) => new SandboxError({ reason: String(e), cause: e })
|
|
1421
|
+
});
|
|
1422
|
+
},
|
|
1423
|
+
stop: async () => {
|
|
1424
|
+
const sandbox2 = await getSandbox2();
|
|
1425
|
+
if (sandbox2 instanceof Error) {
|
|
1426
|
+
return sandbox2;
|
|
1427
|
+
}
|
|
1428
|
+
return errore3.tryAsync({
|
|
1429
|
+
try: async () => {
|
|
1430
|
+
await sandbox2.stop();
|
|
1431
|
+
const existing = await storage.sandbox.get(id);
|
|
1432
|
+
if (existing instanceof Error || !existing) {
|
|
1433
|
+
return void 0;
|
|
1434
|
+
}
|
|
1435
|
+
await storage.sandbox.set({
|
|
1436
|
+
id: existing.id,
|
|
1437
|
+
config: existing.config,
|
|
1438
|
+
createdAt: existing.createdAt,
|
|
1439
|
+
lastActivityAt: existing.lastActivityAt,
|
|
1440
|
+
acquiringLockId: null,
|
|
1441
|
+
acquiringLockAt: null,
|
|
1442
|
+
providerMetadata: {
|
|
1443
|
+
provider: "vercel",
|
|
1444
|
+
sandboxId: null,
|
|
1445
|
+
snapshotId: null
|
|
1446
|
+
}
|
|
1447
|
+
});
|
|
1448
|
+
return void 0;
|
|
1449
|
+
},
|
|
1450
|
+
catch: (e) => new SandboxError({ reason: String(e), cause: e })
|
|
1451
|
+
});
|
|
1452
|
+
},
|
|
1453
|
+
getStatus: async () => {
|
|
1454
|
+
const sandbox2 = await getSandbox2();
|
|
1455
|
+
if (sandbox2 instanceof Error) {
|
|
1456
|
+
return sandbox2;
|
|
1457
|
+
}
|
|
1458
|
+
return sandbox2.status;
|
|
1459
|
+
},
|
|
1460
|
+
getCreatedAt: async () => {
|
|
1461
|
+
const sandbox2 = await getSandbox2();
|
|
1462
|
+
if (sandbox2 instanceof Error) {
|
|
1463
|
+
return sandbox2;
|
|
1464
|
+
}
|
|
1465
|
+
return sandbox2.createdAt;
|
|
1466
|
+
},
|
|
1467
|
+
getRemainingTimeout: async () => {
|
|
1468
|
+
const sandbox2 = await getSandbox2();
|
|
1469
|
+
if (sandbox2 instanceof Error) {
|
|
1470
|
+
return sandbox2;
|
|
1471
|
+
}
|
|
1472
|
+
return sandbox2.timeout;
|
|
1473
|
+
}
|
|
1474
|
+
};
|
|
1475
|
+
const sandbox = {
|
|
1476
|
+
id,
|
|
1477
|
+
config,
|
|
1478
|
+
exec: async ({ command, args, signal }) => {
|
|
1479
|
+
const instance = await getSandbox2();
|
|
1480
|
+
if (instance instanceof Error) {
|
|
1481
|
+
return instance;
|
|
1482
|
+
}
|
|
1483
|
+
const updatePromise = updateLastActivity();
|
|
1484
|
+
const execResult = await errore3.tryAsync({
|
|
1485
|
+
try: async () => {
|
|
1486
|
+
const output = await instance.runCommand(command, args, { signal });
|
|
1487
|
+
let stdout = "";
|
|
1488
|
+
let stderr = "";
|
|
1489
|
+
const logBuffer = [];
|
|
1490
|
+
const state = {
|
|
1491
|
+
resolve: null,
|
|
1492
|
+
consumed: false
|
|
1493
|
+
};
|
|
1494
|
+
const consumeLogs = (async () => {
|
|
1495
|
+
for await (const log of output.logs()) {
|
|
1496
|
+
const entry = log.stream === "stdout" ? { stream: "stdout", data: log.data } : { stream: "stderr", data: log.data };
|
|
1497
|
+
if (log.stream === "stdout") {
|
|
1498
|
+
stdout += log.data;
|
|
1499
|
+
} else {
|
|
1500
|
+
stderr += log.data;
|
|
1501
|
+
}
|
|
1502
|
+
logBuffer.push(entry);
|
|
1503
|
+
state.resolve?.();
|
|
1504
|
+
}
|
|
1505
|
+
state.consumed = true;
|
|
1506
|
+
state.resolve?.();
|
|
1507
|
+
})();
|
|
1508
|
+
async function* logs() {
|
|
1509
|
+
let index = 0;
|
|
1510
|
+
while (!state.consumed || index < logBuffer.length) {
|
|
1511
|
+
if (index < logBuffer.length) {
|
|
1512
|
+
yield logBuffer[index++];
|
|
1513
|
+
} else {
|
|
1514
|
+
await new Promise((resolve) => {
|
|
1515
|
+
state.resolve = resolve;
|
|
1516
|
+
});
|
|
1517
|
+
state.resolve = null;
|
|
1518
|
+
}
|
|
1519
|
+
}
|
|
1520
|
+
}
|
|
1521
|
+
const result = consumeLogs.then(() => ({
|
|
1522
|
+
stdout,
|
|
1523
|
+
stderr,
|
|
1524
|
+
exitCode: output.exitCode
|
|
1525
|
+
}));
|
|
1526
|
+
return { commandId: output.cmdId, logs, result };
|
|
1527
|
+
},
|
|
1528
|
+
catch: (e) => new SandboxError({ reason: String(e), cause: e })
|
|
1529
|
+
});
|
|
1530
|
+
await updatePromise;
|
|
1531
|
+
return execResult;
|
|
1532
|
+
},
|
|
1533
|
+
getDomain: async (port) => {
|
|
1534
|
+
const sandbox2 = await getSandbox2();
|
|
1535
|
+
if (sandbox2 instanceof Error) {
|
|
1536
|
+
return sandbox2;
|
|
1537
|
+
}
|
|
1538
|
+
try {
|
|
1539
|
+
return sandbox2.domain(port);
|
|
1540
|
+
} catch (e) {
|
|
1541
|
+
return new SandboxError({ reason: String(e), cause: e });
|
|
1542
|
+
}
|
|
1543
|
+
},
|
|
1544
|
+
kill: async ({ commandId, storage: cmdStorage }) => {
|
|
1545
|
+
const instance = await getSandbox2();
|
|
1546
|
+
if (instance instanceof Error) {
|
|
1547
|
+
return instance;
|
|
1548
|
+
}
|
|
1549
|
+
const cmd = await cmdStorage.command.get(commandId);
|
|
1550
|
+
if (cmd instanceof Error) {
|
|
1551
|
+
return new SandboxError({ reason: cmd.message, cause: cmd });
|
|
1552
|
+
}
|
|
1553
|
+
if (cmd && cmd.status === "running") {
|
|
1554
|
+
const result = await cmdStorage.command.set({
|
|
1555
|
+
...cmd,
|
|
1556
|
+
status: "killed"
|
|
1557
|
+
});
|
|
1558
|
+
if (result instanceof Error) {
|
|
1559
|
+
return new SandboxError({ reason: result.message, cause: result });
|
|
1560
|
+
}
|
|
1561
|
+
}
|
|
1562
|
+
return void 0;
|
|
1563
|
+
},
|
|
1564
|
+
writeFiles: (opts) => writeFiles({ sandbox, ...opts }),
|
|
1565
|
+
lifecycle
|
|
1566
|
+
};
|
|
1567
|
+
if (config.lifecycle?.autoStart !== false) {
|
|
1568
|
+
sandboxPromise = doGetSandbox();
|
|
1569
|
+
}
|
|
1570
|
+
return sandbox;
|
|
1571
|
+
};
|
|
1572
|
+
}
|
|
1573
|
+
});
|
|
1574
|
+
|
|
1575
|
+
// src/sandbox/client.ts
|
|
1576
|
+
var client_exports = {};
|
|
1577
|
+
__export(client_exports, {
|
|
1578
|
+
getSandbox: () => getSandbox
|
|
1579
|
+
});
|
|
1580
|
+
function getSandbox({
|
|
1581
|
+
sandboxRecord,
|
|
1582
|
+
storageConfig
|
|
1583
|
+
}) {
|
|
1584
|
+
const { config } = sandboxRecord;
|
|
1585
|
+
switch (config.type) {
|
|
1586
|
+
case "local":
|
|
1587
|
+
return localSandbox({
|
|
1588
|
+
sandboxRecord,
|
|
1589
|
+
storageConfig
|
|
1590
|
+
});
|
|
1591
|
+
case "vercel":
|
|
1592
|
+
return vercelSandbox({
|
|
1593
|
+
sandboxRecord,
|
|
1594
|
+
storageConfig
|
|
1595
|
+
});
|
|
1596
|
+
case "custom":
|
|
1597
|
+
throw new Error("Custom sandboxes are not supported");
|
|
1598
|
+
default:
|
|
1599
|
+
config;
|
|
1600
|
+
throw new Error(
|
|
1601
|
+
`Unknown sandbox type: ${// biome-ignore lint/suspicious/noExplicitAny: .
|
|
1602
|
+
config.type}`
|
|
1603
|
+
);
|
|
1604
|
+
}
|
|
1605
|
+
}
|
|
1606
|
+
var init_client2 = __esm({
|
|
1607
|
+
"src/sandbox/client.ts"() {
|
|
1608
|
+
"use strict";
|
|
1609
|
+
init_local2();
|
|
1610
|
+
init_vercel2();
|
|
1611
|
+
}
|
|
1612
|
+
});
|
|
1613
|
+
|
|
1614
|
+
// src/sandbox/lifecycle-workflow-steps.ts
|
|
1615
|
+
var lifecycle_workflow_steps_exports = {};
|
|
1616
|
+
__export(lifecycle_workflow_steps_exports, {
|
|
1617
|
+
snapshotSandboxStep: () => snapshotSandboxStep
|
|
1618
|
+
});
|
|
1619
|
+
async function snapshotSandboxStep(input) {
|
|
1620
|
+
"use step";
|
|
1621
|
+
const { getStorage: getStorage2 } = await Promise.resolve().then(() => (init_storage(), storage_exports));
|
|
1622
|
+
const { getSandbox: getSandbox2 } = await Promise.resolve().then(() => (init_client2(), client_exports));
|
|
1623
|
+
const storage = getStorage2(input.storageConfig);
|
|
1624
|
+
const sandboxRecord = await storage.sandbox.get(input.id);
|
|
1625
|
+
if (sandboxRecord instanceof Error) {
|
|
1626
|
+
return sandboxRecord;
|
|
1627
|
+
}
|
|
1628
|
+
const sandbox = getSandbox2({
|
|
1629
|
+
sandboxRecord,
|
|
1630
|
+
storageConfig: input.storageConfig
|
|
1631
|
+
});
|
|
1632
|
+
await sandbox.lifecycle?.snapshot();
|
|
1633
|
+
}
|
|
1634
|
+
var init_lifecycle_workflow_steps = __esm({
|
|
1635
|
+
"src/sandbox/lifecycle-workflow-steps.ts"() {
|
|
1636
|
+
"use strict";
|
|
1637
|
+
}
|
|
1638
|
+
});
|
|
1639
|
+
|
|
1640
|
+
// src/sandbox/lifecycle-workflow.ts
|
|
1641
|
+
var lifecycle_workflow_exports = {};
|
|
1642
|
+
__export(lifecycle_workflow_exports, {
|
|
1643
|
+
sandboxActivityHook: () => sandboxActivityHook,
|
|
1644
|
+
sandboxLifecycleWorkflow: () => sandboxLifecycleWorkflow
|
|
1645
|
+
});
|
|
1646
|
+
module.exports = __toCommonJS(lifecycle_workflow_exports);
|
|
1647
|
+
var import_workflow = require("workflow");
|
|
1648
|
+
var sandboxActivityHook = (0, import_workflow.defineHook)();
|
|
1649
|
+
var DEFAULT_IDLE_TIMEOUT_MS = 5 * 60 * 1e3;
|
|
1650
|
+
async function sandboxLifecycleWorkflow({
|
|
1651
|
+
input
|
|
1652
|
+
}) {
|
|
1653
|
+
"use workflow";
|
|
1654
|
+
const activityHook = sandboxActivityHook.create({ token: input.id });
|
|
1655
|
+
const iterator = activityHook[Symbol.asyncIterator]();
|
|
1656
|
+
let pendingNext = iterator.next();
|
|
1657
|
+
let sandboxConfig = input.initialConfig;
|
|
1658
|
+
if (sandboxConfig.type !== "vercel") {
|
|
1659
|
+
throw new Error("Sandbox config is not a Vercel sandbox");
|
|
1660
|
+
}
|
|
1661
|
+
const idleTimeoutMs = sandboxConfig.lifecycle?.stopAfterInactiveMs ?? DEFAULT_IDLE_TIMEOUT_MS;
|
|
1662
|
+
while (true) {
|
|
1663
|
+
const result = await Promise.race([
|
|
1664
|
+
pendingNext.then((r) => ({ ...r, type: "activity" })),
|
|
1665
|
+
(0, import_workflow.sleep)(idleTimeoutMs).then(() => ({ type: "timeout" }))
|
|
1666
|
+
]);
|
|
1667
|
+
if (result.type === "timeout") {
|
|
1668
|
+
const { snapshotSandboxStep: snapshotSandboxStep2 } = await Promise.resolve().then(() => (init_lifecycle_workflow_steps(), lifecycle_workflow_steps_exports));
|
|
1669
|
+
await snapshotSandboxStep2(input).catch((e) => {
|
|
1670
|
+
if (import_workflow.FatalError.is(e)) {
|
|
1671
|
+
console.error("Snapshot failed permanently:", e.message);
|
|
1672
|
+
return;
|
|
1673
|
+
}
|
|
1674
|
+
throw e;
|
|
1675
|
+
});
|
|
1676
|
+
break;
|
|
1677
|
+
}
|
|
1678
|
+
if (result.done) {
|
|
1679
|
+
break;
|
|
1680
|
+
}
|
|
1681
|
+
sandboxConfig = result.value.newConfig;
|
|
1682
|
+
pendingNext = iterator.next();
|
|
1683
|
+
}
|
|
1684
|
+
}
|
|
1685
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
1686
|
+
0 && (module.exports = {
|
|
1687
|
+
sandboxActivityHook,
|
|
1688
|
+
sandboxLifecycleWorkflow
|
|
1689
|
+
});
|
|
1690
|
+
//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vc3JjL2Vycm9ycy50cyIsICIuLi9zcmMvdXRpbHMvcGFnaW5hdGUudHMiLCAiLi4vc3JjL3N0b3JhZ2UvYmluZGluZ3MvbG9jYWwtZnMtaGFuZGxlcnMudHMiLCAiLi4vc3JjL3N0b3JhZ2UvYmluZGluZ3MvbG9jYWwudHMiLCAiLi4vc3JjL3N0b3JhZ2UvYmluZGluZ3MvdmVyY2VsLnRzIiwgIi4uL3NyYy9zdG9yYWdlL2NsaWVudC50cyIsICIuLi9zcmMvc3RvcmFnZS9ycGMudHMiLCAiLi4vc3JjL3N0b3JhZ2UvaGFuZGxlci50cyIsICIuLi9zcmMvc3RvcmFnZS9pbmRleC50cyIsICIuLi9zcmMvc2FuZGJveC93cml0ZS1maWxlcy50cyIsICIuLi9zcmMvc2FuZGJveC9iaW5kaW5ncy9sb2NhbC50cyIsICIuLi9zcmMvc2FuZGJveC9iaW5kaW5ncy92ZXJjZWwudHMiLCAiLi4vc3JjL3NhbmRib3gvY2xpZW50LnRzIiwgIi4uL3NyYy9zYW5kYm94L2xpZmVjeWNsZS13b3JrZmxvdy1zdGVwcy50cyIsICIuLi9zcmMvc2FuZGJveC9saWZlY3ljbGUtd29ya2Zsb3cudHMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbImltcG9ydCAqIGFzIGVycm9yZSBmcm9tIFwiZXJyb3JlXCI7XG5cbmV4cG9ydCBjbGFzcyBTZXNzaW9uTm90Rm91bmRFcnJvciBleHRlbmRzIGVycm9yZS5jcmVhdGVUYWdnZWRFcnJvcih7XG4gIG5hbWU6IFwiU2Vzc2lvbk5vdEZvdW5kRXJyb3JcIixcbiAgbWVzc2FnZTogXCJTZXNzaW9uICRpZCBub3QgZm91bmRcIixcbn0pIHt9XG5cbmV4cG9ydCBjbGFzcyBTZXNzaW9uRXJyb3IgZXh0ZW5kcyBlcnJvcmUuY3JlYXRlVGFnZ2VkRXJyb3Ioe1xuICBuYW1lOiBcIlNlc3Npb25FcnJvclwiLFxuICBtZXNzYWdlOiBcIlNlc3Npb24gJGlkIGZhaWxlZDogJHJlYXNvblwiLFxufSkge31cblxuZXhwb3J0IGNsYXNzIFNhbmRib3hOb3RGb3VuZEVycm9yIGV4dGVuZHMgZXJyb3JlLmNyZWF0ZVRhZ2dlZEVycm9yKHtcbiAgbmFtZTogXCJTYW5kYm94Tm90Rm91bmRFcnJvclwiLFxuICBtZXNzYWdlOiBcIlNhbmRib3ggJGlkIG5vdCBmb3VuZFwiLFxufSkge31cblxuZXhwb3J0IGNsYXNzIFN0b3JhZ2VFcnJvciBleHRlbmRzIGVycm9yZS5jcmVhdGVUYWdnZWRFcnJvcih7XG4gIG5hbWU6IFwiU3RvcmFnZUVycm9yXCIsXG4gIG1lc3NhZ2U6IFwiJHJlYXNvblwiLFxufSkge31cblxuZXhwb3J0IGNsYXNzIFNhbmRib3hFcnJvciBleHRlbmRzIGVycm9yZS5jcmVhdGVUYWdnZWRFcnJvcih7XG4gIG5hbWU6IFwiU2FuZGJveEVycm9yXCIsXG4gIG1lc3NhZ2U6IFwiJHJlYXNvblwiLFxufSkge31cblxuZXhwb3J0IGNsYXNzIE1lc3NhZ2VOb3RGb3VuZEVycm9yIGV4dGVuZHMgZXJyb3JlLmNyZWF0ZVRhZ2dlZEVycm9yKHtcbiAgbmFtZTogXCJNZXNzYWdlTm90Rm91bmRFcnJvclwiLFxuICBtZXNzYWdlOiBcIk1lc3NhZ2UgJGlkIG5vdCBmb3VuZFwiLFxufSkge31cbiIsICJpbXBvcnQgdHlwZSB7IExpc3RSZXN1bHQgfSBmcm9tIFwiLi4vc3RvcmFnZVwiO1xuXG5leHBvcnQgZnVuY3Rpb24gcGFnaW5hdGU8VCBleHRlbmRzIHsgaWQ6IHN0cmluZyB9PihvcHRzOiB7XG4gIGl0ZW1zOiBUW107XG4gIGN1cnNvcj86IHN0cmluZztcbiAgbGltaXQ/OiBudW1iZXI7XG59KTogTGlzdFJlc3VsdDxUPiB7XG4gIGNvbnN0IHsgaXRlbXMsIGN1cnNvciwgbGltaXQgPSA1MCB9ID0gb3B0cztcbiAgY29uc3Qgc3RhcnRJbmRleCA9IGN1cnNvciA/IGl0ZW1zLmZpbmRJbmRleCgobSkgPT4gbS5pZCA9PT0gY3Vyc29yKSArIDEgOiAwO1xuICBjb25zdCBzbGljZWQgPSBpdGVtcy5zbGljZShzdGFydEluZGV4LCBzdGFydEluZGV4ICsgbGltaXQpO1xuICBjb25zdCBuZXh0Q3Vyc29yID1cbiAgICBzdGFydEluZGV4ICsgbGltaXQgPCBpdGVtcy5sZW5ndGggPyAoc2xpY2VkLmF0KC0xKT8uaWQgPz8gbnVsbCkgOiBudWxsO1xuICByZXR1cm4geyBpdGVtczogc2xpY2VkLCBuZXh0Q3Vyc29yIH07XG59XG4iLCAiaW1wb3J0IHsgbWtkaXIsIHJlYWRkaXIsIHJlYWRGaWxlLCB3cml0ZUZpbGUgfSBmcm9tIFwibm9kZTpmcy9wcm9taXNlc1wiO1xuaW1wb3J0IHsgZGlybmFtZSwgam9pbiB9IGZyb20gXCJub2RlOnBhdGhcIjtcbmltcG9ydCB7IHBhZ2luYXRlIH0gZnJvbSBcIi4uLy4uL3V0aWxzL3BhZ2luYXRlXCI7XG5pbXBvcnQgdHlwZSB7XG4gIENvbW1hbmQsXG4gIEhhbmRsZXJzLFxuICBNZXNzYWdlLFxuICBQYXJ0LFxuICBTYW5kYm94UmVjb3JkLFxuICBTZXNzaW9uLFxufSBmcm9tIFwiLi5cIjtcblxuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZUZpbGVzeXN0ZW1IYW5kbGVycyhiYXNlUGF0aDogc3RyaW5nKTogSGFuZGxlcnMge1xuICBjb25zdCBzZXNzaW9uRGlyID0gam9pbihiYXNlUGF0aCwgXCJzZXNzaW9uXCIpO1xuICBjb25zdCBtZXNzYWdlRGlyID0gam9pbihiYXNlUGF0aCwgXCJtZXNzYWdlXCIpO1xuICBjb25zdCBwYXJ0RGlyID0gam9pbihiYXNlUGF0aCwgXCJwYXJ0XCIpO1xuICBjb25zdCBzYW5kYm94RGlyID0gam9pbihiYXNlUGF0aCwgXCJzYW5kYm94XCIpO1xuICBjb25zdCBjb21tYW5kRGlyID0gam9pbihiYXNlUGF0aCwgXCJjb21tYW5kXCIpO1xuXG4gIGFzeW5jIGZ1bmN0aW9uIGVuc3VyZURpcihkaXI6IHN0cmluZykge1xuICAgIGF3YWl0IG1rZGlyKGRpciwgeyByZWN1cnNpdmU6IHRydWUgfSk7XG4gIH1cblxuICBhc3luYyBmdW5jdGlvbiByZWFkSnNvbjxUPihmaWxlUGF0aDogc3RyaW5nKTogUHJvbWlzZTxUIHwgbnVsbD4ge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCBjb250ZW50ID0gYXdhaXQgcmVhZEZpbGUoZmlsZVBhdGgsIFwidXRmLThcIik7XG4gICAgICByZXR1cm4gSlNPTi5wYXJzZShjb250ZW50KSBhcyBUO1xuICAgIH0gY2F0Y2gge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICB9XG5cbiAgYXN5bmMgZnVuY3Rpb24gd3JpdGVKc29uRmlsZShmaWxlUGF0aDogc3RyaW5nLCBkYXRhOiB1bmtub3duKSB7XG4gICAgYXdhaXQgZW5zdXJlRGlyKGRpcm5hbWUoZmlsZVBhdGgpKTtcbiAgICBhd2FpdCB3cml0ZUZpbGUoZmlsZVBhdGgsIEpTT04uc3RyaW5naWZ5KGRhdGEsIG51bGwsIDIpKTtcbiAgfVxuXG4gIGFzeW5jIGZ1bmN0aW9uIHJlYWRBbGxGcm9tRGlyPFQ+KGRpcjogc3RyaW5nKTogUHJvbWlzZTxUW10+IHtcbiAgICB0cnkge1xuICAgICAgY29uc3QgZmlsZXMgPSBhd2FpdCByZWFkZGlyKGRpcik7XG4gICAgICBjb25zdCByZXN1bHRzID0gYXdhaXQgUHJvbWlzZS5hbGwoXG4gICAgICAgIGZpbGVzXG4gICAgICAgICAgLmZpbHRlcigoZikgPT4gZi5lbmRzV2l0aChcIi5qc29uXCIpKVxuICAgICAgICAgIC5tYXAoKGYpID0+IHJlYWRKc29uPFQ+KGpvaW4oZGlyLCBmKSkpXG4gICAgICApO1xuICAgICAgcmV0dXJuIHJlc3VsdHMuZmlsdGVyKChyKTogciBpcyBOb25OdWxsYWJsZTx0eXBlb2Ygcj4gPT4gciAhPT0gbnVsbCk7XG4gICAgfSBjYXRjaCB7XG4gICAgICByZXR1cm4gW107XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHtcbiAgICBcInNlc3Npb24uZ2V0XCI6IGFzeW5jICh7IGlkIH0pID0+IHtcbiAgICAgIGNvbnN0IHNlc3Npb24gPSBhd2FpdCByZWFkSnNvbjxTZXNzaW9uPihqb2luKHNlc3Npb25EaXIsIGAke2lkfS5qc29uYCkpO1xuICAgICAgcmV0dXJuIHNlc3Npb24gPz8gbnVsbDtcbiAgICB9LFxuXG4gICAgXCJzZXNzaW9uLnNldFwiOiBhc3luYyAoc2Vzc2lvbikgPT4ge1xuICAgICAgY29uc3Qgbm93ID0gRGF0ZS5ub3coKTtcbiAgICAgIGNvbnN0IHNlc3Npb25QYXRoID0gam9pbihzZXNzaW9uRGlyLCBgJHtzZXNzaW9uLmlkfS5qc29uYCk7XG4gICAgICBjb25zdCBleGlzdGluZyA9IGF3YWl0IHJlYWRKc29uPFNlc3Npb24+KHNlc3Npb25QYXRoKTtcbiAgICAgIGNvbnN0IG5ld1Nlc3Npb246IFNlc3Npb24gPSB7XG4gICAgICAgIC4uLnNlc3Npb24sXG4gICAgICAgIHRhZ3M6IHNlc3Npb24udGFncyA/PyBleGlzdGluZz8udGFncyA/PyB7fSxcbiAgICAgICAgY3JlYXRlZEF0OiBleGlzdGluZz8uY3JlYXRlZEF0ID8/IHNlc3Npb24uY3JlYXRlZEF0ID8/IG5vdyxcbiAgICAgICAgdXBkYXRlZEF0OiBub3csXG4gICAgICB9O1xuICAgICAgYXdhaXQgd3JpdGVKc29uRmlsZShzZXNzaW9uUGF0aCwgbmV3U2Vzc2lvbik7XG4gICAgICByZXR1cm4gbmV3U2Vzc2lvbjtcbiAgICB9LFxuXG4gICAgXCJzZXNzaW9uLmxpc3RcIjogYXN5bmMgKHsgdGFncywgY3Vyc29yLCBsaW1pdCB9KSA9PiB7XG4gICAgICBjb25zdCBhbGxTZXNzaW9ucyA9IGF3YWl0IHJlYWRBbGxGcm9tRGlyPFNlc3Npb24+KHNlc3Npb25EaXIpO1xuICAgICAgbGV0IGZpbHRlcmVkID0gYWxsU2Vzc2lvbnM7XG4gICAgICBpZiAodGFncyAmJiBPYmplY3Qua2V5cyh0YWdzKS5sZW5ndGggPiAwKSB7XG4gICAgICAgIGZpbHRlcmVkID0gZmlsdGVyZWQuZmlsdGVyKChzKSA9PiB7XG4gICAgICAgICAgY29uc3Qgc2Vzc2lvblRhZ3MgPSBzLnRhZ3MgPz8ge307XG4gICAgICAgICAgcmV0dXJuIE9iamVjdC5lbnRyaWVzKHRhZ3MpLmV2ZXJ5KFxuICAgICAgICAgICAgKFtrZXksIHZhbHVlXSkgPT4gc2Vzc2lvblRhZ3Nba2V5XSA9PT0gdmFsdWVcbiAgICAgICAgICApO1xuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICAgIGZpbHRlcmVkLnNvcnQoKGEsIGIpID0+IGEuY3JlYXRlZEF0IC0gYi5jcmVhdGVkQXQpO1xuICAgICAgcmV0dXJuIHBhZ2luYXRlKHsgaXRlbXM6IGZpbHRlcmVkLCBjdXJzb3IsIGxpbWl0IH0pO1xuICAgIH0sXG5cbiAgICBcInNlc3Npb24ubGlzdEJ5U2FuZGJveFwiOiBhc3luYyAoeyBzYW5kYm94SWQsIHRhZ3MsIGN1cnNvciwgbGltaXQgfSkgPT4ge1xuICAgICAgY29uc3QgYWxsU2Vzc2lvbnMgPSBhd2FpdCByZWFkQWxsRnJvbURpcjxTZXNzaW9uPihzZXNzaW9uRGlyKTtcbiAgICAgIGxldCBmaWx0ZXJlZCA9IGFsbFNlc3Npb25zLmZpbHRlcigocykgPT4gcy5zYW5kYm94SWQgPT09IHNhbmRib3hJZCk7XG4gICAgICBpZiAodGFncyAmJiBPYmplY3Qua2V5cyh0YWdzKS5sZW5ndGggPiAwKSB7XG4gICAgICAgIGZpbHRlcmVkID0gZmlsdGVyZWQuZmlsdGVyKChzKSA9PiB7XG4gICAgICAgICAgY29uc3Qgc2Vzc2lvblRhZ3MgPSBzLnRhZ3MgPz8ge307XG4gICAgICAgICAgcmV0dXJuIE9iamVjdC5lbnRyaWVzKHRhZ3MpLmV2ZXJ5KFxuICAgICAgICAgICAgKFtrZXksIHZhbHVlXSkgPT4gc2Vzc2lvblRhZ3Nba2V5XSA9PT0gdmFsdWVcbiAgICAgICAgICApO1xuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICAgIGZpbHRlcmVkLnNvcnQoKGEsIGIpID0+IGEuY3JlYXRlZEF0IC0gYi5jcmVhdGVkQXQpO1xuICAgICAgcmV0dXJuIHBhZ2luYXRlKHsgaXRlbXM6IGZpbHRlcmVkLCBjdXJzb3IsIGxpbWl0IH0pO1xuICAgIH0sXG5cbiAgICBcInNlc3Npb24udGFnLnNldFwiOiBhc3luYyAoeyBzZXNzaW9uSWQsIHRhZ3MgfSkgPT4ge1xuICAgICAgY29uc3Qgc2Vzc2lvblBhdGggPSBqb2luKHNlc3Npb25EaXIsIGAke3Nlc3Npb25JZH0uanNvbmApO1xuICAgICAgY29uc3QgZXhpc3RpbmcgPSBhd2FpdCByZWFkSnNvbjxTZXNzaW9uPihzZXNzaW9uUGF0aCk7XG4gICAgICBpZiAoIWV4aXN0aW5nKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgU2Vzc2lvbiAke3Nlc3Npb25JZH0gbm90IGZvdW5kYCk7XG4gICAgICB9XG4gICAgICBjb25zdCBtZXJnZWRUYWdzID0geyAuLi5leGlzdGluZy50YWdzLCAuLi50YWdzIH07XG4gICAgICBjb25zdCBub3cgPSBEYXRlLm5vdygpO1xuICAgICAgY29uc3QgdXBkYXRlZFNlc3Npb246IFNlc3Npb24gPSB7XG4gICAgICAgIC4uLmV4aXN0aW5nLFxuICAgICAgICB0YWdzOiBtZXJnZWRUYWdzLFxuICAgICAgICB1cGRhdGVkQXQ6IG5vdyxcbiAgICAgIH07XG4gICAgICBhd2FpdCB3cml0ZUpzb25GaWxlKHNlc3Npb25QYXRoLCB1cGRhdGVkU2Vzc2lvbik7XG4gICAgICByZXR1cm4gdXBkYXRlZFNlc3Npb247XG4gICAgfSxcblxuICAgIFwibWVzc2FnZS5nZXRcIjogYXN5bmMgKHsgaWQgfSkgPT4ge1xuICAgICAgcmV0dXJuIGF3YWl0IHJlYWRKc29uPE1lc3NhZ2U+KGpvaW4obWVzc2FnZURpciwgYCR7aWR9Lmpzb25gKSk7XG4gICAgfSxcblxuICAgIFwibWVzc2FnZS5zZXRcIjogYXN5bmMgKG1lc3NhZ2UpID0+IHtcbiAgICAgIGF3YWl0IHdyaXRlSnNvbkZpbGUoam9pbihtZXNzYWdlRGlyLCBgJHttZXNzYWdlLmlkfS5qc29uYCksIG1lc3NhZ2UpO1xuICAgICAgcmV0dXJuIG1lc3NhZ2U7XG4gICAgfSxcblxuICAgIFwibWVzc2FnZS5saXN0XCI6IGFzeW5jICh7IHNlc3Npb25JZCwgY3Vyc29yLCBsaW1pdCB9KSA9PiB7XG4gICAgICBjb25zdCBhbGxNZXNzYWdlcyA9IGF3YWl0IHJlYWRBbGxGcm9tRGlyPE1lc3NhZ2U+KG1lc3NhZ2VEaXIpO1xuICAgICAgY29uc3QgZmlsdGVyZWQgPSBhbGxNZXNzYWdlc1xuICAgICAgICAuZmlsdGVyKChtKSA9PiBtLnNlc3Npb25JZCA9PT0gc2Vzc2lvbklkKVxuICAgICAgICAuc29ydCgoYSwgYikgPT4gYS5jcmVhdGVkQXQgLSBiLmNyZWF0ZWRBdCk7XG4gICAgICByZXR1cm4gcGFnaW5hdGUoeyBpdGVtczogZmlsdGVyZWQsIGN1cnNvciwgbGltaXQgfSk7XG4gICAgfSxcblxuICAgIFwicGFydC5saXN0QnlNZXNzYWdlXCI6IGFzeW5jICh7IG1lc3NhZ2VJZCwgY3Vyc29yLCBsaW1pdCB9KSA9PiB7XG4gICAgICBjb25zdCBhbGxQYXJ0cyA9IGF3YWl0IHJlYWRBbGxGcm9tRGlyPFBhcnQ+KHBhcnREaXIpO1xuICAgICAgY29uc3QgZmlsdGVyZWQgPSBhbGxQYXJ0c1xuICAgICAgICAuZmlsdGVyKChwKSA9PiBwLm1lc3NhZ2VJZCA9PT0gbWVzc2FnZUlkKVxuICAgICAgICAuc29ydCgoYSwgYikgPT4gYS5pbmRleCAtIGIuaW5kZXgpO1xuICAgICAgcmV0dXJuIHBhZ2luYXRlKHsgaXRlbXM6IGZpbHRlcmVkLCBjdXJzb3IsIGxpbWl0IH0pO1xuICAgIH0sXG5cbiAgICBcInBhcnQubGlzdEJ5U2Vzc2lvblwiOiBhc3luYyAoeyBzZXNzaW9uSWQsIGN1cnNvciwgbGltaXQgfSkgPT4ge1xuICAgICAgY29uc3QgYWxsUGFydHMgPSBhd2FpdCByZWFkQWxsRnJvbURpcjxQYXJ0PihwYXJ0RGlyKTtcbiAgICAgIGNvbnN0IGZpbHRlcmVkID0gYWxsUGFydHNcbiAgICAgICAgLmZpbHRlcigocCkgPT4gcC5zZXNzaW9uSWQgPT09IHNlc3Npb25JZClcbiAgICAgICAgLnNvcnQoKGEsIGIpID0+IHtcbiAgICAgICAgICBpZiAoYS5tZXNzYWdlSWQgIT09IGIubWVzc2FnZUlkKSB7XG4gICAgICAgICAgICByZXR1cm4gYS5tZXNzYWdlSWQubG9jYWxlQ29tcGFyZShiLm1lc3NhZ2VJZCk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybiBhLmluZGV4IC0gYi5pbmRleDtcbiAgICAgICAgfSk7XG4gICAgICByZXR1cm4gcGFnaW5hdGUoeyBpdGVtczogZmlsdGVyZWQsIGN1cnNvciwgbGltaXQgfSk7XG4gICAgfSxcblxuICAgIFwicGFydC5zZXRcIjogYXN5bmMgKHBhcnQpID0+IHtcbiAgICAgIGF3YWl0IHdyaXRlSnNvbkZpbGUoam9pbihwYXJ0RGlyLCBgJHtwYXJ0LmlkfS5qc29uYCksIHBhcnQpO1xuICAgICAgcmV0dXJuIHBhcnQ7XG4gICAgfSxcblxuICAgIFwic2FuZGJveC5nZXRcIjogYXN5bmMgKHsga2V5IH0pID0+IHtcbiAgICAgIGNvbnN0IHNhZmVOYW1lID0gQnVmZmVyLmZyb20oa2V5KS50b1N0cmluZyhcImJhc2U2NHVybFwiKTtcbiAgICAgIGNvbnN0IHNhbmRib3hQYXRoID0gam9pbihzYW5kYm94RGlyLCBgJHtzYWZlTmFtZX0uanNvbmApO1xuICAgICAgY29uc3QgZGF0YSA9IGF3YWl0IHJlYWRKc29uPFNhbmRib3hSZWNvcmQ+KHNhbmRib3hQYXRoKTtcbiAgICAgIGlmICghZGF0YSkge1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH1cbiAgICAgIHJldHVybiBkYXRhO1xuICAgIH0sXG5cbiAgICBcInNhbmRib3guc2V0XCI6IGFzeW5jIChyZWNvcmQpID0+IHtcbiAgICAgIGNvbnN0IHNhZmVOYW1lID0gQnVmZmVyLmZyb20ocmVjb3JkLmlkKS50b1N0cmluZyhcImJhc2U2NHVybFwiKTtcbiAgICAgIGNvbnN0IHNhbmRib3hQYXRoID0gam9pbihzYW5kYm94RGlyLCBgJHtzYWZlTmFtZX0uanNvbmApO1xuICAgICAgYXdhaXQgd3JpdGVKc29uRmlsZShzYW5kYm94UGF0aCwgcmVjb3JkKTtcbiAgICB9LFxuXG4gICAgXCJzYW5kYm94LmdldEJ5U2Vzc2lvblwiOiBhc3luYyAoeyBzZXNzaW9uSWQgfSkgPT4ge1xuICAgICAgY29uc3QgYWxsU2FuZGJveGVzID0gYXdhaXQgcmVhZEFsbEZyb21EaXI8U2FuZGJveFJlY29yZD4oc2FuZGJveERpcik7XG4gICAgICBjb25zdCBtYXRjaGluZyA9IGFsbFNhbmRib3hlcy5maWx0ZXIoKHMpID0+XG4gICAgICAgIHMuaWQuc3RhcnRzV2l0aChgJHtzZXNzaW9uSWR9LWApXG4gICAgICApO1xuICAgICAgaWYgKG1hdGNoaW5nLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH1cbiAgICAgIG1hdGNoaW5nLnNvcnQoXG4gICAgICAgIChhLCBiKSA9PiAoYi5sYXN0QWN0aXZpdHlBdCA/PyAwKSAtIChhLmxhc3RBY3Rpdml0eUF0ID8/IDApXG4gICAgICApO1xuICAgICAgcmV0dXJuIG1hdGNoaW5nWzBdO1xuICAgIH0sXG5cbiAgICBcImNvbW1hbmQuZ2V0XCI6IGFzeW5jICh7IGlkIH0pID0+IHtcbiAgICAgIHJldHVybiBhd2FpdCByZWFkSnNvbjxDb21tYW5kPihqb2luKGNvbW1hbmREaXIsIGAke2lkfS5qc29uYCkpO1xuICAgIH0sXG5cbiAgICBcImNvbW1hbmQuc2V0XCI6IGFzeW5jIChjb21tYW5kKSA9PiB7XG4gICAgICBhd2FpdCB3cml0ZUpzb25GaWxlKGpvaW4oY29tbWFuZERpciwgYCR7Y29tbWFuZC5pZH0uanNvbmApLCBjb21tYW5kKTtcbiAgICAgIHJldHVybiBjb21tYW5kO1xuICAgIH0sXG5cbiAgICBcImNvbW1hbmQubGlzdFwiOiBhc3luYyAoeyBzZXNzaW9uSWQsIGluY2x1ZGVGaW5pc2hlZCwgY3Vyc29yLCBsaW1pdCB9KSA9PiB7XG4gICAgICBjb25zdCBhbGxDb21tYW5kcyA9IGF3YWl0IHJlYWRBbGxGcm9tRGlyPENvbW1hbmQ+KGNvbW1hbmREaXIpO1xuICAgICAgbGV0IGZpbHRlcmVkID0gYWxsQ29tbWFuZHMuZmlsdGVyKChjKSA9PiBjLnNlc3Npb25JZCA9PT0gc2Vzc2lvbklkKTtcbiAgICAgIGlmICghaW5jbHVkZUZpbmlzaGVkKSB7XG4gICAgICAgIGZpbHRlcmVkID0gZmlsdGVyZWQuZmlsdGVyKChjKSA9PiBjLnN0YXR1cyA9PT0gXCJydW5uaW5nXCIpO1xuICAgICAgfVxuICAgICAgZmlsdGVyZWQuc29ydCgoYSwgYikgPT4gYS5zdGFydGVkQXQgLSBiLnN0YXJ0ZWRBdCk7XG4gICAgICByZXR1cm4gcGFnaW5hdGUoeyBpdGVtczogZmlsdGVyZWQsIGN1cnNvciwgbGltaXQgfSk7XG4gICAgfSxcbiAgfTtcbn1cbiIsICJpbXBvcnQgeyB0eXBlIFNlcnZlclR5cGUsIHNlcnZlIH0gZnJvbSBcIkBob25vL25vZGUtc2VydmVyXCI7XG5pbXBvcnQgeyBIb25vIH0gZnJvbSBcImhvbm9cIjtcbmltcG9ydCB7IGhhbmRsZVN0b3JhZ2VScGMgfSBmcm9tIFwiLi5cIjtcbmltcG9ydCB7IGNyZWF0ZUZpbGVzeXN0ZW1IYW5kbGVycyB9IGZyb20gXCIuL2xvY2FsLWZzLWhhbmRsZXJzXCI7XG5cbmNvbnN0IERFRkFVTFRfU1RPUkFHRV9ESVIgPSBcIi5hZ2VudC1zdG9yYWdlXCI7XG5cbmxldCBzdGFydFByb21pc2U6IFByb21pc2U8c3RyaW5nPiB8IG51bGwgPSBudWxsO1xubGV0IHNlcnZlckluc3RhbmNlOiB7IHVybDogc3RyaW5nOyBzZXJ2ZXI6IFNlcnZlclR5cGUgfSB8IG51bGwgPSBudWxsO1xuXG5leHBvcnQgZnVuY3Rpb24gc3RhcnRMb2NhbFN0b3JhZ2Uob3B0cz86IHtcbiAgcGF0aD86IHN0cmluZztcbiAgcG9ydD86IG51bWJlcjtcbn0pOiBQcm9taXNlPHN0cmluZz4ge1xuICBpZiAoc3RhcnRQcm9taXNlKSB7XG4gICAgcmV0dXJuIHN0YXJ0UHJvbWlzZTtcbiAgfVxuXG4gIHN0YXJ0UHJvbWlzZSA9IG5ldyBQcm9taXNlKChyZXNvbHZlKSA9PiB7XG4gICAgY29uc3QgaGFuZGxlcnMgPSBjcmVhdGVGaWxlc3lzdGVtSGFuZGxlcnMoXG4gICAgICBvcHRzPy5wYXRoID8/IERFRkFVTFRfU1RPUkFHRV9ESVJcbiAgICApO1xuICAgIGNvbnN0IGFwcCA9IG5ldyBIb25vKCk7XG5cbiAgICBhcHAucG9zdChcIi9cIiwgYXN5bmMgKGMpID0+IHtcbiAgICAgIGNvbnN0IGJvZHkgPSBhd2FpdCBjLnJlcS5qc29uKCk7XG4gICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGhhbmRsZVN0b3JhZ2VScGMoYm9keSwgaGFuZGxlcnMpO1xuICAgICAgcmV0dXJuIGMuanNvbihyZXNwb25zZSk7XG4gICAgfSk7XG5cbiAgICBjb25zdCBwb3J0ID0gb3B0cz8ucG9ydCA/PyAwO1xuICAgIGNvbnN0IHNlcnZlciA9IHNlcnZlKHtcbiAgICAgIGZldGNoOiBhcHAuZmV0Y2gsXG4gICAgICBwb3J0LFxuICAgIH0pO1xuXG4gICAgc2VydmVyLm9uKFwibGlzdGVuaW5nXCIsICgpID0+IHtcbiAgICAgIGNvbnN0IGFkZHJlc3MgPSBzZXJ2ZXIuYWRkcmVzcygpO1xuICAgICAgY29uc3QgYWN0dWFsUG9ydCA9IHR5cGVvZiBhZGRyZXNzID09PSBcIm9iamVjdFwiID8gYWRkcmVzcz8ucG9ydCA6IHBvcnQ7XG4gICAgICBjb25zdCB1cmwgPSBgaHR0cDovL2xvY2FsaG9zdDoke2FjdHVhbFBvcnR9YDtcblxuICAgICAgc2VydmVySW5zdGFuY2UgPSB7IHVybCwgc2VydmVyIH07XG4gICAgICBjb25zb2xlLmxvZyhgW2FnZW50XSBMb2NhbCBzdG9yYWdlIHNlcnZlciBzdGFydGVkIGF0ICR7dXJsfWApO1xuICAgICAgcmVzb2x2ZSh1cmwpO1xuICAgIH0pO1xuICB9KTtcblxuICByZXR1cm4gc3RhcnRQcm9taXNlO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gc3RvcExvY2FsU3RvcmFnZSgpOiB2b2lkIHtcbiAgaWYgKHNlcnZlckluc3RhbmNlKSB7XG4gICAgc2VydmVySW5zdGFuY2Uuc2VydmVyLmNsb3NlKCk7XG4gICAgc2VydmVySW5zdGFuY2UgPSBudWxsO1xuICAgIHN0YXJ0UHJvbWlzZSA9IG51bGw7XG4gIH1cbn1cblxuaWYgKHR5cGVvZiBwcm9jZXNzICE9PSBcInVuZGVmaW5lZFwiKSB7XG4gIHByb2Nlc3Mub24oXCJTSUdURVJNXCIsIHN0b3BMb2NhbFN0b3JhZ2UpO1xuICBwcm9jZXNzLm9uKFwiU0lHSU5UXCIsIHN0b3BMb2NhbFN0b3JhZ2UpO1xufVxuIiwgImNvbnN0IFZFUkNFTF9TVE9SQUdFX1VSTCA9XG4gIFwiaHR0cHM6Ly9hZ2VudC1zZGstc3RvcmFnZS1uaW5lLmxhYnMudmVyY2VsLmRldi9hcGkvc3RvcmFnZVwiO1xuXG5leHBvcnQgdHlwZSBWZXJjZWxTdG9yYWdlQ29uZmlnID0ge1xuICB1cmw6IHN0cmluZztcbiAgaGVhZGVyczogUmVjb3JkPHN0cmluZywgc3RyaW5nPjtcbn07XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBnZXRWZXJjZWxTdG9yYWdlQ29uZmlnKCk6IFByb21pc2U8VmVyY2VsU3RvcmFnZUNvbmZpZz4ge1xuICBsZXQgdG9rZW46IHN0cmluZyB8IG51bGwgPSBudWxsO1xuXG4gIHRyeSB7XG4gICAgY29uc3QgeyBnZXRWZXJjZWxPaWRjVG9rZW4gfSA9IGF3YWl0IGltcG9ydChcIkB2ZXJjZWwvb2lkY1wiKTtcbiAgICB0b2tlbiA9IGF3YWl0IGdldFZlcmNlbE9pZGNUb2tlbigpO1xuICB9IGNhdGNoIHtcbiAgICAvLyBPSURDIG5vdCBhdmFpbGFibGUgKGxvY2FsIGRldiwgbm9uLVZlcmNlbCBlbnZpcm9ubWVudClcbiAgfVxuXG4gIHJldHVybiB7XG4gICAgdXJsOiBWRVJDRUxfU1RPUkFHRV9VUkwsXG4gICAgaGVhZGVyczogdG9rZW4gPyB7IEF1dGhvcml6YXRpb246IGBCZWFyZXIgJHt0b2tlbn1gIH0gOiB7fSxcbiAgfTtcbn1cbiIsICJpbXBvcnQgdHlwZSB7IHogfSBmcm9tIFwiem9kXCI7XG5pbXBvcnQge1xuICBNZXNzYWdlTm90Rm91bmRFcnJvcixcbiAgU2FuZGJveE5vdEZvdW5kRXJyb3IsXG4gIFNlc3Npb25Ob3RGb3VuZEVycm9yLFxuICBTdG9yYWdlRXJyb3IsXG59IGZyb20gXCIuLi9lcnJvcnNcIjtcbmltcG9ydCB0eXBlIHsgU3RvcmFnZU1ldGhvZHMgfSBmcm9tIFwiLi9ycGNcIjtcbmltcG9ydCB0eXBlIHtcbiAgQ29tbWFuZCxcbiAgTGlzdFJlc3VsdCxcbiAgUGFydCxcbiAgUmVzb2x2ZWRTdG9yYWdlLFxuICBTdG9yYWdlLFxuICBTdG9yYWdlQ29uZmlnLFxufSBmcm9tIFwiLi90eXBlc1wiO1xuXG50eXBlIFJwY1Jlc3BvbnNlPFQ+ID1cbiAgfCB7IHJlc3VsdDogVCB9XG4gIHwgeyBlcnJvcjogeyBjb2RlOiBzdHJpbmc7IG1lc3NhZ2U6IHN0cmluZyB9IH07XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRTdG9yYWdlQ2xpZW50KHsgdXJsLCBoZWFkZXJzIH06IFJlc29sdmVkU3RvcmFnZSk6IFN0b3JhZ2Uge1xuICBhc3luYyBmdW5jdGlvbiBycGM8TSBleHRlbmRzIGtleW9mIFN0b3JhZ2VNZXRob2RzPihcbiAgICBtZXRob2Q6IE0sXG4gICAgcGFyYW1zOiB6LmluZmVyPFN0b3JhZ2VNZXRob2RzW01dW1wicGFyYW1zXCJdPlxuICApOiBQcm9taXNlPHouaW5mZXI8U3RvcmFnZU1ldGhvZHNbTV1bXCJyZXN1bHRcIl0+PiB7XG4gICAgY29uc3QgcmVzID0gYXdhaXQgZmV0Y2godXJsLCB7XG4gICAgICBtZXRob2Q6IFwiUE9TVFwiLFxuICAgICAgaGVhZGVyczogeyBcIkNvbnRlbnQtVHlwZVwiOiBcImFwcGxpY2F0aW9uL2pzb25cIiwgLi4uaGVhZGVycyB9LFxuICAgICAgYm9keTogSlNPTi5zdHJpbmdpZnkoeyBtZXRob2QsIHBhcmFtcyB9KSxcbiAgICB9KTtcblxuICAgIGlmICghcmVzLm9rKSB7XG4gICAgICB0aHJvdyBuZXcgU3RvcmFnZUVycm9yKHtcbiAgICAgICAgcmVhc29uOiBgSFRUUCAke3Jlcy5zdGF0dXN9OiAke3Jlcy5zdGF0dXNUZXh0fWAsXG4gICAgICB9KTtcbiAgICB9XG5cbiAgICBjb25zdCBqc29uID0gKGF3YWl0IHJlcy5qc29uKCkpIGFzIFJwY1Jlc3BvbnNlPFxuICAgICAgei5pbmZlcjxTdG9yYWdlTWV0aG9kc1tNXVtcInJlc3VsdFwiXT5cbiAgICA+O1xuXG4gICAgaWYgKFwiZXJyb3JcIiBpbiBqc29uKSB7XG4gICAgICB0aHJvdyBuZXcgU3RvcmFnZUVycm9yKHsgcmVhc29uOiBqc29uLmVycm9yLm1lc3NhZ2UgfSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGpzb24ucmVzdWx0O1xuICB9XG5cbiAgcmV0dXJuIHtcbiAgICBzZXNzaW9uOiB7XG4gICAgICBnZXQ6IGFzeW5jIChpZCkgPT4ge1xuICAgICAgICB0cnkge1xuICAgICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHJwYyhcInNlc3Npb24uZ2V0XCIsIHsgaWQgfSk7XG4gICAgICAgICAgaWYgKHJlc3VsdCA9PT0gbnVsbCkge1xuICAgICAgICAgICAgcmV0dXJuIG5ldyBTZXNzaW9uTm90Rm91bmRFcnJvcih7IGlkIH0pO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgaWYgKGUgaW5zdGFuY2VvZiBTdG9yYWdlRXJyb3IpIHtcbiAgICAgICAgICAgIHJldHVybiBlO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gbmV3IFN0b3JhZ2VFcnJvcih7IHJlYXNvbjogU3RyaW5nKGUpLCBjYXVzZTogZSB9KTtcbiAgICAgICAgfVxuICAgICAgfSxcbiAgICAgIHNldDogYXN5bmMgKHNlc3Npb24pID0+IHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICByZXR1cm4gYXdhaXQgcnBjKFwic2Vzc2lvbi5zZXRcIiwgc2Vzc2lvbik7XG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICBpZiAoZSBpbnN0YW5jZW9mIFN0b3JhZ2VFcnJvcikge1xuICAgICAgICAgICAgcmV0dXJuIGU7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybiBuZXcgU3RvcmFnZUVycm9yKHsgcmVhc29uOiBTdHJpbmcoZSksIGNhdXNlOiBlIH0pO1xuICAgICAgICB9XG4gICAgICB9LFxuICAgICAgbGlzdDogYXN5bmMgKG9wdHMpID0+IHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICByZXR1cm4gYXdhaXQgcnBjKFwic2Vzc2lvbi5saXN0XCIsIHtcbiAgICAgICAgICAgIHRhZ3M6IG9wdHM/LnRhZ3MsXG4gICAgICAgICAgICBvcmRlcjogb3B0cz8ub3JkZXIsXG4gICAgICAgICAgICBjdXJzb3I6IG9wdHM/LmN1cnNvcixcbiAgICAgICAgICAgIGxpbWl0OiBvcHRzPy5saW1pdCxcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgIGlmIChlIGluc3RhbmNlb2YgU3RvcmFnZUVycm9yKSB7XG4gICAgICAgICAgICByZXR1cm4gZTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIG5ldyBTdG9yYWdlRXJyb3IoeyByZWFzb246IFN0cmluZyhlKSwgY2F1c2U6IGUgfSk7XG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgICB0YWc6IHtcbiAgICAgICAgc2V0OiBhc3luYyAoeyBzZXNzaW9uSWQsIHRhZ3MgfSkgPT4ge1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICByZXR1cm4gYXdhaXQgcnBjKFwic2Vzc2lvbi50YWcuc2V0XCIsIHsgc2Vzc2lvbklkLCB0YWdzIH0pO1xuICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgIGlmIChlIGluc3RhbmNlb2YgU3RvcmFnZUVycm9yKSB7XG4gICAgICAgICAgICAgIHJldHVybiBlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIG5ldyBTdG9yYWdlRXJyb3IoeyByZWFzb246IFN0cmluZyhlKSwgY2F1c2U6IGUgfSk7XG4gICAgICAgICAgfVxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICB9LFxuICAgIG1lc3NhZ2U6IHtcbiAgICAgIGxpc3Q6IGFzeW5jIChzZXNzaW9uSWQsIG9wdHMpID0+IHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICByZXR1cm4gYXdhaXQgcnBjKFwibWVzc2FnZS5saXN0XCIsIHtcbiAgICAgICAgICAgIHNlc3Npb25JZCxcbiAgICAgICAgICAgIGN1cnNvcjogb3B0cz8uY3Vyc29yLFxuICAgICAgICAgICAgbGltaXQ6IG9wdHM/LmxpbWl0LFxuICAgICAgICAgIH0pO1xuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgaWYgKGUgaW5zdGFuY2VvZiBTdG9yYWdlRXJyb3IpIHtcbiAgICAgICAgICAgIHJldHVybiBlO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gbmV3IFN0b3JhZ2VFcnJvcih7IHJlYXNvbjogU3RyaW5nKGUpLCBjYXVzZTogZSB9KTtcbiAgICAgICAgfVxuICAgICAgfSxcbiAgICAgIGdldDogYXN5bmMgKGlkKSA9PiB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgcnBjKFwibWVzc2FnZS5nZXRcIiwgeyBpZCB9KTtcbiAgICAgICAgICBpZiAocmVzdWx0ID09PSBudWxsKSB7XG4gICAgICAgICAgICByZXR1cm4gbmV3IE1lc3NhZ2VOb3RGb3VuZEVycm9yKHsgaWQgfSk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICBpZiAoZSBpbnN0YW5jZW9mIFN0b3JhZ2VFcnJvcikge1xuICAgICAgICAgICAgcmV0dXJuIGU7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybiBuZXcgU3RvcmFnZUVycm9yKHsgcmVhc29uOiBTdHJpbmcoZSksIGNhdXNlOiBlIH0pO1xuICAgICAgICB9XG4gICAgICB9LFxuICAgICAgc2V0OiBhc3luYyAobWVzc2FnZSkgPT4ge1xuICAgICAgICB0cnkge1xuICAgICAgICAgIHJldHVybiBhd2FpdCBycGMoXCJtZXNzYWdlLnNldFwiLCBtZXNzYWdlKTtcbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgIGlmIChlIGluc3RhbmNlb2YgU3RvcmFnZUVycm9yKSB7XG4gICAgICAgICAgICByZXR1cm4gZTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIG5ldyBTdG9yYWdlRXJyb3IoeyByZWFzb246IFN0cmluZyhlKSwgY2F1c2U6IGUgfSk7XG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgfSxcbiAgICBwYXJ0OiB7XG4gICAgICBsaXN0QnlNZXNzYWdlOiBhc3luYyAobWVzc2FnZUlkLCBvcHRzKSA9PiB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgcnBjKFwicGFydC5saXN0QnlNZXNzYWdlXCIsIHtcbiAgICAgICAgICAgIG1lc3NhZ2VJZCxcbiAgICAgICAgICAgIGN1cnNvcjogb3B0cz8uY3Vyc29yLFxuICAgICAgICAgICAgbGltaXQ6IG9wdHM/LmxpbWl0LFxuICAgICAgICAgIH0pO1xuICAgICAgICAgIHJldHVybiByZXN1bHQgYXMgTGlzdFJlc3VsdDxQYXJ0PjtcbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgIGlmIChlIGluc3RhbmNlb2YgU3RvcmFnZUVycm9yKSB7XG4gICAgICAgICAgICByZXR1cm4gZTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIG5ldyBTdG9yYWdlRXJyb3IoeyByZWFzb246IFN0cmluZyhlKSwgY2F1c2U6IGUgfSk7XG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgICBsaXN0QnlTZXNzaW9uOiBhc3luYyAoc2Vzc2lvbklkLCBvcHRzKSA9PiB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgcnBjKFwicGFydC5saXN0QnlTZXNzaW9uXCIsIHtcbiAgICAgICAgICAgIHNlc3Npb25JZCxcbiAgICAgICAgICAgIGN1cnNvcjogb3B0cz8uY3Vyc29yLFxuICAgICAgICAgICAgbGltaXQ6IG9wdHM/LmxpbWl0LFxuICAgICAgICAgIH0pO1xuICAgICAgICAgIHJldHVybiByZXN1bHQgYXMgTGlzdFJlc3VsdDxQYXJ0PjtcbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgIGlmIChlIGluc3RhbmNlb2YgU3RvcmFnZUVycm9yKSB7XG4gICAgICAgICAgICByZXR1cm4gZTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIG5ldyBTdG9yYWdlRXJyb3IoeyByZWFzb246IFN0cmluZyhlKSwgY2F1c2U6IGUgfSk7XG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgICBzZXQ6IGFzeW5jIChwYXJ0KSA9PiB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgcmV0dXJuIChhd2FpdCBycGMoXCJwYXJ0LnNldFwiLCBwYXJ0KSkgYXMgUGFydDtcbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgIGlmIChlIGluc3RhbmNlb2YgU3RvcmFnZUVycm9yKSB7XG4gICAgICAgICAgICByZXR1cm4gZTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIG5ldyBTdG9yYWdlRXJyb3IoeyByZWFzb246IFN0cmluZyhlKSwgY2F1c2U6IGUgfSk7XG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgfSxcbiAgICBzYW5kYm94OiB7XG4gICAgICBnZXQ6IGFzeW5jIChrZXkpID0+IHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBycGMoXCJzYW5kYm94LmdldFwiLCB7IGtleSB9KTtcbiAgICAgICAgICBpZiAocmVzdWx0ID09PSBudWxsKSB7XG4gICAgICAgICAgICByZXR1cm4gbmV3IFNhbmRib3hOb3RGb3VuZEVycm9yKHsgaWQ6IGtleSB9KTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgIGlmIChlIGluc3RhbmNlb2YgU3RvcmFnZUVycm9yKSB7XG4gICAgICAgICAgICByZXR1cm4gZTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIG5ldyBTdG9yYWdlRXJyb3IoeyByZWFzb246IFN0cmluZyhlKSwgY2F1c2U6IGUgfSk7XG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgICBnZXRCeVNlc3Npb246IGFzeW5jIChzZXNzaW9uSWQpID0+IHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBycGMoXCJzYW5kYm94LmdldEJ5U2Vzc2lvblwiLCB7IHNlc3Npb25JZCB9KTtcbiAgICAgICAgICBpZiAocmVzdWx0ID09PSBudWxsKSB7XG4gICAgICAgICAgICByZXR1cm4gbmV3IFNhbmRib3hOb3RGb3VuZEVycm9yKHsgaWQ6IHNlc3Npb25JZCB9KTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgIGlmIChlIGluc3RhbmNlb2YgU3RvcmFnZUVycm9yKSB7XG4gICAgICAgICAgICByZXR1cm4gZTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIG5ldyBTdG9yYWdlRXJyb3IoeyByZWFzb246IFN0cmluZyhlKSwgY2F1c2U6IGUgfSk7XG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgICBzZXQ6IGFzeW5jIChyZWNvcmQpID0+IHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBhd2FpdCBycGMoXCJzYW5kYm94LnNldFwiLCByZWNvcmQpO1xuICAgICAgICAgIHJldHVybiByZWNvcmQ7XG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICBpZiAoZSBpbnN0YW5jZW9mIFN0b3JhZ2VFcnJvcikge1xuICAgICAgICAgICAgcmV0dXJuIGU7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybiBuZXcgU3RvcmFnZUVycm9yKHsgcmVhc29uOiBTdHJpbmcoZSksIGNhdXNlOiBlIH0pO1xuICAgICAgICB9XG4gICAgICB9LFxuICAgIH0sXG4gICAgY29tbWFuZDoge1xuICAgICAgZ2V0OiBhc3luYyAoaWQpID0+IHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICByZXR1cm4gKGF3YWl0IHJwYyhcImNvbW1hbmQuZ2V0XCIsIHsgaWQgfSkpIGFzIENvbW1hbmQgfCBudWxsO1xuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgaWYgKGUgaW5zdGFuY2VvZiBTdG9yYWdlRXJyb3IpIHtcbiAgICAgICAgICAgIHJldHVybiBlO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gbmV3IFN0b3JhZ2VFcnJvcih7IHJlYXNvbjogU3RyaW5nKGUpLCBjYXVzZTogZSB9KTtcbiAgICAgICAgfVxuICAgICAgfSxcbiAgICAgIHNldDogYXN5bmMgKGNvbW1hbmQpID0+IHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICByZXR1cm4gKGF3YWl0IHJwYyhcImNvbW1hbmQuc2V0XCIsIGNvbW1hbmQpKSBhcyBDb21tYW5kO1xuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgaWYgKGUgaW5zdGFuY2VvZiBTdG9yYWdlRXJyb3IpIHtcbiAgICAgICAgICAgIHJldHVybiBlO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gbmV3IFN0b3JhZ2VFcnJvcih7IHJlYXNvbjogU3RyaW5nKGUpLCBjYXVzZTogZSB9KTtcbiAgICAgICAgfVxuICAgICAgfSxcbiAgICAgIGxpc3Q6IGFzeW5jIChzZXNzaW9uSWQsIG9wdHMpID0+IHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBycGMoXCJjb21tYW5kLmxpc3RcIiwge1xuICAgICAgICAgICAgc2Vzc2lvbklkLFxuICAgICAgICAgICAgaW5jbHVkZUZpbmlzaGVkOiBvcHRzPy5pbmNsdWRlRmluaXNoZWQsXG4gICAgICAgICAgICBjdXJzb3I6IG9wdHM/LmN1cnNvcixcbiAgICAgICAgICAgIGxpbWl0OiBvcHRzPy5saW1pdCxcbiAgICAgICAgICB9KTtcbiAgICAgICAgICByZXR1cm4gcmVzdWx0IGFzIExpc3RSZXN1bHQ8Q29tbWFuZD47XG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICBpZiAoZSBpbnN0YW5jZW9mIFN0b3JhZ2VFcnJvcikge1xuICAgICAgICAgICAgcmV0dXJuIGU7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybiBuZXcgU3RvcmFnZUVycm9yKHsgcmVhc29uOiBTdHJpbmcoZSksIGNhdXNlOiBlIH0pO1xuICAgICAgICB9XG4gICAgICB9LFxuICAgIH0sXG4gIH07XG59XG5cbmFzeW5jIGZ1bmN0aW9uIHJlc29sdmVTdG9yYWdlVXJsKFxuICBjb25maWc6IFN0b3JhZ2VDb25maWdcbik6IFByb21pc2U8UmVzb2x2ZWRTdG9yYWdlPiB7XG4gIHN3aXRjaCAoY29uZmlnLnR5cGUpIHtcbiAgICBjYXNlIFwibG9jYWxcIjoge1xuICAgICAgY29uc3QgeyBzdGFydExvY2FsU3RvcmFnZSB9ID0gYXdhaXQgaW1wb3J0KFwiLi9iaW5kaW5ncy9sb2NhbFwiKTtcbiAgICAgIHJldHVybiB7IHVybDogYXdhaXQgc3RhcnRMb2NhbFN0b3JhZ2UoeyBwYXRoOiBjb25maWcucGF0aCB9KSB9O1xuICAgIH1cbiAgICBjYXNlIFwidmVyY2VsXCI6IHtcbiAgICAgIGNvbnN0IHsgZ2V0VmVyY2VsU3RvcmFnZUNvbmZpZyB9ID0gYXdhaXQgaW1wb3J0KFwiLi9iaW5kaW5ncy92ZXJjZWxcIik7XG4gICAgICByZXR1cm4gZ2V0VmVyY2VsU3RvcmFnZUNvbmZpZygpO1xuICAgIH1cbiAgICBjYXNlIFwiY3VzdG9tXCI6IHtcbiAgICAgIHJldHVybiB7IHVybDogY29uZmlnLnVybCwgaGVhZGVyczogY29uZmlnLmhlYWRlcnMgfTtcbiAgICB9XG4gICAgZGVmYXVsdDoge1xuICAgICAgY29uZmlnIHNhdGlzZmllcyBuZXZlcjtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgYFVua25vd24gc3RvcmFnZSB0eXBlOiAkeyhjb25maWcgYXMgeyB0eXBlOiBzdHJpbmcgfSkudHlwZX1gXG4gICAgICApO1xuICAgIH1cbiAgfVxufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0U3RvcmFnZShzdG9yYWdlQ29uZmlnOiBTdG9yYWdlQ29uZmlnKTogU3RvcmFnZSB7XG4gIGxldCBjbGllbnRQcm9taXNlOiBQcm9taXNlPFN0b3JhZ2U+IHwgbnVsbCA9IG51bGw7XG4gIGNvbnN0IGdldENsaWVudCA9ICgpID0+IHtcbiAgICBpZiAoIWNsaWVudFByb21pc2UpIHtcbiAgICAgIGNsaWVudFByb21pc2UgPSByZXNvbHZlU3RvcmFnZVVybChzdG9yYWdlQ29uZmlnKS50aGVuKChyZXNvbHZlZCkgPT5cbiAgICAgICAgZ2V0U3RvcmFnZUNsaWVudChyZXNvbHZlZClcbiAgICAgICk7XG4gICAgfVxuICAgIHJldHVybiBjbGllbnRQcm9taXNlO1xuICB9O1xuXG4gIHJldHVybiB7XG4gICAgc2Vzc2lvbjoge1xuICAgICAgZ2V0OiBhc3luYyAoaWQpID0+IChhd2FpdCBnZXRDbGllbnQoKSkuc2Vzc2lvbi5nZXQoaWQpLFxuICAgICAgc2V0OiBhc3luYyAoc2Vzc2lvbikgPT4gKGF3YWl0IGdldENsaWVudCgpKS5zZXNzaW9uLnNldChzZXNzaW9uKSxcbiAgICAgIGxpc3Q6IGFzeW5jIChvcHRzKSA9PiAoYXdhaXQgZ2V0Q2xpZW50KCkpLnNlc3Npb24ubGlzdChvcHRzKSxcbiAgICAgIHRhZzoge1xuICAgICAgICBzZXQ6IGFzeW5jIChvcHRzKSA9PiAoYXdhaXQgZ2V0Q2xpZW50KCkpLnNlc3Npb24udGFnLnNldChvcHRzKSxcbiAgICAgIH0sXG4gICAgfSxcbiAgICBtZXNzYWdlOiB7XG4gICAgICBsaXN0OiBhc3luYyAoc2Vzc2lvbklkLCBvcHRzKSA9PlxuICAgICAgICAoYXdhaXQgZ2V0Q2xpZW50KCkpLm1lc3NhZ2UubGlzdChzZXNzaW9uSWQsIG9wdHMpLFxuICAgICAgZ2V0OiBhc3luYyAoaWQpID0+IChhd2FpdCBnZXRDbGllbnQoKSkubWVzc2FnZS5nZXQoaWQpLFxuICAgICAgc2V0OiBhc3luYyAobWVzc2FnZSkgPT4gKGF3YWl0IGdldENsaWVudCgpKS5tZXNzYWdlLnNldChtZXNzYWdlKSxcbiAgICB9LFxuICAgIHBhcnQ6IHtcbiAgICAgIGxpc3RCeU1lc3NhZ2U6IGFzeW5jIChtZXNzYWdlSWQsIG9wdHMpID0+XG4gICAgICAgIChhd2FpdCBnZXRDbGllbnQoKSkucGFydC5saXN0QnlNZXNzYWdlKG1lc3NhZ2VJZCwgb3B0cyksXG4gICAgICBsaXN0QnlTZXNzaW9uOiBhc3luYyAoc2Vzc2lvbklkLCBvcHRzKSA9PlxuICAgICAgICAoYXdhaXQgZ2V0Q2xpZW50KCkpLnBhcnQubGlzdEJ5U2Vzc2lvbihzZXNzaW9uSWQsIG9wdHMpLFxuICAgICAgc2V0OiBhc3luYyAocGFydCkgPT4gKGF3YWl0IGdldENsaWVudCgpKS5wYXJ0LnNldChwYXJ0KSxcbiAgICB9LFxuICAgIHNhbmRib3g6IHtcbiAgICAgIGdldDogYXN5bmMgKGtleSkgPT4gKGF3YWl0IGdldENsaWVudCgpKS5zYW5kYm94LmdldChrZXkpLFxuICAgICAgc2V0OiBhc3luYyAob3B0cykgPT4gKGF3YWl0IGdldENsaWVudCgpKS5zYW5kYm94LnNldChvcHRzKSxcbiAgICAgIGdldEJ5U2Vzc2lvbjogYXN5bmMgKHNlc3Npb25JZCkgPT5cbiAgICAgICAgKGF3YWl0IGdldENsaWVudCgpKS5zYW5kYm94LmdldEJ5U2Vzc2lvbihzZXNzaW9uSWQpLFxuICAgIH0sXG4gICAgY29tbWFuZDoge1xuICAgICAgZ2V0OiBhc3luYyAoaWQpID0+IChhd2FpdCBnZXRDbGllbnQoKSkuY29tbWFuZC5nZXQoaWQpLFxuICAgICAgc2V0OiBhc3luYyAoY29tbWFuZCkgPT4gKGF3YWl0IGdldENsaWVudCgpKS5jb21tYW5kLnNldChjb21tYW5kKSxcbiAgICAgIGxpc3Q6IGFzeW5jIChzZXNzaW9uSWQsIG9wdHMpID0+XG4gICAgICAgIChhd2FpdCBnZXRDbGllbnQoKSkuY29tbWFuZC5saXN0KHNlc3Npb25JZCwgb3B0cyksXG4gICAgfSxcbiAgfTtcbn1cbiIsICJpbXBvcnQgeyB6IH0gZnJvbSBcInpvZFwiO1xuXG5jb25zdCBWZXJjZWxMaWZlY3ljbGVDb25maWdTY2hlbWEgPSB6Lm9iamVjdCh7XG4gIHN0b3BBZnRlckluYWN0aXZlTXM6IHoubnVtYmVyKCkub3B0aW9uYWwoKSxcbiAgc25hcHNob3RCZWZvcmVUaW1lb3V0TXM6IHoubnVtYmVyKCkub3B0aW9uYWwoKSxcbiAgc25hcHNob3RJZDogei5zdHJpbmcoKS5vcHRpb25hbCgpLFxuICBhdXRvU3RhcnQ6IHouYm9vbGVhbigpLm9wdGlvbmFsKCksXG59KTtcblxuZXhwb3J0IGNvbnN0IFNhbmRib3hDb25maWdTY2hlbWEgPSB6LmRpc2NyaW1pbmF0ZWRVbmlvbihcInR5cGVcIiwgW1xuICB6Lm9iamVjdCh7XG4gICAgdHlwZTogei5saXRlcmFsKFwidmVyY2VsXCIpLFxuICAgIHJlc291cmNlczogei5vYmplY3QoeyB2Y3B1czogei5udW1iZXIoKSB9KS5vcHRpb25hbCgpLFxuICAgIHBvcnRzOiB6LmFycmF5KHoubnVtYmVyKCkpLm9wdGlvbmFsKCksXG4gICAgbGlmZWN5Y2xlOiBWZXJjZWxMaWZlY3ljbGVDb25maWdTY2hlbWEub3B0aW9uYWwoKSxcbiAgfSksXG4gIHoub2JqZWN0KHtcbiAgICB0eXBlOiB6LmxpdGVyYWwoXCJsb2NhbFwiKSxcbiAgICBwYXRoOiB6LnN0cmluZygpLm9wdGlvbmFsKCksXG4gIH0pLFxuICB6Lm9iamVjdCh7XG4gICAgdHlwZTogei5saXRlcmFsKFwiY3VzdG9tXCIpLFxuICAgIHVybDogei5zdHJpbmcoKSxcbiAgICBoZWFkZXJzOiB6LnJlY29yZCh6LnN0cmluZygpLCB6LnN0cmluZygpKS5vcHRpb25hbCgpLFxuICB9KSxcbl0pO1xuXG5leHBvcnQgdHlwZSBTYW5kYm94Q29uZmlnID0gei5pbmZlcjx0eXBlb2YgU2FuZGJveENvbmZpZ1NjaGVtYT47XG5cbmV4cG9ydCBjb25zdCBTZXNzaW9uU2NoZW1hID0gei5vYmplY3Qoe1xuICBpZDogei5zdHJpbmcoKSxcbiAgY3JlYXRlZEF0OiB6Lm51bWJlcigpLFxuICB1cGRhdGVkQXQ6IHoubnVtYmVyKCksXG4gIHJ1bklkOiB6LnN0cmluZygpLm51bGxhYmxlKCksXG4gIGxhc3RNZXNzYWdlSWQ6IHouc3RyaW5nKCkubnVsbGFibGUoKSxcbiAgdGFnczogei5yZWNvcmQoei5zdHJpbmcoKSwgei51bmtub3duKCkpLm51bGxhYmxlKCksXG4gIGluc3RydWN0aW9uczogei5zdHJpbmcoKS5udWxsYWJsZSgpLFxuICBtb2RlbDogei5zdHJpbmcoKS5udWxsYWJsZSgpLFxuICBtY3A6IHoudW5rbm93bigpLm51bGxhYmxlKCksIC8vIFRPRE9cbiAgc2FuZGJveElkOiB6LnN0cmluZygpLm51bGxhYmxlKCksXG4gIHNraWxsc0Rpcjogei5hcnJheSh6LnN0cmluZygpKS5udWxsYWJsZSgpLFxuICBob29rVG9rZW46IHouc3RyaW5nKCkubnVsbGFibGUoKSxcbn0pO1xuXG5leHBvcnQgY29uc3QgTWVzc2FnZVNjaGVtYSA9IHoub2JqZWN0KHtcbiAgaWQ6IHouc3RyaW5nKCksXG4gIHNlc3Npb25JZDogei5zdHJpbmcoKSxcbiAgcm9sZTogei5lbnVtKFtcInVzZXJcIiwgXCJhc3Npc3RhbnRcIiwgXCJzeXN0ZW1cIl0pLFxuICBjcmVhdGVkQXQ6IHoubnVtYmVyKCksXG4gIGNvbXBsZXRlZEF0OiB6Lm51bWJlcigpLm51bGxhYmxlKCksXG4gIG1jcENvbnRleHQ6IHoudW5rbm93bigpLm51bGxhYmxlKCksXG59KTtcblxuLyoqXG4gKiBUaGUgYHBhcnRgIGZpZWxkIGNvcnJlc3BvbmRzIHRvIGBVSU1lc3NhZ2VbXCJwYXJ0c1wiXVtudW1iZXJdYCBmcm9tIHRoZSBgYWlgIHBhY2thZ2UuXG4gKiBXZSB1c2UgYHoudW5rbm93bigpYCBiZWNhdXNlIHRoZSBleGFjdCBzaGFwZSB2YXJpZXMgYnkgcGFydCB0eXBlICh0ZXh0LCB0b29sLWNhbGwsXG4gKiB0b29sLXJlc3VsdCwgZXRjLikgYW5kIG1heSBldm9sdmUgd2l0aCB0aGUgQUkgU0RLLiBUaGUgUlBDIGxheWVyIGp1c3QgcGFzc2VzIGl0IHRocm91Z2guXG4gKi9cbmV4cG9ydCBjb25zdCBQYXJ0U2NoZW1hID0gei5vYmplY3Qoe1xuICBpZDogei5zdHJpbmcoKSxcbiAgbWVzc2FnZUlkOiB6LnN0cmluZygpLFxuICBzZXNzaW9uSWQ6IHouc3RyaW5nKCksXG4gIGluZGV4OiB6Lm51bWJlcigpLFxuICBwYXJ0OiB6LnVua25vd24oKSxcbn0pO1xuXG5leHBvcnQgY29uc3QgQ29tbWFuZFJlc3VsdFNjaGVtYSA9IHoub2JqZWN0KHtcbiAgc3Rkb3V0OiB6LnN0cmluZygpLFxuICBzdGRlcnI6IHouc3RyaW5nKCksXG4gIGV4aXRDb2RlOiB6Lm51bWJlcigpLFxuICBjb21wbGV0ZWRBdDogei5udW1iZXIoKSxcbn0pO1xuXG5leHBvcnQgY29uc3QgU2FuZGJveFJlY29yZFNjaGVtYSA9IHoub2JqZWN0KHtcbiAgaWQ6IHouc3RyaW5nKCksXG4gIGNvbmZpZzogU2FuZGJveENvbmZpZ1NjaGVtYSxcbiAgY3JlYXRlZEF0OiB6Lm51bWJlcigpLm51bGxhYmxlKCksXG4gIGxhc3RBY3Rpdml0eUF0OiB6Lm51bWJlcigpLm51bGxhYmxlKCksXG4gIGFjcXVpcmluZ0xvY2tJZDogei5zdHJpbmcoKS5udWxsYWJsZSgpLFxuICBhY3F1aXJpbmdMb2NrQXQ6IHoubnVtYmVyKCkubnVsbGFibGUoKSxcbiAgcHJvdmlkZXJNZXRhZGF0YTogelxuICAgIC5kaXNjcmltaW5hdGVkVW5pb24oXCJwcm92aWRlclwiLCBbXG4gICAgICB6Lm9iamVjdCh7XG4gICAgICAgIHByb3ZpZGVyOiB6LmxpdGVyYWwoXCJ2ZXJjZWxcIiksXG4gICAgICAgIHNhbmRib3hJZDogei5zdHJpbmcoKS5udWxsYWJsZSgpLFxuICAgICAgICBzbmFwc2hvdElkOiB6LnN0cmluZygpLm51bGxhYmxlKCksXG4gICAgICB9KSxcbiAgICBdKVxuICAgIC5vcHRpb25hbCgpLFxufSk7XG5cbmNvbnN0IENvbW1hbmRCYXNlU2NoZW1hID0gei5vYmplY3Qoe1xuICBpZDogei5zdHJpbmcoKSxcbiAgc2Vzc2lvbklkOiB6LnN0cmluZygpLFxuICBjb21tYW5kOiB6LnN0cmluZygpLFxuICBhcmdzOiB6LmFycmF5KHouc3RyaW5nKCkpLm9wdGlvbmFsKCksXG4gIHN0YXJ0ZWRBdDogei5udW1iZXIoKSxcbn0pO1xuXG5leHBvcnQgY29uc3QgQ29tbWFuZFNjaGVtYSA9IHouZGlzY3JpbWluYXRlZFVuaW9uKFwic3RhdHVzXCIsIFtcbiAgQ29tbWFuZEJhc2VTY2hlbWEuZXh0ZW5kKHsgc3RhdHVzOiB6LmxpdGVyYWwoXCJydW5uaW5nXCIpIH0pLFxuICBDb21tYW5kQmFzZVNjaGVtYS5leHRlbmQoe1xuICAgIHN0YXR1czogei5saXRlcmFsKFwiY29tcGxldGVkXCIpLFxuICAgIHJlc3VsdDogQ29tbWFuZFJlc3VsdFNjaGVtYSxcbiAgfSksXG4gIENvbW1hbmRCYXNlU2NoZW1hLmV4dGVuZCh7XG4gICAgc3RhdHVzOiB6LmxpdGVyYWwoXCJraWxsZWRcIiksXG4gICAgcmVzdWx0OiBDb21tYW5kUmVzdWx0U2NoZW1hLm9wdGlvbmFsKCksXG4gIH0pLFxuICBDb21tYW5kQmFzZVNjaGVtYS5leHRlbmQoe1xuICAgIHN0YXR1czogei5saXRlcmFsKFwiZmFpbGVkXCIpLFxuICAgIHJlc3VsdDogQ29tbWFuZFJlc3VsdFNjaGVtYSxcbiAgfSksXG5dKTtcblxuZnVuY3Rpb24gTGlzdFJlc3VsdFNjaGVtYTxUIGV4dGVuZHMgei5ab2RUeXBlQW55PihpdGVtU2NoZW1hOiBUKSB7XG4gIHJldHVybiB6Lm9iamVjdCh7XG4gICAgaXRlbXM6IHouYXJyYXkoaXRlbVNjaGVtYSksXG4gICAgbmV4dEN1cnNvcjogei5zdHJpbmcoKS5udWxsYWJsZSgpLFxuICB9KTtcbn1cblxuZXhwb3J0IGNvbnN0IG1ldGhvZHMgPSB7XG4gIFwic2Vzc2lvbi5nZXRcIjoge1xuICAgIHBhcmFtczogei5vYmplY3QoeyBpZDogei5zdHJpbmcoKSB9KSxcbiAgICByZXN1bHQ6IFNlc3Npb25TY2hlbWEubnVsbGFibGUoKSxcbiAgfSxcbiAgXCJzZXNzaW9uLnNldFwiOiB7XG4gICAgcGFyYW1zOiBTZXNzaW9uU2NoZW1hLFxuICAgIHJlc3VsdDogU2Vzc2lvblNjaGVtYSxcbiAgfSxcbiAgXCJzZXNzaW9uLmxpc3RcIjoge1xuICAgIHBhcmFtczogei5vYmplY3Qoe1xuICAgICAgdGFnczogei5yZWNvcmQoei5zdHJpbmcoKSwgei51bmtub3duKCkpLm9wdGlvbmFsKCksXG4gICAgICBvcmRlcjogelxuICAgICAgICAuZW51bShbXG4gICAgICAgICAgXCJjcmVhdGVkQXRfYXNjXCIsXG4gICAgICAgICAgXCJjcmVhdGVkQXRfZGVzY1wiLFxuICAgICAgICAgIFwidXBkYXRlZEF0X2FzY1wiLFxuICAgICAgICAgIFwidXBkYXRlZEF0X2Rlc2NcIixcbiAgICAgICAgXSlcbiAgICAgICAgLm9wdGlvbmFsKCksXG4gICAgICBjdXJzb3I6IHouc3RyaW5nKCkub3B0aW9uYWwoKSxcbiAgICAgIGxpbWl0OiB6Lm51bWJlcigpLm9wdGlvbmFsKCksXG4gICAgfSksXG4gICAgcmVzdWx0OiBMaXN0UmVzdWx0U2NoZW1hKFNlc3Npb25TY2hlbWEpLFxuICB9LFxuICBcInNlc3Npb24ubGlzdEJ5U2FuZGJveFwiOiB7XG4gICAgcGFyYW1zOiB6Lm9iamVjdCh7XG4gICAgICBzYW5kYm94SWQ6IHouc3RyaW5nKCksXG4gICAgICB0YWdzOiB6LnJlY29yZCh6LnN0cmluZygpLCB6LnVua25vd24oKSkub3B0aW9uYWwoKSxcbiAgICAgIG9yZGVyOiB6XG4gICAgICAgIC5lbnVtKFtcbiAgICAgICAgICBcImNyZWF0ZWRBdF9hc2NcIixcbiAgICAgICAgICBcImNyZWF0ZWRBdF9kZXNjXCIsXG4gICAgICAgICAgXCJ1cGRhdGVkQXRfYXNjXCIsXG4gICAgICAgICAgXCJ1cGRhdGVkQXRfZGVzY1wiLFxuICAgICAgICBdKVxuICAgICAgICAub3B0aW9uYWwoKSxcbiAgICAgIGN1cnNvcjogei5zdHJpbmcoKS5vcHRpb25hbCgpLFxuICAgICAgbGltaXQ6IHoubnVtYmVyKCkub3B0aW9uYWwoKSxcbiAgICB9KSxcbiAgICByZXN1bHQ6IExpc3RSZXN1bHRTY2hlbWEoU2Vzc2lvblNjaGVtYSksXG4gIH0sXG4gIFwic2Vzc2lvbi50YWcuc2V0XCI6IHtcbiAgICBwYXJhbXM6IHoub2JqZWN0KHtcbiAgICAgIHNlc3Npb25JZDogei5zdHJpbmcoKSxcbiAgICAgIHRhZ3M6IHoucmVjb3JkKHouc3RyaW5nKCksIHoudW5rbm93bigpKSxcbiAgICB9KSxcbiAgICByZXN1bHQ6IFNlc3Npb25TY2hlbWEsXG4gIH0sXG4gIFwibWVzc2FnZS5nZXRcIjoge1xuICAgIHBhcmFtczogei5vYmplY3QoeyBpZDogei5zdHJpbmcoKSB9KSxcbiAgICByZXN1bHQ6IE1lc3NhZ2VTY2hlbWEubnVsbGFibGUoKSxcbiAgfSxcbiAgXCJtZXNzYWdlLnNldFwiOiB7XG4gICAgcGFyYW1zOiBNZXNzYWdlU2NoZW1hLFxuICAgIHJlc3VsdDogTWVzc2FnZVNjaGVtYSxcbiAgfSxcbiAgXCJtZXNzYWdlLmxpc3RcIjoge1xuICAgIHBhcmFtczogei5vYmplY3Qoe1xuICAgICAgc2Vzc2lvbklkOiB6LnN0cmluZygpLFxuICAgICAgY3Vyc29yOiB6LnN0cmluZygpLm9wdGlvbmFsKCksXG4gICAgICBsaW1pdDogei5udW1iZXIoKS5vcHRpb25hbCgpLFxuICAgIH0pLFxuICAgIHJlc3VsdDogTGlzdFJlc3VsdFNjaGVtYShNZXNzYWdlU2NoZW1hKSxcbiAgfSxcbiAgXCJwYXJ0Lmxpc3RCeU1lc3NhZ2VcIjoge1xuICAgIHBhcmFtczogei5vYmplY3Qoe1xuICAgICAgbWVzc2FnZUlkOiB6LnN0cmluZygpLFxuICAgICAgY3Vyc29yOiB6LnN0cmluZygpLm9wdGlvbmFsKCksXG4gICAgICBsaW1pdDogei5udW1iZXIoKS5vcHRpb25hbCgpLFxuICAgIH0pLFxuICAgIHJlc3VsdDogTGlzdFJlc3VsdFNjaGVtYShQYXJ0U2NoZW1hKSxcbiAgfSxcbiAgXCJwYXJ0Lmxpc3RCeVNlc3Npb25cIjoge1xuICAgIHBhcmFtczogei5vYmplY3Qoe1xuICAgICAgc2Vzc2lvbklkOiB6LnN0cmluZygpLFxuICAgICAgY3Vyc29yOiB6LnN0cmluZygpLm9wdGlvbmFsKCksXG4gICAgICBsaW1pdDogei5udW1iZXIoKS5vcHRpb25hbCgpLFxuICAgIH0pLFxuICAgIHJlc3VsdDogTGlzdFJlc3VsdFNjaGVtYShQYXJ0U2NoZW1hKSxcbiAgfSxcbiAgXCJwYXJ0LnNldFwiOiB7XG4gICAgcGFyYW1zOiBQYXJ0U2NoZW1hLFxuICAgIHJlc3VsdDogUGFydFNjaGVtYSxcbiAgfSxcbiAgXCJzYW5kYm94LmdldFwiOiB7XG4gICAgcGFyYW1zOiB6Lm9iamVjdCh7IGtleTogei5zdHJpbmcoKSB9KSxcbiAgICByZXN1bHQ6IFNhbmRib3hSZWNvcmRTY2hlbWEubnVsbGFibGUoKSxcbiAgfSxcbiAgXCJzYW5kYm94LmdldEJ5U2Vzc2lvblwiOiB7XG4gICAgcGFyYW1zOiB6Lm9iamVjdCh7IHNlc3Npb25JZDogei5zdHJpbmcoKSB9KSxcbiAgICByZXN1bHQ6IFNhbmRib3hSZWNvcmRTY2hlbWEubnVsbGFibGUoKSxcbiAgfSxcbiAgXCJzYW5kYm94LnNldFwiOiB7XG4gICAgcGFyYW1zOiBTYW5kYm94UmVjb3JkU2NoZW1hLFxuICAgIHJlc3VsdDogei52b2lkKCksXG4gIH0sXG4gIFwiY29tbWFuZC5nZXRcIjoge1xuICAgIHBhcmFtczogei5vYmplY3QoeyBpZDogei5zdHJpbmcoKSB9KSxcbiAgICByZXN1bHQ6IENvbW1hbmRTY2hlbWEubnVsbGFibGUoKSxcbiAgfSxcbiAgXCJjb21tYW5kLnNldFwiOiB7XG4gICAgcGFyYW1zOiBDb21tYW5kU2NoZW1hLFxuICAgIHJlc3VsdDogQ29tbWFuZFNjaGVtYSxcbiAgfSxcbiAgXCJjb21tYW5kLmxpc3RcIjoge1xuICAgIHBhcmFtczogei5vYmplY3Qoe1xuICAgICAgc2Vzc2lvbklkOiB6LnN0cmluZygpLFxuICAgICAgaW5jbHVkZUZpbmlzaGVkOiB6LmJvb2xlYW4oKS5vcHRpb25hbCgpLFxuICAgICAgY3Vyc29yOiB6LnN0cmluZygpLm9wdGlvbmFsKCksXG4gICAgICBsaW1pdDogei5udW1iZXIoKS5vcHRpb25hbCgpLFxuICAgIH0pLFxuICAgIHJlc3VsdDogTGlzdFJlc3VsdFNjaGVtYShDb21tYW5kU2NoZW1hKSxcbiAgfSxcbn0gYXMgY29uc3Q7XG5cbmV4cG9ydCB0eXBlIFN0b3JhZ2VNZXRob2RzID0gdHlwZW9mIG1ldGhvZHM7XG5leHBvcnQgdHlwZSBNZXRob2ROYW1lID0ga2V5b2YgU3RvcmFnZU1ldGhvZHM7XG4iLCAiaW1wb3J0IHR5cGUgeyB6IH0gZnJvbSBcInpvZFwiO1xuaW1wb3J0IHsgdHlwZSBNZXRob2ROYW1lLCBtZXRob2RzLCB0eXBlIFN0b3JhZ2VNZXRob2RzIH0gZnJvbSBcIi4vcnBjXCI7XG5cbmV4cG9ydCB0eXBlIEhhbmRsZXJzID0ge1xuICBbSyBpbiBNZXRob2ROYW1lXTogKFxuICAgIHBhcmFtczogei5pbmZlcjxTdG9yYWdlTWV0aG9kc1tLXVtcInBhcmFtc1wiXT5cbiAgKSA9PiBQcm9taXNlPHouaW5mZXI8U3RvcmFnZU1ldGhvZHNbS11bXCJyZXN1bHRcIl0+Pjtcbn07XG5cbmV4cG9ydCB0eXBlIFJwY1JlcXVlc3QgPSB7XG4gIG1ldGhvZDogc3RyaW5nO1xuICBwYXJhbXM6IHVua25vd247XG59O1xuXG5leHBvcnQgdHlwZSBScGNTdWNjZXNzUmVzcG9uc2U8VCA9IHVua25vd24+ID0ge1xuICByZXN1bHQ6IFQ7XG59O1xuXG5leHBvcnQgdHlwZSBScGNFcnJvclJlc3BvbnNlID0ge1xuICBlcnJvcjogeyBjb2RlOiBzdHJpbmc7IG1lc3NhZ2U6IHN0cmluZyB9O1xufTtcblxuZXhwb3J0IHR5cGUgUnBjUmVzcG9uc2U8VCA9IHVua25vd24+ID0gUnBjU3VjY2Vzc1Jlc3BvbnNlPFQ+IHwgUnBjRXJyb3JSZXNwb25zZTtcblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGhhbmRsZVN0b3JhZ2VScGMoXG4gIGJvZHk6IFJwY1JlcXVlc3QsXG4gIGhhbmRsZXJzOiBIYW5kbGVyc1xuKTogUHJvbWlzZTxScGNSZXNwb25zZT4ge1xuICBjb25zdCB7IG1ldGhvZCwgcGFyYW1zIH0gPSBib2R5O1xuXG4gIGlmICghKG1ldGhvZCBpbiBtZXRob2RzKSkge1xuICAgIHJldHVybiB7XG4gICAgICBlcnJvcjogeyBjb2RlOiBcIk1FVEhPRF9OT1RfRk9VTkRcIiwgbWVzc2FnZTogYFVua25vd24gbWV0aG9kOiAke21ldGhvZH1gIH0sXG4gICAgfTtcbiAgfVxuXG4gIGNvbnN0IG1ldGhvZE5hbWUgPSBtZXRob2QgYXMgTWV0aG9kTmFtZTtcbiAgY29uc3Qgc2NoZW1hID0gbWV0aG9kc1ttZXRob2ROYW1lXS5wYXJhbXM7XG4gIGNvbnN0IHBhcnNlZCA9IHNjaGVtYS5zYWZlUGFyc2UocGFyYW1zKTtcblxuICBpZiAoIXBhcnNlZC5zdWNjZXNzKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIGVycm9yOiB7XG4gICAgICAgIGNvZGU6IFwiSU5WQUxJRF9QQVJBTVNcIixcbiAgICAgICAgbWVzc2FnZTogcGFyc2VkLmVycm9yLmlzc3Vlc1xuICAgICAgICAgIC5tYXAoKGkpID0+IGAke2kucGF0aC5qb2luKFwiLlwiKX06ICR7aS5tZXNzYWdlfWApXG4gICAgICAgICAgLmpvaW4oXCIsIFwiKSxcbiAgICAgIH0sXG4gICAgfTtcbiAgfVxuXG4gIHRyeSB7XG4gICAgY29uc3QgaGFuZGxlciA9IGhhbmRsZXJzW21ldGhvZE5hbWVdIGFzIChcbiAgICAgIHBhcmFtczogdW5rbm93blxuICAgICkgPT4gUHJvbWlzZTx1bmtub3duPjtcbiAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBoYW5kbGVyKHBhcnNlZC5kYXRhKTtcbiAgICByZXR1cm4geyByZXN1bHQgfTtcbiAgfSBjYXRjaCAoZSkge1xuICAgIHJldHVybiB7XG4gICAgICBlcnJvcjoge1xuICAgICAgICBjb2RlOiBcIklOVEVSTkFMX0VSUk9SXCIsXG4gICAgICAgIG1lc3NhZ2U6IGUgaW5zdGFuY2VvZiBFcnJvciA/IGUubWVzc2FnZSA6IFN0cmluZyhlKSxcbiAgICAgIH0sXG4gICAgfTtcbiAgfVxufVxuIiwgImV4cG9ydCB7IGdldFN0b3JhZ2UgfSBmcm9tIFwiLi9jbGllbnRcIjtcbmV4cG9ydCB7XG4gIHR5cGUgSGFuZGxlcnMsXG4gIGhhbmRsZVN0b3JhZ2VScGMsXG4gIHR5cGUgUnBjRXJyb3JSZXNwb25zZSxcbiAgdHlwZSBScGNSZXF1ZXN0LFxuICB0eXBlIFJwY1Jlc3BvbnNlLFxuICB0eXBlIFJwY1N1Y2Nlc3NSZXNwb25zZSxcbn0gZnJvbSBcIi4vaGFuZGxlclwiO1xuZXhwb3J0IHtcbiAgQ29tbWFuZFJlc3VsdFNjaGVtYSxcbiAgQ29tbWFuZFNjaGVtYSxcbiAgTWVzc2FnZVNjaGVtYSxcbiAgdHlwZSBNZXRob2ROYW1lLFxuICBtZXRob2RzLFxuICBQYXJ0U2NoZW1hLFxuICB0eXBlIFNhbmRib3hDb25maWcsXG4gIFNhbmRib3hDb25maWdTY2hlbWEsXG4gIFNhbmRib3hSZWNvcmRTY2hlbWEsXG4gIFNlc3Npb25TY2hlbWEsXG4gIHR5cGUgU3RvcmFnZU1ldGhvZHMsXG59IGZyb20gXCIuL3JwY1wiO1xuZXhwb3J0IHR5cGUge1xuICBDb21tYW5kLFxuICBMaXN0UmVzdWx0LFxuICBNZXNzYWdlLFxuICBQYXJ0LFxuICBSZXNvbHZlZFN0b3JhZ2UsXG4gIFNhbmRib3hSZWNvcmQsXG4gIFNlc3Npb24sXG4gIFN0b3JhZ2UsXG4gIFN0b3JhZ2VDb25maWcsXG59IGZyb20gXCIuL3R5cGVzXCI7XG4iLCAiaW1wb3J0ICogYXMgcGF0aCBmcm9tIFwibm9kZTpwYXRoXCI7XG5pbXBvcnQgdHlwZSB7IFVwbG9hZGFibGVGaWxlIH0gZnJvbSBcIi4uL3NraWxscy90eXBlc1wiO1xuaW1wb3J0IHR5cGUgeyBTYW5kYm94IH0gZnJvbSBcIi4vdHlwZXNcIjtcblxuLyoqXG4gKiBXcml0ZXMgZmlsZXMgdG8gYSBzYW5kYm94IGF0IHRoZSBzcGVjaWZpZWQgZGVzdGluYXRpb24gcGF0aC5cbiAqIFNoZWxsIHNjcmlwdHMgKC5zaCBmaWxlcykgYXJlIGF1dG9tYXRpY2FsbHkgbWFkZSBleGVjdXRhYmxlLlxuICpcbiAqIEZvciBzbWFsbCBmaWxlcyAoPDEwMEtCIHRvdGFsKSwgdXNlcyBzaW5nbGUgZXhlYyB3aXRoIGhlcmVkb2MuXG4gKiBGb3IgbGFyZ2UgZmlsZXMsIHdyaXRlcyBiYXNlNjQgY2h1bmtzIHRoZW4gZGVjb2RlcyB0byBhdm9pZCBBUkdfTUFYIGxpbWl0cy5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHdyaXRlRmlsZXMob3B0czoge1xuICBzYW5kYm94OiBQaWNrPFNhbmRib3gsIFwiZXhlY1wiPjtcbiAgZmlsZXM6IFVwbG9hZGFibGVGaWxlW107XG4gIGRlc3RQYXRoOiBzdHJpbmc7XG59KTogUHJvbWlzZTx2b2lkPiB7XG4gIGNvbnN0IHsgc2FuZGJveCwgZmlsZXMsIGRlc3RQYXRoIH0gPSBvcHRzO1xuXG4gIGlmIChmaWxlcy5sZW5ndGggPT09IDApIHtcbiAgICByZXR1cm47XG4gIH1cblxuICBjb25zdCBmaWxlUGF0aHMgPSBmaWxlcy5tYXAoKGZpbGUpID0+IHBhdGgucG9zaXguam9pbihkZXN0UGF0aCwgZmlsZS5wYXRoKSk7XG4gIGNvbnN0IHBhcmVudERpcnMgPSBbLi4ubmV3IFNldChmaWxlUGF0aHMubWFwKChwKSA9PiBwYXRoLnBvc2l4LmRpcm5hbWUocCkpKV07XG4gIGNvbnN0IHNoZWxsU2NyaXB0cyA9IGZpbGVQYXRocy5maWx0ZXIoKHApID0+IHAuZW5kc1dpdGgoXCIuc2hcIikpO1xuXG4gIGNvbnN0IG1rZGlyUmVzdWx0ID0gYXdhaXQgc2FuZGJveC5leGVjKHtcbiAgICBjb21tYW5kOiBcIm1rZGlyXCIsXG4gICAgYXJnczogW1wiLXBcIiwgLi4ucGFyZW50RGlyc10sXG4gIH0pO1xuICBpZiAobWtkaXJSZXN1bHQgaW5zdGFuY2VvZiBFcnJvcikge1xuICAgIHRocm93IG1rZGlyUmVzdWx0O1xuICB9XG4gIGF3YWl0IG1rZGlyUmVzdWx0LnJlc3VsdDtcblxuICBjb25zdCBDSFVOS19TSVpFID0gNTBfMDAwO1xuXG4gIGZvciAobGV0IGkgPSAwOyBpIDwgZmlsZXMubGVuZ3RoOyBpKyspIHtcbiAgICBjb25zdCBmaWxlID0gZmlsZXNbaV07XG4gICAgY29uc3QgZnVsbFBhdGggPSBmaWxlUGF0aHNbaV07XG4gICAgY29uc3QgYmFzZTY0Q29udGVudCA9IHRvQmFzZTY0KGZpbGUuY29udGVudCk7XG5cbiAgICBpZiAoYmFzZTY0Q29udGVudC5sZW5ndGggPCBDSFVOS19TSVpFKSB7XG4gICAgICBjb25zdCBtYXJrZXIgPSBgRU9GXyR7aX1gO1xuICAgICAgY29uc3QgZXhlY1Jlc3VsdCA9IGF3YWl0IHNhbmRib3guZXhlYyh7XG4gICAgICAgIGNvbW1hbmQ6IFwiYmFzaFwiLFxuICAgICAgICBhcmdzOiBbXG4gICAgICAgICAgXCItY1wiLFxuICAgICAgICAgIGBiYXNlNjQgLWQgPiAke3F1b3RlKGZ1bGxQYXRoKX0gPDwgJyR7bWFya2VyfSdcbiR7YmFzZTY0Q29udGVudH1cbiR7bWFya2VyfWAsXG4gICAgICAgIF0sXG4gICAgICB9KTtcblxuICAgICAgaWYgKGV4ZWNSZXN1bHQgaW5zdGFuY2VvZiBFcnJvcikge1xuICAgICAgICB0aHJvdyBleGVjUmVzdWx0O1xuICAgICAgfVxuXG4gICAgICBjb25zdCB7IGV4aXRDb2RlLCBzdGRlcnIgfSA9IGF3YWl0IGV4ZWNSZXN1bHQucmVzdWx0O1xuICAgICAgaWYgKGV4aXRDb2RlICE9PSAwKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgICBgd3JpdGVGaWxlcyBmYWlsZWQgd2l0aCBleGl0IGNvZGUgJHtleGl0Q29kZX06ICR7c3RkZXJyfWBcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgY29uc3QgdGVtcEI2NCA9IGAvdG1wL2NodW5rLSR7RGF0ZS5ub3coKX0tJHtpfS5iNjRgO1xuXG4gICAgICBjb25zdCBjbGVhclJlc3VsdCA9IGF3YWl0IHNhbmRib3guZXhlYyh7XG4gICAgICAgIGNvbW1hbmQ6IFwiYmFzaFwiLFxuICAgICAgICBhcmdzOiBbXCItY1wiLCBgPiAke3F1b3RlKHRlbXBCNjQpfWBdLFxuICAgICAgfSk7XG4gICAgICBpZiAoY2xlYXJSZXN1bHQgaW5zdGFuY2VvZiBFcnJvcikge1xuICAgICAgICB0aHJvdyBjbGVhclJlc3VsdDtcbiAgICAgIH1cbiAgICAgIGF3YWl0IGNsZWFyUmVzdWx0LnJlc3VsdDtcblxuICAgICAgZm9yIChsZXQgb2Zmc2V0ID0gMDsgb2Zmc2V0IDwgYmFzZTY0Q29udGVudC5sZW5ndGg7IG9mZnNldCArPSBDSFVOS19TSVpFKSB7XG4gICAgICAgIGNvbnN0IGNodW5rID0gYmFzZTY0Q29udGVudC5zbGljZShvZmZzZXQsIG9mZnNldCArIENIVU5LX1NJWkUpO1xuICAgICAgICBjb25zdCBtYXJrZXIgPSBgQ0hVTktfJHtvZmZzZXR9YDtcbiAgICAgICAgY29uc3QgYXBwZW5kUmVzdWx0ID0gYXdhaXQgc2FuZGJveC5leGVjKHtcbiAgICAgICAgICBjb21tYW5kOiBcImJhc2hcIixcbiAgICAgICAgICBhcmdzOiBbXG4gICAgICAgICAgICBcIi1jXCIsXG4gICAgICAgICAgICBgY2F0ID4+ICR7cXVvdGUodGVtcEI2NCl9IDw8ICcke21hcmtlcn0nXG4ke2NodW5rfVxuJHttYXJrZXJ9YCxcbiAgICAgICAgICBdLFxuICAgICAgICB9KTtcblxuICAgICAgICBpZiAoYXBwZW5kUmVzdWx0IGluc3RhbmNlb2YgRXJyb3IpIHtcbiAgICAgICAgICB0aHJvdyBhcHBlbmRSZXN1bHQ7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCB7IGV4aXRDb2RlLCBzdGRlcnIgfSA9IGF3YWl0IGFwcGVuZFJlc3VsdC5yZXN1bHQ7XG4gICAgICAgIGlmIChleGl0Q29kZSAhPT0gMCkge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgICAgIGB3cml0ZUZpbGVzIGNodW5rIGZhaWxlZCB3aXRoIGV4aXQgY29kZSAke2V4aXRDb2RlfTogJHtzdGRlcnJ9YFxuICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgY29uc3QgZGVjb2RlUmVzdWx0ID0gYXdhaXQgc2FuZGJveC5leGVjKHtcbiAgICAgICAgY29tbWFuZDogXCJiYXNoXCIsXG4gICAgICAgIGFyZ3M6IFtcbiAgICAgICAgICBcIi1jXCIsXG4gICAgICAgICAgYGJhc2U2NCAtZCA8ICR7cXVvdGUodGVtcEI2NCl9ID4gJHtxdW90ZShmdWxsUGF0aCl9ICYmIHJtIC1mICR7cXVvdGUodGVtcEI2NCl9YCxcbiAgICAgICAgXSxcbiAgICAgIH0pO1xuXG4gICAgICBpZiAoZGVjb2RlUmVzdWx0IGluc3RhbmNlb2YgRXJyb3IpIHtcbiAgICAgICAgdGhyb3cgZGVjb2RlUmVzdWx0O1xuICAgICAgfVxuXG4gICAgICBjb25zdCB7IGV4aXRDb2RlLCBzdGRlcnIgfSA9IGF3YWl0IGRlY29kZVJlc3VsdC5yZXN1bHQ7XG4gICAgICBpZiAoZXhpdENvZGUgIT09IDApIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAgIGB3cml0ZUZpbGVzIGRlY29kZSBmYWlsZWQgd2l0aCBleGl0IGNvZGUgJHtleGl0Q29kZX06ICR7c3RkZXJyfWBcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBpZiAoc2hlbGxTY3JpcHRzLmxlbmd0aCA+IDApIHtcbiAgICBjb25zdCBjaG1vZFJlc3VsdCA9IGF3YWl0IHNhbmRib3guZXhlYyh7XG4gICAgICBjb21tYW5kOiBcImNobW9kXCIsXG4gICAgICBhcmdzOiBbXCIreFwiLCAuLi5zaGVsbFNjcmlwdHNdLFxuICAgIH0pO1xuICAgIGlmIChjaG1vZFJlc3VsdCBpbnN0YW5jZW9mIEVycm9yKSB7XG4gICAgICB0aHJvdyBjaG1vZFJlc3VsdDtcbiAgICB9XG4gICAgYXdhaXQgY2htb2RSZXN1bHQucmVzdWx0O1xuICB9XG59XG5cbmZ1bmN0aW9uIHRvQmFzZTY0KGNvbnRlbnQ6IHN0cmluZyB8IEJ1ZmZlcik6IHN0cmluZyB7XG4gIGlmICh0eXBlb2YgY29udGVudCA9PT0gXCJzdHJpbmdcIikge1xuICAgIHJldHVybiBCdWZmZXIuZnJvbShjb250ZW50KS50b1N0cmluZyhcImJhc2U2NFwiKTtcbiAgfVxuICByZXR1cm4gY29udGVudC50b1N0cmluZyhcImJhc2U2NFwiKTtcbn1cblxuZnVuY3Rpb24gcXVvdGUoczogc3RyaW5nKTogc3RyaW5nIHtcbiAgcmV0dXJuIGAnJHtzLnJlcGxhY2UoLycvZywgXCInXFxcXCcnXCIpfSdgO1xufVxuIiwgImltcG9ydCB0eXBlIHsgQ2hpbGRQcm9jZXNzIH0gZnJvbSBcIm5vZGU6Y2hpbGRfcHJvY2Vzc1wiO1xuaW1wb3J0IHsgc3Bhd24gfSBmcm9tIFwibm9kZTpjaGlsZF9wcm9jZXNzXCI7XG5pbXBvcnQgKiBhcyBlcnJvcmUgZnJvbSBcImVycm9yZVwiO1xuaW1wb3J0IHsgdWxpZCB9IGZyb20gXCJ1bGlkXCI7XG5pbXBvcnQgeyBTYW5kYm94RXJyb3IgfSBmcm9tIFwiLi4vLi4vZXJyb3JzXCI7XG5pbXBvcnQgdHlwZSB7IFNhbmRib3hSZWNvcmQsIFN0b3JhZ2VDb25maWcgfSBmcm9tIFwiLi4vLi4vc3RvcmFnZS90eXBlc1wiO1xuaW1wb3J0IHR5cGUgeyBMb2dFbnRyeSwgU2FuZGJveCB9IGZyb20gXCIuLi90eXBlc1wiO1xuaW1wb3J0IHsgd3JpdGVGaWxlcyB9IGZyb20gXCIuLi93cml0ZS1maWxlc1wiO1xuXG5leHBvcnQgY29uc3QgbG9jYWxTYW5kYm94ID0gKHtcbiAgc2FuZGJveFJlY29yZCxcbn06IHtcbiAgc2FuZGJveFJlY29yZDogU2FuZGJveFJlY29yZCAmIHsgY29uZmlnOiB7IHR5cGU6IFwibG9jYWxcIiB9IH07XG4gIHN0b3JhZ2VDb25maWc6IFN0b3JhZ2VDb25maWc7XG59KTogU2FuZGJveCA9PiB7XG4gIGNvbnN0IGNvbmZpZyA9IHNhbmRib3hSZWNvcmQuY29uZmlnO1xuICBjb25zdCBiYXNlUGF0aCA9IGNvbmZpZy5wYXRoID8/IHByb2Nlc3MuY3dkKCk7XG4gIGNvbnN0IHByb2Nlc3NlcyA9IG5ldyBNYXA8c3RyaW5nLCBDaGlsZFByb2Nlc3M+KCk7XG5cbiAgY29uc3Qgc2FuZGJveDogU2FuZGJveCA9IHtcbiAgICBpZDogc2FuZGJveFJlY29yZC5pZCxcbiAgICBjb25maWc6IHNhbmRib3hSZWNvcmQuY29uZmlnLFxuICAgIGV4ZWM6ICh7IGNvbW1hbmQsIGFyZ3MsIHNpZ25hbCB9KSA9PiB7XG4gICAgICByZXR1cm4gZXJyb3JlLnRyeUFzeW5jKHtcbiAgICAgICAgdHJ5OiAoKSA9PiB7XG4gICAgICAgICAgY29uc3QgY29tbWFuZElkID0gYGNvbW1hbmRfJHt1bGlkKCl9YDtcblxuICAgICAgICAgIGNvbnN0IGNoaWxkID0gc3Bhd24oY29tbWFuZCwgYXJncywge1xuICAgICAgICAgICAgY3dkOiBiYXNlUGF0aCxcbiAgICAgICAgICAgIHNpZ25hbCxcbiAgICAgICAgICB9KTtcblxuICAgICAgICAgIHByb2Nlc3Nlcy5zZXQoY29tbWFuZElkLCBjaGlsZCk7XG5cbiAgICAgICAgICBsZXQgc3Rkb3V0ID0gXCJcIjtcbiAgICAgICAgICBsZXQgc3RkZXJyID0gXCJcIjtcbiAgICAgICAgICBjb25zdCBsb2dRdWV1ZTogTG9nRW50cnlbXSA9IFtdO1xuICAgICAgICAgIGxldCBsb2dSZXNvbHZlOiAoKCkgPT4gdm9pZCkgfCBudWxsID0gbnVsbDtcbiAgICAgICAgICBsZXQgY2xvc2VkID0gZmFsc2U7XG5cbiAgICAgICAgICBjaGlsZC5zdGRvdXQub24oXCJkYXRhXCIsIChkYXRhOiBzdHJpbmcgfCBCdWZmZXIpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHN0ciA9IFN0cmluZyhkYXRhKTtcbiAgICAgICAgICAgIHN0ZG91dCArPSBzdHI7XG4gICAgICAgICAgICBsb2dRdWV1ZS5wdXNoKHsgc3RyZWFtOiBcInN0ZG91dFwiLCBkYXRhOiBzdHIgfSk7XG4gICAgICAgICAgICBsb2dSZXNvbHZlPy4oKTtcbiAgICAgICAgICB9KTtcblxuICAgICAgICAgIGNoaWxkLnN0ZGVyci5vbihcImRhdGFcIiwgKGRhdGE6IHN0cmluZyB8IEJ1ZmZlcikgPT4ge1xuICAgICAgICAgICAgY29uc3Qgc3RyID0gU3RyaW5nKGRhdGEpO1xuICAgICAgICAgICAgc3RkZXJyICs9IHN0cjtcbiAgICAgICAgICAgIGxvZ1F1ZXVlLnB1c2goeyBzdHJlYW06IFwic3RkZXJyXCIsIGRhdGE6IHN0ciB9KTtcbiAgICAgICAgICAgIGxvZ1Jlc29sdmU/LigpO1xuICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgY29uc3QgcmVzdWx0ID0gbmV3IFByb21pc2U8e1xuICAgICAgICAgICAgc3Rkb3V0OiBzdHJpbmc7XG4gICAgICAgICAgICBzdGRlcnI6IHN0cmluZztcbiAgICAgICAgICAgIGV4aXRDb2RlOiBudW1iZXI7XG4gICAgICAgICAgfT4oKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgY2hpbGQub24oXCJlcnJvclwiLCAoZXJyKSA9PiB7XG4gICAgICAgICAgICAgIHByb2Nlc3Nlcy5kZWxldGUoY29tbWFuZElkKTtcbiAgICAgICAgICAgICAgY2xvc2VkID0gdHJ1ZTtcbiAgICAgICAgICAgICAgbG9nUmVzb2x2ZT8uKCk7XG4gICAgICAgICAgICAgIHJlamVjdChlcnIpO1xuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIGNoaWxkLm9uKFwiY2xvc2VcIiwgKGNvZGU6IG51bWJlciB8IG51bGwpID0+IHtcbiAgICAgICAgICAgICAgcHJvY2Vzc2VzLmRlbGV0ZShjb21tYW5kSWQpO1xuICAgICAgICAgICAgICBjbG9zZWQgPSB0cnVlO1xuICAgICAgICAgICAgICBsb2dSZXNvbHZlPy4oKTtcbiAgICAgICAgICAgICAgcmVzb2x2ZSh7IHN0ZG91dCwgc3RkZXJyLCBleGl0Q29kZTogY29kZSA/PyAwIH0pO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgICBhc3luYyBmdW5jdGlvbiogbG9ncygpOiBBc3luY0l0ZXJhYmxlPExvZ0VudHJ5PiB7XG4gICAgICAgICAgICB3aGlsZSAoIWNsb3NlZCB8fCBsb2dRdWV1ZS5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICAgIGNvbnN0IGVudHJ5ID0gbG9nUXVldWUuc2hpZnQoKTtcbiAgICAgICAgICAgICAgaWYgKGVudHJ5KSB7XG4gICAgICAgICAgICAgICAgeWllbGQgZW50cnk7XG4gICAgICAgICAgICAgIH0gZWxzZSBpZiAoIWNsb3NlZCkge1xuICAgICAgICAgICAgICAgIGF3YWl0IG5ldyBQcm9taXNlPHZvaWQ+KChyZXNvbHZlKSA9PiB7XG4gICAgICAgICAgICAgICAgICBsb2dSZXNvbHZlID0gcmVzb2x2ZTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICBsb2dSZXNvbHZlID0gbnVsbDtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cblxuICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoeyBjb21tYW5kSWQsIGxvZ3MsIHJlc3VsdCB9KTtcbiAgICAgICAgfSxcbiAgICAgICAgY2F0Y2g6IChlOiB1bmtub3duKSA9PlxuICAgICAgICAgIG5ldyBTYW5kYm94RXJyb3IoeyByZWFzb246IFN0cmluZyhlKSwgY2F1c2U6IGUgfSksXG4gICAgICB9KTtcbiAgICB9LFxuXG4gICAgZ2V0RG9tYWluOiAocG9ydCkgPT4ge1xuICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShgaHR0cDovL2xvY2FsaG9zdDoke3BvcnR9YCk7XG4gICAgfSxcblxuICAgIGtpbGw6IGFzeW5jICh7IGNvbW1hbmRJZCwgc3RvcmFnZSB9KSA9PiB7XG4gICAgICBjb25zdCBjaGlsZCA9IHByb2Nlc3Nlcy5nZXQoY29tbWFuZElkKTtcbiAgICAgIGlmICghY2hpbGQpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBTYW5kYm94RXJyb3Ioe1xuICAgICAgICAgIHJlYXNvbjogYENvbW1hbmQgJHtjb21tYW5kSWR9IG5vdCBmb3VuZCBvciBhbHJlYWR5IGZpbmlzaGVkYCxcbiAgICAgICAgfSk7XG4gICAgICB9XG5cbiAgICAgIGNoaWxkLmtpbGwoXCJTSUdURVJNXCIpO1xuXG4gICAgICBjb25zdCBjbWQgPSBhd2FpdCBzdG9yYWdlLmNvbW1hbmQuZ2V0KGNvbW1hbmRJZCk7XG4gICAgICBpZiAoY21kIGluc3RhbmNlb2YgRXJyb3IpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBTYW5kYm94RXJyb3IoeyByZWFzb246IGNtZC5tZXNzYWdlLCBjYXVzZTogY21kIH0pO1xuICAgICAgfVxuICAgICAgaWYgKGNtZCAmJiBjbWQuc3RhdHVzID09PSBcInJ1bm5pbmdcIikge1xuICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBzdG9yYWdlLmNvbW1hbmQuc2V0KHtcbiAgICAgICAgICAuLi5jbWQsXG4gICAgICAgICAgc3RhdHVzOiBcImtpbGxlZFwiLFxuICAgICAgICB9KTtcbiAgICAgICAgaWYgKHJlc3VsdCBpbnN0YW5jZW9mIEVycm9yKSB7XG4gICAgICAgICAgcmV0dXJuIG5ldyBTYW5kYm94RXJyb3IoeyByZWFzb246IHJlc3VsdC5tZXNzYWdlLCBjYXVzZTogcmVzdWx0IH0pO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSxcblxuICAgIHdyaXRlRmlsZXM6IChvcHRzKSA9PiB3cml0ZUZpbGVzKHsgc2FuZGJveCwgLi4ub3B0cyB9KSxcbiAgfTtcblxuICByZXR1cm4gc2FuZGJveDtcbn07XG4iLCAiaW1wb3J0ICogYXMgZXJyb3JlIGZyb20gXCJlcnJvcmVcIjtcbmltcG9ydCB7IFNhbmRib3ggYXMgVmVyY2VsU2FuZGJveFNESyB9IGZyb20gXCJzYW5kYm94XCI7XG5pbXBvcnQgeyBTYW5kYm94RXJyb3IgfSBmcm9tIFwiLi4vLi4vZXJyb3JzXCI7XG5pbXBvcnQge1xuICBnZXRTdG9yYWdlLFxuICB0eXBlIFNhbmRib3hSZWNvcmQsXG4gIHR5cGUgU3RvcmFnZSxcbiAgdHlwZSBTdG9yYWdlQ29uZmlnLFxufSBmcm9tIFwiLi4vLi4vc3RvcmFnZVwiO1xuaW1wb3J0IHR5cGUge1xuICBMb2dFbnRyeSxcbiAgU2FuZGJveCxcbiAgU2FuZGJveExpZmVjeWNsZSxcbiAgU2FuZGJveFN0YXR1cyxcbn0gZnJvbSBcIi4uL3R5cGVzXCI7XG5pbXBvcnQgeyB3cml0ZUZpbGVzIH0gZnJvbSBcIi4uL3dyaXRlLWZpbGVzXCI7XG5cbmV4cG9ydCB0eXBlIFZlcmNlbFNhbmRib3hDcmVhdGVPcHRpb25zID0gRXh0cmFjdDxcbiAgUGFyYW1ldGVyczx0eXBlb2YgVmVyY2VsU2FuZGJveFNESy5jcmVhdGU+WzBdLFxuICAvLyBiaW9tZS1pZ25vcmUgbGludC9jb21wbGV4aXR5L25vQmFubmVkVHlwZXM6IC5cbiAge31cbj47XG5cbmV4cG9ydCBjb25zdCBWRVJDRUxfTUFYX1RJTUVPVVRfTVMgPSA1ICogNjAgKiA2MCAqIDEwMDA7IC8vIDUgaG91cnNcbmNvbnN0IExPQ0tfVElNRU9VVF9NUyA9IDMwXzAwMDsgLy8gMzAgc2Vjb25kcyAtIGlmIGxvY2sgb2xkZXIgdGhhbiB0aGlzLCBjb25zaWRlciBpdCBzdGFsZVxuY29uc3QgTE9DS19QT0xMX0lOVEVSVkFMX01TID0gMjAwO1xuXG5jb25zdCBnZXRUZXN0Q3JlZGVudGlhbHMgPSAoKSA9PlxuICBwcm9jZXNzLmVudi5OT0RFX0VOViA9PT0gXCJ0ZXN0XCJcbiAgICA/IHtcbiAgICAgICAgdG9rZW46IHByb2Nlc3MuZW52LlRFU1RfVkVSQ0VMX1RPS0VOLFxuICAgICAgICB0ZWFtSWQ6IHByb2Nlc3MuZW52LlRFU1RfVkVSQ0VMX1RFQU1fSUQsXG4gICAgICAgIHByb2plY3RJZDogcHJvY2Vzcy5lbnYuVEVTVF9WRVJDRUxfUFJPSkVDVF9JRCxcbiAgICAgIH1cbiAgICA6IHt9O1xuXG4vKipcbiAqIE1vZHVsZS1sZXZlbCBjYWNoZSBmb3IgaW4tZmxpZ2h0IHNhbmRib3ggY3JlYXRpb24gcHJvbWlzZXMuXG4gKiBQcmV2ZW50cyBwYXJhbGxlbCByZXF1ZXN0cyB3aXRoaW4gdGhlIHNhbWUgcHJvY2VzcyBmcm9tIGNyZWF0aW5nIGR1cGxpY2F0ZSBzYW5kYm94ZXMuXG4gKi9cbmNvbnN0IGNyZWF0ZVByb21pc2VzID0gbmV3IE1hcDxzdHJpbmcsIFByb21pc2U8U2FuZGJveEVycm9yIHwgc3RyaW5nPj4oKTtcblxuY29uc3QgQUNUSVZJVFlfVEhST1RUTEVfTVMgPSAxMF8wMDA7XG5jb25zdCBsYXN0QWN0aXZpdHlTZW50ID0gbmV3IE1hcDxzdHJpbmcsIG51bWJlcj4oKTtcblxuY29uc3QgREVGQVVMVF9WQ1BVUyA9IDI7XG5cbmV4cG9ydCBjb25zdCB2ZXJjZWxTYW5kYm94ID0gKHtcbiAgc2FuZGJveFJlY29yZCxcbiAgc3RvcmFnZUNvbmZpZyxcbiAgZW5hYmxlTGlmZWN5Y2xlV29ya2Zsb3cgPSB0cnVlLFxuICBzdG9yYWdlOiBzdG9yYWdlT3ZlcnJpZGUsXG59OiB7XG4gIHNhbmRib3hSZWNvcmQ6IFNhbmRib3hSZWNvcmQgJiB7IGNvbmZpZzogeyB0eXBlOiBcInZlcmNlbFwiIH0gfTtcbiAgc3RvcmFnZUNvbmZpZzogU3RvcmFnZUNvbmZpZztcbiAgZW5hYmxlTGlmZWN5Y2xlV29ya2Zsb3c/OiBib29sZWFuO1xuICBzdG9yYWdlPzogU3RvcmFnZTtcbn0pOiBTYW5kYm94ID0+IHtcbiAgY29uc3QgeyBpZCwgY29uZmlnIH0gPSBzYW5kYm94UmVjb3JkO1xuICBjb25zdCB2Y3B1cyA9IGNvbmZpZy5yZXNvdXJjZXM/LnZjcHVzID8/IERFRkFVTFRfVkNQVVM7XG4gIGNvbnN0IHBvcnRzID0gY29uZmlnLnBvcnRzO1xuICBjb25zdCBzdG9yYWdlID0gc3RvcmFnZU92ZXJyaWRlID8/IGdldFN0b3JhZ2Uoc3RvcmFnZUNvbmZpZyk7XG4gIGNvbnN0IGluaXRpYWxWZXJjZWwgPVxuICAgIHNhbmRib3hSZWNvcmQucHJvdmlkZXJNZXRhZGF0YT8ucHJvdmlkZXIgPT09IFwidmVyY2VsXCJcbiAgICAgID8gc2FuZGJveFJlY29yZC5wcm92aWRlck1ldGFkYXRhXG4gICAgICA6IG51bGw7XG5cbiAgdHlwZSBTYW5kYm94SW5zdGFuY2UgPSBBd2FpdGVkPFJldHVyblR5cGU8dHlwZW9mIFZlcmNlbFNhbmRib3hTREsuZ2V0Pj47XG4gIGxldCBzYW5kYm94UHJvbWlzZTogUHJvbWlzZTxTYW5kYm94RXJyb3IgfCBTYW5kYm94SW5zdGFuY2U+IHwgbnVsbCA9IG51bGw7XG5cbiAgYXN5bmMgZnVuY3Rpb24gcG9sbEZvclNhbmRib3hJZCgpOiBQcm9taXNlPFNhbmRib3hFcnJvciB8IHN0cmluZz4ge1xuICAgIGNvbnN0IGRlYWRsaW5lID0gRGF0ZS5ub3coKSArIExPQ0tfVElNRU9VVF9NUztcbiAgICB3aGlsZSAoRGF0ZS5ub3coKSA8IGRlYWRsaW5lKSB7XG4gICAgICBhd2FpdCBuZXcgUHJvbWlzZSgocikgPT4gc2V0VGltZW91dChyLCBMT0NLX1BPTExfSU5URVJWQUxfTVMpKTtcbiAgICAgIGNvbnN0IHJlY29yZCA9IGF3YWl0IHN0b3JhZ2Uuc2FuZGJveC5nZXQoaWQpO1xuICAgICAgaWYgKHJlY29yZCBpbnN0YW5jZW9mIEVycm9yKSB7XG4gICAgICAgIHJldHVybiBuZXcgU2FuZGJveEVycm9yKHsgcmVhc29uOiByZWNvcmQubWVzc2FnZSwgY2F1c2U6IHJlY29yZCB9KTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IHZlcmNlbFNhbmRib3hJZCA9XG4gICAgICAgIHJlY29yZD8ucHJvdmlkZXJNZXRhZGF0YT8ucHJvdmlkZXIgPT09IFwidmVyY2VsXCJcbiAgICAgICAgICA/IHJlY29yZC5wcm92aWRlck1ldGFkYXRhLnNhbmRib3hJZFxuICAgICAgICAgIDogbnVsbDtcbiAgICAgIGlmICh2ZXJjZWxTYW5kYm94SWQpIHtcbiAgICAgICAgcmV0dXJuIHZlcmNlbFNhbmRib3hJZDtcbiAgICAgIH1cbiAgICAgIGlmICghcmVjb3JkPy5hY3F1aXJpbmdMb2NrQXQpIHtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBuZXcgU2FuZGJveEVycm9yKHtcbiAgICAgIHJlYXNvbjogXCJUaW1lZCBvdXQgd2FpdGluZyBmb3Igc2FuZGJveCBjcmVhdGlvbiBieSBhbm90aGVyIHByb2Nlc3NcIixcbiAgICB9KTtcbiAgfVxuXG4gIGFzeW5jIGZ1bmN0aW9uIGNyZWF0ZVNhbmRib3hGcm9tU25hcHNob3QoXG4gICAgc25hcHNob3RJZDogc3RyaW5nXG4gICk6IFByb21pc2U8U2FuZGJveEVycm9yIHwgc3RyaW5nPiB7XG4gICAgcmV0dXJuIGF3YWl0IGVycm9yZS50cnlBc3luYyh7XG4gICAgICB0cnk6IGFzeW5jICgpID0+IHtcbiAgICAgICAgY29uc3Qgc2FuZGJveCA9IGF3YWl0IFZlcmNlbFNhbmRib3hTREsuY3JlYXRlKHtcbiAgICAgICAgICBzb3VyY2U6IHsgdHlwZTogXCJzbmFwc2hvdFwiLCBzbmFwc2hvdElkIH0sXG4gICAgICAgICAgcmVzb3VyY2VzOiB7IHZjcHVzIH0sXG4gICAgICAgICAgdGltZW91dDogVkVSQ0VMX01BWF9USU1FT1VUX01TLFxuICAgICAgICAgIHBvcnRzLFxuICAgICAgICAgIC4uLmdldFRlc3RDcmVkZW50aWFscygpLFxuICAgICAgICB9KTtcbiAgICAgICAgY29uc3Qgbm93ID0gRGF0ZS5ub3coKTtcbiAgICAgICAgYXdhaXQgc3RvcmFnZS5zYW5kYm94LnNldCh7XG4gICAgICAgICAgaWQsXG4gICAgICAgICAgY29uZmlnLFxuICAgICAgICAgIGNyZWF0ZWRBdDogbm93LFxuICAgICAgICAgIGxhc3RBY3Rpdml0eUF0OiBub3csXG4gICAgICAgICAgYWNxdWlyaW5nTG9ja0lkOiBudWxsLFxuICAgICAgICAgIGFjcXVpcmluZ0xvY2tBdDogbnVsbCxcbiAgICAgICAgICBwcm92aWRlck1ldGFkYXRhOiB7XG4gICAgICAgICAgICBwcm92aWRlcjogXCJ2ZXJjZWxcIixcbiAgICAgICAgICAgIHNhbmRib3hJZDogc2FuZGJveC5zYW5kYm94SWQsXG4gICAgICAgICAgICBzbmFwc2hvdElkLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gc2FuZGJveC5zYW5kYm94SWQ7XG4gICAgICB9LFxuICAgICAgY2F0Y2g6IChlKSA9PiBuZXcgU2FuZGJveEVycm9yKHsgcmVhc29uOiBTdHJpbmcoZSksIGNhdXNlOiBlIH0pLFxuICAgIH0pO1xuICB9XG5cbiAgYXN5bmMgZnVuY3Rpb24gY3JlYXRlRnJlc2hTYW5kYm94KCk6IFByb21pc2U8U2FuZGJveEVycm9yIHwgc3RyaW5nPiB7XG4gICAgcmV0dXJuIGF3YWl0IGVycm9yZS50cnlBc3luYyh7XG4gICAgICB0cnk6IGFzeW5jICgpID0+IHtcbiAgICAgICAgY29uc3Qgc2FuZGJveCA9IGF3YWl0IFZlcmNlbFNhbmRib3hTREsuY3JlYXRlKHtcbiAgICAgICAgICByZXNvdXJjZXM6IHsgdmNwdXMgfSxcbiAgICAgICAgICB0aW1lb3V0OiBWRVJDRUxfTUFYX1RJTUVPVVRfTVMsXG4gICAgICAgICAgcG9ydHMsXG4gICAgICAgICAgLi4uZ2V0VGVzdENyZWRlbnRpYWxzKCksXG4gICAgICAgIH0pO1xuICAgICAgICBjb25zdCBub3cgPSBEYXRlLm5vdygpO1xuICAgICAgICBhd2FpdCBzdG9yYWdlLnNhbmRib3guc2V0KHtcbiAgICAgICAgICBpZCxcbiAgICAgICAgICBjb25maWcsXG4gICAgICAgICAgY3JlYXRlZEF0OiBub3csXG4gICAgICAgICAgbGFzdEFjdGl2aXR5QXQ6IG5vdyxcbiAgICAgICAgICBhY3F1aXJpbmdMb2NrSWQ6IG51bGwsXG4gICAgICAgICAgYWNxdWlyaW5nTG9ja0F0OiBudWxsLFxuICAgICAgICAgIHByb3ZpZGVyTWV0YWRhdGE6IHtcbiAgICAgICAgICAgIHByb3ZpZGVyOiBcInZlcmNlbFwiLFxuICAgICAgICAgICAgc2FuZGJveElkOiBzYW5kYm94LnNhbmRib3hJZCxcbiAgICAgICAgICAgIHNuYXBzaG90SWQ6IG51bGwsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiBzYW5kYm94LnNhbmRib3hJZDtcbiAgICAgIH0sXG4gICAgICBjYXRjaDogKGUpID0+IG5ldyBTYW5kYm94RXJyb3IoeyByZWFzb246IFN0cmluZyhlKSwgY2F1c2U6IGUgfSksXG4gICAgfSk7XG4gIH1cblxuICBhc3luYyBmdW5jdGlvbiBkb0dldE9yQ3JlYXRlU2FuZGJveElkKCk6IFByb21pc2U8U2FuZGJveEVycm9yIHwgc3RyaW5nPiB7XG4gICAgaWYgKGluaXRpYWxWZXJjZWw/LnNhbmRib3hJZCkge1xuICAgICAgcmV0dXJuIGluaXRpYWxWZXJjZWwuc2FuZGJveElkO1xuICAgIH1cblxuICAgIGNvbnN0IGV4aXN0aW5nID0gYXdhaXQgc3RvcmFnZS5zYW5kYm94LmdldChpZCk7XG4gICAgaWYgKGV4aXN0aW5nIGluc3RhbmNlb2YgRXJyb3IpIHtcbiAgICAgIHJldHVybiBuZXcgU2FuZGJveEVycm9yKHsgcmVhc29uOiBleGlzdGluZy5tZXNzYWdlLCBjYXVzZTogZXhpc3RpbmcgfSk7XG4gICAgfVxuXG4gICAgY29uc3QgZXhpc3RpbmdWZXJjZWwgPVxuICAgICAgZXhpc3Rpbmc/LnByb3ZpZGVyTWV0YWRhdGE/LnByb3ZpZGVyID09PSBcInZlcmNlbFwiXG4gICAgICAgID8gZXhpc3RpbmcucHJvdmlkZXJNZXRhZGF0YVxuICAgICAgICA6IG51bGw7XG5cbiAgICBpZiAoZXhpc3RpbmdWZXJjZWw/LnNhbmRib3hJZCkge1xuICAgICAgcmV0dXJuIGV4aXN0aW5nVmVyY2VsLnNhbmRib3hJZDtcbiAgICB9XG5cbiAgICBjb25zdCBoYXNBY3RpdmVMb2NrID1cbiAgICAgIGV4aXN0aW5nPy5hY3F1aXJpbmdMb2NrSWQgJiZcbiAgICAgIGV4aXN0aW5nLmFjcXVpcmluZ0xvY2tBdCAmJlxuICAgICAgRGF0ZS5ub3coKSAtIGV4aXN0aW5nLmFjcXVpcmluZ0xvY2tBdCA8IExPQ0tfVElNRU9VVF9NUztcblxuICAgIGlmIChoYXNBY3RpdmVMb2NrKSB7XG4gICAgICByZXR1cm4gcG9sbEZvclNhbmRib3hJZCgpO1xuICAgIH1cblxuICAgIGNvbnN0IGxvY2tJZCA9IGNyeXB0by5yYW5kb21VVUlEKCk7XG4gICAgY29uc3Qgbm93ID0gRGF0ZS5ub3coKTtcbiAgICBhd2FpdCBzdG9yYWdlLnNhbmRib3guc2V0KHtcbiAgICAgIGlkLFxuICAgICAgY29uZmlnLFxuICAgICAgY3JlYXRlZEF0OiBleGlzdGluZz8uY3JlYXRlZEF0ID8/IHNhbmRib3hSZWNvcmQuY3JlYXRlZEF0LFxuICAgICAgbGFzdEFjdGl2aXR5QXQ6IGV4aXN0aW5nPy5sYXN0QWN0aXZpdHlBdCA/PyBzYW5kYm94UmVjb3JkLmxhc3RBY3Rpdml0eUF0LFxuICAgICAgYWNxdWlyaW5nTG9ja0lkOiBsb2NrSWQsXG4gICAgICBhY3F1aXJpbmdMb2NrQXQ6IG5vdyxcbiAgICAgIHByb3ZpZGVyTWV0YWRhdGE6IHtcbiAgICAgICAgcHJvdmlkZXI6IFwidmVyY2VsXCIsXG4gICAgICAgIHNhbmRib3hJZDogbnVsbCxcbiAgICAgICAgc25hcHNob3RJZDpcbiAgICAgICAgICBleGlzdGluZ1ZlcmNlbD8uc25hcHNob3RJZCA/PyBpbml0aWFsVmVyY2VsPy5zbmFwc2hvdElkID8/IG51bGwsXG4gICAgICB9LFxuICAgIH0pO1xuXG4gICAgY29uc3QgYWZ0ZXJMb2NrID0gYXdhaXQgc3RvcmFnZS5zYW5kYm94LmdldChpZCk7XG4gICAgaWYgKGFmdGVyTG9jayBpbnN0YW5jZW9mIEVycm9yKSB7XG4gICAgICByZXR1cm4gbmV3IFNhbmRib3hFcnJvcih7IHJlYXNvbjogYWZ0ZXJMb2NrLm1lc3NhZ2UsIGNhdXNlOiBhZnRlckxvY2sgfSk7XG4gICAgfVxuICAgIGlmIChhZnRlckxvY2s/LmFjcXVpcmluZ0xvY2tJZCAhPT0gbG9ja0lkKSB7XG4gICAgICByZXR1cm4gcG9sbEZvclNhbmRib3hJZCgpO1xuICAgIH1cblxuICAgIGNvbnN0IHNuYXBzaG90SWQgPVxuICAgICAgZXhpc3RpbmdWZXJjZWw/LnNuYXBzaG90SWQgPz9cbiAgICAgIGluaXRpYWxWZXJjZWw/LnNuYXBzaG90SWQgPz9cbiAgICAgIGNvbmZpZy5saWZlY3ljbGU/LnNuYXBzaG90SWQ7XG4gICAgaWYgKHNuYXBzaG90SWQpIHtcbiAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGNyZWF0ZVNhbmRib3hGcm9tU25hcHNob3Qoc25hcHNob3RJZCk7XG4gICAgICBpZiAoIShyZXN1bHQgaW5zdGFuY2VvZiBFcnJvcikpIHtcbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gY3JlYXRlRnJlc2hTYW5kYm94KCk7XG4gIH1cblxuICBmdW5jdGlvbiBnZXRPckNyZWF0ZVNhbmRib3hJZCgpOiBQcm9taXNlPFNhbmRib3hFcnJvciB8IHN0cmluZz4ge1xuICAgIGNvbnN0IGNhY2hlZCA9IGNyZWF0ZVByb21pc2VzLmdldChpZCk7XG4gICAgaWYgKGNhY2hlZCkge1xuICAgICAgcmV0dXJuIGNhY2hlZDtcbiAgICB9XG5cbiAgICBjb25zdCBwcm9taXNlID0gZG9HZXRPckNyZWF0ZVNhbmRib3hJZCgpLmZpbmFsbHkoKCkgPT4ge1xuICAgICAgY3JlYXRlUHJvbWlzZXMuZGVsZXRlKGlkKTtcbiAgICB9KTtcbiAgICBjcmVhdGVQcm9taXNlcy5zZXQoaWQsIHByb21pc2UpO1xuICAgIHJldHVybiBwcm9taXNlO1xuICB9XG5cbiAgYXN5bmMgZnVuY3Rpb24gZG9HZXRTYW5kYm94KCk6IFByb21pc2U8U2FuZGJveEVycm9yIHwgU2FuZGJveEluc3RhbmNlPiB7XG4gICAgY29uc3QgdmVyY2VsU2FuZGJveElkID0gYXdhaXQgZ2V0T3JDcmVhdGVTYW5kYm94SWQoKTtcbiAgICBpZiAodmVyY2VsU2FuZGJveElkIGluc3RhbmNlb2YgRXJyb3IpIHtcbiAgICAgIHJldHVybiB2ZXJjZWxTYW5kYm94SWQ7XG4gICAgfVxuXG4gICAgcmV0dXJuIGVycm9yZS50cnlBc3luYyh7XG4gICAgICB0cnk6ICgpID0+XG4gICAgICAgIFZlcmNlbFNhbmRib3hTREsuZ2V0KHtcbiAgICAgICAgICBzYW5kYm94SWQ6IHZlcmNlbFNhbmRib3hJZCxcbiAgICAgICAgICAuLi5nZXRUZXN0Q3JlZGVudGlhbHMoKSxcbiAgICAgICAgfSksXG4gICAgICBjYXRjaDogKGUpID0+IG5ldyBTYW5kYm94RXJyb3IoeyByZWFzb246IFN0cmluZyhlKSwgY2F1c2U6IGUgfSksXG4gICAgfSk7XG4gIH1cblxuICBmdW5jdGlvbiBnZXRTYW5kYm94KCk6IFByb21pc2U8U2FuZGJveEVycm9yIHwgU2FuZGJveEluc3RhbmNlPiB7XG4gICAgaWYgKCFzYW5kYm94UHJvbWlzZSkge1xuICAgICAgc2FuZGJveFByb21pc2UgPSBkb0dldFNhbmRib3goKTtcbiAgICB9XG4gICAgcmV0dXJuIHNhbmRib3hQcm9taXNlO1xuICB9XG5cbiAgYXN5bmMgZnVuY3Rpb24gdXBkYXRlTGFzdEFjdGl2aXR5KCk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IG5vdyA9IERhdGUubm93KCk7XG4gICAgY29uc3QgbGFzdFNlbnQgPSBsYXN0QWN0aXZpdHlTZW50LmdldChpZCk7XG4gICAgaWYgKGxhc3RTZW50ICYmIG5vdyAtIGxhc3RTZW50IDwgQUNUSVZJVFlfVEhST1RUTEVfTVMpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgbGFzdEFjdGl2aXR5U2VudC5zZXQoaWQsIG5vdyk7XG5cbiAgICBjb25zdCBleGlzdGluZyA9IGF3YWl0IHN0b3JhZ2Uuc2FuZGJveC5nZXQoaWQpO1xuICAgIGlmIChleGlzdGluZyBpbnN0YW5jZW9mIEVycm9yIHx8ICFleGlzdGluZykge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCBleGlzdGluZ1ZlcmNlbCA9XG4gICAgICBleGlzdGluZy5wcm92aWRlck1ldGFkYXRhPy5wcm92aWRlciA9PT0gXCJ2ZXJjZWxcIlxuICAgICAgICA/IGV4aXN0aW5nLnByb3ZpZGVyTWV0YWRhdGFcbiAgICAgICAgOiBudWxsO1xuICAgIGF3YWl0IHN0b3JhZ2Uuc2FuZGJveC5zZXQoe1xuICAgICAgaWQ6IGV4aXN0aW5nLmlkLFxuICAgICAgY29uZmlnOiBleGlzdGluZy5jb25maWcsXG4gICAgICBjcmVhdGVkQXQ6IGV4aXN0aW5nLmNyZWF0ZWRBdCxcbiAgICAgIGxhc3RBY3Rpdml0eUF0OiBub3csXG4gICAgICBhY3F1aXJpbmdMb2NrSWQ6IG51bGwsXG4gICAgICBhY3F1aXJpbmdMb2NrQXQ6IG51bGwsXG4gICAgICBwcm92aWRlck1ldGFkYXRhOiBleGlzdGluZ1ZlcmNlbCA/PyB7XG4gICAgICAgIHByb3ZpZGVyOiBcInZlcmNlbFwiLFxuICAgICAgICBzYW5kYm94SWQ6IG51bGwsXG4gICAgICAgIHNuYXBzaG90SWQ6IG51bGwsXG4gICAgICB9LFxuICAgIH0pO1xuXG4gICAgaWYgKGVuYWJsZUxpZmVjeWNsZVdvcmtmbG93KSB7XG4gICAgICAvLyB0b2RvIHJlLWVuYWJsZSBvbmNlIHdlIGZpZ3VyZSBvdXQgd2h5IHdvcmtmbG93IHRocm93cyBhIGJ1bmNoIG9mIGVycm9ycyBpbiBkZXZcbiAgICAgIC8vIGNvbnN0IGxpZmVjeWNsZUlucHV0OiBTYW5kYm94TGlmZWN5Y2xlSW5wdXQgPSB7XG4gICAgICAvLyAgIGlkLFxuICAgICAgLy8gICBzdG9yYWdlQ29uZmlnLFxuICAgICAgLy8gICBpbml0aWFsQ29uZmlnOiBjb25maWcsXG4gICAgICAvLyB9O1xuICAgICAgLy8gdHJ5IHtcbiAgICAgIC8vICAgYXdhaXQgc2FuZGJveEFjdGl2aXR5SG9vay5yZXN1bWUoaWQsIHtcbiAgICAgIC8vICAgICB0eXBlOiBcImFjdGl2aXR5XCIsXG4gICAgICAvLyAgICAgbmV3Q29uZmlnOiBjb25maWcsXG4gICAgICAvLyAgIH0pO1xuICAgICAgLy8gfSBjYXRjaCB7XG4gICAgICAvLyAgIGF3YWl0IHN0YXJ0KHNhbmRib3hMaWZlY3ljbGVXb3JrZmxvdywgW3sgaW5wdXQ6IGxpZmVjeWNsZUlucHV0IH1dKTtcbiAgICAgIC8vIH1cbiAgICB9XG4gIH1cblxuICBjb25zdCBsaWZlY3ljbGU6IFNhbmRib3hMaWZlY3ljbGUgPSB7XG4gICAgc3RhcnQ6IGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IHNhbmRib3ggPSBhd2FpdCBnZXRTYW5kYm94KCk7XG4gICAgICBpZiAoc2FuZGJveCBpbnN0YW5jZW9mIEVycm9yKSB7XG4gICAgICAgIHJldHVybiBzYW5kYm94O1xuICAgICAgfVxuICAgICAgYXdhaXQgdXBkYXRlTGFzdEFjdGl2aXR5KCk7XG4gICAgICByZXR1cm4gc2FuZGJveC5zdGF0dXMgYXMgU2FuZGJveFN0YXR1cztcbiAgICB9LFxuXG4gICAgc25hcHNob3Q6IGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IHNhbmRib3ggPSBhd2FpdCBnZXRTYW5kYm94KCk7XG4gICAgICBpZiAoc2FuZGJveCBpbnN0YW5jZW9mIEVycm9yKSB7XG4gICAgICAgIHJldHVybiBzYW5kYm94O1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gZXJyb3JlLnRyeUFzeW5jKHtcbiAgICAgICAgdHJ5OiBhc3luYyAoKSA9PiB7XG4gICAgICAgICAgY29uc3QgZXhpc3RpbmcgPSBhd2FpdCBzdG9yYWdlLnNhbmRib3guZ2V0KGlkKTtcbiAgICAgICAgICBjb25zdCBzbmFwc2hvdCA9IGF3YWl0IHNhbmRib3guc25hcHNob3QoKTtcbiAgICAgICAgICBhd2FpdCBzdG9yYWdlLnNhbmRib3guc2V0KHtcbiAgICAgICAgICAgIGlkLFxuICAgICAgICAgICAgY29uZmlnLFxuICAgICAgICAgICAgY3JlYXRlZEF0OlxuICAgICAgICAgICAgICBleGlzdGluZyBpbnN0YW5jZW9mIEVycm9yID8gbnVsbCA6IGV4aXN0aW5nPy5jcmVhdGVkQXQgPz8gbnVsbCxcbiAgICAgICAgICAgIGxhc3RBY3Rpdml0eUF0OlxuICAgICAgICAgICAgICBleGlzdGluZyBpbnN0YW5jZW9mIEVycm9yXG4gICAgICAgICAgICAgICAgPyBudWxsXG4gICAgICAgICAgICAgICAgOiBleGlzdGluZz8ubGFzdEFjdGl2aXR5QXQgPz8gbnVsbCxcbiAgICAgICAgICAgIGFjcXVpcmluZ0xvY2tJZDogbnVsbCxcbiAgICAgICAgICAgIGFjcXVpcmluZ0xvY2tBdDogbnVsbCxcbiAgICAgICAgICAgIHByb3ZpZGVyTWV0YWRhdGE6IHtcbiAgICAgICAgICAgICAgcHJvdmlkZXI6IFwidmVyY2VsXCIsXG4gICAgICAgICAgICAgIHNhbmRib3hJZDogbnVsbCxcbiAgICAgICAgICAgICAgc25hcHNob3RJZDogc25hcHNob3Quc25hcHNob3RJZCxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSk7XG4gICAgICAgICAgcmV0dXJuIHsgc25hcHNob3RJZDogc25hcHNob3Quc25hcHNob3RJZCB9O1xuICAgICAgICB9LFxuICAgICAgICBjYXRjaDogKGUpID0+IG5ldyBTYW5kYm94RXJyb3IoeyByZWFzb246IFN0cmluZyhlKSwgY2F1c2U6IGUgfSksXG4gICAgICB9KTtcbiAgICB9LFxuXG4gICAgc3RvcDogYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3Qgc2FuZGJveCA9IGF3YWl0IGdldFNhbmRib3goKTtcbiAgICAgIGlmIChzYW5kYm94IGluc3RhbmNlb2YgRXJyb3IpIHtcbiAgICAgICAgcmV0dXJuIHNhbmRib3g7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBlcnJvcmUudHJ5QXN5bmMoe1xuICAgICAgICB0cnk6IGFzeW5jICgpID0+IHtcbiAgICAgICAgICBhd2FpdCBzYW5kYm94LnN0b3AoKTtcbiAgICAgICAgICBjb25zdCBleGlzdGluZyA9IGF3YWl0IHN0b3JhZ2Uuc2FuZGJveC5nZXQoaWQpO1xuICAgICAgICAgIGlmIChleGlzdGluZyBpbnN0YW5jZW9mIEVycm9yIHx8ICFleGlzdGluZykge1xuICAgICAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgICAgICB9XG4gICAgICAgICAgYXdhaXQgc3RvcmFnZS5zYW5kYm94LnNldCh7XG4gICAgICAgICAgICBpZDogZXhpc3RpbmcuaWQsXG4gICAgICAgICAgICBjb25maWc6IGV4aXN0aW5nLmNvbmZpZyxcbiAgICAgICAgICAgIGNyZWF0ZWRBdDogZXhpc3RpbmcuY3JlYXRlZEF0LFxuICAgICAgICAgICAgbGFzdEFjdGl2aXR5QXQ6IGV4aXN0aW5nLmxhc3RBY3Rpdml0eUF0LFxuICAgICAgICAgICAgYWNxdWlyaW5nTG9ja0lkOiBudWxsLFxuICAgICAgICAgICAgYWNxdWlyaW5nTG9ja0F0OiBudWxsLFxuICAgICAgICAgICAgcHJvdmlkZXJNZXRhZGF0YToge1xuICAgICAgICAgICAgICBwcm92aWRlcjogXCJ2ZXJjZWxcIixcbiAgICAgICAgICAgICAgc2FuZGJveElkOiBudWxsLFxuICAgICAgICAgICAgICBzbmFwc2hvdElkOiBudWxsLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9KTtcbiAgICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgICB9LFxuICAgICAgICBjYXRjaDogKGUpID0+IG5ldyBTYW5kYm94RXJyb3IoeyByZWFzb246IFN0cmluZyhlKSwgY2F1c2U6IGUgfSksXG4gICAgICB9KTtcbiAgICB9LFxuXG4gICAgZ2V0U3RhdHVzOiBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCBzYW5kYm94ID0gYXdhaXQgZ2V0U2FuZGJveCgpO1xuICAgICAgaWYgKHNhbmRib3ggaW5zdGFuY2VvZiBFcnJvcikge1xuICAgICAgICByZXR1cm4gc2FuZGJveDtcbiAgICAgIH1cbiAgICAgIHJldHVybiBzYW5kYm94LnN0YXR1cyBhcyBTYW5kYm94U3RhdHVzO1xuICAgIH0sXG5cbiAgICBnZXRDcmVhdGVkQXQ6IGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IHNhbmRib3ggPSBhd2FpdCBnZXRTYW5kYm94KCk7XG4gICAgICBpZiAoc2FuZGJveCBpbnN0YW5jZW9mIEVycm9yKSB7XG4gICAgICAgIHJldHVybiBzYW5kYm94O1xuICAgICAgfVxuICAgICAgcmV0dXJuIHNhbmRib3guY3JlYXRlZEF0O1xuICAgIH0sXG5cbiAgICBnZXRSZW1haW5pbmdUaW1lb3V0OiBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCBzYW5kYm94ID0gYXdhaXQgZ2V0U2FuZGJveCgpO1xuICAgICAgaWYgKHNhbmRib3ggaW5zdGFuY2VvZiBFcnJvcikge1xuICAgICAgICByZXR1cm4gc2FuZGJveDtcbiAgICAgIH1cbiAgICAgIHJldHVybiBzYW5kYm94LnRpbWVvdXQ7XG4gICAgfSxcbiAgfTtcblxuICBjb25zdCBzYW5kYm94OiBTYW5kYm94ID0ge1xuICAgIGlkLFxuICAgIGNvbmZpZyxcbiAgICBleGVjOiBhc3luYyAoeyBjb21tYW5kLCBhcmdzLCBzaWduYWwgfSkgPT4ge1xuICAgICAgY29uc3QgaW5zdGFuY2UgPSBhd2FpdCBnZXRTYW5kYm94KCk7XG4gICAgICBpZiAoaW5zdGFuY2UgaW5zdGFuY2VvZiBFcnJvcikge1xuICAgICAgICByZXR1cm4gaW5zdGFuY2U7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHVwZGF0ZVByb21pc2UgPSB1cGRhdGVMYXN0QWN0aXZpdHkoKTtcblxuICAgICAgY29uc3QgZXhlY1Jlc3VsdCA9IGF3YWl0IGVycm9yZS50cnlBc3luYyh7XG4gICAgICAgIHRyeTogYXN5bmMgKCkgPT4ge1xuICAgICAgICAgIGNvbnN0IG91dHB1dCA9IGF3YWl0IGluc3RhbmNlLnJ1bkNvbW1hbmQoY29tbWFuZCwgYXJncywgeyBzaWduYWwgfSk7XG5cbiAgICAgICAgICBsZXQgc3Rkb3V0ID0gXCJcIjtcbiAgICAgICAgICBsZXQgc3RkZXJyID0gXCJcIjtcbiAgICAgICAgICBjb25zdCBsb2dCdWZmZXI6IExvZ0VudHJ5W10gPSBbXTtcbiAgICAgICAgICBjb25zdCBzdGF0ZSA9IHtcbiAgICAgICAgICAgIHJlc29sdmU6IG51bGwgYXMgKCgpID0+IHZvaWQpIHwgbnVsbCxcbiAgICAgICAgICAgIGNvbnN1bWVkOiBmYWxzZSxcbiAgICAgICAgICB9O1xuXG4gICAgICAgICAgY29uc3QgY29uc3VtZUxvZ3MgPSAoYXN5bmMgKCkgPT4ge1xuICAgICAgICAgICAgZm9yIGF3YWl0IChjb25zdCBsb2cgb2Ygb3V0cHV0LmxvZ3MoKSkge1xuICAgICAgICAgICAgICBjb25zdCBlbnRyeTogTG9nRW50cnkgPVxuICAgICAgICAgICAgICAgIGxvZy5zdHJlYW0gPT09IFwic3Rkb3V0XCJcbiAgICAgICAgICAgICAgICAgID8geyBzdHJlYW06IFwic3Rkb3V0XCIsIGRhdGE6IGxvZy5kYXRhIH1cbiAgICAgICAgICAgICAgICAgIDogeyBzdHJlYW06IFwic3RkZXJyXCIsIGRhdGE6IGxvZy5kYXRhIH07XG5cbiAgICAgICAgICAgICAgaWYgKGxvZy5zdHJlYW0gPT09IFwic3Rkb3V0XCIpIHtcbiAgICAgICAgICAgICAgICBzdGRvdXQgKz0gbG9nLmRhdGE7XG4gICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgc3RkZXJyICs9IGxvZy5kYXRhO1xuICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgbG9nQnVmZmVyLnB1c2goZW50cnkpO1xuICAgICAgICAgICAgICBzdGF0ZS5yZXNvbHZlPy4oKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHN0YXRlLmNvbnN1bWVkID0gdHJ1ZTtcbiAgICAgICAgICAgIHN0YXRlLnJlc29sdmU/LigpO1xuICAgICAgICAgIH0pKCk7XG5cbiAgICAgICAgICBhc3luYyBmdW5jdGlvbiogbG9ncygpOiBBc3luY0l0ZXJhYmxlPExvZ0VudHJ5PiB7XG4gICAgICAgICAgICBsZXQgaW5kZXggPSAwO1xuICAgICAgICAgICAgd2hpbGUgKCFzdGF0ZS5jb25zdW1lZCB8fCBpbmRleCA8IGxvZ0J1ZmZlci5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgaWYgKGluZGV4IDwgbG9nQnVmZmVyLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgIHlpZWxkIGxvZ0J1ZmZlcltpbmRleCsrXTtcbiAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBhd2FpdCBuZXcgUHJvbWlzZTx2b2lkPigocmVzb2x2ZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgc3RhdGUucmVzb2x2ZSA9IHJlc29sdmU7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgc3RhdGUucmVzb2x2ZSA9IG51bGw7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG5cbiAgICAgICAgICBjb25zdCByZXN1bHQgPSBjb25zdW1lTG9ncy50aGVuKCgpID0+ICh7XG4gICAgICAgICAgICBzdGRvdXQsXG4gICAgICAgICAgICBzdGRlcnIsXG4gICAgICAgICAgICBleGl0Q29kZTogb3V0cHV0LmV4aXRDb2RlLFxuICAgICAgICAgIH0pKTtcblxuICAgICAgICAgIHJldHVybiB7IGNvbW1hbmRJZDogb3V0cHV0LmNtZElkLCBsb2dzLCByZXN1bHQgfTtcbiAgICAgICAgfSxcbiAgICAgICAgY2F0Y2g6IChlKSA9PiBuZXcgU2FuZGJveEVycm9yKHsgcmVhc29uOiBTdHJpbmcoZSksIGNhdXNlOiBlIH0pLFxuICAgICAgfSk7XG5cbiAgICAgIGF3YWl0IHVwZGF0ZVByb21pc2U7XG4gICAgICByZXR1cm4gZXhlY1Jlc3VsdDtcbiAgICB9LFxuXG4gICAgZ2V0RG9tYWluOiBhc3luYyAocG9ydCkgPT4ge1xuICAgICAgY29uc3Qgc2FuZGJveCA9IGF3YWl0IGdldFNhbmRib3goKTtcbiAgICAgIGlmIChzYW5kYm94IGluc3RhbmNlb2YgRXJyb3IpIHtcbiAgICAgICAgcmV0dXJuIHNhbmRib3g7XG4gICAgICB9XG5cbiAgICAgIHRyeSB7XG4gICAgICAgIHJldHVybiBzYW5kYm94LmRvbWFpbihwb3J0KTtcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBTYW5kYm94RXJyb3IoeyByZWFzb246IFN0cmluZyhlKSwgY2F1c2U6IGUgfSk7XG4gICAgICB9XG4gICAgfSxcblxuICAgIGtpbGw6IGFzeW5jICh7IGNvbW1hbmRJZCwgc3RvcmFnZTogY21kU3RvcmFnZSB9KSA9PiB7XG4gICAgICBjb25zdCBpbnN0YW5jZSA9IGF3YWl0IGdldFNhbmRib3goKTtcbiAgICAgIGlmIChpbnN0YW5jZSBpbnN0YW5jZW9mIEVycm9yKSB7XG4gICAgICAgIHJldHVybiBpbnN0YW5jZTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgY21kID0gYXdhaXQgY21kU3RvcmFnZS5jb21tYW5kLmdldChjb21tYW5kSWQpO1xuICAgICAgaWYgKGNtZCBpbnN0YW5jZW9mIEVycm9yKSB7XG4gICAgICAgIHJldHVybiBuZXcgU2FuZGJveEVycm9yKHsgcmVhc29uOiBjbWQubWVzc2FnZSwgY2F1c2U6IGNtZCB9KTtcbiAgICAgIH1cbiAgICAgIGlmIChjbWQgJiYgY21kLnN0YXR1cyA9PT0gXCJydW5uaW5nXCIpIHtcbiAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgY21kU3RvcmFnZS5jb21tYW5kLnNldCh7XG4gICAgICAgICAgLi4uY21kLFxuICAgICAgICAgIHN0YXR1czogXCJraWxsZWRcIixcbiAgICAgICAgfSk7XG4gICAgICAgIGlmIChyZXN1bHQgaW5zdGFuY2VvZiBFcnJvcikge1xuICAgICAgICAgIHJldHVybiBuZXcgU2FuZGJveEVycm9yKHsgcmVhc29uOiByZXN1bHQubWVzc2FnZSwgY2F1c2U6IHJlc3VsdCB9KTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9LFxuXG4gICAgd3JpdGVGaWxlczogKG9wdHMpID0+IHdyaXRlRmlsZXMoeyBzYW5kYm94LCAuLi5vcHRzIH0pLFxuXG4gICAgbGlmZWN5Y2xlLFxuICB9O1xuXG4gIGlmIChjb25maWcubGlmZWN5Y2xlPy5hdXRvU3RhcnQgIT09IGZhbHNlKSB7XG4gICAgc2FuZGJveFByb21pc2UgPSBkb0dldFNhbmRib3goKTtcbiAgfVxuXG4gIHJldHVybiBzYW5kYm94O1xufTtcbiIsICJpbXBvcnQgdHlwZSB7IFNhbmRib3hSZWNvcmQsIFN0b3JhZ2VDb25maWcgfSBmcm9tIFwiLi4vc3RvcmFnZVwiO1xuaW1wb3J0IHsgbG9jYWxTYW5kYm94IH0gZnJvbSBcIi4vYmluZGluZ3MvbG9jYWxcIjtcbmltcG9ydCB7IHZlcmNlbFNhbmRib3ggfSBmcm9tIFwiLi9iaW5kaW5ncy92ZXJjZWxcIjtcbmltcG9ydCB0eXBlIHsgU2FuZGJveCB9IGZyb20gXCIuL3R5cGVzXCI7XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRTYW5kYm94KHtcbiAgc2FuZGJveFJlY29yZCxcbiAgc3RvcmFnZUNvbmZpZyxcbn06IHtcbiAgc3RvcmFnZUNvbmZpZzogU3RvcmFnZUNvbmZpZztcbiAgc2FuZGJveFJlY29yZDogU2FuZGJveFJlY29yZDtcbn0pOiBTYW5kYm94IHtcbiAgY29uc3QgeyBjb25maWcgfSA9IHNhbmRib3hSZWNvcmQ7XG4gIHN3aXRjaCAoY29uZmlnLnR5cGUpIHtcbiAgICBjYXNlIFwibG9jYWxcIjpcbiAgICAgIHJldHVybiBsb2NhbFNhbmRib3goe1xuICAgICAgICBzYW5kYm94UmVjb3JkOiBzYW5kYm94UmVjb3JkIGFzIFNhbmRib3hSZWNvcmQgJiB7XG4gICAgICAgICAgY29uZmlnOiB7IHR5cGU6IFwibG9jYWxcIiB9O1xuICAgICAgICB9LFxuICAgICAgICBzdG9yYWdlQ29uZmlnLFxuICAgICAgfSk7XG4gICAgY2FzZSBcInZlcmNlbFwiOlxuICAgICAgcmV0dXJuIHZlcmNlbFNhbmRib3goe1xuICAgICAgICBzYW5kYm94UmVjb3JkOiBzYW5kYm94UmVjb3JkIGFzIFNhbmRib3hSZWNvcmQgJiB7XG4gICAgICAgICAgY29uZmlnOiB7IHR5cGU6IFwidmVyY2VsXCIgfTtcbiAgICAgICAgfSxcbiAgICAgICAgc3RvcmFnZUNvbmZpZyxcbiAgICAgIH0pO1xuICAgIGNhc2UgXCJjdXN0b21cIjpcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIkN1c3RvbSBzYW5kYm94ZXMgYXJlIG5vdCBzdXBwb3J0ZWRcIik7XG4gICAgZGVmYXVsdDpcbiAgICAgIGNvbmZpZyBzYXRpc2ZpZXMgbmV2ZXI7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgIGBVbmtub3duIHNhbmRib3ggdHlwZTogJHtcbiAgICAgICAgICAvLyBiaW9tZS1pZ25vcmUgbGludC9zdXNwaWNpb3VzL25vRXhwbGljaXRBbnk6IC5cbiAgICAgICAgICAoY29uZmlnIGFzIGFueSkudHlwZVxuICAgICAgICB9YFxuICAgICAgKTtcbiAgfVxufVxuIiwgImltcG9ydCB0eXBlIHsgU2FuZGJveExpZmVjeWNsZUlucHV0IH0gZnJvbSBcIi4vdHlwZXNcIjtcblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHNuYXBzaG90U2FuZGJveFN0ZXAoaW5wdXQ6IFNhbmRib3hMaWZlY3ljbGVJbnB1dCkge1xuICBcInVzZSBzdGVwXCI7XG5cbiAgY29uc3QgeyBnZXRTdG9yYWdlIH0gPSBhd2FpdCBpbXBvcnQoXCIuLi9zdG9yYWdlXCIpO1xuICBjb25zdCB7IGdldFNhbmRib3ggfSA9IGF3YWl0IGltcG9ydChcIi4vY2xpZW50XCIpO1xuXG4gIGNvbnN0IHN0b3JhZ2UgPSBnZXRTdG9yYWdlKGlucHV0LnN0b3JhZ2VDb25maWcpO1xuICBjb25zdCBzYW5kYm94UmVjb3JkID0gYXdhaXQgc3RvcmFnZS5zYW5kYm94LmdldChpbnB1dC5pZCk7XG4gIGlmIChzYW5kYm94UmVjb3JkIGluc3RhbmNlb2YgRXJyb3IpIHtcbiAgICByZXR1cm4gc2FuZGJveFJlY29yZDtcbiAgfVxuXG4gIGNvbnN0IHNhbmRib3ggPSBnZXRTYW5kYm94KHtcbiAgICBzYW5kYm94UmVjb3JkLFxuICAgIHN0b3JhZ2VDb25maWc6IGlucHV0LnN0b3JhZ2VDb25maWcsXG4gIH0pO1xuXG4gIGF3YWl0IHNhbmRib3gubGlmZWN5Y2xlPy5zbmFwc2hvdCgpO1xufVxuIiwgImltcG9ydCB7IGRlZmluZUhvb2ssIEZhdGFsRXJyb3IsIHNsZWVwIH0gZnJvbSBcIndvcmtmbG93XCI7XG5pbXBvcnQgdHlwZSB7IFNhbmRib3hDb25maWcgfSBmcm9tIFwiLi4vc3RvcmFnZS9ycGNcIjtcbmltcG9ydCB0eXBlIHsgU2FuZGJveExpZmVjeWNsZUlucHV0IH0gZnJvbSBcIi4vdHlwZXNcIjtcblxuZXhwb3J0IHR5cGUgeyBTYW5kYm94TGlmZWN5Y2xlSW5wdXQgfTtcblxuZXhwb3J0IHR5cGUgU2FuZGJveEFjdGl2aXR5U2lnbmFsID0ge1xuICB0eXBlOiBcImFjdGl2aXR5XCI7XG4gIG5ld0NvbmZpZzogU2FuZGJveENvbmZpZztcbn07XG5cbmV4cG9ydCBjb25zdCBzYW5kYm94QWN0aXZpdHlIb29rID0gZGVmaW5lSG9vazxTYW5kYm94QWN0aXZpdHlTaWduYWw+KCk7XG5cbmNvbnN0IERFRkFVTFRfSURMRV9USU1FT1VUX01TID0gNSAqIDYwICogMTAwMDsgLy8gNSBtaW51dGVzXG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBzYW5kYm94TGlmZWN5Y2xlV29ya2Zsb3coe1xuICBpbnB1dCxcbn06IHtcbiAgaW5wdXQ6IFNhbmRib3hMaWZlY3ljbGVJbnB1dDtcbn0pIHtcbiAgXCJ1c2Ugd29ya2Zsb3dcIjtcblxuICBjb25zdCBhY3Rpdml0eUhvb2sgPSBzYW5kYm94QWN0aXZpdHlIb29rLmNyZWF0ZSh7IHRva2VuOiBpbnB1dC5pZCB9KTtcbiAgY29uc3QgaXRlcmF0b3IgPSBhY3Rpdml0eUhvb2tbU3ltYm9sLmFzeW5jSXRlcmF0b3JdKCk7XG4gIGxldCBwZW5kaW5nTmV4dCA9IGl0ZXJhdG9yLm5leHQoKTtcblxuICBsZXQgc2FuZGJveENvbmZpZyA9IGlucHV0LmluaXRpYWxDb25maWc7XG5cbiAgaWYgKHNhbmRib3hDb25maWcudHlwZSAhPT0gXCJ2ZXJjZWxcIikge1xuICAgIHRocm93IG5ldyBFcnJvcihcIlNhbmRib3ggY29uZmlnIGlzIG5vdCBhIFZlcmNlbCBzYW5kYm94XCIpO1xuICB9XG5cbiAgY29uc3QgaWRsZVRpbWVvdXRNcyA9XG4gICAgc2FuZGJveENvbmZpZy5saWZlY3ljbGU/LnN0b3BBZnRlckluYWN0aXZlTXMgPz8gREVGQVVMVF9JRExFX1RJTUVPVVRfTVM7XG5cbiAgd2hpbGUgKHRydWUpIHtcbiAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBQcm9taXNlLnJhY2UoW1xuICAgICAgcGVuZGluZ05leHQudGhlbigocikgPT4gKHsgLi4uciwgdHlwZTogXCJhY3Rpdml0eVwiIGFzIGNvbnN0IH0pKSxcbiAgICAgIHNsZWVwKGlkbGVUaW1lb3V0TXMpLnRoZW4oKCkgPT4gKHsgdHlwZTogXCJ0aW1lb3V0XCIgYXMgY29uc3QgfSkpLFxuICAgIF0pO1xuXG4gICAgaWYgKHJlc3VsdC50eXBlID09PSBcInRpbWVvdXRcIikge1xuICAgICAgY29uc3QgeyBzbmFwc2hvdFNhbmRib3hTdGVwIH0gPSBhd2FpdCBpbXBvcnQoXG4gICAgICAgIFwiLi9saWZlY3ljbGUtd29ya2Zsb3ctc3RlcHNcIlxuICAgICAgKTtcbiAgICAgIGF3YWl0IHNuYXBzaG90U2FuZGJveFN0ZXAoaW5wdXQpLmNhdGNoKChlKSA9PiB7XG4gICAgICAgIGlmIChGYXRhbEVycm9yLmlzKGUpKSB7XG4gICAgICAgICAgY29uc29sZS5lcnJvcihcIlNuYXBzaG90IGZhaWxlZCBwZXJtYW5lbnRseTpcIiwgZS5tZXNzYWdlKTtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgdGhyb3cgZTtcbiAgICAgIH0pO1xuICAgICAgYnJlYWs7XG4gICAgfVxuXG4gICAgaWYgKHJlc3VsdC5kb25lKSB7XG4gICAgICBicmVhaztcbiAgICB9XG5cbiAgICBzYW5kYm94Q29uZmlnID0gcmVzdWx0LnZhbHVlLm5ld0NvbmZpZztcbiAgICBwZW5kaW5nTmV4dCA9IGl0ZXJhdG9yLm5leHQoKTtcbiAgfVxufVxuIl0sCiAgIm1hcHBpbmdzIjogIjs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUEsWUFFYSxzQkFLQSxjQUtBLHNCQUtBLGNBS0EsY0FLQTtBQTNCYjtBQUFBO0FBQUE7QUFBQSxhQUF3QjtBQUVqQixJQUFNLHVCQUFOLGNBQTBDLHlCQUFrQjtBQUFBLE1BQ2pFLE1BQU07QUFBQSxNQUNOLFNBQVM7QUFBQSxJQUNYLENBQUMsRUFBRTtBQUFBLElBQUM7QUFFRyxJQUFNLGVBQU4sY0FBa0MseUJBQWtCO0FBQUEsTUFDekQsTUFBTTtBQUFBLE1BQ04sU0FBUztBQUFBLElBQ1gsQ0FBQyxFQUFFO0FBQUEsSUFBQztBQUVHLElBQU0sdUJBQU4sY0FBMEMseUJBQWtCO0FBQUEsTUFDakUsTUFBTTtBQUFBLE1BQ04sU0FBUztBQUFBLElBQ1gsQ0FBQyxFQUFFO0FBQUEsSUFBQztBQUVHLElBQU0sZUFBTixjQUFrQyx5QkFBa0I7QUFBQSxNQUN6RCxNQUFNO0FBQUEsTUFDTixTQUFTO0FBQUEsSUFDWCxDQUFDLEVBQUU7QUFBQSxJQUFDO0FBRUcsSUFBTSxlQUFOLGNBQWtDLHlCQUFrQjtBQUFBLE1BQ3pELE1BQU07QUFBQSxNQUNOLFNBQVM7QUFBQSxJQUNYLENBQUMsRUFBRTtBQUFBLElBQUM7QUFFRyxJQUFNLHVCQUFOLGNBQTBDLHlCQUFrQjtBQUFBLE1BQ2pFLE1BQU07QUFBQSxNQUNOLFNBQVM7QUFBQSxJQUNYLENBQUMsRUFBRTtBQUFBLElBQUM7QUFBQTtBQUFBOzs7QUM1QkcsU0FBUyxTQUFtQyxNQUlqQztBQUNoQixRQUFNLEVBQUUsT0FBTyxRQUFRLFFBQVEsR0FBRyxJQUFJO0FBQ3RDLFFBQU0sYUFBYSxT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LFVBQzdELHVCQUFNLGFBQWEsRUFBRSxLQUFLLE9BQU8sRUFBRSxNQUFNLFVBQW1CLEVBQUU7QUFBQSxJQUNoRSxDQUFDO0FBRUQsUUFBSSxPQUFPLFNBQVMsV0FBVztBQUM3QixZQUFNLEVBQUUscUJBQUFDLHFCQUFvQixJQUFJLE1BQU07QUFHdEMsWUFBTUEscUJBQW9CLEtBQUssRUFBRSxNQUFNLENBQUMsTUFBTTtBQUM1QyxZQUFJLDJCQUFXLEdBQUcsQ0FBQyxHQUFHO0FBQ3BCLGtCQUFRLE1BQU0sZ0NBQWdDLEVBQUUsT0FBTztBQUN2RDtBQUFBLFFBQ0Y7QUFDQSxjQUFNO0FBQUEsTUFDUixDQUFDO0FBQ0Q7QUFBQSxJQUNGO0FBRUEsUUFBSSxPQUFPLE1BQU07QUFDZjtBQUFBLElBQ0Y7QUFFQSxvQkFBZ0IsT0FBTyxNQUFNO0FBQzdCLGtCQUFjLFNBQVMsS0FBSztBQUFBLEVBQzlCO0FBQ0Y7IiwKICAibmFtZXMiOiBbInN0YXJ0TG9jYWxTdG9yYWdlIiwgImdldFZlcmNlbFN0b3JhZ2VDb25maWciLCAiZXhpdENvZGUiLCAic3RkZXJyIiwgImVycm9yZSIsICJpbml0X2xvY2FsIiwgImVycm9yZSIsICJpbml0X3ZlcmNlbCIsICJzYW5kYm94IiwgIlZlcmNlbFNhbmRib3hTREsiLCAiZ2V0U2FuZGJveCIsICJpbml0X2NsaWVudCIsICJpbml0X2xvY2FsIiwgImluaXRfdmVyY2VsIiwgImdldFN0b3JhZ2UiLCAiZ2V0U2FuZGJveCIsICJzbmFwc2hvdFNhbmRib3hTdGVwIl0KfQo=
|