experimental-agent 0.1.2 → 0.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/README.md +9 -0
  2. package/dist/agent-workflow.d.mts +1 -1
  3. package/dist/agent-workflow.d.ts +1 -1
  4. package/dist/agent-workflow.js +352 -104
  5. package/dist/agent-workflow.mjs +1 -1
  6. package/dist/{chunk-W4SSZPDX.mjs → chunk-24UDM5XV.mjs} +4 -4
  7. package/dist/chunk-2ZXHR6T6.mjs +401 -0
  8. package/dist/chunk-4WDKWMVB.mjs +389 -0
  9. package/dist/chunk-IACG26TC.mjs +2212 -0
  10. package/dist/chunk-NGLND33F.mjs +1247 -0
  11. package/dist/{chunk-E7TOPGHY.mjs → chunk-RXPVLORL.mjs} +3 -3
  12. package/dist/{chunk-HJGPUEFC.mjs → chunk-YRYXN7W4.mjs} +7 -1
  13. package/dist/client-Bkuq-Dfa.d.mts +2340 -0
  14. package/dist/client-Bkuq-Dfa.d.ts +2340 -0
  15. package/dist/{client-YUU54ZZH.mjs → client-SNN3XDKO.mjs} +2 -2
  16. package/dist/client.d.mts +1 -1
  17. package/dist/client.d.ts +1 -1
  18. package/dist/client.js +1 -1
  19. package/dist/client.mjs +1 -1
  20. package/dist/{handler-LDFBSCRA.mjs → handler-WFNQWR6V.mjs} +2 -1
  21. package/dist/index.d.mts +2 -2
  22. package/dist/index.d.ts +2 -2
  23. package/dist/index.js +623 -220
  24. package/dist/index.mjs +78 -40
  25. package/dist/lifecycle-workflow.d.mts +1 -1
  26. package/dist/lifecycle-workflow.d.ts +1 -1
  27. package/dist/lifecycle-workflow.js +88 -6
  28. package/dist/lifecycle-workflow.mjs +1 -1
  29. package/dist/local-fs-handlers-ESZBRAWK.mjs +439 -0
  30. package/dist/next/loader.js +3 -3
  31. package/dist/next/loader.mjs +1 -1
  32. package/dist/next.js +10 -4
  33. package/dist/next.mjs +9 -3
  34. package/dist/{sandbox-GPCA35PJ.mjs → sandbox-IFK5MVRM.mjs} +3 -3
  35. package/dist/{storage-LL6IA24R.mjs → storage-FCSHTDLC.mjs} +3 -3
  36. package/package.json +2 -2
  37. package/dist/chunk-2SPAJ777.mjs +0 -365
  38. package/dist/chunk-6J462JGP.mjs +0 -1267
  39. package/dist/chunk-ILPVXRI5.mjs +0 -2026
  40. package/dist/chunk-ORE6LK2L.mjs +0 -344
  41. package/dist/client-CKLwB-ES.d.mts +0 -2115
  42. package/dist/client-CKLwB-ES.d.ts +0 -2115
  43. package/dist/local-fs-handlers-SY2RDXZE.mjs +0 -314
