experimental-agent 0.2.0 → 0.2.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.
@@ -1,1287 +0,0 @@
1
- import {
2
- dockerSandbox,
3
- markSetupComplete,
4
- pollForSetupCompletion,
5
- resetSetupState,
6
- writeFiles
7
- } from "./chunk-ZIAHPXOJ.mjs";
8
- import {
9
- createLogger
10
- } from "./chunk-OZZVS6L5.mjs";
11
- import {
12
- sandboxLifecycleWorkflow
13
- } from "./chunk-NXDVNJRS.mjs";
14
- import {
15
- getStorage
16
- } from "./chunk-TGNVXSMX.mjs";
17
- import {
18
- SandboxError,
19
- SandboxNotFoundError
20
- } from "./chunk-YRYXN7W4.mjs";
21
-
22
- // src/sandbox/bindings/local.ts
23
- import { spawn } from "child_process";
24
- import * as fs from "fs/promises";
25
- import * as path from "path";
26
- import * as errore from "errore";
27
- import { ulid } from "ulid";
28
- var localSandbox = ({
29
- sandboxRecord,
30
- storage,
31
- setup,
32
- onRestart
33
- }) => {
34
- const config = sandboxRecord.config;
35
- const basePath = config.cwd ?? process.cwd();
36
- const processes = /* @__PURE__ */ new Map();
37
- let startPromise = null;
38
- const sandbox = {
39
- id: sandboxRecord.id,
40
- config: sandboxRecord.config,
41
- cwd: basePath,
42
- exec: ({ command, args, cwd, env, signal, sudo }) => {
43
- return errore.tryAsync({
44
- try: () => {
45
- const commandId = `command_${ulid()}`;
46
- const finalCmd = sudo ? "sudo" : command;
47
- const finalArgs = sudo ? [command, ...args ?? []] : args ?? [];
48
- const child = spawn(finalCmd, finalArgs, {
49
- cwd: cwd ? path.resolve(basePath, cwd) : basePath,
50
- env: env ? { ...process.env, ...env } : void 0,
51
- signal
52
- });
53
- processes.set(commandId, child);
54
- let stdout = "";
55
- let stderr = "";
56
- const logQueue = [];
57
- let logResolve = null;
58
- let closed = false;
59
- child.stdout.on("data", (data) => {
60
- const str = String(data);
61
- stdout += str;
62
- logQueue.push({ stream: "stdout", data: str });
63
- logResolve?.();
64
- });
65
- child.stderr.on("data", (data) => {
66
- const str = String(data);
67
- stderr += str;
68
- logQueue.push({ stream: "stderr", data: str });
69
- logResolve?.();
70
- });
71
- const result = new Promise((resolve2, reject) => {
72
- child.on("error", (err) => {
73
- processes.delete(commandId);
74
- closed = true;
75
- logResolve?.();
76
- reject(err);
77
- });
78
- child.on("close", (code) => {
79
- processes.delete(commandId);
80
- closed = true;
81
- logResolve?.();
82
- resolve2({ stdout, stderr, exitCode: code ?? 0 });
83
- });
84
- });
85
- async function* logs() {
86
- while (!closed || logQueue.length > 0) {
87
- const entry = logQueue.shift();
88
- if (entry) {
89
- yield entry;
90
- } else if (!closed) {
91
- await new Promise((resolve2) => {
92
- logResolve = resolve2;
93
- });
94
- logResolve = null;
95
- }
96
- }
97
- }
98
- return Promise.resolve({ commandId, logs, result });
99
- },
100
- catch: (e) => new SandboxError({ reason: String(e), cause: e })
101
- });
102
- },
103
- getDomain: (port) => {
104
- return Promise.resolve(`http://localhost:${port}`);
105
- },
106
- kill: async ({ commandId, storage: storage2 }) => {
107
- const child = processes.get(commandId);
108
- if (!child) {
109
- return new SandboxError({
110
- reason: `Command ${commandId} not found or already finished`
111
- });
112
- }
113
- child.kill("SIGTERM");
114
- const cmd = await storage2.command.get(commandId);
115
- if (cmd instanceof Error) {
116
- return new SandboxError({ reason: cmd.message, cause: cmd });
117
- }
118
- if (cmd && cmd.status === "running") {
119
- const result = await storage2.command.set({
120
- ...cmd,
121
- status: "killed"
122
- });
123
- if (result instanceof Error) {
124
- return new SandboxError({ reason: result.message, cause: result });
125
- }
126
- }
127
- },
128
- readFile: async ({ path: filePath }) => {
129
- const fullPath = path.join(basePath, filePath);
130
- try {
131
- return await fs.readFile(fullPath);
132
- } catch (e) {
133
- if (e instanceof Error && "code" in e && e.code === "ENOENT") {
134
- return null;
135
- }
136
- return new SandboxError({ reason: String(e), cause: e });
137
- }
138
- },
139
- writeFiles: (opts) => writeFiles({ sandbox, ...opts }),
140
- updateNetworkPolicy: () => Promise.resolve(
141
- new SandboxError({
142
- reason: "updateNetworkPolicy is only available for Vercel sandboxes"
143
- })
144
- ),
145
- lifecycle: {
146
- start: () => {
147
- if (startPromise) {
148
- return startPromise;
149
- }
150
- startPromise = (async () => {
151
- if (!setup && sandboxRecord.setupKey) {
152
- await pollForSetupCompletion({
153
- storage,
154
- sandboxId: sandboxRecord.id,
155
- setupKey: sandboxRecord.setupKey
156
- });
157
- }
158
- if (setup) {
159
- const existing = await storage.setup.get(setup.key);
160
- if (existing instanceof Error || !existing) {
161
- try {
162
- await setup.run(sandbox);
163
- await storage.setup.set({
164
- key: setup.key,
165
- snapshotId: null,
166
- createdAt: Date.now(),
167
- lastUsedAt: null,
168
- acquiringLockId: null,
169
- acquiringLockAt: null
170
- });
171
- await markSetupComplete({
172
- storage,
173
- sandboxId: sandboxRecord.id,
174
- setupKey: setup.key
175
- });
176
- } catch (e) {
177
- await resetSetupState({
178
- storage,
179
- sandboxId: sandboxRecord.id,
180
- setupKey: setup.key
181
- });
182
- throw e;
183
- }
184
- }
185
- }
186
- if (onRestart) {
187
- await onRestart(sandbox);
188
- }
189
- return void 0;
190
- })().catch((e) => {
191
- startPromise = null;
192
- throw e;
193
- });
194
- return startPromise;
195
- },
196
- snapshot: () => Promise.resolve(
197
- new SandboxError({
198
- reason: "snapshot is not supported for local sandboxes"
199
- })
200
- ),
201
- stop: () => Promise.resolve(
202
- new SandboxError({
203
- reason: "stop is not supported for local sandboxes"
204
- })
205
- ),
206
- getStatus: () => Promise.resolve(
207
- new SandboxError({
208
- reason: "getStatus is not supported for local sandboxes"
209
- })
210
- ),
211
- getCreatedAt: () => Promise.resolve(
212
- new SandboxError({
213
- reason: "getCreatedAt is not supported for local sandboxes"
214
- })
215
- ),
216
- getRemainingTimeout: () => Promise.resolve(
217
- new SandboxError({
218
- reason: "getRemainingTimeout is not supported for local sandboxes"
219
- })
220
- )
221
- },
222
- tag: {
223
- list: async () => {
224
- const sandboxRecord2 = await storage.sandbox.get(sandbox.id);
225
- if (sandboxRecord2 instanceof Error) {
226
- return sandboxRecord2;
227
- }
228
- return sandboxRecord2.tags ?? {};
229
- },
230
- get: async (key) => {
231
- const sandboxRecord2 = await storage.sandbox.get(sandbox.id);
232
- if (sandboxRecord2 instanceof Error) {
233
- return sandboxRecord2;
234
- }
235
- return sandboxRecord2.tags?.[key];
236
- },
237
- set: async (key, value) => {
238
- const result = await storage.sandbox.tag.set({
239
- sandboxId: sandbox.id,
240
- tags: { [key]: value }
241
- });
242
- if (result instanceof Error) {
243
- return result;
244
- }
245
- return void 0;
246
- },
247
- setMany: async (tags) => {
248
- const result = await storage.sandbox.tag.set({
249
- sandboxId: sandbox.id,
250
- tags
251
- });
252
- if (result instanceof Error) {
253
- return result;
254
- }
255
- return void 0;
256
- }
257
- }
258
- };
259
- return sandbox;
260
- };
261
-
262
- // src/sandbox/bindings/vercel.ts
263
- import * as path2 from "path";
264
- import { Sandbox as VercelSandboxSDK } from "@vercel/sandbox";
265
- import * as errore2 from "errore";
266
- import { start } from "workflow/api";
267
- var setupLog = createLogger({ subsystem: "sandbox:setup" });
268
- var VERCEL_MAX_TIMEOUT_MS = 5 * 60 * 60 * 1e3;
269
- var LOCK_TIMEOUT_MS = 5 * 60 * 1e3;
270
- var LOCK_POLL_INTERVAL_MS = 200;
271
- var getTestCredentials = () => process.env.NODE_ENV === "test" ? {
272
- token: process.env.TEST_VERCEL_TOKEN,
273
- teamId: process.env.TEST_VERCEL_TEAM_ID,
274
- projectId: process.env.TEST_VERCEL_PROJECT_ID
275
- } : {};
276
- var createPromises = /* @__PURE__ */ new Map();
277
- var ACTIVITY_THROTTLE_MS = 1e4;
278
- var lastActivitySent = /* @__PURE__ */ new Map();
279
- var DEFAULT_VCPUS = 2;
280
- function isSandboxGoneError(e) {
281
- if (!(e instanceof Error)) {
282
- return false;
283
- }
284
- const errorWithResponse = e;
285
- const errorWithCause = e;
286
- const status = errorWithResponse.response?.status ?? errorWithCause.cause?.response?.status;
287
- if (status === 410 || status === 422) {
288
- return true;
289
- }
290
- const message = e.message || String(e);
291
- if (message.includes("Expected a stream of command data") || message.includes("Expected a stream of logs")) {
292
- return true;
293
- }
294
- return false;
295
- }
296
- var vercelSandbox = ({
297
- sandboxRecord,
298
- storageConfig,
299
- enableLifecycleWorkflow,
300
- storage,
301
- rpc,
302
- setup,
303
- onRestart
304
- }) => {
305
- const { id, config } = sandboxRecord;
306
- const vcpus = config.resources?.vcpus ?? DEFAULT_VCPUS;
307
- const ports = config.ports;
308
- const networkPolicy = config.networkPolicy;
309
- const initialVercel = sandboxRecord.providerMetadata?.provider === "vercel" ? sandboxRecord.providerMetadata : null;
310
- let recoveredFromStale = false;
311
- const HOME_DIR = "/home/vercel-sandbox";
312
- const cwd = config.cwd ?? HOME_DIR;
313
- const pollStorage = getStorage({
314
- config: storageConfig,
315
- rpc: (p) => rpc({ ...p, _quiet: true })
316
- });
317
- async function pollForSandboxId() {
318
- const done = setupLog.time(
319
- "waiting for sandbox lock",
320
- { sandboxId: id },
321
- { logOnStart: true }
322
- );
323
- const deadline = Date.now() + LOCK_TIMEOUT_MS;
324
- while (Date.now() < deadline) {
325
- await new Promise((r) => setTimeout(r, LOCK_POLL_INTERVAL_MS));
326
- const record = await pollStorage.sandbox.get(id);
327
- if (record instanceof Error) {
328
- return new SandboxError({ reason: record.message, cause: record });
329
- }
330
- const vercelSandboxId = record?.providerMetadata?.provider === "vercel" ? record.providerMetadata.sandboxId : null;
331
- if (vercelSandboxId) {
332
- done();
333
- return {
334
- sandboxId: vercelSandboxId,
335
- needsSetupRun: false,
336
- createdFromSnapshot: false
337
- };
338
- }
339
- const lockStale = record?.acquiringLockAt && Date.now() - record.acquiringLockAt >= LOCK_TIMEOUT_MS;
340
- if (!record?.acquiringLockAt || lockStale) {
341
- if (lockStale) {
342
- setupLog.warn("sandbox lock is stale, taking over", {
343
- sandboxId: id,
344
- lockAge: Date.now() - record.acquiringLockAt
345
- });
346
- }
347
- done({ staleLock: !!lockStale });
348
- return doGetOrCreateSandboxId();
349
- }
350
- }
351
- return new SandboxError({
352
- reason: "Timed out waiting for sandbox creation by another process"
353
- });
354
- }
355
- async function startLifecycleWorkflow(vercelSandboxId) {
356
- if (!enableLifecycleWorkflow) {
357
- return;
358
- }
359
- const lifecycleInput = {
360
- id,
361
- vercelSandboxId,
362
- storageConfig,
363
- rpc
364
- };
365
- await start(sandboxLifecycleWorkflow, [{ input: lifecycleInput }]).catch(
366
- // biome-ignore lint/suspicious/noEmptyBlockStatements: intentionally ignored - workflow start is fire-and-forget
367
- () => {
368
- }
369
- );
370
- }
371
- async function createSandboxFromSnapshot(snapshotId) {
372
- return await errore2.tryAsync({
373
- try: async () => {
374
- const sandbox2 = await VercelSandboxSDK.create({
375
- source: { type: "snapshot", snapshotId },
376
- resources: { vcpus },
377
- timeout: VERCEL_MAX_TIMEOUT_MS,
378
- ports,
379
- networkPolicy,
380
- ...getTestCredentials()
381
- });
382
- const now = Date.now();
383
- await storage.sandbox.set({
384
- id,
385
- config,
386
- tags: sandboxRecord.tags,
387
- createdAt: now,
388
- lastActivityAt: now,
389
- acquiringLockId: null,
390
- acquiringLockAt: null,
391
- setupKey: sandboxRecord.setupKey,
392
- providerMetadata: {
393
- provider: "vercel",
394
- sandboxId: sandbox2.sandboxId,
395
- snapshotId
396
- }
397
- });
398
- await startLifecycleWorkflow(sandbox2.sandboxId);
399
- return sandbox2.sandboxId;
400
- },
401
- catch: (e) => new SandboxError({ reason: String(e), cause: e })
402
- });
403
- }
404
- async function createFreshSandbox() {
405
- return await errore2.tryAsync({
406
- try: async () => {
407
- const sandbox2 = await VercelSandboxSDK.create({
408
- resources: { vcpus },
409
- timeout: VERCEL_MAX_TIMEOUT_MS,
410
- ports,
411
- networkPolicy,
412
- ...getTestCredentials()
413
- });
414
- const now = Date.now();
415
- await storage.sandbox.set({
416
- id,
417
- config,
418
- tags: sandboxRecord.tags,
419
- createdAt: now,
420
- lastActivityAt: now,
421
- acquiringLockId: null,
422
- acquiringLockAt: null,
423
- setupKey: sandboxRecord.setupKey,
424
- providerMetadata: {
425
- provider: "vercel",
426
- sandboxId: sandbox2.sandboxId,
427
- snapshotId: null
428
- }
429
- });
430
- await startLifecycleWorkflow(sandbox2.sandboxId);
431
- return sandbox2.sandboxId;
432
- },
433
- catch: (e) => new SandboxError({ reason: String(e), cause: e })
434
- });
435
- }
436
- function execOnInstance(instance, {
437
- command,
438
- args,
439
- cwd: execCwd,
440
- env,
441
- signal,
442
- sudo
443
- }) {
444
- return errore2.tryAsync({
445
- try: async () => {
446
- const finalCmd = sudo ? "sudo" : command;
447
- const finalArgs = sudo ? [command, ...args ?? []] : args;
448
- const output = await instance.runCommand({
449
- cwd: execCwd ?? cwd,
450
- args: finalArgs,
451
- env,
452
- cmd: finalCmd,
453
- signal,
454
- detached: true
455
- });
456
- let stdout = "";
457
- let stderr = "";
458
- const logBuffer = [];
459
- const state = {
460
- resolve: null,
461
- consumed: false
462
- };
463
- const consumeLogs = (async () => {
464
- try {
465
- for await (const log2 of output.logs()) {
466
- const entry = log2.stream === "stdout" ? { stream: "stdout", data: log2.data } : { stream: "stderr", data: log2.data };
467
- if (log2.stream === "stdout") {
468
- stdout += log2.data;
469
- } else {
470
- stderr += log2.data;
471
- }
472
- logBuffer.push(entry);
473
- state.resolve?.();
474
- }
475
- } catch {
476
- }
477
- state.consumed = true;
478
- state.resolve?.();
479
- })();
480
- async function* logs() {
481
- let index = 0;
482
- while (!state.consumed || index < logBuffer.length) {
483
- if (index < logBuffer.length) {
484
- yield logBuffer[index++];
485
- } else {
486
- await new Promise((resolve2) => {
487
- state.resolve = resolve2;
488
- });
489
- state.resolve = null;
490
- }
491
- }
492
- }
493
- const result = consumeLogs.then(async () => {
494
- try {
495
- const finished = await output.wait();
496
- return {
497
- stdout,
498
- stderr,
499
- exitCode: finished.exitCode
500
- };
501
- } catch (e) {
502
- if (isSandboxGoneError(e)) {
503
- return { stdout, stderr, exitCode: 1 };
504
- }
505
- throw e;
506
- }
507
- });
508
- return { commandId: output.cmdId, logs, result };
509
- },
510
- catch: (e) => new SandboxError({ reason: String(e), cause: e })
511
- });
512
- }
513
- function readFileOnInstance(instance, { path: path3 }) {
514
- return errore2.tryAsync({
515
- try: () => instance.readFileToBuffer({ path: path3, cwd }),
516
- catch: (e) => new SandboxError({ reason: String(e), cause: e })
517
- });
518
- }
519
- async function writeFilesOnInstance(instance, opts) {
520
- const { files, destPath } = opts;
521
- if (files.length === 0) {
522
- return;
523
- }
524
- const nativeFiles = files.map((file) => {
525
- const filePath = path2.posix.join(destPath, file.path);
526
- const absolutePath = path2.posix.isAbsolute(filePath) ? filePath : path2.posix.join(cwd, filePath);
527
- return {
528
- path: absolutePath,
529
- content: typeof file.content === "string" ? Buffer.from(file.content) : file.content
530
- };
531
- });
532
- await instance.writeFiles(nativeFiles);
533
- const shellScripts = nativeFiles.filter((f) => f.path.endsWith(".sh"));
534
- if (shellScripts.length > 0) {
535
- const chmodResult = await execOnInstance(instance, {
536
- command: "chmod",
537
- args: ["+x", ...shellScripts.map((f) => f.path)]
538
- });
539
- if (chmodResult instanceof Error) {
540
- throw chmodResult;
541
- }
542
- await chmodResult.result;
543
- }
544
- }
545
- function createTempSandbox(instance) {
546
- const notAvailable = () => Promise.resolve(
547
- new SandboxError({ reason: "not available during setup" })
548
- );
549
- const tempSandbox = {
550
- id: `__setup_temp_${Date.now()}`,
551
- config,
552
- cwd,
553
- exec: (opts) => execOnInstance(instance, opts),
554
- readFile: (opts) => readFileOnInstance(instance, opts),
555
- getDomain: () => notAvailable(),
556
- kill: () => notAvailable(),
557
- writeFiles: (opts) => writeFilesOnInstance(instance, opts),
558
- updateNetworkPolicy: (policy) => errore2.tryAsync({
559
- try: () => instance.updateNetworkPolicy(policy),
560
- catch: (e) => new SandboxError({ reason: String(e), cause: e })
561
- }),
562
- lifecycle: {
563
- start: () => notAvailable(),
564
- snapshot: () => notAvailable(),
565
- stop: () => notAvailable(),
566
- getStatus: () => notAvailable(),
567
- getCreatedAt: () => notAvailable(),
568
- getRemainingTimeout: () => notAvailable()
569
- },
570
- tag: {
571
- list: async () => ({}),
572
- get: async () => void 0,
573
- set: async () => void 0,
574
- setMany: async () => void 0
575
- }
576
- };
577
- return tempSandbox;
578
- }
579
- async function pollForSetupSnapshot(key) {
580
- const done = setupLog.time(
581
- "waiting for setup snapshot",
582
- { setupKey: key },
583
- { logOnStart: true }
584
- );
585
- const deadline = Date.now() + LOCK_TIMEOUT_MS;
586
- while (Date.now() < deadline) {
587
- await new Promise((r) => setTimeout(r, LOCK_POLL_INTERVAL_MS));
588
- const record = await pollStorage.setup.get(key);
589
- if (record instanceof Error) {
590
- return null;
591
- }
592
- if (record?.snapshotId) {
593
- done();
594
- return record.snapshotId;
595
- }
596
- const lockStale = record?.acquiringLockAt && Date.now() - record.acquiringLockAt >= LOCK_TIMEOUT_MS;
597
- if (!record?.acquiringLockId || lockStale) {
598
- if (lockStale) {
599
- setupLog.warn("setup lock is stale, giving up poll", {
600
- setupKey: key,
601
- lockAge: Date.now() - record.acquiringLockAt
602
- });
603
- }
604
- done({ staleLock: !!lockStale, found: false });
605
- return null;
606
- }
607
- }
608
- done({ timedOut: true });
609
- return null;
610
- }
611
- async function createSetupSnapshot(opts) {
612
- if (!setup) {
613
- return;
614
- }
615
- const setupKey = setup.key;
616
- if (!opts?.force) {
617
- const existing = await storage.setup.get(setupKey);
618
- if (!(existing instanceof Error) && existing?.snapshotId) {
619
- return;
620
- }
621
- }
622
- const lockId = crypto.randomUUID();
623
- const locked = await storage.setup.acquireLock(
624
- setupKey,
625
- lockId,
626
- LOCK_TIMEOUT_MS
627
- );
628
- if (locked instanceof Error || !locked) {
629
- return;
630
- }
631
- if (!opts?.force && locked.snapshotId) {
632
- return;
633
- }
634
- let tempInstance = null;
635
- try {
636
- tempInstance = await VercelSandboxSDK.create({
637
- resources: { vcpus },
638
- timeout: VERCEL_MAX_TIMEOUT_MS,
639
- ports,
640
- networkPolicy,
641
- ...getTestCredentials()
642
- });
643
- const tempSandbox = createTempSandbox(
644
- tempInstance
645
- );
646
- await setup.run(tempSandbox);
647
- const snapshot = await tempInstance.snapshot();
648
- await storage.setup.set({
649
- key: setupKey,
650
- snapshotId: snapshot.snapshotId,
651
- createdAt: locked.createdAt,
652
- lastUsedAt: null,
653
- acquiringLockId: null,
654
- acquiringLockAt: null
655
- });
656
- await tempInstance.stop().catch(() => void 0);
657
- } catch (e) {
658
- setupLog.error("failed to create setup snapshot", { setupKey, cause: e });
659
- if (tempInstance) {
660
- await tempInstance.stop().catch(() => void 0);
661
- }
662
- await storage.setup.set({
663
- key: setupKey,
664
- snapshotId: null,
665
- createdAt: locked.createdAt,
666
- lastUsedAt: null,
667
- acquiringLockId: null,
668
- acquiringLockAt: null
669
- }).catch(() => void 0);
670
- }
671
- }
672
- async function doGetOrCreateSandboxId() {
673
- const done = setupLog.time("doGetOrCreateSandboxId", { sandboxId: id });
674
- if (initialVercel?.sandboxId && !recoveredFromStale) {
675
- done({ path: "cache-hit" });
676
- return {
677
- sandboxId: initialVercel.sandboxId,
678
- needsSetupRun: false,
679
- createdFromSnapshot: false
680
- };
681
- }
682
- const existing = await storage.sandbox.get(id);
683
- if (existing instanceof Error) {
684
- if (existing instanceof SandboxNotFoundError) {
685
- } else {
686
- return new SandboxError({ reason: existing.message, cause: existing });
687
- }
688
- }
689
- const existingRecord = existing instanceof SandboxNotFoundError ? null : existing;
690
- const existingVercel = existingRecord?.providerMetadata?.provider === "vercel" ? existingRecord.providerMetadata : null;
691
- if (existingVercel?.sandboxId) {
692
- return {
693
- sandboxId: existingVercel.sandboxId,
694
- needsSetupRun: false,
695
- createdFromSnapshot: false
696
- };
697
- }
698
- const hasActiveLock = existingRecord?.acquiringLockId && existingRecord.acquiringLockAt && Date.now() - existingRecord.acquiringLockAt < LOCK_TIMEOUT_MS;
699
- if (hasActiveLock) {
700
- return pollForSandboxId();
701
- }
702
- const lockId = crypto.randomUUID();
703
- const now = Date.now();
704
- const locked = await storage.sandbox.acquireLock(
705
- {
706
- id,
707
- config,
708
- tags: existingRecord?.tags ?? sandboxRecord.tags,
709
- createdAt: existingRecord?.createdAt ?? sandboxRecord.createdAt,
710
- lastActivityAt: existingRecord?.lastActivityAt ?? sandboxRecord.lastActivityAt,
711
- acquiringLockId: lockId,
712
- acquiringLockAt: now,
713
- setupKey: sandboxRecord.setupKey,
714
- providerMetadata: {
715
- provider: "vercel",
716
- sandboxId: null,
717
- snapshotId: existingVercel?.snapshotId ?? initialVercel?.snapshotId ?? null
718
- }
719
- },
720
- LOCK_TIMEOUT_MS
721
- );
722
- if (locked instanceof Error) {
723
- return new SandboxError({ reason: locked.message, cause: locked });
724
- }
725
- if (!locked) {
726
- return pollForSandboxId();
727
- }
728
- const lockedRecord = locked;
729
- async function releaseSandboxLock() {
730
- await storage.sandbox.update({
731
- id: lockedRecord.id,
732
- acquiringLockId: null,
733
- acquiringLockAt: null
734
- }).catch(() => void 0);
735
- }
736
- const lockedVercel = lockedRecord.providerMetadata?.provider === "vercel" ? lockedRecord.providerMetadata : null;
737
- if (lockedVercel?.sandboxId) {
738
- await releaseSandboxLock();
739
- return {
740
- sandboxId: lockedVercel.sandboxId,
741
- needsSetupRun: false,
742
- createdFromSnapshot: false
743
- };
744
- }
745
- const snapshotId = lockedVercel?.snapshotId ?? initialVercel?.snapshotId ?? config.lifecycle?.snapshotId;
746
- if (snapshotId) {
747
- const result = await createSandboxFromSnapshot(snapshotId);
748
- if (!(result instanceof Error)) {
749
- done({ path: "config-snapshot" });
750
- return {
751
- sandboxId: result,
752
- needsSetupRun: false,
753
- createdFromSnapshot: true
754
- };
755
- }
756
- }
757
- if (setup) {
758
- let forceRecreateSnapshot = false;
759
- const setupRecord = await storage.setup.get(setup.key);
760
- if (!(setupRecord instanceof Error) && setupRecord) {
761
- if (setupRecord.snapshotId) {
762
- const result = await createSandboxFromSnapshot(
763
- setupRecord.snapshotId
764
- );
765
- if (!(result instanceof Error)) {
766
- storage.setup.set({
767
- ...setupRecord,
768
- lastUsedAt: Date.now()
769
- }).catch(() => void 0);
770
- done({ path: "setup-snapshot" });
771
- return {
772
- sandboxId: result,
773
- needsSetupRun: false,
774
- createdFromSnapshot: true
775
- };
776
- }
777
- forceRecreateSnapshot = true;
778
- } else if (setupRecord.acquiringLockId && setupRecord.acquiringLockAt && Date.now() - setupRecord.acquiringLockAt < LOCK_TIMEOUT_MS) {
779
- const polledSnapshotId = await pollForSetupSnapshot(setup.key);
780
- if (polledSnapshotId) {
781
- const result = await createSandboxFromSnapshot(polledSnapshotId);
782
- if (!(result instanceof Error)) {
783
- done({ path: "polled-snapshot" });
784
- return {
785
- sandboxId: result,
786
- needsSetupRun: false,
787
- createdFromSnapshot: true
788
- };
789
- }
790
- }
791
- }
792
- }
793
- createSetupSnapshot({ force: forceRecreateSnapshot }).catch((e) => {
794
- setupLog.error("failed to create background snapshot", { cause: e });
795
- });
796
- const freshResult2 = await createFreshSandbox();
797
- if (freshResult2 instanceof Error) {
798
- await releaseSandboxLock();
799
- return freshResult2;
800
- }
801
- done({ path: "fresh-with-setup" });
802
- return {
803
- sandboxId: freshResult2,
804
- needsSetupRun: true,
805
- createdFromSnapshot: false
806
- };
807
- }
808
- const freshResult = await createFreshSandbox();
809
- if (freshResult instanceof Error) {
810
- await releaseSandboxLock();
811
- return freshResult;
812
- }
813
- done({ path: "fresh" });
814
- return {
815
- sandboxId: freshResult,
816
- needsSetupRun: false,
817
- createdFromSnapshot: false
818
- };
819
- }
820
- function getOrCreateSandboxId() {
821
- const cached = createPromises.get(id);
822
- if (cached) {
823
- return cached;
824
- }
825
- const promise = doGetOrCreateSandboxId().finally(() => {
826
- createPromises.delete(id);
827
- });
828
- createPromises.set(id, promise);
829
- return promise;
830
- }
831
- async function doGetSandbox() {
832
- const createResult = await getOrCreateSandboxId();
833
- if (createResult instanceof Error) {
834
- return createResult;
835
- }
836
- const instance = await errore2.tryAsync({
837
- try: () => VercelSandboxSDK.get({
838
- sandboxId: createResult.sandboxId,
839
- ...getTestCredentials()
840
- }),
841
- catch: (e) => new SandboxError({ reason: String(e), cause: e })
842
- });
843
- if (instance instanceof Error) {
844
- return instance;
845
- }
846
- return {
847
- instance,
848
- needsSetupRun: createResult.needsSetupRun,
849
- createdFromSnapshot: createResult.createdFromSnapshot
850
- };
851
- }
852
- let getSandboxPromise = null;
853
- function getSandboxResult() {
854
- if (!getSandboxPromise) {
855
- getSandboxPromise = doGetSandbox();
856
- }
857
- return getSandboxPromise;
858
- }
859
- async function getSandboxInstance() {
860
- const result = await getSandboxResult();
861
- if (result instanceof Error) {
862
- return result;
863
- }
864
- return result.instance;
865
- }
866
- async function recoverFromStaleSandbox() {
867
- getSandboxPromise = null;
868
- recoveredFromStale = true;
869
- const existing = await storage.sandbox.get(id);
870
- if (existing instanceof Error || !existing) {
871
- return;
872
- }
873
- const existingVercel = existing.providerMetadata?.provider === "vercel" ? existing.providerMetadata : null;
874
- if (existingVercel?.sandboxId) {
875
- await storage.sandbox.update({
876
- id: existing.id,
877
- acquiringLockId: null,
878
- acquiringLockAt: null,
879
- providerMetadata: {
880
- provider: "vercel",
881
- sandboxId: null,
882
- snapshotId: existingVercel.snapshotId
883
- }
884
- });
885
- }
886
- }
887
- async function updateLastActivity() {
888
- const now = Date.now();
889
- const lastSent = lastActivitySent.get(id);
890
- if (lastSent && now - lastSent < ACTIVITY_THROTTLE_MS) {
891
- return;
892
- }
893
- lastActivitySent.set(id, now);
894
- const existing = await storage.sandbox.get(id);
895
- if (existing instanceof Error || !existing) {
896
- return;
897
- }
898
- const existingVercel = existing.providerMetadata?.provider === "vercel" ? existing.providerMetadata : null;
899
- await storage.sandbox.update({
900
- id: existing.id,
901
- lastActivityAt: now,
902
- acquiringLockId: null,
903
- acquiringLockAt: null,
904
- providerMetadata: existingVercel ?? {
905
- provider: "vercel",
906
- sandboxId: null,
907
- snapshotId: null
908
- }
909
- });
910
- }
911
- let startPromise = null;
912
- const lifecycle = {
913
- start: () => {
914
- if (startPromise) {
915
- return startPromise;
916
- }
917
- startPromise = (async () => {
918
- if (!setup && sandboxRecord.setupKey) {
919
- await pollForSetupCompletion({
920
- storage: pollStorage,
921
- sandboxId: sandboxRecord.id,
922
- setupKey: sandboxRecord.setupKey
923
- });
924
- }
925
- const result = await getSandboxResult();
926
- if (result instanceof Error) {
927
- startPromise = null;
928
- return result;
929
- }
930
- await updateLastActivity();
931
- if (result.needsSetupRun && setup) {
932
- try {
933
- await setup.run(sandbox);
934
- await markSetupComplete({
935
- storage,
936
- sandboxId: sandboxRecord.id,
937
- setupKey: setup.key
938
- });
939
- } catch (e) {
940
- await resetSetupState({
941
- storage,
942
- sandboxId: sandboxRecord.id,
943
- setupKey: setup.key
944
- });
945
- throw e;
946
- }
947
- }
948
- if (result.createdFromSnapshot && onRestart) {
949
- await onRestart(sandbox);
950
- }
951
- return void 0;
952
- })().catch((e) => {
953
- startPromise = null;
954
- throw e;
955
- });
956
- return startPromise;
957
- },
958
- snapshot: async () => {
959
- const sandbox2 = await getSandboxInstance();
960
- if (sandbox2 instanceof Error) {
961
- return sandbox2;
962
- }
963
- return errore2.tryAsync({
964
- try: async () => {
965
- const snapshot = await sandbox2.snapshot();
966
- await storage.sandbox.update({
967
- id,
968
- acquiringLockId: null,
969
- acquiringLockAt: null,
970
- providerMetadata: {
971
- provider: "vercel",
972
- sandboxId: null,
973
- snapshotId: snapshot.snapshotId
974
- }
975
- });
976
- return { snapshotId: snapshot.snapshotId };
977
- },
978
- catch: (e) => new SandboxError({ reason: String(e), cause: e })
979
- });
980
- },
981
- stop: async () => {
982
- const sandbox2 = await getSandboxInstance();
983
- if (sandbox2 instanceof Error) {
984
- return sandbox2;
985
- }
986
- return errore2.tryAsync({
987
- try: async () => {
988
- await sandbox2.stop();
989
- await storage.sandbox.update({
990
- id,
991
- acquiringLockId: null,
992
- acquiringLockAt: null,
993
- providerMetadata: {
994
- provider: "vercel",
995
- sandboxId: null,
996
- snapshotId: null
997
- }
998
- });
999
- return void 0;
1000
- },
1001
- catch: (e) => new SandboxError({ reason: String(e), cause: e })
1002
- });
1003
- },
1004
- getStatus: async () => {
1005
- const sandbox2 = await getSandboxInstance();
1006
- if (sandbox2 instanceof Error) {
1007
- return sandbox2;
1008
- }
1009
- return sandbox2.status;
1010
- },
1011
- getCreatedAt: async () => {
1012
- const sandbox2 = await getSandboxInstance();
1013
- if (sandbox2 instanceof Error) {
1014
- return sandbox2;
1015
- }
1016
- return sandbox2.createdAt;
1017
- },
1018
- getRemainingTimeout: async () => {
1019
- const sandbox2 = await getSandboxInstance();
1020
- if (sandbox2 instanceof Error) {
1021
- return sandbox2;
1022
- }
1023
- return sandbox2.timeout;
1024
- }
1025
- };
1026
- async function doExec(opts) {
1027
- const instance = await getSandboxInstance();
1028
- if (instance instanceof Error) {
1029
- return instance;
1030
- }
1031
- const updatePromise = updateLastActivity();
1032
- const execResult = await execOnInstance(instance, opts);
1033
- await updatePromise;
1034
- return execResult;
1035
- }
1036
- const sandbox = {
1037
- id,
1038
- config,
1039
- cwd,
1040
- exec: async (opts) => {
1041
- const result = await doExec(opts);
1042
- if (result instanceof SandboxError && isSandboxGoneError(result.cause)) {
1043
- await recoverFromStaleSandbox();
1044
- return await doExec(opts);
1045
- }
1046
- return result;
1047
- },
1048
- getDomain: async (port) => {
1049
- const sandbox2 = await getSandboxInstance();
1050
- if (sandbox2 instanceof Error) {
1051
- return sandbox2;
1052
- }
1053
- try {
1054
- return sandbox2.domain(port);
1055
- } catch (e) {
1056
- return new SandboxError({ reason: String(e), cause: e });
1057
- }
1058
- },
1059
- kill: async ({ commandId, storage: cmdStorage }) => {
1060
- const instance = await getSandboxInstance();
1061
- if (instance instanceof Error) {
1062
- return instance;
1063
- }
1064
- const cmd = await cmdStorage.command.get(commandId);
1065
- if (cmd instanceof Error) {
1066
- return new SandboxError({ reason: cmd.message, cause: cmd });
1067
- }
1068
- if (cmd && cmd.status === "running") {
1069
- const result = await cmdStorage.command.set({
1070
- ...cmd,
1071
- status: "killed"
1072
- });
1073
- if (result instanceof Error) {
1074
- return new SandboxError({ reason: result.message, cause: result });
1075
- }
1076
- }
1077
- return void 0;
1078
- },
1079
- readFile: async (opts) => {
1080
- const instance = await getSandboxInstance();
1081
- if (instance instanceof Error) {
1082
- return instance;
1083
- }
1084
- return readFileOnInstance(instance, opts);
1085
- },
1086
- writeFiles: async (opts) => {
1087
- const instance = await getSandboxInstance();
1088
- if (instance instanceof Error) {
1089
- throw instance;
1090
- }
1091
- return writeFilesOnInstance(instance, opts);
1092
- },
1093
- lifecycle,
1094
- updateNetworkPolicy: async (policy) => {
1095
- const instance = await getSandboxInstance();
1096
- if (instance instanceof Error) {
1097
- return instance;
1098
- }
1099
- return errore2.tryAsync({
1100
- try: () => instance.updateNetworkPolicy(policy),
1101
- catch: (e) => new SandboxError({ reason: String(e), cause: e })
1102
- });
1103
- },
1104
- tag: {
1105
- list: async () => {
1106
- const sandboxRecord2 = await storage.sandbox.get(id);
1107
- if (sandboxRecord2 instanceof Error) {
1108
- return sandboxRecord2;
1109
- }
1110
- return sandboxRecord2.tags ?? {};
1111
- },
1112
- get: async (key) => {
1113
- const sandboxRecord2 = await storage.sandbox.get(id);
1114
- if (sandboxRecord2 instanceof Error) {
1115
- return sandboxRecord2;
1116
- }
1117
- return sandboxRecord2.tags?.[key];
1118
- },
1119
- set: async (key, value) => {
1120
- const result = await storage.sandbox.tag.set({
1121
- sandboxId: id,
1122
- tags: { [key]: value }
1123
- });
1124
- if (result instanceof Error) {
1125
- return result;
1126
- }
1127
- return void 0;
1128
- },
1129
- setMany: async (tags) => {
1130
- const result = await storage.sandbox.tag.set({
1131
- sandboxId: id,
1132
- tags
1133
- });
1134
- if (result instanceof Error) {
1135
- return result;
1136
- }
1137
- return void 0;
1138
- }
1139
- }
1140
- };
1141
- return sandbox;
1142
- };
1143
-
1144
- // src/sandbox/client.ts
1145
- var log = createLogger({ subsystem: "sandbox" });
1146
- var sandboxCache = /* @__PURE__ */ new Map();
1147
- function getSandbox({
1148
- sandboxRecord,
1149
- storageConfig,
1150
- storage,
1151
- rpc,
1152
- enableLifecycleWorkflow = true,
1153
- setup,
1154
- onRestart
1155
- }) {
1156
- const cached = sandboxCache.get(sandboxRecord.id);
1157
- if (cached) {
1158
- return cached;
1159
- }
1160
- const sbx = createSandbox({
1161
- sandboxRecord,
1162
- storageConfig,
1163
- storage,
1164
- rpc,
1165
- enableLifecycleWorkflow,
1166
- setup,
1167
- onRestart
1168
- });
1169
- cacheSandbox(sandboxRecord.id, sbx);
1170
- return sbx;
1171
- }
1172
- function evictSandbox(id) {
1173
- sandboxCache.delete(id);
1174
- }
1175
- function cacheSandbox(id, sandbox) {
1176
- sandboxCache.set(id, sandbox);
1177
- }
1178
- function createSandbox({
1179
- sandboxRecord,
1180
- storageConfig,
1181
- storage,
1182
- rpc,
1183
- enableLifecycleWorkflow = true,
1184
- setup,
1185
- onRestart
1186
- }) {
1187
- let sbx;
1188
- const scopedSetup = setup ? {
1189
- ...setup,
1190
- key: `${sandboxRecord.config.type}:${setup.key}`
1191
- } : void 0;
1192
- const recordWithSetupKey = scopedSetup ? { ...sandboxRecord, setupKey: scopedSetup.key } : sandboxRecord;
1193
- switch (sandboxRecord.config.type) {
1194
- case "local":
1195
- sbx = localSandbox({
1196
- sandboxRecord: recordWithSetupKey,
1197
- storage,
1198
- setup: scopedSetup,
1199
- onRestart
1200
- });
1201
- break;
1202
- case "docker":
1203
- sbx = dockerSandbox({
1204
- sandboxRecord: recordWithSetupKey,
1205
- storage,
1206
- setup: scopedSetup,
1207
- onRestart
1208
- });
1209
- break;
1210
- case "vercel":
1211
- sbx = vercelSandbox({
1212
- sandboxRecord: recordWithSetupKey,
1213
- storageConfig,
1214
- storage,
1215
- rpc,
1216
- enableLifecycleWorkflow,
1217
- setup: scopedSetup,
1218
- onRestart
1219
- });
1220
- break;
1221
- case "custom":
1222
- throw new Error("Custom sandboxes are not supported");
1223
- default:
1224
- sandboxRecord.config;
1225
- throw new Error(
1226
- `Unknown sandbox type: ${// biome-ignore lint/suspicious/noExplicitAny: .
1227
- sandboxRecord.config.type}`
1228
- );
1229
- }
1230
- let readyPromise = null;
1231
- let publicOnReady;
1232
- function ensureReady() {
1233
- if (readyPromise) {
1234
- return readyPromise;
1235
- }
1236
- readyPromise = (async () => {
1237
- const done = log.time("ensureReady / lifecycle.start", {
1238
- sandboxId: sandboxRecord.id
1239
- });
1240
- const result = await sbx.lifecycle.start();
1241
- done();
1242
- if (result instanceof Error) {
1243
- throw result;
1244
- }
1245
- })().catch((e) => {
1246
- readyPromise = null;
1247
- publicOnReady = void 0;
1248
- throw e;
1249
- });
1250
- publicOnReady = readyPromise;
1251
- return readyPromise;
1252
- }
1253
- const autoStart = sandboxRecord.config.type === "vercel" ? sandboxRecord.config.lifecycle?.autoStart !== false : true;
1254
- if (autoStart) {
1255
- ensureReady();
1256
- }
1257
- return {
1258
- ...sbx,
1259
- get _onReady() {
1260
- return publicOnReady;
1261
- },
1262
- exec: async (opts) => {
1263
- await ensureReady();
1264
- return sbx.exec(opts);
1265
- },
1266
- getDomain: async (port) => {
1267
- await ensureReady();
1268
- return sbx.getDomain(port);
1269
- },
1270
- readFile: async (opts) => {
1271
- await ensureReady();
1272
- return sbx.readFile(opts);
1273
- },
1274
- writeFiles: async (opts) => {
1275
- await ensureReady();
1276
- return sbx.writeFiles(opts);
1277
- }
1278
- };
1279
- }
1280
-
1281
- export {
1282
- getSandbox,
1283
- evictSandbox,
1284
- cacheSandbox,
1285
- createSandbox
1286
- };
1287
- //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vc3JjL3NhbmRib3gvYmluZGluZ3MvbG9jYWwudHMiLCAiLi4vc3JjL3NhbmRib3gvYmluZGluZ3MvdmVyY2VsLnRzIiwgIi4uL3NyYy9zYW5kYm94L2NsaWVudC50cyJdLAogICJzb3VyY2VzQ29udGVudCI6IFsiaW1wb3J0IHR5cGUgeyBDaGlsZFByb2Nlc3MgfSBmcm9tIFwibm9kZTpjaGlsZF9wcm9jZXNzXCI7XG5pbXBvcnQgeyBzcGF3biB9IGZyb20gXCJub2RlOmNoaWxkX3Byb2Nlc3NcIjtcbmltcG9ydCAqIGFzIGZzIGZyb20gXCJub2RlOmZzL3Byb21pc2VzXCI7XG5pbXBvcnQgKiBhcyBwYXRoIGZyb20gXCJub2RlOnBhdGhcIjtcbmltcG9ydCAqIGFzIGVycm9yZSBmcm9tIFwiZXJyb3JlXCI7XG5pbXBvcnQgeyB1bGlkIH0gZnJvbSBcInVsaWRcIjtcbmltcG9ydCB7IFNhbmRib3hFcnJvciB9IGZyb20gXCIuLi8uLi9lcnJvcnNcIjtcbmltcG9ydCB0eXBlIHsgVGFnc1NjaGVtYSB9IGZyb20gXCIuLi8uLi9pbmRleFwiO1xuaW1wb3J0IHR5cGUgeyBTYW5kYm94UmVjb3JkLCBTdG9yYWdlIH0gZnJvbSBcIi4uLy4uL3N0b3JhZ2VcIjtcbmltcG9ydCB7XG4gIG1hcmtTZXR1cENvbXBsZXRlLFxuICBwb2xsRm9yU2V0dXBDb21wbGV0aW9uLFxuICByZXNldFNldHVwU3RhdGUsXG59IGZyb20gXCIuLi9zZXR1cC1wb2xsXCI7XG5pbXBvcnQgdHlwZSB7IExvZ0VudHJ5LCBPblJlc3RhcnQsIFNhbmRib3gsIFNhbmRib3hTZXR1cCB9IGZyb20gXCIuLi90eXBlc1wiO1xuaW1wb3J0IHsgd3JpdGVGaWxlcyB9IGZyb20gXCIuLi93cml0ZS1maWxlc1wiO1xuXG5leHBvcnQgY29uc3QgbG9jYWxTYW5kYm94ID0gPFRUYWdzIGV4dGVuZHMgVGFnc1NjaGVtYSA9IFRhZ3NTY2hlbWE+KHtcbiAgc2FuZGJveFJlY29yZCxcbiAgc3RvcmFnZSxcbiAgc2V0dXAsXG4gIG9uUmVzdGFydCxcbn06IHtcbiAgc2FuZGJveFJlY29yZDogU2FuZGJveFJlY29yZCAmIHsgY29uZmlnOiB7IHR5cGU6IFwibG9jYWxcIiB9IH07XG4gIHN0b3JhZ2U6IFN0b3JhZ2U7XG4gIHNldHVwPzogU2FuZGJveFNldHVwO1xuICBvblJlc3RhcnQ/OiBPblJlc3RhcnQ7XG59KTogU2FuZGJveDxUVGFncz4gPT4ge1xuICBjb25zdCBjb25maWcgPSBzYW5kYm94UmVjb3JkLmNvbmZpZztcbiAgY29uc3QgYmFzZVBhdGggPSBjb25maWcuY3dkID8/IHByb2Nlc3MuY3dkKCk7XG4gIGNvbnN0IHByb2Nlc3NlcyA9IG5ldyBNYXA8c3RyaW5nLCBDaGlsZFByb2Nlc3M+KCk7XG5cbiAgbGV0IHN0YXJ0UHJvbWlzZTogUHJvbWlzZTxTYW5kYm94RXJyb3IgfCB1bmRlZmluZWQ+IHwgbnVsbCA9IG51bGw7XG5cbiAgY29uc3Qgc2FuZGJveDogU2FuZGJveDxUVGFncz4gPSB7XG4gICAgaWQ6IHNhbmRib3hSZWNvcmQuaWQsXG4gICAgY29uZmlnOiBzYW5kYm94UmVjb3JkLmNvbmZpZyxcbiAgICBjd2Q6IGJhc2VQYXRoLFxuICAgIGV4ZWM6ICh7IGNvbW1hbmQsIGFyZ3MsIGN3ZCwgZW52LCBzaWduYWwsIHN1ZG8gfSkgPT4ge1xuICAgICAgcmV0dXJuIGVycm9yZS50cnlBc3luYyh7XG4gICAgICAgIHRyeTogKCkgPT4ge1xuICAgICAgICAgIGNvbnN0IGNvbW1hbmRJZCA9IGBjb21tYW5kXyR7dWxpZCgpfWA7XG4gICAgICAgICAgY29uc3QgZmluYWxDbWQgPSBzdWRvID8gXCJzdWRvXCIgOiBjb21tYW5kO1xuICAgICAgICAgIGNvbnN0IGZpbmFsQXJncyA9IHN1ZG9cbiAgICAgICAgICAgID8gW2NvbW1hbmQsIC4uLihhcmdzID8/IFtdKV1cbiAgICAgICAgICAgIDogKGFyZ3MgPz8gW10pO1xuXG4gICAgICAgICAgY29uc3QgY2hpbGQgPSBzcGF3bihmaW5hbENtZCwgZmluYWxBcmdzLCB7XG4gICAgICAgICAgICBjd2Q6IGN3ZCA/IHBhdGgucmVzb2x2ZShiYXNlUGF0aCwgY3dkKSA6IGJhc2VQYXRoLFxuICAgICAgICAgICAgZW52OiBlbnYgPyB7IC4uLnByb2Nlc3MuZW52LCAuLi5lbnYgfSA6IHVuZGVmaW5lZCxcbiAgICAgICAgICAgIHNpZ25hbCxcbiAgICAgICAgICB9KTtcblxuICAgICAgICAgIHByb2Nlc3Nlcy5zZXQoY29tbWFuZElkLCBjaGlsZCk7XG5cbiAgICAgICAgICBsZXQgc3Rkb3V0ID0gXCJcIjtcbiAgICAgICAgICBsZXQgc3RkZXJyID0gXCJcIjtcbiAgICAgICAgICBjb25zdCBsb2dRdWV1ZTogTG9nRW50cnlbXSA9IFtdO1xuICAgICAgICAgIGxldCBsb2dSZXNvbHZlOiAoKCkgPT4gdm9pZCkgfCBudWxsID0gbnVsbDtcbiAgICAgICAgICBsZXQgY2xvc2VkID0gZmFsc2U7XG5cbiAgICAgICAgICBjaGlsZC5zdGRvdXQub24oXCJkYXRhXCIsIChkYXRhOiBzdHJpbmcgfCBCdWZmZXIpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHN0ciA9IFN0cmluZyhkYXRhKTtcbiAgICAgICAgICAgIHN0ZG91dCArPSBzdHI7XG4gICAgICAgICAgICBsb2dRdWV1ZS5wdXNoKHsgc3RyZWFtOiBcInN0ZG91dFwiLCBkYXRhOiBzdHIgfSk7XG4gICAgICAgICAgICBsb2dSZXNvbHZlPy4oKTtcbiAgICAgICAgICB9KTtcblxuICAgICAgICAgIGNoaWxkLnN0ZGVyci5vbihcImRhdGFcIiwgKGRhdGE6IHN0cmluZyB8IEJ1ZmZlcikgPT4ge1xuICAgICAgICAgICAgY29uc3Qgc3RyID0gU3RyaW5nKGRhdGEpO1xuICAgICAgICAgICAgc3RkZXJyICs9IHN0cjtcbiAgICAgICAgICAgIGxvZ1F1ZXVlLnB1c2goeyBzdHJlYW06IFwic3RkZXJyXCIsIGRhdGE6IHN0ciB9KTtcbiAgICAgICAgICAgIGxvZ1Jlc29sdmU/LigpO1xuICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgY29uc3QgcmVzdWx0ID0gbmV3IFByb21pc2U8e1xuICAgICAgICAgICAgc3Rkb3V0OiBzdHJpbmc7XG4gICAgICAgICAgICBzdGRlcnI6IHN0cmluZztcbiAgICAgICAgICAgIGV4aXRDb2RlOiBudW1iZXI7XG4gICAgICAgICAgfT4oKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgY2hpbGQub24oXCJlcnJvclwiLCAoZXJyKSA9PiB7XG4gICAgICAgICAgICAgIHByb2Nlc3Nlcy5kZWxldGUoY29tbWFuZElkKTtcbiAgICAgICAgICAgICAgY2xvc2VkID0gdHJ1ZTtcbiAgICAgICAgICAgICAgbG9nUmVzb2x2ZT8uKCk7XG4gICAgICAgICAgICAgIHJlamVjdChlcnIpO1xuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIGNoaWxkLm9uKFwiY2xvc2VcIiwgKGNvZGU6IG51bWJlciB8IG51bGwpID0+IHtcbiAgICAgICAgICAgICAgcHJvY2Vzc2VzLmRlbGV0ZShjb21tYW5kSWQpO1xuICAgICAgICAgICAgICBjbG9zZWQgPSB0cnVlO1xuICAgICAgICAgICAgICBsb2dSZXNvbHZlPy4oKTtcbiAgICAgICAgICAgICAgcmVzb2x2ZSh7IHN0ZG91dCwgc3RkZXJyLCBleGl0Q29kZTogY29kZSA/PyAwIH0pO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgICBhc3luYyBmdW5jdGlvbiogbG9ncygpOiBBc3luY0l0ZXJhYmxlPExvZ0VudHJ5PiB7XG4gICAgICAgICAgICB3aGlsZSAoIWNsb3NlZCB8fCBsb2dRdWV1ZS5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICAgIGNvbnN0IGVudHJ5ID0gbG9nUXVldWUuc2hpZnQoKTtcbiAgICAgICAgICAgICAgaWYgKGVudHJ5KSB7XG4gICAgICAgICAgICAgICAgeWllbGQgZW50cnk7XG4gICAgICAgICAgICAgIH0gZWxzZSBpZiAoIWNsb3NlZCkge1xuICAgICAgICAgICAgICAgIGF3YWl0IG5ldyBQcm9taXNlPHZvaWQ+KChyZXNvbHZlKSA9PiB7XG4gICAgICAgICAgICAgICAgICBsb2dSZXNvbHZlID0gcmVzb2x2ZTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICBsb2dSZXNvbHZlID0gbnVsbDtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cblxuICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoeyBjb21tYW5kSWQsIGxvZ3MsIHJlc3VsdCB9KTtcbiAgICAgICAgfSxcbiAgICAgICAgY2F0Y2g6IChlOiB1bmtub3duKSA9PlxuICAgICAgICAgIG5ldyBTYW5kYm94RXJyb3IoeyByZWFzb246IFN0cmluZyhlKSwgY2F1c2U6IGUgfSksXG4gICAgICB9KTtcbiAgICB9LFxuXG4gICAgZ2V0RG9tYWluOiAocG9ydCkgPT4ge1xuICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShgaHR0cDovL2xvY2FsaG9zdDoke3BvcnR9YCk7XG4gICAgfSxcblxuICAgIGtpbGw6IGFzeW5jICh7IGNvbW1hbmRJZCwgc3RvcmFnZSB9KSA9PiB7XG4gICAgICBjb25zdCBjaGlsZCA9IHByb2Nlc3Nlcy5nZXQoY29tbWFuZElkKTtcbiAgICAgIGlmICghY2hpbGQpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBTYW5kYm94RXJyb3Ioe1xuICAgICAgICAgIHJlYXNvbjogYENvbW1hbmQgJHtjb21tYW5kSWR9IG5vdCBmb3VuZCBvciBhbHJlYWR5IGZpbmlzaGVkYCxcbiAgICAgICAgfSk7XG4gICAgICB9XG5cbiAgICAgIGNoaWxkLmtpbGwoXCJTSUdURVJNXCIpO1xuXG4gICAgICBjb25zdCBjbWQgPSBhd2FpdCBzdG9yYWdlLmNvbW1hbmQuZ2V0KGNvbW1hbmRJZCk7XG4gICAgICBpZiAoY21kIGluc3RhbmNlb2YgRXJyb3IpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBTYW5kYm94RXJyb3IoeyByZWFzb246IGNtZC5tZXNzYWdlLCBjYXVzZTogY21kIH0pO1xuICAgICAgfVxuICAgICAgaWYgKGNtZCAmJiBjbWQuc3RhdHVzID09PSBcInJ1bm5pbmdcIikge1xuICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBzdG9yYWdlLmNvbW1hbmQuc2V0KHtcbiAgICAgICAgICAuLi5jbWQsXG4gICAgICAgICAgc3RhdHVzOiBcImtpbGxlZFwiLFxuICAgICAgICB9KTtcbiAgICAgICAgaWYgKHJlc3VsdCBpbnN0YW5jZW9mIEVycm9yKSB7XG4gICAgICAgICAgcmV0dXJuIG5ldyBTYW5kYm94RXJyb3IoeyByZWFzb246IHJlc3VsdC5tZXNzYWdlLCBjYXVzZTogcmVzdWx0IH0pO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSxcblxuICAgIHJlYWRGaWxlOiBhc3luYyAoeyBwYXRoOiBmaWxlUGF0aCB9KSA9PiB7XG4gICAgICBjb25zdCBmdWxsUGF0aCA9IHBhdGguam9pbihiYXNlUGF0aCwgZmlsZVBhdGgpO1xuICAgICAgdHJ5IHtcbiAgICAgICAgcmV0dXJuIGF3YWl0IGZzLnJlYWRGaWxlKGZ1bGxQYXRoKTtcbiAgICAgIH0gY2F0Y2ggKGU6IHVua25vd24pIHtcbiAgICAgICAgaWYgKFxuICAgICAgICAgIGUgaW5zdGFuY2VvZiBFcnJvciAmJlxuICAgICAgICAgIFwiY29kZVwiIGluIGUgJiZcbiAgICAgICAgICAoZSBhcyBOb2RlSlMuRXJybm9FeGNlcHRpb24pLmNvZGUgPT09IFwiRU5PRU5UXCJcbiAgICAgICAgKSB7XG4gICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG5ldyBTYW5kYm94RXJyb3IoeyByZWFzb246IFN0cmluZyhlKSwgY2F1c2U6IGUgfSk7XG4gICAgICB9XG4gICAgfSxcblxuICAgIHdyaXRlRmlsZXM6IChvcHRzKSA9PiB3cml0ZUZpbGVzKHsgc2FuZGJveCwgLi4ub3B0cyB9KSxcblxuICAgIHVwZGF0ZU5ldHdvcmtQb2xpY3k6ICgpID0+XG4gICAgICBQcm9taXNlLnJlc29sdmUoXG4gICAgICAgIG5ldyBTYW5kYm94RXJyb3Ioe1xuICAgICAgICAgIHJlYXNvbjogXCJ1cGRhdGVOZXR3b3JrUG9saWN5IGlzIG9ubHkgYXZhaWxhYmxlIGZvciBWZXJjZWwgc2FuZGJveGVzXCIsXG4gICAgICAgIH0pXG4gICAgICApLFxuXG4gICAgbGlmZWN5Y2xlOiB7XG4gICAgICBzdGFydDogKCkgPT4ge1xuICAgICAgICBpZiAoc3RhcnRQcm9taXNlKSB7XG4gICAgICAgICAgcmV0dXJuIHN0YXJ0UHJvbWlzZTtcbiAgICAgICAgfVxuICAgICAgICBzdGFydFByb21pc2UgPSAoYXN5bmMgKCkgPT4ge1xuICAgICAgICAgIGlmICghc2V0dXAgJiYgc2FuZGJveFJlY29yZC5zZXR1cEtleSkge1xuICAgICAgICAgICAgYXdhaXQgcG9sbEZvclNldHVwQ29tcGxldGlvbih7XG4gICAgICAgICAgICAgIHN0b3JhZ2UsXG4gICAgICAgICAgICAgIHNhbmRib3hJZDogc2FuZGJveFJlY29yZC5pZCxcbiAgICAgICAgICAgICAgc2V0dXBLZXk6IHNhbmRib3hSZWNvcmQuc2V0dXBLZXksXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAoc2V0dXApIHtcbiAgICAgICAgICAgIGNvbnN0IGV4aXN0aW5nID0gYXdhaXQgc3RvcmFnZS5zZXR1cC5nZXQoc2V0dXAua2V5KTtcbiAgICAgICAgICAgIGlmIChleGlzdGluZyBpbnN0YW5jZW9mIEVycm9yIHx8ICFleGlzdGluZykge1xuICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIGF3YWl0IHNldHVwLnJ1bihzYW5kYm94KTtcbiAgICAgICAgICAgICAgICBhd2FpdCBzdG9yYWdlLnNldHVwLnNldCh7XG4gICAgICAgICAgICAgICAgICBrZXk6IHNldHVwLmtleSxcbiAgICAgICAgICAgICAgICAgIHNuYXBzaG90SWQ6IG51bGwsXG4gICAgICAgICAgICAgICAgICBjcmVhdGVkQXQ6IERhdGUubm93KCksXG4gICAgICAgICAgICAgICAgICBsYXN0VXNlZEF0OiBudWxsLFxuICAgICAgICAgICAgICAgICAgYWNxdWlyaW5nTG9ja0lkOiBudWxsLFxuICAgICAgICAgICAgICAgICAgYWNxdWlyaW5nTG9ja0F0OiBudWxsLFxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIGF3YWl0IG1hcmtTZXR1cENvbXBsZXRlKHtcbiAgICAgICAgICAgICAgICAgIHN0b3JhZ2UsXG4gICAgICAgICAgICAgICAgICBzYW5kYm94SWQ6IHNhbmRib3hSZWNvcmQuaWQsXG4gICAgICAgICAgICAgICAgICBzZXR1cEtleTogc2V0dXAua2V5LFxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICAgICAgYXdhaXQgcmVzZXRTZXR1cFN0YXRlKHtcbiAgICAgICAgICAgICAgICAgIHN0b3JhZ2UsXG4gICAgICAgICAgICAgICAgICBzYW5kYm94SWQ6IHNhbmRib3hSZWNvcmQuaWQsXG4gICAgICAgICAgICAgICAgICBzZXR1cEtleTogc2V0dXAua2V5LFxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIHRocm93IGU7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAob25SZXN0YXJ0KSB7XG4gICAgICAgICAgICBhd2FpdCBvblJlc3RhcnQoc2FuZGJveCk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICAgIH0pKCkuY2F0Y2goKGUpID0+IHtcbiAgICAgICAgICBzdGFydFByb21pc2UgPSBudWxsO1xuICAgICAgICAgIHRocm93IGU7XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gc3RhcnRQcm9taXNlO1xuICAgICAgfSxcbiAgICAgIHNuYXBzaG90OiAoKSA9PlxuICAgICAgICBQcm9taXNlLnJlc29sdmUoXG4gICAgICAgICAgbmV3IFNhbmRib3hFcnJvcih7XG4gICAgICAgICAgICByZWFzb246IFwic25hcHNob3QgaXMgbm90IHN1cHBvcnRlZCBmb3IgbG9jYWwgc2FuZGJveGVzXCIsXG4gICAgICAgICAgfSlcbiAgICAgICAgKSxcbiAgICAgIHN0b3A6ICgpID0+XG4gICAgICAgIFByb21pc2UucmVzb2x2ZShcbiAgICAgICAgICBuZXcgU2FuZGJveEVycm9yKHtcbiAgICAgICAgICAgIHJlYXNvbjogXCJzdG9wIGlzIG5vdCBzdXBwb3J0ZWQgZm9yIGxvY2FsIHNhbmRib3hlc1wiLFxuICAgICAgICAgIH0pXG4gICAgICAgICksXG4gICAgICBnZXRTdGF0dXM6ICgpID0+XG4gICAgICAgIFByb21pc2UucmVzb2x2ZShcbiAgICAgICAgICBuZXcgU2FuZGJveEVycm9yKHtcbiAgICAgICAgICAgIHJlYXNvbjogXCJnZXRTdGF0dXMgaXMgbm90IHN1cHBvcnRlZCBmb3IgbG9jYWwgc2FuZGJveGVzXCIsXG4gICAgICAgICAgfSlcbiAgICAgICAgKSxcbiAgICAgIGdldENyZWF0ZWRBdDogKCkgPT5cbiAgICAgICAgUHJvbWlzZS5yZXNvbHZlKFxuICAgICAgICAgIG5ldyBTYW5kYm94RXJyb3Ioe1xuICAgICAgICAgICAgcmVhc29uOiBcImdldENyZWF0ZWRBdCBpcyBub3Qgc3VwcG9ydGVkIGZvciBsb2NhbCBzYW5kYm94ZXNcIixcbiAgICAgICAgICB9KVxuICAgICAgICApLFxuICAgICAgZ2V0UmVtYWluaW5nVGltZW91dDogKCkgPT5cbiAgICAgICAgUHJvbWlzZS5yZXNvbHZlKFxuICAgICAgICAgIG5ldyBTYW5kYm94RXJyb3Ioe1xuICAgICAgICAgICAgcmVhc29uOiBcImdldFJlbWFpbmluZ1RpbWVvdXQgaXMgbm90IHN1cHBvcnRlZCBmb3IgbG9jYWwgc2FuZGJveGVzXCIsXG4gICAgICAgICAgfSlcbiAgICAgICAgKSxcbiAgICB9LFxuXG4gICAgdGFnOiB7XG4gICAgICBsaXN0OiBhc3luYyAoKSA9PiB7XG4gICAgICAgIGNvbnN0IHNhbmRib3hSZWNvcmQgPSBhd2FpdCBzdG9yYWdlLnNhbmRib3guZ2V0KHNhbmRib3guaWQpO1xuICAgICAgICBpZiAoc2FuZGJveFJlY29yZCBpbnN0YW5jZW9mIEVycm9yKSB7XG4gICAgICAgICAgcmV0dXJuIHNhbmRib3hSZWNvcmQ7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIChzYW5kYm94UmVjb3JkLnRhZ3MgPz8ge30pIGFzIFRUYWdzO1xuICAgICAgfSxcbiAgICAgIGdldDogYXN5bmMgKGtleTogc3RyaW5nKSA9PiB7XG4gICAgICAgIGNvbnN0IHNhbmRib3hSZWNvcmQgPSBhd2FpdCBzdG9yYWdlLnNhbmRib3guZ2V0KHNhbmRib3guaWQpO1xuICAgICAgICBpZiAoc2FuZGJveFJlY29yZCBpbnN0YW5jZW9mIEVycm9yKSB7XG4gICAgICAgICAgcmV0dXJuIHNhbmRib3hSZWNvcmQ7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHNhbmRib3hSZWNvcmQudGFncz8uW2tleSBhcyBzdHJpbmddIGFzXG4gICAgICAgICAgfCBUVGFnc1t0eXBlb2Yga2V5XVxuICAgICAgICAgIHwgdW5kZWZpbmVkO1xuICAgICAgfSxcbiAgICAgIHNldDogYXN5bmMgKGtleTogc3RyaW5nLCB2YWx1ZTogdW5rbm93bikgPT4ge1xuICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBzdG9yYWdlLnNhbmRib3gudGFnLnNldCh7XG4gICAgICAgICAgc2FuZGJveElkOiBzYW5kYm94LmlkLFxuICAgICAgICAgIHRhZ3M6IHsgW2tleV06IHZhbHVlIH0gYXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj4sXG4gICAgICAgIH0pO1xuICAgICAgICBpZiAocmVzdWx0IGluc3RhbmNlb2YgRXJyb3IpIHtcbiAgICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICB9LFxuICAgICAgc2V0TWFueTogYXN5bmMgKHRhZ3M6IFJlY29yZDxzdHJpbmcsIHVua25vd24+KSA9PiB7XG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHN0b3JhZ2Uuc2FuZGJveC50YWcuc2V0KHtcbiAgICAgICAgICBzYW5kYm94SWQ6IHNhbmRib3guaWQsXG4gICAgICAgICAgdGFnczogdGFncyBhcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPixcbiAgICAgICAgfSk7XG4gICAgICAgIGlmIChyZXN1bHQgaW5zdGFuY2VvZiBFcnJvcikge1xuICAgICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgIH0sXG4gICAgfSxcbiAgfTtcblxuICByZXR1cm4gc2FuZGJveDtcbn07XG4iLCAiaW1wb3J0ICogYXMgcGF0aCBmcm9tIFwibm9kZTpwYXRoXCI7XG5pbXBvcnQgeyBTYW5kYm94IGFzIFZlcmNlbFNhbmRib3hTREsgfSBmcm9tIFwiQHZlcmNlbC9zYW5kYm94XCI7XG5pbXBvcnQgKiBhcyBlcnJvcmUgZnJvbSBcImVycm9yZVwiO1xuaW1wb3J0IHsgc3RhcnQgfSBmcm9tIFwid29ya2Zsb3cvYXBpXCI7XG5pbXBvcnQgeyBTYW5kYm94RXJyb3IsIFNhbmRib3hOb3RGb3VuZEVycm9yIH0gZnJvbSBcIi4uLy4uL2Vycm9yc1wiO1xuaW1wb3J0IHR5cGUgeyBUYWdzU2NoZW1hIH0gZnJvbSBcIi4uLy4uL2luZGV4XCI7XG5pbXBvcnQge1xuICBnZXRTdG9yYWdlLFxuICB0eXBlIFJwY0ZuLFxuICB0eXBlIFNhbmRib3hSZWNvcmQsXG4gIHR5cGUgU3RvcmFnZSxcbiAgdHlwZSBTdG9yYWdlQ29uZmlnLFxufSBmcm9tIFwiLi4vLi4vc3RvcmFnZVwiO1xuaW1wb3J0IHsgY3JlYXRlTG9nZ2VyIH0gZnJvbSBcIi4uLy4uL3V0aWxzL2xvZ2dlclwiO1xuaW1wb3J0IHtcbiAgbWFya1NldHVwQ29tcGxldGUsXG4gIHBvbGxGb3JTZXR1cENvbXBsZXRpb24sXG4gIHJlc2V0U2V0dXBTdGF0ZSxcbn0gZnJvbSBcIi4uL3NldHVwLXBvbGxcIjtcbmltcG9ydCB0eXBlIHtcbiAgTG9nRW50cnksXG4gIE9uUmVzdGFydCxcbiAgU2FuZGJveCxcbiAgU2FuZGJveExpZmVjeWNsZSxcbiAgU2FuZGJveExpZmVjeWNsZUlucHV0LFxuICBTYW5kYm94U2V0dXAsXG4gIFNhbmRib3hTdGF0dXMsXG59IGZyb20gXCIuLi90eXBlc1wiO1xuaW1wb3J0IHsgc2FuZGJveExpZmVjeWNsZVdvcmtmbG93IH0gZnJvbSBcIi4vbGlmZWN5Y2xlLXdvcmtmbG93XCI7XG5cbmNvbnN0IHNldHVwTG9nID0gY3JlYXRlTG9nZ2VyKHsgc3Vic3lzdGVtOiBcInNhbmRib3g6c2V0dXBcIiB9KTtcblxuZXhwb3J0IHR5cGUgVmVyY2VsU2FuZGJveENyZWF0ZU9wdGlvbnMgPSBFeHRyYWN0PFxuICBQYXJhbWV0ZXJzPHR5cGVvZiBWZXJjZWxTYW5kYm94U0RLLmNyZWF0ZT5bMF0sXG4gIC8vIGJpb21lLWlnbm9yZSBsaW50L2NvbXBsZXhpdHkvbm9CYW5uZWRUeXBlczogLlxuICB7fVxuPjtcblxuZXhwb3J0IGNvbnN0IFZFUkNFTF9NQVhfVElNRU9VVF9NUyA9IDUgKiA2MCAqIDYwICogMTAwMDsgLy8gNSBob3Vyc1xuY29uc3QgTE9DS19USU1FT1VUX01TID0gNSAqIDYwICogMTAwMDsgLy8gNSBtaW51dGVzIC0gaWYgbG9jayBvbGRlciB0aGFuIHRoaXMsIGNvbnNpZGVyIGl0IHN0YWxlXG5jb25zdCBMT0NLX1BPTExfSU5URVJWQUxfTVMgPSAyMDA7XG5cbmNvbnN0IGdldFRlc3RDcmVkZW50aWFscyA9ICgpID0+XG4gIHByb2Nlc3MuZW52Lk5PREVfRU5WID09PSBcInRlc3RcIlxuICAgID8ge1xuICAgICAgICB0b2tlbjogcHJvY2Vzcy5lbnYuVEVTVF9WRVJDRUxfVE9LRU4sXG4gICAgICAgIHRlYW1JZDogcHJvY2Vzcy5lbnYuVEVTVF9WRVJDRUxfVEVBTV9JRCxcbiAgICAgICAgcHJvamVjdElkOiBwcm9jZXNzLmVudi5URVNUX1ZFUkNFTF9QUk9KRUNUX0lELFxuICAgICAgfVxuICAgIDoge307XG5cbi8qKlxuICogTW9kdWxlLWxldmVsIGNhY2hlIGZvciBpbi1mbGlnaHQgc2FuZGJveCBjcmVhdGlvbiBwcm9taXNlcy5cbiAqIFByZXZlbnRzIHBhcmFsbGVsIHJlcXVlc3RzIHdpdGhpbiB0aGUgc2FtZSBwcm9jZXNzIGZyb20gY3JlYXRpbmcgZHVwbGljYXRlIHNhbmRib3hlcy5cbiAqL1xuY29uc3QgY3JlYXRlUHJvbWlzZXMgPSBuZXcgTWFwPFxuICBzdHJpbmcsXG4gIFByb21pc2U8XG4gICAgfCBTYW5kYm94RXJyb3JcbiAgICB8IHtcbiAgICAgICAgc2FuZGJveElkOiBzdHJpbmc7XG4gICAgICAgIG5lZWRzU2V0dXBSdW46IGJvb2xlYW47XG4gICAgICAgIGNyZWF0ZWRGcm9tU25hcHNob3Q6IGJvb2xlYW47XG4gICAgICB9XG4gID5cbj4oKTtcblxuY29uc3QgQUNUSVZJVFlfVEhST1RUTEVfTVMgPSAxMF8wMDA7XG5jb25zdCBsYXN0QWN0aXZpdHlTZW50ID0gbmV3IE1hcDxzdHJpbmcsIG51bWJlcj4oKTtcblxuY29uc3QgREVGQVVMVF9WQ1BVUyA9IDI7XG5cbmZ1bmN0aW9uIGlzU2FuZGJveEdvbmVFcnJvcihlOiB1bmtub3duKTogYm9vbGVhbiB7XG4gIGlmICghKGUgaW5zdGFuY2VvZiBFcnJvcikpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICBjb25zdCBlcnJvcldpdGhSZXNwb25zZSA9IGUgYXMgeyByZXNwb25zZT86IHsgc3RhdHVzPzogbnVtYmVyIH0gfTtcbiAgY29uc3QgZXJyb3JXaXRoQ2F1c2UgPSBlIGFzIHsgY2F1c2U/OiB7IHJlc3BvbnNlPzogeyBzdGF0dXM/OiBudW1iZXIgfSB9IH07XG5cbiAgY29uc3Qgc3RhdHVzID1cbiAgICBlcnJvcldpdGhSZXNwb25zZS5yZXNwb25zZT8uc3RhdHVzID8/XG4gICAgZXJyb3JXaXRoQ2F1c2UuY2F1c2U/LnJlc3BvbnNlPy5zdGF0dXM7XG5cbiAgaWYgKHN0YXR1cyA9PT0gNDEwIHx8IHN0YXR1cyA9PT0gNDIyKSB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICBjb25zdCBtZXNzYWdlID0gZS5tZXNzYWdlIHx8IFN0cmluZyhlKTtcbiAgaWYgKFxuICAgIG1lc3NhZ2UuaW5jbHVkZXMoXCJFeHBlY3RlZCBhIHN0cmVhbSBvZiBjb21tYW5kIGRhdGFcIikgfHxcbiAgICBtZXNzYWdlLmluY2x1ZGVzKFwiRXhwZWN0ZWQgYSBzdHJlYW0gb2YgbG9nc1wiKVxuICApIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIHJldHVybiBmYWxzZTtcbn1cblxuZXhwb3J0IGNvbnN0IHZlcmNlbFNhbmRib3ggPSA8VFRhZ3MgZXh0ZW5kcyBUYWdzU2NoZW1hID0gVGFnc1NjaGVtYT4oe1xuICBzYW5kYm94UmVjb3JkLFxuICBzdG9yYWdlQ29uZmlnLFxuICBlbmFibGVMaWZlY3ljbGVXb3JrZmxvdyxcbiAgc3RvcmFnZSxcbiAgcnBjLFxuICBzZXR1cCxcbiAgb25SZXN0YXJ0LFxufToge1xuICBzYW5kYm94UmVjb3JkOiBTYW5kYm94UmVjb3JkICYgeyBjb25maWc6IHsgdHlwZTogXCJ2ZXJjZWxcIiB9IH07XG4gIHN0b3JhZ2VDb25maWc6IFN0b3JhZ2VDb25maWc7XG4gIGVuYWJsZUxpZmVjeWNsZVdvcmtmbG93OiBib29sZWFuO1xuICBzdG9yYWdlOiBTdG9yYWdlO1xuICBycGM6IFJwY0ZuO1xuICBzZXR1cD86IFNhbmRib3hTZXR1cDtcbiAgb25SZXN0YXJ0PzogT25SZXN0YXJ0O1xufSk6IFNhbmRib3g8VFRhZ3M+ID0+IHtcbiAgY29uc3QgeyBpZCwgY29uZmlnIH0gPSBzYW5kYm94UmVjb3JkO1xuICBjb25zdCB2Y3B1cyA9IGNvbmZpZy5yZXNvdXJjZXM/LnZjcHVzID8/IERFRkFVTFRfVkNQVVM7XG4gIGNvbnN0IHBvcnRzID0gY29uZmlnLnBvcnRzO1xuICBjb25zdCBuZXR3b3JrUG9saWN5ID0gY29uZmlnLm5ldHdvcmtQb2xpY3k7XG4gIGNvbnN0IGluaXRpYWxWZXJjZWwgPVxuICAgIHNhbmRib3hSZWNvcmQucHJvdmlkZXJNZXRhZGF0YT8ucHJvdmlkZXIgPT09IFwidmVyY2VsXCJcbiAgICAgID8gc2FuZGJveFJlY29yZC5wcm92aWRlck1ldGFkYXRhXG4gICAgICA6IG51bGw7XG5cbiAgdHlwZSBTYW5kYm94SW5zdGFuY2UgPSBBd2FpdGVkPFJldHVyblR5cGU8dHlwZW9mIFZlcmNlbFNhbmRib3hTREsuZ2V0Pj47XG4gIGxldCByZWNvdmVyZWRGcm9tU3RhbGUgPSBmYWxzZTtcbiAgY29uc3QgSE9NRV9ESVIgPSBcIi9ob21lL3ZlcmNlbC1zYW5kYm94XCI7XG4gIGNvbnN0IGN3ZCA9IGNvbmZpZy5jd2QgPz8gSE9NRV9ESVI7XG5cbiAgY29uc3QgcG9sbFN0b3JhZ2UgPSBnZXRTdG9yYWdlKHtcbiAgICBjb25maWc6IHN0b3JhZ2VDb25maWcsXG4gICAgcnBjOiAocCkgPT4gcnBjKHsgLi4ucCwgX3F1aWV0OiB0cnVlIH0pLFxuICB9KTtcblxuICB0eXBlIENyZWF0ZVJlc3VsdCA9IHtcbiAgICBzYW5kYm94SWQ6IHN0cmluZztcbiAgICBuZWVkc1NldHVwUnVuOiBib29sZWFuO1xuICAgIGNyZWF0ZWRGcm9tU25hcHNob3Q6IGJvb2xlYW47XG4gIH07XG5cbiAgYXN5bmMgZnVuY3Rpb24gcG9sbEZvclNhbmRib3hJZCgpOiBQcm9taXNlPFNhbmRib3hFcnJvciB8IENyZWF0ZVJlc3VsdD4ge1xuICAgIGNvbnN0IGRvbmUgPSBzZXR1cExvZy50aW1lKFxuICAgICAgXCJ3YWl0aW5nIGZvciBzYW5kYm94IGxvY2tcIixcbiAgICAgIHsgc2FuZGJveElkOiBpZCB9LFxuICAgICAgeyBsb2dPblN0YXJ0OiB0cnVlIH1cbiAgICApO1xuICAgIGNvbnN0IGRlYWRsaW5lID0gRGF0ZS5ub3coKSArIExPQ0tfVElNRU9VVF9NUztcbiAgICB3aGlsZSAoRGF0ZS5ub3coKSA8IGRlYWRsaW5lKSB7XG4gICAgICBhd2FpdCBuZXcgUHJvbWlzZSgocikgPT4gc2V0VGltZW91dChyLCBMT0NLX1BPTExfSU5URVJWQUxfTVMpKTtcbiAgICAgIGNvbnN0IHJlY29yZCA9IGF3YWl0IHBvbGxTdG9yYWdlLnNhbmRib3guZ2V0KGlkKTtcbiAgICAgIGlmIChyZWNvcmQgaW5zdGFuY2VvZiBFcnJvcikge1xuICAgICAgICByZXR1cm4gbmV3IFNhbmRib3hFcnJvcih7IHJlYXNvbjogcmVjb3JkLm1lc3NhZ2UsIGNhdXNlOiByZWNvcmQgfSk7XG4gICAgICB9XG4gICAgICBjb25zdCB2ZXJjZWxTYW5kYm94SWQgPVxuICAgICAgICByZWNvcmQ/LnByb3ZpZGVyTWV0YWRhdGE/LnByb3ZpZGVyID09PSBcInZlcmNlbFwiXG4gICAgICAgICAgPyByZWNvcmQucHJvdmlkZXJNZXRhZGF0YS5zYW5kYm94SWRcbiAgICAgICAgICA6IG51bGw7XG4gICAgICBpZiAodmVyY2VsU2FuZGJveElkKSB7XG4gICAgICAgIGRvbmUoKTtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICBzYW5kYm94SWQ6IHZlcmNlbFNhbmRib3hJZCxcbiAgICAgICAgICBuZWVkc1NldHVwUnVuOiBmYWxzZSxcbiAgICAgICAgICBjcmVhdGVkRnJvbVNuYXBzaG90OiBmYWxzZSxcbiAgICAgICAgfTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGxvY2tTdGFsZSA9XG4gICAgICAgIHJlY29yZD8uYWNxdWlyaW5nTG9ja0F0ICYmXG4gICAgICAgIERhdGUubm93KCkgLSByZWNvcmQuYWNxdWlyaW5nTG9ja0F0ID49IExPQ0tfVElNRU9VVF9NUztcbiAgICAgIGlmICghcmVjb3JkPy5hY3F1aXJpbmdMb2NrQXQgfHwgbG9ja1N0YWxlKSB7XG4gICAgICAgIGlmIChsb2NrU3RhbGUpIHtcbiAgICAgICAgICBzZXR1cExvZy53YXJuKFwic2FuZGJveCBsb2NrIGlzIHN0YWxlLCB0YWtpbmcgb3ZlclwiLCB7XG4gICAgICAgICAgICBzYW5kYm94SWQ6IGlkLFxuICAgICAgICAgICAgbG9ja0FnZTogRGF0ZS5ub3coKSAtIHJlY29yZCEuYWNxdWlyaW5nTG9ja0F0ISxcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICBkb25lKHsgc3RhbGVMb2NrOiAhIWxvY2tTdGFsZSB9KTtcbiAgICAgICAgcmV0dXJuIGRvR2V0T3JDcmVhdGVTYW5kYm94SWQoKTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIG5ldyBTYW5kYm94RXJyb3Ioe1xuICAgICAgcmVhc29uOiBcIlRpbWVkIG91dCB3YWl0aW5nIGZvciBzYW5kYm94IGNyZWF0aW9uIGJ5IGFub3RoZXIgcHJvY2Vzc1wiLFxuICAgIH0pO1xuICB9XG5cbiAgYXN5bmMgZnVuY3Rpb24gc3RhcnRMaWZlY3ljbGVXb3JrZmxvdyhcbiAgICB2ZXJjZWxTYW5kYm94SWQ6IHN0cmluZ1xuICApOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBpZiAoIWVuYWJsZUxpZmVjeWNsZVdvcmtmbG93KSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IGxpZmVjeWNsZUlucHV0OiBTYW5kYm94TGlmZWN5Y2xlSW5wdXQgPSB7XG4gICAgICBpZCxcbiAgICAgIHZlcmNlbFNhbmRib3hJZCxcbiAgICAgIHN0b3JhZ2VDb25maWcsXG4gICAgICBycGMsXG4gICAgfTtcbiAgICBhd2FpdCBzdGFydChzYW5kYm94TGlmZWN5Y2xlV29ya2Zsb3csIFt7IGlucHV0OiBsaWZlY3ljbGVJbnB1dCB9XSkuY2F0Y2goXG4gICAgICAvLyBiaW9tZS1pZ25vcmUgbGludC9zdXNwaWNpb3VzL25vRW1wdHlCbG9ja1N0YXRlbWVudHM6IGludGVudGlvbmFsbHkgaWdub3JlZCAtIHdvcmtmbG93IHN0YXJ0IGlzIGZpcmUtYW5kLWZvcmdldFxuICAgICAgKCkgPT4ge31cbiAgICApO1xuICB9XG5cbiAgYXN5bmMgZnVuY3Rpb24gY3JlYXRlU2FuZGJveEZyb21TbmFwc2hvdChcbiAgICBzbmFwc2hvdElkOiBzdHJpbmdcbiAgKTogUHJvbWlzZTxTYW5kYm94RXJyb3IgfCBzdHJpbmc+IHtcbiAgICByZXR1cm4gYXdhaXQgZXJyb3JlLnRyeUFzeW5jKHtcbiAgICAgIHRyeTogYXN5bmMgKCkgPT4ge1xuICAgICAgICBjb25zdCBzYW5kYm94ID0gYXdhaXQgVmVyY2VsU2FuZGJveFNESy5jcmVhdGUoe1xuICAgICAgICAgIHNvdXJjZTogeyB0eXBlOiBcInNuYXBzaG90XCIsIHNuYXBzaG90SWQgfSxcbiAgICAgICAgICByZXNvdXJjZXM6IHsgdmNwdXMgfSxcbiAgICAgICAgICB0aW1lb3V0OiBWRVJDRUxfTUFYX1RJTUVPVVRfTVMsXG4gICAgICAgICAgcG9ydHMsXG4gICAgICAgICAgbmV0d29ya1BvbGljeSxcbiAgICAgICAgICAuLi5nZXRUZXN0Q3JlZGVudGlhbHMoKSxcbiAgICAgICAgfSk7XG4gICAgICAgIGNvbnN0IG5vdyA9IERhdGUubm93KCk7XG4gICAgICAgIGF3YWl0IHN0b3JhZ2Uuc2FuZGJveC5zZXQoe1xuICAgICAgICAgIGlkLFxuICAgICAgICAgIGNvbmZpZyxcbiAgICAgICAgICB0YWdzOiBzYW5kYm94UmVjb3JkLnRhZ3MsXG4gICAgICAgICAgY3JlYXRlZEF0OiBub3csXG4gICAgICAgICAgbGFzdEFjdGl2aXR5QXQ6IG5vdyxcbiAgICAgICAgICBhY3F1aXJpbmdMb2NrSWQ6IG51bGwsXG4gICAgICAgICAgYWNxdWlyaW5nTG9ja0F0OiBudWxsLFxuICAgICAgICAgIHNldHVwS2V5OiBzYW5kYm94UmVjb3JkLnNldHVwS2V5LFxuICAgICAgICAgIHByb3ZpZGVyTWV0YWRhdGE6IHtcbiAgICAgICAgICAgIHByb3ZpZGVyOiBcInZlcmNlbFwiLFxuICAgICAgICAgICAgc2FuZGJveElkOiBzYW5kYm94LnNhbmRib3hJZCxcbiAgICAgICAgICAgIHNuYXBzaG90SWQsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSk7XG4gICAgICAgIGF3YWl0IHN0YXJ0TGlmZWN5Y2xlV29ya2Zsb3coc2FuZGJveC5zYW5kYm94SWQpO1xuICAgICAgICByZXR1cm4gc2FuZGJveC5zYW5kYm94SWQ7XG4gICAgICB9LFxuICAgICAgY2F0Y2g6IChlKSA9PiBuZXcgU2FuZGJveEVycm9yKHsgcmVhc29uOiBTdHJpbmcoZSksIGNhdXNlOiBlIH0pLFxuICAgIH0pO1xuICB9XG5cbiAgYXN5bmMgZnVuY3Rpb24gY3JlYXRlRnJlc2hTYW5kYm94KCk6IFByb21pc2U8U2FuZGJveEVycm9yIHwgc3RyaW5nPiB7XG4gICAgcmV0dXJuIGF3YWl0IGVycm9yZS50cnlBc3luYyh7XG4gICAgICB0cnk6IGFzeW5jICgpID0+IHtcbiAgICAgICAgY29uc3Qgc2FuZGJveCA9IGF3YWl0IFZlcmNlbFNhbmRib3hTREsuY3JlYXRlKHtcbiAgICAgICAgICByZXNvdXJjZXM6IHsgdmNwdXMgfSxcbiAgICAgICAgICB0aW1lb3V0OiBWRVJDRUxfTUFYX1RJTUVPVVRfTVMsXG4gICAgICAgICAgcG9ydHMsXG4gICAgICAgICAgbmV0d29ya1BvbGljeSxcbiAgICAgICAgICAuLi5nZXRUZXN0Q3JlZGVudGlhbHMoKSxcbiAgICAgICAgfSk7XG4gICAgICAgIGNvbnN0IG5vdyA9IERhdGUubm93KCk7XG4gICAgICAgIGF3YWl0IHN0b3JhZ2Uuc2FuZGJveC5zZXQoe1xuICAgICAgICAgIGlkLFxuICAgICAgICAgIGNvbmZpZyxcbiAgICAgICAgICB0YWdzOiBzYW5kYm94UmVjb3JkLnRhZ3MsXG4gICAgICAgICAgY3JlYXRlZEF0OiBub3csXG4gICAgICAgICAgbGFzdEFjdGl2aXR5QXQ6IG5vdyxcbiAgICAgICAgICBhY3F1aXJpbmdMb2NrSWQ6IG51bGwsXG4gICAgICAgICAgYWNxdWlyaW5nTG9ja0F0OiBudWxsLFxuICAgICAgICAgIHNldHVwS2V5OiBzYW5kYm94UmVjb3JkLnNldHVwS2V5LFxuICAgICAgICAgIHByb3ZpZGVyTWV0YWRhdGE6IHtcbiAgICAgICAgICAgIHByb3ZpZGVyOiBcInZlcmNlbFwiLFxuICAgICAgICAgICAgc2FuZGJveElkOiBzYW5kYm94LnNhbmRib3hJZCxcbiAgICAgICAgICAgIHNuYXBzaG90SWQ6IG51bGwsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSk7XG4gICAgICAgIGF3YWl0IHN0YXJ0TGlmZWN5Y2xlV29ya2Zsb3coc2FuZGJveC5zYW5kYm94SWQpO1xuICAgICAgICByZXR1cm4gc2FuZGJveC5zYW5kYm94SWQ7XG4gICAgICB9LFxuICAgICAgY2F0Y2g6IChlKSA9PiBuZXcgU2FuZGJveEVycm9yKHsgcmVhc29uOiBTdHJpbmcoZSksIGNhdXNlOiBlIH0pLFxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIENvcmUgZXhlYyBsb2dpYyBhZ2FpbnN0IGEgcmF3IFZlcmNlbCBTREsgaW5zdGFuY2UuXG4gICAqIFNoYXJlZCBiZXR3ZWVuIHRoZSBtYWluIHNhbmRib3ggd3JhcHBlciBhbmQgdGVtcG9yYXJ5IHNldHVwIHNhbmRib3hlcy5cbiAgICovXG4gIGZ1bmN0aW9uIGV4ZWNPbkluc3RhbmNlKFxuICAgIGluc3RhbmNlOiBTYW5kYm94SW5zdGFuY2UsXG4gICAge1xuICAgICAgY29tbWFuZCxcbiAgICAgIGFyZ3MsXG4gICAgICBjd2Q6IGV4ZWNDd2QsXG4gICAgICBlbnYsXG4gICAgICBzaWduYWwsXG4gICAgICBzdWRvLFxuICAgIH06IHtcbiAgICAgIGNvbW1hbmQ6IHN0cmluZztcbiAgICAgIGFyZ3M/OiBzdHJpbmdbXTtcbiAgICAgIGN3ZD86IHN0cmluZztcbiAgICAgIGVudj86IFJlY29yZDxzdHJpbmcsIHN0cmluZz47XG4gICAgICBzaWduYWw/OiBBYm9ydFNpZ25hbDtcbiAgICAgIHN1ZG8/OiBib29sZWFuO1xuICAgIH1cbiAgKTogUHJvbWlzZTxcbiAgICB8IFNhbmRib3hFcnJvclxuICAgIHwge1xuICAgICAgICBjb21tYW5kSWQ6IHN0cmluZztcbiAgICAgICAgbG9nczogKCkgPT4gQXN5bmNJdGVyYWJsZTxMb2dFbnRyeT47XG4gICAgICAgIHJlc3VsdDogUHJvbWlzZTx7IHN0ZG91dDogc3RyaW5nOyBzdGRlcnI6IHN0cmluZzsgZXhpdENvZGU6IG51bWJlciB9PjtcbiAgICAgIH1cbiAgPiB7XG4gICAgcmV0dXJuIGVycm9yZS50cnlBc3luYyh7XG4gICAgICB0cnk6IGFzeW5jICgpID0+IHtcbiAgICAgICAgY29uc3QgZmluYWxDbWQgPSBzdWRvID8gXCJzdWRvXCIgOiBjb21tYW5kO1xuICAgICAgICBjb25zdCBmaW5hbEFyZ3MgPSBzdWRvID8gW2NvbW1hbmQsIC4uLihhcmdzID8/IFtdKV0gOiBhcmdzO1xuICAgICAgICBjb25zdCBvdXRwdXQgPSBhd2FpdCBpbnN0YW5jZS5ydW5Db21tYW5kKHtcbiAgICAgICAgICBjd2Q6IGV4ZWNDd2QgPz8gY3dkLFxuICAgICAgICAgIGFyZ3M6IGZpbmFsQXJncyxcbiAgICAgICAgICBlbnYsXG4gICAgICAgICAgY21kOiBmaW5hbENtZCxcbiAgICAgICAgICBzaWduYWwsXG4gICAgICAgICAgZGV0YWNoZWQ6IHRydWUsXG4gICAgICAgIH0pO1xuXG4gICAgICAgIGxldCBzdGRvdXQgPSBcIlwiO1xuICAgICAgICBsZXQgc3RkZXJyID0gXCJcIjtcbiAgICAgICAgY29uc3QgbG9nQnVmZmVyOiBMb2dFbnRyeVtdID0gW107XG4gICAgICAgIGNvbnN0IHN0YXRlID0ge1xuICAgICAgICAgIHJlc29sdmU6IG51bGwgYXMgKCgpID0+IHZvaWQpIHwgbnVsbCxcbiAgICAgICAgICBjb25zdW1lZDogZmFsc2UsXG4gICAgICAgIH07XG5cbiAgICAgICAgY29uc3QgY29uc3VtZUxvZ3MgPSAoYXN5bmMgKCkgPT4ge1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICBmb3IgYXdhaXQgKGNvbnN0IGxvZyBvZiBvdXRwdXQubG9ncygpKSB7XG4gICAgICAgICAgICAgIGNvbnN0IGVudHJ5OiBMb2dFbnRyeSA9XG4gICAgICAgICAgICAgICAgbG9nLnN0cmVhbSA9PT0gXCJzdGRvdXRcIlxuICAgICAgICAgICAgICAgICAgPyB7IHN0cmVhbTogXCJzdGRvdXRcIiwgZGF0YTogbG9nLmRhdGEgfVxuICAgICAgICAgICAgICAgICAgOiB7IHN0cmVhbTogXCJzdGRlcnJcIiwgZGF0YTogbG9nLmRhdGEgfTtcblxuICAgICAgICAgICAgICBpZiAobG9nLnN0cmVhbSA9PT0gXCJzdGRvdXRcIikge1xuICAgICAgICAgICAgICAgIHN0ZG91dCArPSBsb2cuZGF0YTtcbiAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBzdGRlcnIgKz0gbG9nLmRhdGE7XG4gICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICBsb2dCdWZmZXIucHVzaChlbnRyeSk7XG4gICAgICAgICAgICAgIHN0YXRlLnJlc29sdmU/LigpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0gY2F0Y2gge1xuICAgICAgICAgICAgLy8gU2FuZGJveCBtYXkgaGF2ZSBiZWVuIHN0b3BwZWQgLSBsb2dzIGVuZHBvaW50IHJldHVybnMgNDIyXG4gICAgICAgICAgfVxuICAgICAgICAgIHN0YXRlLmNvbnN1bWVkID0gdHJ1ZTtcbiAgICAgICAgICBzdGF0ZS5yZXNvbHZlPy4oKTtcbiAgICAgICAgfSkoKTtcblxuICAgICAgICBhc3luYyBmdW5jdGlvbiogbG9ncygpOiBBc3luY0l0ZXJhYmxlPExvZ0VudHJ5PiB7XG4gICAgICAgICAgbGV0IGluZGV4ID0gMDtcbiAgICAgICAgICB3aGlsZSAoIXN0YXRlLmNvbnN1bWVkIHx8IGluZGV4IDwgbG9nQnVmZmVyLmxlbmd0aCkge1xuICAgICAgICAgICAgaWYgKGluZGV4IDwgbG9nQnVmZmVyLmxlbmd0aCkge1xuICAgICAgICAgICAgICB5aWVsZCBsb2dCdWZmZXJbaW5kZXgrK107XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICBhd2FpdCBuZXcgUHJvbWlzZTx2b2lkPigocmVzb2x2ZSkgPT4ge1xuICAgICAgICAgICAgICAgIHN0YXRlLnJlc29sdmUgPSByZXNvbHZlO1xuICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgc3RhdGUucmVzb2x2ZSA9IG51bGw7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgcmVzdWx0ID0gY29uc3VtZUxvZ3MudGhlbihhc3luYyAoKSA9PiB7XG4gICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGNvbnN0IGZpbmlzaGVkID0gYXdhaXQgb3V0cHV0LndhaXQoKTtcbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgIHN0ZG91dCxcbiAgICAgICAgICAgICAgc3RkZXJyLFxuICAgICAgICAgICAgICBleGl0Q29kZTogZmluaXNoZWQuZXhpdENvZGUsXG4gICAgICAgICAgICB9O1xuICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgIGlmIChpc1NhbmRib3hHb25lRXJyb3IoZSkpIHtcbiAgICAgICAgICAgICAgcmV0dXJuIHsgc3Rkb3V0LCBzdGRlcnIsIGV4aXRDb2RlOiAxIH07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aHJvdyBlO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG5cbiAgICAgICAgcmV0dXJuIHsgY29tbWFuZElkOiBvdXRwdXQuY21kSWQsIGxvZ3MsIHJlc3VsdCB9O1xuICAgICAgfSxcbiAgICAgIGNhdGNoOiAoZSkgPT4gbmV3IFNhbmRib3hFcnJvcih7IHJlYXNvbjogU3RyaW5nKGUpLCBjYXVzZTogZSB9KSxcbiAgICB9KTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHJlYWRGaWxlT25JbnN0YW5jZShcbiAgICBpbnN0YW5jZTogU2FuZGJveEluc3RhbmNlLFxuICAgIHsgcGF0aCB9OiB7IHBhdGg6IHN0cmluZyB9XG4gICk6IFByb21pc2U8U2FuZGJveEVycm9yIHwgQnVmZmVyIHwgbnVsbD4ge1xuICAgIHJldHVybiBlcnJvcmUudHJ5QXN5bmMoe1xuICAgICAgdHJ5OiAoKSA9PiBpbnN0YW5jZS5yZWFkRmlsZVRvQnVmZmVyKHsgcGF0aCwgY3dkIH0pLFxuICAgICAgY2F0Y2g6IChlKSA9PiBuZXcgU2FuZGJveEVycm9yKHsgcmVhc29uOiBTdHJpbmcoZSksIGNhdXNlOiBlIH0pLFxuICAgIH0pO1xuICB9XG5cbiAgYXN5bmMgZnVuY3Rpb24gd3JpdGVGaWxlc09uSW5zdGFuY2UoXG4gICAgaW5zdGFuY2U6IFNhbmRib3hJbnN0YW5jZSxcbiAgICBvcHRzOiB7XG4gICAgICBmaWxlczogeyBwYXRoOiBzdHJpbmc7IGNvbnRlbnQ6IHN0cmluZyB8IEJ1ZmZlciB9W107XG4gICAgICBkZXN0UGF0aDogc3RyaW5nO1xuICAgIH1cbiAgKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgeyBmaWxlcywgZGVzdFBhdGggfSA9IG9wdHM7XG4gICAgaWYgKGZpbGVzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IG5hdGl2ZUZpbGVzID0gZmlsZXMubWFwKChmaWxlKSA9PiB7XG4gICAgICBjb25zdCBmaWxlUGF0aCA9IHBhdGgucG9zaXguam9pbihkZXN0UGF0aCwgZmlsZS5wYXRoKTtcbiAgICAgIGNvbnN0IGFic29sdXRlUGF0aCA9IHBhdGgucG9zaXguaXNBYnNvbHV0ZShmaWxlUGF0aClcbiAgICAgICAgPyBmaWxlUGF0aFxuICAgICAgICA6IHBhdGgucG9zaXguam9pbihjd2QsIGZpbGVQYXRoKTtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHBhdGg6IGFic29sdXRlUGF0aCxcbiAgICAgICAgY29udGVudDpcbiAgICAgICAgICB0eXBlb2YgZmlsZS5jb250ZW50ID09PSBcInN0cmluZ1wiXG4gICAgICAgICAgICA/IEJ1ZmZlci5mcm9tKGZpbGUuY29udGVudClcbiAgICAgICAgICAgIDogZmlsZS5jb250ZW50LFxuICAgICAgfTtcbiAgICB9KTtcblxuICAgIGF3YWl0IGluc3RhbmNlLndyaXRlRmlsZXMobmF0aXZlRmlsZXMpO1xuXG4gICAgY29uc3Qgc2hlbGxTY3JpcHRzID0gbmF0aXZlRmlsZXMuZmlsdGVyKChmKSA9PiBmLnBhdGguZW5kc1dpdGgoXCIuc2hcIikpO1xuICAgIGlmIChzaGVsbFNjcmlwdHMubGVuZ3RoID4gMCkge1xuICAgICAgY29uc3QgY2htb2RSZXN1bHQgPSBhd2FpdCBleGVjT25JbnN0YW5jZShpbnN0YW5jZSwge1xuICAgICAgICBjb21tYW5kOiBcImNobW9kXCIsXG4gICAgICAgIGFyZ3M6IFtcIit4XCIsIC4uLnNoZWxsU2NyaXB0cy5tYXAoKGYpID0+IGYucGF0aCldLFxuICAgICAgfSk7XG4gICAgICBpZiAoY2htb2RSZXN1bHQgaW5zdGFuY2VvZiBFcnJvcikge1xuICAgICAgICB0aHJvdyBjaG1vZFJlc3VsdDtcbiAgICAgIH1cbiAgICAgIGF3YWl0IGNobW9kUmVzdWx0LnJlc3VsdDtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQ3JlYXRlcyBhIG1pbmltYWwgU2FuZGJveCB3cmFwcGVyIGFyb3VuZCBhIHJhdyBWZXJjZWwgU0RLIGluc3RhbmNlLlxuICAgKiBVc2VkIGZvciBydW5uaW5nIHNldHVwLnJ1bigpIG9uIGEgdGVtcG9yYXJ5IHNhbmRib3ggZm9yIHNuYXBzaG90IGNyZWF0aW9uLlxuICAgKi9cbiAgZnVuY3Rpb24gY3JlYXRlVGVtcFNhbmRib3goaW5zdGFuY2U6IFNhbmRib3hJbnN0YW5jZSk6IFNhbmRib3gge1xuICAgIGNvbnN0IG5vdEF2YWlsYWJsZSA9ICgpID0+XG4gICAgICBQcm9taXNlLnJlc29sdmUoXG4gICAgICAgIG5ldyBTYW5kYm94RXJyb3IoeyByZWFzb246IFwibm90IGF2YWlsYWJsZSBkdXJpbmcgc2V0dXBcIiB9KVxuICAgICAgKTtcbiAgICBjb25zdCB0ZW1wU2FuZGJveDogU2FuZGJveCA9IHtcbiAgICAgIGlkOiBgX19zZXR1cF90ZW1wXyR7RGF0ZS5ub3coKX1gLFxuICAgICAgY29uZmlnLFxuICAgICAgY3dkLFxuICAgICAgZXhlYzogKG9wdHMpID0+IGV4ZWNPbkluc3RhbmNlKGluc3RhbmNlLCBvcHRzKSxcbiAgICAgIHJlYWRGaWxlOiAob3B0cykgPT4gcmVhZEZpbGVPbkluc3RhbmNlKGluc3RhbmNlLCBvcHRzKSxcbiAgICAgIGdldERvbWFpbjogKCkgPT4gbm90QXZhaWxhYmxlKCksXG4gICAgICBraWxsOiAoKSA9PiBub3RBdmFpbGFibGUoKSxcbiAgICAgIHdyaXRlRmlsZXM6IChvcHRzKSA9PiB3cml0ZUZpbGVzT25JbnN0YW5jZShpbnN0YW5jZSwgb3B0cyksXG4gICAgICB1cGRhdGVOZXR3b3JrUG9saWN5OiAocG9saWN5KSA9PlxuICAgICAgICBlcnJvcmUudHJ5QXN5bmMoe1xuICAgICAgICAgIHRyeTogKCkgPT4gaW5zdGFuY2UudXBkYXRlTmV0d29ya1BvbGljeShwb2xpY3kpLFxuICAgICAgICAgIGNhdGNoOiAoZSkgPT4gbmV3IFNhbmRib3hFcnJvcih7IHJlYXNvbjogU3RyaW5nKGUpLCBjYXVzZTogZSB9KSxcbiAgICAgICAgfSksXG4gICAgICBsaWZlY3ljbGU6IHtcbiAgICAgICAgc3RhcnQ6ICgpID0+IG5vdEF2YWlsYWJsZSgpLFxuICAgICAgICBzbmFwc2hvdDogKCkgPT4gbm90QXZhaWxhYmxlKCksXG4gICAgICAgIHN0b3A6ICgpID0+IG5vdEF2YWlsYWJsZSgpLFxuICAgICAgICBnZXRTdGF0dXM6ICgpID0+IG5vdEF2YWlsYWJsZSgpLFxuICAgICAgICBnZXRDcmVhdGVkQXQ6ICgpID0+IG5vdEF2YWlsYWJsZSgpLFxuICAgICAgICBnZXRSZW1haW5pbmdUaW1lb3V0OiAoKSA9PiBub3RBdmFpbGFibGUoKSxcbiAgICAgIH0sXG4gICAgICB0YWc6IHtcbiAgICAgICAgbGlzdDogYXN5bmMgKCkgPT4gKHt9KSBhcyBUVGFncyxcbiAgICAgICAgZ2V0OiBhc3luYyAoKSA9PiB1bmRlZmluZWQsXG4gICAgICAgIHNldDogYXN5bmMgKCkgPT4gdW5kZWZpbmVkLFxuICAgICAgICBzZXRNYW55OiBhc3luYyAoKSA9PiB1bmRlZmluZWQsXG4gICAgICB9LFxuICAgIH07XG4gICAgcmV0dXJuIHRlbXBTYW5kYm94O1xuICB9XG5cbiAgLyoqXG4gICAqIFBvbGxzIGZvciBhIHNldHVwIHNuYXBzaG90IHRvIGJlY29tZSBhdmFpbGFibGUuIFJldHVybnMgdGhlIHNuYXBzaG90SWRcbiAgICogaWYgb25lIGFwcGVhcnMgYmVmb3JlIHRoZSBsb2NrIHRpbWVzIG91dCwgb3IgbnVsbCBpZiBpdCBkb2Vzbid0LlxuICAgKi9cbiAgYXN5bmMgZnVuY3Rpb24gcG9sbEZvclNldHVwU25hcHNob3Qoa2V5OiBzdHJpbmcpOiBQcm9taXNlPHN0cmluZyB8IG51bGw+IHtcbiAgICBjb25zdCBkb25lID0gc2V0dXBMb2cudGltZShcbiAgICAgIFwid2FpdGluZyBmb3Igc2V0dXAgc25hcHNob3RcIixcbiAgICAgIHsgc2V0dXBLZXk6IGtleSB9LFxuICAgICAgeyBsb2dPblN0YXJ0OiB0cnVlIH1cbiAgICApO1xuICAgIGNvbnN0IGRlYWRsaW5lID0gRGF0ZS5ub3coKSArIExPQ0tfVElNRU9VVF9NUztcbiAgICB3aGlsZSAoRGF0ZS5ub3coKSA8IGRlYWRsaW5lKSB7XG4gICAgICBhd2FpdCBuZXcgUHJvbWlzZSgocikgPT4gc2V0VGltZW91dChyLCBMT0NLX1BPTExfSU5URVJWQUxfTVMpKTtcbiAgICAgIGNvbnN0IHJlY29yZCA9IGF3YWl0IHBvbGxTdG9yYWdlLnNldHVwLmdldChrZXkpO1xuICAgICAgaWYgKHJlY29yZCBpbnN0YW5jZW9mIEVycm9yKSB7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgICAgfVxuICAgICAgaWYgKHJlY29yZD8uc25hcHNob3RJZCkge1xuICAgICAgICBkb25lKCk7XG4gICAgICAgIHJldHVybiByZWNvcmQuc25hcHNob3RJZDtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGxvY2tTdGFsZSA9XG4gICAgICAgIHJlY29yZD8uYWNxdWlyaW5nTG9ja0F0ICYmXG4gICAgICAgIERhdGUubm93KCkgLSByZWNvcmQuYWNxdWlyaW5nTG9ja0F0ID49IExPQ0tfVElNRU9VVF9NUztcbiAgICAgIGlmICghcmVjb3JkPy5hY3F1aXJpbmdMb2NrSWQgfHwgbG9ja1N0YWxlKSB7XG4gICAgICAgIGlmIChsb2NrU3RhbGUpIHtcbiAgICAgICAgICBzZXR1cExvZy53YXJuKFwic2V0dXAgbG9jayBpcyBzdGFsZSwgZ2l2aW5nIHVwIHBvbGxcIiwge1xuICAgICAgICAgICAgc2V0dXBLZXk6IGtleSxcbiAgICAgICAgICAgIGxvY2tBZ2U6IERhdGUubm93KCkgLSByZWNvcmQhLmFjcXVpcmluZ0xvY2tBdCEsXG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgZG9uZSh7IHN0YWxlTG9jazogISFsb2NrU3RhbGUsIGZvdW5kOiBmYWxzZSB9KTtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICB9XG4gICAgfVxuICAgIGRvbmUoeyB0aW1lZE91dDogdHJ1ZSB9KTtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIC8qKlxuICAgKiBDcmVhdGVzIGEgYmFja2dyb3VuZCBzYW5kYm94LCBydW5zIHNldHVwLCBzbmFwc2hvdHMgaXQsIGFuZCBzdG9yZXMgdGhlXG4gICAqIHNuYXBzaG90IElELiBVc2VzIGF0b21pYyBsb2NraW5nIHRvIGVuc3VyZSBvbmx5IG9uZSBwcm9jZXNzIGNyZWF0ZXMgaXQuXG4gICAqXG4gICAqIEBwYXJhbSBmb3JjZSAtIFNraXAgdGhlIFwic25hcHNob3QgYWxyZWFkeSBleGlzdHNcIiBlYXJseSBleGl0LiBVc2VkIHdoZW5cbiAgICogICB0aGUgY2FsbGVyIGtub3dzIHRoZSBleGlzdGluZyBzbmFwc2hvdCBpcyBzdGFsZS9leHBpcmVkLlxuICAgKi9cbiAgYXN5bmMgZnVuY3Rpb24gY3JlYXRlU2V0dXBTbmFwc2hvdChvcHRzPzoge1xuICAgIGZvcmNlPzogYm9vbGVhbjtcbiAgfSk6IFByb21pc2U8dm9pZD4ge1xuICAgIGlmICghc2V0dXApIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3Qgc2V0dXBLZXkgPSBzZXR1cC5rZXk7XG5cbiAgICAvLyBDaGVjayBpZiBzbmFwc2hvdCBhbHJlYWR5IGV4aXN0cyAoZmFzdCBwYXRoIFx1MjAxNCBhdm9pZHMgbG9jayBhdHRlbXB0KVxuICAgIGlmICghb3B0cz8uZm9yY2UpIHtcbiAgICAgIGNvbnN0IGV4aXN0aW5nID0gYXdhaXQgc3RvcmFnZS5zZXR1cC5nZXQoc2V0dXBLZXkpO1xuICAgICAgaWYgKCEoZXhpc3RpbmcgaW5zdGFuY2VvZiBFcnJvcikgJiYgZXhpc3Rpbmc/LnNuYXBzaG90SWQpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIEF0b21pY2FsbHkgYWNxdWlyZSBsb2NrIChoYW5kbGVzIGFjdGl2ZS1sb2NrIGRldGVjdGlvbiBpbnRlcm5hbGx5KVxuICAgIGNvbnN0IGxvY2tJZCA9IGNyeXB0by5yYW5kb21VVUlEKCk7XG4gICAgY29uc3QgbG9ja2VkID0gYXdhaXQgc3RvcmFnZS5zZXR1cC5hY3F1aXJlTG9jayhcbiAgICAgIHNldHVwS2V5LFxuICAgICAgbG9ja0lkLFxuICAgICAgTE9DS19USU1FT1VUX01TXG4gICAgKTtcbiAgICBpZiAobG9ja2VkIGluc3RhbmNlb2YgRXJyb3IgfHwgIWxvY2tlZCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIFJlLWNoZWNrOiBhbm90aGVyIHdvcmtlciBtYXkgaGF2ZSBjcmVhdGVkIHRoZSBzbmFwc2hvdCBiZXR3ZWVuIG91clxuICAgIC8vIHByZS1jaGVjayBhbmQgbG9jayBhY3F1aXNpdGlvbi4gSWYgc28sIHNraXAgdW5sZXNzIGZvcmNlIChzdGFsZSBzbmFwc2hvdCkuXG4gICAgaWYgKCFvcHRzPy5mb3JjZSAmJiBsb2NrZWQuc25hcHNob3RJZCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGxldCB0ZW1wSW5zdGFuY2U6IEF3YWl0ZWQ8XG4gICAgICBSZXR1cm5UeXBlPHR5cGVvZiBWZXJjZWxTYW5kYm94U0RLLmNyZWF0ZT5cbiAgICA+IHwgbnVsbCA9IG51bGw7XG4gICAgdHJ5IHtcbiAgICAgIC8vIENyZWF0ZSBhIHRlbXBvcmFyeSBzYW5kYm94IGZvciBzbmFwc2hvdHRpbmcuXG4gICAgICB0ZW1wSW5zdGFuY2UgPSBhd2FpdCBWZXJjZWxTYW5kYm94U0RLLmNyZWF0ZSh7XG4gICAgICAgIHJlc291cmNlczogeyB2Y3B1cyB9LFxuICAgICAgICB0aW1lb3V0OiBWRVJDRUxfTUFYX1RJTUVPVVRfTVMsXG4gICAgICAgIHBvcnRzLFxuICAgICAgICBuZXR3b3JrUG9saWN5LFxuICAgICAgICAuLi5nZXRUZXN0Q3JlZGVudGlhbHMoKSxcbiAgICAgIH0pO1xuXG4gICAgICBjb25zdCB0ZW1wU2FuZGJveCA9IGNyZWF0ZVRlbXBTYW5kYm94KFxuICAgICAgICB0ZW1wSW5zdGFuY2UgYXMgdW5rbm93biBhcyBTYW5kYm94SW5zdGFuY2VcbiAgICAgICk7XG4gICAgICBhd2FpdCBzZXR1cC5ydW4odGVtcFNhbmRib3gpO1xuICAgICAgY29uc3Qgc25hcHNob3QgPSBhd2FpdCB0ZW1wSW5zdGFuY2Uuc25hcHNob3QoKTtcblxuICAgICAgYXdhaXQgc3RvcmFnZS5zZXR1cC5zZXQoe1xuICAgICAgICBrZXk6IHNldHVwS2V5LFxuICAgICAgICBzbmFwc2hvdElkOiBzbmFwc2hvdC5zbmFwc2hvdElkLFxuICAgICAgICBjcmVhdGVkQXQ6IGxvY2tlZC5jcmVhdGVkQXQsXG4gICAgICAgIGxhc3RVc2VkQXQ6IG51bGwsXG4gICAgICAgIGFjcXVpcmluZ0xvY2tJZDogbnVsbCxcbiAgICAgICAgYWNxdWlyaW5nTG9ja0F0OiBudWxsLFxuICAgICAgfSk7XG5cbiAgICAgIC8vIFN0b3AgdGhlIHRlbXAgc2FuZGJveCBcdTIwMTQgbm8gbG9uZ2VyIG5lZWRlZCBhZnRlciBzbmFwc2hvdHRpbmdcbiAgICAgIGF3YWl0IHRlbXBJbnN0YW5jZS5zdG9wKCkuY2F0Y2goKCkgPT4gdW5kZWZpbmVkKTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICBzZXR1cExvZy5lcnJvcihcImZhaWxlZCB0byBjcmVhdGUgc2V0dXAgc25hcHNob3RcIiwgeyBzZXR1cEtleSwgY2F1c2U6IGUgfSk7XG4gICAgICAvLyBTdG9wIHRoZSB0ZW1wIHNhbmRib3ggb24gZmFpbHVyZVxuICAgICAgaWYgKHRlbXBJbnN0YW5jZSkge1xuICAgICAgICBhd2FpdCB0ZW1wSW5zdGFuY2Uuc3RvcCgpLmNhdGNoKCgpID0+IHVuZGVmaW5lZCk7XG4gICAgICB9XG4gICAgICAvLyBDbGVhbiB1cCBsb2NrIG9uIGZhaWx1cmVcbiAgICAgIGF3YWl0IHN0b3JhZ2Uuc2V0dXBcbiAgICAgICAgLnNldCh7XG4gICAgICAgICAga2V5OiBzZXR1cEtleSxcbiAgICAgICAgICBzbmFwc2hvdElkOiBudWxsLFxuICAgICAgICAgIGNyZWF0ZWRBdDogbG9ja2VkLmNyZWF0ZWRBdCxcbiAgICAgICAgICBsYXN0VXNlZEF0OiBudWxsLFxuICAgICAgICAgIGFjcXVpcmluZ0xvY2tJZDogbnVsbCxcbiAgICAgICAgICBhY3F1aXJpbmdMb2NrQXQ6IG51bGwsXG4gICAgICAgIH0pXG4gICAgICAgIC5jYXRjaCgoKSA9PiB1bmRlZmluZWQpO1xuICAgIH1cbiAgfVxuXG4gIGFzeW5jIGZ1bmN0aW9uIGRvR2V0T3JDcmVhdGVTYW5kYm94SWQoKTogUHJvbWlzZTxcbiAgICBTYW5kYm94RXJyb3IgfCBDcmVhdGVSZXN1bHRcbiAgPiB7XG4gICAgY29uc3QgZG9uZSA9IHNldHVwTG9nLnRpbWUoXCJkb0dldE9yQ3JlYXRlU2FuZGJveElkXCIsIHsgc2FuZGJveElkOiBpZCB9KTtcblxuICAgIGlmIChpbml0aWFsVmVyY2VsPy5zYW5kYm94SWQgJiYgIXJlY292ZXJlZEZyb21TdGFsZSkge1xuICAgICAgZG9uZSh7IHBhdGg6IFwiY2FjaGUtaGl0XCIgfSk7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBzYW5kYm94SWQ6IGluaXRpYWxWZXJjZWwuc2FuZGJveElkLFxuICAgICAgICBuZWVkc1NldHVwUnVuOiBmYWxzZSxcbiAgICAgICAgY3JlYXRlZEZyb21TbmFwc2hvdDogZmFsc2UsXG4gICAgICB9O1xuICAgIH1cblxuICAgIGNvbnN0IGV4aXN0aW5nID0gYXdhaXQgc3RvcmFnZS5zYW5kYm94LmdldChpZCk7XG4gICAgaWYgKGV4aXN0aW5nIGluc3RhbmNlb2YgRXJyb3IpIHtcbiAgICAgIGlmIChleGlzdGluZyBpbnN0YW5jZW9mIFNhbmRib3hOb3RGb3VuZEVycm9yKSB7XG4gICAgICAgIC8vIFNhbmRib3ggZG9lc24ndCBleGlzdCB5ZXQsIGNvbnRpbnVlIHdpdGggY3JlYXRpb25cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBuZXcgU2FuZGJveEVycm9yKHsgcmVhc29uOiBleGlzdGluZy5tZXNzYWdlLCBjYXVzZTogZXhpc3RpbmcgfSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgY29uc3QgZXhpc3RpbmdSZWNvcmQgPVxuICAgICAgZXhpc3RpbmcgaW5zdGFuY2VvZiBTYW5kYm94Tm90Rm91bmRFcnJvciA/IG51bGwgOiBleGlzdGluZztcbiAgICBjb25zdCBleGlzdGluZ1ZlcmNlbCA9XG4gICAgICBleGlzdGluZ1JlY29yZD8ucHJvdmlkZXJNZXRhZGF0YT8ucHJvdmlkZXIgPT09IFwidmVyY2VsXCJcbiAgICAgICAgPyBleGlzdGluZ1JlY29yZC5wcm92aWRlck1ldGFkYXRhXG4gICAgICAgIDogbnVsbDtcblxuICAgIGlmIChleGlzdGluZ1ZlcmNlbD8uc2FuZGJveElkKSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBzYW5kYm94SWQ6IGV4aXN0aW5nVmVyY2VsLnNhbmRib3hJZCxcbiAgICAgICAgbmVlZHNTZXR1cFJ1bjogZmFsc2UsXG4gICAgICAgIGNyZWF0ZWRGcm9tU25hcHNob3Q6IGZhbHNlLFxuICAgICAgfTtcbiAgICB9XG5cbiAgICBjb25zdCBoYXNBY3RpdmVMb2NrID1cbiAgICAgIGV4aXN0aW5nUmVjb3JkPy5hY3F1aXJpbmdMb2NrSWQgJiZcbiAgICAgIGV4aXN0aW5nUmVjb3JkLmFjcXVpcmluZ0xvY2tBdCAmJlxuICAgICAgRGF0ZS5ub3coKSAtIGV4aXN0aW5nUmVjb3JkLmFjcXVpcmluZ0xvY2tBdCA8IExPQ0tfVElNRU9VVF9NUztcblxuICAgIGlmIChoYXNBY3RpdmVMb2NrKSB7XG4gICAgICByZXR1cm4gcG9sbEZvclNhbmRib3hJZCgpO1xuICAgIH1cblxuICAgIGNvbnN0IGxvY2tJZCA9IGNyeXB0by5yYW5kb21VVUlEKCk7XG4gICAgY29uc3Qgbm93ID0gRGF0ZS5ub3coKTtcbiAgICBjb25zdCBsb2NrZWQgPSBhd2FpdCBzdG9yYWdlLnNhbmRib3guYWNxdWlyZUxvY2soXG4gICAgICB7XG4gICAgICAgIGlkLFxuICAgICAgICBjb25maWcsXG4gICAgICAgIHRhZ3M6IGV4aXN0aW5nUmVjb3JkPy50YWdzID8/IHNhbmRib3hSZWNvcmQudGFncyxcbiAgICAgICAgY3JlYXRlZEF0OiBleGlzdGluZ1JlY29yZD8uY3JlYXRlZEF0ID8/IHNhbmRib3hSZWNvcmQuY3JlYXRlZEF0LFxuICAgICAgICBsYXN0QWN0aXZpdHlBdDpcbiAgICAgICAgICBleGlzdGluZ1JlY29yZD8ubGFzdEFjdGl2aXR5QXQgPz8gc2FuZGJveFJlY29yZC5sYXN0QWN0aXZpdHlBdCxcbiAgICAgICAgYWNxdWlyaW5nTG9ja0lkOiBsb2NrSWQsXG4gICAgICAgIGFjcXVpcmluZ0xvY2tBdDogbm93LFxuICAgICAgICBzZXR1cEtleTogc2FuZGJveFJlY29yZC5zZXR1cEtleSxcbiAgICAgICAgcHJvdmlkZXJNZXRhZGF0YToge1xuICAgICAgICAgIHByb3ZpZGVyOiBcInZlcmNlbFwiLFxuICAgICAgICAgIHNhbmRib3hJZDogbnVsbCxcbiAgICAgICAgICBzbmFwc2hvdElkOlxuICAgICAgICAgICAgZXhpc3RpbmdWZXJjZWw/LnNuYXBzaG90SWQgPz8gaW5pdGlhbFZlcmNlbD8uc25hcHNob3RJZCA/PyBudWxsLFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICAgIExPQ0tfVElNRU9VVF9NU1xuICAgICk7XG5cbiAgICBpZiAobG9ja2VkIGluc3RhbmNlb2YgRXJyb3IpIHtcbiAgICAgIHJldHVybiBuZXcgU2FuZGJveEVycm9yKHsgcmVhc29uOiBsb2NrZWQubWVzc2FnZSwgY2F1c2U6IGxvY2tlZCB9KTtcbiAgICB9XG4gICAgaWYgKCFsb2NrZWQpIHtcbiAgICAgIHJldHVybiBwb2xsRm9yU2FuZGJveElkKCk7XG4gICAgfVxuXG4gICAgY29uc3QgbG9ja2VkUmVjb3JkID0gbG9ja2VkO1xuXG4gICAgYXN5bmMgZnVuY3Rpb24gcmVsZWFzZVNhbmRib3hMb2NrKCk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgYXdhaXQgc3RvcmFnZS5zYW5kYm94XG4gICAgICAgIC51cGRhdGUoe1xuICAgICAgICAgIGlkOiBsb2NrZWRSZWNvcmQuaWQsXG4gICAgICAgICAgYWNxdWlyaW5nTG9ja0lkOiBudWxsLFxuICAgICAgICAgIGFjcXVpcmluZ0xvY2tBdDogbnVsbCxcbiAgICAgICAgfSlcbiAgICAgICAgLmNhdGNoKCgpID0+IHVuZGVmaW5lZCk7XG4gICAgfVxuXG4gICAgY29uc3QgbG9ja2VkVmVyY2VsID1cbiAgICAgIGxvY2tlZFJlY29yZC5wcm92aWRlck1ldGFkYXRhPy5wcm92aWRlciA9PT0gXCJ2ZXJjZWxcIlxuICAgICAgICA/IGxvY2tlZFJlY29yZC5wcm92aWRlck1ldGFkYXRhXG4gICAgICAgIDogbnVsbDtcbiAgICBpZiAobG9ja2VkVmVyY2VsPy5zYW5kYm94SWQpIHtcbiAgICAgIGF3YWl0IHJlbGVhc2VTYW5kYm94TG9jaygpO1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgc2FuZGJveElkOiBsb2NrZWRWZXJjZWwuc2FuZGJveElkLFxuICAgICAgICBuZWVkc1NldHVwUnVuOiBmYWxzZSxcbiAgICAgICAgY3JlYXRlZEZyb21TbmFwc2hvdDogZmFsc2UsXG4gICAgICB9O1xuICAgIH1cblxuICAgIGNvbnN0IHNuYXBzaG90SWQgPVxuICAgICAgbG9ja2VkVmVyY2VsPy5zbmFwc2hvdElkID8/XG4gICAgICBpbml0aWFsVmVyY2VsPy5zbmFwc2hvdElkID8/XG4gICAgICBjb25maWcubGlmZWN5Y2xlPy5zbmFwc2hvdElkO1xuICAgIGlmIChzbmFwc2hvdElkKSB7XG4gICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBjcmVhdGVTYW5kYm94RnJvbVNuYXBzaG90KHNuYXBzaG90SWQpO1xuICAgICAgaWYgKCEocmVzdWx0IGluc3RhbmNlb2YgRXJyb3IpKSB7XG4gICAgICAgIGRvbmUoeyBwYXRoOiBcImNvbmZpZy1zbmFwc2hvdFwiIH0pO1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIHNhbmRib3hJZDogcmVzdWx0LFxuICAgICAgICAgIG5lZWRzU2V0dXBSdW46IGZhbHNlLFxuICAgICAgICAgIGNyZWF0ZWRGcm9tU25hcHNob3Q6IHRydWUsXG4gICAgICAgIH07XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKHNldHVwKSB7XG4gICAgICBsZXQgZm9yY2VSZWNyZWF0ZVNuYXBzaG90ID0gZmFsc2U7XG4gICAgICBjb25zdCBzZXR1cFJlY29yZCA9IGF3YWl0IHN0b3JhZ2Uuc2V0dXAuZ2V0KHNldHVwLmtleSk7XG4gICAgICBpZiAoIShzZXR1cFJlY29yZCBpbnN0YW5jZW9mIEVycm9yKSAmJiBzZXR1cFJlY29yZCkge1xuICAgICAgICBpZiAoc2V0dXBSZWNvcmQuc25hcHNob3RJZCkge1xuICAgICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGNyZWF0ZVNhbmRib3hGcm9tU25hcHNob3QoXG4gICAgICAgICAgICBzZXR1cFJlY29yZC5zbmFwc2hvdElkXG4gICAgICAgICAgKTtcbiAgICAgICAgICBpZiAoIShyZXN1bHQgaW5zdGFuY2VvZiBFcnJvcikpIHtcbiAgICAgICAgICAgIHN0b3JhZ2Uuc2V0dXBcbiAgICAgICAgICAgICAgLnNldCh7XG4gICAgICAgICAgICAgICAgLi4uc2V0dXBSZWNvcmQsXG4gICAgICAgICAgICAgICAgbGFzdFVzZWRBdDogRGF0ZS5ub3coKSxcbiAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgLmNhdGNoKCgpID0+IHVuZGVmaW5lZCk7XG4gICAgICAgICAgICBkb25lKHsgcGF0aDogXCJzZXR1cC1zbmFwc2hvdFwiIH0pO1xuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgc2FuZGJveElkOiByZXN1bHQsXG4gICAgICAgICAgICAgIG5lZWRzU2V0dXBSdW46IGZhbHNlLFxuICAgICAgICAgICAgICBjcmVhdGVkRnJvbVNuYXBzaG90OiB0cnVlLFxuICAgICAgICAgICAgfTtcbiAgICAgICAgICB9XG4gICAgICAgICAgZm9yY2VSZWNyZWF0ZVNuYXBzaG90ID0gdHJ1ZTtcbiAgICAgICAgfSBlbHNlIGlmIChcbiAgICAgICAgICBzZXR1cFJlY29yZC5hY3F1aXJpbmdMb2NrSWQgJiZcbiAgICAgICAgICBzZXR1cFJlY29yZC5hY3F1aXJpbmdMb2NrQXQgJiZcbiAgICAgICAgICBEYXRlLm5vdygpIC0gc2V0dXBSZWNvcmQuYWNxdWlyaW5nTG9ja0F0IDwgTE9DS19USU1FT1VUX01TXG4gICAgICAgICkge1xuICAgICAgICAgIGNvbnN0IHBvbGxlZFNuYXBzaG90SWQgPSBhd2FpdCBwb2xsRm9yU2V0dXBTbmFwc2hvdChzZXR1cC5rZXkpO1xuICAgICAgICAgIGlmIChwb2xsZWRTbmFwc2hvdElkKSB7XG4gICAgICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBjcmVhdGVTYW5kYm94RnJvbVNuYXBzaG90KHBvbGxlZFNuYXBzaG90SWQpO1xuICAgICAgICAgICAgaWYgKCEocmVzdWx0IGluc3RhbmNlb2YgRXJyb3IpKSB7XG4gICAgICAgICAgICAgIGRvbmUoeyBwYXRoOiBcInBvbGxlZC1zbmFwc2hvdFwiIH0pO1xuICAgICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgIHNhbmRib3hJZDogcmVzdWx0LFxuICAgICAgICAgICAgICAgIG5lZWRzU2V0dXBSdW46IGZhbHNlLFxuICAgICAgICAgICAgICAgIGNyZWF0ZWRGcm9tU25hcHNob3Q6IHRydWUsXG4gICAgICAgICAgICAgIH07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGNyZWF0ZVNldHVwU25hcHNob3QoeyBmb3JjZTogZm9yY2VSZWNyZWF0ZVNuYXBzaG90IH0pLmNhdGNoKChlKSA9PiB7XG4gICAgICAgIHNldHVwTG9nLmVycm9yKFwiZmFpbGVkIHRvIGNyZWF0ZSBiYWNrZ3JvdW5kIHNuYXBzaG90XCIsIHsgY2F1c2U6IGUgfSk7XG4gICAgICB9KTtcblxuICAgICAgY29uc3QgZnJlc2hSZXN1bHQgPSBhd2FpdCBjcmVhdGVGcmVzaFNhbmRib3goKTtcbiAgICAgIGlmIChmcmVzaFJlc3VsdCBpbnN0YW5jZW9mIEVycm9yKSB7XG4gICAgICAgIGF3YWl0IHJlbGVhc2VTYW5kYm94TG9jaygpO1xuICAgICAgICByZXR1cm4gZnJlc2hSZXN1bHQ7XG4gICAgICB9XG4gICAgICBkb25lKHsgcGF0aDogXCJmcmVzaC13aXRoLXNldHVwXCIgfSk7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBzYW5kYm94SWQ6IGZyZXNoUmVzdWx0LFxuICAgICAgICBuZWVkc1NldHVwUnVuOiB0cnVlLFxuICAgICAgICBjcmVhdGVkRnJvbVNuYXBzaG90OiBmYWxzZSxcbiAgICAgIH07XG4gICAgfVxuXG4gICAgY29uc3QgZnJlc2hSZXN1bHQgPSBhd2FpdCBjcmVhdGVGcmVzaFNhbmRib3goKTtcbiAgICBpZiAoZnJlc2hSZXN1bHQgaW5zdGFuY2VvZiBFcnJvcikge1xuICAgICAgYXdhaXQgcmVsZWFzZVNhbmRib3hMb2NrKCk7XG4gICAgICByZXR1cm4gZnJlc2hSZXN1bHQ7XG4gICAgfVxuICAgIGRvbmUoeyBwYXRoOiBcImZyZXNoXCIgfSk7XG4gICAgcmV0dXJuIHtcbiAgICAgIHNhbmRib3hJZDogZnJlc2hSZXN1bHQsXG4gICAgICBuZWVkc1NldHVwUnVuOiBmYWxzZSxcbiAgICAgIGNyZWF0ZWRGcm9tU25hcHNob3Q6IGZhbHNlLFxuICAgIH07XG4gIH1cblxuICBmdW5jdGlvbiBnZXRPckNyZWF0ZVNhbmRib3hJZCgpOiBQcm9taXNlPFNhbmRib3hFcnJvciB8IENyZWF0ZVJlc3VsdD4ge1xuICAgIGNvbnN0IGNhY2hlZCA9IGNyZWF0ZVByb21pc2VzLmdldChpZCk7XG4gICAgaWYgKGNhY2hlZCkge1xuICAgICAgcmV0dXJuIGNhY2hlZDtcbiAgICB9XG5cbiAgICBjb25zdCBwcm9taXNlID0gZG9HZXRPckNyZWF0ZVNhbmRib3hJZCgpLmZpbmFsbHkoKCkgPT4ge1xuICAgICAgY3JlYXRlUHJvbWlzZXMuZGVsZXRlKGlkKTtcbiAgICB9KTtcbiAgICBjcmVhdGVQcm9taXNlcy5zZXQoaWQsIHByb21pc2UpO1xuICAgIHJldHVybiBwcm9taXNlO1xuICB9XG5cbiAgdHlwZSBHZXRTYW5kYm94UmVzdWx0ID0ge1xuICAgIGluc3RhbmNlOiBTYW5kYm94SW5zdGFuY2U7XG4gICAgbmVlZHNTZXR1cFJ1bjogYm9vbGVhbjtcbiAgICBjcmVhdGVkRnJvbVNuYXBzaG90OiBib29sZWFuO1xuICB9O1xuXG4gIGFzeW5jIGZ1bmN0aW9uIGRvR2V0U2FuZGJveCgpOiBQcm9taXNlPFNhbmRib3hFcnJvciB8IEdldFNhbmRib3hSZXN1bHQ+IHtcbiAgICBjb25zdCBjcmVhdGVSZXN1bHQgPSBhd2FpdCBnZXRPckNyZWF0ZVNhbmRib3hJZCgpO1xuICAgIGlmIChjcmVhdGVSZXN1bHQgaW5zdGFuY2VvZiBFcnJvcikge1xuICAgICAgcmV0dXJuIGNyZWF0ZVJlc3VsdDtcbiAgICB9XG5cbiAgICBjb25zdCBpbnN0YW5jZSA9IGF3YWl0IGVycm9yZS50cnlBc3luYyh7XG4gICAgICB0cnk6ICgpID0+XG4gICAgICAgIFZlcmNlbFNhbmRib3hTREsuZ2V0KHtcbiAgICAgICAgICBzYW5kYm94SWQ6IGNyZWF0ZVJlc3VsdC5zYW5kYm94SWQsXG4gICAgICAgICAgLi4uZ2V0VGVzdENyZWRlbnRpYWxzKCksXG4gICAgICAgIH0pLFxuICAgICAgY2F0Y2g6IChlKSA9PiBuZXcgU2FuZGJveEVycm9yKHsgcmVhc29uOiBTdHJpbmcoZSksIGNhdXNlOiBlIH0pLFxuICAgIH0pO1xuXG4gICAgaWYgKGluc3RhbmNlIGluc3RhbmNlb2YgRXJyb3IpIHtcbiAgICAgIHJldHVybiBpbnN0YW5jZTtcbiAgICB9XG5cbiAgICByZXR1cm4ge1xuICAgICAgaW5zdGFuY2UsXG4gICAgICBuZWVkc1NldHVwUnVuOiBjcmVhdGVSZXN1bHQubmVlZHNTZXR1cFJ1bixcbiAgICAgIGNyZWF0ZWRGcm9tU25hcHNob3Q6IGNyZWF0ZVJlc3VsdC5jcmVhdGVkRnJvbVNuYXBzaG90LFxuICAgIH07XG4gIH1cblxuICBsZXQgZ2V0U2FuZGJveFByb21pc2U6IFByb21pc2U8U2FuZGJveEVycm9yIHwgR2V0U2FuZGJveFJlc3VsdD4gfCBudWxsID0gbnVsbDtcblxuICBmdW5jdGlvbiBnZXRTYW5kYm94UmVzdWx0KCk6IFByb21pc2U8U2FuZGJveEVycm9yIHwgR2V0U2FuZGJveFJlc3VsdD4ge1xuICAgIGlmICghZ2V0U2FuZGJveFByb21pc2UpIHtcbiAgICAgIGdldFNhbmRib3hQcm9taXNlID0gZG9HZXRTYW5kYm94KCk7XG4gICAgfVxuICAgIHJldHVybiBnZXRTYW5kYm94UHJvbWlzZTtcbiAgfVxuXG4gIGFzeW5jIGZ1bmN0aW9uIGdldFNhbmRib3hJbnN0YW5jZSgpOiBQcm9taXNlPFNhbmRib3hFcnJvciB8IFNhbmRib3hJbnN0YW5jZT4ge1xuICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGdldFNhbmRib3hSZXN1bHQoKTtcbiAgICBpZiAocmVzdWx0IGluc3RhbmNlb2YgRXJyb3IpIHtcbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuICAgIHJldHVybiByZXN1bHQuaW5zdGFuY2U7XG4gIH1cblxuICBhc3luYyBmdW5jdGlvbiByZWNvdmVyRnJvbVN0YWxlU2FuZGJveCgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBnZXRTYW5kYm94UHJvbWlzZSA9IG51bGw7XG4gICAgcmVjb3ZlcmVkRnJvbVN0YWxlID0gdHJ1ZTtcblxuICAgIGNvbnN0IGV4aXN0aW5nID0gYXdhaXQgc3RvcmFnZS5zYW5kYm94LmdldChpZCk7XG4gICAgaWYgKGV4aXN0aW5nIGluc3RhbmNlb2YgRXJyb3IgfHwgIWV4aXN0aW5nKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgZXhpc3RpbmdWZXJjZWwgPVxuICAgICAgZXhpc3RpbmcucHJvdmlkZXJNZXRhZGF0YT8ucHJvdmlkZXIgPT09IFwidmVyY2VsXCJcbiAgICAgICAgPyBleGlzdGluZy5wcm92aWRlck1ldGFkYXRhXG4gICAgICAgIDogbnVsbDtcblxuICAgIGlmIChleGlzdGluZ1ZlcmNlbD8uc2FuZGJveElkKSB7XG4gICAgICBhd2FpdCBzdG9yYWdlLnNhbmRib3gudXBkYXRlKHtcbiAgICAgICAgaWQ6IGV4aXN0aW5nLmlkLFxuICAgICAgICBhY3F1aXJpbmdMb2NrSWQ6IG51bGwsXG4gICAgICAgIGFjcXVpcmluZ0xvY2tBdDogbnVsbCxcbiAgICAgICAgcHJvdmlkZXJNZXRhZGF0YToge1xuICAgICAgICAgIHByb3ZpZGVyOiBcInZlcmNlbFwiLFxuICAgICAgICAgIHNhbmRib3hJZDogbnVsbCxcbiAgICAgICAgICBzbmFwc2hvdElkOiBleGlzdGluZ1ZlcmNlbC5zbmFwc2hvdElkLFxuICAgICAgICB9LFxuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgYXN5bmMgZnVuY3Rpb24gdXBkYXRlTGFzdEFjdGl2aXR5KCk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IG5vdyA9IERhdGUubm93KCk7XG4gICAgY29uc3QgbGFzdFNlbnQgPSBsYXN0QWN0aXZpdHlTZW50LmdldChpZCk7XG4gICAgaWYgKGxhc3RTZW50ICYmIG5vdyAtIGxhc3RTZW50IDwgQUNUSVZJVFlfVEhST1RUTEVfTVMpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgbGFzdEFjdGl2aXR5U2VudC5zZXQoaWQsIG5vdyk7XG5cbiAgICBjb25zdCBleGlzdGluZyA9IGF3YWl0IHN0b3JhZ2Uuc2FuZGJveC5nZXQoaWQpO1xuICAgIGlmIChleGlzdGluZyBpbnN0YW5jZW9mIEVycm9yIHx8ICFleGlzdGluZykge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCBleGlzdGluZ1ZlcmNlbCA9XG4gICAgICBleGlzdGluZy5wcm92aWRlck1ldGFkYXRhPy5wcm92aWRlciA9PT0gXCJ2ZXJjZWxcIlxuICAgICAgICA/IGV4aXN0aW5nLnByb3ZpZGVyTWV0YWRhdGFcbiAgICAgICAgOiBudWxsO1xuICAgIGF3YWl0IHN0b3JhZ2Uuc2FuZGJveC51cGRhdGUoe1xuICAgICAgaWQ6IGV4aXN0aW5nLmlkLFxuICAgICAgbGFzdEFjdGl2aXR5QXQ6IG5vdyxcbiAgICAgIGFjcXVpcmluZ0xvY2tJZDogbnVsbCxcbiAgICAgIGFjcXVpcmluZ0xvY2tBdDogbnVsbCxcbiAgICAgIHByb3ZpZGVyTWV0YWRhdGE6IGV4aXN0aW5nVmVyY2VsID8/IHtcbiAgICAgICAgcHJvdmlkZXI6IFwidmVyY2VsXCIsXG4gICAgICAgIHNhbmRib3hJZDogbnVsbCxcbiAgICAgICAgc25hcHNob3RJZDogbnVsbCxcbiAgICAgIH0sXG4gICAgfSk7XG4gIH1cblxuICBsZXQgc3RhcnRQcm9taXNlOiBQcm9taXNlPFNhbmRib3hFcnJvciB8IHVuZGVmaW5lZD4gfCBudWxsID0gbnVsbDtcblxuICBjb25zdCBsaWZlY3ljbGU6IFNhbmRib3hMaWZlY3ljbGUgPSB7XG4gICAgc3RhcnQ6ICgpID0+IHtcbiAgICAgIGlmIChzdGFydFByb21pc2UpIHtcbiAgICAgICAgcmV0dXJuIHN0YXJ0UHJvbWlzZTtcbiAgICAgIH1cbiAgICAgIHN0YXJ0UHJvbWlzZSA9IChhc3luYyAoKSA9PiB7XG4gICAgICAgIGlmICghc2V0dXAgJiYgc2FuZGJveFJlY29yZC5zZXR1cEtleSkge1xuICAgICAgICAgIGF3YWl0IHBvbGxGb3JTZXR1cENvbXBsZXRpb24oe1xuICAgICAgICAgICAgc3RvcmFnZTogcG9sbFN0b3JhZ2UsXG4gICAgICAgICAgICBzYW5kYm94SWQ6IHNhbmRib3hSZWNvcmQuaWQsXG4gICAgICAgICAgICBzZXR1cEtleTogc2FuZGJveFJlY29yZC5zZXR1cEtleSxcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGdldFNhbmRib3hSZXN1bHQoKTtcbiAgICAgICAgaWYgKHJlc3VsdCBpbnN0YW5jZW9mIEVycm9yKSB7XG4gICAgICAgICAgc3RhcnRQcm9taXNlID0gbnVsbDtcbiAgICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgICB9XG4gICAgICAgIGF3YWl0IHVwZGF0ZUxhc3RBY3Rpdml0eSgpO1xuXG4gICAgICAgIGlmIChyZXN1bHQubmVlZHNTZXR1cFJ1biAmJiBzZXR1cCkge1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICBhd2FpdCBzZXR1cC5ydW4oc2FuZGJveCk7XG4gICAgICAgICAgICBhd2FpdCBtYXJrU2V0dXBDb21wbGV0ZSh7XG4gICAgICAgICAgICAgIHN0b3JhZ2UsXG4gICAgICAgICAgICAgIHNhbmRib3hJZDogc2FuZGJveFJlY29yZC5pZCxcbiAgICAgICAgICAgICAgc2V0dXBLZXk6IHNldHVwLmtleSxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgIGF3YWl0IHJlc2V0U2V0dXBTdGF0ZSh7XG4gICAgICAgICAgICAgIHN0b3JhZ2UsXG4gICAgICAgICAgICAgIHNhbmRib3hJZDogc2FuZGJveFJlY29yZC5pZCxcbiAgICAgICAgICAgICAgc2V0dXBLZXk6IHNldHVwLmtleSxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgdGhyb3cgZTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBpZiAocmVzdWx0LmNyZWF0ZWRGcm9tU25hcHNob3QgJiYgb25SZXN0YXJ0KSB7XG4gICAgICAgICAgYXdhaXQgb25SZXN0YXJ0KHNhbmRib3gpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgIH0pKCkuY2F0Y2goKGUpID0+IHtcbiAgICAgICAgc3RhcnRQcm9taXNlID0gbnVsbDtcbiAgICAgICAgdGhyb3cgZTtcbiAgICAgIH0pO1xuICAgICAgcmV0dXJuIHN0YXJ0UHJvbWlzZTtcbiAgICB9LFxuXG4gICAgc25hcHNob3Q6IGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IHNhbmRib3ggPSBhd2FpdCBnZXRTYW5kYm94SW5zdGFuY2UoKTtcbiAgICAgIGlmIChzYW5kYm94IGluc3RhbmNlb2YgRXJyb3IpIHtcbiAgICAgICAgcmV0dXJuIHNhbmRib3g7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBlcnJvcmUudHJ5QXN5bmMoe1xuICAgICAgICB0cnk6IGFzeW5jICgpID0+IHtcbiAgICAgICAgICBjb25zdCBzbmFwc2hvdCA9IGF3YWl0IHNhbmRib3guc25hcHNob3QoKTtcbiAgICAgICAgICBhd2FpdCBzdG9yYWdlLnNhbmRib3gudXBkYXRlKHtcbiAgICAgICAgICAgIGlkLFxuICAgICAgICAgICAgYWNxdWlyaW5nTG9ja0lkOiBudWxsLFxuICAgICAgICAgICAgYWNxdWlyaW5nTG9ja0F0OiBudWxsLFxuICAgICAgICAgICAgcHJvdmlkZXJNZXRhZGF0YToge1xuICAgICAgICAgICAgICBwcm92aWRlcjogXCJ2ZXJjZWxcIixcbiAgICAgICAgICAgICAgc2FuZGJveElkOiBudWxsLFxuICAgICAgICAgICAgICBzbmFwc2hvdElkOiBzbmFwc2hvdC5zbmFwc2hvdElkLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9KTtcbiAgICAgICAgICByZXR1cm4geyBzbmFwc2hvdElkOiBzbmFwc2hvdC5zbmFwc2hvdElkIH07XG4gICAgICAgIH0sXG4gICAgICAgIGNhdGNoOiAoZSkgPT4gbmV3IFNhbmRib3hFcnJvcih7IHJlYXNvbjogU3RyaW5nKGUpLCBjYXVzZTogZSB9KSxcbiAgICAgIH0pO1xuICAgIH0sXG5cbiAgICBzdG9wOiBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCBzYW5kYm94ID0gYXdhaXQgZ2V0U2FuZGJveEluc3RhbmNlKCk7XG4gICAgICBpZiAoc2FuZGJveCBpbnN0YW5jZW9mIEVycm9yKSB7XG4gICAgICAgIHJldHVybiBzYW5kYm94O1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gZXJyb3JlLnRyeUFzeW5jKHtcbiAgICAgICAgdHJ5OiBhc3luYyAoKSA9PiB7XG4gICAgICAgICAgYXdhaXQgc2FuZGJveC5zdG9wKCk7XG4gICAgICAgICAgYXdhaXQgc3RvcmFnZS5zYW5kYm94LnVwZGF0ZSh7XG4gICAgICAgICAgICBpZCxcbiAgICAgICAgICAgIGFjcXVpcmluZ0xvY2tJZDogbnVsbCxcbiAgICAgICAgICAgIGFjcXVpcmluZ0xvY2tBdDogbnVsbCxcbiAgICAgICAgICAgIHByb3ZpZGVyTWV0YWRhdGE6IHtcbiAgICAgICAgICAgICAgcHJvdmlkZXI6IFwidmVyY2VsXCIsXG4gICAgICAgICAgICAgIHNhbmRib3hJZDogbnVsbCxcbiAgICAgICAgICAgICAgc25hcHNob3RJZDogbnVsbCxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSk7XG4gICAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgICAgfSxcbiAgICAgICAgY2F0Y2g6IChlKSA9PiBuZXcgU2FuZGJveEVycm9yKHsgcmVhc29uOiBTdHJpbmcoZSksIGNhdXNlOiBlIH0pLFxuICAgICAgfSk7XG4gICAgfSxcblxuICAgIGdldFN0YXR1czogYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3Qgc2FuZGJveCA9IGF3YWl0IGdldFNhbmRib3hJbnN0YW5jZSgpO1xuICAgICAgaWYgKHNhbmRib3ggaW5zdGFuY2VvZiBFcnJvcikge1xuICAgICAgICByZXR1cm4gc2FuZGJveDtcbiAgICAgIH1cbiAgICAgIHJldHVybiBzYW5kYm94LnN0YXR1cyBhcyBTYW5kYm94U3RhdHVzO1xuICAgIH0sXG5cbiAgICBnZXRDcmVhdGVkQXQ6IGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IHNhbmRib3ggPSBhd2FpdCBnZXRTYW5kYm94SW5zdGFuY2UoKTtcbiAgICAgIGlmIChzYW5kYm94IGluc3RhbmNlb2YgRXJyb3IpIHtcbiAgICAgICAgcmV0dXJuIHNhbmRib3g7XG4gICAgICB9XG4gICAgICByZXR1cm4gc2FuZGJveC5jcmVhdGVkQXQ7XG4gICAgfSxcblxuICAgIGdldFJlbWFpbmluZ1RpbWVvdXQ6IGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IHNhbmRib3ggPSBhd2FpdCBnZXRTYW5kYm94SW5zdGFuY2UoKTtcbiAgICAgIGlmIChzYW5kYm94IGluc3RhbmNlb2YgRXJyb3IpIHtcbiAgICAgICAgcmV0dXJuIHNhbmRib3g7XG4gICAgICB9XG4gICAgICByZXR1cm4gc2FuZGJveC50aW1lb3V0O1xuICAgIH0sXG4gIH07XG5cbiAgYXN5bmMgZnVuY3Rpb24gZG9FeGVjKG9wdHM6IHtcbiAgICBjb21tYW5kOiBzdHJpbmc7XG4gICAgYXJncz86IHN0cmluZ1tdO1xuICAgIGN3ZD86IHN0cmluZztcbiAgICBlbnY/OiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+O1xuICAgIHNpZ25hbD86IEFib3J0U2lnbmFsO1xuICAgIHN1ZG8/OiBib29sZWFuO1xuICB9KSB7XG4gICAgY29uc3QgaW5zdGFuY2UgPSBhd2FpdCBnZXRTYW5kYm94SW5zdGFuY2UoKTtcbiAgICBpZiAoaW5zdGFuY2UgaW5zdGFuY2VvZiBFcnJvcikge1xuICAgICAgcmV0dXJuIGluc3RhbmNlO1xuICAgIH1cblxuICAgIGNvbnN0IHVwZGF0ZVByb21pc2UgPSB1cGRhdGVMYXN0QWN0aXZpdHkoKTtcbiAgICBjb25zdCBleGVjUmVzdWx0ID0gYXdhaXQgZXhlY09uSW5zdGFuY2UoaW5zdGFuY2UsIG9wdHMpO1xuICAgIGF3YWl0IHVwZGF0ZVByb21pc2U7XG4gICAgcmV0dXJuIGV4ZWNSZXN1bHQ7XG4gIH1cblxuICBjb25zdCBzYW5kYm94OiBTYW5kYm94PFRUYWdzPiA9IHtcbiAgICBpZCxcbiAgICBjb25maWcsXG4gICAgY3dkLFxuICAgIGV4ZWM6IGFzeW5jIChvcHRzKSA9PiB7XG4gICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBkb0V4ZWMob3B0cyk7XG5cbiAgICAgIGlmIChyZXN1bHQgaW5zdGFuY2VvZiBTYW5kYm94RXJyb3IgJiYgaXNTYW5kYm94R29uZUVycm9yKHJlc3VsdC5jYXVzZSkpIHtcbiAgICAgICAgYXdhaXQgcmVjb3ZlckZyb21TdGFsZVNhbmRib3goKTtcbiAgICAgICAgcmV0dXJuIGF3YWl0IGRvRXhlYyhvcHRzKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9LFxuXG4gICAgZ2V0RG9tYWluOiBhc3luYyAocG9ydCkgPT4ge1xuICAgICAgY29uc3Qgc2FuZGJveCA9IGF3YWl0IGdldFNhbmRib3hJbnN0YW5jZSgpO1xuICAgICAgaWYgKHNhbmRib3ggaW5zdGFuY2VvZiBFcnJvcikge1xuICAgICAgICByZXR1cm4gc2FuZGJveDtcbiAgICAgIH1cblxuICAgICAgdHJ5IHtcbiAgICAgICAgcmV0dXJuIHNhbmRib3guZG9tYWluKHBvcnQpO1xuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICByZXR1cm4gbmV3IFNhbmRib3hFcnJvcih7IHJlYXNvbjogU3RyaW5nKGUpLCBjYXVzZTogZSB9KTtcbiAgICAgIH1cbiAgICB9LFxuXG4gICAga2lsbDogYXN5bmMgKHsgY29tbWFuZElkLCBzdG9yYWdlOiBjbWRTdG9yYWdlIH0pID0+IHtcbiAgICAgIGNvbnN0IGluc3RhbmNlID0gYXdhaXQgZ2V0U2FuZGJveEluc3RhbmNlKCk7XG4gICAgICBpZiAoaW5zdGFuY2UgaW5zdGFuY2VvZiBFcnJvcikge1xuICAgICAgICByZXR1cm4gaW5zdGFuY2U7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGNtZCA9IGF3YWl0IGNtZFN0b3JhZ2UuY29tbWFuZC5nZXQoY29tbWFuZElkKTtcbiAgICAgIGlmIChjbWQgaW5zdGFuY2VvZiBFcnJvcikge1xuICAgICAgICByZXR1cm4gbmV3IFNhbmRib3hFcnJvcih7IHJlYXNvbjogY21kLm1lc3NhZ2UsIGNhdXNlOiBjbWQgfSk7XG4gICAgICB9XG4gICAgICBpZiAoY21kICYmIGNtZC5zdGF0dXMgPT09IFwicnVubmluZ1wiKSB7XG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGNtZFN0b3JhZ2UuY29tbWFuZC5zZXQoe1xuICAgICAgICAgIC4uLmNtZCxcbiAgICAgICAgICBzdGF0dXM6IFwia2lsbGVkXCIsXG4gICAgICAgIH0pO1xuICAgICAgICBpZiAocmVzdWx0IGluc3RhbmNlb2YgRXJyb3IpIHtcbiAgICAgICAgICByZXR1cm4gbmV3IFNhbmRib3hFcnJvcih7IHJlYXNvbjogcmVzdWx0Lm1lc3NhZ2UsIGNhdXNlOiByZXN1bHQgfSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfSxcblxuICAgIHJlYWRGaWxlOiBhc3luYyAob3B0cykgPT4ge1xuICAgICAgY29uc3QgaW5zdGFuY2UgPSBhd2FpdCBnZXRTYW5kYm94SW5zdGFuY2UoKTtcbiAgICAgIGlmIChpbnN0YW5jZSBpbnN0YW5jZW9mIEVycm9yKSB7XG4gICAgICAgIHJldHVybiBpbnN0YW5jZTtcbiAgICAgIH1cbiAgICAgIHJldHVybiByZWFkRmlsZU9uSW5zdGFuY2UoaW5zdGFuY2UsIG9wdHMpO1xuICAgIH0sXG5cbiAgICB3cml0ZUZpbGVzOiBhc3luYyAob3B0cykgPT4ge1xuICAgICAgY29uc3QgaW5zdGFuY2UgPSBhd2FpdCBnZXRTYW5kYm94SW5zdGFuY2UoKTtcbiAgICAgIGlmIChpbnN0YW5jZSBpbnN0YW5jZW9mIEVycm9yKSB7XG4gICAgICAgIHRocm93IGluc3RhbmNlO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHdyaXRlRmlsZXNPbkluc3RhbmNlKGluc3RhbmNlLCBvcHRzKTtcbiAgICB9LFxuXG4gICAgbGlmZWN5Y2xlLFxuXG4gICAgdXBkYXRlTmV0d29ya1BvbGljeTogYXN5bmMgKHBvbGljeSkgPT4ge1xuICAgICAgY29uc3QgaW5zdGFuY2UgPSBhd2FpdCBnZXRTYW5kYm94SW5zdGFuY2UoKTtcbiAgICAgIGlmIChpbnN0YW5jZSBpbnN0YW5jZW9mIEVycm9yKSB7XG4gICAgICAgIHJldHVybiBpbnN0YW5jZTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBlcnJvcmUudHJ5QXN5bmMoe1xuICAgICAgICB0cnk6ICgpID0+IGluc3RhbmNlLnVwZGF0ZU5ldHdvcmtQb2xpY3kocG9saWN5KSxcbiAgICAgICAgY2F0Y2g6IChlKSA9PiBuZXcgU2FuZGJveEVycm9yKHsgcmVhc29uOiBTdHJpbmcoZSksIGNhdXNlOiBlIH0pLFxuICAgICAgfSk7XG4gICAgfSxcblxuICAgIHRhZzoge1xuICAgICAgbGlzdDogYXN5bmMgKCkgPT4ge1xuICAgICAgICBjb25zdCBzYW5kYm94UmVjb3JkID0gYXdhaXQgc3RvcmFnZS5zYW5kYm94LmdldChpZCk7XG4gICAgICAgIGlmIChzYW5kYm94UmVjb3JkIGluc3RhbmNlb2YgRXJyb3IpIHtcbiAgICAgICAgICByZXR1cm4gc2FuZGJveFJlY29yZDtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gKHNhbmRib3hSZWNvcmQudGFncyA/PyB7fSkgYXMgVFRhZ3M7XG4gICAgICB9LFxuICAgICAgZ2V0OiBhc3luYyAoa2V5OiBzdHJpbmcpID0+IHtcbiAgICAgICAgY29uc3Qgc2FuZGJveFJlY29yZCA9IGF3YWl0IHN0b3JhZ2Uuc2FuZGJveC5nZXQoaWQpO1xuICAgICAgICBpZiAoc2FuZGJveFJlY29yZCBpbnN0YW5jZW9mIEVycm9yKSB7XG4gICAgICAgICAgcmV0dXJuIHNhbmRib3hSZWNvcmQ7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHNhbmRib3hSZWNvcmQudGFncz8uW2tleSBhcyBzdHJpbmddIGFzXG4gICAgICAgICAgfCBUVGFnc1t0eXBlb2Yga2V5XVxuICAgICAgICAgIHwgdW5kZWZpbmVkO1xuICAgICAgfSxcbiAgICAgIHNldDogYXN5bmMgKGtleTogc3RyaW5nLCB2YWx1ZTogdW5rbm93bikgPT4ge1xuICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBzdG9yYWdlLnNhbmRib3gudGFnLnNldCh7XG4gICAgICAgICAgc2FuZGJveElkOiBpZCxcbiAgICAgICAgICB0YWdzOiB7IFtrZXldOiB2YWx1ZSB9IGFzIFJlY29yZDxzdHJpbmcsIHVua25vd24+LFxuICAgICAgICB9KTtcbiAgICAgICAgaWYgKHJlc3VsdCBpbnN0YW5jZW9mIEVycm9yKSB7XG4gICAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgfSxcbiAgICAgIHNldE1hbnk6IGFzeW5jICh0YWdzOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPikgPT4ge1xuICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBzdG9yYWdlLnNhbmRib3gudGFnLnNldCh7XG4gICAgICAgICAgc2FuZGJveElkOiBpZCxcbiAgICAgICAgICB0YWdzOiB0YWdzIGFzIFJlY29yZDxzdHJpbmcsIHVua25vd24+LFxuICAgICAgICB9KTtcbiAgICAgICAgaWYgKHJlc3VsdCBpbnN0YW5jZW9mIEVycm9yKSB7XG4gICAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgfSxcbiAgICB9LFxuICB9O1xuXG4gIHJldHVybiBzYW5kYm94O1xufTtcbiIsICJpbXBvcnQgdHlwZSB7IFRhZ3NTY2hlbWEgfSBmcm9tIFwiLi4vaW5kZXhcIjtcbmltcG9ydCB0eXBlIHsgUnBjRm4sIFNhbmRib3hSZWNvcmQsIFN0b3JhZ2UsIFN0b3JhZ2VDb25maWcgfSBmcm9tIFwiLi4vc3RvcmFnZVwiO1xuaW1wb3J0IHsgY3JlYXRlTG9nZ2VyIH0gZnJvbSBcIi4uL3V0aWxzL2xvZ2dlclwiO1xuaW1wb3J0IHsgZG9ja2VyU2FuZGJveCB9IGZyb20gXCIuL2JpbmRpbmdzL2RvY2tlclwiO1xuaW1wb3J0IHsgbG9jYWxTYW5kYm94IH0gZnJvbSBcIi4vYmluZGluZ3MvbG9jYWxcIjtcbmltcG9ydCB7IHZlcmNlbFNhbmRib3ggfSBmcm9tIFwiLi9iaW5kaW5ncy92ZXJjZWxcIjtcbmltcG9ydCB0eXBlIHsgT25SZXN0YXJ0LCBTYW5kYm94LCBTYW5kYm94U2V0dXAgfSBmcm9tIFwiLi90eXBlc1wiO1xuXG5jb25zdCBsb2cgPSBjcmVhdGVMb2dnZXIoeyBzdWJzeXN0ZW06IFwic2FuZGJveFwiIH0pO1xuXG50eXBlIFNhbmRib3hXaXRoTWV0YTxUVGFncyBleHRlbmRzIFRhZ3NTY2hlbWEgPSBUYWdzU2NoZW1hPiA9IFNhbmRib3g8VFRhZ3M+ICYge1xuICBfb25SZWFkeT86IFByb21pc2U8dm9pZD47XG59O1xuXG4vKipcbiAqIE1vZHVsZS1sZXZlbCBjYWNoZSBmb3Igc2FuZGJveCBpbnN0YW5jZXMga2V5ZWQgYnkgc2FuZGJveCByZWNvcmQgSUQuXG4gKlxuICogQ2FjaGVzIGFsbCBzYW5kYm94IGluc3RhbmNlcyBzbyB0aGF0IHRoZSB3b3JrZmxvdyAod2hpY2ggY2FsbHMgZ2V0U2FuZGJveFxuICogd2l0aG91dCBzZXR1cC9vblJlc3RhcnQpIHJldXNlcyB0aGUgc2FtZSBpbnN0YW5jZSBjcmVhdGVkIGR1cmluZyBzZXNzaW9uKCksXG4gKiBpbmNsdWRpbmcgaXRzIF9vblJlYWR5IHByb21pc2UuXG4gKi9cbmNvbnN0IHNhbmRib3hDYWNoZSA9IG5ldyBNYXA8c3RyaW5nLCBTYW5kYm94V2l0aE1ldGE+KCk7XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRTYW5kYm94PFRUYWdzIGV4dGVuZHMgVGFnc1NjaGVtYSA9IFRhZ3NTY2hlbWE+KHtcbiAgc2FuZGJveFJlY29yZCxcbiAgc3RvcmFnZUNvbmZpZyxcbiAgc3RvcmFnZSxcbiAgcnBjLFxuICBlbmFibGVMaWZlY3ljbGVXb3JrZmxvdyA9IHRydWUsXG4gIHNldHVwLFxuICBvblJlc3RhcnQsXG59OiB7XG4gIHN0b3JhZ2VDb25maWc6IFN0b3JhZ2VDb25maWc7XG4gIHNhbmRib3hSZWNvcmQ6IFNhbmRib3hSZWNvcmQ7XG4gIHN0b3JhZ2U6IFN0b3JhZ2U7XG4gIHJwYzogUnBjRm47XG4gIGVuYWJsZUxpZmVjeWNsZVdvcmtmbG93PzogYm9vbGVhbjtcbiAgc2V0dXA/OiBTYW5kYm94U2V0dXA7XG4gIG9uUmVzdGFydD86IE9uUmVzdGFydDtcbn0pOiBTYW5kYm94V2l0aE1ldGE8VFRhZ3M+IHtcbiAgY29uc3QgY2FjaGVkID0gc2FuZGJveENhY2hlLmdldChzYW5kYm94UmVjb3JkLmlkKTtcbiAgaWYgKGNhY2hlZCkge1xuICAgIHJldHVybiBjYWNoZWQgYXMgU2FuZGJveFdpdGhNZXRhPFRUYWdzPjtcbiAgfVxuXG4gIGNvbnN0IHNieCA9IGNyZWF0ZVNhbmRib3g8VFRhZ3M+KHtcbiAgICBzYW5kYm94UmVjb3JkLFxuICAgIHN0b3JhZ2VDb25maWcsXG4gICAgc3RvcmFnZSxcbiAgICBycGMsXG4gICAgZW5hYmxlTGlmZWN5Y2xlV29ya2Zsb3csXG4gICAgc2V0dXAsXG4gICAgb25SZXN0YXJ0LFxuICB9KTtcblxuICBjYWNoZVNhbmRib3goc2FuZGJveFJlY29yZC5pZCwgc2J4KTtcblxuICByZXR1cm4gc2J4O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZXZpY3RTYW5kYm94KGlkOiBzdHJpbmcpOiB2b2lkIHtcbiAgc2FuZGJveENhY2hlLmRlbGV0ZShpZCk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBjYWNoZVNhbmRib3goaWQ6IHN0cmluZywgc2FuZGJveDogU2FuZGJveCk6IHZvaWQge1xuICBzYW5kYm94Q2FjaGUuc2V0KGlkLCBzYW5kYm94IGFzIFNhbmRib3hXaXRoTWV0YSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVTYW5kYm94PFRUYWdzIGV4dGVuZHMgVGFnc1NjaGVtYSA9IFRhZ3NTY2hlbWE+KHtcbiAgc2FuZGJveFJlY29yZCxcbiAgc3RvcmFnZUNvbmZpZyxcbiAgc3RvcmFnZSxcbiAgcnBjLFxuICBlbmFibGVMaWZlY3ljbGVXb3JrZmxvdyA9IHRydWUsXG4gIHNldHVwLFxuICBvblJlc3RhcnQsXG59OiB7XG4gIHN0b3JhZ2VDb25maWc6IFN0b3JhZ2VDb25maWc7XG4gIHNhbmRib3hSZWNvcmQ6IFNhbmRib3hSZWNvcmQ7XG4gIHN0b3JhZ2U6IFN0b3JhZ2U7XG4gIHJwYzogUnBjRm47XG4gIGVuYWJsZUxpZmVjeWNsZVdvcmtmbG93PzogYm9vbGVhbjtcbiAgc2V0dXA/OiBTYW5kYm94U2V0dXA7XG4gIG9uUmVzdGFydD86IE9uUmVzdGFydDtcbn0pOiBTYW5kYm94V2l0aE1ldGE8VFRhZ3M+IHtcbiAgbGV0IHNieDogU2FuZGJveDxUVGFncz47XG5cbiAgLy8gU2NvcGUgc2V0dXAga2V5IGJ5IHNhbmRib3ggdHlwZSBzbyBhIHNldHVwIGNvbXBsZXRlZCBvbiBvbmUgcHJvdmlkZXJcbiAgLy8gKGUuZy4gXCJsb2NhbFwiKSBkb2Vzbid0IGNvdW50IGFzIGRvbmUgZm9yIGFub3RoZXIgKGUuZy4gXCJkb2NrZXJcIikuXG4gIGNvbnN0IHNjb3BlZFNldHVwOiBTYW5kYm94U2V0dXAgfCB1bmRlZmluZWQgPSBzZXR1cFxuICAgID8ge1xuICAgICAgICAuLi5zZXR1cCxcbiAgICAgICAga2V5OiBgJHtzYW5kYm94UmVjb3JkLmNvbmZpZy50eXBlfToke3NldHVwLmtleX1gLFxuICAgICAgfVxuICAgIDogdW5kZWZpbmVkO1xuXG4gIGNvbnN0IHJlY29yZFdpdGhTZXR1cEtleSA9IHNjb3BlZFNldHVwXG4gICAgPyB7IC4uLnNhbmRib3hSZWNvcmQsIHNldHVwS2V5OiBzY29wZWRTZXR1cC5rZXkgfVxuICAgIDogc2FuZGJveFJlY29yZDtcblxuICBzd2l0Y2ggKHNhbmRib3hSZWNvcmQuY29uZmlnLnR5cGUpIHtcbiAgICBjYXNlIFwibG9jYWxcIjpcbiAgICAgIHNieCA9IGxvY2FsU2FuZGJveDxUVGFncz4oe1xuICAgICAgICBzYW5kYm94UmVjb3JkOiByZWNvcmRXaXRoU2V0dXBLZXkgYXMgU2FuZGJveFJlY29yZCAmIHtcbiAgICAgICAgICBjb25maWc6IHsgdHlwZTogXCJsb2NhbFwiIH07XG4gICAgICAgIH0sXG4gICAgICAgIHN0b3JhZ2UsXG4gICAgICAgIHNldHVwOiBzY29wZWRTZXR1cCxcbiAgICAgICAgb25SZXN0YXJ0LFxuICAgICAgfSk7XG4gICAgICBicmVhaztcbiAgICBjYXNlIFwiZG9ja2VyXCI6XG4gICAgICBzYnggPSBkb2NrZXJTYW5kYm94PFRUYWdzPih7XG4gICAgICAgIHNhbmRib3hSZWNvcmQ6IHJlY29yZFdpdGhTZXR1cEtleSBhcyBTYW5kYm94UmVjb3JkICYge1xuICAgICAgICAgIGNvbmZpZzogeyB0eXBlOiBcImRvY2tlclwiIH07XG4gICAgICAgIH0sXG4gICAgICAgIHN0b3JhZ2UsXG4gICAgICAgIHNldHVwOiBzY29wZWRTZXR1cCxcbiAgICAgICAgb25SZXN0YXJ0LFxuICAgICAgfSk7XG4gICAgICBicmVhaztcbiAgICBjYXNlIFwidmVyY2VsXCI6XG4gICAgICBzYnggPSB2ZXJjZWxTYW5kYm94PFRUYWdzPih7XG4gICAgICAgIHNhbmRib3hSZWNvcmQ6IHJlY29yZFdpdGhTZXR1cEtleSBhcyBTYW5kYm94UmVjb3JkICYge1xuICAgICAgICAgIGNvbmZpZzogeyB0eXBlOiBcInZlcmNlbFwiIH07XG4gICAgICAgIH0sXG4gICAgICAgIHN0b3JhZ2VDb25maWcsXG4gICAgICAgIHN0b3JhZ2UsXG4gICAgICAgIHJwYyxcbiAgICAgICAgZW5hYmxlTGlmZWN5Y2xlV29ya2Zsb3csXG4gICAgICAgIHNldHVwOiBzY29wZWRTZXR1cCxcbiAgICAgICAgb25SZXN0YXJ0LFxuICAgICAgfSk7XG4gICAgICBicmVhaztcbiAgICBjYXNlIFwiY3VzdG9tXCI6XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJDdXN0b20gc2FuZGJveGVzIGFyZSBub3Qgc3VwcG9ydGVkXCIpO1xuICAgIGRlZmF1bHQ6XG4gICAgICBzYW5kYm94UmVjb3JkLmNvbmZpZyBzYXRpc2ZpZXMgbmV2ZXI7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgIGBVbmtub3duIHNhbmRib3ggdHlwZTogJHtcbiAgICAgICAgICAvLyBiaW9tZS1pZ25vcmUgbGludC9zdXNwaWNpb3VzL25vRXhwbGljaXRBbnk6IC5cbiAgICAgICAgICAoc2FuZGJveFJlY29yZC5jb25maWcgYXMgYW55KS50eXBlXG4gICAgICAgIH1gXG4gICAgICApO1xuICB9XG5cbiAgbGV0IHJlYWR5UHJvbWlzZTogUHJvbWlzZTx2b2lkPiB8IG51bGwgPSBudWxsO1xuICBsZXQgcHVibGljT25SZWFkeTogUHJvbWlzZTx2b2lkPiB8IHVuZGVmaW5lZDtcblxuICBmdW5jdGlvbiBlbnN1cmVSZWFkeSgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBpZiAocmVhZHlQcm9taXNlKSB7XG4gICAgICByZXR1cm4gcmVhZHlQcm9taXNlO1xuICAgIH1cbiAgICByZWFkeVByb21pc2UgPSAoYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3QgZG9uZSA9IGxvZy50aW1lKFwiZW5zdXJlUmVhZHkgLyBsaWZlY3ljbGUuc3RhcnRcIiwge1xuICAgICAgICBzYW5kYm94SWQ6IHNhbmRib3hSZWNvcmQuaWQsXG4gICAgICB9KTtcbiAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHNieC5saWZlY3ljbGUuc3RhcnQoKTtcbiAgICAgIGRvbmUoKTtcbiAgICAgIGlmIChyZXN1bHQgaW5zdGFuY2VvZiBFcnJvcikge1xuICAgICAgICB0aHJvdyByZXN1bHQ7XG4gICAgICB9XG4gICAgfSkoKS5jYXRjaCgoZSkgPT4ge1xuICAgICAgcmVhZHlQcm9taXNlID0gbnVsbDtcbiAgICAgIHB1YmxpY09uUmVhZHkgPSB1bmRlZmluZWQ7XG4gICAgICB0aHJvdyBlO1xuICAgIH0pO1xuICAgIHB1YmxpY09uUmVhZHkgPSByZWFkeVByb21pc2U7XG4gICAgcmV0dXJuIHJlYWR5UHJvbWlzZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBFYWdlcmx5IGtpY2sgb2ZmIHN0YXJ0IHVubGVzcyBhdXRvU3RhcnQgaXMgZmFsc2UuXG4gICAqIFRoZSB2ZXJjZWwgYmluZGluZyBhbHNvIHByZS13YXJtcyB0aGUgc2FuZGJveCBwcm9taXNlIGludGVybmFsbHlcbiAgICogd2hlbiBhdXRvU3RhcnQgIT09IGZhbHNlLCBzbyB0aGlzIGp1c3QgbGF5ZXJzIHNldHVwL2NvbGQtc3RhcnQgb24gdG9wLlxuICAgKi9cbiAgY29uc3QgYXV0b1N0YXJ0ID1cbiAgICBzYW5kYm94UmVjb3JkLmNvbmZpZy50eXBlID09PSBcInZlcmNlbFwiXG4gICAgICA/IHNhbmRib3hSZWNvcmQuY29uZmlnLmxpZmVjeWNsZT8uYXV0b1N0YXJ0ICE9PSBmYWxzZVxuICAgICAgOiB0cnVlO1xuXG4gIGlmIChhdXRvU3RhcnQpIHtcbiAgICBlbnN1cmVSZWFkeSgpO1xuICB9XG5cbiAgLyoqXG4gICAqIFdyYXAgc2FuZGJveCBtZXRob2RzIHNvIGFueSBvcGVyYXRpb24gaW1wbGljaXRseSB3YWl0cyBmb3Igc3RhcnQuXG4gICAqIFdlIHJldHVybiBhIE5FVyBvYmplY3Qgc28gdGhhdCBzZXR1cC5ydW4oKSwgd2hpY2ggaG9sZHMgdGhlIG9yaWdpbmFsXG4gICAqIGBzYnhgIHZpYSBjbG9zdXJlLCBjYWxscyB1bndyYXBwZWQgbWV0aG9kcyBhbmQgYXZvaWRzIGEgZGVhZGxvY2suXG4gICAqXG4gICAqIF9vblJlYWR5IGlzIGEgcGFzc2l2ZSBnZXR0ZXI6IGl0IHJldHVybnMgdGhlIGN1cnJlbnQgaW4tZmxpZ2h0IHByb21pc2VcbiAgICogKG9yIHVuZGVmaW5lZCkgd2l0aG91dCB0cmlnZ2VyaW5nIHN0YXJ0dXAuIE9ubHkgZW5zdXJlUmVhZHkoKSBhbmQgdGhlXG4gICAqIHdyYXBwZWQgbWV0aG9kcyB0cmlnZ2VyIHN0YXJ0dXAuIFRoaXMgcHJlc2VydmVzIGF1dG9TdGFydDogZmFsc2VcbiAgICogc2VtYW50aWNzIFx1MjAxNCByZWFkaW5nIF9vblJlYWR5IGZvciBzdGF0dXMgZGlzcGxheSBuZXZlciBzdGFydHMgdGhlIHNhbmRib3guXG4gICAqL1xuICByZXR1cm4ge1xuICAgIC4uLnNieCxcbiAgICBnZXQgX29uUmVhZHkoKSB7XG4gICAgICByZXR1cm4gcHVibGljT25SZWFkeTtcbiAgICB9LFxuICAgIGV4ZWM6IGFzeW5jIChvcHRzKSA9PiB7XG4gICAgICBhd2FpdCBlbnN1cmVSZWFkeSgpO1xuICAgICAgcmV0dXJuIHNieC5leGVjKG9wdHMpO1xuICAgIH0sXG4gICAgZ2V0RG9tYWluOiBhc3luYyAocG9ydCkgPT4ge1xuICAgICAgYXdhaXQgZW5zdXJlUmVhZHkoKTtcbiAgICAgIHJldHVybiBzYnguZ2V0RG9tYWluKHBvcnQpO1xuICAgIH0sXG4gICAgcmVhZEZpbGU6IGFzeW5jIChvcHRzKSA9PiB7XG4gICAgICBhd2FpdCBlbnN1cmVSZWFkeSgpO1xuICAgICAgcmV0dXJuIHNieC5yZWFkRmlsZShvcHRzKTtcbiAgICB9LFxuICAgIHdyaXRlRmlsZXM6IGFzeW5jIChvcHRzKSA9PiB7XG4gICAgICBhd2FpdCBlbnN1cmVSZWFkeSgpO1xuICAgICAgcmV0dXJuIHNieC53cml0ZUZpbGVzKG9wdHMpO1xuICAgIH0sXG4gIH07XG59XG4iXSwKICAibWFwcGluZ3MiOiAiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQ0EsU0FBUyxhQUFhO0FBQ3RCLFlBQVksUUFBUTtBQUNwQixZQUFZLFVBQVU7QUFDdEIsWUFBWSxZQUFZO0FBQ3hCLFNBQVMsWUFBWTtBQVlkLElBQU0sZUFBZSxDQUF3QztBQUFBLEVBQ2xFO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQ0YsTUFLc0I7QUFDcEIsUUFBTSxTQUFTLGNBQWM7QUFDN0IsUUFBTSxXQUFXLE9BQU8sT0FBTyxRQUFRLElBQUk7QUFDM0MsUUFBTSxZQUFZLG9CQUFJLElBQTBCO0FBRWhELE1BQUksZUFBeUQ7QUFFN0QsUUFBTSxVQUEwQjtBQUFBLElBQzlCLElBQUksY0FBYztBQUFBLElBQ2xCLFFBQVEsY0FBYztBQUFBLElBQ3RCLEtBQUs7QUFBQSxJQUNMLE1BQU0sQ0FBQyxFQUFFLFNBQVMsTUFBTSxLQUFLLEtBQUssUUFBUSxLQUFLLE1BQU07QUFDbkQsYUFBYyxnQkFBUztBQUFBLFFBQ3JCLEtBQUssTUFBTTtBQUNULGdCQUFNLFlBQVksV0FBVyxLQUFLLENBQUM7QUFDbkMsZ0JBQU0sV0FBVyxPQUFPLFNBQVM7QUFDakMsZ0JBQU0sWUFBWSxPQUNkLENBQUMsU0FBUyxHQUFJLFFBQVEsQ0FBQyxDQUFFLElBQ3hCLFFBQVEsQ0FBQztBQUVkLGdCQUFNLFFBQVEsTUFBTSxVQUFVLFdBQVc7QUFBQSxZQUN2QyxLQUFLLE1BQVcsYUFBUSxVQUFVLEdBQUcsSUFBSTtBQUFBLFlBQ3pDLEtBQUssTUFBTSxFQUFFLEdBQUcsUUFBUSxLQUFLLEdBQUcsSUFBSSxJQUFJO0FBQUEsWUFDeEM7QUFBQSxVQUNGLENBQUM7QUFFRCxvQkFBVSxJQUFJLFdBQVcsS0FBSztBQUU5QixjQUFJLFNBQVM7QUFDYixjQUFJLFNBQVM7QUFDYixnQkFBTSxXQUF1QixDQUFDO0FBQzlCLGNBQUksYUFBa0M7QUFDdEMsY0FBSSxTQUFTO0FBRWIsZ0JBQU0sT0FBTyxHQUFHLFFBQVEsQ0FBQyxTQUEwQjtBQUNqRCxrQkFBTSxNQUFNLE9BQU8sSUFBSTtBQUN2QixzQkFBVTtBQUNWLHFCQUFTLEtBQUssRUFBRSxRQUFRLFVBQVUsTUFBTSxJQUFJLENBQUM7QUFDN0MseUJBQWE7QUFBQSxVQUNmLENBQUM7QUFFRCxnQkFBTSxPQUFPLEdBQUcsUUFBUSxDQUFDLFNBQTBCO0FBQ2pELGtCQUFNLE1BQU0sT0FBTyxJQUFJO0FBQ3ZCLHNCQUFVO0FBQ1YscUJBQVMsS0FBSyxFQUFFLFFBQVEsVUFBVSxNQUFNLElBQUksQ0FBQztBQUM3Qyx5QkFBYTtBQUFBLFVBQ2YsQ0FBQztBQUVELGdCQUFNLFNBQVMsSUFBSSxRQUloQixDQUFDQSxVQUFTLFdBQVc7QUFDdEIsa0JBQU0sR0FBRyxTQUFTLENBQUMsUUFBUTtBQUN6Qix3QkFBVSxPQUFPLFNBQVM7QUFDMUIsdUJBQVM7QUFDVCwyQkFBYTtBQUNiLHFCQUFPLEdBQUc7QUFBQSxZQUNaLENBQUM7QUFFRCxrQkFBTSxHQUFHLFNBQVMsQ0FBQyxTQUF3QjtBQUN6Qyx3QkFBVSxPQUFPLFNBQVM7QUFDMUIsdUJBQVM7QUFDVCwyQkFBYTtBQUNiLGNBQUFBLFNBQVEsRUFBRSxRQUFRLFFBQVEsVUFBVSxRQUFRLEVBQUUsQ0FBQztBQUFBLFlBQ2pELENBQUM7QUFBQSxVQUNILENBQUM7QUFFRCwwQkFBZ0IsT0FBZ0M7QUFDOUMsbUJBQU8sQ0FBQyxVQUFVLFNBQVMsU0FBUyxHQUFHO0FBQ3JDLG9CQUFNLFFBQVEsU0FBUyxNQUFNO0FBQzdCLGtCQUFJLE9BQU87QUFDVCxzQkFBTTtBQUFBLGNBQ1IsV0FBVyxDQUFDLFFBQVE7QUFDbEIsc0JBQU0sSUFBSSxRQUFjLENBQUNBLGFBQVk7QUFDbkMsK0JBQWFBO0FBQUEsZ0JBQ2YsQ0FBQztBQUNELDZCQUFhO0FBQUEsY0FDZjtBQUFBLFlBQ0Y7QUFBQSxVQUNGO0FBRUEsaUJBQU8sUUFBUSxRQUFRLEVBQUUsV0FBVyxNQUFNLE9BQU8sQ0FBQztBQUFBLFFBQ3BEO0FBQUEsUUFDQSxPQUFPLENBQUMsTUFDTixJQUFJLGFBQWEsRUFBRSxRQUFRLE9BQU8sQ0FBQyxHQUFHLE9BQU8sRUFBRSxDQUFDO0FBQUEsTUFDcEQsQ0FBQztBQUFBLElBQ0g7QUFBQSxJQUVBLFdBQVcsQ0FBQyxTQUFTO0FBQ25CLGFBQU8sUUFBUSxRQUFRLG9CQUFvQixJQUFJLEVBQUU7QUFBQSxJQUNuRDtBQUFBLElBRUEsTUFBTSxPQUFPLEVBQUUsV0FBVyxTQUFBQyxTQUFRLE1BQU07QUFDdEMsWUFBTSxRQUFRLFVBQVUsSUFBSSxTQUFTO0FBQ3JDLFVBQUksQ0FBQyxPQUFPO0FBQ1YsZUFBTyxJQUFJLGFBQWE7QUFBQSxVQUN0QixRQUFRLFdBQVcsU0FBUztBQUFBLFFBQzlCLENBQUM7QUFBQSxNQUNIO0FBRUEsWUFBTSxLQUFLLFNBQVM7QUFFcEIsWUFBTSxNQUFNLE1BQU1BLFNBQVEsUUFBUSxJQUFJLFNBQVM7QUFDL0MsVUFBSSxlQUFlLE9BQU87QUFDeEIsZUFBTyxJQUFJLGFBQWEsRUFBRSxRQUFRLElBQUksU0FBUyxPQUFPLElBQUksQ0FBQztBQUFBLE1BQzdEO0FBQ0EsVUFBSSxPQUFPLElBQUksV0FBVyxXQUFXO0FBQ25DLGNBQU0sU0FBUyxNQUFNQSxTQUFRLFFBQVEsSUFBSTtBQUFBLFVBQ3ZDLEdBQUc7QUFBQSxVQUNILFFBQVE7QUFBQSxRQUNWLENBQUM7QUFDRCxZQUFJLGtCQUFrQixPQUFPO0FBQzNCLGlCQUFPLElBQUksYUFBYSxFQUFFLFFBQVEsT0FBTyxTQUFTLE9BQU8sT0FBTyxDQUFDO0FBQUEsUUFDbkU7QUFBQSxNQUNGO0FBQUEsSUFDRjtBQUFBLElBRUEsVUFBVSxPQUFPLEVBQUUsTUFBTSxTQUFTLE1BQU07QUFDdEMsWUFBTSxXQUFnQixVQUFLLFVBQVUsUUFBUTtBQUM3QyxVQUFJO0FBQ0YsZUFBTyxNQUFTLFlBQVMsUUFBUTtBQUFBLE1BQ25DLFNBQVMsR0FBWTtBQUNuQixZQUNFLGFBQWEsU0FDYixVQUFVLEtBQ1QsRUFBNEIsU0FBUyxVQUN0QztBQUNBLGlCQUFPO0FBQUEsUUFDVDtBQUNBLGVBQU8sSUFBSSxhQUFhLEVBQUUsUUFBUSxPQUFPLENBQUMsR0FBRyxPQUFPLEVBQUUsQ0FBQztBQUFBLE1BQ3pEO0FBQUEsSUFDRjtBQUFBLElBRUEsWUFBWSxDQUFDLFNBQVMsV0FBVyxFQUFFLFNBQVMsR0FBRyxLQUFLLENBQUM7QUFBQSxJQUVyRCxxQkFBcUIsTUFDbkIsUUFBUTtBQUFBLE1BQ04sSUFBSSxhQUFhO0FBQUEsUUFDZixRQUFRO0FBQUEsTUFDVixDQUFDO0FBQUEsSUFDSDtBQUFBLElBRUYsV0FBVztBQUFBLE1BQ1QsT0FBTyxNQUFNO0FBQ1gsWUFBSSxjQUFjO0FBQ2hCLGlCQUFPO0FBQUEsUUFDVDtBQUNBLHdCQUFnQixZQUFZO0FBQzFCLGNBQUksQ0FBQyxTQUFTLGNBQWMsVUFBVTtBQUNwQyxrQkFBTSx1QkFBdUI7QUFBQSxjQUMzQjtBQUFBLGNBQ0EsV0FBVyxjQUFjO0FBQUEsY0FDekIsVUFBVSxjQUFjO0FBQUEsWUFDMUIsQ0FBQztBQUFBLFVBQ0g7QUFFQSxjQUFJLE9BQU87QUFDVCxrQkFBTSxXQUFXLE1BQU0sUUFBUSxNQUFNLElBQUksTUFBTSxHQUFHO0FBQ2xELGdCQUFJLG9CQUFvQixTQUFTLENBQUMsVUFBVTtBQUMxQyxrQkFBSTtBQUNGLHNCQUFNLE1BQU0sSUFBSSxPQUFPO0FBQ3ZCLHNCQUFNLFFBQVEsTUFBTSxJQUFJO0FBQUEsa0JBQ3RCLEtBQUssTUFBTTtBQUFBLGtCQUNYLFlBQVk7QUFBQSxrQkFDWixXQUFXLEtBQUssSUFBSTtBQUFBLGtCQUNwQixZQUFZO0FBQUEsa0JBQ1osaUJBQWlCO0FBQUEsa0JBQ2pCLGlCQUFpQjtBQUFBLGdCQUNuQixDQUFDO0FBQ0Qsc0JBQU0sa0JBQWtCO0FBQUEsa0JBQ3RCO0FBQUEsa0JBQ0EsV0FBVyxjQUFjO0FBQUEsa0JBQ3pCLFVBQVUsTUFBTTtBQUFBLGdCQUNsQixDQUFDO0FBQUEsY0FDSCxTQUFTLEdBQUc7QUFDVixzQkFBTSxnQkFBZ0I7QUFBQSxrQkFDcEI7QUFBQSxrQkFDQSxXQUFXLGNBQWM7QUFBQSxrQkFDekIsVUFBVSxNQUFNO0FBQUEsZ0JBQ2xCLENBQUM7QUFDRCxzQkFBTTtBQUFBLGNBQ1I7QUFBQSxZQUNGO0FBQUEsVUFDRjtBQUVBLGNBQUksV0FBVztBQUNiLGtCQUFNLFVBQVUsT0FBTztBQUFBLFVBQ3pCO0FBQ0EsaUJBQU87QUFBQSxRQUNULEdBQUcsRUFBRSxNQUFNLENBQUMsTUFBTTtBQUNoQix5QkFBZTtBQUNmLGdCQUFNO0FBQUEsUUFDUixDQUFDO0FBQ0QsZUFBTztBQUFBLE1BQ1Q7QUFBQSxNQUNBLFVBQVUsTUFDUixRQUFRO0FBQUEsUUFDTixJQUFJLGFBQWE7QUFBQSxVQUNmLFFBQVE7QUFBQSxRQUNWLENBQUM7QUFBQSxNQUNIO0FBQUEsTUFDRixNQUFNLE1BQ0osUUFBUTtBQUFBLFFBQ04sSUFBSSxhQUFhO0FBQUEsVUFDZixRQUFRO0FBQUEsUUFDVixDQUFDO0FBQUEsTUFDSDtBQUFBLE1BQ0YsV0FBVyxNQUNULFFBQVE7QUFBQSxRQUNOLElBQUksYUFBYTtBQUFBLFVBQ2YsUUFBUTtBQUFBLFFBQ1YsQ0FBQztBQUFBLE1BQ0g7QUFBQSxNQUNGLGNBQWMsTUFDWixRQUFRO0FBQUEsUUFDTixJQUFJLGFBQWE7QUFBQSxVQUNmLFFBQVE7QUFBQSxRQUNWLENBQUM7QUFBQSxNQUNIO0FBQUEsTUFDRixxQkFBcUIsTUFDbkIsUUFBUTtBQUFBLFFBQ04sSUFBSSxhQUFhO0FBQUEsVUFDZixRQUFRO0FBQUEsUUFDVixDQUFDO0FBQUEsTUFDSDtBQUFBLElBQ0o7QUFBQSxJQUVBLEtBQUs7QUFBQSxNQUNILE1BQU0sWUFBWTtBQUNoQixjQUFNQyxpQkFBZ0IsTUFBTSxRQUFRLFFBQVEsSUFBSSxRQUFRLEVBQUU7QUFDMUQsWUFBSUEsMEJBQXlCLE9BQU87QUFDbEMsaUJBQU9BO0FBQUEsUUFDVDtBQUNBLGVBQVFBLGVBQWMsUUFBUSxDQUFDO0FBQUEsTUFDakM7QUFBQSxNQUNBLEtBQUssT0FBTyxRQUFnQjtBQUMxQixjQUFNQSxpQkFBZ0IsTUFBTSxRQUFRLFFBQVEsSUFBSSxRQUFRLEVBQUU7QUFDMUQsWUFBSUEsMEJBQXlCLE9BQU87QUFDbEMsaUJBQU9BO0FBQUEsUUFDVDtBQUNBLGVBQU9BLGVBQWMsT0FBTyxHQUFhO0FBQUEsTUFHM0M7QUFBQSxNQUNBLEtBQUssT0FBTyxLQUFhLFVBQW1CO0FBQzFDLGNBQU0sU0FBUyxNQUFNLFFBQVEsUUFBUSxJQUFJLElBQUk7QUFBQSxVQUMzQyxXQUFXLFFBQVE7QUFBQSxVQUNuQixNQUFNLEVBQUUsQ0FBQyxHQUFHLEdBQUcsTUFBTTtBQUFBLFFBQ3ZCLENBQUM7QUFDRCxZQUFJLGtCQUFrQixPQUFPO0FBQzNCLGlCQUFPO0FBQUEsUUFDVDtBQUNBLGVBQU87QUFBQSxNQUNUO0FBQUEsTUFDQSxTQUFTLE9BQU8sU0FBa0M7QUFDaEQsY0FBTSxTQUFTLE1BQU0sUUFBUSxRQUFRLElBQUksSUFBSTtBQUFBLFVBQzNDLFdBQVcsUUFBUTtBQUFBLFVBQ25CO0FBQUEsUUFDRixDQUFDO0FBQ0QsWUFBSSxrQkFBa0IsT0FBTztBQUMzQixpQkFBTztBQUFBLFFBQ1Q7QUFDQSxlQUFPO0FBQUEsTUFDVDtBQUFBLElBQ0Y7QUFBQSxFQUNGO0FBRUEsU0FBTztBQUNUOzs7QUN4U0EsWUFBWUMsV0FBVTtBQUN0QixTQUFTLFdBQVcsd0JBQXdCO0FBQzVDLFlBQVlDLGFBQVk7QUFDeEIsU0FBUyxhQUFhO0FBMkJ0QixJQUFNLFdBQVcsYUFBYSxFQUFFLFdBQVcsZ0JBQWdCLENBQUM7QUFRckQsSUFBTSx3QkFBd0IsSUFBSSxLQUFLLEtBQUs7QUFDbkQsSUFBTSxrQkFBa0IsSUFBSSxLQUFLO0FBQ2pDLElBQU0sd0JBQXdCO0FBRTlCLElBQU0scUJBQXFCLE1BQ3pCLFFBQVEsSUFBSSxhQUFhLFNBQ3JCO0FBQUEsRUFDRSxPQUFPLFFBQVEsSUFBSTtBQUFBLEVBQ25CLFFBQVEsUUFBUSxJQUFJO0FBQUEsRUFDcEIsV0FBVyxRQUFRLElBQUk7QUFDekIsSUFDQSxDQUFDO0FBTVAsSUFBTSxpQkFBaUIsb0JBQUksSUFVekI7QUFFRixJQUFNLHVCQUF1QjtBQUM3QixJQUFNLG1CQUFtQixvQkFBSSxJQUFvQjtBQUVqRCxJQUFNLGdCQUFnQjtBQUV0QixTQUFTLG1CQUFtQixHQUFxQjtBQUMvQyxNQUFJLEVBQUUsYUFBYSxRQUFRO0FBQ3pCLFdBQU87QUFBQSxFQUNUO0FBRUEsUUFBTSxvQkFBb0I7QUFDMUIsUUFBTSxpQkFBaUI7QUFFdkIsUUFBTSxTQUNKLGtCQUFrQixVQUFVLFVBQzVCLGVBQWUsT0FBTyxVQUFVO0FBRWxDLE1BQUksV0FBVyxPQUFPLFdBQVcsS0FBSztBQUNwQyxXQUFPO0FBQUEsRUFDVDtBQUVBLFFBQU0sVUFBVSxFQUFFLFdBQVcsT0FBTyxDQUFDO0FBQ3JDLE1BQ0UsUUFBUSxTQUFTLG1DQUFtQyxLQUNwRCxRQUFRLFNBQVMsMkJBQTJCLEdBQzVDO0FBQ0EsV0FBTztBQUFBLEVBQ1Q7QUFFQSxTQUFPO0FBQ1Q7QUFFTyxJQUFNLGdCQUFnQixDQUF3QztBQUFBLEVBQ25FO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQ0YsTUFRc0I7QUFDcEIsUUFBTSxFQUFFLElBQUksT0FBTyxJQUFJO0FBQ3ZCLFFBQU0sUUFBUSxPQUFPLFdBQVcsU0FBUztBQUN6QyxRQUFNLFFBQVEsT0FBTztBQUNyQixRQUFNLGdCQUFnQixPQUFPO0FBQzdCLFFBQU0sZ0JBQ0osY0FBYyxrQkFBa0IsYUFBYSxXQUN6QyxjQUFjLG1CQUNkO0FBR04sTUFBSSxxQkFBcUI7QUFDekIsUUFBTSxXQUFXO0FBQ2pCLFFBQU0sTUFBTSxPQUFPLE9BQU87QUFFMUIsUUFBTSxjQUFjLFdBQVc7QUFBQSxJQUM3QixRQUFRO0FBQUEsSUFDUixLQUFLLENBQUMsTUFBTSxJQUFJLEVBQUUsR0FBRyxHQUFHLFFBQVEsS0FBSyxDQUFDO0FBQUEsRUFDeEMsQ0FBQztBQVFELGlCQUFlLG1CQUF5RDtBQUN0RSxVQUFNLE9BQU8sU0FBUztBQUFBLE1BQ3BCO0FBQUEsTUFDQSxFQUFFLFdBQVcsR0FBRztBQUFBLE1BQ2hCLEVBQUUsWUFBWSxLQUFLO0FBQUEsSUFDckI7QUFDQSxVQUFNLFdBQVcsS0FBSyxJQUFJLElBQUk7QUFDOUIsV0FBTyxLQUFLLElBQUksSUFBSSxVQUFVO0FBQzVCLFlBQU0sSUFBSSxRQUFRLENBQUMsTUFBTSxXQUFXLEdBQUcscUJBQXFCLENBQUM7QUFDN0QsWUFBTSxTQUFTLE1BQU0sWUFBWSxRQUFRLElBQUksRUFBRTtBQUMvQyxVQUFJLGtCQUFrQixPQUFPO0FBQzNCLGVBQU8sSUFBSSxhQUFhLEVBQUUsUUFBUSxPQUFPLFNBQVMsT0FBTyxPQUFPLENBQUM7QUFBQSxNQUNuRTtBQUNBLFlBQU0sa0JBQ0osUUFBUSxrQkFBa0IsYUFBYSxXQUNuQyxPQUFPLGlCQUFpQixZQUN4QjtBQUNOLFVBQUksaUJBQWlCO0FBQ25CLGFBQUs7QUFDTCxlQUFPO0FBQUEsVUFDTCxXQUFXO0FBQUEsVUFDWCxlQUFlO0FBQUEsVUFDZixxQkFBcUI7QUFBQSxRQUN2QjtBQUFBLE1BQ0Y7QUFDQSxZQUFNLFlBQ0osUUFBUSxtQkFDUixLQUFLLElBQUksSUFBSSxPQUFPLG1CQUFtQjtBQUN6QyxVQUFJLENBQUMsUUFBUSxtQkFBbUIsV0FBVztBQUN6QyxZQUFJLFdBQVc7QUFDYixtQkFBUyxLQUFLLHNDQUFzQztBQUFBLFlBQ2xELFdBQVc7QUFBQSxZQUNYLFNBQVMsS0FBSyxJQUFJLElBQUksT0FBUTtBQUFBLFVBQ2hDLENBQUM7QUFBQSxRQUNIO0FBQ0EsYUFBSyxFQUFFLFdBQVcsQ0FBQyxDQUFDLFVBQVUsQ0FBQztBQUMvQixlQUFPLHVCQUF1QjtBQUFBLE1BQ2hDO0FBQUEsSUFDRjtBQUNBLFdBQU8sSUFBSSxhQUFhO0FBQUEsTUFDdEIsUUFBUTtBQUFBLElBQ1YsQ0FBQztBQUFBLEVBQ0g7QUFFQSxpQkFBZSx1QkFDYixpQkFDZTtBQUNmLFFBQUksQ0FBQyx5QkFBeUI7QUFDNUI7QUFBQSxJQUNGO0FBQ0EsVUFBTSxpQkFBd0M7QUFBQSxNQUM1QztBQUFBLE1BQ0E7QUFBQSxNQUNBO0FBQUEsTUFDQTtBQUFBLElBQ0Y7QUFDQSxVQUFNLE1BQU0sMEJBQTBCLENBQUMsRUFBRSxPQUFPLGVBQWUsQ0FBQyxDQUFDLEVBQUU7QUFBQTtBQUFBLE1BRWpFLE1BQU07QUFBQSxNQUFDO0FBQUEsSUFDVDtBQUFBLEVBQ0Y7QUFFQSxpQkFBZSwwQkFDYixZQUNnQztBQUNoQyxXQUFPLE1BQWEsaUJBQVM7QUFBQSxNQUMzQixLQUFLLFlBQVk7QUFDZixjQUFNQyxXQUFVLE1BQU0saUJBQWlCLE9BQU87QUFBQSxVQUM1QyxRQUFRLEVBQUUsTUFBTSxZQUFZLFdBQVc7QUFBQSxVQUN2QyxXQUFXLEVBQUUsTUFBTTtBQUFBLFVBQ25CLFNBQVM7QUFBQSxVQUNUO0FBQUEsVUFDQTtBQUFBLFVBQ0EsR0FBRyxtQkFBbUI7QUFBQSxRQUN4QixDQUFDO0FBQ0QsY0FBTSxNQUFNLEtBQUssSUFBSTtBQUNyQixjQUFNLFFBQVEsUUFBUSxJQUFJO0FBQUEsVUFDeEI7QUFBQSxVQUNBO0FBQUEsVUFDQSxNQUFNLGNBQWM7QUFBQSxVQUNwQixXQUFXO0FBQUEsVUFDWCxnQkFBZ0I7QUFBQSxVQUNoQixpQkFBaUI7QUFBQSxVQUNqQixpQkFBaUI7QUFBQSxVQUNqQixVQUFVLGNBQWM7QUFBQSxVQUN4QixrQkFBa0I7QUFBQSxZQUNoQixVQUFVO0FBQUEsWUFDVixXQUFXQSxTQUFRO0FBQUEsWUFDbkI7QUFBQSxVQUNGO0FBQUEsUUFDRixDQUFDO0FBQ0QsY0FBTSx1QkFBdUJBLFNBQVEsU0FBUztBQUM5QyxlQUFPQSxTQUFRO0FBQUEsTUFDakI7QUFBQSxNQUNBLE9BQU8sQ0FBQyxNQUFNLElBQUksYUFBYSxFQUFFLFFBQVEsT0FBTyxDQUFDLEdBQUcsT0FBTyxFQUFFLENBQUM7QUFBQSxJQUNoRSxDQUFDO0FBQUEsRUFDSDtBQUVBLGlCQUFlLHFCQUFxRDtBQUNsRSxXQUFPLE1BQWEsaUJBQVM7QUFBQSxNQUMzQixLQUFLLFlBQVk7QUFDZixjQUFNQSxXQUFVLE1BQU0saUJBQWlCLE9BQU87QUFBQSxVQUM1QyxXQUFXLEVBQUUsTUFBTTtBQUFBLFVBQ25CLFNBQVM7QUFBQSxVQUNUO0FBQUEsVUFDQTtBQUFBLFVBQ0EsR0FBRyxtQkFBbUI7QUFBQSxRQUN4QixDQUFDO0FBQ0QsY0FBTSxNQUFNLEtBQUssSUFBSTtBQUNyQixjQUFNLFFBQVEsUUFBUSxJQUFJO0FBQUEsVUFDeEI7QUFBQSxVQUNBO0FBQUEsVUFDQSxNQUFNLGNBQWM7QUFBQSxVQUNwQixXQUFXO0FBQUEsVUFDWCxnQkFBZ0I7QUFBQSxVQUNoQixpQkFBaUI7QUFBQSxVQUNqQixpQkFBaUI7QUFBQSxVQUNqQixVQUFVLGNBQWM7QUFBQSxVQUN4QixrQkFBa0I7QUFBQSxZQUNoQixVQUFVO0FBQUEsWUFDVixXQUFXQSxTQUFRO0FBQUEsWUFDbkIsWUFBWTtBQUFBLFVBQ2Q7QUFBQSxRQUNGLENBQUM7QUFDRCxjQUFNLHVCQUF1QkEsU0FBUSxTQUFTO0FBQzlDLGVBQU9BLFNBQVE7QUFBQSxNQUNqQjtBQUFBLE1BQ0EsT0FBTyxDQUFDLE1BQU0sSUFBSSxhQUFhLEVBQUUsUUFBUSxPQUFPLENBQUMsR0FBRyxPQUFPLEVBQUUsQ0FBQztBQUFBLElBQ2hFLENBQUM7QUFBQSxFQUNIO0FBTUEsV0FBUyxlQUNQLFVBQ0E7QUFBQSxJQUNFO0FBQUEsSUFDQTtBQUFBLElBQ0EsS0FBSztBQUFBLElBQ0w7QUFBQSxJQUNBO0FBQUEsSUFDQTtBQUFBLEVBQ0YsR0FlQTtBQUNBLFdBQWMsaUJBQVM7QUFBQSxNQUNyQixLQUFLLFlBQVk7QUFDZixjQUFNLFdBQVcsT0FBTyxTQUFTO0FBQ2pDLGNBQU0sWUFBWSxPQUFPLENBQUMsU0FBUyxHQUFJLFFBQVEsQ0FBQyxDQUFFLElBQUk7QUFDdEQsY0FBTSxTQUFTLE1BQU0sU0FBUyxXQUFXO0FBQUEsVUFDdkMsS0FBSyxXQUFXO0FBQUEsVUFDaEIsTUFBTTtBQUFBLFVBQ047QUFBQSxVQUNBLEtBQUs7QUFBQSxVQUNMO0FBQUEsVUFDQSxVQUFVO0FBQUEsUUFDWixDQUFDO0FBRUQsWUFBSSxTQUFTO0FBQ2IsWUFBSSxTQUFTO0FBQ2IsY0FBTSxZQUF3QixDQUFDO0FBQy9CLGNBQU0sUUFBUTtBQUFBLFVBQ1osU0FBUztBQUFBLFVBQ1QsVUFBVTtBQUFBLFFBQ1o7QUFFQSxjQUFNLGVBQWUsWUFBWTtBQUMvQixjQUFJO0FBQ0YsNkJBQWlCQyxRQUFPLE9BQU8sS0FBSyxHQUFHO0FBQ3JDLG9CQUFNLFFBQ0pBLEtBQUksV0FBVyxXQUNYLEVBQUUsUUFBUSxVQUFVLE1BQU1BLEtBQUksS0FBSyxJQUNuQyxFQUFFLFFBQVEsVUFBVSxNQUFNQSxLQUFJLEtBQUs7QUFFekMsa0JBQUlBLEtBQUksV0FBVyxVQUFVO0FBQzNCLDBCQUFVQSxLQUFJO0FBQUEsY0FDaEIsT0FBTztBQUNMLDBCQUFVQSxLQUFJO0FBQUEsY0FDaEI7QUFFQSx3QkFBVSxLQUFLLEtBQUs7QUFDcEIsb0JBQU0sVUFBVTtBQUFBLFlBQ2xCO0FBQUEsVUFDRixRQUFRO0FBQUEsVUFFUjtBQUNBLGdCQUFNLFdBQVc7QUFDakIsZ0JBQU0sVUFBVTtBQUFBLFFBQ2xCLEdBQUc7QUFFSCx3QkFBZ0IsT0FBZ0M7QUFDOUMsY0FBSSxRQUFRO0FBQ1osaUJBQU8sQ0FBQyxNQUFNLFlBQVksUUFBUSxVQUFVLFFBQVE7QUFDbEQsZ0JBQUksUUFBUSxVQUFVLFFBQVE7QUFDNUIsb0JBQU0sVUFBVSxPQUFPO0FBQUEsWUFDekIsT0FBTztBQUNMLG9CQUFNLElBQUksUUFBYyxDQUFDQyxhQUFZO0FBQ25DLHNCQUFNLFVBQVVBO0FBQUEsY0FDbEIsQ0FBQztBQUNELG9CQUFNLFVBQVU7QUFBQSxZQUNsQjtBQUFBLFVBQ0Y7QUFBQSxRQUNGO0FBRUEsY0FBTSxTQUFTLFlBQVksS0FBSyxZQUFZO0FBQzFDLGNBQUk7QUFDRixrQkFBTSxXQUFXLE1BQU0sT0FBTyxLQUFLO0FBQ25DLG1CQUFPO0FBQUEsY0FDTDtBQUFBLGNBQ0E7QUFBQSxjQUNBLFVBQVUsU0FBUztBQUFBLFlBQ3JCO0FBQUEsVUFDRixTQUFTLEdBQUc7QUFDVixnQkFBSSxtQkFBbUIsQ0FBQyxHQUFHO0FBQ3pCLHFCQUFPLEVBQUUsUUFBUSxRQUFRLFVBQVUsRUFBRTtBQUFBLFlBQ3ZDO0FBQ0Esa0JBQU07QUFBQSxVQUNSO0FBQUEsUUFDRixDQUFDO0FBRUQsZUFBTyxFQUFFLFdBQVcsT0FBTyxPQUFPLE1BQU0sT0FBTztBQUFBLE1BQ2pEO0FBQUEsTUFDQSxPQUFPLENBQUMsTUFBTSxJQUFJLGFBQWEsRUFBRSxRQUFRLE9BQU8sQ0FBQyxHQUFHLE9BQU8sRUFBRSxDQUFDO0FBQUEsSUFDaEUsQ0FBQztBQUFBLEVBQ0g7QUFFQSxXQUFTLG1CQUNQLFVBQ0EsRUFBRSxNQUFBQyxNQUFLLEdBQ2dDO0FBQ3ZDLFdBQWMsaUJBQVM7QUFBQSxNQUNyQixLQUFLLE1BQU0sU0FBUyxpQkFBaUIsRUFBRSxNQUFBQSxPQUFNLElBQUksQ0FBQztBQUFBLE1BQ2xELE9BQU8sQ0FBQyxNQUFNLElBQUksYUFBYSxFQUFFLFFBQVEsT0FBTyxDQUFDLEdBQUcsT0FBTyxFQUFFLENBQUM7QUFBQSxJQUNoRSxDQUFDO0FBQUEsRUFDSDtBQUVBLGlCQUFlLHFCQUNiLFVBQ0EsTUFJZTtBQUNmLFVBQU0sRUFBRSxPQUFPLFNBQVMsSUFBSTtBQUM1QixRQUFJLE1BQU0sV0FBVyxHQUFHO0FBQ3RCO0FBQUEsSUFDRjtBQUVBLFVBQU0sY0FBYyxNQUFNLElBQUksQ0FBQyxTQUFTO0FBQ3RDLFlBQU0sV0FBZ0IsWUFBTSxLQUFLLFVBQVUsS0FBSyxJQUFJO0FBQ3BELFlBQU0sZUFBb0IsWUFBTSxXQUFXLFFBQVEsSUFDL0MsV0FDSyxZQUFNLEtBQUssS0FBSyxRQUFRO0FBQ2pDLGFBQU87QUFBQSxRQUNMLE1BQU07QUFBQSxRQUNOLFNBQ0UsT0FBTyxLQUFLLFlBQVksV0FDcEIsT0FBTyxLQUFLLEtBQUssT0FBTyxJQUN4QixLQUFLO0FBQUEsTUFDYjtBQUFBLElBQ0YsQ0FBQztBQUVELFVBQU0sU0FBUyxXQUFXLFdBQVc7QUFFckMsVUFBTSxlQUFlLFlBQVksT0FBTyxDQUFDLE1BQU0sRUFBRSxLQUFLLFNBQVMsS0FBSyxDQUFDO0FBQ3JFLFFBQUksYUFBYSxTQUFTLEdBQUc7QUFDM0IsWUFBTSxjQUFjLE1BQU0sZUFBZSxVQUFVO0FBQUEsUUFDakQsU0FBUztBQUFBLFFBQ1QsTUFBTSxDQUFDLE1BQU0sR0FBRyxhQUFhLElBQUksQ0FBQyxNQUFNLEVBQUUsSUFBSSxDQUFDO0FBQUEsTUFDakQsQ0FBQztBQUNELFVBQUksdUJBQXVCLE9BQU87QUFDaEMsY0FBTTtBQUFBLE1BQ1I7QUFDQSxZQUFNLFlBQVk7QUFBQSxJQUNwQjtBQUFBLEVBQ0Y7QUFNQSxXQUFTLGtCQUFrQixVQUFvQztBQUM3RCxVQUFNLGVBQWUsTUFDbkIsUUFBUTtBQUFBLE1BQ04sSUFBSSxhQUFhLEVBQUUsUUFBUSw2QkFBNkIsQ0FBQztBQUFBLElBQzNEO0FBQ0YsVUFBTSxjQUF1QjtBQUFBLE1BQzNCLElBQUksZ0JBQWdCLEtBQUssSUFBSSxDQUFDO0FBQUEsTUFDOUI7QUFBQSxNQUNBO0FBQUEsTUFDQSxNQUFNLENBQUMsU0FBUyxlQUFlLFVBQVUsSUFBSTtBQUFBLE1BQzdDLFVBQVUsQ0FBQyxTQUFTLG1CQUFtQixVQUFVLElBQUk7QUFBQSxNQUNyRCxXQUFXLE1BQU0sYUFBYTtBQUFBLE1BQzlCLE1BQU0sTUFBTSxhQUFhO0FBQUEsTUFDekIsWUFBWSxDQUFDLFNBQVMscUJBQXFCLFVBQVUsSUFBSTtBQUFBLE1BQ3pELHFCQUFxQixDQUFDLFdBQ2IsaUJBQVM7QUFBQSxRQUNkLEtBQUssTUFBTSxTQUFTLG9CQUFvQixNQUFNO0FBQUEsUUFDOUMsT0FBTyxDQUFDLE1BQU0sSUFBSSxhQUFhLEVBQUUsUUFBUSxPQUFPLENBQUMsR0FBRyxPQUFPLEVBQUUsQ0FBQztBQUFBLE1BQ2hFLENBQUM7QUFBQSxNQUNILFdBQVc7QUFBQSxRQUNULE9BQU8sTUFBTSxhQUFhO0FBQUEsUUFDMUIsVUFBVSxNQUFNLGFBQWE7QUFBQSxRQUM3QixNQUFNLE1BQU0sYUFBYTtBQUFBLFFBQ3pCLFdBQVcsTUFBTSxhQUFhO0FBQUEsUUFDOUIsY0FBYyxNQUFNLGFBQWE7QUFBQSxRQUNqQyxxQkFBcUIsTUFBTSxhQUFhO0FBQUEsTUFDMUM7QUFBQSxNQUNBLEtBQUs7QUFBQSxRQUNILE1BQU0sYUFBYSxDQUFDO0FBQUEsUUFDcEIsS0FBSyxZQUFZO0FBQUEsUUFDakIsS0FBSyxZQUFZO0FBQUEsUUFDakIsU0FBUyxZQUFZO0FBQUEsTUFDdkI7QUFBQSxJQUNGO0FBQ0EsV0FBTztBQUFBLEVBQ1Q7QUFNQSxpQkFBZSxxQkFBcUIsS0FBcUM7QUFDdkUsVUFBTSxPQUFPLFNBQVM7QUFBQSxNQUNwQjtBQUFBLE1BQ0EsRUFBRSxVQUFVLElBQUk7QUFBQSxNQUNoQixFQUFFLFlBQVksS0FBSztBQUFBLElBQ3JCO0FBQ0EsVUFBTSxXQUFXLEtBQUssSUFBSSxJQUFJO0FBQzlCLFdBQU8sS0FBSyxJQUFJLElBQUksVUFBVTtBQUM1QixZQUFNLElBQUksUUFBUSxDQUFDLE1BQU0sV0FBVyxHQUFHLHFCQUFxQixDQUFDO0FBQzdELFlBQU0sU0FBUyxNQUFNLFlBQVksTUFBTSxJQUFJLEdBQUc7QUFDOUMsVUFBSSxrQkFBa0IsT0FBTztBQUMzQixlQUFPO0FBQUEsTUFDVDtBQUNBLFVBQUksUUFBUSxZQUFZO0FBQ3RCLGFBQUs7QUFDTCxlQUFPLE9BQU87QUFBQSxNQUNoQjtBQUNBLFlBQU0sWUFDSixRQUFRLG1CQUNSLEtBQUssSUFBSSxJQUFJLE9BQU8sbUJBQW1CO0FBQ3pDLFVBQUksQ0FBQyxRQUFRLG1CQUFtQixXQUFXO0FBQ3pDLFlBQUksV0FBVztBQUNiLG1CQUFTLEtBQUssdUNBQXVDO0FBQUEsWUFDbkQsVUFBVTtBQUFBLFlBQ1YsU0FBUyxLQUFLLElBQUksSUFBSSxPQUFRO0FBQUEsVUFDaEMsQ0FBQztBQUFBLFFBQ0g7QUFDQSxhQUFLLEVBQUUsV0FBVyxDQUFDLENBQUMsV0FBVyxPQUFPLE1BQU0sQ0FBQztBQUM3QyxlQUFPO0FBQUEsTUFDVDtBQUFBLElBQ0Y7QUFDQSxTQUFLLEVBQUUsVUFBVSxLQUFLLENBQUM7QUFDdkIsV0FBTztBQUFBLEVBQ1Q7QUFTQSxpQkFBZSxvQkFBb0IsTUFFakI7QUFDaEIsUUFBSSxDQUFDLE9BQU87QUFDVjtBQUFBLElBQ0Y7QUFDQSxVQUFNLFdBQVcsTUFBTTtBQUd2QixRQUFJLENBQUMsTUFBTSxPQUFPO0FBQ2hCLFlBQU0sV0FBVyxNQUFNLFFBQVEsTUFBTSxJQUFJLFFBQVE7QUFDakQsVUFBSSxFQUFFLG9CQUFvQixVQUFVLFVBQVUsWUFBWTtBQUN4RDtBQUFBLE1BQ0Y7QUFBQSxJQUNGO0FBR0EsVUFBTSxTQUFTLE9BQU8sV0FBVztBQUNqQyxVQUFNLFNBQVMsTUFBTSxRQUFRLE1BQU07QUFBQSxNQUNqQztBQUFBLE1BQ0E7QUFBQSxNQUNBO0FBQUEsSUFDRjtBQUNBLFFBQUksa0JBQWtCLFNBQVMsQ0FBQyxRQUFRO0FBQ3RDO0FBQUEsSUFDRjtBQUlBLFFBQUksQ0FBQyxNQUFNLFNBQVMsT0FBTyxZQUFZO0FBQ3JDO0FBQUEsSUFDRjtBQUVBLFFBQUksZUFFTztBQUNYLFFBQUk7QUFFRixxQkFBZSxNQUFNLGlCQUFpQixPQUFPO0FBQUEsUUFDM0MsV0FBVyxFQUFFLE1BQU07QUFBQSxRQUNuQixTQUFTO0FBQUEsUUFDVDtBQUFBLFFBQ0E7QUFBQSxRQUNBLEdBQUcsbUJBQW1CO0FBQUEsTUFDeEIsQ0FBQztBQUVELFlBQU0sY0FBYztBQUFBLFFBQ2xCO0FBQUEsTUFDRjtBQUNBLFlBQU0sTUFBTSxJQUFJLFdBQVc7QUFDM0IsWUFBTSxXQUFXLE1BQU0sYUFBYSxTQUFTO0FBRTdDLFlBQU0sUUFBUSxNQUFNLElBQUk7QUFBQSxRQUN0QixLQUFLO0FBQUEsUUFDTCxZQUFZLFNBQVM7QUFBQSxRQUNyQixXQUFXLE9BQU87QUFBQSxRQUNsQixZQUFZO0FBQUEsUUFDWixpQkFBaUI7QUFBQSxRQUNqQixpQkFBaUI7QUFBQSxNQUNuQixDQUFDO0FBR0QsWUFBTSxhQUFhLEtBQUssRUFBRSxNQUFNLE1BQU0sTUFBUztBQUFBLElBQ2pELFNBQVMsR0FBRztBQUNWLGVBQVMsTUFBTSxtQ0FBbUMsRUFBRSxVQUFVLE9BQU8sRUFBRSxDQUFDO0FBRXhFLFVBQUksY0FBYztBQUNoQixjQUFNLGFBQWEsS0FBSyxFQUFFLE1BQU0sTUFBTSxNQUFTO0FBQUEsTUFDakQ7QUFFQSxZQUFNLFFBQVEsTUFDWCxJQUFJO0FBQUEsUUFDSCxLQUFLO0FBQUEsUUFDTCxZQUFZO0FBQUEsUUFDWixXQUFXLE9BQU87QUFBQSxRQUNsQixZQUFZO0FBQUEsUUFDWixpQkFBaUI7QUFBQSxRQUNqQixpQkFBaUI7QUFBQSxNQUNuQixDQUFDLEVBQ0EsTUFBTSxNQUFNLE1BQVM7QUFBQSxJQUMxQjtBQUFBLEVBQ0Y7QUFFQSxpQkFBZSx5QkFFYjtBQUNBLFVBQU0sT0FBTyxTQUFTLEtBQUssMEJBQTBCLEVBQUUsV0FBVyxHQUFHLENBQUM7QUFFdEUsUUFBSSxlQUFlLGFBQWEsQ0FBQyxvQkFBb0I7QUFDbkQsV0FBSyxFQUFFLE1BQU0sWUFBWSxDQUFDO0FBQzFCLGFBQU87QUFBQSxRQUNMLFdBQVcsY0FBYztBQUFBLFFBQ3pCLGVBQWU7QUFBQSxRQUNmLHFCQUFxQjtBQUFBLE1BQ3ZCO0FBQUEsSUFDRjtBQUVBLFVBQU0sV0FBVyxNQUFNLFFBQVEsUUFBUSxJQUFJLEVBQUU7QUFDN0MsUUFBSSxvQkFBb0IsT0FBTztBQUM3QixVQUFJLG9CQUFvQixzQkFBc0I7QUFBQSxNQUU5QyxPQUFPO0FBQ0wsZUFBTyxJQUFJLGFBQWEsRUFBRSxRQUFRLFNBQVMsU0FBUyxPQUFPLFNBQVMsQ0FBQztBQUFBLE1BQ3ZFO0FBQUEsSUFDRjtBQUVBLFVBQU0saUJBQ0osb0JBQW9CLHVCQUF1QixPQUFPO0FBQ3BELFVBQU0saUJBQ0osZ0JBQWdCLGtCQUFrQixhQUFhLFdBQzNDLGVBQWUsbUJBQ2Y7QUFFTixRQUFJLGdCQUFnQixXQUFXO0FBQzdCLGFBQU87QUFBQSxRQUNMLFdBQVcsZUFBZTtBQUFBLFFBQzFCLGVBQWU7QUFBQSxRQUNmLHFCQUFxQjtBQUFBLE1BQ3ZCO0FBQUEsSUFDRjtBQUVBLFVBQU0sZ0JBQ0osZ0JBQWdCLG1CQUNoQixlQUFlLG1CQUNmLEtBQUssSUFBSSxJQUFJLGVBQWUsa0JBQWtCO0FBRWhELFFBQUksZUFBZTtBQUNqQixhQUFPLGlCQUFpQjtBQUFBLElBQzFCO0FBRUEsVUFBTSxTQUFTLE9BQU8sV0FBVztBQUNqQyxVQUFNLE1BQU0sS0FBSyxJQUFJO0FBQ3JCLFVBQU0sU0FBUyxNQUFNLFFBQVEsUUFBUTtBQUFBLE1BQ25DO0FBQUEsUUFDRTtBQUFBLFFBQ0E7QUFBQSxRQUNBLE1BQU0sZ0JBQWdCLFFBQVEsY0FBYztBQUFBLFFBQzVDLFdBQVcsZ0JBQWdCLGFBQWEsY0FBYztBQUFBLFFBQ3RELGdCQUNFLGdCQUFnQixrQkFBa0IsY0FBYztBQUFBLFFBQ2xELGlCQUFpQjtBQUFBLFFBQ2pCLGlCQUFpQjtBQUFBLFFBQ2pCLFVBQVUsY0FBYztBQUFBLFFBQ3hCLGtCQUFrQjtBQUFBLFVBQ2hCLFVBQVU7QUFBQSxVQUNWLFdBQVc7QUFBQSxVQUNYLFlBQ0UsZ0JBQWdCLGNBQWMsZUFBZSxjQUFjO0FBQUEsUUFDL0Q7QUFBQSxNQUNGO0FBQUEsTUFDQTtBQUFBLElBQ0Y7QUFFQSxRQUFJLGtCQUFrQixPQUFPO0FBQzNCLGFBQU8sSUFBSSxhQUFhLEVBQUUsUUFBUSxPQUFPLFNBQVMsT0FBTyxPQUFPLENBQUM7QUFBQSxJQUNuRTtBQUNBLFFBQUksQ0FBQyxRQUFRO0FBQ1gsYUFBTyxpQkFBaUI7QUFBQSxJQUMxQjtBQUVBLFVBQU0sZUFBZTtBQUVyQixtQkFBZSxxQkFBb0M7QUFDakQsWUFBTSxRQUFRLFFBQ1gsT0FBTztBQUFBLFFBQ04sSUFBSSxhQUFhO0FBQUEsUUFDakIsaUJBQWlCO0FBQUEsUUFDakIsaUJBQWlCO0FBQUEsTUFDbkIsQ0FBQyxFQUNBLE1BQU0sTUFBTSxNQUFTO0FBQUEsSUFDMUI7QUFFQSxVQUFNLGVBQ0osYUFBYSxrQkFBa0IsYUFBYSxXQUN4QyxhQUFhLG1CQUNiO0FBQ04sUUFBSSxjQUFjLFdBQVc7QUFDM0IsWUFBTSxtQkFBbUI7QUFDekIsYUFBTztBQUFBLFFBQ0wsV0FBVyxhQUFhO0FBQUEsUUFDeEIsZUFBZTtBQUFBLFFBQ2YscUJBQXFCO0FBQUEsTUFDdkI7QUFBQSxJQUNGO0FBRUEsVUFBTSxhQUNKLGNBQWMsY0FDZCxlQUFlLGNBQ2YsT0FBTyxXQUFXO0FBQ3BCLFFBQUksWUFBWTtBQUNkLFlBQU0sU0FBUyxNQUFNLDBCQUEwQixVQUFVO0FBQ3pELFVBQUksRUFBRSxrQkFBa0IsUUFBUTtBQUM5QixhQUFLLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQztBQUNoQyxlQUFPO0FBQUEsVUFDTCxXQUFXO0FBQUEsVUFDWCxlQUFlO0FBQUEsVUFDZixxQkFBcUI7QUFBQSxRQUN2QjtBQUFBLE1BQ0Y7QUFBQSxJQUNGO0FBRUEsUUFBSSxPQUFPO0FBQ1QsVUFBSSx3QkFBd0I7QUFDNUIsWUFBTSxjQUFjLE1BQU0sUUFBUSxNQUFNLElBQUksTUFBTSxHQUFHO0FBQ3JELFVBQUksRUFBRSx1QkFBdUIsVUFBVSxhQUFhO0FBQ2xELFlBQUksWUFBWSxZQUFZO0FBQzFCLGdCQUFNLFNBQVMsTUFBTTtBQUFBLFlBQ25CLFlBQVk7QUFBQSxVQUNkO0FBQ0EsY0FBSSxFQUFFLGtCQUFrQixRQUFRO0FBQzlCLG9CQUFRLE1BQ0wsSUFBSTtBQUFBLGNBQ0gsR0FBRztBQUFBLGNBQ0gsWUFBWSxLQUFLLElBQUk7QUFBQSxZQUN2QixDQUFDLEVBQ0EsTUFBTSxNQUFNLE1BQVM7QUFDeEIsaUJBQUssRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQy9CLG1CQUFPO0FBQUEsY0FDTCxXQUFXO0FBQUEsY0FDWCxlQUFlO0FBQUEsY0FDZixxQkFBcUI7QUFBQSxZQUN2QjtBQUFBLFVBQ0Y7QUFDQSxrQ0FBd0I7QUFBQSxRQUMxQixXQUNFLFlBQVksbUJBQ1osWUFBWSxtQkFDWixLQUFLLElBQUksSUFBSSxZQUFZLGtCQUFrQixpQkFDM0M7QUFDQSxnQkFBTSxtQkFBbUIsTUFBTSxxQkFBcUIsTUFBTSxHQUFHO0FBQzdELGNBQUksa0JBQWtCO0FBQ3BCLGtCQUFNLFNBQVMsTUFBTSwwQkFBMEIsZ0JBQWdCO0FBQy9ELGdCQUFJLEVBQUUsa0JBQWtCLFFBQVE7QUFDOUIsbUJBQUssRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBQ2hDLHFCQUFPO0FBQUEsZ0JBQ0wsV0FBVztBQUFBLGdCQUNYLGVBQWU7QUFBQSxnQkFDZixxQkFBcUI7QUFBQSxjQUN2QjtBQUFBLFlBQ0Y7QUFBQSxVQUNGO0FBQUEsUUFDRjtBQUFBLE1BQ0Y7QUFFQSwwQkFBb0IsRUFBRSxPQUFPLHNCQUFzQixDQUFDLEVBQUUsTUFBTSxDQUFDLE1BQU07QUFDakUsaUJBQVMsTUFBTSx3Q0FBd0MsRUFBRSxPQUFPLEVBQUUsQ0FBQztBQUFBLE1BQ3JFLENBQUM7QUFFRCxZQUFNQyxlQUFjLE1BQU0sbUJBQW1CO0FBQzdDLFVBQUlBLHdCQUF1QixPQUFPO0FBQ2hDLGNBQU0sbUJBQW1CO0FBQ3pCLGVBQU9BO0FBQUEsTUFDVDtBQUNBLFdBQUssRUFBRSxNQUFNLG1CQUFtQixDQUFDO0FBQ2pDLGFBQU87QUFBQSxRQUNMLFdBQVdBO0FBQUEsUUFDWCxlQUFlO0FBQUEsUUFDZixxQkFBcUI7QUFBQSxNQUN2QjtBQUFBLElBQ0Y7QUFFQSxVQUFNLGNBQWMsTUFBTSxtQkFBbUI7QUFDN0MsUUFBSSx1QkFBdUIsT0FBTztBQUNoQyxZQUFNLG1CQUFtQjtBQUN6QixhQUFPO0FBQUEsSUFDVDtBQUNBLFNBQUssRUFBRSxNQUFNLFFBQVEsQ0FBQztBQUN0QixXQUFPO0FBQUEsTUFDTCxXQUFXO0FBQUEsTUFDWCxlQUFlO0FBQUEsTUFDZixxQkFBcUI7QUFBQSxJQUN2QjtBQUFBLEVBQ0Y7QUFFQSxXQUFTLHVCQUE2RDtBQUNwRSxVQUFNLFNBQVMsZUFBZSxJQUFJLEVBQUU7QUFDcEMsUUFBSSxRQUFRO0FBQ1YsYUFBTztBQUFBLElBQ1Q7QUFFQSxVQUFNLFVBQVUsdUJBQXVCLEVBQUUsUUFBUSxNQUFNO0FBQ3JELHFCQUFlLE9BQU8sRUFBRTtBQUFBLElBQzFCLENBQUM7QUFDRCxtQkFBZSxJQUFJLElBQUksT0FBTztBQUM5QixXQUFPO0FBQUEsRUFDVDtBQVFBLGlCQUFlLGVBQXlEO0FBQ3RFLFVBQU0sZUFBZSxNQUFNLHFCQUFxQjtBQUNoRCxRQUFJLHdCQUF3QixPQUFPO0FBQ2pDLGFBQU87QUFBQSxJQUNUO0FBRUEsVUFBTSxXQUFXLE1BQWEsaUJBQVM7QUFBQSxNQUNyQyxLQUFLLE1BQ0gsaUJBQWlCLElBQUk7QUFBQSxRQUNuQixXQUFXLGFBQWE7QUFBQSxRQUN4QixHQUFHLG1CQUFtQjtBQUFBLE1BQ3hCLENBQUM7QUFBQSxNQUNILE9BQU8sQ0FBQyxNQUFNLElBQUksYUFBYSxFQUFFLFFBQVEsT0FBTyxDQUFDLEdBQUcsT0FBTyxFQUFFLENBQUM7QUFBQSxJQUNoRSxDQUFDO0FBRUQsUUFBSSxvQkFBb0IsT0FBTztBQUM3QixhQUFPO0FBQUEsSUFDVDtBQUVBLFdBQU87QUFBQSxNQUNMO0FBQUEsTUFDQSxlQUFlLGFBQWE7QUFBQSxNQUM1QixxQkFBcUIsYUFBYTtBQUFBLElBQ3BDO0FBQUEsRUFDRjtBQUVBLE1BQUksb0JBQXFFO0FBRXpFLFdBQVMsbUJBQTZEO0FBQ3BFLFFBQUksQ0FBQyxtQkFBbUI7QUFDdEIsMEJBQW9CLGFBQWE7QUFBQSxJQUNuQztBQUNBLFdBQU87QUFBQSxFQUNUO0FBRUEsaUJBQWUscUJBQThEO0FBQzNFLFVBQU0sU0FBUyxNQUFNLGlCQUFpQjtBQUN0QyxRQUFJLGtCQUFrQixPQUFPO0FBQzNCLGFBQU87QUFBQSxJQUNUO0FBQ0EsV0FBTyxPQUFPO0FBQUEsRUFDaEI7QUFFQSxpQkFBZSwwQkFBeUM7QUFDdEQsd0JBQW9CO0FBQ3BCLHlCQUFxQjtBQUVyQixVQUFNLFdBQVcsTUFBTSxRQUFRLFFBQVEsSUFBSSxFQUFFO0FBQzdDLFFBQUksb0JBQW9CLFNBQVMsQ0FBQyxVQUFVO0FBQzFDO0FBQUEsSUFDRjtBQUVBLFVBQU0saUJBQ0osU0FBUyxrQkFBa0IsYUFBYSxXQUNwQyxTQUFTLG1CQUNUO0FBRU4sUUFBSSxnQkFBZ0IsV0FBVztBQUM3QixZQUFNLFFBQVEsUUFBUSxPQUFPO0FBQUEsUUFDM0IsSUFBSSxTQUFTO0FBQUEsUUFDYixpQkFBaUI7QUFBQSxRQUNqQixpQkFBaUI7QUFBQSxRQUNqQixrQkFBa0I7QUFBQSxVQUNoQixVQUFVO0FBQUEsVUFDVixXQUFXO0FBQUEsVUFDWCxZQUFZLGVBQWU7QUFBQSxRQUM3QjtBQUFBLE1BQ0YsQ0FBQztBQUFBLElBQ0g7QUFBQSxFQUNGO0FBRUEsaUJBQWUscUJBQW9DO0FBQ2pELFVBQU0sTUFBTSxLQUFLLElBQUk7QUFDckIsVUFBTSxXQUFXLGlCQUFpQixJQUFJLEVBQUU7QUFDeEMsUUFBSSxZQUFZLE1BQU0sV0FBVyxzQkFBc0I7QUFDckQ7QUFBQSxJQUNGO0FBQ0EscUJBQWlCLElBQUksSUFBSSxHQUFHO0FBRTVCLFVBQU0sV0FBVyxNQUFNLFFBQVEsUUFBUSxJQUFJLEVBQUU7QUFDN0MsUUFBSSxvQkFBb0IsU0FBUyxDQUFDLFVBQVU7QUFDMUM7QUFBQSxJQUNGO0FBQ0EsVUFBTSxpQkFDSixTQUFTLGtCQUFrQixhQUFhLFdBQ3BDLFNBQVMsbUJBQ1Q7QUFDTixVQUFNLFFBQVEsUUFBUSxPQUFPO0FBQUEsTUFDM0IsSUFBSSxTQUFTO0FBQUEsTUFDYixnQkFBZ0I7QUFBQSxNQUNoQixpQkFBaUI7QUFBQSxNQUNqQixpQkFBaUI7QUFBQSxNQUNqQixrQkFBa0Isa0JBQWtCO0FBQUEsUUFDbEMsVUFBVTtBQUFBLFFBQ1YsV0FBVztBQUFBLFFBQ1gsWUFBWTtBQUFBLE1BQ2Q7QUFBQSxJQUNGLENBQUM7QUFBQSxFQUNIO0FBRUEsTUFBSSxlQUF5RDtBQUU3RCxRQUFNLFlBQThCO0FBQUEsSUFDbEMsT0FBTyxNQUFNO0FBQ1gsVUFBSSxjQUFjO0FBQ2hCLGVBQU87QUFBQSxNQUNUO0FBQ0Esc0JBQWdCLFlBQVk7QUFDMUIsWUFBSSxDQUFDLFNBQVMsY0FBYyxVQUFVO0FBQ3BDLGdCQUFNLHVCQUF1QjtBQUFBLFlBQzNCLFNBQVM7QUFBQSxZQUNULFdBQVcsY0FBYztBQUFBLFlBQ3pCLFVBQVUsY0FBYztBQUFBLFVBQzFCLENBQUM7QUFBQSxRQUNIO0FBRUEsY0FBTSxTQUFTLE1BQU0saUJBQWlCO0FBQ3RDLFlBQUksa0JBQWtCLE9BQU87QUFDM0IseUJBQWU7QUFDZixpQkFBTztBQUFBLFFBQ1Q7QUFDQSxjQUFNLG1CQUFtQjtBQUV6QixZQUFJLE9BQU8saUJBQWlCLE9BQU87QUFDakMsY0FBSTtBQUNGLGtCQUFNLE1BQU0sSUFBSSxPQUFPO0FBQ3ZCLGtCQUFNLGtCQUFrQjtBQUFBLGNBQ3RCO0FBQUEsY0FDQSxXQUFXLGNBQWM7QUFBQSxjQUN6QixVQUFVLE1BQU07QUFBQSxZQUNsQixDQUFDO0FBQUEsVUFDSCxTQUFTLEdBQUc7QUFDVixrQkFBTSxnQkFBZ0I7QUFBQSxjQUNwQjtBQUFBLGNBQ0EsV0FBVyxjQUFjO0FBQUEsY0FDekIsVUFBVSxNQUFNO0FBQUEsWUFDbEIsQ0FBQztBQUNELGtCQUFNO0FBQUEsVUFDUjtBQUFBLFFBQ0Y7QUFFQSxZQUFJLE9BQU8sdUJBQXVCLFdBQVc7QUFDM0MsZ0JBQU0sVUFBVSxPQUFPO0FBQUEsUUFDekI7QUFFQSxlQUFPO0FBQUEsTUFDVCxHQUFHLEVBQUUsTUFBTSxDQUFDLE1BQU07QUFDaEIsdUJBQWU7QUFDZixjQUFNO0FBQUEsTUFDUixDQUFDO0FBQ0QsYUFBTztBQUFBLElBQ1Q7QUFBQSxJQUVBLFVBQVUsWUFBWTtBQUNwQixZQUFNSixXQUFVLE1BQU0sbUJBQW1CO0FBQ3pDLFVBQUlBLG9CQUFtQixPQUFPO0FBQzVCLGVBQU9BO0FBQUEsTUFDVDtBQUVBLGFBQWMsaUJBQVM7QUFBQSxRQUNyQixLQUFLLFlBQVk7QUFDZixnQkFBTSxXQUFXLE1BQU1BLFNBQVEsU0FBUztBQUN4QyxnQkFBTSxRQUFRLFFBQVEsT0FBTztBQUFBLFlBQzNCO0FBQUEsWUFDQSxpQkFBaUI7QUFBQSxZQUNqQixpQkFBaUI7QUFBQSxZQUNqQixrQkFBa0I7QUFBQSxjQUNoQixVQUFVO0FBQUEsY0FDVixXQUFXO0FBQUEsY0FDWCxZQUFZLFNBQVM7QUFBQSxZQUN2QjtBQUFBLFVBQ0YsQ0FBQztBQUNELGlCQUFPLEVBQUUsWUFBWSxTQUFTLFdBQVc7QUFBQSxRQUMzQztBQUFBLFFBQ0EsT0FBTyxDQUFDLE1BQU0sSUFBSSxhQUFhLEVBQUUsUUFBUSxPQUFPLENBQUMsR0FBRyxPQUFPLEVBQUUsQ0FBQztBQUFBLE1BQ2hFLENBQUM7QUFBQSxJQUNIO0FBQUEsSUFFQSxNQUFNLFlBQVk7QUFDaEIsWUFBTUEsV0FBVSxNQUFNLG1CQUFtQjtBQUN6QyxVQUFJQSxvQkFBbUIsT0FBTztBQUM1QixlQUFPQTtBQUFBLE1BQ1Q7QUFFQSxhQUFjLGlCQUFTO0FBQUEsUUFDckIsS0FBSyxZQUFZO0FBQ2YsZ0JBQU1BLFNBQVEsS0FBSztBQUNuQixnQkFBTSxRQUFRLFFBQVEsT0FBTztBQUFBLFlBQzNCO0FBQUEsWUFDQSxpQkFBaUI7QUFBQSxZQUNqQixpQkFBaUI7QUFBQSxZQUNqQixrQkFBa0I7QUFBQSxjQUNoQixVQUFVO0FBQUEsY0FDVixXQUFXO0FBQUEsY0FDWCxZQUFZO0FBQUEsWUFDZDtBQUFBLFVBQ0YsQ0FBQztBQUNELGlCQUFPO0FBQUEsUUFDVDtBQUFBLFFBQ0EsT0FBTyxDQUFDLE1BQU0sSUFBSSxhQUFhLEVBQUUsUUFBUSxPQUFPLENBQUMsR0FBRyxPQUFPLEVBQUUsQ0FBQztBQUFBLE1BQ2hFLENBQUM7QUFBQSxJQUNIO0FBQUEsSUFFQSxXQUFXLFlBQVk7QUFDckIsWUFBTUEsV0FBVSxNQUFNLG1CQUFtQjtBQUN6QyxVQUFJQSxvQkFBbUIsT0FBTztBQUM1QixlQUFPQTtBQUFBLE1BQ1Q7QUFDQSxhQUFPQSxTQUFRO0FBQUEsSUFDakI7QUFBQSxJQUVBLGNBQWMsWUFBWTtBQUN4QixZQUFNQSxXQUFVLE1BQU0sbUJBQW1CO0FBQ3pDLFVBQUlBLG9CQUFtQixPQUFPO0FBQzVCLGVBQU9BO0FBQUEsTUFDVDtBQUNBLGFBQU9BLFNBQVE7QUFBQSxJQUNqQjtBQUFBLElBRUEscUJBQXFCLFlBQVk7QUFDL0IsWUFBTUEsV0FBVSxNQUFNLG1CQUFtQjtBQUN6QyxVQUFJQSxvQkFBbUIsT0FBTztBQUM1QixlQUFPQTtBQUFBLE1BQ1Q7QUFDQSxhQUFPQSxTQUFRO0FBQUEsSUFDakI7QUFBQSxFQUNGO0FBRUEsaUJBQWUsT0FBTyxNQU9uQjtBQUNELFVBQU0sV0FBVyxNQUFNLG1CQUFtQjtBQUMxQyxRQUFJLG9CQUFvQixPQUFPO0FBQzdCLGFBQU87QUFBQSxJQUNUO0FBRUEsVUFBTSxnQkFBZ0IsbUJBQW1CO0FBQ3pDLFVBQU0sYUFBYSxNQUFNLGVBQWUsVUFBVSxJQUFJO0FBQ3RELFVBQU07QUFDTixXQUFPO0FBQUEsRUFDVDtBQUVBLFFBQU0sVUFBMEI7QUFBQSxJQUM5QjtBQUFBLElBQ0E7QUFBQSxJQUNBO0FBQUEsSUFDQSxNQUFNLE9BQU8sU0FBUztBQUNwQixZQUFNLFNBQVMsTUFBTSxPQUFPLElBQUk7QUFFaEMsVUFBSSxrQkFBa0IsZ0JBQWdCLG1CQUFtQixPQUFPLEtBQUssR0FBRztBQUN0RSxjQUFNLHdCQUF3QjtBQUM5QixlQUFPLE1BQU0sT0FBTyxJQUFJO0FBQUEsTUFDMUI7QUFFQSxhQUFPO0FBQUEsSUFDVDtBQUFBLElBRUEsV0FBVyxPQUFPLFNBQVM7QUFDekIsWUFBTUEsV0FBVSxNQUFNLG1CQUFtQjtBQUN6QyxVQUFJQSxvQkFBbUIsT0FBTztBQUM1QixlQUFPQTtBQUFBLE1BQ1Q7QUFFQSxVQUFJO0FBQ0YsZUFBT0EsU0FBUSxPQUFPLElBQUk7QUFBQSxNQUM1QixTQUFTLEdBQUc7QUFDVixlQUFPLElBQUksYUFBYSxFQUFFLFFBQVEsT0FBTyxDQUFDLEdBQUcsT0FBTyxFQUFFLENBQUM7QUFBQSxNQUN6RDtBQUFBLElBQ0Y7QUFBQSxJQUVBLE1BQU0sT0FBTyxFQUFFLFdBQVcsU0FBUyxXQUFXLE1BQU07QUFDbEQsWUFBTSxXQUFXLE1BQU0sbUJBQW1CO0FBQzFDLFVBQUksb0JBQW9CLE9BQU87QUFDN0IsZUFBTztBQUFBLE1BQ1Q7QUFFQSxZQUFNLE1BQU0sTUFBTSxXQUFXLFFBQVEsSUFBSSxTQUFTO0FBQ2xELFVBQUksZUFBZSxPQUFPO0FBQ3hCLGVBQU8sSUFBSSxhQUFhLEVBQUUsUUFBUSxJQUFJLFNBQVMsT0FBTyxJQUFJLENBQUM7QUFBQSxNQUM3RDtBQUNBLFVBQUksT0FBTyxJQUFJLFdBQVcsV0FBVztBQUNuQyxjQUFNLFNBQVMsTUFBTSxXQUFXLFFBQVEsSUFBSTtBQUFBLFVBQzFDLEdBQUc7QUFBQSxVQUNILFFBQVE7QUFBQSxRQUNWLENBQUM7QUFDRCxZQUFJLGtCQUFrQixPQUFPO0FBQzNCLGlCQUFPLElBQUksYUFBYSxFQUFFLFFBQVEsT0FBTyxTQUFTLE9BQU8sT0FBTyxDQUFDO0FBQUEsUUFDbkU7QUFBQSxNQUNGO0FBQ0EsYUFBTztBQUFBLElBQ1Q7QUFBQSxJQUVBLFVBQVUsT0FBTyxTQUFTO0FBQ3hCLFlBQU0sV0FBVyxNQUFNLG1CQUFtQjtBQUMxQyxVQUFJLG9CQUFvQixPQUFPO0FBQzdCLGVBQU87QUFBQSxNQUNUO0FBQ0EsYUFBTyxtQkFBbUIsVUFBVSxJQUFJO0FBQUEsSUFDMUM7QUFBQSxJQUVBLFlBQVksT0FBTyxTQUFTO0FBQzFCLFlBQU0sV0FBVyxNQUFNLG1CQUFtQjtBQUMxQyxVQUFJLG9CQUFvQixPQUFPO0FBQzdCLGNBQU07QUFBQSxNQUNSO0FBQ0EsYUFBTyxxQkFBcUIsVUFBVSxJQUFJO0FBQUEsSUFDNUM7QUFBQSxJQUVBO0FBQUEsSUFFQSxxQkFBcUIsT0FBTyxXQUFXO0FBQ3JDLFlBQU0sV0FBVyxNQUFNLG1CQUFtQjtBQUMxQyxVQUFJLG9CQUFvQixPQUFPO0FBQzdCLGVBQU87QUFBQSxNQUNUO0FBQ0EsYUFBYyxpQkFBUztBQUFBLFFBQ3JCLEtBQUssTUFBTSxTQUFTLG9CQUFvQixNQUFNO0FBQUEsUUFDOUMsT0FBTyxDQUFDLE1BQU0sSUFBSSxhQUFhLEVBQUUsUUFBUSxPQUFPLENBQUMsR0FBRyxPQUFPLEVBQUUsQ0FBQztBQUFBLE1BQ2hFLENBQUM7QUFBQSxJQUNIO0FBQUEsSUFFQSxLQUFLO0FBQUEsTUFDSCxNQUFNLFlBQVk7QUFDaEIsY0FBTUssaUJBQWdCLE1BQU0sUUFBUSxRQUFRLElBQUksRUFBRTtBQUNsRCxZQUFJQSwwQkFBeUIsT0FBTztBQUNsQyxpQkFBT0E7QUFBQSxRQUNUO0FBQ0EsZUFBUUEsZUFBYyxRQUFRLENBQUM7QUFBQSxNQUNqQztBQUFBLE1BQ0EsS0FBSyxPQUFPLFFBQWdCO0FBQzFCLGNBQU1BLGlCQUFnQixNQUFNLFFBQVEsUUFBUSxJQUFJLEVBQUU7QUFDbEQsWUFBSUEsMEJBQXlCLE9BQU87QUFDbEMsaUJBQU9BO0FBQUEsUUFDVDtBQUNBLGVBQU9BLGVBQWMsT0FBTyxHQUFhO0FBQUEsTUFHM0M7QUFBQSxNQUNBLEtBQUssT0FBTyxLQUFhLFVBQW1CO0FBQzFDLGNBQU0sU0FBUyxNQUFNLFFBQVEsUUFBUSxJQUFJLElBQUk7QUFBQSxVQUMzQyxXQUFXO0FBQUEsVUFDWCxNQUFNLEVBQUUsQ0FBQyxHQUFHLEdBQUcsTUFBTTtBQUFBLFFBQ3ZCLENBQUM7QUFDRCxZQUFJLGtCQUFrQixPQUFPO0FBQzNCLGlCQUFPO0FBQUEsUUFDVDtBQUNBLGVBQU87QUFBQSxNQUNUO0FBQUEsTUFDQSxTQUFTLE9BQU8sU0FBa0M7QUFDaEQsY0FBTSxTQUFTLE1BQU0sUUFBUSxRQUFRLElBQUksSUFBSTtBQUFBLFVBQzNDLFdBQVc7QUFBQSxVQUNYO0FBQUEsUUFDRixDQUFDO0FBQ0QsWUFBSSxrQkFBa0IsT0FBTztBQUMzQixpQkFBTztBQUFBLFFBQ1Q7QUFDQSxlQUFPO0FBQUEsTUFDVDtBQUFBLElBQ0Y7QUFBQSxFQUNGO0FBRUEsU0FBTztBQUNUOzs7QUNwcENBLElBQU0sTUFBTSxhQUFhLEVBQUUsV0FBVyxVQUFVLENBQUM7QUFhakQsSUFBTSxlQUFlLG9CQUFJLElBQTZCO0FBRS9DLFNBQVMsV0FBa0Q7QUFBQSxFQUNoRTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0EsMEJBQTBCO0FBQUEsRUFDMUI7QUFBQSxFQUNBO0FBQ0YsR0FRMkI7QUFDekIsUUFBTSxTQUFTLGFBQWEsSUFBSSxjQUFjLEVBQUU7QUFDaEQsTUFBSSxRQUFRO0FBQ1YsV0FBTztBQUFBLEVBQ1Q7QUFFQSxRQUFNLE1BQU0sY0FBcUI7QUFBQSxJQUMvQjtBQUFBLElBQ0E7QUFBQSxJQUNBO0FBQUEsSUFDQTtBQUFBLElBQ0E7QUFBQSxJQUNBO0FBQUEsSUFDQTtBQUFBLEVBQ0YsQ0FBQztBQUVELGVBQWEsY0FBYyxJQUFJLEdBQUc7QUFFbEMsU0FBTztBQUNUO0FBRU8sU0FBUyxhQUFhLElBQWtCO0FBQzdDLGVBQWEsT0FBTyxFQUFFO0FBQ3hCO0FBRU8sU0FBUyxhQUFhLElBQVksU0FBd0I7QUFDL0QsZUFBYSxJQUFJLElBQUksT0FBMEI7QUFDakQ7QUFFTyxTQUFTLGNBQXFEO0FBQUEsRUFDbkU7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBLDBCQUEwQjtBQUFBLEVBQzFCO0FBQUEsRUFDQTtBQUNGLEdBUTJCO0FBQ3pCLE1BQUk7QUFJSixRQUFNLGNBQXdDLFFBQzFDO0FBQUEsSUFDRSxHQUFHO0FBQUEsSUFDSCxLQUFLLEdBQUcsY0FBYyxPQUFPLElBQUksSUFBSSxNQUFNLEdBQUc7QUFBQSxFQUNoRCxJQUNBO0FBRUosUUFBTSxxQkFBcUIsY0FDdkIsRUFBRSxHQUFHLGVBQWUsVUFBVSxZQUFZLElBQUksSUFDOUM7QUFFSixVQUFRLGNBQWMsT0FBTyxNQUFNO0FBQUEsSUFDakMsS0FBSztBQUNILFlBQU0sYUFBb0I7QUFBQSxRQUN4QixlQUFlO0FBQUEsUUFHZjtBQUFBLFFBQ0EsT0FBTztBQUFBLFFBQ1A7QUFBQSxNQUNGLENBQUM7QUFDRDtBQUFBLElBQ0YsS0FBSztBQUNILFlBQU0sY0FBcUI7QUFBQSxRQUN6QixlQUFlO0FBQUEsUUFHZjtBQUFBLFFBQ0EsT0FBTztBQUFBLFFBQ1A7QUFBQSxNQUNGLENBQUM7QUFDRDtBQUFBLElBQ0YsS0FBSztBQUNILFlBQU0sY0FBcUI7QUFBQSxRQUN6QixlQUFlO0FBQUEsUUFHZjtBQUFBLFFBQ0E7QUFBQSxRQUNBO0FBQUEsUUFDQTtBQUFBLFFBQ0EsT0FBTztBQUFBLFFBQ1A7QUFBQSxNQUNGLENBQUM7QUFDRDtBQUFBLElBQ0YsS0FBSztBQUNILFlBQU0sSUFBSSxNQUFNLG9DQUFvQztBQUFBLElBQ3REO0FBQ0Usb0JBQWM7QUFDZCxZQUFNLElBQUk7QUFBQSxRQUNSO0FBQUEsUUFFRyxjQUFjLE9BQWUsSUFDaEM7QUFBQSxNQUNGO0FBQUEsRUFDSjtBQUVBLE1BQUksZUFBcUM7QUFDekMsTUFBSTtBQUVKLFdBQVMsY0FBNkI7QUFDcEMsUUFBSSxjQUFjO0FBQ2hCLGFBQU87QUFBQSxJQUNUO0FBQ0Esb0JBQWdCLFlBQVk7QUFDMUIsWUFBTSxPQUFPLElBQUksS0FBSyxpQ0FBaUM7QUFBQSxRQUNyRCxXQUFXLGNBQWM7QUFBQSxNQUMzQixDQUFDO0FBQ0QsWUFBTSxTQUFTLE1BQU0sSUFBSSxVQUFVLE1BQU07QUFDekMsV0FBSztBQUNMLFVBQUksa0JBQWtCLE9BQU87QUFDM0IsY0FBTTtBQUFBLE1BQ1I7QUFBQSxJQUNGLEdBQUcsRUFBRSxNQUFNLENBQUMsTUFBTTtBQUNoQixxQkFBZTtBQUNmLHNCQUFnQjtBQUNoQixZQUFNO0FBQUEsSUFDUixDQUFDO0FBQ0Qsb0JBQWdCO0FBQ2hCLFdBQU87QUFBQSxFQUNUO0FBT0EsUUFBTSxZQUNKLGNBQWMsT0FBTyxTQUFTLFdBQzFCLGNBQWMsT0FBTyxXQUFXLGNBQWMsUUFDOUM7QUFFTixNQUFJLFdBQVc7QUFDYixnQkFBWTtBQUFBLEVBQ2Q7QUFZQSxTQUFPO0FBQUEsSUFDTCxHQUFHO0FBQUEsSUFDSCxJQUFJLFdBQVc7QUFDYixhQUFPO0FBQUEsSUFDVDtBQUFBLElBQ0EsTUFBTSxPQUFPLFNBQVM7QUFDcEIsWUFBTSxZQUFZO0FBQ2xCLGFBQU8sSUFBSSxLQUFLLElBQUk7QUFBQSxJQUN0QjtBQUFBLElBQ0EsV0FBVyxPQUFPLFNBQVM7QUFDekIsWUFBTSxZQUFZO0FBQ2xCLGFBQU8sSUFBSSxVQUFVLElBQUk7QUFBQSxJQUMzQjtBQUFBLElBQ0EsVUFBVSxPQUFPLFNBQVM7QUFDeEIsWUFBTSxZQUFZO0FBQ2xCLGFBQU8sSUFBSSxTQUFTLElBQUk7QUFBQSxJQUMxQjtBQUFBLElBQ0EsWUFBWSxPQUFPLFNBQVM7QUFDMUIsWUFBTSxZQUFZO0FBQ2xCLGFBQU8sSUFBSSxXQUFXLElBQUk7QUFBQSxJQUM1QjtBQUFBLEVBQ0Y7QUFDRjsiLAogICJuYW1lcyI6IFsicmVzb2x2ZSIsICJzdG9yYWdlIiwgInNhbmRib3hSZWNvcmQiLCAicGF0aCIsICJlcnJvcmUiLCAic2FuZGJveCIsICJsb2ciLCAicmVzb2x2ZSIsICJwYXRoIiwgImZyZXNoUmVzdWx0IiwgInNhbmRib3hSZWNvcmQiXQp9Cg==