@@ -0,0 +1,1247 @@
1
+ import {
2
+ sandboxLifecycleWorkflow
3
+ } from "./chunk-24UDM5XV.mjs";
4
+ import {
5
+ SandboxError,
6
+ SandboxNotFoundError
7
+ } from "./chunk-YRYXN7W4.mjs";
8
+
9
+ // src/utils/debug.ts
10
+ var enabled = process.env.AGENT_DEBUG === "1" || process.env.AGENT_DEBUG === "true";
11
+ function debug(...args) {
12
+ if (enabled) {
13
+ console.log(...args);
14
+ }
15
+ }
16
+
17
+ // src/sandbox/bindings/local.ts
18
+ import { spawn } from "child_process";
19
+ import * as fs from "fs/promises";
20
+ import * as path2 from "path";
21
+ import * as errore from "errore";
22
+ import { ulid } from "ulid";
23
+
24
+ // src/sandbox/write-files.ts
25
+ import * as path from "path";
26
+ var MAX_RETRIES = 2;
27
+ var RETRY_BASE_MS = 500;
28
+ async function execChecked(sandbox, opts, errorLabel) {
29
+ for (let attempt = 0; ; attempt++) {
30
+ const execResult = await sandbox.exec(opts);
31
+ if (execResult instanceof Error) {
32
+ throw execResult;
33
+ }
34
+ const result = await execResult.result;
35
+ if (result.exitCode === 0) {
36
+ return result;
37
+ }
38
+ const isTransient = result.exitCode === 255 && !result.stderr.trim();
39
+ if (isTransient && attempt < MAX_RETRIES) {
40
+ await new Promise((r) => setTimeout(r, RETRY_BASE_MS * (attempt + 1)));
41
+ continue;
42
+ }
43
+ throw new Error(
44
+ `${errorLabel} with exit code ${result.exitCode}: ${result.stderr}`
45
+ );
46
+ }
47
+ }
48
+ async function writeFiles(opts) {
49
+ const { sandbox, files, destPath } = opts;
50
+ if (files.length === 0) {
51
+ return;
52
+ }
53
+ const filePaths = files.map((file) => path.posix.join(destPath, file.path));
54
+ const parentDirs = Array.from(
55
+ new Set(filePaths.map((p) => path.posix.dirname(p)))
56
+ );
57
+ const shellScripts = filePaths.filter((p) => p.endsWith(".sh"));
58
+ const mkdirResult = await sandbox.exec({
59
+ command: "mkdir",
60
+ args: ["-p", ...parentDirs]
61
+ });
62
+ if (mkdirResult instanceof Error) {
63
+ throw mkdirResult;
64
+ }
65
+ await mkdirResult.result;
66
+ const CHUNK_SIZE = 5e4;
67
+ for (let i = 0; i < files.length; i++) {
68
+ const file = files[i];
69
+ const fullPath = filePaths[i];
70
+ const base64Content = toBase64(file.content);
71
+ if (base64Content.length < CHUNK_SIZE) {
72
+ const marker = `EOF_${i}`;
73
+ await execChecked(
74
+ sandbox,
75
+ {
76
+ command: "bash",
77
+ args: [
78
+ "-c",
79
+ `base64 -d > ${quote(fullPath)} << '${marker}'
80
+ ${base64Content}
81
+ ${marker}`
82
+ ]
83
+ },
84
+ "writeFiles failed"
85
+ );
86
+ } else {
87
+ const tempB64 = `/tmp/chunk-${Date.now()}-${i}.b64`;
88
+ const clearResult = await sandbox.exec({
89
+ command: "bash",
90
+ args: ["-c", `> ${quote(tempB64)}`]
91
+ });
92
+ if (clearResult instanceof Error) {
93
+ throw clearResult;
94
+ }
95
+ await clearResult.result;
96
+ for (let offset = 0; offset < base64Content.length; offset += CHUNK_SIZE) {
97
+ const chunk = base64Content.slice(offset, offset + CHUNK_SIZE);
98
+ const marker = `CHUNK_${offset}`;
99
+ await execChecked(
100
+ sandbox,
101
+ {
102
+ command: "bash",
103
+ args: [
104
+ "-c",
105
+ `cat >> ${quote(tempB64)} << '${marker}'
106
+ ${chunk}
107
+ ${marker}`
108
+ ]
109
+ },
110
+ "writeFiles chunk failed"
111
+ );
112
+ }
113
+ await execChecked(
114
+ sandbox,
115
+ {
116
+ command: "bash",
117
+ args: [
118
+ "-c",
119
+ `base64 -d < ${quote(tempB64)} > ${quote(fullPath)} && rm -f ${quote(tempB64)}`
120
+ ]
121
+ },
122
+ "writeFiles decode failed"
123
+ );
124
+ }
125
+ }
126
+ if (shellScripts.length > 0) {
127
+ const chmodResult = await sandbox.exec({
128
+ command: "chmod",
129
+ args: ["+x", ...shellScripts]
130
+ });
131
+ if (chmodResult instanceof Error) {
132
+ throw chmodResult;
133
+ }
134
+ await chmodResult.result;
135
+ }
136
+ }
137
+ function toBase64(content) {
138
+ if (typeof content === "string") {
139
+ return Buffer.from(content).toString("base64");
140
+ }
141
+ return content.toString("base64");
142
+ }
143
+ function quote(s) {
144
+ return `'${s.replace(/'/g, "'\\''")}'`;
145
+ }
146
+
147
+ // src/sandbox/bindings/local.ts
148
+ var localSandbox = ({
149
+ sandboxRecord,
150
+ storage,
151
+ setup,
152
+ onRestart
153
+ }) => {
154
+ const config = sandboxRecord.config;
155
+ const basePath = config.path ?? process.cwd();
156
+ const processes = /* @__PURE__ */ new Map();
157
+ const sandbox = {
158
+ id: sandboxRecord.id,
159
+ config: sandboxRecord.config,
160
+ exec: ({ command, args, signal }) => {
161
+ return errore.tryAsync({
162
+ try: () => {
163
+ const commandId = `command_${ulid()}`;
164
+ const child = spawn(command, args, {
165
+ cwd: basePath,
166
+ signal
167
+ });
168
+ processes.set(commandId, child);
169
+ let stdout = "";
170
+ let stderr = "";
171
+ const logQueue = [];
172
+ let logResolve = null;
173
+ let closed = false;
174
+ child.stdout.on("data", (data) => {
175
+ const str = String(data);
176
+ stdout += str;
177
+ logQueue.push({ stream: "stdout", data: str });
178
+ logResolve?.();
179
+ });
180
+ child.stderr.on("data", (data) => {
181
+ const str = String(data);
182
+ stderr += str;
183
+ logQueue.push({ stream: "stderr", data: str });
184
+ logResolve?.();
185
+ });
186
+ const result2 = new Promise((resolve, reject) => {
187
+ child.on("error", (err) => {
188
+ processes.delete(commandId);
189
+ closed = true;
190
+ logResolve?.();
191
+ reject(err);
192
+ });
193
+ child.on("close", (code) => {
194
+ processes.delete(commandId);
195
+ closed = true;
196
+ logResolve?.();
197
+ resolve({ stdout, stderr, exitCode: code ?? 0 });
198
+ });
199
+ });
200
+ async function* logs() {
201
+ while (!closed || logQueue.length > 0) {
202
+ const entry = logQueue.shift();
203
+ if (entry) {
204
+ yield entry;
205
+ } else if (!closed) {
206
+ await new Promise((resolve) => {
207
+ logResolve = resolve;
208
+ });
209
+ logResolve = null;
210
+ }
211
+ }
212
+ }
213
+ return Promise.resolve({ commandId, logs, result: result2 });
214
+ },
215
+ catch: (e) => new SandboxError({ reason: String(e), cause: e })
216
+ });
217
+ },
218
+ getDomain: (port) => {
219
+ return Promise.resolve(`http://localhost:${port}`);
220
+ },
221
+ kill: async ({ commandId, storage: storage2 }) => {
222
+ const child = processes.get(commandId);
223
+ if (!child) {
224
+ return new SandboxError({
225
+ reason: `Command ${commandId} not found or already finished`
226
+ });
227
+ }
228
+ child.kill("SIGTERM");
229
+ const cmd = await storage2.command.get(commandId);
230
+ if (cmd instanceof Error) {
231
+ return new SandboxError({ reason: cmd.message, cause: cmd });
232
+ }
233
+ if (cmd && cmd.status === "running") {
234
+ const result2 = await storage2.command.set({
235
+ ...cmd,
236
+ status: "killed"
237
+ });
238
+ if (result2 instanceof Error) {
239
+ return new SandboxError({ reason: result2.message, cause: result2 });
240
+ }
241
+ }
242
+ },
243
+ readFile: async ({ path: filePath }) => {
244
+ const fullPath = path2.join(basePath, filePath);
245
+ try {
246
+ return await fs.readFile(fullPath);
247
+ } catch (e) {
248
+ if (e instanceof Error && "code" in e && e.code === "ENOENT") {
249
+ return null;
250
+ }
251
+ return new SandboxError({ reason: String(e), cause: e });
252
+ }
253
+ },
254
+ writeFiles: (opts) => writeFiles({ sandbox, ...opts }),
255
+ updateNetworkPolicy: () => Promise.resolve(
256
+ new SandboxError({
257
+ reason: "updateNetworkPolicy is only available for Vercel sandboxes"
258
+ })
259
+ ),
260
+ tag: {
261
+ list: async () => {
262
+ const sandboxRecord2 = await storage.sandbox.get(sandbox.id);
263
+ if (sandboxRecord2 instanceof Error) {
264
+ return sandboxRecord2;
265
+ }
266
+ return sandboxRecord2.tags ?? {};
267
+ },
268
+ get: async (key) => {
269
+ const sandboxRecord2 = await storage.sandbox.get(sandbox.id);
270
+ if (sandboxRecord2 instanceof Error) {
271
+ return sandboxRecord2;
272
+ }
273
+ return sandboxRecord2.tags?.[key];
274
+ },
275
+ set: async (key, value) => {
276
+ const result2 = await storage.sandbox.tag.set({
277
+ sandboxId: sandbox.id,
278
+ tags: { [key]: value }
279
+ });
280
+ if (result2 instanceof Error) {
281
+ return result2;
282
+ }
283
+ return void 0;
284
+ },
285
+ setMany: async (tags) => {
286
+ const result2 = await storage.sandbox.tag.set({
287
+ sandboxId: sandbox.id,
288
+ tags
289
+ });
290
+ if (result2 instanceof Error) {
291
+ return result2;
292
+ }
293
+ return void 0;
294
+ }
295
+ }
296
+ };
297
+ const result = sandbox;
298
+ if (setup || onRestart) {
299
+ let resolveSetupMeta;
300
+ result._setupMeta = new Promise((r) => {
301
+ resolveSetupMeta = r;
302
+ });
303
+ result._onReady = (async () => {
304
+ let needsSetupRun = !!setup;
305
+ if (setup) {
306
+ const existing = await storage.setup.get(setup.key);
307
+ if (!(existing instanceof Error) && existing) {
308
+ debug(
309
+ `[sandbox:setup] setup already complete for key "${setup.key}", skipping`
310
+ );
311
+ needsSetupRun = false;
312
+ }
313
+ }
314
+ resolveSetupMeta({
315
+ needsSetupRun,
316
+ createdFromSnapshot: false
317
+ });
318
+ if (needsSetupRun && setup) {
319
+ debug(`[sandbox:setup] running setup.run (local, key="${setup.key}")`);
320
+ await setup.run(sandbox);
321
+ await storage.setup.set({
322
+ key: setup.key,
323
+ snapshotId: null,
324
+ createdAt: Date.now(),
325
+ lastUsedAt: null,
326
+ acquiringLockId: null,
327
+ acquiringLockAt: null
328
+ });
329
+ debug(
330
+ `[sandbox:setup] setup complete, stored record (key="${setup.key}")`
331
+ );
332
+ }
333
+ if (onRestart) {
334
+ debug("[sandbox:setup] running onRestart (local)");
335
+ await onRestart(sandbox);
336
+ }
337
+ })();
338
+ }
339
+ return result;
340
+ };
341
+
342
+ // src/sandbox/bindings/vercel.ts
343
+ import * as path3 from "path";
344
+ import { Sandbox as VercelSandboxSDK } from "@vercel/sandbox";
345
+ import * as errore2 from "errore";
346
+ import { start } from "workflow/api";
347
+ var VERCEL_MAX_TIMEOUT_MS = 5 * 60 * 60 * 1e3;
348
+ var LOCK_TIMEOUT_MS = 5 * 60 * 1e3;
349
+ var LOCK_POLL_INTERVAL_MS = 200;
350
+ var getTestCredentials = () => process.env.NODE_ENV === "test" ? {
351
+ token: process.env.TEST_VERCEL_TOKEN,
352
+ teamId: process.env.TEST_VERCEL_TEAM_ID,
353
+ projectId: process.env.TEST_VERCEL_PROJECT_ID
354
+ } : {};
355
+ var createPromises = /* @__PURE__ */ new Map();
356
+ var ACTIVITY_THROTTLE_MS = 1e4;
357
+ var lastActivitySent = /* @__PURE__ */ new Map();
358
+ var DEFAULT_VCPUS = 2;
359
+ function isSandboxGoneError(e) {
360
+ if (!(e instanceof Error)) {
361
+ return false;
362
+ }
363
+ const errorWithResponse = e;
364
+ const errorWithCause = e;
365
+ const status = errorWithResponse.response?.status ?? errorWithCause.cause?.response?.status;
366
+ if (status === 410 || status === 422) {
367
+ return true;
368
+ }
369
+ const message = e.message || String(e);
370
+ if (message.includes("Expected a stream of command data") || message.includes("Expected a stream of logs")) {
371
+ return true;
372
+ }
373
+ return false;
374
+ }
375
+ var vercelSandbox = ({
376
+ sandboxRecord,
377
+ storageConfig,
378
+ enableLifecycleWorkflow,
379
+ storage,
380
+ rpc,
381
+ setup,
382
+ onRestart
383
+ }) => {
384
+ const { id, config } = sandboxRecord;
385
+ const vcpus = config.resources?.vcpus ?? DEFAULT_VCPUS;
386
+ const ports = config.ports;
387
+ const networkPolicy = config.networkPolicy;
388
+ const initialVercel = sandboxRecord.providerMetadata?.provider === "vercel" ? sandboxRecord.providerMetadata : null;
389
+ let sandboxPromise = null;
390
+ let recoveredFromStale = false;
391
+ let createdFromSnapshot = false;
392
+ let needsSetupRun = false;
393
+ const HOME_DIR = "/home/vercel-sandbox";
394
+ async function pollForSandboxId() {
395
+ const deadline = Date.now() + LOCK_TIMEOUT_MS;
396
+ while (Date.now() < deadline) {
397
+ await new Promise((r) => setTimeout(r, LOCK_POLL_INTERVAL_MS));
398
+ const record = await storage.sandbox.get(id);
399
+ if (record instanceof Error) {
400
+ return new SandboxError({ reason: record.message, cause: record });
401
+ }
402
+ const vercelSandboxId = record?.providerMetadata?.provider === "vercel" ? record.providerMetadata.sandboxId : null;
403
+ if (vercelSandboxId) {
404
+ return vercelSandboxId;
405
+ }
406
+ if (!record?.acquiringLockAt) {
407
+ const finalCheck = await storage.sandbox.get(id);
408
+ if (finalCheck instanceof Error) {
409
+ return new SandboxError({
410
+ reason: finalCheck.message,
411
+ cause: finalCheck
412
+ });
413
+ }
414
+ const finalVercelSandboxId = finalCheck?.providerMetadata?.provider === "vercel" ? finalCheck.providerMetadata.sandboxId : null;
415
+ if (finalVercelSandboxId) {
416
+ return finalVercelSandboxId;
417
+ }
418
+ return doGetOrCreateSandboxId();
419
+ }
420
+ }
421
+ return new SandboxError({
422
+ reason: "Timed out waiting for sandbox creation by another process"
423
+ });
424
+ }
425
+ async function startLifecycleWorkflow(vercelSandboxId) {
426
+ if (!enableLifecycleWorkflow) {
427
+ return;
428
+ }
429
+ const lifecycleInput = {
430
+ id,
431
+ vercelSandboxId,
432
+ storageConfig,
433
+ rpc
434
+ };
435
+ await start(sandboxLifecycleWorkflow, [{ input: lifecycleInput }]).catch(
436
+ // biome-ignore lint/suspicious/noEmptyBlockStatements: intentionally ignored - workflow start is fire-and-forget
437
+ () => {
438
+ }
439
+ );
440
+ }
441
+ async function createSandboxFromSnapshot(snapshotId) {
442
+ return await errore2.tryAsync({
443
+ try: async () => {
444
+ const sandbox2 = await VercelSandboxSDK.create({
445
+ source: { type: "snapshot", snapshotId },
446
+ resources: { vcpus },
447
+ timeout: VERCEL_MAX_TIMEOUT_MS,
448
+ ports,
449
+ networkPolicy,
450
+ ...getTestCredentials()
451
+ });
452
+ const now = Date.now();
453
+ await storage.sandbox.set({
454
+ id,
455
+ config,
456
+ tags: sandboxRecord.tags,
457
+ createdAt: now,
458
+ lastActivityAt: now,
459
+ acquiringLockId: null,
460
+ acquiringLockAt: null,
461
+ providerMetadata: {
462
+ provider: "vercel",
463
+ sandboxId: sandbox2.sandboxId,
464
+ snapshotId
465
+ }
466
+ });
467
+ await startLifecycleWorkflow(sandbox2.sandboxId);
468
+ return sandbox2.sandboxId;
469
+ },
470
+ catch: (e) => new SandboxError({ reason: String(e), cause: e })
471
+ });
472
+ }
473
+ async function createFreshSandbox() {
474
+ return await errore2.tryAsync({
475
+ try: async () => {
476
+ const sandbox2 = await VercelSandboxSDK.create({
477
+ resources: { vcpus },
478
+ timeout: VERCEL_MAX_TIMEOUT_MS,
479
+ ports,
480
+ networkPolicy,
481
+ ...getTestCredentials()
482
+ });
483
+ const now = Date.now();
484
+ await storage.sandbox.set({
485
+ id,
486
+ config,
487
+ tags: sandboxRecord.tags,
488
+ createdAt: now,
489
+ lastActivityAt: now,
490
+ acquiringLockId: null,
491
+ acquiringLockAt: null,
492
+ providerMetadata: {
493
+ provider: "vercel",
494
+ sandboxId: sandbox2.sandboxId,
495
+ snapshotId: null
496
+ }
497
+ });
498
+ await startLifecycleWorkflow(sandbox2.sandboxId);
499
+ return sandbox2.sandboxId;
500
+ },
501
+ catch: (e) => new SandboxError({ reason: String(e), cause: e })
502
+ });
503
+ }
504
+ function execOnInstance(instance, {
505
+ command,
506
+ args,
507
+ signal
508
+ }) {
509
+ return errore2.tryAsync({
510
+ try: async () => {
511
+ const output = await instance.runCommand({
512
+ cwd: HOME_DIR,
513
+ args,
514
+ cmd: command,
515
+ signal,
516
+ detached: true
517
+ });
518
+ let stdout = "";
519
+ let stderr = "";
520
+ const logBuffer = [];
521
+ const state = {
522
+ resolve: null,
523
+ consumed: false
524
+ };
525
+ const consumeLogs = (async () => {
526
+ try {
527
+ for await (const log of output.logs()) {
528
+ const entry = log.stream === "stdout" ? { stream: "stdout", data: log.data } : { stream: "stderr", data: log.data };
529
+ if (log.stream === "stdout") {
530
+ stdout += log.data;
531
+ } else {
532
+ stderr += log.data;
533
+ }
534
+ logBuffer.push(entry);
535
+ state.resolve?.();
536
+ }
537
+ } catch {
538
+ }
539
+ state.consumed = true;
540
+ state.resolve?.();
541
+ })();
542
+ async function* logs() {
543
+ let index = 0;
544
+ while (!state.consumed || index < logBuffer.length) {
545
+ if (index < logBuffer.length) {
546
+ yield logBuffer[index++];
547
+ } else {
548
+ await new Promise((resolve) => {
549
+ state.resolve = resolve;
550
+ });
551
+ state.resolve = null;
552
+ }
553
+ }
554
+ }
555
+ const result = consumeLogs.then(async () => {
556
+ try {
557
+ const finished = await output.wait();
558
+ return {
559
+ stdout,
560
+ stderr,
561
+ exitCode: finished.exitCode
562
+ };
563
+ } catch (e) {
564
+ if (isSandboxGoneError(e)) {
565
+ return { stdout, stderr, exitCode: 1 };
566
+ }
567
+ throw e;
568
+ }
569
+ });
570
+ return { commandId: output.cmdId, logs, result };
571
+ },
572
+ catch: (e) => new SandboxError({ reason: String(e), cause: e })
573
+ });
574
+ }
575
+ function readFileOnInstance(instance, { path: path4 }) {
576
+ return errore2.tryAsync({
577
+ try: () => instance.readFileToBuffer({ path: path4, cwd: HOME_DIR }),
578
+ catch: (e) => new SandboxError({ reason: String(e), cause: e })
579
+ });
580
+ }
581
+ async function writeFilesOnInstance(instance, opts) {
582
+ const { files, destPath } = opts;
583
+ if (files.length === 0) {
584
+ return;
585
+ }
586
+ const nativeFiles = files.map((file) => {
587
+ const filePath = path3.posix.join(destPath, file.path);
588
+ const absolutePath = path3.posix.isAbsolute(filePath) ? filePath : path3.posix.join(HOME_DIR, filePath);
589
+ return {
590
+ path: absolutePath,
591
+ content: typeof file.content === "string" ? Buffer.from(file.content) : file.content
592
+ };
593
+ });
594
+ await instance.writeFiles(nativeFiles);
595
+ const shellScripts = nativeFiles.filter((f) => f.path.endsWith(".sh"));
596
+ if (shellScripts.length > 0) {
597
+ const chmodResult = await execOnInstance(instance, {
598
+ command: "chmod",
599
+ args: ["+x", ...shellScripts.map((f) => f.path)]
600
+ });
601
+ if (chmodResult instanceof Error) {
602
+ throw chmodResult;
603
+ }
604
+ await chmodResult.result;
605
+ }
606
+ }
607
+ function createTempSandbox(instance) {
608
+ const tempSandbox = {
609
+ id: `__setup_temp_${Date.now()}`,
610
+ config,
611
+ exec: (opts) => execOnInstance(instance, opts),
612
+ readFile: (opts) => readFileOnInstance(instance, opts),
613
+ getDomain: () => Promise.resolve(
614
+ new SandboxError({ reason: "not available during setup" })
615
+ ),
616
+ kill: () => Promise.resolve(
617
+ new SandboxError({ reason: "not available during setup" })
618
+ ),
619
+ writeFiles: (opts) => writeFilesOnInstance(instance, opts),
620
+ updateNetworkPolicy: (policy) => errore2.tryAsync({
621
+ try: () => instance.updateNetworkPolicy(policy),
622
+ catch: (e) => new SandboxError({ reason: String(e), cause: e })
623
+ }),
624
+ tag: {
625
+ list: async () => ({}),
626
+ get: async () => void 0,
627
+ set: async () => void 0,
628
+ setMany: async () => void 0
629
+ }
630
+ };
631
+ return tempSandbox;
632
+ }
633
+ async function pollForSetupSnapshot(key) {
634
+ const deadline = Date.now() + LOCK_TIMEOUT_MS;
635
+ while (Date.now() < deadline) {
636
+ await new Promise((r) => setTimeout(r, LOCK_POLL_INTERVAL_MS));
637
+ const record = await storage.setup.get(key);
638
+ if (record instanceof Error) {
639
+ return null;
640
+ }
641
+ if (record?.snapshotId) {
642
+ return record.snapshotId;
643
+ }
644
+ if (!record?.acquiringLockId) {
645
+ return null;
646
+ }
647
+ }
648
+ return null;
649
+ }
650
+ async function createSetupSnapshot(opts) {
651
+ if (!setup) {
652
+ return;
653
+ }
654
+ const setupKey = setup.key;
655
+ if (!opts?.force) {
656
+ const existing = await storage.setup.get(setupKey);
657
+ if (!(existing instanceof Error) && existing?.snapshotId) {
658
+ return;
659
+ }
660
+ }
661
+ debug(`[sandbox:setup] acquiring lock for setup key "${setupKey}"`);
662
+ const lockId = crypto.randomUUID();
663
+ const locked = await storage.setup.acquireLock(
664
+ setupKey,
665
+ lockId,
666
+ LOCK_TIMEOUT_MS
667
+ );
668
+ if (locked instanceof Error || !locked) {
669
+ debug(
670
+ `[sandbox:setup] lock not acquired for key "${setupKey}" (another process holds it)`
671
+ );
672
+ return;
673
+ }
674
+ if (!opts?.force && locked.snapshotId) {
675
+ debug(
676
+ `[sandbox:setup] snapshot already exists after lock for key "${setupKey}", skipping`
677
+ );
678
+ return;
679
+ }
680
+ let tempInstance = null;
681
+ try {
682
+ debug(
683
+ `[sandbox:setup] creating temp sandbox for snapshot (key="${setupKey}")`
684
+ );
685
+ tempInstance = await VercelSandboxSDK.create({
686
+ resources: { vcpus },
687
+ timeout: VERCEL_MAX_TIMEOUT_MS,
688
+ ports,
689
+ networkPolicy,
690
+ ...getTestCredentials()
691
+ });
692
+ const tempSandbox = createTempSandbox(
693
+ tempInstance
694
+ );
695
+ await setup.run(tempSandbox);
696
+ debug(
697
+ `[sandbox:setup] setup.run complete, snapshotting (key="${setupKey}")`
698
+ );
699
+ const snapshot = await tempInstance.snapshot();
700
+ await storage.setup.set({
701
+ key: setupKey,
702
+ snapshotId: snapshot.snapshotId,
703
+ createdAt: locked.createdAt,
704
+ lastUsedAt: null,
705
+ acquiringLockId: null,
706
+ acquiringLockAt: null
707
+ });
708
+ debug(
709
+ `[sandbox:setup] snapshot stored: ${snapshot.snapshotId} (key="${setupKey}")`
710
+ );
711
+ await tempInstance.stop().catch(() => void 0);
712
+ } catch (e) {
713
+ console.error(
714
+ `[sandbox:setup] failed to create setup snapshot (key="${setupKey}"):`,
715
+ e
716
+ );
717
+ if (tempInstance) {
718
+ await tempInstance.stop().catch(() => void 0);
719
+ }
720
+ await storage.setup.set({
721
+ key: setupKey,
722
+ snapshotId: null,
723
+ createdAt: locked.createdAt,
724
+ lastUsedAt: null,
725
+ acquiringLockId: null,
726
+ acquiringLockAt: null
727
+ }).catch(() => void 0);
728
+ }
729
+ }
730
+ async function doGetOrCreateSandboxId() {
731
+ if (initialVercel?.sandboxId && !recoveredFromStale) {
732
+ return initialVercel.sandboxId;
733
+ }
734
+ const existing = await storage.sandbox.get(id);
735
+ if (existing instanceof Error) {
736
+ if (existing instanceof SandboxNotFoundError) {
737
+ } else {
738
+ return new SandboxError({ reason: existing.message, cause: existing });
739
+ }
740
+ }
741
+ const existingRecord = existing instanceof SandboxNotFoundError ? null : existing;
742
+ const existingVercel = existingRecord?.providerMetadata?.provider === "vercel" ? existingRecord.providerMetadata : null;
743
+ if (existingVercel?.sandboxId) {
744
+ return existingVercel.sandboxId;
745
+ }
746
+ const hasActiveLock = existingRecord?.acquiringLockId && existingRecord.acquiringLockAt && Date.now() - existingRecord.acquiringLockAt < LOCK_TIMEOUT_MS;
747
+ if (hasActiveLock) {
748
+ return pollForSandboxId();
749
+ }
750
+ const lockId = crypto.randomUUID();
751
+ const now = Date.now();
752
+ const locked = await storage.sandbox.acquireLock(
753
+ {
754
+ id,
755
+ config,
756
+ tags: existingRecord?.tags ?? sandboxRecord.tags,
757
+ createdAt: existingRecord?.createdAt ?? sandboxRecord.createdAt,
758
+ lastActivityAt: existingRecord?.lastActivityAt ?? sandboxRecord.lastActivityAt,
759
+ acquiringLockId: lockId,
760
+ acquiringLockAt: now,
761
+ providerMetadata: {
762
+ provider: "vercel",
763
+ sandboxId: null,
764
+ snapshotId: existingVercel?.snapshotId ?? initialVercel?.snapshotId ?? null
765
+ }
766
+ },
767
+ LOCK_TIMEOUT_MS
768
+ );
769
+ if (locked instanceof Error) {
770
+ return new SandboxError({ reason: locked.message, cause: locked });
771
+ }
772
+ if (!locked) {
773
+ return pollForSandboxId();
774
+ }
775
+ const lockedRecord = locked;
776
+ async function releaseSandboxLock() {
777
+ await storage.sandbox.update({
778
+ id: lockedRecord.id,
779
+ acquiringLockId: null,
780
+ acquiringLockAt: null
781
+ }).catch(() => void 0);
782
+ }
783
+ const lockedVercel = lockedRecord.providerMetadata?.provider === "vercel" ? lockedRecord.providerMetadata : null;
784
+ if (lockedVercel?.sandboxId) {
785
+ await releaseSandboxLock();
786
+ return lockedVercel.sandboxId;
787
+ }
788
+ const snapshotId = lockedVercel?.snapshotId ?? initialVercel?.snapshotId ?? config.lifecycle?.snapshotId;
789
+ if (snapshotId) {
790
+ const result = await createSandboxFromSnapshot(snapshotId);
791
+ if (!(result instanceof Error)) {
792
+ createdFromSnapshot = true;
793
+ return result;
794
+ }
795
+ }
796
+ if (setup) {
797
+ let forceRecreateSnapshot = false;
798
+ const setupRecord = await storage.setup.get(setup.key);
799
+ if (!(setupRecord instanceof Error) && setupRecord) {
800
+ if (setupRecord.snapshotId) {
801
+ debug(
802
+ `[sandbox:setup] found setup snapshot ${setupRecord.snapshotId} for key "${setup.key}"`
803
+ );
804
+ const result = await createSandboxFromSnapshot(
805
+ setupRecord.snapshotId
806
+ );
807
+ if (!(result instanceof Error)) {
808
+ createdFromSnapshot = true;
809
+ storage.setup.set({
810
+ ...setupRecord,
811
+ lastUsedAt: Date.now()
812
+ }).catch(() => void 0);
813
+ return result;
814
+ }
815
+ debug(
816
+ `[sandbox:setup] snapshot ${setupRecord.snapshotId} failed (expired?), will recreate`
817
+ );
818
+ forceRecreateSnapshot = true;
819
+ } else if (setupRecord.acquiringLockId && setupRecord.acquiringLockAt && Date.now() - setupRecord.acquiringLockAt < LOCK_TIMEOUT_MS) {
820
+ debug(
821
+ `[sandbox:setup] snapshot in progress for key "${setup.key}", waiting...`
822
+ );
823
+ const snapshotId2 = await pollForSetupSnapshot(setup.key);
824
+ if (snapshotId2) {
825
+ debug(
826
+ `[sandbox:setup] snapshot ready: ${snapshotId2} for key "${setup.key}"`
827
+ );
828
+ const result = await createSandboxFromSnapshot(snapshotId2);
829
+ if (!(result instanceof Error)) {
830
+ createdFromSnapshot = true;
831
+ return result;
832
+ }
833
+ }
834
+ }
835
+ }
836
+ debug(
837
+ `[sandbox:setup] no snapshot for key "${setup.key}", will run setup on this sandbox`
838
+ );
839
+ needsSetupRun = true;
840
+ createSetupSnapshot({ force: forceRecreateSnapshot }).catch((e) => {
841
+ console.error(
842
+ "[sandbox:setup] failed to create background snapshot:",
843
+ e
844
+ );
845
+ });
846
+ }
847
+ const freshResult = await createFreshSandbox();
848
+ if (freshResult instanceof Error) {
849
+ await releaseSandboxLock();
850
+ }
851
+ return freshResult;
852
+ }
853
+ function getOrCreateSandboxId() {
854
+ const cached = createPromises.get(id);
855
+ if (cached) {
856
+ return cached;
857
+ }
858
+ const promise = doGetOrCreateSandboxId().finally(() => {
859
+ createPromises.delete(id);
860
+ });
861
+ createPromises.set(id, promise);
862
+ return promise;
863
+ }
864
+ async function doGetSandbox() {
865
+ const vercelSandboxId = await getOrCreateSandboxId();
866
+ if (vercelSandboxId instanceof Error) {
867
+ return vercelSandboxId;
868
+ }
869
+ return errore2.tryAsync({
870
+ try: () => VercelSandboxSDK.get({
871
+ sandboxId: vercelSandboxId,
872
+ ...getTestCredentials()
873
+ }),
874
+ catch: (e) => new SandboxError({ reason: String(e), cause: e })
875
+ });
876
+ }
877
+ function getSandbox2() {
878
+ if (!sandboxPromise) {
879
+ sandboxPromise = doGetSandbox();
880
+ }
881
+ return sandboxPromise;
882
+ }
883
+ async function recoverFromStaleSandbox() {
884
+ sandboxPromise = null;
885
+ recoveredFromStale = true;
886
+ const existing = await storage.sandbox.get(id);
887
+ if (existing instanceof Error || !existing) {
888
+ return;
889
+ }
890
+ const existingVercel = existing.providerMetadata?.provider === "vercel" ? existing.providerMetadata : null;
891
+ if (existingVercel?.sandboxId) {
892
+ await storage.sandbox.update({
893
+ id: existing.id,
894
+ acquiringLockId: null,
895
+ acquiringLockAt: null,
896
+ providerMetadata: {
897
+ provider: "vercel",
898
+ sandboxId: null,
899
+ snapshotId: existingVercel.snapshotId
900
+ }
901
+ });
902
+ }
903
+ }
904
+ async function updateLastActivity() {
905
+ const now = Date.now();
906
+ const lastSent = lastActivitySent.get(id);
907
+ if (lastSent && now - lastSent < ACTIVITY_THROTTLE_MS) {
908
+ return;
909
+ }
910
+ lastActivitySent.set(id, now);
911
+ const existing = await storage.sandbox.get(id);
912
+ if (existing instanceof Error || !existing) {
913
+ return;
914
+ }
915
+ const existingVercel = existing.providerMetadata?.provider === "vercel" ? existing.providerMetadata : null;
916
+ await storage.sandbox.update({
917
+ id: existing.id,
918
+ lastActivityAt: now,
919
+ acquiringLockId: null,
920
+ acquiringLockAt: null,
921
+ providerMetadata: existingVercel ?? {
922
+ provider: "vercel",
923
+ sandboxId: null,
924
+ snapshotId: null
925
+ }
926
+ });
927
+ }
928
+ const lifecycle = {
929
+ start: async () => {
930
+ const sandbox2 = await getSandbox2();
931
+ if (sandbox2 instanceof Error) {
932
+ return sandbox2;
933
+ }
934
+ await updateLastActivity();
935
+ return sandbox2.status;
936
+ },
937
+ snapshot: async () => {
938
+ const sandbox2 = await getSandbox2();
939
+ if (sandbox2 instanceof Error) {
940
+ return sandbox2;
941
+ }
942
+ return errore2.tryAsync({
943
+ try: async () => {
944
+ const snapshot = await sandbox2.snapshot();
945
+ await storage.sandbox.update({
946
+ id,
947
+ acquiringLockId: null,
948
+ acquiringLockAt: null,
949
+ providerMetadata: {
950
+ provider: "vercel",
951
+ sandboxId: null,
952
+ snapshotId: snapshot.snapshotId
953
+ }
954
+ });
955
+ return { snapshotId: snapshot.snapshotId };
956
+ },
957
+ catch: (e) => new SandboxError({ reason: String(e), cause: e })
958
+ });
959
+ },
960
+ stop: async () => {
961
+ const sandbox2 = await getSandbox2();
962
+ if (sandbox2 instanceof Error) {
963
+ return sandbox2;
964
+ }
965
+ return errore2.tryAsync({
966
+ try: async () => {
967
+ await sandbox2.stop();
968
+ await storage.sandbox.update({
969
+ id,
970
+ acquiringLockId: null,
971
+ acquiringLockAt: null,
972
+ providerMetadata: {
973
+ provider: "vercel",
974
+ sandboxId: null,
975
+ snapshotId: null
976
+ }
977
+ });
978
+ return void 0;
979
+ },
980
+ catch: (e) => new SandboxError({ reason: String(e), cause: e })
981
+ });
982
+ },
983
+ getStatus: async () => {
984
+ const sandbox2 = await getSandbox2();
985
+ if (sandbox2 instanceof Error) {
986
+ return sandbox2;
987
+ }
988
+ return sandbox2.status;
989
+ },
990
+ getCreatedAt: async () => {
991
+ const sandbox2 = await getSandbox2();
992
+ if (sandbox2 instanceof Error) {
993
+ return sandbox2;
994
+ }
995
+ return sandbox2.createdAt;
996
+ },
997
+ getRemainingTimeout: async () => {
998
+ const sandbox2 = await getSandbox2();
999
+ if (sandbox2 instanceof Error) {
1000
+ return sandbox2;
1001
+ }
1002
+ return sandbox2.timeout;
1003
+ }
1004
+ };
1005
+ async function doExec(opts) {
1006
+ const instance = await getSandbox2();
1007
+ if (instance instanceof Error) {
1008
+ return instance;
1009
+ }
1010
+ const updatePromise = updateLastActivity();
1011
+ const execResult = await execOnInstance(instance, opts);
1012
+ await updatePromise;
1013
+ return execResult;
1014
+ }
1015
+ const sandbox = {
1016
+ id,
1017
+ config,
1018
+ exec: async (opts) => {
1019
+ const result = await doExec(opts);
1020
+ if (result instanceof SandboxError && isSandboxGoneError(result.cause)) {
1021
+ await recoverFromStaleSandbox();
1022
+ return await doExec(opts);
1023
+ }
1024
+ return result;
1025
+ },
1026
+ getDomain: async (port) => {
1027
+ const sandbox2 = await getSandbox2();
1028
+ if (sandbox2 instanceof Error) {
1029
+ return sandbox2;
1030
+ }
1031
+ try {
1032
+ return sandbox2.domain(port);
1033
+ } catch (e) {
1034
+ return new SandboxError({ reason: String(e), cause: e });
1035
+ }
1036
+ },
1037
+ kill: async ({ commandId, storage: cmdStorage }) => {
1038
+ const instance = await getSandbox2();
1039
+ if (instance instanceof Error) {
1040
+ return instance;
1041
+ }
1042
+ const cmd = await cmdStorage.command.get(commandId);
1043
+ if (cmd instanceof Error) {
1044
+ return new SandboxError({ reason: cmd.message, cause: cmd });
1045
+ }
1046
+ if (cmd && cmd.status === "running") {
1047
+ const result = await cmdStorage.command.set({
1048
+ ...cmd,
1049
+ status: "killed"
1050
+ });
1051
+ if (result instanceof Error) {
1052
+ return new SandboxError({ reason: result.message, cause: result });
1053
+ }
1054
+ }
1055
+ return void 0;
1056
+ },
1057
+ readFile: async (opts) => {
1058
+ const instance = await getSandbox2();
1059
+ if (instance instanceof Error) {
1060
+ return instance;
1061
+ }
1062
+ return readFileOnInstance(instance, opts);
1063
+ },
1064
+ writeFiles: async (opts) => {
1065
+ const instance = await getSandbox2();
1066
+ if (instance instanceof Error) {
1067
+ throw instance;
1068
+ }
1069
+ return writeFilesOnInstance(instance, opts);
1070
+ },
1071
+ lifecycle,
1072
+ updateNetworkPolicy: async (policy) => {
1073
+ const instance = await getSandbox2();
1074
+ if (instance instanceof Error) {
1075
+ return instance;
1076
+ }
1077
+ return errore2.tryAsync({
1078
+ try: () => instance.updateNetworkPolicy(policy),
1079
+ catch: (e) => new SandboxError({ reason: String(e), cause: e })
1080
+ });
1081
+ },
1082
+ tag: {
1083
+ list: async () => {
1084
+ const sandboxRecord2 = await storage.sandbox.get(id);
1085
+ if (sandboxRecord2 instanceof Error) {
1086
+ return sandboxRecord2;
1087
+ }
1088
+ return sandboxRecord2.tags ?? {};
1089
+ },
1090
+ get: async (key) => {
1091
+ const sandboxRecord2 = await storage.sandbox.get(id);
1092
+ if (sandboxRecord2 instanceof Error) {
1093
+ return sandboxRecord2;
1094
+ }
1095
+ return sandboxRecord2.tags?.[key];
1096
+ },
1097
+ set: async (key, value) => {
1098
+ const result = await storage.sandbox.tag.set({
1099
+ sandboxId: id,
1100
+ tags: { [key]: value }
1101
+ });
1102
+ if (result instanceof Error) {
1103
+ return result;
1104
+ }
1105
+ return void 0;
1106
+ },
1107
+ setMany: async (tags) => {
1108
+ const result = await storage.sandbox.tag.set({
1109
+ sandboxId: id,
1110
+ tags
1111
+ });
1112
+ if (result instanceof Error) {
1113
+ return result;
1114
+ }
1115
+ return void 0;
1116
+ }
1117
+ }
1118
+ };
1119
+ let onReadyPromise = Promise.resolve();
1120
+ let setupMetaPromise = Promise.resolve({
1121
+ needsSetupRun: false,
1122
+ createdFromSnapshot: false
1123
+ });
1124
+ if (config.lifecycle?.autoStart !== false) {
1125
+ sandboxPromise = doGetSandbox();
1126
+ setupMetaPromise = sandboxPromise.then(() => ({
1127
+ needsSetupRun,
1128
+ createdFromSnapshot
1129
+ }));
1130
+ onReadyPromise = sandboxPromise.then(async (instance) => {
1131
+ if (instance instanceof Error) {
1132
+ return;
1133
+ }
1134
+ if (needsSetupRun && setup) {
1135
+ debug(
1136
+ `[sandbox:setup] running setup.run on session sandbox (key="${setup.key}")`
1137
+ );
1138
+ await setup.run(sandbox);
1139
+ debug("[sandbox:setup] setup.run complete on session sandbox");
1140
+ }
1141
+ if (createdFromSnapshot && onRestart) {
1142
+ debug("[sandbox:setup] running onRestart (created from snapshot)");
1143
+ await onRestart(sandbox);
1144
+ }
1145
+ });
1146
+ }
1147
+ sandbox._onReady = onReadyPromise;
1148
+ sandbox._setupMeta = setupMetaPromise;
1149
+ return sandbox;
1150
+ };
1151
+
1152
+ // src/sandbox/client.ts
1153
+ var sandboxCache = /* @__PURE__ */ new Map();
1154
+ function getSandbox({
1155
+ sandboxRecord,
1156
+ storageConfig,
1157
+ storage,
1158
+ rpc,
1159
+ enableLifecycleWorkflow = true,
1160
+ setup,
1161
+ onRestart
1162
+ }) {
1163
+ const cached = sandboxCache.get(sandboxRecord.id);
1164
+ if (cached) {
1165
+ debug("[getSandbox] cache hit for", sandboxRecord.id);
1166
+ return cached;
1167
+ }
1168
+ const sbx = createSandbox({
1169
+ sandboxRecord,
1170
+ storageConfig,
1171
+ storage,
1172
+ rpc,
1173
+ enableLifecycleWorkflow,
1174
+ setup,
1175
+ onRestart
1176
+ });
1177
+ sandboxCache.set(sandboxRecord.id, sbx);
1178
+ return sbx;
1179
+ }
1180
+ function createSandbox({
1181
+ sandboxRecord,
1182
+ storageConfig,
1183
+ storage,
1184
+ rpc,
1185
+ enableLifecycleWorkflow = true,
1186
+ setup,
1187
+ onRestart
1188
+ }) {
1189
+ let sbx;
1190
+ switch (sandboxRecord.config.type) {
1191
+ case "local":
1192
+ sbx = localSandbox({
1193
+ sandboxRecord,
1194
+ storage,
1195
+ setup,
1196
+ onRestart
1197
+ });
1198
+ break;
1199
+ case "vercel":
1200
+ sbx = vercelSandbox({
1201
+ sandboxRecord,
1202
+ storageConfig,
1203
+ storage,
1204
+ rpc,
1205
+ enableLifecycleWorkflow,
1206
+ setup,
1207
+ onRestart
1208
+ });
1209
+ break;
1210
+ case "custom":
1211
+ throw new Error("Custom sandboxes are not supported");
1212
+ default:
1213
+ sandboxRecord.config;
1214
+ throw new Error(
1215
+ `Unknown sandbox type: ${// biome-ignore lint/suspicious/noExplicitAny: .
1216
+ sandboxRecord.config.type}`
1217
+ );
1218
+ }
1219
+ if (!sbx._onReady) {
1220
+ return sbx;
1221
+ }
1222
+ const onReady = sbx._onReady;
1223
+ return {
1224
+ ...sbx,
1225
+ exec: async (opts) => {
1226
+ await onReady;
1227
+ return sbx.exec(opts);
1228
+ },
1229
+ getDomain: async (port) => {
1230
+ await onReady;
1231
+ return sbx.getDomain(port);
1232
+ },
1233
+ readFile: async (opts) => {
1234
+ await onReady;
1235
+ return sbx.readFile(opts);
1236
+ },
1237
+ writeFiles: async (opts) => {
1238
+ await onReady;
1239
+ return sbx.writeFiles(opts);
1240
+ }
1241
+ };
1242
+ }
1243
+
1244
+ export {
1245
+ getSandbox
1246
+ };
1247
+ //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vc3JjL3V0aWxzL2RlYnVnLnRzIiwgIi4uL3NyYy9zYW5kYm94L2JpbmRpbmdzL2xvY2FsLnRzIiwgIi4uL3NyYy9zYW5kYm94L3dyaXRlLWZpbGVzLnRzIiwgIi4uL3NyYy9zYW5kYm94L2JpbmRpbmdzL3ZlcmNlbC50cyIsICIuLi9zcmMvc2FuZGJveC9jbGllbnQudHMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbImNvbnN0IGVuYWJsZWQgPVxuICBwcm9jZXNzLmVudi5BR0VOVF9ERUJVRyA9PT0gXCIxXCIgfHwgcHJvY2Vzcy5lbnYuQUdFTlRfREVCVUcgPT09IFwidHJ1ZVwiO1xuXG5leHBvcnQgZnVuY3Rpb24gZGVidWcoLi4uYXJnczogdW5rbm93bltdKSB7XG4gIGlmIChlbmFibGVkKSB7XG4gICAgY29uc29sZS5sb2coLi4uYXJncyk7XG4gIH1cbn1cbiIsICJpbXBvcnQgdHlwZSB7IENoaWxkUHJvY2VzcyB9IGZyb20gXCJub2RlOmNoaWxkX3Byb2Nlc3NcIjtcbmltcG9ydCB7IHNwYXduIH0gZnJvbSBcIm5vZGU6Y2hpbGRfcHJvY2Vzc1wiO1xuaW1wb3J0ICogYXMgZnMgZnJvbSBcIm5vZGU6ZnMvcHJvbWlzZXNcIjtcbmltcG9ydCAqIGFzIHBhdGggZnJvbSBcIm5vZGU6cGF0aFwiO1xuaW1wb3J0ICogYXMgZXJyb3JlIGZyb20gXCJlcnJvcmVcIjtcbmltcG9ydCB7IHVsaWQgfSBmcm9tIFwidWxpZFwiO1xuaW1wb3J0IHsgU2FuZGJveEVycm9yIH0gZnJvbSBcIi4uLy4uL2Vycm9yc1wiO1xuaW1wb3J0IHR5cGUgeyBUYWdzU2NoZW1hIH0gZnJvbSBcIi4uLy4uL2luZGV4XCI7XG5pbXBvcnQgdHlwZSB7IFNhbmRib3hSZWNvcmQsIFN0b3JhZ2UgfSBmcm9tIFwiLi4vLi4vc3RvcmFnZVwiO1xuaW1wb3J0IHsgZGVidWcgfSBmcm9tIFwiLi4vLi4vdXRpbHMvZGVidWdcIjtcbmltcG9ydCB0eXBlIHsgU2FuZGJveFNldHVwTWV0YSB9IGZyb20gXCIuLi9jbGllbnRcIjtcbmltcG9ydCB0eXBlIHsgTG9nRW50cnksIE9uUmVzdGFydCwgU2FuZGJveCwgU2FuZGJveFNldHVwIH0gZnJvbSBcIi4uL3R5cGVzXCI7XG5pbXBvcnQgeyB3cml0ZUZpbGVzIH0gZnJvbSBcIi4uL3dyaXRlLWZpbGVzXCI7XG5cbmV4cG9ydCBjb25zdCBsb2NhbFNhbmRib3ggPSA8VFRhZ3MgZXh0ZW5kcyBUYWdzU2NoZW1hID0gVGFnc1NjaGVtYT4oe1xuICBzYW5kYm94UmVjb3JkLFxuICBzdG9yYWdlLFxuICBzZXR1cCxcbiAgb25SZXN0YXJ0LFxufToge1xuICBzYW5kYm94UmVjb3JkOiBTYW5kYm94UmVjb3JkICYgeyBjb25maWc6IHsgdHlwZTogXCJsb2NhbFwiIH0gfTtcbiAgc3RvcmFnZTogU3RvcmFnZTtcbiAgc2V0dXA/OiBTYW5kYm94U2V0dXA7XG4gIG9uUmVzdGFydD86IE9uUmVzdGFydDtcbn0pOiBTYW5kYm94PFRUYWdzPiAmIHtcbiAgX29uUmVhZHk/OiBQcm9taXNlPHZvaWQ+O1xuICBfc2V0dXBNZXRhPzogUHJvbWlzZTxTYW5kYm94U2V0dXBNZXRhPjtcbn0gPT4ge1xuICBjb25zdCBjb25maWcgPSBzYW5kYm94UmVjb3JkLmNvbmZpZztcbiAgY29uc3QgYmFzZVBhdGggPSBjb25maWcucGF0aCA/PyBwcm9jZXNzLmN3ZCgpO1xuICBjb25zdCBwcm9jZXNzZXMgPSBuZXcgTWFwPHN0cmluZywgQ2hpbGRQcm9jZXNzPigpO1xuXG4gIGNvbnN0IHNhbmRib3g6IFNhbmRib3g8VFRhZ3M+ID0ge1xuICAgIGlkOiBzYW5kYm94UmVjb3JkLmlkLFxuICAgIGNvbmZpZzogc2FuZGJveFJlY29yZC5jb25maWcsXG4gICAgZXhlYzogKHsgY29tbWFuZCwgYXJncywgc2lnbmFsIH0pID0+IHtcbiAgICAgIHJldHVybiBlcnJvcmUudHJ5QXN5bmMoe1xuICAgICAgICB0cnk6ICgpID0+IHtcbiAgICAgICAgICBjb25zdCBjb21tYW5kSWQgPSBgY29tbWFuZF8ke3VsaWQoKX1gO1xuXG4gICAgICAgICAgY29uc3QgY2hpbGQgPSBzcGF3bihjb21tYW5kLCBhcmdzLCB7XG4gICAgICAgICAgICBjd2Q6IGJhc2VQYXRoLFxuICAgICAgICAgICAgc2lnbmFsLFxuICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgcHJvY2Vzc2VzLnNldChjb21tYW5kSWQsIGNoaWxkKTtcblxuICAgICAgICAgIGxldCBzdGRvdXQgPSBcIlwiO1xuICAgICAgICAgIGxldCBzdGRlcnIgPSBcIlwiO1xuICAgICAgICAgIGNvbnN0IGxvZ1F1ZXVlOiBMb2dFbnRyeVtdID0gW107XG4gICAgICAgICAgbGV0IGxvZ1Jlc29sdmU6ICgoKSA9PiB2b2lkKSB8IG51bGwgPSBudWxsO1xuICAgICAgICAgIGxldCBjbG9zZWQgPSBmYWxzZTtcblxuICAgICAgICAgIGNoaWxkLnN0ZG91dC5vbihcImRhdGFcIiwgKGRhdGE6IHN0cmluZyB8IEJ1ZmZlcikgPT4ge1xuICAgICAgICAgICAgY29uc3Qgc3RyID0gU3RyaW5nKGRhdGEpO1xuICAgICAgICAgICAgc3Rkb3V0ICs9IHN0cjtcbiAgICAgICAgICAgIGxvZ1F1ZXVlLnB1c2goeyBzdHJlYW06IFwic3Rkb3V0XCIsIGRhdGE6IHN0ciB9KTtcbiAgICAgICAgICAgIGxvZ1Jlc29sdmU/LigpO1xuICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgY2hpbGQuc3RkZXJyLm9uKFwiZGF0YVwiLCAoZGF0YTogc3RyaW5nIHwgQnVmZmVyKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBzdHIgPSBTdHJpbmcoZGF0YSk7XG4gICAgICAgICAgICBzdGRlcnIgKz0gc3RyO1xuICAgICAgICAgICAgbG9nUXVldWUucHVzaCh7IHN0cmVhbTogXCJzdGRlcnJcIiwgZGF0YTogc3RyIH0pO1xuICAgICAgICAgICAgbG9nUmVzb2x2ZT8uKCk7XG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgICBjb25zdCByZXN1bHQgPSBuZXcgUHJvbWlzZTx7XG4gICAgICAgICAgICBzdGRvdXQ6IHN0cmluZztcbiAgICAgICAgICAgIHN0ZGVycjogc3RyaW5nO1xuICAgICAgICAgICAgZXhpdENvZGU6IG51bWJlcjtcbiAgICAgICAgICB9PigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBjaGlsZC5vbihcImVycm9yXCIsIChlcnIpID0+IHtcbiAgICAgICAgICAgICAgcHJvY2Vzc2VzLmRlbGV0ZShjb21tYW5kSWQpO1xuICAgICAgICAgICAgICBjbG9zZWQgPSB0cnVlO1xuICAgICAgICAgICAgICBsb2dSZXNvbHZlPy4oKTtcbiAgICAgICAgICAgICAgcmVqZWN0KGVycik7XG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgY2hpbGQub24oXCJjbG9zZVwiLCAoY29kZTogbnVtYmVyIHwgbnVsbCkgPT4ge1xuICAgICAgICAgICAgICBwcm9jZXNzZXMuZGVsZXRlKGNvbW1hbmRJZCk7XG4gICAgICAgICAgICAgIGNsb3NlZCA9IHRydWU7XG4gICAgICAgICAgICAgIGxvZ1Jlc29sdmU/LigpO1xuICAgICAgICAgICAgICByZXNvbHZlKHsgc3Rkb3V0LCBzdGRlcnIsIGV4aXRDb2RlOiBjb2RlID8/IDAgfSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9KTtcblxuICAgICAgICAgIGFzeW5jIGZ1bmN0aW9uKiBsb2dzKCk6IEFzeW5jSXRlcmFibGU8TG9nRW50cnk+IHtcbiAgICAgICAgICAgIHdoaWxlICghY2xvc2VkIHx8IGxvZ1F1ZXVlLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgICAgY29uc3QgZW50cnkgPSBsb2dRdWV1ZS5zaGlmdCgpO1xuICAgICAgICAgICAgICBpZiAoZW50cnkpIHtcbiAgICAgICAgICAgICAgICB5aWVsZCBlbnRyeTtcbiAgICAgICAgICAgICAgfSBlbHNlIGlmICghY2xvc2VkKSB7XG4gICAgICAgICAgICAgICAgYXdhaXQgbmV3IFByb21pc2U8dm9pZD4oKHJlc29sdmUpID0+IHtcbiAgICAgICAgICAgICAgICAgIGxvZ1Jlc29sdmUgPSByZXNvbHZlO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIGxvZ1Jlc29sdmUgPSBudWxsO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSh7IGNvbW1hbmRJZCwgbG9ncywgcmVzdWx0IH0pO1xuICAgICAgICB9LFxuICAgICAgICBjYXRjaDogKGU6IHVua25vd24pID0+XG4gICAgICAgICAgbmV3IFNhbmRib3hFcnJvcih7IHJlYXNvbjogU3RyaW5nKGUpLCBjYXVzZTogZSB9KSxcbiAgICAgIH0pO1xuICAgIH0sXG5cbiAgICBnZXREb21haW46IChwb3J0KSA9PiB7XG4gICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKGBodHRwOi8vbG9jYWxob3N0OiR7cG9ydH1gKTtcbiAgICB9LFxuXG4gICAga2lsbDogYXN5bmMgKHsgY29tbWFuZElkLCBzdG9yYWdlIH0pID0+IHtcbiAgICAgIGNvbnN0IGNoaWxkID0gcHJvY2Vzc2VzLmdldChjb21tYW5kSWQpO1xuICAgICAgaWYgKCFjaGlsZCkge1xuICAgICAgICByZXR1cm4gbmV3IFNhbmRib3hFcnJvcih7XG4gICAgICAgICAgcmVhc29uOiBgQ29tbWFuZCAke2NvbW1hbmRJZH0gbm90IGZvdW5kIG9yIGFscmVhZHkgZmluaXNoZWRgLFxuICAgICAgICB9KTtcbiAgICAgIH1cblxuICAgICAgY2hpbGQua2lsbChcIlNJR1RFUk1cIik7XG5cbiAgICAgIGNvbnN0IGNtZCA9IGF3YWl0IHN0b3JhZ2UuY29tbWFuZC5nZXQoY29tbWFuZElkKTtcbiAgICAgIGlmIChjbWQgaW5zdGFuY2VvZiBFcnJvcikge1xuICAgICAgICByZXR1cm4gbmV3IFNhbmRib3hFcnJvcih7IHJlYXNvbjogY21kLm1lc3NhZ2UsIGNhdXNlOiBjbWQgfSk7XG4gICAgICB9XG4gICAgICBpZiAoY21kICYmIGNtZC5zdGF0dXMgPT09IFwicnVubmluZ1wiKSB7XG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHN0b3JhZ2UuY29tbWFuZC5zZXQoe1xuICAgICAgICAgIC4uLmNtZCxcbiAgICAgICAgICBzdGF0dXM6IFwia2lsbGVkXCIsXG4gICAgICAgIH0pO1xuICAgICAgICBpZiAocmVzdWx0IGluc3RhbmNlb2YgRXJyb3IpIHtcbiAgICAgICAgICByZXR1cm4gbmV3IFNhbmRib3hFcnJvcih7IHJlYXNvbjogcmVzdWx0Lm1lc3NhZ2UsIGNhdXNlOiByZXN1bHQgfSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9LFxuXG4gICAgcmVhZEZpbGU6IGFzeW5jICh7IHBhdGg6IGZpbGVQYXRoIH0pID0+IHtcbiAgICAgIGNvbnN0IGZ1bGxQYXRoID0gcGF0aC5qb2luKGJhc2VQYXRoLCBmaWxlUGF0aCk7XG4gICAgICB0cnkge1xuICAgICAgICByZXR1cm4gYXdhaXQgZnMucmVhZEZpbGUoZnVsbFBhdGgpO1xuICAgICAgfSBjYXRjaCAoZTogdW5rbm93bikge1xuICAgICAgICBpZiAoXG4gICAgICAgICAgZSBpbnN0YW5jZW9mIEVycm9yICYmXG4gICAgICAgICAgXCJjb2RlXCIgaW4gZSAmJlxuICAgICAgICAgIChlIGFzIE5vZGVKUy5FcnJub0V4Y2VwdGlvbikuY29kZSA9PT0gXCJFTk9FTlRcIlxuICAgICAgICApIHtcbiAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbmV3IFNhbmRib3hFcnJvcih7IHJlYXNvbjogU3RyaW5nKGUpLCBjYXVzZTogZSB9KTtcbiAgICAgIH1cbiAgICB9LFxuXG4gICAgd3JpdGVGaWxlczogKG9wdHMpID0+IHdyaXRlRmlsZXMoeyBzYW5kYm94LCAuLi5vcHRzIH0pLFxuXG4gICAgdXBkYXRlTmV0d29ya1BvbGljeTogKCkgPT5cbiAgICAgIFByb21pc2UucmVzb2x2ZShcbiAgICAgICAgbmV3IFNhbmRib3hFcnJvcih7XG4gICAgICAgICAgcmVhc29uOiBcInVwZGF0ZU5ldHdvcmtQb2xpY3kgaXMgb25seSBhdmFpbGFibGUgZm9yIFZlcmNlbCBzYW5kYm94ZXNcIixcbiAgICAgICAgfSlcbiAgICAgICksXG5cbiAgICB0YWc6IHtcbiAgICAgIGxpc3Q6IGFzeW5jICgpID0+IHtcbiAgICAgICAgY29uc3Qgc2FuZGJveFJlY29yZCA9IGF3YWl0IHN0b3JhZ2Uuc2FuZGJveC5nZXQoc2FuZGJveC5pZCk7XG4gICAgICAgIGlmIChzYW5kYm94UmVjb3JkIGluc3RhbmNlb2YgRXJyb3IpIHtcbiAgICAgICAgICByZXR1cm4gc2FuZGJveFJlY29yZDtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gKHNhbmRib3hSZWNvcmQudGFncyA/PyB7fSkgYXMgVFRhZ3M7XG4gICAgICB9LFxuICAgICAgZ2V0OiBhc3luYyAoa2V5OiBzdHJpbmcpID0+IHtcbiAgICAgICAgY29uc3Qgc2FuZGJveFJlY29yZCA9IGF3YWl0IHN0b3JhZ2Uuc2FuZGJveC5nZXQoc2FuZGJveC5pZCk7XG4gICAgICAgIGlmIChzYW5kYm94UmVjb3JkIGluc3RhbmNlb2YgRXJyb3IpIHtcbiAgICAgICAgICByZXR1cm4gc2FuZGJveFJlY29yZDtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gc2FuZGJveFJlY29yZC50YWdzPy5ba2V5IGFzIHN0cmluZ10gYXNcbiAgICAgICAgICB8IFRUYWdzW3R5cGVvZiBrZXldXG4gICAgICAgICAgfCB1bmRlZmluZWQ7XG4gICAgICB9LFxuICAgICAgc2V0OiBhc3luYyAoa2V5OiBzdHJpbmcsIHZhbHVlOiB1bmtub3duKSA9PiB7XG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHN0b3JhZ2Uuc2FuZGJveC50YWcuc2V0KHtcbiAgICAgICAgICBzYW5kYm94SWQ6IHNhbmRib3guaWQsXG4gICAgICAgICAgdGFnczogeyBba2V5XTogdmFsdWUgfSBhcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPixcbiAgICAgICAgfSk7XG4gICAgICAgIGlmIChyZXN1bHQgaW5zdGFuY2VvZiBFcnJvcikge1xuICAgICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgIH0sXG4gICAgICBzZXRNYW55OiBhc3luYyAodGFnczogUmVjb3JkPHN0cmluZywgdW5rbm93bj4pID0+IHtcbiAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgc3RvcmFnZS5zYW5kYm94LnRhZy5zZXQoe1xuICAgICAgICAgIHNhbmRib3hJZDogc2FuZGJveC5pZCxcbiAgICAgICAgICB0YWdzOiB0YWdzIGFzIFJlY29yZDxzdHJpbmcsIHVua25vd24+LFxuICAgICAgICB9KTtcbiAgICAgICAgaWYgKHJlc3VsdCBpbnN0YW5jZW9mIEVycm9yKSB7XG4gICAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgfSxcbiAgICB9LFxuICB9O1xuXG4gIGNvbnN0IHJlc3VsdDogU2FuZGJveDxUVGFncz4gJiB7XG4gICAgX29uUmVhZHk/OiBQcm9taXNlPHZvaWQ+O1xuICAgIF9zZXR1cE1ldGE/OiBQcm9taXNlPFNhbmRib3hTZXR1cE1ldGE+O1xuICB9ID0gc2FuZGJveDtcblxuICBpZiAoc2V0dXAgfHwgb25SZXN0YXJ0KSB7XG4gICAgbGV0IHJlc29sdmVTZXR1cE1ldGEhOiAobWV0YTogU2FuZGJveFNldHVwTWV0YSkgPT4gdm9pZDtcbiAgICByZXN1bHQuX3NldHVwTWV0YSA9IG5ldyBQcm9taXNlPFNhbmRib3hTZXR1cE1ldGE+KChyKSA9PiB7XG4gICAgICByZXNvbHZlU2V0dXBNZXRhID0gcjtcbiAgICB9KTtcblxuICAgIHJlc3VsdC5fb25SZWFkeSA9IChhc3luYyAoKSA9PiB7XG4gICAgICBsZXQgbmVlZHNTZXR1cFJ1biA9ICEhc2V0dXA7XG4gICAgICBpZiAoc2V0dXApIHtcbiAgICAgICAgY29uc3QgZXhpc3RpbmcgPSBhd2FpdCBzdG9yYWdlLnNldHVwLmdldChzZXR1cC5rZXkpO1xuICAgICAgICBpZiAoIShleGlzdGluZyBpbnN0YW5jZW9mIEVycm9yKSAmJiBleGlzdGluZykge1xuICAgICAgICAgIGRlYnVnKFxuICAgICAgICAgICAgYFtzYW5kYm94OnNldHVwXSBzZXR1cCBhbHJlYWR5IGNvbXBsZXRlIGZvciBrZXkgXCIke3NldHVwLmtleX1cIiwgc2tpcHBpbmdgXG4gICAgICAgICAgKTtcbiAgICAgICAgICBuZWVkc1NldHVwUnVuID0gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgLy8gUmVzb2x2ZSBzZXR1cCBtZXRhZGF0YSBiZWZvcmUgcnVubmluZyBzZXR1cCBzbyB0aGUgd29ya2Zsb3dcbiAgICAgIC8vIGNhbiBlbWl0IHRoZSBjb3JyZWN0IHN0YXR1cyBpbmRpY2F0b3Igd2hpbGUgc2V0dXAgcnVucy5cbiAgICAgIHJlc29sdmVTZXR1cE1ldGEoe1xuICAgICAgICBuZWVkc1NldHVwUnVuLFxuICAgICAgICBjcmVhdGVkRnJvbVNuYXBzaG90OiBmYWxzZSxcbiAgICAgIH0pO1xuXG4gICAgICBpZiAobmVlZHNTZXR1cFJ1biAmJiBzZXR1cCkge1xuICAgICAgICBkZWJ1ZyhgW3NhbmRib3g6c2V0dXBdIHJ1bm5pbmcgc2V0dXAucnVuIChsb2NhbCwga2V5PVwiJHtzZXR1cC5rZXl9XCIpYCk7XG4gICAgICAgIGF3YWl0IHNldHVwLnJ1bihzYW5kYm94KTtcbiAgICAgICAgYXdhaXQgc3RvcmFnZS5zZXR1cC5zZXQoe1xuICAgICAgICAgIGtleTogc2V0dXAua2V5LFxuICAgICAgICAgIHNuYXBzaG90SWQ6IG51bGwsXG4gICAgICAgICAgY3JlYXRlZEF0OiBEYXRlLm5vdygpLFxuICAgICAgICAgIGxhc3RVc2VkQXQ6IG51bGwsXG4gICAgICAgICAgYWNxdWlyaW5nTG9ja0lkOiBudWxsLFxuICAgICAgICAgIGFjcXVpcmluZ0xvY2tBdDogbnVsbCxcbiAgICAgICAgfSk7XG4gICAgICAgIGRlYnVnKFxuICAgICAgICAgIGBbc2FuZGJveDpzZXR1cF0gc2V0dXAgY29tcGxldGUsIHN0b3JlZCByZWNvcmQgKGtleT1cIiR7c2V0dXAua2V5fVwiKWBcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICAgIGlmIChvblJlc3RhcnQpIHtcbiAgICAgICAgZGVidWcoXCJbc2FuZGJveDpzZXR1cF0gcnVubmluZyBvblJlc3RhcnQgKGxvY2FsKVwiKTtcbiAgICAgICAgYXdhaXQgb25SZXN0YXJ0KHNhbmRib3gpO1xuICAgICAgfVxuICAgIH0pKCk7XG4gIH1cblxuICByZXR1cm4gcmVzdWx0O1xufTtcbiIsICJpbXBvcnQgKiBhcyBwYXRoIGZyb20gXCJub2RlOnBhdGhcIjtcbmltcG9ydCB0eXBlIHsgVXBsb2FkYWJsZUZpbGUgfSBmcm9tIFwiLi4vc2tpbGxzL3R5cGVzXCI7XG5pbXBvcnQgdHlwZSB7IFNhbmRib3ggfSBmcm9tIFwiLi90eXBlc1wiO1xuXG5jb25zdCBNQVhfUkVUUklFUyA9IDI7XG5jb25zdCBSRVRSWV9CQVNFX01TID0gNTAwO1xuXG4vKipcbiAqIEV4ZWMgYSBjb21tYW5kIGFuZCBhc3NlcnQgZXhpdCBjb2RlIDAuIFJldHJpZXMgb24gdHJhbnNpZW50IGZhaWx1cmVzXG4gKiAoZXhpdCBjb2RlIDI1NSB3aXRoIGVtcHR5IHN0ZGVyciBcdTIwMTQgdHlwaWNhbGx5IGEgc2FuZGJveCBwcm9jZXNzIGtpbGxlZFxuICogYmVmb3JlIGl0IGNvdWxkIHByb2R1Y2Ugb3V0cHV0KS5cbiAqL1xuYXN5bmMgZnVuY3Rpb24gZXhlY0NoZWNrZWQoXG4gIHNhbmRib3g6IFBpY2s8U2FuZGJveCwgXCJleGVjXCI+LFxuICBvcHRzOiB7IGNvbW1hbmQ6IHN0cmluZzsgYXJncz86IHN0cmluZ1tdIH0sXG4gIGVycm9yTGFiZWw6IHN0cmluZ1xuKTogUHJvbWlzZTx7IHN0ZG91dDogc3RyaW5nOyBzdGRlcnI6IHN0cmluZzsgZXhpdENvZGU6IG51bWJlciB9PiB7XG4gIGZvciAobGV0IGF0dGVtcHQgPSAwOyA7IGF0dGVtcHQrKykge1xuICAgIGNvbnN0IGV4ZWNSZXN1bHQgPSBhd2FpdCBzYW5kYm94LmV4ZWMob3B0cyk7XG4gICAgaWYgKGV4ZWNSZXN1bHQgaW5zdGFuY2VvZiBFcnJvcikge1xuICAgICAgdGhyb3cgZXhlY1Jlc3VsdDtcbiAgICB9XG4gICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgZXhlY1Jlc3VsdC5yZXN1bHQ7XG4gICAgaWYgKHJlc3VsdC5leGl0Q29kZSA9PT0gMCkge1xuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG5cbiAgICBjb25zdCBpc1RyYW5zaWVudCA9IHJlc3VsdC5leGl0Q29kZSA9PT0gMjU1ICYmICFyZXN1bHQuc3RkZXJyLnRyaW0oKTtcbiAgICBpZiAoaXNUcmFuc2llbnQgJiYgYXR0ZW1wdCA8IE1BWF9SRVRSSUVTKSB7XG4gICAgICBhd2FpdCBuZXcgUHJvbWlzZSgocikgPT4gc2V0VGltZW91dChyLCBSRVRSWV9CQVNFX01TICogKGF0dGVtcHQgKyAxKSkpO1xuICAgICAgY29udGludWU7XG4gICAgfVxuXG4gICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgYCR7ZXJyb3JMYWJlbH0gd2l0aCBleGl0IGNvZGUgJHtyZXN1bHQuZXhpdENvZGV9OiAke3Jlc3VsdC5zdGRlcnJ9YFxuICAgICk7XG4gIH1cbn1cblxuLyoqXG4gKiBXcml0ZXMgZmlsZXMgdG8gYSBzYW5kYm94IGF0IHRoZSBzcGVjaWZpZWQgZGVzdGluYXRpb24gcGF0aC5cbiAqIFNoZWxsIHNjcmlwdHMgKC5zaCBmaWxlcykgYXJlIGF1dG9tYXRpY2FsbHkgbWFkZSBleGVjdXRhYmxlLlxuICpcbiAqIEZvciBzbWFsbCBmaWxlcyAoPDEwMEtCIHRvdGFsKSwgdXNlcyBzaW5nbGUgZXhlYyB3aXRoIGhlcmVkb2MuXG4gKiBGb3IgbGFyZ2UgZmlsZXMsIHdyaXRlcyBiYXNlNjQgY2h1bmtzIHRoZW4gZGVjb2RlcyB0byBhdm9pZCBBUkdfTUFYIGxpbWl0cy5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHdyaXRlRmlsZXMob3B0czoge1xuICBzYW5kYm94OiBQaWNrPFNhbmRib3gsIFwiZXhlY1wiPjtcbiAgZmlsZXM6IFVwbG9hZGFibGVGaWxlW107XG4gIGRlc3RQYXRoOiBzdHJpbmc7XG59KTogUHJvbWlzZTx2b2lkPiB7XG4gIGNvbnN0IHsgc2FuZGJveCwgZmlsZXMsIGRlc3RQYXRoIH0gPSBvcHRzO1xuXG4gIGlmIChmaWxlcy5sZW5ndGggPT09IDApIHtcbiAgICByZXR1cm47XG4gIH1cblxuICBjb25zdCBmaWxlUGF0aHMgPSBmaWxlcy5tYXAoKGZpbGUpID0+IHBhdGgucG9zaXguam9pbihkZXN0UGF0aCwgZmlsZS5wYXRoKSk7XG4gIGNvbnN0IHBhcmVudERpcnMgPSBBcnJheS5mcm9tKFxuICAgIG5ldyBTZXQoZmlsZVBhdGhzLm1hcCgocCkgPT4gcGF0aC5wb3NpeC5kaXJuYW1lKHApKSlcbiAgKTtcbiAgY29uc3Qgc2hlbGxTY3JpcHRzID0gZmlsZVBhdGhzLmZpbHRlcigocCkgPT4gcC5lbmRzV2l0aChcIi5zaFwiKSk7XG5cbiAgY29uc3QgbWtkaXJSZXN1bHQgPSBhd2FpdCBzYW5kYm94LmV4ZWMoe1xuICAgIGNvbW1hbmQ6IFwibWtkaXJcIixcbiAgICBhcmdzOiBbXCItcFwiLCAuLi5wYXJlbnREaXJzXSxcbiAgfSk7XG4gIGlmIChta2RpclJlc3VsdCBpbnN0YW5jZW9mIEVycm9yKSB7XG4gICAgdGhyb3cgbWtkaXJSZXN1bHQ7XG4gIH1cbiAgYXdhaXQgbWtkaXJSZXN1bHQucmVzdWx0O1xuXG4gIGNvbnN0IENIVU5LX1NJWkUgPSA1MF8wMDA7XG5cbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBmaWxlcy5sZW5ndGg7IGkrKykge1xuICAgIGNvbnN0IGZpbGUgPSBmaWxlc1tpXTtcbiAgICBjb25zdCBmdWxsUGF0aCA9IGZpbGVQYXRoc1tpXTtcbiAgICBjb25zdCBiYXNlNjRDb250ZW50ID0gdG9CYXNlNjQoZmlsZS5jb250ZW50KTtcblxuICAgIGlmIChiYXNlNjRDb250ZW50Lmxlbmd0aCA8IENIVU5LX1NJWkUpIHtcbiAgICAgIGNvbnN0IG1hcmtlciA9IGBFT0ZfJHtpfWA7XG4gICAgICBhd2FpdCBleGVjQ2hlY2tlZChcbiAgICAgICAgc2FuZGJveCxcbiAgICAgICAge1xuICAgICAgICAgIGNvbW1hbmQ6IFwiYmFzaFwiLFxuICAgICAgICAgIGFyZ3M6IFtcbiAgICAgICAgICAgIFwiLWNcIixcbiAgICAgICAgICAgIGBiYXNlNjQgLWQgPiAke3F1b3RlKGZ1bGxQYXRoKX0gPDwgJyR7bWFya2VyfSdcbiR7YmFzZTY0Q29udGVudH1cbiR7bWFya2VyfWAsXG4gICAgICAgICAgXSxcbiAgICAgICAgfSxcbiAgICAgICAgXCJ3cml0ZUZpbGVzIGZhaWxlZFwiXG4gICAgICApO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb25zdCB0ZW1wQjY0ID0gYC90bXAvY2h1bmstJHtEYXRlLm5vdygpfS0ke2l9LmI2NGA7XG5cbiAgICAgIGNvbnN0IGNsZWFyUmVzdWx0ID0gYXdhaXQgc2FuZGJveC5leGVjKHtcbiAgICAgICAgY29tbWFuZDogXCJiYXNoXCIsXG4gICAgICAgIGFyZ3M6IFtcIi1jXCIsIGA+ICR7cXVvdGUodGVtcEI2NCl9YF0sXG4gICAgICB9KTtcbiAgICAgIGlmIChjbGVhclJlc3VsdCBpbnN0YW5jZW9mIEVycm9yKSB7XG4gICAgICAgIHRocm93IGNsZWFyUmVzdWx0O1xuICAgICAgfVxuICAgICAgYXdhaXQgY2xlYXJSZXN1bHQucmVzdWx0O1xuXG4gICAgICBmb3IgKFxuICAgICAgICBsZXQgb2Zmc2V0ID0gMDtcbiAgICAgICAgb2Zmc2V0IDwgYmFzZTY0Q29udGVudC5sZW5ndGg7XG4gICAgICAgIG9mZnNldCArPSBDSFVOS19TSVpFXG4gICAgICApIHtcbiAgICAgICAgY29uc3QgY2h1bmsgPSBiYXNlNjRDb250ZW50LnNsaWNlKG9mZnNldCwgb2Zmc2V0ICsgQ0hVTktfU0laRSk7XG4gICAgICAgIGNvbnN0IG1hcmtlciA9IGBDSFVOS18ke29mZnNldH1gO1xuICAgICAgICBhd2FpdCBleGVjQ2hlY2tlZChcbiAgICAgICAgICBzYW5kYm94LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIGNvbW1hbmQ6IFwiYmFzaFwiLFxuICAgICAgICAgICAgYXJnczogW1xuICAgICAgICAgICAgICBcIi1jXCIsXG4gICAgICAgICAgICAgIGBjYXQgPj4gJHtxdW90ZSh0ZW1wQjY0KX0gPDwgJyR7bWFya2VyfSdcbiR7Y2h1bmt9XG4ke21hcmtlcn1gLFxuICAgICAgICAgICAgXSxcbiAgICAgICAgICB9LFxuICAgICAgICAgIFwid3JpdGVGaWxlcyBjaHVuayBmYWlsZWRcIlxuICAgICAgICApO1xuICAgICAgfVxuXG4gICAgICBhd2FpdCBleGVjQ2hlY2tlZChcbiAgICAgICAgc2FuZGJveCxcbiAgICAgICAge1xuICAgICAgICAgIGNvbW1hbmQ6IFwiYmFzaFwiLFxuICAgICAgICAgIGFyZ3M6IFtcbiAgICAgICAgICAgIFwiLWNcIixcbiAgICAgICAgICAgIGBiYXNlNjQgLWQgPCAke3F1b3RlKHRlbXBCNjQpfSA+ICR7cXVvdGUoZnVsbFBhdGgpfSAmJiBybSAtZiAke3F1b3RlKHRlbXBCNjQpfWAsXG4gICAgICAgICAgXSxcbiAgICAgICAgfSxcbiAgICAgICAgXCJ3cml0ZUZpbGVzIGRlY29kZSBmYWlsZWRcIlxuICAgICAgKTtcbiAgICB9XG4gIH1cblxuICBpZiAoc2hlbGxTY3JpcHRzLmxlbmd0aCA+IDApIHtcbiAgICBjb25zdCBjaG1vZFJlc3VsdCA9IGF3YWl0IHNhbmRib3guZXhlYyh7XG4gICAgICBjb21tYW5kOiBcImNobW9kXCIsXG4gICAgICBhcmdzOiBbXCIreFwiLCAuLi5zaGVsbFNjcmlwdHNdLFxuICAgIH0pO1xuICAgIGlmIChjaG1vZFJlc3VsdCBpbnN0YW5jZW9mIEVycm9yKSB7XG4gICAgICB0aHJvdyBjaG1vZFJlc3VsdDtcbiAgICB9XG4gICAgYXdhaXQgY2htb2RSZXN1bHQucmVzdWx0O1xuICB9XG59XG5cbmZ1bmN0aW9uIHRvQmFzZTY0KGNvbnRlbnQ6IHN0cmluZyB8IEJ1ZmZlcik6IHN0cmluZyB7XG4gIGlmICh0eXBlb2YgY29udGVudCA9PT0gXCJzdHJpbmdcIikge1xuICAgIHJldHVybiBCdWZmZXIuZnJvbShjb250ZW50KS50b1N0cmluZyhcImJhc2U2NFwiKTtcbiAgfVxuICByZXR1cm4gY29udGVudC50b1N0cmluZyhcImJhc2U2NFwiKTtcbn1cblxuZnVuY3Rpb24gcXVvdGUoczogc3RyaW5nKTogc3RyaW5nIHtcbiAgcmV0dXJuIGAnJHtzLnJlcGxhY2UoLycvZywgXCInXFxcXCcnXCIpfSdgO1xufVxuIiwgImltcG9ydCAqIGFzIHBhdGggZnJvbSBcIm5vZGU6cGF0aFwiO1xuaW1wb3J0IHsgU2FuZGJveCBhcyBWZXJjZWxTYW5kYm94U0RLIH0gZnJvbSBcIkB2ZXJjZWwvc2FuZGJveFwiO1xuaW1wb3J0ICogYXMgZXJyb3JlIGZyb20gXCJlcnJvcmVcIjtcbmltcG9ydCB7IHN0YXJ0IH0gZnJvbSBcIndvcmtmbG93L2FwaVwiO1xuaW1wb3J0IHsgU2FuZGJveEVycm9yLCBTYW5kYm94Tm90Rm91bmRFcnJvciB9IGZyb20gXCIuLi8uLi9lcnJvcnNcIjtcbmltcG9ydCB0eXBlIHsgVGFnc1NjaGVtYSB9IGZyb20gXCIuLi8uLi9pbmRleFwiO1xuaW1wb3J0IHR5cGUge1xuICBScGNGbixcbiAgU2FuZGJveFJlY29yZCxcbiAgU3RvcmFnZSxcbiAgU3RvcmFnZUNvbmZpZyxcbn0gZnJvbSBcIi4uLy4uL3N0b3JhZ2VcIjtcbmltcG9ydCB7IGRlYnVnIH0gZnJvbSBcIi4uLy4uL3V0aWxzL2RlYnVnXCI7XG5pbXBvcnQgdHlwZSB7IFNhbmRib3hTZXR1cE1ldGEgfSBmcm9tIFwiLi4vY2xpZW50XCI7XG5pbXBvcnQgdHlwZSB7XG4gIExvZ0VudHJ5LFxuICBPblJlc3RhcnQsXG4gIFNhbmRib3gsXG4gIFNhbmRib3hMaWZlY3ljbGUsXG4gIFNhbmRib3hMaWZlY3ljbGVJbnB1dCxcbiAgU2FuZGJveFNldHVwLFxuICBTYW5kYm94U3RhdHVzLFxufSBmcm9tIFwiLi4vdHlwZXNcIjtcbmltcG9ydCB7IHNhbmRib3hMaWZlY3ljbGVXb3JrZmxvdyB9IGZyb20gXCIuL2xpZmVjeWNsZS13b3JrZmxvd1wiO1xuXG5leHBvcnQgdHlwZSBWZXJjZWxTYW5kYm94Q3JlYXRlT3B0aW9ucyA9IEV4dHJhY3Q8XG4gIFBhcmFtZXRlcnM8dHlwZW9mIFZlcmNlbFNhbmRib3hTREsuY3JlYXRlPlswXSxcbiAgLy8gYmlvbWUtaWdub3JlIGxpbnQvY29tcGxleGl0eS9ub0Jhbm5lZFR5cGVzOiAuXG4gIHt9XG4+O1xuXG5leHBvcnQgY29uc3QgVkVSQ0VMX01BWF9USU1FT1VUX01TID0gNSAqIDYwICogNjAgKiAxMDAwOyAvLyA1IGhvdXJzXG5jb25zdCBMT0NLX1RJTUVPVVRfTVMgPSA1ICogNjAgKiAxMDAwOyAvLyA1IG1pbnV0ZXMgLSBpZiBsb2NrIG9sZGVyIHRoYW4gdGhpcywgY29uc2lkZXIgaXQgc3RhbGVcbmNvbnN0IExPQ0tfUE9MTF9JTlRFUlZBTF9NUyA9IDIwMDtcblxuY29uc3QgZ2V0VGVzdENyZWRlbnRpYWxzID0gKCkgPT5cbiAgcHJvY2Vzcy5lbnYuTk9ERV9FTlYgPT09IFwidGVzdFwiXG4gICAgPyB7XG4gICAgICAgIHRva2VuOiBwcm9jZXNzLmVudi5URVNUX1ZFUkNFTF9UT0tFTixcbiAgICAgICAgdGVhbUlkOiBwcm9jZXNzLmVudi5URVNUX1ZFUkNFTF9URUFNX0lELFxuICAgICAgICBwcm9qZWN0SWQ6IHByb2Nlc3MuZW52LlRFU1RfVkVSQ0VMX1BST0pFQ1RfSUQsXG4gICAgICB9XG4gICAgOiB7fTtcblxuLyoqXG4gKiBNb2R1bGUtbGV2ZWwgY2FjaGUgZm9yIGluLWZsaWdodCBzYW5kYm94IGNyZWF0aW9uIHByb21pc2VzLlxuICogUHJldmVudHMgcGFyYWxsZWwgcmVxdWVzdHMgd2l0aGluIHRoZSBzYW1lIHByb2Nlc3MgZnJvbSBjcmVhdGluZyBkdXBsaWNhdGUgc2FuZGJveGVzLlxuICovXG5jb25zdCBjcmVhdGVQcm9taXNlcyA9IG5ldyBNYXA8c3RyaW5nLCBQcm9taXNlPFNhbmRib3hFcnJvciB8IHN0cmluZz4+KCk7XG5cbmNvbnN0IEFDVElWSVRZX1RIUk9UVExFX01TID0gMTBfMDAwO1xuY29uc3QgbGFzdEFjdGl2aXR5U2VudCA9IG5ldyBNYXA8c3RyaW5nLCBudW1iZXI+KCk7XG5cbmNvbnN0IERFRkFVTFRfVkNQVVMgPSAyO1xuXG5mdW5jdGlvbiBpc1NhbmRib3hHb25lRXJyb3IoZTogdW5rbm93bik6IGJvb2xlYW4ge1xuICBpZiAoIShlIGluc3RhbmNlb2YgRXJyb3IpKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgY29uc3QgZXJyb3JXaXRoUmVzcG9uc2UgPSBlIGFzIHsgcmVzcG9uc2U/OiB7IHN0YXR1cz86IG51bWJlciB9IH07XG4gIGNvbnN0IGVycm9yV2l0aENhdXNlID0gZSBhcyB7IGNhdXNlPzogeyByZXNwb25zZT86IHsgc3RhdHVzPzogbnVtYmVyIH0gfSB9O1xuXG4gIGNvbnN0IHN0YXR1cyA9XG4gICAgZXJyb3JXaXRoUmVzcG9uc2UucmVzcG9uc2U/LnN0YXR1cyA/P1xuICAgIGVycm9yV2l0aENhdXNlLmNhdXNlPy5yZXNwb25zZT8uc3RhdHVzO1xuXG4gIGlmIChzdGF0dXMgPT09IDQxMCB8fCBzdGF0dXMgPT09IDQyMikge1xuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgY29uc3QgbWVzc2FnZSA9IGUubWVzc2FnZSB8fCBTdHJpbmcoZSk7XG4gIGlmIChcbiAgICBtZXNzYWdlLmluY2x1ZGVzKFwiRXhwZWN0ZWQgYSBzdHJlYW0gb2YgY29tbWFuZCBkYXRhXCIpIHx8XG4gICAgbWVzc2FnZS5pbmNsdWRlcyhcIkV4cGVjdGVkIGEgc3RyZWFtIG9mIGxvZ3NcIilcbiAgKSB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICByZXR1cm4gZmFsc2U7XG59XG5cbmV4cG9ydCBjb25zdCB2ZXJjZWxTYW5kYm94ID0gPFRUYWdzIGV4dGVuZHMgVGFnc1NjaGVtYSA9IFRhZ3NTY2hlbWE+KHtcbiAgc2FuZGJveFJlY29yZCxcbiAgc3RvcmFnZUNvbmZpZyxcbiAgZW5hYmxlTGlmZWN5Y2xlV29ya2Zsb3csXG4gIHN0b3JhZ2UsXG4gIHJwYyxcbiAgc2V0dXAsXG4gIG9uUmVzdGFydCxcbn06IHtcbiAgc2FuZGJveFJlY29yZDogU2FuZGJveFJlY29yZCAmIHsgY29uZmlnOiB7IHR5cGU6IFwidmVyY2VsXCIgfSB9O1xuICBzdG9yYWdlQ29uZmlnOiBTdG9yYWdlQ29uZmlnO1xuICBlbmFibGVMaWZlY3ljbGVXb3JrZmxvdzogYm9vbGVhbjtcbiAgc3RvcmFnZTogU3RvcmFnZTtcbiAgcnBjOiBScGNGbjtcbiAgc2V0dXA/OiBTYW5kYm94U2V0dXA7XG4gIG9uUmVzdGFydD86IE9uUmVzdGFydDtcbn0pOiBTYW5kYm94PFRUYWdzPiAmIHtcbiAgX29uUmVhZHk/OiBQcm9taXNlPHZvaWQ+O1xuICBfc2V0dXBNZXRhPzogUHJvbWlzZTxTYW5kYm94U2V0dXBNZXRhPjtcbn0gPT4ge1xuICBjb25zdCB7IGlkLCBjb25maWcgfSA9IHNhbmRib3hSZWNvcmQ7XG4gIGNvbnN0IHZjcHVzID0gY29uZmlnLnJlc291cmNlcz8udmNwdXMgPz8gREVGQVVMVF9WQ1BVUztcbiAgY29uc3QgcG9ydHMgPSBjb25maWcucG9ydHM7XG4gIGNvbnN0IG5ldHdvcmtQb2xpY3kgPSBjb25maWcubmV0d29ya1BvbGljeTtcbiAgY29uc3QgaW5pdGlhbFZlcmNlbCA9XG4gICAgc2FuZGJveFJlY29yZC5wcm92aWRlck1ldGFkYXRhPy5wcm92aWRlciA9PT0gXCJ2ZXJjZWxcIlxuICAgICAgPyBzYW5kYm94UmVjb3JkLnByb3ZpZGVyTWV0YWRhdGFcbiAgICAgIDogbnVsbDtcblxuICB0eXBlIFNhbmRib3hJbnN0YW5jZSA9IEF3YWl0ZWQ8UmV0dXJuVHlwZTx0eXBlb2YgVmVyY2VsU2FuZGJveFNESy5nZXQ+PjtcbiAgbGV0IHNhbmRib3hQcm9taXNlOiBQcm9taXNlPFNhbmRib3hFcnJvciB8IFNhbmRib3hJbnN0YW5jZT4gfCBudWxsID0gbnVsbDtcbiAgbGV0IHJlY292ZXJlZEZyb21TdGFsZSA9IGZhbHNlO1xuICBsZXQgY3JlYXRlZEZyb21TbmFwc2hvdCA9IGZhbHNlO1xuICBsZXQgbmVlZHNTZXR1cFJ1biA9IGZhbHNlO1xuICBjb25zdCBIT01FX0RJUiA9IFwiL2hvbWUvdmVyY2VsLXNhbmRib3hcIjtcblxuICBhc3luYyBmdW5jdGlvbiBwb2xsRm9yU2FuZGJveElkKCk6IFByb21pc2U8U2FuZGJveEVycm9yIHwgc3RyaW5nPiB7XG4gICAgY29uc3QgZGVhZGxpbmUgPSBEYXRlLm5vdygpICsgTE9DS19USU1FT1VUX01TO1xuICAgIHdoaWxlIChEYXRlLm5vdygpIDwgZGVhZGxpbmUpIHtcbiAgICAgIGF3YWl0IG5ldyBQcm9taXNlKChyKSA9PiBzZXRUaW1lb3V0KHIsIExPQ0tfUE9MTF9JTlRFUlZBTF9NUykpO1xuICAgICAgY29uc3QgcmVjb3JkID0gYXdhaXQgc3RvcmFnZS5zYW5kYm94LmdldChpZCk7XG4gICAgICBpZiAocmVjb3JkIGluc3RhbmNlb2YgRXJyb3IpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBTYW5kYm94RXJyb3IoeyByZWFzb246IHJlY29yZC5tZXNzYWdlLCBjYXVzZTogcmVjb3JkIH0pO1xuICAgICAgfVxuICAgICAgY29uc3QgdmVyY2VsU2FuZGJveElkID1cbiAgICAgICAgcmVjb3JkPy5wcm92aWRlck1ldGFkYXRhPy5wcm92aWRlciA9PT0gXCJ2ZXJjZWxcIlxuICAgICAgICAgID8gcmVjb3JkLnByb3ZpZGVyTWV0YWRhdGEuc2FuZGJveElkXG4gICAgICAgICAgOiBudWxsO1xuICAgICAgaWYgKHZlcmNlbFNhbmRib3hJZCkge1xuICAgICAgICByZXR1cm4gdmVyY2VsU2FuZGJveElkO1xuICAgICAgfVxuICAgICAgaWYgKCFyZWNvcmQ/LmFjcXVpcmluZ0xvY2tBdCkge1xuICAgICAgICBjb25zdCBmaW5hbENoZWNrID0gYXdhaXQgc3RvcmFnZS5zYW5kYm94LmdldChpZCk7XG4gICAgICAgIGlmIChmaW5hbENoZWNrIGluc3RhbmNlb2YgRXJyb3IpIHtcbiAgICAgICAgICByZXR1cm4gbmV3IFNhbmRib3hFcnJvcih7XG4gICAgICAgICAgICByZWFzb246IGZpbmFsQ2hlY2subWVzc2FnZSxcbiAgICAgICAgICAgIGNhdXNlOiBmaW5hbENoZWNrLFxuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGZpbmFsVmVyY2VsU2FuZGJveElkID1cbiAgICAgICAgICBmaW5hbENoZWNrPy5wcm92aWRlck1ldGFkYXRhPy5wcm92aWRlciA9PT0gXCJ2ZXJjZWxcIlxuICAgICAgICAgICAgPyBmaW5hbENoZWNrLnByb3ZpZGVyTWV0YWRhdGEuc2FuZGJveElkXG4gICAgICAgICAgICA6IG51bGw7XG4gICAgICAgIGlmIChmaW5hbFZlcmNlbFNhbmRib3hJZCkge1xuICAgICAgICAgIHJldHVybiBmaW5hbFZlcmNlbFNhbmRib3hJZDtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZG9HZXRPckNyZWF0ZVNhbmRib3hJZCgpO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gbmV3IFNhbmRib3hFcnJvcih7XG4gICAgICByZWFzb246IFwiVGltZWQgb3V0IHdhaXRpbmcgZm9yIHNhbmRib3ggY3JlYXRpb24gYnkgYW5vdGhlciBwcm9jZXNzXCIsXG4gICAgfSk7XG4gIH1cblxuICBhc3luYyBmdW5jdGlvbiBzdGFydExpZmVjeWNsZVdvcmtmbG93KFxuICAgIHZlcmNlbFNhbmRib3hJZDogc3RyaW5nXG4gICk6IFByb21pc2U8dm9pZD4ge1xuICAgIGlmICghZW5hYmxlTGlmZWN5Y2xlV29ya2Zsb3cpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3QgbGlmZWN5Y2xlSW5wdXQ6IFNhbmRib3hMaWZlY3ljbGVJbnB1dCA9IHtcbiAgICAgIGlkLFxuICAgICAgdmVyY2VsU2FuZGJveElkLFxuICAgICAgc3RvcmFnZUNvbmZpZyxcbiAgICAgIHJwYyxcbiAgICB9O1xuICAgIGF3YWl0IHN0YXJ0KHNhbmRib3hMaWZlY3ljbGVXb3JrZmxvdywgW3sgaW5wdXQ6IGxpZmVjeWNsZUlucHV0IH1dKS5jYXRjaChcbiAgICAgIC8vIGJpb21lLWlnbm9yZSBsaW50L3N1c3BpY2lvdXMvbm9FbXB0eUJsb2NrU3RhdGVtZW50czogaW50ZW50aW9uYWxseSBpZ25vcmVkIC0gd29ya2Zsb3cgc3RhcnQgaXMgZmlyZS1hbmQtZm9yZ2V0XG4gICAgICAoKSA9PiB7fVxuICAgICk7XG4gIH1cblxuICBhc3luYyBmdW5jdGlvbiBjcmVhdGVTYW5kYm94RnJvbVNuYXBzaG90KFxuICAgIHNuYXBzaG90SWQ6IHN0cmluZ1xuICApOiBQcm9taXNlPFNhbmRib3hFcnJvciB8IHN0cmluZz4ge1xuICAgIHJldHVybiBhd2FpdCBlcnJvcmUudHJ5QXN5bmMoe1xuICAgICAgdHJ5OiBhc3luYyAoKSA9PiB7XG4gICAgICAgIGNvbnN0IHNhbmRib3ggPSBhd2FpdCBWZXJjZWxTYW5kYm94U0RLLmNyZWF0ZSh7XG4gICAgICAgICAgc291cmNlOiB7IHR5cGU6IFwic25hcHNob3RcIiwgc25hcHNob3RJZCB9LFxuICAgICAgICAgIHJlc291cmNlczogeyB2Y3B1cyB9LFxuICAgICAgICAgIHRpbWVvdXQ6IFZFUkNFTF9NQVhfVElNRU9VVF9NUyxcbiAgICAgICAgICBwb3J0cyxcbiAgICAgICAgICBuZXR3b3JrUG9saWN5LFxuICAgICAgICAgIC4uLmdldFRlc3RDcmVkZW50aWFscygpLFxuICAgICAgICB9KTtcbiAgICAgICAgY29uc3Qgbm93ID0gRGF0ZS5ub3coKTtcbiAgICAgICAgYXdhaXQgc3RvcmFnZS5zYW5kYm94LnNldCh7XG4gICAgICAgICAgaWQsXG4gICAgICAgICAgY29uZmlnLFxuICAgICAgICAgIHRhZ3M6IHNhbmRib3hSZWNvcmQudGFncyxcbiAgICAgICAgICBjcmVhdGVkQXQ6IG5vdyxcbiAgICAgICAgICBsYXN0QWN0aXZpdHlBdDogbm93LFxuICAgICAgICAgIGFjcXVpcmluZ0xvY2tJZDogbnVsbCxcbiAgICAgICAgICBhY3F1aXJpbmdMb2NrQXQ6IG51bGwsXG4gICAgICAgICAgcHJvdmlkZXJNZXRhZGF0YToge1xuICAgICAgICAgICAgcHJvdmlkZXI6IFwidmVyY2VsXCIsXG4gICAgICAgICAgICBzYW5kYm94SWQ6IHNhbmRib3guc2FuZGJveElkLFxuICAgICAgICAgICAgc25hcHNob3RJZCxcbiAgICAgICAgICB9LFxuICAgICAgICB9KTtcbiAgICAgICAgYXdhaXQgc3RhcnRMaWZlY3ljbGVXb3JrZmxvdyhzYW5kYm94LnNhbmRib3hJZCk7XG4gICAgICAgIHJldHVybiBzYW5kYm94LnNhbmRib3hJZDtcbiAgICAgIH0sXG4gICAgICBjYXRjaDogKGUpID0+IG5ldyBTYW5kYm94RXJyb3IoeyByZWFzb246IFN0cmluZyhlKSwgY2F1c2U6IGUgfSksXG4gICAgfSk7XG4gIH1cblxuICBhc3luYyBmdW5jdGlvbiBjcmVhdGVGcmVzaFNhbmRib3goKTogUHJvbWlzZTxTYW5kYm94RXJyb3IgfCBzdHJpbmc+IHtcbiAgICByZXR1cm4gYXdhaXQgZXJyb3JlLnRyeUFzeW5jKHtcbiAgICAgIHRyeTogYXN5bmMgKCkgPT4ge1xuICAgICAgICBjb25zdCBzYW5kYm94ID0gYXdhaXQgVmVyY2VsU2FuZGJveFNESy5jcmVhdGUoe1xuICAgICAgICAgIHJlc291cmNlczogeyB2Y3B1cyB9LFxuICAgICAgICAgIHRpbWVvdXQ6IFZFUkNFTF9NQVhfVElNRU9VVF9NUyxcbiAgICAgICAgICBwb3J0cyxcbiAgICAgICAgICBuZXR3b3JrUG9saWN5LFxuICAgICAgICAgIC4uLmdldFRlc3RDcmVkZW50aWFscygpLFxuICAgICAgICB9KTtcbiAgICAgICAgY29uc3Qgbm93ID0gRGF0ZS5ub3coKTtcbiAgICAgICAgYXdhaXQgc3RvcmFnZS5zYW5kYm94LnNldCh7XG4gICAgICAgICAgaWQsXG4gICAgICAgICAgY29uZmlnLFxuICAgICAgICAgIHRhZ3M6IHNhbmRib3hSZWNvcmQudGFncyxcbiAgICAgICAgICBjcmVhdGVkQXQ6IG5vdyxcbiAgICAgICAgICBsYXN0QWN0aXZpdHlBdDogbm93LFxuICAgICAgICAgIGFjcXVpcmluZ0xvY2tJZDogbnVsbCxcbiAgICAgICAgICBhY3F1aXJpbmdMb2NrQXQ6IG51bGwsXG4gICAgICAgICAgcHJvdmlkZXJNZXRhZGF0YToge1xuICAgICAgICAgICAgcHJvdmlkZXI6IFwidmVyY2VsXCIsXG4gICAgICAgICAgICBzYW5kYm94SWQ6IHNhbmRib3guc2FuZGJveElkLFxuICAgICAgICAgICAgc25hcHNob3RJZDogbnVsbCxcbiAgICAgICAgICB9LFxuICAgICAgICB9KTtcbiAgICAgICAgYXdhaXQgc3RhcnRMaWZlY3ljbGVXb3JrZmxvdyhzYW5kYm94LnNhbmRib3hJZCk7XG4gICAgICAgIHJldHVybiBzYW5kYm94LnNhbmRib3hJZDtcbiAgICAgIH0sXG4gICAgICBjYXRjaDogKGUpID0+IG5ldyBTYW5kYm94RXJyb3IoeyByZWFzb246IFN0cmluZyhlKSwgY2F1c2U6IGUgfSksXG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogQ29yZSBleGVjIGxvZ2ljIGFnYWluc3QgYSByYXcgVmVyY2VsIFNESyBpbnN0YW5jZS5cbiAgICogU2hhcmVkIGJldHdlZW4gdGhlIG1haW4gc2FuZGJveCB3cmFwcGVyIGFuZCB0ZW1wb3Jhcnkgc2V0dXAgc2FuZGJveGVzLlxuICAgKi9cbiAgZnVuY3Rpb24gZXhlY09uSW5zdGFuY2UoXG4gICAgaW5zdGFuY2U6IFNhbmRib3hJbnN0YW5jZSxcbiAgICB7XG4gICAgICBjb21tYW5kLFxuICAgICAgYXJncyxcbiAgICAgIHNpZ25hbCxcbiAgICB9OiB7IGNvbW1hbmQ6IHN0cmluZzsgYXJncz86IHN0cmluZ1tdOyBzaWduYWw/OiBBYm9ydFNpZ25hbCB9XG4gICk6IFByb21pc2U8XG4gICAgfCBTYW5kYm94RXJyb3JcbiAgICB8IHtcbiAgICAgICAgY29tbWFuZElkOiBzdHJpbmc7XG4gICAgICAgIGxvZ3M6ICgpID0+IEFzeW5jSXRlcmFibGU8TG9nRW50cnk+O1xuICAgICAgICByZXN1bHQ6IFByb21pc2U8eyBzdGRvdXQ6IHN0cmluZzsgc3RkZXJyOiBzdHJpbmc7IGV4aXRDb2RlOiBudW1iZXIgfT47XG4gICAgICB9XG4gID4ge1xuICAgIHJldHVybiBlcnJvcmUudHJ5QXN5bmMoe1xuICAgICAgdHJ5OiBhc3luYyAoKSA9PiB7XG4gICAgICAgIGNvbnN0IG91dHB1dCA9IGF3YWl0IGluc3RhbmNlLnJ1bkNvbW1hbmQoe1xuICAgICAgICAgIGN3ZDogSE9NRV9ESVIsXG4gICAgICAgICAgYXJncyxcbiAgICAgICAgICBjbWQ6IGNvbW1hbmQsXG4gICAgICAgICAgc2lnbmFsLFxuICAgICAgICAgIGRldGFjaGVkOiB0cnVlLFxuICAgICAgICB9KTtcblxuICAgICAgICBsZXQgc3Rkb3V0ID0gXCJcIjtcbiAgICAgICAgbGV0IHN0ZGVyciA9IFwiXCI7XG4gICAgICAgIGNvbnN0IGxvZ0J1ZmZlcjogTG9nRW50cnlbXSA9IFtdO1xuICAgICAgICBjb25zdCBzdGF0ZSA9IHtcbiAgICAgICAgICByZXNvbHZlOiBudWxsIGFzICgoKSA9PiB2b2lkKSB8IG51bGwsXG4gICAgICAgICAgY29uc3VtZWQ6IGZhbHNlLFxuICAgICAgICB9O1xuXG4gICAgICAgIGNvbnN0IGNvbnN1bWVMb2dzID0gKGFzeW5jICgpID0+IHtcbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgZm9yIGF3YWl0IChjb25zdCBsb2cgb2Ygb3V0cHV0LmxvZ3MoKSkge1xuICAgICAgICAgICAgICBjb25zdCBlbnRyeTogTG9nRW50cnkgPVxuICAgICAgICAgICAgICAgIGxvZy5zdHJlYW0gPT09IFwic3Rkb3V0XCJcbiAgICAgICAgICAgICAgICAgID8geyBzdHJlYW06IFwic3Rkb3V0XCIsIGRhdGE6IGxvZy5kYXRhIH1cbiAgICAgICAgICAgICAgICAgIDogeyBzdHJlYW06IFwic3RkZXJyXCIsIGRhdGE6IGxvZy5kYXRhIH07XG5cbiAgICAgICAgICAgICAgaWYgKGxvZy5zdHJlYW0gPT09IFwic3Rkb3V0XCIpIHtcbiAgICAgICAgICAgICAgICBzdGRvdXQgKz0gbG9nLmRhdGE7XG4gICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgc3RkZXJyICs9IGxvZy5kYXRhO1xuICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgbG9nQnVmZmVyLnB1c2goZW50cnkpO1xuICAgICAgICAgICAgICBzdGF0ZS5yZXNvbHZlPy4oKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGNhdGNoIHtcbiAgICAgICAgICAgIC8vIFNhbmRib3ggbWF5IGhhdmUgYmVlbiBzdG9wcGVkIC0gbG9ncyBlbmRwb2ludCByZXR1cm5zIDQyMlxuICAgICAgICAgIH1cbiAgICAgICAgICBzdGF0ZS5jb25zdW1lZCA9IHRydWU7XG4gICAgICAgICAgc3RhdGUucmVzb2x2ZT8uKCk7XG4gICAgICAgIH0pKCk7XG5cbiAgICAgICAgYXN5bmMgZnVuY3Rpb24qIGxvZ3MoKTogQXN5bmNJdGVyYWJsZTxMb2dFbnRyeT4ge1xuICAgICAgICAgIGxldCBpbmRleCA9IDA7XG4gICAgICAgICAgd2hpbGUgKCFzdGF0ZS5jb25zdW1lZCB8fCBpbmRleCA8IGxvZ0J1ZmZlci5sZW5ndGgpIHtcbiAgICAgICAgICAgIGlmIChpbmRleCA8IGxvZ0J1ZmZlci5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgeWllbGQgbG9nQnVmZmVyW2luZGV4KytdO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgYXdhaXQgbmV3IFByb21pc2U8dm9pZD4oKHJlc29sdmUpID0+IHtcbiAgICAgICAgICAgICAgICBzdGF0ZS5yZXNvbHZlID0gcmVzb2x2ZTtcbiAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgIHN0YXRlLnJlc29sdmUgPSBudWxsO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IGNvbnN1bWVMb2dzLnRoZW4oYXN5bmMgKCkgPT4ge1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICBjb25zdCBmaW5pc2hlZCA9IGF3YWl0IG91dHB1dC53YWl0KCk7XG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICBzdGRvdXQsXG4gICAgICAgICAgICAgIHN0ZGVycixcbiAgICAgICAgICAgICAgZXhpdENvZGU6IGZpbmlzaGVkLmV4aXRDb2RlLFxuICAgICAgICAgICAgfTtcbiAgICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICBpZiAoaXNTYW5kYm94R29uZUVycm9yKGUpKSB7XG4gICAgICAgICAgICAgIHJldHVybiB7IHN0ZG91dCwgc3RkZXJyLCBleGl0Q29kZTogMSB9O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhyb3cgZTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuXG4gICAgICAgIHJldHVybiB7IGNvbW1hbmRJZDogb3V0cHV0LmNtZElkLCBsb2dzLCByZXN1bHQgfTtcbiAgICAgIH0sXG4gICAgICBjYXRjaDogKGUpID0+IG5ldyBTYW5kYm94RXJyb3IoeyByZWFzb246IFN0cmluZyhlKSwgY2F1c2U6IGUgfSksXG4gICAgfSk7XG4gIH1cblxuICBmdW5jdGlvbiByZWFkRmlsZU9uSW5zdGFuY2UoXG4gICAgaW5zdGFuY2U6IFNhbmRib3hJbnN0YW5jZSxcbiAgICB7IHBhdGggfTogeyBwYXRoOiBzdHJpbmcgfVxuICApOiBQcm9taXNlPFNhbmRib3hFcnJvciB8IEJ1ZmZlciB8IG51bGw+IHtcbiAgICByZXR1cm4gZXJyb3JlLnRyeUFzeW5jKHtcbiAgICAgIHRyeTogKCkgPT4gaW5zdGFuY2UucmVhZEZpbGVUb0J1ZmZlcih7IHBhdGgsIGN3ZDogSE9NRV9ESVIgfSksXG4gICAgICBjYXRjaDogKGUpID0+IG5ldyBTYW5kYm94RXJyb3IoeyByZWFzb246IFN0cmluZyhlKSwgY2F1c2U6IGUgfSksXG4gICAgfSk7XG4gIH1cblxuICBhc3luYyBmdW5jdGlvbiB3cml0ZUZpbGVzT25JbnN0YW5jZShcbiAgICBpbnN0YW5jZTogU2FuZGJveEluc3RhbmNlLFxuICAgIG9wdHM6IHtcbiAgICAgIGZpbGVzOiB7IHBhdGg6IHN0cmluZzsgY29udGVudDogc3RyaW5nIHwgQnVmZmVyIH1bXTtcbiAgICAgIGRlc3RQYXRoOiBzdHJpbmc7XG4gICAgfVxuICApOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCB7IGZpbGVzLCBkZXN0UGF0aCB9ID0gb3B0cztcbiAgICBpZiAoZmlsZXMubGVuZ3RoID09PSAwKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgbmF0aXZlRmlsZXMgPSBmaWxlcy5tYXAoKGZpbGUpID0+IHtcbiAgICAgIGNvbnN0IGZpbGVQYXRoID0gcGF0aC5wb3NpeC5qb2luKGRlc3RQYXRoLCBmaWxlLnBhdGgpO1xuICAgICAgY29uc3QgYWJzb2x1dGVQYXRoID0gcGF0aC5wb3NpeC5pc0Fic29sdXRlKGZpbGVQYXRoKVxuICAgICAgICA/IGZpbGVQYXRoXG4gICAgICAgIDogcGF0aC5wb3NpeC5qb2luKEhPTUVfRElSLCBmaWxlUGF0aCk7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBwYXRoOiBhYnNvbHV0ZVBhdGgsXG4gICAgICAgIGNvbnRlbnQ6XG4gICAgICAgICAgdHlwZW9mIGZpbGUuY29udGVudCA9PT0gXCJzdHJpbmdcIlxuICAgICAgICAgICAgPyBCdWZmZXIuZnJvbShmaWxlLmNvbnRlbnQpXG4gICAgICAgICAgICA6IGZpbGUuY29udGVudCxcbiAgICAgIH07XG4gICAgfSk7XG5cbiAgICBhd2FpdCBpbnN0YW5jZS53cml0ZUZpbGVzKG5hdGl2ZUZpbGVzKTtcblxuICAgIGNvbnN0IHNoZWxsU2NyaXB0cyA9IG5hdGl2ZUZpbGVzLmZpbHRlcigoZikgPT4gZi5wYXRoLmVuZHNXaXRoKFwiLnNoXCIpKTtcbiAgICBpZiAoc2hlbGxTY3JpcHRzLmxlbmd0aCA+IDApIHtcbiAgICAgIGNvbnN0IGNobW9kUmVzdWx0ID0gYXdhaXQgZXhlY09uSW5zdGFuY2UoaW5zdGFuY2UsIHtcbiAgICAgICAgY29tbWFuZDogXCJjaG1vZFwiLFxuICAgICAgICBhcmdzOiBbXCIreFwiLCAuLi5zaGVsbFNjcmlwdHMubWFwKChmKSA9PiBmLnBhdGgpXSxcbiAgICAgIH0pO1xuICAgICAgaWYgKGNobW9kUmVzdWx0IGluc3RhbmNlb2YgRXJyb3IpIHtcbiAgICAgICAgdGhyb3cgY2htb2RSZXN1bHQ7XG4gICAgICB9XG4gICAgICBhd2FpdCBjaG1vZFJlc3VsdC5yZXN1bHQ7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIENyZWF0ZXMgYSBtaW5pbWFsIFNhbmRib3ggd3JhcHBlciBhcm91bmQgYSByYXcgVmVyY2VsIFNESyBpbnN0YW5jZS5cbiAgICogVXNlZCBmb3IgcnVubmluZyBzZXR1cC5ydW4oKSBvbiBhIHRlbXBvcmFyeSBzYW5kYm94IGZvciBzbmFwc2hvdCBjcmVhdGlvbi5cbiAgICovXG4gIGZ1bmN0aW9uIGNyZWF0ZVRlbXBTYW5kYm94KGluc3RhbmNlOiBTYW5kYm94SW5zdGFuY2UpOiBTYW5kYm94IHtcbiAgICBjb25zdCB0ZW1wU2FuZGJveDogU2FuZGJveCA9IHtcbiAgICAgIGlkOiBgX19zZXR1cF90ZW1wXyR7RGF0ZS5ub3coKX1gLFxuICAgICAgY29uZmlnLFxuICAgICAgZXhlYzogKG9wdHMpID0+IGV4ZWNPbkluc3RhbmNlKGluc3RhbmNlLCBvcHRzKSxcbiAgICAgIHJlYWRGaWxlOiAob3B0cykgPT4gcmVhZEZpbGVPbkluc3RhbmNlKGluc3RhbmNlLCBvcHRzKSxcbiAgICAgIGdldERvbWFpbjogKCkgPT5cbiAgICAgICAgUHJvbWlzZS5yZXNvbHZlKFxuICAgICAgICAgIG5ldyBTYW5kYm94RXJyb3IoeyByZWFzb246IFwibm90IGF2YWlsYWJsZSBkdXJpbmcgc2V0dXBcIiB9KVxuICAgICAgICApLFxuICAgICAga2lsbDogKCkgPT5cbiAgICAgICAgUHJvbWlzZS5yZXNvbHZlKFxuICAgICAgICAgIG5ldyBTYW5kYm94RXJyb3IoeyByZWFzb246IFwibm90IGF2YWlsYWJsZSBkdXJpbmcgc2V0dXBcIiB9KVxuICAgICAgICApLFxuICAgICAgd3JpdGVGaWxlczogKG9wdHMpID0+IHdyaXRlRmlsZXNPbkluc3RhbmNlKGluc3RhbmNlLCBvcHRzKSxcbiAgICAgIHVwZGF0ZU5ldHdvcmtQb2xpY3k6IChwb2xpY3kpID0+XG4gICAgICAgIGVycm9yZS50cnlBc3luYyh7XG4gICAgICAgICAgdHJ5OiAoKSA9PiBpbnN0YW5jZS51cGRhdGVOZXR3b3JrUG9saWN5KHBvbGljeSksXG4gICAgICAgICAgY2F0Y2g6IChlKSA9PiBuZXcgU2FuZGJveEVycm9yKHsgcmVhc29uOiBTdHJpbmcoZSksIGNhdXNlOiBlIH0pLFxuICAgICAgICB9KSxcbiAgICAgIHRhZzoge1xuICAgICAgICBsaXN0OiBhc3luYyAoKSA9PiAoe30pIGFzIFRUYWdzLFxuICAgICAgICBnZXQ6IGFzeW5jICgpID0+IHVuZGVmaW5lZCxcbiAgICAgICAgc2V0OiBhc3luYyAoKSA9PiB1bmRlZmluZWQsXG4gICAgICAgIHNldE1hbnk6IGFzeW5jICgpID0+IHVuZGVmaW5lZCxcbiAgICAgIH0sXG4gICAgfTtcbiAgICByZXR1cm4gdGVtcFNhbmRib3g7XG4gIH1cblxuICAvKipcbiAgICogUG9sbHMgZm9yIGEgc2V0dXAgc25hcHNob3QgdG8gYmVjb21lIGF2YWlsYWJsZS4gUmV0dXJucyB0aGUgc25hcHNob3RJZFxuICAgKiBpZiBvbmUgYXBwZWFycyBiZWZvcmUgdGhlIGxvY2sgdGltZXMgb3V0LCBvciBudWxsIGlmIGl0IGRvZXNuJ3QuXG4gICAqL1xuICBhc3luYyBmdW5jdGlvbiBwb2xsRm9yU2V0dXBTbmFwc2hvdChrZXk6IHN0cmluZyk6IFByb21pc2U8c3RyaW5nIHwgbnVsbD4ge1xuICAgIGNvbnN0IGRlYWRsaW5lID0gRGF0ZS5ub3coKSArIExPQ0tfVElNRU9VVF9NUztcbiAgICB3aGlsZSAoRGF0ZS5ub3coKSA8IGRlYWRsaW5lKSB7XG4gICAgICBhd2FpdCBuZXcgUHJvbWlzZSgocikgPT4gc2V0VGltZW91dChyLCBMT0NLX1BPTExfSU5URVJWQUxfTVMpKTtcbiAgICAgIGNvbnN0IHJlY29yZCA9IGF3YWl0IHN0b3JhZ2Uuc2V0dXAuZ2V0KGtleSk7XG4gICAgICBpZiAocmVjb3JkIGluc3RhbmNlb2YgRXJyb3IpIHtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICB9XG4gICAgICBpZiAocmVjb3JkPy5zbmFwc2hvdElkKSB7XG4gICAgICAgIHJldHVybiByZWNvcmQuc25hcHNob3RJZDtcbiAgICAgIH1cbiAgICAgIC8vIExvY2sgcmVsZWFzZWQgYnV0IG5vIHNuYXBzaG90IFx1MjAxNCBjcmVhdGlvbiBmYWlsZWRcbiAgICAgIGlmICghcmVjb3JkPy5hY3F1aXJpbmdMb2NrSWQpIHtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgLyoqXG4gICAqIENyZWF0ZXMgYSBiYWNrZ3JvdW5kIHNhbmRib3gsIHJ1bnMgc2V0dXAsIHNuYXBzaG90cyBpdCwgYW5kIHN0b3JlcyB0aGVcbiAgICogc25hcHNob3QgSUQuIFVzZXMgYXRvbWljIGxvY2tpbmcgdG8gZW5zdXJlIG9ubHkgb25lIHByb2Nlc3MgY3JlYXRlcyBpdC5cbiAgICpcbiAgICogQHBhcmFtIGZvcmNlIC0gU2tpcCB0aGUgXCJzbmFwc2hvdCBhbHJlYWR5IGV4aXN0c1wiIGVhcmx5IGV4aXQuIFVzZWQgd2hlblxuICAgKiAgIHRoZSBjYWxsZXIga25vd3MgdGhlIGV4aXN0aW5nIHNuYXBzaG90IGlzIHN0YWxlL2V4cGlyZWQuXG4gICAqL1xuICBhc3luYyBmdW5jdGlvbiBjcmVhdGVTZXR1cFNuYXBzaG90KG9wdHM/OiB7XG4gICAgZm9yY2U/OiBib29sZWFuO1xuICB9KTogUHJvbWlzZTx2b2lkPiB7XG4gICAgaWYgKCFzZXR1cCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCBzZXR1cEtleSA9IHNldHVwLmtleTtcblxuICAgIC8vIENoZWNrIGlmIHNuYXBzaG90IGFscmVhZHkgZXhpc3RzIChmYXN0IHBhdGggXHUyMDE0IGF2b2lkcyBsb2NrIGF0dGVtcHQpXG4gICAgaWYgKCFvcHRzPy5mb3JjZSkge1xuICAgICAgY29uc3QgZXhpc3RpbmcgPSBhd2FpdCBzdG9yYWdlLnNldHVwLmdldChzZXR1cEtleSk7XG4gICAgICBpZiAoIShleGlzdGluZyBpbnN0YW5jZW9mIEVycm9yKSAmJiBleGlzdGluZz8uc25hcHNob3RJZCkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gQXRvbWljYWxseSBhY3F1aXJlIGxvY2sgKGhhbmRsZXMgYWN0aXZlLWxvY2sgZGV0ZWN0aW9uIGludGVybmFsbHkpXG4gICAgZGVidWcoYFtzYW5kYm94OnNldHVwXSBhY3F1aXJpbmcgbG9jayBmb3Igc2V0dXAga2V5IFwiJHtzZXR1cEtleX1cImApO1xuICAgIGNvbnN0IGxvY2tJZCA9IGNyeXB0by5yYW5kb21VVUlEKCk7XG4gICAgY29uc3QgbG9ja2VkID0gYXdhaXQgc3RvcmFnZS5zZXR1cC5hY3F1aXJlTG9jayhcbiAgICAgIHNldHVwS2V5LFxuICAgICAgbG9ja0lkLFxuICAgICAgTE9DS19USU1FT1VUX01TXG4gICAgKTtcbiAgICBpZiAobG9ja2VkIGluc3RhbmNlb2YgRXJyb3IgfHwgIWxvY2tlZCkge1xuICAgICAgZGVidWcoXG4gICAgICAgIGBbc2FuZGJveDpzZXR1cF0gbG9jayBub3QgYWNxdWlyZWQgZm9yIGtleSBcIiR7c2V0dXBLZXl9XCIgKGFub3RoZXIgcHJvY2VzcyBob2xkcyBpdClgXG4gICAgICApO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIFJlLWNoZWNrOiBhbm90aGVyIHdvcmtlciBtYXkgaGF2ZSBjcmVhdGVkIHRoZSBzbmFwc2hvdCBiZXR3ZWVuIG91clxuICAgIC8vIHByZS1jaGVjayBhbmQgbG9jayBhY3F1aXNpdGlvbi4gSWYgc28sIHNraXAgdW5sZXNzIGZvcmNlIChzdGFsZSBzbmFwc2hvdCkuXG4gICAgaWYgKCFvcHRzPy5mb3JjZSAmJiBsb2NrZWQuc25hcHNob3RJZCkge1xuICAgICAgZGVidWcoXG4gICAgICAgIGBbc2FuZGJveDpzZXR1cF0gc25hcHNob3QgYWxyZWFkeSBleGlzdHMgYWZ0ZXIgbG9jayBmb3Iga2V5IFwiJHtzZXR1cEtleX1cIiwgc2tpcHBpbmdgXG4gICAgICApO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGxldCB0ZW1wSW5zdGFuY2U6IEF3YWl0ZWQ8XG4gICAgICBSZXR1cm5UeXBlPHR5cGVvZiBWZXJjZWxTYW5kYm94U0RLLmNyZWF0ZT5cbiAgICA+IHwgbnVsbCA9IG51bGw7XG4gICAgdHJ5IHtcbiAgICAgIC8vIENyZWF0ZSBhIHRlbXBvcmFyeSBzYW5kYm94IGZvciBzbmFwc2hvdHRpbmcuXG4gICAgICBkZWJ1ZyhcbiAgICAgICAgYFtzYW5kYm94OnNldHVwXSBjcmVhdGluZyB0ZW1wIHNhbmRib3ggZm9yIHNuYXBzaG90IChrZXk9XCIke3NldHVwS2V5fVwiKWBcbiAgICAgICk7XG4gICAgICB0ZW1wSW5zdGFuY2UgPSBhd2FpdCBWZXJjZWxTYW5kYm94U0RLLmNyZWF0ZSh7XG4gICAgICAgIHJlc291cmNlczogeyB2Y3B1cyB9LFxuICAgICAgICB0aW1lb3V0OiBWRVJDRUxfTUFYX1RJTUVPVVRfTVMsXG4gICAgICAgIHBvcnRzLFxuICAgICAgICBuZXR3b3JrUG9saWN5LFxuICAgICAgICAuLi5nZXRUZXN0Q3JlZGVudGlhbHMoKSxcbiAgICAgIH0pO1xuXG4gICAgICBjb25zdCB0ZW1wU2FuZGJveCA9IGNyZWF0ZVRlbXBTYW5kYm94KFxuICAgICAgICB0ZW1wSW5zdGFuY2UgYXMgdW5rbm93biBhcyBTYW5kYm94SW5zdGFuY2VcbiAgICAgICk7XG4gICAgICBhd2FpdCBzZXR1cC5ydW4odGVtcFNhbmRib3gpO1xuICAgICAgZGVidWcoXG4gICAgICAgIGBbc2FuZGJveDpzZXR1cF0gc2V0dXAucnVuIGNvbXBsZXRlLCBzbmFwc2hvdHRpbmcgKGtleT1cIiR7c2V0dXBLZXl9XCIpYFxuICAgICAgKTtcbiAgICAgIGNvbnN0IHNuYXBzaG90ID0gYXdhaXQgdGVtcEluc3RhbmNlLnNuYXBzaG90KCk7XG5cbiAgICAgIGF3YWl0IHN0b3JhZ2Uuc2V0dXAuc2V0KHtcbiAgICAgICAga2V5OiBzZXR1cEtleSxcbiAgICAgICAgc25hcHNob3RJZDogc25hcHNob3Quc25hcHNob3RJZCxcbiAgICAgICAgY3JlYXRlZEF0OiBsb2NrZWQuY3JlYXRlZEF0LFxuICAgICAgICBsYXN0VXNlZEF0OiBudWxsLFxuICAgICAgICBhY3F1aXJpbmdMb2NrSWQ6IG51bGwsXG4gICAgICAgIGFjcXVpcmluZ0xvY2tBdDogbnVsbCxcbiAgICAgIH0pO1xuICAgICAgZGVidWcoXG4gICAgICAgIGBbc2FuZGJveDpzZXR1cF0gc25hcHNob3Qgc3RvcmVkOiAke3NuYXBzaG90LnNuYXBzaG90SWR9IChrZXk9XCIke3NldHVwS2V5fVwiKWBcbiAgICAgICk7XG5cbiAgICAgIC8vIFN0b3AgdGhlIHRlbXAgc2FuZGJveCBcdTIwMTQgbm8gbG9uZ2VyIG5lZWRlZCBhZnRlciBzbmFwc2hvdHRpbmdcbiAgICAgIGF3YWl0IHRlbXBJbnN0YW5jZS5zdG9wKCkuY2F0Y2goKCkgPT4gdW5kZWZpbmVkKTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICBjb25zb2xlLmVycm9yKFxuICAgICAgICBgW3NhbmRib3g6c2V0dXBdIGZhaWxlZCB0byBjcmVhdGUgc2V0dXAgc25hcHNob3QgKGtleT1cIiR7c2V0dXBLZXl9XCIpOmAsXG4gICAgICAgIGVcbiAgICAgICk7XG4gICAgICAvLyBTdG9wIHRoZSB0ZW1wIHNhbmRib3ggb24gZmFpbHVyZVxuICAgICAgaWYgKHRlbXBJbnN0YW5jZSkge1xuICAgICAgICBhd2FpdCB0ZW1wSW5zdGFuY2Uuc3RvcCgpLmNhdGNoKCgpID0+IHVuZGVmaW5lZCk7XG4gICAgICB9XG4gICAgICAvLyBDbGVhbiB1cCBsb2NrIG9uIGZhaWx1cmVcbiAgICAgIGF3YWl0IHN0b3JhZ2Uuc2V0dXBcbiAgICAgICAgLnNldCh7XG4gICAgICAgICAga2V5OiBzZXR1cEtleSxcbiAgICAgICAgICBzbmFwc2hvdElkOiBudWxsLFxuICAgICAgICAgIGNyZWF0ZWRBdDogbG9ja2VkLmNyZWF0ZWRBdCxcbiAgICAgICAgICBsYXN0VXNlZEF0OiBudWxsLFxuICAgICAgICAgIGFjcXVpcmluZ0xvY2tJZDogbnVsbCxcbiAgICAgICAgICBhY3F1aXJpbmdMb2NrQXQ6IG51bGwsXG4gICAgICAgIH0pXG4gICAgICAgIC5jYXRjaCgoKSA9PiB1bmRlZmluZWQpO1xuICAgIH1cbiAgfVxuXG4gIGFzeW5jIGZ1bmN0aW9uIGRvR2V0T3JDcmVhdGVTYW5kYm94SWQoKTogUHJvbWlzZTxTYW5kYm94RXJyb3IgfCBzdHJpbmc+IHtcbiAgICBpZiAoaW5pdGlhbFZlcmNlbD8uc2FuZGJveElkICYmICFyZWNvdmVyZWRGcm9tU3RhbGUpIHtcbiAgICAgIHJldHVybiBpbml0aWFsVmVyY2VsLnNhbmRib3hJZDtcbiAgICB9XG5cbiAgICBjb25zdCBleGlzdGluZyA9IGF3YWl0IHN0b3JhZ2Uuc2FuZGJveC5nZXQoaWQpO1xuICAgIGlmIChleGlzdGluZyBpbnN0YW5jZW9mIEVycm9yKSB7XG4gICAgICBpZiAoZXhpc3RpbmcgaW5zdGFuY2VvZiBTYW5kYm94Tm90Rm91bmRFcnJvcikge1xuICAgICAgICAvLyBTYW5kYm94IGRvZXNuJ3QgZXhpc3QgeWV0LCBjb250aW51ZSB3aXRoIGNyZWF0aW9uXG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gbmV3IFNhbmRib3hFcnJvcih7IHJlYXNvbjogZXhpc3RpbmcubWVzc2FnZSwgY2F1c2U6IGV4aXN0aW5nIH0pO1xuICAgICAgfVxuICAgIH1cblxuICAgIGNvbnN0IGV4aXN0aW5nUmVjb3JkID1cbiAgICAgIGV4aXN0aW5nIGluc3RhbmNlb2YgU2FuZGJveE5vdEZvdW5kRXJyb3IgPyBudWxsIDogZXhpc3Rpbmc7XG4gICAgY29uc3QgZXhpc3RpbmdWZXJjZWwgPVxuICAgICAgZXhpc3RpbmdSZWNvcmQ/LnByb3ZpZGVyTWV0YWRhdGE/LnByb3ZpZGVyID09PSBcInZlcmNlbFwiXG4gICAgICAgID8gZXhpc3RpbmdSZWNvcmQucHJvdmlkZXJNZXRhZGF0YVxuICAgICAgICA6IG51bGw7XG5cbiAgICBpZiAoZXhpc3RpbmdWZXJjZWw/LnNhbmRib3hJZCkge1xuICAgICAgcmV0dXJuIGV4aXN0aW5nVmVyY2VsLnNhbmRib3hJZDtcbiAgICB9XG5cbiAgICBjb25zdCBoYXNBY3RpdmVMb2NrID1cbiAgICAgIGV4aXN0aW5nUmVjb3JkPy5hY3F1aXJpbmdMb2NrSWQgJiZcbiAgICAgIGV4aXN0aW5nUmVjb3JkLmFjcXVpcmluZ0xvY2tBdCAmJlxuICAgICAgRGF0ZS5ub3coKSAtIGV4aXN0aW5nUmVjb3JkLmFjcXVpcmluZ0xvY2tBdCA8IExPQ0tfVElNRU9VVF9NUztcblxuICAgIGlmIChoYXNBY3RpdmVMb2NrKSB7XG4gICAgICByZXR1cm4gcG9sbEZvclNhbmRib3hJZCgpO1xuICAgIH1cblxuICAgIGNvbnN0IGxvY2tJZCA9IGNyeXB0by5yYW5kb21VVUlEKCk7XG4gICAgY29uc3Qgbm93ID0gRGF0ZS5ub3coKTtcbiAgICBjb25zdCBsb2NrZWQgPSBhd2FpdCBzdG9yYWdlLnNhbmRib3guYWNxdWlyZUxvY2soXG4gICAgICB7XG4gICAgICAgIGlkLFxuICAgICAgICBjb25maWcsXG4gICAgICAgIHRhZ3M6IGV4aXN0aW5nUmVjb3JkPy50YWdzID8/IHNhbmRib3hSZWNvcmQudGFncyxcbiAgICAgICAgY3JlYXRlZEF0OiBleGlzdGluZ1JlY29yZD8uY3JlYXRlZEF0ID8/IHNhbmRib3hSZWNvcmQuY3JlYXRlZEF0LFxuICAgICAgICBsYXN0QWN0aXZpdHlBdDpcbiAgICAgICAgICBleGlzdGluZ1JlY29yZD8ubGFzdEFjdGl2aXR5QXQgPz8gc2FuZGJveFJlY29yZC5sYXN0QWN0aXZpdHlBdCxcbiAgICAgICAgYWNxdWlyaW5nTG9ja0lkOiBsb2NrSWQsXG4gICAgICAgIGFjcXVpcmluZ0xvY2tBdDogbm93LFxuICAgICAgICBwcm92aWRlck1ldGFkYXRhOiB7XG4gICAgICAgICAgcHJvdmlkZXI6IFwidmVyY2VsXCIsXG4gICAgICAgICAgc2FuZGJveElkOiBudWxsLFxuICAgICAgICAgIHNuYXBzaG90SWQ6XG4gICAgICAgICAgICBleGlzdGluZ1ZlcmNlbD8uc25hcHNob3RJZCA/PyBpbml0aWFsVmVyY2VsPy5zbmFwc2hvdElkID8/IG51bGwsXG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgICAgTE9DS19USU1FT1VUX01TXG4gICAgKTtcblxuICAgIGlmIChsb2NrZWQgaW5zdGFuY2VvZiBFcnJvcikge1xuICAgICAgcmV0dXJuIG5ldyBTYW5kYm94RXJyb3IoeyByZWFzb246IGxvY2tlZC5tZXNzYWdlLCBjYXVzZTogbG9ja2VkIH0pO1xuICAgIH1cbiAgICBpZiAoIWxvY2tlZCkge1xuICAgICAgcmV0dXJuIHBvbGxGb3JTYW5kYm94SWQoKTtcbiAgICB9XG5cbiAgICAvLyBDYXB0dXJlIHRoZSBsb2NrZWQgcmVjb3JkIGZvciB1c2UgaW4gdGhlIHJlbGVhc2UgaGVscGVyLlxuICAgIC8vIFRTIGNhbid0IG5hcnJvdyBgbG9ja2VkYCBpbnNpZGUgbmVzdGVkIGZ1bmN0aW9ucywgc28gd2UgYmluZCBpdCBoZXJlLlxuICAgIGNvbnN0IGxvY2tlZFJlY29yZCA9IGxvY2tlZDtcblxuICAgIC8vIFJlbGVhc2UgdGhlIHNhbmRib3ggbG9jayBzbyBvdGhlciB3b3JrZXJzIGNhbiByZXRyeSBxdWlja2x5XG4gICAgLy8gaW5zdGVhZCBvZiB3YWl0aW5nIGZvciBsb2NrIHRpbWVvdXQuXG4gICAgYXN5bmMgZnVuY3Rpb24gcmVsZWFzZVNhbmRib3hMb2NrKCk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgYXdhaXQgc3RvcmFnZS5zYW5kYm94XG4gICAgICAgIC51cGRhdGUoe1xuICAgICAgICAgIGlkOiBsb2NrZWRSZWNvcmQuaWQsXG4gICAgICAgICAgYWNxdWlyaW5nTG9ja0lkOiBudWxsLFxuICAgICAgICAgIGFjcXVpcmluZ0xvY2tBdDogbnVsbCxcbiAgICAgICAgfSlcbiAgICAgICAgLmNhdGNoKCgpID0+IHVuZGVmaW5lZCk7XG4gICAgfVxuXG4gICAgLy8gUmUtY2hlY2sgYWZ0ZXIgbG9jazogYW5vdGhlciB3b3JrZXIgbWF5IGhhdmUgY3JlYXRlZCB0aGUgc2FuZGJveFxuICAgIC8vIGJldHdlZW4gb3VyIGluaXRpYWwgY2hlY2sgYW5kIGxvY2sgYWNxdWlzaXRpb24uXG4gICAgY29uc3QgbG9ja2VkVmVyY2VsID1cbiAgICAgIGxvY2tlZFJlY29yZC5wcm92aWRlck1ldGFkYXRhPy5wcm92aWRlciA9PT0gXCJ2ZXJjZWxcIlxuICAgICAgICA/IGxvY2tlZFJlY29yZC5wcm92aWRlck1ldGFkYXRhXG4gICAgICAgIDogbnVsbDtcbiAgICBpZiAobG9ja2VkVmVyY2VsPy5zYW5kYm94SWQpIHtcbiAgICAgIGF3YWl0IHJlbGVhc2VTYW5kYm94TG9jaygpO1xuICAgICAgcmV0dXJuIGxvY2tlZFZlcmNlbC5zYW5kYm94SWQ7XG4gICAgfVxuXG4gICAgY29uc3Qgc25hcHNob3RJZCA9XG4gICAgICBsb2NrZWRWZXJjZWw/LnNuYXBzaG90SWQgPz9cbiAgICAgIGluaXRpYWxWZXJjZWw/LnNuYXBzaG90SWQgPz9cbiAgICAgIGNvbmZpZy5saWZlY3ljbGU/LnNuYXBzaG90SWQ7XG4gICAgaWYgKHNuYXBzaG90SWQpIHtcbiAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGNyZWF0ZVNhbmRib3hGcm9tU25hcHNob3Qoc25hcHNob3RJZCk7XG4gICAgICBpZiAoIShyZXN1bHQgaW5zdGFuY2VvZiBFcnJvcikpIHtcbiAgICAgICAgY3JlYXRlZEZyb21TbmFwc2hvdCA9IHRydWU7XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gQ2hlY2sgZm9yIHNldHVwIHNuYXBzaG90XG4gICAgaWYgKHNldHVwKSB7XG4gICAgICBsZXQgZm9yY2VSZWNyZWF0ZVNuYXBzaG90ID0gZmFsc2U7XG4gICAgICBjb25zdCBzZXR1cFJlY29yZCA9IGF3YWl0IHN0b3JhZ2Uuc2V0dXAuZ2V0KHNldHVwLmtleSk7XG4gICAgICBpZiAoIShzZXR1cFJlY29yZCBpbnN0YW5jZW9mIEVycm9yKSAmJiBzZXR1cFJlY29yZCkge1xuICAgICAgICBpZiAoc2V0dXBSZWNvcmQuc25hcHNob3RJZCkge1xuICAgICAgICAgIGRlYnVnKFxuICAgICAgICAgICAgYFtzYW5kYm94OnNldHVwXSBmb3VuZCBzZXR1cCBzbmFwc2hvdCAke3NldHVwUmVjb3JkLnNuYXBzaG90SWR9IGZvciBrZXkgXCIke3NldHVwLmtleX1cImBcbiAgICAgICAgICApO1xuICAgICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGNyZWF0ZVNhbmRib3hGcm9tU25hcHNob3QoXG4gICAgICAgICAgICBzZXR1cFJlY29yZC5zbmFwc2hvdElkXG4gICAgICAgICAgKTtcbiAgICAgICAgICBpZiAoIShyZXN1bHQgaW5zdGFuY2VvZiBFcnJvcikpIHtcbiAgICAgICAgICAgIGNyZWF0ZWRGcm9tU25hcHNob3QgPSB0cnVlO1xuICAgICAgICAgICAgLy8gVXBkYXRlIGxhc3RVc2VkQXQgKGZpcmUtYW5kLWZvcmdldClcbiAgICAgICAgICAgIHN0b3JhZ2Uuc2V0dXBcbiAgICAgICAgICAgICAgLnNldCh7XG4gICAgICAgICAgICAgICAgLi4uc2V0dXBSZWNvcmQsXG4gICAgICAgICAgICAgICAgbGFzdFVzZWRBdDogRGF0ZS5ub3coKSxcbiAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgLmNhdGNoKCgpID0+IHVuZGVmaW5lZCk7XG4gICAgICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgICAgIH1cbiAgICAgICAgICAvLyBTbmFwc2hvdCBpcyBzdGFsZS9leHBpcmVkIFx1MjAxNCBmb3JjZSBiYWNrZ3JvdW5kIHRvIG92ZXJ3cml0ZSBpdFxuICAgICAgICAgIGRlYnVnKFxuICAgICAgICAgICAgYFtzYW5kYm94OnNldHVwXSBzbmFwc2hvdCAke3NldHVwUmVjb3JkLnNuYXBzaG90SWR9IGZhaWxlZCAoZXhwaXJlZD8pLCB3aWxsIHJlY3JlYXRlYFxuICAgICAgICAgICk7XG4gICAgICAgICAgZm9yY2VSZWNyZWF0ZVNuYXBzaG90ID0gdHJ1ZTtcbiAgICAgICAgfSBlbHNlIGlmIChcbiAgICAgICAgICBzZXR1cFJlY29yZC5hY3F1aXJpbmdMb2NrSWQgJiZcbiAgICAgICAgICBzZXR1cFJlY29yZC5hY3F1aXJpbmdMb2NrQXQgJiZcbiAgICAgICAgICBEYXRlLm5vdygpIC0gc2V0dXBSZWNvcmQuYWNxdWlyaW5nTG9ja0F0IDwgTE9DS19USU1FT1VUX01TXG4gICAgICAgICkge1xuICAgICAgICAgIC8vIEFub3RoZXIgcHJvY2VzcyBpcyBjcmVhdGluZyB0aGUgc2V0dXAgc25hcHNob3QgXHUyMDE0IHdhaXQgZm9yIGl0XG4gICAgICAgICAgZGVidWcoXG4gICAgICAgICAgICBgW3NhbmRib3g6c2V0dXBdIHNuYXBzaG90IGluIHByb2dyZXNzIGZvciBrZXkgXCIke3NldHVwLmtleX1cIiwgd2FpdGluZy4uLmBcbiAgICAgICAgICApO1xuICAgICAgICAgIGNvbnN0IHNuYXBzaG90SWQgPSBhd2FpdCBwb2xsRm9yU2V0dXBTbmFwc2hvdChzZXR1cC5rZXkpO1xuICAgICAgICAgIGlmIChzbmFwc2hvdElkKSB7XG4gICAgICAgICAgICBkZWJ1ZyhcbiAgICAgICAgICAgICAgYFtzYW5kYm94OnNldHVwXSBzbmFwc2hvdCByZWFkeTogJHtzbmFwc2hvdElkfSBmb3Iga2V5IFwiJHtzZXR1cC5rZXl9XCJgXG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgY3JlYXRlU2FuZGJveEZyb21TbmFwc2hvdChzbmFwc2hvdElkKTtcbiAgICAgICAgICAgIGlmICghKHJlc3VsdCBpbnN0YW5jZW9mIEVycm9yKSkge1xuICAgICAgICAgICAgICBjcmVhdGVkRnJvbVNuYXBzaG90ID0gdHJ1ZTtcbiAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgLy8gUG9sbCBmYWlsZWQgb3Igc25hcHNob3QgY3JlYXRpb24gZmFpbGVkIFx1MjAxNCBmYWxsIHRocm91Z2ggdG8gY29sZCBwYXRoXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIC8vIE5vIHNldHVwIHNuYXBzaG90IGF2YWlsYWJsZSBcdTIwMTQgY3JlYXRlIGZyZXNoIGFuZCBydW4gc2V0dXAgbGF0ZXIuXG4gICAgICAvLyBLaWNrIG9mZiBiYWNrZ3JvdW5kIHNuYXBzaG90IGltbWVkaWF0ZWx5IHNvIGl0IHJ1bnMgaW4gcGFyYWxsZWxcbiAgICAgIC8vIHdpdGggc2V0dXAucnVuIG9uIHRoZSBzZXNzaW9uIHNhbmRib3guXG4gICAgICBkZWJ1ZyhcbiAgICAgICAgYFtzYW5kYm94OnNldHVwXSBubyBzbmFwc2hvdCBmb3Iga2V5IFwiJHtzZXR1cC5rZXl9XCIsIHdpbGwgcnVuIHNldHVwIG9uIHRoaXMgc2FuZGJveGBcbiAgICAgICk7XG4gICAgICBuZWVkc1NldHVwUnVuID0gdHJ1ZTtcbiAgICAgIGNyZWF0ZVNldHVwU25hcHNob3QoeyBmb3JjZTogZm9yY2VSZWNyZWF0ZVNuYXBzaG90IH0pLmNhdGNoKChlKSA9PiB7XG4gICAgICAgIGNvbnNvbGUuZXJyb3IoXG4gICAgICAgICAgXCJbc2FuZGJveDpzZXR1cF0gZmFpbGVkIHRvIGNyZWF0ZSBiYWNrZ3JvdW5kIHNuYXBzaG90OlwiLFxuICAgICAgICAgIGVcbiAgICAgICAgKTtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIGNvbnN0IGZyZXNoUmVzdWx0ID0gYXdhaXQgY3JlYXRlRnJlc2hTYW5kYm94KCk7XG4gICAgaWYgKGZyZXNoUmVzdWx0IGluc3RhbmNlb2YgRXJyb3IpIHtcbiAgICAgIGF3YWl0IHJlbGVhc2VTYW5kYm94TG9jaygpO1xuICAgIH1cbiAgICByZXR1cm4gZnJlc2hSZXN1bHQ7XG4gIH1cblxuICBmdW5jdGlvbiBnZXRPckNyZWF0ZVNhbmRib3hJZCgpOiBQcm9taXNlPFNhbmRib3hFcnJvciB8IHN0cmluZz4ge1xuICAgIGNvbnN0IGNhY2hlZCA9IGNyZWF0ZVByb21pc2VzLmdldChpZCk7XG4gICAgaWYgKGNhY2hlZCkge1xuICAgICAgcmV0dXJuIGNhY2hlZDtcbiAgICB9XG5cbiAgICBjb25zdCBwcm9taXNlID0gZG9HZXRPckNyZWF0ZVNhbmRib3hJZCgpLmZpbmFsbHkoKCkgPT4ge1xuICAgICAgY3JlYXRlUHJvbWlzZXMuZGVsZXRlKGlkKTtcbiAgICB9KTtcbiAgICBjcmVhdGVQcm9taXNlcy5zZXQoaWQsIHByb21pc2UpO1xuICAgIHJldHVybiBwcm9taXNlO1xuICB9XG5cbiAgYXN5bmMgZnVuY3Rpb24gZG9HZXRTYW5kYm94KCk6IFByb21pc2U8U2FuZGJveEVycm9yIHwgU2FuZGJveEluc3RhbmNlPiB7XG4gICAgY29uc3QgdmVyY2VsU2FuZGJveElkID0gYXdhaXQgZ2V0T3JDcmVhdGVTYW5kYm94SWQoKTtcbiAgICBpZiAodmVyY2VsU2FuZGJveElkIGluc3RhbmNlb2YgRXJyb3IpIHtcbiAgICAgIHJldHVybiB2ZXJjZWxTYW5kYm94SWQ7XG4gICAgfVxuXG4gICAgcmV0dXJuIGVycm9yZS50cnlBc3luYyh7XG4gICAgICB0cnk6ICgpID0+XG4gICAgICAgIFZlcmNlbFNhbmRib3hTREsuZ2V0KHtcbiAgICAgICAgICBzYW5kYm94SWQ6IHZlcmNlbFNhbmRib3hJZCxcbiAgICAgICAgICAuLi5nZXRUZXN0Q3JlZGVudGlhbHMoKSxcbiAgICAgICAgfSksXG4gICAgICBjYXRjaDogKGUpID0+IG5ldyBTYW5kYm94RXJyb3IoeyByZWFzb246IFN0cmluZyhlKSwgY2F1c2U6IGUgfSksXG4gICAgfSk7XG4gIH1cblxuICBmdW5jdGlvbiBnZXRTYW5kYm94KCk6IFByb21pc2U8U2FuZGJveEVycm9yIHwgU2FuZGJveEluc3RhbmNlPiB7XG4gICAgaWYgKCFzYW5kYm94UHJvbWlzZSkge1xuICAgICAgc2FuZGJveFByb21pc2UgPSBkb0dldFNhbmRib3goKTtcbiAgICB9XG4gICAgcmV0dXJuIHNhbmRib3hQcm9taXNlO1xuICB9XG5cbiAgYXN5bmMgZnVuY3Rpb24gcmVjb3ZlckZyb21TdGFsZVNhbmRib3goKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgc2FuZGJveFByb21pc2UgPSBudWxsO1xuICAgIHJlY292ZXJlZEZyb21TdGFsZSA9IHRydWU7XG5cbiAgICBjb25zdCBleGlzdGluZyA9IGF3YWl0IHN0b3JhZ2Uuc2FuZGJveC5nZXQoaWQpO1xuICAgIGlmIChleGlzdGluZyBpbnN0YW5jZW9mIEVycm9yIHx8ICFleGlzdGluZykge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IGV4aXN0aW5nVmVyY2VsID1cbiAgICAgIGV4aXN0aW5nLnByb3ZpZGVyTWV0YWRhdGE/LnByb3ZpZGVyID09PSBcInZlcmNlbFwiXG4gICAgICAgID8gZXhpc3RpbmcucHJvdmlkZXJNZXRhZGF0YVxuICAgICAgICA6IG51bGw7XG5cbiAgICBpZiAoZXhpc3RpbmdWZXJjZWw/LnNhbmRib3hJZCkge1xuICAgICAgYXdhaXQgc3RvcmFnZS5zYW5kYm94LnVwZGF0ZSh7XG4gICAgICAgIGlkOiBleGlzdGluZy5pZCxcbiAgICAgICAgYWNxdWlyaW5nTG9ja0lkOiBudWxsLFxuICAgICAgICBhY3F1aXJpbmdMb2NrQXQ6IG51bGwsXG4gICAgICAgIHByb3ZpZGVyTWV0YWRhdGE6IHtcbiAgICAgICAgICBwcm92aWRlcjogXCJ2ZXJjZWxcIixcbiAgICAgICAgICBzYW5kYm94SWQ6IG51bGwsXG4gICAgICAgICAgc25hcHNob3RJZDogZXhpc3RpbmdWZXJjZWwuc25hcHNob3RJZCxcbiAgICAgICAgfSxcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIGFzeW5jIGZ1bmN0aW9uIHVwZGF0ZUxhc3RBY3Rpdml0eSgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCBub3cgPSBEYXRlLm5vdygpO1xuICAgIGNvbnN0IGxhc3RTZW50ID0gbGFzdEFjdGl2aXR5U2VudC5nZXQoaWQpO1xuICAgIGlmIChsYXN0U2VudCAmJiBub3cgLSBsYXN0U2VudCA8IEFDVElWSVRZX1RIUk9UVExFX01TKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGxhc3RBY3Rpdml0eVNlbnQuc2V0KGlkLCBub3cpO1xuXG4gICAgY29uc3QgZXhpc3RpbmcgPSBhd2FpdCBzdG9yYWdlLnNhbmRib3guZ2V0KGlkKTtcbiAgICBpZiAoZXhpc3RpbmcgaW5zdGFuY2VvZiBFcnJvciB8fCAhZXhpc3RpbmcpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3QgZXhpc3RpbmdWZXJjZWwgPVxuICAgICAgZXhpc3RpbmcucHJvdmlkZXJNZXRhZGF0YT8ucHJvdmlkZXIgPT09IFwidmVyY2VsXCJcbiAgICAgICAgPyBleGlzdGluZy5wcm92aWRlck1ldGFkYXRhXG4gICAgICAgIDogbnVsbDtcbiAgICBhd2FpdCBzdG9yYWdlLnNhbmRib3gudXBkYXRlKHtcbiAgICAgIGlkOiBleGlzdGluZy5pZCxcbiAgICAgIGxhc3RBY3Rpdml0eUF0OiBub3csXG4gICAgICBhY3F1aXJpbmdMb2NrSWQ6IG51bGwsXG4gICAgICBhY3F1aXJpbmdMb2NrQXQ6IG51bGwsXG4gICAgICBwcm92aWRlck1ldGFkYXRhOiBleGlzdGluZ1ZlcmNlbCA/PyB7XG4gICAgICAgIHByb3ZpZGVyOiBcInZlcmNlbFwiLFxuICAgICAgICBzYW5kYm94SWQ6IG51bGwsXG4gICAgICAgIHNuYXBzaG90SWQ6IG51bGwsXG4gICAgICB9LFxuICAgIH0pO1xuICB9XG5cbiAgY29uc3QgbGlmZWN5Y2xlOiBTYW5kYm94TGlmZWN5Y2xlID0ge1xuICAgIHN0YXJ0OiBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCBzYW5kYm94ID0gYXdhaXQgZ2V0U2FuZGJveCgpO1xuICAgICAgaWYgKHNhbmRib3ggaW5zdGFuY2VvZiBFcnJvcikge1xuICAgICAgICByZXR1cm4gc2FuZGJveDtcbiAgICAgIH1cbiAgICAgIGF3YWl0IHVwZGF0ZUxhc3RBY3Rpdml0eSgpO1xuICAgICAgcmV0dXJuIHNhbmRib3guc3RhdHVzIGFzIFNhbmRib3hTdGF0dXM7XG4gICAgfSxcblxuICAgIHNuYXBzaG90OiBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCBzYW5kYm94ID0gYXdhaXQgZ2V0U2FuZGJveCgpO1xuICAgICAgaWYgKHNhbmRib3ggaW5zdGFuY2VvZiBFcnJvcikge1xuICAgICAgICByZXR1cm4gc2FuZGJveDtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIGVycm9yZS50cnlBc3luYyh7XG4gICAgICAgIHRyeTogYXN5bmMgKCkgPT4ge1xuICAgICAgICAgIGNvbnN0IHNuYXBzaG90ID0gYXdhaXQgc2FuZGJveC5zbmFwc2hvdCgpO1xuICAgICAgICAgIGF3YWl0IHN0b3JhZ2Uuc2FuZGJveC51cGRhdGUoe1xuICAgICAgICAgICAgaWQsXG4gICAgICAgICAgICBhY3F1aXJpbmdMb2NrSWQ6IG51bGwsXG4gICAgICAgICAgICBhY3F1aXJpbmdMb2NrQXQ6IG51bGwsXG4gICAgICAgICAgICBwcm92aWRlck1ldGFkYXRhOiB7XG4gICAgICAgICAgICAgIHByb3ZpZGVyOiBcInZlcmNlbFwiLFxuICAgICAgICAgICAgICBzYW5kYm94SWQ6IG51bGwsXG4gICAgICAgICAgICAgIHNuYXBzaG90SWQ6IHNuYXBzaG90LnNuYXBzaG90SWQsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0pO1xuICAgICAgICAgIHJldHVybiB7IHNuYXBzaG90SWQ6IHNuYXBzaG90LnNuYXBzaG90SWQgfTtcbiAgICAgICAgfSxcbiAgICAgICAgY2F0Y2g6IChlKSA9PiBuZXcgU2FuZGJveEVycm9yKHsgcmVhc29uOiBTdHJpbmcoZSksIGNhdXNlOiBlIH0pLFxuICAgICAgfSk7XG4gICAgfSxcblxuICAgIHN0b3A6IGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IHNhbmRib3ggPSBhd2FpdCBnZXRTYW5kYm94KCk7XG4gICAgICBpZiAoc2FuZGJveCBpbnN0YW5jZW9mIEVycm9yKSB7XG4gICAgICAgIHJldHVybiBzYW5kYm94O1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gZXJyb3JlLnRyeUFzeW5jKHtcbiAgICAgICAgdHJ5OiBhc3luYyAoKSA9PiB7XG4gICAgICAgICAgYXdhaXQgc2FuZGJveC5zdG9wKCk7XG4gICAgICAgICAgYXdhaXQgc3RvcmFnZS5zYW5kYm94LnVwZGF0ZSh7XG4gICAgICAgICAgICBpZCxcbiAgICAgICAgICAgIGFjcXVpcmluZ0xvY2tJZDogbnVsbCxcbiAgICAgICAgICAgIGFjcXVpcmluZ0xvY2tBdDogbnVsbCxcbiAgICAgICAgICAgIHByb3ZpZGVyTWV0YWRhdGE6IHtcbiAgICAgICAgICAgICAgcHJvdmlkZXI6IFwidmVyY2VsXCIsXG4gICAgICAgICAgICAgIHNhbmRib3hJZDogbnVsbCxcbiAgICAgICAgICAgICAgc25hcHNob3RJZDogbnVsbCxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSk7XG4gICAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgICAgfSxcbiAgICAgICAgY2F0Y2g6IChlKSA9PiBuZXcgU2FuZGJveEVycm9yKHsgcmVhc29uOiBTdHJpbmcoZSksIGNhdXNlOiBlIH0pLFxuICAgICAgfSk7XG4gICAgfSxcblxuICAgIGdldFN0YXR1czogYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3Qgc2FuZGJveCA9IGF3YWl0IGdldFNhbmRib3goKTtcbiAgICAgIGlmIChzYW5kYm94IGluc3RhbmNlb2YgRXJyb3IpIHtcbiAgICAgICAgcmV0dXJuIHNhbmRib3g7XG4gICAgICB9XG4gICAgICByZXR1cm4gc2FuZGJveC5zdGF0dXMgYXMgU2FuZGJveFN0YXR1cztcbiAgICB9LFxuXG4gICAgZ2V0Q3JlYXRlZEF0OiBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCBzYW5kYm94ID0gYXdhaXQgZ2V0U2FuZGJveCgpO1xuICAgICAgaWYgKHNhbmRib3ggaW5zdGFuY2VvZiBFcnJvcikge1xuICAgICAgICByZXR1cm4gc2FuZGJveDtcbiAgICAgIH1cbiAgICAgIHJldHVybiBzYW5kYm94LmNyZWF0ZWRBdDtcbiAgICB9LFxuXG4gICAgZ2V0UmVtYWluaW5nVGltZW91dDogYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3Qgc2FuZGJveCA9IGF3YWl0IGdldFNhbmRib3goKTtcbiAgICAgIGlmIChzYW5kYm94IGluc3RhbmNlb2YgRXJyb3IpIHtcbiAgICAgICAgcmV0dXJuIHNhbmRib3g7XG4gICAgICB9XG4gICAgICByZXR1cm4gc2FuZGJveC50aW1lb3V0O1xuICAgIH0sXG4gIH07XG5cbiAgYXN5bmMgZnVuY3Rpb24gZG9FeGVjKG9wdHM6IHtcbiAgICBjb21tYW5kOiBzdHJpbmc7XG4gICAgYXJncz86IHN0cmluZ1tdO1xuICAgIHNpZ25hbD86IEFib3J0U2lnbmFsO1xuICB9KSB7XG4gICAgY29uc3QgaW5zdGFuY2UgPSBhd2FpdCBnZXRTYW5kYm94KCk7XG4gICAgaWYgKGluc3RhbmNlIGluc3RhbmNlb2YgRXJyb3IpIHtcbiAgICAgIHJldHVybiBpbnN0YW5jZTtcbiAgICB9XG5cbiAgICBjb25zdCB1cGRhdGVQcm9taXNlID0gdXBkYXRlTGFzdEFjdGl2aXR5KCk7XG4gICAgY29uc3QgZXhlY1Jlc3VsdCA9IGF3YWl0IGV4ZWNPbkluc3RhbmNlKGluc3RhbmNlLCBvcHRzKTtcbiAgICBhd2FpdCB1cGRhdGVQcm9taXNlO1xuICAgIHJldHVybiBleGVjUmVzdWx0O1xuICB9XG5cbiAgY29uc3Qgc2FuZGJveDogU2FuZGJveDxUVGFncz4gJiB7XG4gICAgX29uUmVhZHk/OiBQcm9taXNlPHZvaWQ+O1xuICAgIF9zZXR1cE1ldGE/OiBQcm9taXNlPFNhbmRib3hTZXR1cE1ldGE+O1xuICB9ID0ge1xuICAgIGlkLFxuICAgIGNvbmZpZyxcbiAgICBleGVjOiBhc3luYyAob3B0cykgPT4ge1xuICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgZG9FeGVjKG9wdHMpO1xuXG4gICAgICBpZiAocmVzdWx0IGluc3RhbmNlb2YgU2FuZGJveEVycm9yICYmIGlzU2FuZGJveEdvbmVFcnJvcihyZXN1bHQuY2F1c2UpKSB7XG4gICAgICAgIGF3YWl0IHJlY292ZXJGcm9tU3RhbGVTYW5kYm94KCk7XG4gICAgICAgIHJldHVybiBhd2FpdCBkb0V4ZWMob3B0cyk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfSxcblxuICAgIGdldERvbWFpbjogYXN5bmMgKHBvcnQpID0+IHtcbiAgICAgIGNvbnN0IHNhbmRib3ggPSBhd2FpdCBnZXRTYW5kYm94KCk7XG4gICAgICBpZiAoc2FuZGJveCBpbnN0YW5jZW9mIEVycm9yKSB7XG4gICAgICAgIHJldHVybiBzYW5kYm94O1xuICAgICAgfVxuXG4gICAgICB0cnkge1xuICAgICAgICByZXR1cm4gc2FuZGJveC5kb21haW4ocG9ydCk7XG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIHJldHVybiBuZXcgU2FuZGJveEVycm9yKHsgcmVhc29uOiBTdHJpbmcoZSksIGNhdXNlOiBlIH0pO1xuICAgICAgfVxuICAgIH0sXG5cbiAgICBraWxsOiBhc3luYyAoeyBjb21tYW5kSWQsIHN0b3JhZ2U6IGNtZFN0b3JhZ2UgfSkgPT4ge1xuICAgICAgY29uc3QgaW5zdGFuY2UgPSBhd2FpdCBnZXRTYW5kYm94KCk7XG4gICAgICBpZiAoaW5zdGFuY2UgaW5zdGFuY2VvZiBFcnJvcikge1xuICAgICAgICByZXR1cm4gaW5zdGFuY2U7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGNtZCA9IGF3YWl0IGNtZFN0b3JhZ2UuY29tbWFuZC5nZXQoY29tbWFuZElkKTtcbiAgICAgIGlmIChjbWQgaW5zdGFuY2VvZiBFcnJvcikge1xuICAgICAgICByZXR1cm4gbmV3IFNhbmRib3hFcnJvcih7IHJlYXNvbjogY21kLm1lc3NhZ2UsIGNhdXNlOiBjbWQgfSk7XG4gICAgICB9XG4gICAgICBpZiAoY21kICYmIGNtZC5zdGF0dXMgPT09IFwicnVubmluZ1wiKSB7XG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGNtZFN0b3JhZ2UuY29tbWFuZC5zZXQoe1xuICAgICAgICAgIC4uLmNtZCxcbiAgICAgICAgICBzdGF0dXM6IFwia2lsbGVkXCIsXG4gICAgICAgIH0pO1xuICAgICAgICBpZiAocmVzdWx0IGluc3RhbmNlb2YgRXJyb3IpIHtcbiAgICAgICAgICByZXR1cm4gbmV3IFNhbmRib3hFcnJvcih7IHJlYXNvbjogcmVzdWx0Lm1lc3NhZ2UsIGNhdXNlOiByZXN1bHQgfSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfSxcblxuICAgIHJlYWRGaWxlOiBhc3luYyAob3B0cykgPT4ge1xuICAgICAgY29uc3QgaW5zdGFuY2UgPSBhd2FpdCBnZXRTYW5kYm94KCk7XG4gICAgICBpZiAoaW5zdGFuY2UgaW5zdGFuY2VvZiBFcnJvcikge1xuICAgICAgICByZXR1cm4gaW5zdGFuY2U7XG4gICAgICB9XG4gICAgICByZXR1cm4gcmVhZEZpbGVPbkluc3RhbmNlKGluc3RhbmNlLCBvcHRzKTtcbiAgICB9LFxuXG4gICAgd3JpdGVGaWxlczogYXN5bmMgKG9wdHMpID0+IHtcbiAgICAgIGNvbnN0IGluc3RhbmNlID0gYXdhaXQgZ2V0U2FuZGJveCgpO1xuICAgICAgaWYgKGluc3RhbmNlIGluc3RhbmNlb2YgRXJyb3IpIHtcbiAgICAgICAgdGhyb3cgaW5zdGFuY2U7XG4gICAgICB9XG4gICAgICByZXR1cm4gd3JpdGVGaWxlc09uSW5zdGFuY2UoaW5zdGFuY2UsIG9wdHMpO1xuICAgIH0sXG5cbiAgICBsaWZlY3ljbGUsXG5cbiAgICB1cGRhdGVOZXR3b3JrUG9saWN5OiBhc3luYyAocG9saWN5KSA9PiB7XG4gICAgICBjb25zdCBpbnN0YW5jZSA9IGF3YWl0IGdldFNhbmRib3goKTtcbiAgICAgIGlmIChpbnN0YW5jZSBpbnN0YW5jZW9mIEVycm9yKSB7XG4gICAgICAgIHJldHVybiBpbnN0YW5jZTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBlcnJvcmUudHJ5QXN5bmMoe1xuICAgICAgICB0cnk6ICgpID0+IGluc3RhbmNlLnVwZGF0ZU5ldHdvcmtQb2xpY3kocG9saWN5KSxcbiAgICAgICAgY2F0Y2g6IChlKSA9PiBuZXcgU2FuZGJveEVycm9yKHsgcmVhc29uOiBTdHJpbmcoZSksIGNhdXNlOiBlIH0pLFxuICAgICAgfSk7XG4gICAgfSxcblxuICAgIHRhZzoge1xuICAgICAgbGlzdDogYXN5bmMgKCkgPT4ge1xuICAgICAgICBjb25zdCBzYW5kYm94UmVjb3JkID0gYXdhaXQgc3RvcmFnZS5zYW5kYm94LmdldChpZCk7XG4gICAgICAgIGlmIChzYW5kYm94UmVjb3JkIGluc3RhbmNlb2YgRXJyb3IpIHtcbiAgICAgICAgICByZXR1cm4gc2FuZGJveFJlY29yZDtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gKHNhbmRib3hSZWNvcmQudGFncyA/PyB7fSkgYXMgVFRhZ3M7XG4gICAgICB9LFxuICAgICAgZ2V0OiBhc3luYyAoa2V5OiBzdHJpbmcpID0+IHtcbiAgICAgICAgY29uc3Qgc2FuZGJveFJlY29yZCA9IGF3YWl0IHN0b3JhZ2Uuc2FuZGJveC5nZXQoaWQpO1xuICAgICAgICBpZiAoc2FuZGJveFJlY29yZCBpbnN0YW5jZW9mIEVycm9yKSB7XG4gICAgICAgICAgcmV0dXJuIHNhbmRib3hSZWNvcmQ7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHNhbmRib3hSZWNvcmQudGFncz8uW2tleSBhcyBzdHJpbmddIGFzXG4gICAgICAgICAgfCBUVGFnc1t0eXBlb2Yga2V5XVxuICAgICAgICAgIHwgdW5kZWZpbmVkO1xuICAgICAgfSxcbiAgICAgIHNldDogYXN5bmMgKGtleTogc3RyaW5nLCB2YWx1ZTogdW5rbm93bikgPT4ge1xuICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBzdG9yYWdlLnNhbmRib3gudGFnLnNldCh7XG4gICAgICAgICAgc2FuZGJveElkOiBpZCxcbiAgICAgICAgICB0YWdzOiB7IFtrZXldOiB2YWx1ZSB9IGFzIFJlY29yZDxzdHJpbmcsIHVua25vd24+LFxuICAgICAgICB9KTtcbiAgICAgICAgaWYgKHJlc3VsdCBpbnN0YW5jZW9mIEVycm9yKSB7XG4gICAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgfSxcbiAgICAgIHNldE1hbnk6IGFzeW5jICh0YWdzOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPikgPT4ge1xuICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBzdG9yYWdlLnNhbmRib3gudGFnLnNldCh7XG4gICAgICAgICAgc2FuZGJveElkOiBpZCxcbiAgICAgICAgICB0YWdzOiB0YWdzIGFzIFJlY29yZDxzdHJpbmcsIHVua25vd24+LFxuICAgICAgICB9KTtcbiAgICAgICAgaWYgKHJlc3VsdCBpbnN0YW5jZW9mIEVycm9yKSB7XG4gICAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgfSxcbiAgICB9LFxuICB9O1xuXG4gIGxldCBvblJlYWR5UHJvbWlzZTogUHJvbWlzZTx2b2lkPiA9IFByb21pc2UucmVzb2x2ZSgpO1xuICBsZXQgc2V0dXBNZXRhUHJvbWlzZTogUHJvbWlzZTxTYW5kYm94U2V0dXBNZXRhPiA9IFByb21pc2UucmVzb2x2ZSh7XG4gICAgbmVlZHNTZXR1cFJ1bjogZmFsc2UsXG4gICAgY3JlYXRlZEZyb21TbmFwc2hvdDogZmFsc2UsXG4gIH0pO1xuXG4gIGlmIChjb25maWcubGlmZWN5Y2xlPy5hdXRvU3RhcnQgIT09IGZhbHNlKSB7XG4gICAgc2FuZGJveFByb21pc2UgPSBkb0dldFNhbmRib3goKTtcblxuICAgIC8vIFJlc29sdmUgc2V0dXAgbWV0YWRhdGEgYXMgc29vbiBhcyB0aGUgc2FuZGJveCBpbnN0YW5jZSBpcyByZWFkeVxuICAgIC8vIChiZWZvcmUgX29uUmVhZHkgcnVucyBzZXR1cCkuIFRoZSB3b3JrZmxvdyByZWFkcyB0aGlzIHRvIGNob29zZSB0aGUgc3RhdHVzIGluZGljYXRvci5cbiAgICBzZXR1cE1ldGFQcm9taXNlID0gc2FuZGJveFByb21pc2UudGhlbigoKSA9PiAoe1xuICAgICAgbmVlZHNTZXR1cFJ1bixcbiAgICAgIGNyZWF0ZWRGcm9tU25hcHNob3QsXG4gICAgfSkpO1xuXG4gICAgLy8gQWZ0ZXIgc2FuZGJveCBpbnN0YW5jZSBpcyByZWFkeSwgcnVuIHNldHVwIGFuZC9vciBvblJlc3RhcnQuXG4gICAgLy8gc2FuZGJveFByb21pc2UgaXMgYWxyZWFkeSByZXNvbHZlZCBieSB0aGUgdGltZSAudGhlbigpIHJ1bnMsXG4gICAgLy8gc28gc2V0dXAucnVuIC8gb25SZXN0YXJ0IGNhbGxpbmcgc2FuZGJveC5leGVjKCkgd29uJ3QgZGVhZGxvY2suXG4gICAgb25SZWFkeVByb21pc2UgPSBzYW5kYm94UHJvbWlzZS50aGVuKGFzeW5jIChpbnN0YW5jZSkgPT4ge1xuICAgICAgaWYgKGluc3RhbmNlIGluc3RhbmNlb2YgRXJyb3IpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBpZiAobmVlZHNTZXR1cFJ1biAmJiBzZXR1cCkge1xuICAgICAgICBkZWJ1ZyhcbiAgICAgICAgICBgW3NhbmRib3g6c2V0dXBdIHJ1bm5pbmcgc2V0dXAucnVuIG9uIHNlc3Npb24gc2FuZGJveCAoa2V5PVwiJHtzZXR1cC5rZXl9XCIpYFxuICAgICAgICApO1xuICAgICAgICBhd2FpdCBzZXR1cC5ydW4oc2FuZGJveCk7XG4gICAgICAgIGRlYnVnKFwiW3NhbmRib3g6c2V0dXBdIHNldHVwLnJ1biBjb21wbGV0ZSBvbiBzZXNzaW9uIHNhbmRib3hcIik7XG4gICAgICB9XG5cbiAgICAgIGlmIChjcmVhdGVkRnJvbVNuYXBzaG90ICYmIG9uUmVzdGFydCkge1xuICAgICAgICBkZWJ1ZyhcIltzYW5kYm94OnNldHVwXSBydW5uaW5nIG9uUmVzdGFydCAoY3JlYXRlZCBmcm9tIHNuYXBzaG90KVwiKTtcbiAgICAgICAgYXdhaXQgb25SZXN0YXJ0KHNhbmRib3gpO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgc2FuZGJveC5fb25SZWFkeSA9IG9uUmVhZHlQcm9taXNlO1xuICBzYW5kYm94Ll9zZXR1cE1ldGEgPSBzZXR1cE1ldGFQcm9taXNlO1xuICByZXR1cm4gc2FuZGJveDtcbn07XG4iLCAiaW1wb3J0IHR5cGUgeyBUYWdzU2NoZW1hIH0gZnJvbSBcIi4uL2luZGV4XCI7XG5pbXBvcnQgdHlwZSB7IFJwY0ZuLCBTYW5kYm94UmVjb3JkLCBTdG9yYWdlLCBTdG9yYWdlQ29uZmlnIH0gZnJvbSBcIi4uL3N0b3JhZ2VcIjtcbmltcG9ydCB7IGRlYnVnIH0gZnJvbSBcIi4uL3V0aWxzL2RlYnVnXCI7XG5pbXBvcnQgeyBsb2NhbFNhbmRib3ggfSBmcm9tIFwiLi9iaW5kaW5ncy9sb2NhbFwiO1xuaW1wb3J0IHsgdmVyY2VsU2FuZGJveCB9IGZyb20gXCIuL2JpbmRpbmdzL3ZlcmNlbFwiO1xuaW1wb3J0IHR5cGUgeyBPblJlc3RhcnQsIFNhbmRib3gsIFNhbmRib3hTZXR1cCB9IGZyb20gXCIuL3R5cGVzXCI7XG5cbi8qKlxuICogTWV0YWRhdGEgYWJvdXQgaG93IHRoZSBzYW5kYm94IHdhcyBzZXQgdXAuXG4gKiBVc2VkIGJ5IHRoZSB3b3JrZmxvdyB0byBlbWl0IHRoZSBjb3JyZWN0IHN0YXR1cyBpbmRpY2F0b3IuXG4gKiBSZXR1cm5lZCBhcyBhIHByb21pc2UgYmVjYXVzZSB0aGUgbWV0YWRhdGEgaXMgZGV0ZXJtaW5lZCBhc3luY2hyb25vdXNseVxuICogZHVyaW5nIHNhbmRib3ggY3JlYXRpb24sIGJlZm9yZSBfb25SZWFkeSBydW5zIHNldHVwLlxuICovXG5leHBvcnQgdHlwZSBTYW5kYm94U2V0dXBNZXRhID0ge1xuICAvKiogV2hldGhlciBzZXR1cC5ydW4oKSBuZWVkcyB0byBleGVjdXRlIChjb2xkIHN0YXJ0LCBubyBzbmFwc2hvdCkuICovXG4gIG5lZWRzU2V0dXBSdW46IGJvb2xlYW47XG4gIC8qKiBXaGV0aGVyIHRoZSBzYW5kYm94IHdhcyBjcmVhdGVkIGZyb20gYSBzbmFwc2hvdC4gKi9cbiAgY3JlYXRlZEZyb21TbmFwc2hvdDogYm9vbGVhbjtcbn07XG5cbnR5cGUgU2FuZGJveFdpdGhNZXRhPFRUYWdzIGV4dGVuZHMgVGFnc1NjaGVtYSA9IFRhZ3NTY2hlbWE+ID0gU2FuZGJveDxUVGFncz4gJiB7XG4gIF9vblJlYWR5PzogUHJvbWlzZTx2b2lkPjtcbiAgX3NldHVwTWV0YT86IFByb21pc2U8U2FuZGJveFNldHVwTWV0YT47XG59O1xuXG4vKipcbiAqIE1vZHVsZS1sZXZlbCBjYWNoZSBmb3Igc2FuZGJveCBpbnN0YW5jZXMga2V5ZWQgYnkgc2FuZGJveCByZWNvcmQgSUQuXG4gKlxuICogQ2FjaGVzIGFsbCBzYW5kYm94IGluc3RhbmNlcyBzbyB0aGF0IHRoZSB3b3JrZmxvdyAod2hpY2ggY2FsbHMgZ2V0U2FuZGJveFxuICogd2l0aG91dCBzZXR1cC9vblJlc3RhcnQpIHJldXNlcyB0aGUgc2FtZSBpbnN0YW5jZSBjcmVhdGVkIGR1cmluZyBzZXNzaW9uKCksXG4gKiBpbmNsdWRpbmcgaXRzIF9vblJlYWR5IHByb21pc2UgYW5kIHNldHVwIG1ldGFkYXRhLlxuICovXG5jb25zdCBzYW5kYm94Q2FjaGUgPSBuZXcgTWFwPHN0cmluZywgU2FuZGJveFdpdGhNZXRhPigpO1xuXG5leHBvcnQgZnVuY3Rpb24gZ2V0U2FuZGJveDxUVGFncyBleHRlbmRzIFRhZ3NTY2hlbWEgPSBUYWdzU2NoZW1hPih7XG4gIHNhbmRib3hSZWNvcmQsXG4gIHN0b3JhZ2VDb25maWcsXG4gIHN0b3JhZ2UsXG4gIHJwYyxcbiAgZW5hYmxlTGlmZWN5Y2xlV29ya2Zsb3cgPSB0cnVlLFxuICBzZXR1cCxcbiAgb25SZXN0YXJ0LFxufToge1xuICBzdG9yYWdlQ29uZmlnOiBTdG9yYWdlQ29uZmlnO1xuICBzYW5kYm94UmVjb3JkOiBTYW5kYm94UmVjb3JkO1xuICBzdG9yYWdlOiBTdG9yYWdlO1xuICBycGM6IFJwY0ZuO1xuICBlbmFibGVMaWZlY3ljbGVXb3JrZmxvdz86IGJvb2xlYW47XG4gIHNldHVwPzogU2FuZGJveFNldHVwO1xuICBvblJlc3RhcnQ/OiBPblJlc3RhcnQ7XG59KTogU2FuZGJveFdpdGhNZXRhPFRUYWdzPiB7XG4gIGNvbnN0IGNhY2hlZCA9IHNhbmRib3hDYWNoZS5nZXQoc2FuZGJveFJlY29yZC5pZCk7XG4gIGlmIChjYWNoZWQpIHtcbiAgICBkZWJ1ZyhcIltnZXRTYW5kYm94XSBjYWNoZSBoaXQgZm9yXCIsIHNhbmRib3hSZWNvcmQuaWQpO1xuICAgIHJldHVybiBjYWNoZWQgYXMgU2FuZGJveFdpdGhNZXRhPFRUYWdzPjtcbiAgfVxuXG4gIGNvbnN0IHNieCA9IGNyZWF0ZVNhbmRib3g8VFRhZ3M+KHtcbiAgICBzYW5kYm94UmVjb3JkLFxuICAgIHN0b3JhZ2VDb25maWcsXG4gICAgc3RvcmFnZSxcbiAgICBycGMsXG4gICAgZW5hYmxlTGlmZWN5Y2xlV29ya2Zsb3csXG4gICAgc2V0dXAsXG4gICAgb25SZXN0YXJ0LFxuICB9KTtcblxuICBzYW5kYm94Q2FjaGUuc2V0KHNhbmRib3hSZWNvcmQuaWQsIHNieCBhcyBTYW5kYm94V2l0aE1ldGEpO1xuXG4gIHJldHVybiBzYng7XG59XG5cbmZ1bmN0aW9uIGNyZWF0ZVNhbmRib3g8VFRhZ3MgZXh0ZW5kcyBUYWdzU2NoZW1hID0gVGFnc1NjaGVtYT4oe1xuICBzYW5kYm94UmVjb3JkLFxuICBzdG9yYWdlQ29uZmlnLFxuICBzdG9yYWdlLFxuICBycGMsXG4gIGVuYWJsZUxpZmVjeWNsZVdvcmtmbG93ID0gdHJ1ZSxcbiAgc2V0dXAsXG4gIG9uUmVzdGFydCxcbn06IHtcbiAgc3RvcmFnZUNvbmZpZzogU3RvcmFnZUNvbmZpZztcbiAgc2FuZGJveFJlY29yZDogU2FuZGJveFJlY29yZDtcbiAgc3RvcmFnZTogU3RvcmFnZTtcbiAgcnBjOiBScGNGbjtcbiAgZW5hYmxlTGlmZWN5Y2xlV29ya2Zsb3c/OiBib29sZWFuO1xuICBzZXR1cD86IFNhbmRib3hTZXR1cDtcbiAgb25SZXN0YXJ0PzogT25SZXN0YXJ0O1xufSk6IFNhbmRib3hXaXRoTWV0YTxUVGFncz4ge1xuICBsZXQgc2J4OiBTYW5kYm94V2l0aE1ldGE8VFRhZ3M+O1xuXG4gIHN3aXRjaCAoc2FuZGJveFJlY29yZC5jb25maWcudHlwZSkge1xuICAgIGNhc2UgXCJsb2NhbFwiOlxuICAgICAgc2J4ID0gbG9jYWxTYW5kYm94PFRUYWdzPih7XG4gICAgICAgIHNhbmRib3hSZWNvcmQ6IHNhbmRib3hSZWNvcmQgYXMgU2FuZGJveFJlY29yZCAmIHtcbiAgICAgICAgICBjb25maWc6IHsgdHlwZTogXCJsb2NhbFwiIH07XG4gICAgICAgIH0sXG4gICAgICAgIHN0b3JhZ2UsXG4gICAgICAgIHNldHVwLFxuICAgICAgICBvblJlc3RhcnQsXG4gICAgICB9KTtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgXCJ2ZXJjZWxcIjpcbiAgICAgIHNieCA9IHZlcmNlbFNhbmRib3g8VFRhZ3M+KHtcbiAgICAgICAgc2FuZGJveFJlY29yZDogc2FuZGJveFJlY29yZCBhcyBTYW5kYm94UmVjb3JkICYge1xuICAgICAgICAgIGNvbmZpZzogeyB0eXBlOiBcInZlcmNlbFwiIH07XG4gICAgICAgIH0sXG4gICAgICAgIHN0b3JhZ2VDb25maWcsXG4gICAgICAgIHN0b3JhZ2UsXG4gICAgICAgIHJwYyxcbiAgICAgICAgZW5hYmxlTGlmZWN5Y2xlV29ya2Zsb3csXG4gICAgICAgIHNldHVwLFxuICAgICAgICBvblJlc3RhcnQsXG4gICAgICB9KTtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgXCJjdXN0b21cIjpcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIkN1c3RvbSBzYW5kYm94ZXMgYXJlIG5vdCBzdXBwb3J0ZWRcIik7XG4gICAgZGVmYXVsdDpcbiAgICAgIHNhbmRib3hSZWNvcmQuY29uZmlnIHNhdGlzZmllcyBuZXZlcjtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgYFVua25vd24gc2FuZGJveCB0eXBlOiAke1xuICAgICAgICAgIC8vIGJpb21lLWlnbm9yZSBsaW50L3N1c3BpY2lvdXMvbm9FeHBsaWNpdEFueTogLlxuICAgICAgICAgIChzYW5kYm94UmVjb3JkLmNvbmZpZyBhcyBhbnkpLnR5cGVcbiAgICAgICAgfWBcbiAgICAgICk7XG4gIH1cblxuICAvLyBEb24ndCBhd2FpdCBfb25SZWFkeSBoZXJlIFx1MjAxNCBsZXQgdGhlIHdvcmtmbG93IGF3YWl0IGl0IHNvIGl0IGNhbiBlbWl0XG4gIC8vIHN0YXR1cyBpbmRpY2F0b3JzIG92ZXIgdGhlIHN0cmVhbSB3aGlsZSBzZXR1cCBydW5zLlxuICAvLyBJbnN0ZWFkLCB3cmFwIHNhbmRib3ggbWV0aG9kcyBzbyBhbnkgb3BlcmF0aW9uIG9uIHRoZSBzYW5kYm94IGltcGxpY2l0bHlcbiAgLy8gd2FpdHMgZm9yIHNldHVwIHRvIGNvbXBsZXRlLiBXZSByZXR1cm4gYSBORVcgb2JqZWN0IHNvIHRoYXQgc2V0dXAucnVuKCksXG4gIC8vIHdoaWNoIGhvbGRzIHRoZSBvcmlnaW5hbCBgc2J4YCB2aWEgY2xvc3VyZSwgY2FsbHMgdW53cmFwcGVkIG1ldGhvZHMgYW5kXG4gIC8vIGF2b2lkcyBhIGRlYWRsb2NrLlxuICBpZiAoIXNieC5fb25SZWFkeSkge1xuICAgIHJldHVybiBzYng7XG4gIH1cblxuICBjb25zdCBvblJlYWR5ID0gc2J4Ll9vblJlYWR5O1xuICByZXR1cm4ge1xuICAgIC4uLnNieCxcbiAgICBleGVjOiBhc3luYyAob3B0cykgPT4ge1xuICAgICAgYXdhaXQgb25SZWFkeTtcbiAgICAgIHJldHVybiBzYnguZXhlYyhvcHRzKTtcbiAgICB9LFxuICAgIGdldERvbWFpbjogYXN5bmMgKHBvcnQpID0+IHtcbiAgICAgIGF3YWl0IG9uUmVhZHk7XG4gICAgICByZXR1cm4gc2J4LmdldERvbWFpbihwb3J0KTtcbiAgICB9LFxuICAgIHJlYWRGaWxlOiBhc3luYyAob3B0cykgPT4ge1xuICAgICAgYXdhaXQgb25SZWFkeTtcbiAgICAgIHJldHVybiBzYngucmVhZEZpbGUob3B0cyk7XG4gICAgfSxcbiAgICB3cml0ZUZpbGVzOiBhc3luYyAob3B0cykgPT4ge1xuICAgICAgYXdhaXQgb25SZWFkeTtcbiAgICAgIHJldHVybiBzYngud3JpdGVGaWxlcyhvcHRzKTtcbiAgICB9LFxuICB9O1xufVxuIl0sCiAgIm1hcHBpbmdzIjogIjs7Ozs7Ozs7O0FBQUEsSUFBTSxVQUNKLFFBQVEsSUFBSSxnQkFBZ0IsT0FBTyxRQUFRLElBQUksZ0JBQWdCO0FBRTFELFNBQVMsU0FBUyxNQUFpQjtBQUN4QyxNQUFJLFNBQVM7QUFDWCxZQUFRLElBQUksR0FBRyxJQUFJO0FBQUEsRUFDckI7QUFDRjs7O0FDTkEsU0FBUyxhQUFhO0FBQ3RCLFlBQVksUUFBUTtBQUNwQixZQUFZQSxXQUFVO0FBQ3RCLFlBQVksWUFBWTtBQUN4QixTQUFTLFlBQVk7OztBQ0xyQixZQUFZLFVBQVU7QUFJdEIsSUFBTSxjQUFjO0FBQ3BCLElBQU0sZ0JBQWdCO0FBT3RCLGVBQWUsWUFDYixTQUNBLE1BQ0EsWUFDK0Q7QUFDL0QsV0FBUyxVQUFVLEtBQUssV0FBVztBQUNqQyxVQUFNLGFBQWEsTUFBTSxRQUFRLEtBQUssSUFBSTtBQUMxQyxRQUFJLHNCQUFzQixPQUFPO0FBQy9CLFlBQU07QUFBQSxJQUNSO0FBQ0EsVUFBTSxTQUFTLE1BQU0sV0FBVztBQUNoQyxR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QUFBLFFBQ0E7QUFBQSxRQUNBO0FBQUEsUUFDQTtBQUFBLFFBQ0E7QUFBQSxRQUNBO0FBQUEsTUFDRixDQUFDO0FBQ0Q7QUFBQSxJQUNGLEtBQUs7QUFDSCxZQUFNLElBQUksTUFBTSxvQ0FBb0M7QUFBQSxJQUN0RDtBQUNFLG9CQUFjO0FBQ2QsWUFBTSxJQUFJO0FBQUEsUUFDUjtBQUFBLFFBRUcsY0FBYyxPQUFlLElBQ2hDO0FBQUEsTUFDRjtBQUFBLEVBQ0o7QUFRQSxNQUFJLENBQUMsSUFBSSxVQUFVO0FBQ2pCLFdBQU87QUFBQSxFQUNUO0FBRUEsUUFBTSxVQUFVLElBQUk7QUFDcEIsU0FBTztBQUFBLElBQ0wsR0FBRztBQUFBLElBQ0gsTUFBTSxPQUFPLFNBQVM7QUFDcEIsWUFBTTtBQUNOLGFBQU8sSUFBSSxLQUFLLElBQUk7QUFBQSxJQUN0QjtBQUFBLElBQ0EsV0FBVyxPQUFPLFNBQVM7QUFDekIsWUFBTTtBQUNOLGFBQU8sSUFBSSxVQUFVLElBQUk7QUFBQSxJQUMzQjtBQUFBLElBQ0EsVUFBVSxPQUFPLFNBQVM7QUFDeEIsWUFBTTtBQUNOLGFBQU8sSUFBSSxTQUFTLElBQUk7QUFBQSxJQUMxQjtBQUFBLElBQ0EsWUFBWSxPQUFPLFNBQVM7QUFDMUIsWUFBTTtBQUNOLGFBQU8sSUFBSSxXQUFXLElBQUk7QUFBQSxJQUM1QjtBQUFBLEVBQ0Y7QUFDRjsiLAogICJuYW1lcyI6IFsicGF0aCIsICJyZXN1bHQiLCAic3RvcmFnZSIsICJzYW5kYm94UmVjb3JkIiwgInBhdGgiLCAiZXJyb3JlIiwgInNhbmRib3giLCAicGF0aCIsICJzbmFwc2hvdElkIiwgImdldFNhbmRib3giLCAic2FuZGJveFJlY29yZCJdCn0K