@tscircuit/cli 0.1.16 → 0.1.17

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.
@@ -8,6 +8,7 @@ import path from "node:path"
8
8
  import fs from "node:fs"
9
9
  import type { FileUpdatedEvent } from "lib/file-server/FileServerEvent"
10
10
  import * as chokidar from "chokidar"
11
+ import { FilesystemTypesHandler } from "lib/dependency-analysis/FilesystemTypesHandler"
11
12
 
12
13
  export class DevServer {
13
14
  port: number
@@ -37,6 +38,8 @@ export class DevServer {
37
38
  */
38
39
  filesystemWatcher?: chokidar.FSWatcher
39
40
 
41
+ private typesHandler?: FilesystemTypesHandler
42
+
40
43
  constructor({
41
44
  port,
42
45
  componentFilePath,
@@ -50,6 +53,7 @@ export class DevServer {
50
53
  this.fsKy = ky.create({
51
54
  prefixUrl: `http://localhost:${port}`,
52
55
  }) as any
56
+ this.typesHandler = new FilesystemTypesHandler(this.projectDir)
53
57
  }
54
58
 
55
59
  async start() {
@@ -77,6 +81,8 @@ export class DevServer {
77
81
  )
78
82
 
79
83
  this.upsertInitialFiles()
84
+
85
+ this.typesHandler?.handleInitialTypeDependencies(this.componentFilePath)
80
86
  }
81
87
 
82
88
  async addEntrypoint() {
@@ -119,6 +125,8 @@ circuit.add(<MyCircuit />)
119
125
  // because it can be edited by the browser
120
126
  if (relativeFilePath.includes("manual-edits.json")) return
121
127
 
128
+ await this.typesHandler?.handleFileTypeDependencies(absoluteFilePath)
129
+
122
130
  console.log(`${relativeFilePath} saved. Applying changes...`)
123
131
  await this.fsKy
124
132
  .post("api/files/upsert", {
package/dist/main.js CHANGED
@@ -54,8 +54,8 @@ export default () => (
54
54
  };
55
55
 
56
56
  // cli/dev/register.ts
57
- import * as path5 from "node:path";
58
- import * as fs5 from "node:fs";
57
+ import * as path6 from "node:path";
58
+ import * as fs7 from "node:fs";
59
59
 
60
60
  // lib/dependency-analysis/installNodeModuleTypesForSnippet.ts
61
61
  import * as fs2 from "node:fs";
@@ -131,7 +131,7 @@ var package_default = {
131
131
  name: "@tscircuit/cli",
132
132
  main: "dist/main.js",
133
133
  type: "module",
134
- version: "0.1.15",
134
+ version: "0.1.16",
135
135
  bin: {
136
136
  tsci: "./dist/main.js"
137
137
  },
@@ -233,10 +233,10 @@ var createHttpServer = async (port = 3e3) => {
233
233
  res.writeHead(404);
234
234
  res.end("Not found");
235
235
  });
236
- return new Promise((resolve3) => {
236
+ return new Promise((resolve4) => {
237
237
  server.listen(port, () => {
238
238
  console.log(`Server running at http://localhost:${port}`);
239
- resolve3({ server });
239
+ resolve4({ server });
240
240
  });
241
241
  });
242
242
  };
@@ -293,9 +293,99 @@ var EventsWatcher = class extends EventEmitter {
293
293
  };
294
294
 
295
295
  // cli/dev/DevServer.ts
296
- import path4 from "node:path";
297
- import fs4 from "node:fs";
296
+ import path5 from "node:path";
297
+ import fs6 from "node:fs";
298
298
  import * as chokidar from "chokidar";
299
+
300
+ // lib/dependency-analysis/FilesystemTypesHandler.ts
301
+ import * as fs5 from "node:fs";
302
+ import * as path4 from "node:path";
303
+
304
+ // lib/dependency-analysis/findImportsInSnippet.ts
305
+ import * as fs4 from "node:fs";
306
+ import * as ts2 from "typescript";
307
+ function findImportsInSnippet(snippetPath) {
308
+ const content = fs4.readFileSync(snippetPath, "utf-8");
309
+ const sourceFile = ts2.createSourceFile(
310
+ snippetPath,
311
+ content,
312
+ ts2.ScriptTarget.Latest,
313
+ true
314
+ );
315
+ const imports = [];
316
+ function visit(node) {
317
+ if (ts2.isImportDeclaration(node)) {
318
+ const moduleSpecifier = node.moduleSpecifier;
319
+ if (moduleSpecifier && ts2.isStringLiteral(moduleSpecifier)) {
320
+ const importPath = moduleSpecifier.text;
321
+ if (importPath.startsWith("@tsci/")) {
322
+ imports.push(importPath);
323
+ }
324
+ }
325
+ }
326
+ ts2.forEachChild(node, visit);
327
+ }
328
+ visit(sourceFile);
329
+ return imports;
330
+ }
331
+
332
+ // lib/dependency-analysis/FilesystemTypesHandler.ts
333
+ var FilesystemTypesHandler = class {
334
+ projectRoot;
335
+ constructor(initialDir) {
336
+ this.projectRoot = this.findProjectRoot(initialDir);
337
+ }
338
+ async handleInitialTypeDependencies(filePath) {
339
+ console.log("Checking initial type dependencies...");
340
+ try {
341
+ if (!this.areTypesInstalled(filePath)) {
342
+ console.log("Installing missing initial types...");
343
+ await installNodeModuleTypesForSnippet(filePath);
344
+ }
345
+ } catch (error) {
346
+ console.warn("Error handling initial type dependencies:", error);
347
+ }
348
+ }
349
+ async handleFileTypeDependencies(filePath) {
350
+ try {
351
+ if (!this.areTypesInstalled(filePath)) {
352
+ console.log("Installing missing file types...");
353
+ await installNodeModuleTypesForSnippet(filePath);
354
+ }
355
+ } catch (error) {
356
+ console.warn("Failed to verify types:", error);
357
+ }
358
+ }
359
+ areTypesInstalled(filePath) {
360
+ const imports = findImportsInSnippet(filePath);
361
+ return imports.every((imp) => this.checkTypeExists(imp));
362
+ }
363
+ checkTypeExists(importPath) {
364
+ if (!importPath.startsWith("@tsci/")) return true;
365
+ const pathWithoutPrefix = importPath.replace("@tsci/", "");
366
+ const [owner, name] = pathWithoutPrefix.split(".");
367
+ const typePath = path4.join(
368
+ this.projectRoot,
369
+ "node_modules",
370
+ "@tsci",
371
+ `${owner}.${name}`,
372
+ "index.d.ts"
373
+ );
374
+ return fs5.existsSync(typePath);
375
+ }
376
+ findProjectRoot(startDir) {
377
+ let root = path4.resolve(startDir);
378
+ while (root !== path4.parse(root).root) {
379
+ if (fs5.existsSync(path4.join(root, "package.json"))) {
380
+ return root;
381
+ }
382
+ root = path4.dirname(root);
383
+ }
384
+ return startDir;
385
+ }
386
+ };
387
+
388
+ // cli/dev/DevServer.ts
299
389
  var DevServer = class {
300
390
  port;
301
391
  /**
@@ -321,16 +411,18 @@ var DevServer = class {
321
411
  * A chokidar instance that watches the project directory for file changes
322
412
  */
323
413
  filesystemWatcher;
414
+ typesHandler;
324
415
  constructor({
325
416
  port,
326
417
  componentFilePath
327
418
  }) {
328
419
  this.port = port;
329
420
  this.componentFilePath = componentFilePath;
330
- this.projectDir = path4.dirname(componentFilePath);
421
+ this.projectDir = path5.dirname(componentFilePath);
331
422
  this.fsKy = ky.create({
332
423
  prefixUrl: `http://localhost:${port}`
333
424
  });
425
+ this.typesHandler = new FilesystemTypesHandler(this.projectDir);
334
426
  }
335
427
  async start() {
336
428
  const { server } = await createHttpServer(this.port);
@@ -354,9 +446,10 @@ var DevServer = class {
354
446
  (filePath) => this.handleFileChangedOnFilesystem(filePath)
355
447
  );
356
448
  this.upsertInitialFiles();
449
+ this.typesHandler?.handleInitialTypeDependencies(this.componentFilePath);
357
450
  }
358
451
  async addEntrypoint() {
359
- const relativeComponentFilePath = path4.relative(
452
+ const relativeComponentFilePath = path5.relative(
360
453
  this.projectDir,
361
454
  this.componentFilePath
362
455
  );
@@ -378,31 +471,32 @@ circuit.add(<MyCircuit />)
378
471
  const { file } = await this.fsKy.get("api/files/get", {
379
472
  searchParams: { file_path: ev.file_path }
380
473
  }).json();
381
- fs4.writeFileSync(
382
- path4.join(this.projectDir, "manual-edits.json"),
474
+ fs6.writeFileSync(
475
+ path5.join(this.projectDir, "manual-edits.json"),
383
476
  file.text_content
384
477
  );
385
478
  }
386
479
  }
387
480
  async handleFileChangedOnFilesystem(absoluteFilePath) {
388
- const relativeFilePath = path4.relative(this.projectDir, absoluteFilePath);
481
+ const relativeFilePath = path5.relative(this.projectDir, absoluteFilePath);
389
482
  if (relativeFilePath.includes("manual-edits.json")) return;
483
+ await this.typesHandler?.handleFileTypeDependencies(absoluteFilePath);
390
484
  console.log(`${relativeFilePath} saved. Applying changes...`);
391
485
  await this.fsKy.post("api/files/upsert", {
392
486
  json: {
393
487
  file_path: relativeFilePath,
394
- text_content: fs4.readFileSync(absoluteFilePath, "utf-8"),
488
+ text_content: fs6.readFileSync(absoluteFilePath, "utf-8"),
395
489
  initiator: "filesystem_change"
396
490
  }
397
491
  }).json();
398
492
  }
399
493
  async upsertInitialFiles() {
400
- const fileNames = fs4.readdirSync(this.projectDir);
494
+ const fileNames = fs6.readdirSync(this.projectDir);
401
495
  for (const fileName of fileNames) {
402
- if (fs4.statSync(path4.join(this.projectDir, fileName)).isDirectory())
496
+ if (fs6.statSync(path5.join(this.projectDir, fileName)).isDirectory())
403
497
  continue;
404
- const fileContent = fs4.readFileSync(
405
- path4.join(this.projectDir, fileName),
498
+ const fileContent = fs6.readFileSync(
499
+ path5.join(this.projectDir, fileName),
406
500
  "utf-8"
407
501
  );
408
502
  await this.fsKy.post("api/files/upsert", {
@@ -426,10 +520,10 @@ var registerDev = (program2) => {
426
520
  const port = parseInt(options.port);
427
521
  let absolutePath;
428
522
  if (file) {
429
- absolutePath = path5.resolve(file);
523
+ absolutePath = path6.resolve(file);
430
524
  } else {
431
- const entrypointPath = path5.resolve("index.tsx");
432
- if (fs5.existsSync(entrypointPath)) {
525
+ const entrypointPath = path6.resolve("index.tsx");
526
+ if (fs7.existsSync(entrypointPath)) {
433
527
  absolutePath = entrypointPath;
434
528
  console.log("No file provided. Using 'index.tsx' as the entrypoint.");
435
529
  } else {
@@ -439,7 +533,7 @@ var registerDev = (program2) => {
439
533
  return;
440
534
  }
441
535
  }
442
- const fileDir = path5.dirname(absolutePath);
536
+ const fileDir = path6.dirname(absolutePath);
443
537
  try {
444
538
  console.log("Installing types for imported snippets...");
445
539
  await installNodeModuleTypesForSnippet(absolutePath);
@@ -568,8 +662,8 @@ var registerConfigPrint = (program2) => {
568
662
  };
569
663
 
570
664
  // cli/clone/register.ts
571
- import * as fs6 from "node:fs";
572
- import * as path6 from "node:path";
665
+ import * as fs8 from "node:fs";
666
+ import * as path7 from "node:path";
573
667
  var registerClone = (program2) => {
574
668
  program2.command("clone").description("Clone a snippet from the registry").argument("<snippet>", "Snippet to clone (e.g. author/snippetName)").action(async (snippetPath) => {
575
669
  let author;
@@ -599,8 +693,8 @@ var registerClone = (program2) => {
599
693
  }
600
694
  }).json();
601
695
  const dirPath = `./${author}.${snippetName}`;
602
- if (!fs6.existsSync(dirPath)) {
603
- fs6.mkdirSync(dirPath);
696
+ if (!fs8.existsSync(dirPath)) {
697
+ fs8.mkdirSync(dirPath);
604
698
  }
605
699
  for (const fileInfo of packageFileList.package_files) {
606
700
  const filePath = fileInfo.file_path.startsWith("/") ? fileInfo.file_path.slice(1) : fileInfo.file_path;
@@ -611,15 +705,15 @@ var registerClone = (program2) => {
611
705
  file_path: fileInfo.file_path
612
706
  }
613
707
  }).json();
614
- const fullPath = path6.join(dirPath, filePath);
615
- const dirName = path6.dirname(fullPath);
616
- if (!fs6.existsSync(dirName)) {
617
- fs6.mkdirSync(dirName, { recursive: true });
708
+ const fullPath = path7.join(dirPath, filePath);
709
+ const dirName = path7.dirname(fullPath);
710
+ if (!fs8.existsSync(dirName)) {
711
+ fs8.mkdirSync(dirName, { recursive: true });
618
712
  }
619
- fs6.writeFileSync(fullPath, fileContent.package_file.content_text);
713
+ fs8.writeFileSync(fullPath, fileContent.package_file.content_text);
620
714
  }
621
- const npmrcPath = path6.join(dirPath, ".npmrc");
622
- fs6.writeFileSync(npmrcPath, "@tsci:registry=https://npm.tscircuit.com");
715
+ const npmrcPath = path7.join(dirPath, ".npmrc");
716
+ fs8.writeFileSync(npmrcPath, "@tsci:registry=https://npm.tscircuit.com");
623
717
  console.log(`Successfully cloned to ./${author}.${snippetName}/`);
624
718
  } catch (error) {
625
719
  if (error instanceof Error) {
@@ -640,8 +734,8 @@ import semver from "semver";
640
734
  import { createCircuitWebWorker } from "@tscircuit/eval-webworker";
641
735
  import webWorkerBundleUrl from "@tscircuit/eval-webworker/blob-url";
642
736
  import { getVirtualFileSystemFromDirPath } from "make-vfs";
643
- import path7 from "node:path";
644
- import fs7 from "node:fs";
737
+ import path8 from "node:path";
738
+ import fs9 from "node:fs";
645
739
  var ALLOWED_FORMATS = [
646
740
  "json",
647
741
  "circuit-json",
@@ -673,13 +767,13 @@ Supported formats: ${ALLOWED_FORMATS.join(",")}`
673
767
  );
674
768
  }
675
769
  if (!output) {
676
- output = path7.basename(file).replace(/\.[^.]+$/, "");
770
+ output = path8.basename(file).replace(/\.[^.]+$/, "");
677
771
  }
678
772
  const worker = await createCircuitWebWorker({
679
773
  webWorkerUrl: webWorkerBundleUrl
680
774
  });
681
- const projectDir = path7.dirname(file);
682
- const relativeComponentPath = path7.relative(projectDir, file);
775
+ const projectDir = path8.dirname(file);
776
+ const relativeComponentPath = path8.relative(projectDir, file);
683
777
  await worker.executeWithFsMap({
684
778
  entrypoint: "entrypoint.tsx",
685
779
  fsMap: {
@@ -696,11 +790,11 @@ circuit.add(<MyCircuit />)
696
790
  });
697
791
  await worker.renderUntilSettled();
698
792
  const circuitJson = await worker.getCircuitJson();
699
- const outputPath = path7.join(
793
+ const outputPath = path8.join(
700
794
  projectDir,
701
795
  `${output}${OUTPUT_EXTENSIONS[format]}`
702
796
  );
703
- fs7.writeFileSync(outputPath, JSON.stringify(circuitJson));
797
+ fs9.writeFileSync(outputPath, JSON.stringify(circuitJson));
704
798
  console.log(`Exported to ${outputPath}`);
705
799
  process.exit(0);
706
800
  });
@@ -752,4 +846,4 @@ if (process.argv.length === 2) {
752
846
  } else {
753
847
  program.parse();
754
848
  }
755
- //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vY2xpL21haW4udHMiLCAiLi4vY2xpL2luaXQvcmVnaXN0ZXIudHMiLCAiLi4vY2xpL2Rldi9yZWdpc3Rlci50cyIsICIuLi9saWIvZGVwZW5kZW5jeS1hbmFseXNpcy9pbnN0YWxsTm9kZU1vZHVsZVR5cGVzRm9yU25pcHBldC50cyIsICIuLi9jbGkvZGV2L0RldlNlcnZlci50cyIsICIuLi9saWIvc2VydmVyL2NyZWF0ZUh0dHBTZXJ2ZXIudHMiLCAiLi4vcGFja2FnZS5qc29uIiwgIi4uL2xpYi9zaXRlL2dldEluZGV4LnRzIiwgIi4uL2xpYi9zZXJ2ZXIvRXZlbnRzV2F0Y2hlci50cyIsICIuLi9saWIvY2xpLWNvbmZpZy9pbmRleC50cyIsICIuLi9jbGkvYXV0aC9sb2dpbi9yZWdpc3Rlci50cyIsICIuLi9saWIvcmVnaXN0cnktYXBpL2dldC1reS50cyIsICIuLi9jbGkvYXV0aC9sb2dvdXQvcmVnaXN0ZXIudHMiLCAiLi4vY2xpL2F1dGgvcmVnaXN0ZXIudHMiLCAiLi4vY2xpL2NvbmZpZy9yZWdpc3Rlci50cyIsICIuLi9jbGkvY29uZmlnL3ByaW50L3JlZ2lzdGVyLnRzIiwgIi4uL2NsaS9jbG9uZS9yZWdpc3Rlci50cyIsICIuLi9jbGkvZXhwb3J0L3JlZ2lzdGVyLnRzIiwgIi4uL2NsaS9hdXRoL3ByaW50LXRva2VuL3JlZ2lzdGVyLnRzIiwgIi4uL2NsaS9hdXRoL3NldC10b2tlbi9yZWdpc3Rlci50cyJdLAogICJzb3VyY2VzQ29udGVudCI6IFsiIyEvdXNyL2Jpbi9lbnYgbm9kZVxuaW1wb3J0IHsgQ29tbWFuZCB9IGZyb20gXCJjb21tYW5kZXJcIlxuaW1wb3J0IHsgcmVnaXN0ZXJJbml0IH0gZnJvbSBcIi4vaW5pdC9yZWdpc3RlclwiXG5pbXBvcnQgeyByZWdpc3RlckRldiB9IGZyb20gXCIuL2Rldi9yZWdpc3RlclwiXG5pbXBvcnQgeyByZWdpc3RlckF1dGhMb2dpbiB9IGZyb20gXCIuL2F1dGgvbG9naW4vcmVnaXN0ZXJcIlxuaW1wb3J0IHsgcmVnaXN0ZXJBdXRoTG9nb3V0IH0gZnJvbSBcIi4vYXV0aC9sb2dvdXQvcmVnaXN0ZXJcIlxuaW1wb3J0IHsgcmVnaXN0ZXJBdXRoIH0gZnJvbSBcIi4vYXV0aC9yZWdpc3RlclwiXG5pbXBvcnQgeyByZWdpc3RlckNvbmZpZyB9IGZyb20gXCIuL2NvbmZpZy9yZWdpc3RlclwiXG5pbXBvcnQgeyByZWdpc3RlckNvbmZpZ1ByaW50IH0gZnJvbSBcIi4vY29uZmlnL3ByaW50L3JlZ2lzdGVyXCJcbmltcG9ydCB7IHJlZ2lzdGVyQ2xvbmUgfSBmcm9tIFwiLi9jbG9uZS9yZWdpc3RlclwiXG5pbXBvcnQgeyBwZXJmZWN0Q2xpIH0gZnJvbSBcInBlcmZlY3QtY2xpXCJcbmltcG9ydCBwa2cgZnJvbSBcIi4uL3BhY2thZ2UuanNvblwiXG5pbXBvcnQgc2VtdmVyIGZyb20gXCJzZW12ZXJcIlxuaW1wb3J0IHsgcmVnaXN0ZXJFeHBvcnQgfSBmcm9tIFwiLi9leHBvcnQvcmVnaXN0ZXJcIlxuaW1wb3J0IHsgcmVnaXN0ZXJBdXRoUHJpbnRUb2tlbiB9IGZyb20gXCIuL2F1dGgvcHJpbnQtdG9rZW4vcmVnaXN0ZXJcIlxuaW1wb3J0IHsgcmVnaXN0ZXJBdXRoU2V0VG9rZW4gfSBmcm9tIFwiLi9hdXRoL3NldC10b2tlbi9yZWdpc3RlclwiXG5cbmNvbnN0IHByb2dyYW0gPSBuZXcgQ29tbWFuZCgpXG5cbnByb2dyYW1cbiAgLm5hbWUoXCJ0c2NpXCIpXG4gIC5kZXNjcmlwdGlvbihcIkNMSSBmb3IgZGV2ZWxvcGluZyB0c2NpcmN1aXQgc25pcHBldHNcIilcbiAgLy8gSEFDSzogYXQgYnVpbGQgdGltZSB0aGUgdmVyc2lvbiBpcyBvbGQsIHdlIG5lZWQgdG9cbiAgLy8gZml4IHRoaXMgYXQgc29tZSBwb2ludC4uLlxuICAudmVyc2lvbihzZW12ZXIuaW5jKHBrZy52ZXJzaW9uLCBcInBhdGNoXCIpID8/IHBrZy52ZXJzaW9uKVxuXG5yZWdpc3RlckluaXQocHJvZ3JhbSlcblxucmVnaXN0ZXJEZXYocHJvZ3JhbSlcbnJlZ2lzdGVyQ2xvbmUocHJvZ3JhbSlcblxucmVnaXN0ZXJBdXRoKHByb2dyYW0pXG5yZWdpc3RlckF1dGhMb2dpbihwcm9ncmFtKVxucmVnaXN0ZXJBdXRoTG9nb3V0KHByb2dyYW0pXG5yZWdpc3RlckF1dGhQcmludFRva2VuKHByb2dyYW0pXG5yZWdpc3RlckF1dGhTZXRUb2tlbihwcm9ncmFtKVxuXG5yZWdpc3RlckNvbmZpZyhwcm9ncmFtKVxucmVnaXN0ZXJDb25maWdQcmludChwcm9ncmFtKVxuXG5yZWdpc3RlckV4cG9ydChwcm9ncmFtKVxuXG5pZiAocHJvY2Vzcy5hcmd2Lmxlbmd0aCA9PT0gMikge1xuICBwZXJmZWN0Q2xpKHByb2dyYW0sIHByb2Nlc3MuYXJndilcbn0gZWxzZSB7XG4gIHByb2dyYW0ucGFyc2UoKVxufVxuIiwgImltcG9ydCB0eXBlIHsgQ29tbWFuZCB9IGZyb20gXCJjb21tYW5kZXJcIlxuaW1wb3J0ICogYXMgZnMgZnJvbSBcIm5vZGU6ZnNcIlxuaW1wb3J0ICogYXMgcGF0aCBmcm9tIFwibm9kZTpwYXRoXCJcblxuZXhwb3J0IGNvbnN0IHJlZ2lzdGVySW5pdCA9IChwcm9ncmFtOiBDb21tYW5kKSA9PiB7XG4gIHByb2dyYW1cbiAgICAuY29tbWFuZChcImluaXRcIilcbiAgICAuZGVzY3JpcHRpb24oXCJJbml0aWFsaXplIGEgbmV3IFRTQ2lyY3VpdCBwcm9qZWN0IGluIHRoZSBjdXJyZW50IGRpcmVjdG9yeVwiKVxuICAgIC5hY3Rpb24oKCkgPT4ge1xuICAgICAgY29uc3QgY3VycmVudERpciA9IHByb2Nlc3MuY3dkKClcblxuICAgICAgY29uc3QgaW5kZXhGaWxlUGF0aCA9IHBhdGguam9pbihjdXJyZW50RGlyLCBcImluZGV4LnRzeFwiKVxuICAgICAgY29uc3QgbnBtcmNGaWxlUGF0aCA9IHBhdGguam9pbihjdXJyZW50RGlyLCBcIi5ucG1yY1wiKVxuXG4gICAgICBjb25zdCBpbmRleENvbnRlbnQgPSBgXG5leHBvcnQgZGVmYXVsdCAoKSA9PiAoXG4gIDxib2FyZCB3aWR0aD1cIjEwbW1cIiBoZWlnaHQ9XCIxMG1tXCI+XG4gICAgPHJlc2lzdG9yXG4gICAgICByZXNpc3RhbmNlPVwiMWtcIlxuICAgICAgZm9vdHByaW50PVwiMDQwMlwiXG4gICAgICBuYW1lPVwiUjFcIlxuICAgICAgc2NoWD17M31cbiAgICAgIHBjYlg9ezN9XG4gICAgLz5cbiAgICA8Y2FwYWNpdG9yXG4gICAgICBjYXBhY2l0YW5jZT1cIjEwMDBwRlwiXG4gICAgICBmb290cHJpbnQ9XCIwNDAyXCJcbiAgICAgIG5hbWU9XCJDMVwiXG4gICAgICBzY2hYPXstM31cbiAgICAgIHBjYlg9ey0zfVxuICAgIC8+XG4gICAgPHRyYWNlIGZyb209XCIuUjEgPiAucGluMVwiIHRvPVwiLkMxID4gLnBpbjFcIiAvPlxuICA8L2JvYXJkPlxuKTtcbmBcblxuICAgICAgY29uc3QgbnBtcmNDb250ZW50ID0gYFxuQHRzY2k6cmVnaXN0cnk9aHR0cHM6Ly9ucG0udHNjaXJjdWl0LmNvbVxuYFxuXG4gICAgICBpZiAoIWZzLmV4aXN0c1N5bmMoaW5kZXhGaWxlUGF0aCkpIHtcbiAgICAgICAgZnMud3JpdGVGaWxlU3luYyhpbmRleEZpbGVQYXRoLCBpbmRleENvbnRlbnQudHJpbVN0YXJ0KCkpXG4gICAgICAgIGNvbnNvbGUubG9nKGBDcmVhdGVkOiAke2luZGV4RmlsZVBhdGh9YClcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbnNvbGUubG9nKGBTa2lwcGVkOiAke2luZGV4RmlsZVBhdGh9IGFscmVhZHkgZXhpc3RzYClcbiAgICAgIH1cblxuICAgICAgaWYgKCFmcy5leGlzdHNTeW5jKG5wbXJjRmlsZVBhdGgpKSB7XG4gICAgICAgIGZzLndyaXRlRmlsZVN5bmMobnBtcmNGaWxlUGF0aCwgbnBtcmNDb250ZW50LnRyaW1TdGFydCgpKVxuICAgICAgICBjb25zb2xlLmxvZyhgQ3JlYXRlZDogJHtucG1yY0ZpbGVQYXRofWApXG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjb25zb2xlLmxvZyhgU2tpcHBlZDogJHtucG1yY0ZpbGVQYXRofSBhbHJlYWR5IGV4aXN0c2ApXG4gICAgICB9XG5cbiAgICAgIGNvbnNvbGUubG9nKFxuICAgICAgICBgSW5pdGlhbGl6YXRpb24gY29tcGxldGUuIFJ1biBcInRzY2kgZGV2XCIgdG8gc3RhcnQgZGV2ZWxvcGluZy5gLFxuICAgICAgKVxuICAgIH0pXG59XG4iLCAiaW1wb3J0IHR5cGUgeyBDb21tYW5kIH0gZnJvbSBcImNvbW1hbmRlclwiXG5pbXBvcnQgKiBhcyBwYXRoIGZyb20gXCJub2RlOnBhdGhcIlxuaW1wb3J0ICogYXMgY2hva2lkYXIgZnJvbSBcImNob2tpZGFyXCJcbmltcG9ydCAqIGFzIGZzIGZyb20gXCJub2RlOmZzXCJcbmltcG9ydCB7IGNyZWF0ZUh0dHBTZXJ2ZXIgfSBmcm9tIFwibGliL3NlcnZlci9jcmVhdGVIdHRwU2VydmVyXCJcbmltcG9ydCB7IGdldExvY2FsRmlsZURlcGVuZGVuY2llcyB9IGZyb20gXCJsaWIvZGVwZW5kZW5jeS1hbmFseXNpcy9nZXRMb2NhbEZpbGVEZXBlbmRlbmNpZXNcIlxuaW1wb3J0IHsgaW5zdGFsbE5vZGVNb2R1bGVUeXBlc0ZvclNuaXBwZXQgfSBmcm9tIFwiLi4vLi4vbGliL2RlcGVuZGVuY3ktYW5hbHlzaXMvaW5zdGFsbE5vZGVNb2R1bGVUeXBlc0ZvclNuaXBwZXRcIlxuaW1wb3J0IHsgRXZlbnRzV2F0Y2hlciB9IGZyb20gXCIuLi8uLi9saWIvc2VydmVyL0V2ZW50c1dhdGNoZXJcIlxuaW1wb3J0IHsgRGV2U2VydmVyIH0gZnJvbSBcIi4vRGV2U2VydmVyXCJcblxuZXhwb3J0IGNvbnN0IHJlZ2lzdGVyRGV2ID0gKHByb2dyYW06IENvbW1hbmQpID0+IHtcbiAgcHJvZ3JhbVxuICAgIC5jb21tYW5kKFwiZGV2XCIpXG4gICAgLmRlc2NyaXB0aW9uKFwiU3RhcnQgZGV2ZWxvcG1lbnQgc2VydmVyIGZvciBhIHNuaXBwZXRcIilcbiAgICAuYXJndW1lbnQoXCJbZmlsZV1cIiwgXCJQYXRoIHRvIHRoZSBzbmlwcGV0IGZpbGVcIilcbiAgICAub3B0aW9uKFwiLXAsIC0tcG9ydCA8bnVtYmVyPlwiLCBcIlBvcnQgdG8gcnVuIHNlcnZlciBvblwiLCBcIjMwMDBcIilcbiAgICAuYWN0aW9uKGFzeW5jIChmaWxlOiBzdHJpbmcsIG9wdGlvbnM6IHsgcG9ydDogc3RyaW5nIH0pID0+IHtcbiAgICAgIGNvbnN0IHBvcnQgPSBwYXJzZUludChvcHRpb25zLnBvcnQpXG4gICAgICBsZXQgYWJzb2x1dGVQYXRoOiBzdHJpbmdcblxuICAgICAgaWYgKGZpbGUpIHtcbiAgICAgICAgYWJzb2x1dGVQYXRoID0gcGF0aC5yZXNvbHZlKGZpbGUpXG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjb25zdCBlbnRyeXBvaW50UGF0aCA9IHBhdGgucmVzb2x2ZShcImluZGV4LnRzeFwiKVxuICAgICAgICBpZiAoZnMuZXhpc3RzU3luYyhlbnRyeXBvaW50UGF0aCkpIHtcbiAgICAgICAgICBhYnNvbHV0ZVBhdGggPSBlbnRyeXBvaW50UGF0aFxuICAgICAgICAgIGNvbnNvbGUubG9nKFwiTm8gZmlsZSBwcm92aWRlZC4gVXNpbmcgJ2luZGV4LnRzeCcgYXMgdGhlIGVudHJ5cG9pbnQuXCIpXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgY29uc29sZS5sb2coXG4gICAgICAgICAgICBcIk5vIGVudHJ5cG9pbnQgZm91bmQuIFJ1biAndHNjaSBpbml0JyB0byBib290c3RyYXAgYSBiYXNpYyBwcm9qZWN0LlwiLFxuICAgICAgICAgIClcbiAgICAgICAgICByZXR1cm5cbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBjb25zdCBmaWxlRGlyID0gcGF0aC5kaXJuYW1lKGFic29sdXRlUGF0aClcblxuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc29sZS5sb2coXCJJbnN0YWxsaW5nIHR5cGVzIGZvciBpbXBvcnRlZCBzbmlwcGV0cy4uLlwiKVxuICAgICAgICBhd2FpdCBpbnN0YWxsTm9kZU1vZHVsZVR5cGVzRm9yU25pcHBldChhYnNvbHV0ZVBhdGgpXG4gICAgICAgIGNvbnNvbGUubG9nKFwiVHlwZXMgaW5zdGFsbGVkIHN1Y2Nlc3NmdWxseVwiKVxuICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgY29uc29sZS53YXJuKFwiRmFpbGVkIHRvIGluc3RhbGwgdHlwZXM6XCIsIGVycm9yKVxuICAgICAgfVxuXG4gICAgICBjb25zdCBzZXJ2ZXIgPSBuZXcgRGV2U2VydmVyKHtcbiAgICAgICAgcG9ydCxcbiAgICAgICAgY29tcG9uZW50RmlsZVBhdGg6IGFic29sdXRlUGF0aCxcbiAgICAgIH0pXG5cbiAgICAgIGF3YWl0IHNlcnZlci5zdGFydCgpXG4gICAgICBhd2FpdCBzZXJ2ZXIuYWRkRW50cnlwb2ludCgpXG4gICAgfSlcbn1cbiIsICJpbXBvcnQgKiBhcyBmcyBmcm9tIFwibm9kZTpmc1wiXG5pbXBvcnQgKiBhcyBwYXRoIGZyb20gXCJub2RlOnBhdGhcIlxuaW1wb3J0ICogYXMgdHMgZnJvbSBcInR5cGVzY3JpcHRcIlxuXG5pbnRlcmZhY2UgU25pcHBldEFwaVJlc3BvbnNlIHtcbiAgc25pcHBldDoge1xuICAgIGR0czogc3RyaW5nXG4gIH1cbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGluc3RhbGxOb2RlTW9kdWxlVHlwZXNGb3JTbmlwcGV0KHNuaXBwZXRQYXRoOiBzdHJpbmcpIHtcbiAgY29uc3QgY29udGVudCA9IGZzLnJlYWRGaWxlU3luYyhzbmlwcGV0UGF0aCwgXCJ1dGYtOFwiKVxuICBjb25zdCBzb3VyY2VGaWxlID0gdHMuY3JlYXRlU291cmNlRmlsZShcbiAgICBzbmlwcGV0UGF0aCxcbiAgICBjb250ZW50LFxuICAgIHRzLlNjcmlwdFRhcmdldC5MYXRlc3QsXG4gICAgdHJ1ZSxcbiAgKVxuXG4gIGNvbnN0IGltcG9ydHM6IHN0cmluZ1tdID0gW11cblxuICBmdW5jdGlvbiB2aXNpdChub2RlOiB0cy5Ob2RlKSB7XG4gICAgaWYgKHRzLmlzSW1wb3J0RGVjbGFyYXRpb24obm9kZSkpIHtcbiAgICAgIGNvbnN0IG1vZHVsZVNwZWNpZmllciA9IG5vZGUubW9kdWxlU3BlY2lmaWVyXG4gICAgICBpZiAobW9kdWxlU3BlY2lmaWVyICYmIHRzLmlzU3RyaW5nTGl0ZXJhbChtb2R1bGVTcGVjaWZpZXIpKSB7XG4gICAgICAgIGNvbnN0IGltcG9ydFBhdGggPSBtb2R1bGVTcGVjaWZpZXIudGV4dFxuICAgICAgICBpZiAoaW1wb3J0UGF0aC5zdGFydHNXaXRoKFwiQHRzY2kvXCIpKSB7XG4gICAgICAgICAgaW1wb3J0cy5wdXNoKGltcG9ydFBhdGgpXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgdHMuZm9yRWFjaENoaWxkKG5vZGUsIHZpc2l0KVxuICB9XG5cbiAgdmlzaXQoc291cmNlRmlsZSlcblxuICBsZXQgcHJvamVjdFJvb3QgPSBwYXRoLmRpcm5hbWUoc25pcHBldFBhdGgpXG4gIHdoaWxlIChwcm9qZWN0Um9vdCAhPT0gcGF0aC5wYXJzZShwcm9qZWN0Um9vdCkucm9vdCkge1xuICAgIGlmIChmcy5leGlzdHNTeW5jKHBhdGguam9pbihwcm9qZWN0Um9vdCwgXCJwYWNrYWdlLmpzb25cIikpKSB7XG4gICAgICBicmVha1xuICAgIH1cbiAgICBwcm9qZWN0Um9vdCA9IHBhdGguZGlybmFtZShwcm9qZWN0Um9vdClcbiAgfVxuXG4gIGZvciAoY29uc3QgaW1wb3J0UGF0aCBvZiBpbXBvcnRzKSB7XG4gICAgY29uc3QgW293bmVyLCBuYW1lXSA9IGltcG9ydFBhdGgucmVwbGFjZShcIkB0c2NpL1wiLCBcIlwiKS5zcGxpdChcIi5cIilcbiAgICB0cnkge1xuICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBmZXRjaChcbiAgICAgICAgYGh0dHBzOi8vcmVnaXN0cnktYXBpLnRzY2lyY3VpdC5jb20vc25pcHBldHMvZ2V0P293bmVyX25hbWU9JHtvd25lcn0mdW5zY29wZWRfbmFtZT0ke25hbWV9YCxcbiAgICAgIClcblxuICAgICAgaWYgKCFyZXNwb25zZS5vaykge1xuICAgICAgICBjb25zb2xlLndhcm4oYEZhaWxlZCB0byBmZXRjaCB0eXBlcyBmb3IgJHtpbXBvcnRQYXRofWApXG4gICAgICAgIGNvbnRpbnVlXG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGRhdGE6IFNuaXBwZXRBcGlSZXNwb25zZSA9IGF3YWl0IHJlc3BvbnNlLmpzb24oKVxuXG4gICAgICBpZiAoZGF0YS5zbmlwcGV0LmR0cykge1xuICAgICAgICBjb25zdCBwYWNrYWdlRGlyID0gcGF0aC5qb2luKFxuICAgICAgICAgIHByb2plY3RSb290LFxuICAgICAgICAgIFwibm9kZV9tb2R1bGVzXCIsXG4gICAgICAgICAgXCJAdHNjaVwiLFxuICAgICAgICAgIGAke293bmVyfS4ke25hbWV9YCxcbiAgICAgICAgKVxuICAgICAgICBmcy5ta2RpclN5bmMocGFja2FnZURpciwgeyByZWN1cnNpdmU6IHRydWUgfSlcblxuICAgICAgICBmcy53cml0ZUZpbGVTeW5jKHBhdGguam9pbihwYWNrYWdlRGlyLCBcImluZGV4LmQudHNcIiksIGRhdGEuc25pcHBldC5kdHMpXG4gICAgICB9XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGNvbnNvbGUud2FybihgRXJyb3IgZmV0Y2hpbmcgdHlwZXMgZm9yICR7aW1wb3J0UGF0aH06YCwgZXJyb3IpXG4gICAgfVxuICB9XG59XG4iLCAiaW1wb3J0IGt5IGZyb20gXCJreVwiXG5pbXBvcnQgdHlwZSB7IEZpbGVTZXJ2ZXJSb3V0ZXMgfSBmcm9tIFwibGliL2ZpbGUtc2VydmVyL0ZpbGVTZXJ2ZXJSb3V0ZXNcIlxuaW1wb3J0IHsgY3JlYXRlSHR0cFNlcnZlciB9IGZyb20gXCJsaWIvc2VydmVyL2NyZWF0ZUh0dHBTZXJ2ZXJcIlxuaW1wb3J0IHsgRXZlbnRzV2F0Y2hlciB9IGZyb20gXCJsaWIvc2VydmVyL0V2ZW50c1dhdGNoZXJcIlxuaW1wb3J0IHR5cGUgaHR0cCBmcm9tIFwibm9kZTpodHRwXCJcbmltcG9ydCB0eXBlIHsgVHlwZWRLeUluc3RhbmNlIH0gZnJvbSBcInR5cGVkLWt5XCJcbmltcG9ydCBwYXRoIGZyb20gXCJub2RlOnBhdGhcIlxuaW1wb3J0IGZzIGZyb20gXCJub2RlOmZzXCJcbmltcG9ydCB0eXBlIHsgRmlsZVVwZGF0ZWRFdmVudCB9IGZyb20gXCJsaWIvZmlsZS1zZXJ2ZXIvRmlsZVNlcnZlckV2ZW50XCJcbmltcG9ydCAqIGFzIGNob2tpZGFyIGZyb20gXCJjaG9raWRhclwiXG5cbmV4cG9ydCBjbGFzcyBEZXZTZXJ2ZXIge1xuICBwb3J0OiBudW1iZXJcbiAgLyoqXG4gICAqIFRoZSBwYXRoIHRvIGEgY29tcG9uZW50IHRoYXQgZXhwb3J0cyBhIDxib2FyZCAvPiBvciA8Z3JvdXAgLz4gY29tcG9uZW50XG4gICAqL1xuICBjb21wb25lbnRGaWxlUGF0aDogc3RyaW5nXG5cbiAgcHJvamVjdERpcjogc3RyaW5nXG5cbiAgLyoqXG4gICAqIFRoZSBIVFRQIHNlcnZlciB0aGF0IGhvc3RzIHRoZSBmaWxlIHNlcnZlciBhbmQgZXZlbnQgYnVzLiBZb3UgY2FuIHVzZVxuICAgKiBmc0t5IHRvIGNvbW11bmljYXRlIHdpdGggdGhlIGZpbGUgc2VydmVyL2V2ZW50IGJ1c1xuICAgKi9cbiAgaHR0cFNlcnZlcj86IGh0dHAuU2VydmVyXG4gIC8qKlxuICAgKiBXYXRjaGVzIGZvciBldmVudHMgb24gdGhlIGV2ZW50IGJ1cyBieSBwb2xsaW5nIGBhcGkvZXZlbnRzL2xpc3RgXG4gICAqL1xuICBldmVudHNXYXRjaGVyPzogRXZlbnRzV2F0Y2hlclxuICAvKipcbiAgICogQSBreSBpbnN0YW5jZSB0aGF0IGNhbiBiZSB1c2VkIHRvIGNvbW11bmljYXRlIHdpdGggdGhlIGZpbGUgc2VydmVyIGFuZFxuICAgKiBldmVudCBidXNcbiAgICovXG4gIGZzS3k6IFR5cGVkS3lJbnN0YW5jZTxrZXlvZiBGaWxlU2VydmVyUm91dGVzLCBGaWxlU2VydmVyUm91dGVzPlxuICAvKipcbiAgICogQSBjaG9raWRhciBpbnN0YW5jZSB0aGF0IHdhdGNoZXMgdGhlIHByb2plY3QgZGlyZWN0b3J5IGZvciBmaWxlIGNoYW5nZXNcbiAgICovXG4gIGZpbGVzeXN0ZW1XYXRjaGVyPzogY2hva2lkYXIuRlNXYXRjaGVyXG5cbiAgY29uc3RydWN0b3Ioe1xuICAgIHBvcnQsXG4gICAgY29tcG9uZW50RmlsZVBhdGgsXG4gIH06IHtcbiAgICBwb3J0OiBudW1iZXJcbiAgICBjb21wb25lbnRGaWxlUGF0aDogc3RyaW5nXG4gIH0pIHtcbiAgICB0aGlzLnBvcnQgPSBwb3J0XG4gICAgdGhpcy5jb21wb25lbnRGaWxlUGF0aCA9IGNvbXBvbmVudEZpbGVQYXRoXG4gICAgdGhpcy5wcm9qZWN0RGlyID0gcGF0aC5kaXJuYW1lKGNvbXBvbmVudEZpbGVQYXRoKVxuICAgIHRoaXMuZnNLeSA9IGt5LmNyZWF0ZSh7XG4gICAgICBwcmVmaXhVcmw6IGBodHRwOi8vbG9jYWxob3N0OiR7cG9ydH1gLFxuICAgIH0pIGFzIGFueVxuICB9XG5cbiAgYXN5bmMgc3RhcnQoKSB7XG4gICAgY29uc3QgeyBzZXJ2ZXIgfSA9IGF3YWl0IGNyZWF0ZUh0dHBTZXJ2ZXIodGhpcy5wb3J0KVxuICAgIHRoaXMuaHR0cFNlcnZlciA9IHNlcnZlclxuXG4gICAgdGhpcy5ldmVudHNXYXRjaGVyID0gbmV3IEV2ZW50c1dhdGNoZXIoYGh0dHA6Ly9sb2NhbGhvc3Q6JHt0aGlzLnBvcnR9YClcbiAgICB0aGlzLmV2ZW50c1dhdGNoZXIuc3RhcnQoKVxuXG4gICAgdGhpcy5ldmVudHNXYXRjaGVyLm9uKFxuICAgICAgXCJGSUxFX1VQREFURURcIixcbiAgICAgIHRoaXMuaGFuZGxlRmlsZVVwZGF0ZWRFdmVudEZyb21TZXJ2ZXIuYmluZCh0aGlzKSxcbiAgICApXG5cbiAgICB0aGlzLmZpbGVzeXN0ZW1XYXRjaGVyID0gY2hva2lkYXIud2F0Y2godGhpcy5wcm9qZWN0RGlyLCB7XG4gICAgICBwZXJzaXN0ZW50OiB0cnVlLFxuICAgICAgaWdub3JlSW5pdGlhbDogdHJ1ZSxcbiAgICB9KVxuXG4gICAgdGhpcy5maWxlc3lzdGVtV2F0Y2hlci5vbihcImNoYW5nZVwiLCAoZmlsZVBhdGgpID0+XG4gICAgICB0aGlzLmhhbmRsZUZpbGVDaGFuZ2VkT25GaWxlc3lzdGVtKGZpbGVQYXRoKSxcbiAgICApXG4gICAgdGhpcy5maWxlc3lzdGVtV2F0Y2hlci5vbihcImFkZFwiLCAoZmlsZVBhdGgpID0+XG4gICAgICB0aGlzLmhhbmRsZUZpbGVDaGFuZ2VkT25GaWxlc3lzdGVtKGZpbGVQYXRoKSxcbiAgICApXG5cbiAgICB0aGlzLnVwc2VydEluaXRpYWxGaWxlcygpXG4gIH1cblxuICBhc3luYyBhZGRFbnRyeXBvaW50KCkge1xuICAgIGNvbnN0IHJlbGF0aXZlQ29tcG9uZW50RmlsZVBhdGggPSBwYXRoLnJlbGF0aXZlKFxuICAgICAgdGhpcy5wcm9qZWN0RGlyLFxuICAgICAgdGhpcy5jb21wb25lbnRGaWxlUGF0aCxcbiAgICApXG4gICAgYXdhaXQgdGhpcy5mc0t5LnBvc3QoXCJhcGkvZmlsZXMvdXBzZXJ0XCIsIHtcbiAgICAgIGpzb246IHtcbiAgICAgICAgZmlsZV9wYXRoOiBcImVudHJ5cG9pbnQudHN4XCIsXG4gICAgICAgIHRleHRfY29udGVudDogYFxuaW1wb3J0IE15Q2lyY3VpdCBmcm9tIFwiLi8ke3JlbGF0aXZlQ29tcG9uZW50RmlsZVBhdGh9XCJcblxuY2lyY3VpdC5hZGQoPE15Q2lyY3VpdCAvPilcbmAsXG4gICAgICB9LFxuICAgIH0pXG4gIH1cblxuICBhc3luYyBoYW5kbGVGaWxlVXBkYXRlZEV2ZW50RnJvbVNlcnZlcihldjogRmlsZVVwZGF0ZWRFdmVudCkge1xuICAgIGlmIChldi5pbml0aWF0b3IgPT09IFwiZmlsZXN5c3RlbV9jaGFuZ2VcIikgcmV0dXJuXG5cbiAgICBpZiAoZXYuZmlsZV9wYXRoID09PSBcIm1hbnVhbC1lZGl0cy5qc29uXCIpIHtcbiAgICAgIGNvbnNvbGUubG9nKFwiTWFudWFsIGVkaXRzIHVwZGF0ZWQsIHVwZGF0aW5nIG9uIGZpbGVzeXN0ZW0uLi5cIilcbiAgICAgIGNvbnN0IHsgZmlsZSB9ID0gYXdhaXQgdGhpcy5mc0t5XG4gICAgICAgIC5nZXQoXCJhcGkvZmlsZXMvZ2V0XCIsIHtcbiAgICAgICAgICBzZWFyY2hQYXJhbXM6IHsgZmlsZV9wYXRoOiBldi5maWxlX3BhdGggfSxcbiAgICAgICAgfSlcbiAgICAgICAgLmpzb24oKVxuICAgICAgZnMud3JpdGVGaWxlU3luYyhcbiAgICAgICAgcGF0aC5qb2luKHRoaXMucHJvamVjdERpciwgXCJtYW51YWwtZWRpdHMuanNvblwiKSxcbiAgICAgICAgZmlsZS50ZXh0X2NvbnRlbnQsXG4gICAgICApXG4gICAgfVxuICB9XG5cbiAgYXN5bmMgaGFuZGxlRmlsZUNoYW5nZWRPbkZpbGVzeXN0ZW0oYWJzb2x1dGVGaWxlUGF0aDogc3RyaW5nKSB7XG4gICAgY29uc3QgcmVsYXRpdmVGaWxlUGF0aCA9IHBhdGgucmVsYXRpdmUodGhpcy5wcm9qZWN0RGlyLCBhYnNvbHV0ZUZpbGVQYXRoKVxuICAgIC8vIFdlJ3ZlIHRlbXBvcmFyaWx5IGRpc2FibGVkIHVwc2VydGluZyBtYW51YWwgZWRpdHMgZnJvbSBmaWxlc3lzdGVtIGNoYW5nZXNcbiAgICAvLyBiZWNhdXNlIGl0IGNhbiBiZSBlZGl0ZWQgYnkgdGhlIGJyb3dzZXJcbiAgICBpZiAocmVsYXRpdmVGaWxlUGF0aC5pbmNsdWRlcyhcIm1hbnVhbC1lZGl0cy5qc29uXCIpKSByZXR1cm5cblxuICAgIGNvbnNvbGUubG9nKGAke3JlbGF0aXZlRmlsZVBhdGh9IHNhdmVkLiBBcHBseWluZyBjaGFuZ2VzLi4uYClcbiAgICBhd2FpdCB0aGlzLmZzS3lcbiAgICAgIC5wb3N0KFwiYXBpL2ZpbGVzL3Vwc2VydFwiLCB7XG4gICAgICAgIGpzb246IHtcbiAgICAgICAgICBmaWxlX3BhdGg6IHJlbGF0aXZlRmlsZVBhdGgsXG4gICAgICAgICAgdGV4dF9jb250ZW50OiBmcy5yZWFkRmlsZVN5bmMoYWJzb2x1dGVGaWxlUGF0aCwgXCJ1dGYtOFwiKSxcbiAgICAgICAgICBpbml0aWF0b3I6IFwiZmlsZXN5c3RlbV9jaGFuZ2VcIixcbiAgICAgICAgfSxcbiAgICAgIH0pXG4gICAgICAuanNvbigpXG4gIH1cblxuICBhc3luYyB1cHNlcnRJbml0aWFsRmlsZXMoKSB7XG4gICAgLy8gU2NhbiBwcm9qZWN0IGRpcmVjdG9yeSBmb3IgYWxsIGZpbGVzIGFuZCB1cHNlcnQgdGhlbVxuICAgIGNvbnN0IGZpbGVOYW1lcyA9IGZzLnJlYWRkaXJTeW5jKHRoaXMucHJvamVjdERpcilcbiAgICBmb3IgKGNvbnN0IGZpbGVOYW1lIG9mIGZpbGVOYW1lcykge1xuICAgICAgaWYgKGZzLnN0YXRTeW5jKHBhdGguam9pbih0aGlzLnByb2plY3REaXIsIGZpbGVOYW1lKSkuaXNEaXJlY3RvcnkoKSlcbiAgICAgICAgY29udGludWVcbiAgICAgIGNvbnN0IGZpbGVDb250ZW50ID0gZnMucmVhZEZpbGVTeW5jKFxuICAgICAgICBwYXRoLmpvaW4odGhpcy5wcm9qZWN0RGlyLCBmaWxlTmFtZSksXG4gICAgICAgIFwidXRmLThcIixcbiAgICAgIClcbiAgICAgIGF3YWl0IHRoaXMuZnNLeS5wb3N0KFwiYXBpL2ZpbGVzL3Vwc2VydFwiLCB7XG4gICAgICAgIGpzb246IHtcbiAgICAgICAgICBmaWxlX3BhdGg6IGZpbGVOYW1lLFxuICAgICAgICAgIHRleHRfY29udGVudDogZmlsZUNvbnRlbnQsXG4gICAgICAgICAgaW5pdGlhdG9yOiBcImZpbGVzeXN0ZW1fY2hhbmdlXCIsXG4gICAgICAgIH0sXG4gICAgICB9KVxuICAgIH1cbiAgfVxuXG4gIGFzeW5jIHN0b3AoKSB7XG4gICAgdGhpcy5odHRwU2VydmVyPy5jbG9zZSgpXG4gICAgdGhpcy5ldmVudHNXYXRjaGVyPy5zdG9wKClcbiAgfVxufVxuIiwgImltcG9ydCAqIGFzIGh0dHAgZnJvbSBcIm5vZGU6aHR0cFwiXG5pbXBvcnQgKiBhcyBmcyBmcm9tIFwibm9kZTpmc1wiXG5pbXBvcnQgKiBhcyBwYXRoIGZyb20gXCJub2RlOnBhdGhcIlxuaW1wb3J0IHsgZ2V0Tm9kZUhhbmRsZXIgfSBmcm9tIFwid2ludGVyc3BlYy9hZGFwdGVycy9ub2RlXCJcbmltcG9ydCBwa2cgZnJvbSBcIi4uLy4uL3BhY2thZ2UuanNvblwiXG5cbi8vIEB0cy1pZ25vcmVcbmltcG9ydCB3aW50ZXJzcGVjQnVuZGxlIGZyb20gXCJAdHNjaXJjdWl0L2ZpbGUtc2VydmVyL2Rpc3QvYnVuZGxlLmpzXCJcbmltcG9ydCB7IGdldEluZGV4IH0gZnJvbSBcIi4uL3NpdGUvZ2V0SW5kZXhcIlxuXG5leHBvcnQgY29uc3QgY3JlYXRlSHR0cFNlcnZlciA9IGFzeW5jIChwb3J0ID0gMzAwMCkgPT4ge1xuICBjb25zdCBmaWxlU2VydmVySGFuZGxlciA9IGdldE5vZGVIYW5kbGVyKHdpbnRlcnNwZWNCdW5kbGUgYXMgYW55LCB7fSlcblxuICBjb25zdCBzZXJ2ZXIgPSBodHRwLmNyZWF0ZVNlcnZlcihhc3luYyAocmVxLCByZXMpID0+IHtcbiAgICBjb25zdCB1cmwgPSBuZXcgVVJMKHJlcS51cmwhLCBgaHR0cDovLyR7cmVxLmhlYWRlcnMuaG9zdH1gKVxuXG4gICAgaWYgKHVybC5wYXRobmFtZSA9PT0gXCIvc3RhbmRhbG9uZS5taW4uanNcIikge1xuICAgICAgY29uc3Qgc3RhbmRhbG9uZUZpbGVQYXRoID1cbiAgICAgICAgcHJvY2Vzcy5lbnYuUlVORlJBTUVfU1RBTkRBTE9ORV9GSUxFX1BBVEggfHxcbiAgICAgICAgcGF0aC5yZXNvbHZlKFxuICAgICAgICAgIHByb2Nlc3MuY3dkKCksXG4gICAgICAgICAgXCJub2RlX21vZHVsZXNcIixcbiAgICAgICAgICBcIkB0c2NpcmN1aXQvcnVuZnJhbWUvZGlzdC9zdGFuZGFsb25lLm1pbi5qc1wiLFxuICAgICAgICApXG5cbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IGNvbnRlbnQgPSBmcy5yZWFkRmlsZVN5bmMoc3RhbmRhbG9uZUZpbGVQYXRoLCBcInV0ZjhcIilcbiAgICAgICAgcmVzLndyaXRlSGVhZCgyMDAsIHtcbiAgICAgICAgICBcIkNvbnRlbnQtVHlwZVwiOiBcImFwcGxpY2F0aW9uL2phdmFzY3JpcHQ7IGNoYXJzZXQ9dXRmLThcIixcbiAgICAgICAgfSlcbiAgICAgICAgcmVzLmVuZChjb250ZW50KVxuICAgICAgICByZXR1cm5cbiAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgIGNvbnNvbGUuZXJyb3IoXCJFcnJvciBzZXJ2aW5nIHN0YW5kYWxvbmUubWluLmpzOlwiLCBlcnJvcilcbiAgICAgIH1cblxuICAgICAgcmVzLndyaXRlSGVhZCgzMDIsIHtcbiAgICAgICAgTG9jYXRpb246IGBodHRwczovL2Nkbi5qc2RlbGl2ci5uZXQvbnBtL0B0c2NpcmN1aXQvcnVuZnJhbWVAJHtwa2cuZGVwZW5kZW5jaWVzW1wiQHRzY2lyY3VpdC9ydW5mcmFtZVwiXS5yZXBsYWNlKC9eW14wLTldKy8sIFwiXCIpfS9kaXN0L3N0YW5kYWxvbmUubWluLmpzYCxcbiAgICAgIH0pXG4gICAgICByZXMuZW5kKClcbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIGlmICh1cmwucGF0aG5hbWUgPT09IFwiL1wiKSB7XG4gICAgICBjb25zdCBodG1sID0gYXdhaXQgZ2V0SW5kZXgoKVxuICAgICAgcmVzLndyaXRlSGVhZCgyMDAsIHsgXCJDb250ZW50LVR5cGVcIjogXCJ0ZXh0L2h0bWxcIiB9KVxuICAgICAgcmVzLmVuZChodG1sKVxuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgaWYgKHVybC5wYXRobmFtZS5zdGFydHNXaXRoKFwiL2FwaS9cIikpIHtcbiAgICAgIHJlcS51cmwgPSByZXEudXJsIS5yZXBsYWNlKFwiL2FwaS9cIiwgXCIvXCIpXG4gICAgICBmaWxlU2VydmVySGFuZGxlcihyZXEsIHJlcylcbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIHJlcy53cml0ZUhlYWQoNDA0KVxuICAgIHJlcy5lbmQoXCJOb3QgZm91bmRcIilcbiAgfSlcblxuICByZXR1cm4gbmV3IFByb21pc2U8eyBzZXJ2ZXI6IGh0dHAuU2VydmVyIH0+KChyZXNvbHZlKSA9PiB7XG4gICAgc2VydmVyLmxpc3Rlbihwb3J0LCAoKSA9PiB7XG4gICAgICBjb25zb2xlLmxvZyhgU2VydmVyIHJ1bm5pbmcgYXQgaHR0cDovL2xvY2FsaG9zdDoke3BvcnR9YClcbiAgICAgIHJlc29sdmUoeyBzZXJ2ZXIgfSlcbiAgICB9KVxuICB9KVxufVxuIiwgIntcbiAgXCJuYW1lXCI6IFwiQHRzY2lyY3VpdC9jbGlcIixcbiAgXCJtYWluXCI6IFwiZGlzdC9tYWluLmpzXCIsXG4gIFwidHlwZVwiOiBcIm1vZHVsZVwiLFxuICBcInZlcnNpb25cIjogXCIwLjEuMTVcIixcbiAgXCJiaW5cIjoge1xuICAgIFwidHNjaVwiOiBcIi4vZGlzdC9tYWluLmpzXCJcbiAgfSxcbiAgXCJzY3JpcHRzXCI6IHtcbiAgICBcInN0YXJ0XCI6IFwiYnVuIHJ1biBkZXZcIixcbiAgICBcImRldlwiOiBcImJ1biAtLWhvdCAuL2NsaS9tYWluLnRzIGRldiAuL2V4YW1wbGUtZGlyL3NuaXBwZXQxLWJhc2ljLnRzeFwiLFxuICAgIFwiYnVpbGRcIjogXCJ0c3VwLW5vZGUgY2xpL21haW4udHMgLS1mb3JtYXQgZXNtIC0tc291cmNlbWFwIGlubGluZVwiLFxuICAgIFwiZm9ybWF0XCI6IFwiYmlvbWUgZm9ybWF0IC0td3JpdGUgLlwiLFxuICAgIFwiZm9ybWF0OmNoZWNrXCI6IFwiYmlvbWUgZm9ybWF0IC5cIixcbiAgICBcImNsaVwiOiBcImJ1biAuL2NsaS9tYWluLnRzXCJcbiAgfSxcbiAgXCJkZXZEZXBlbmRlbmNpZXNcIjoge1xuICAgIFwiQGJpb21lanMvYmlvbWVcIjogXCJeMS45LjRcIixcbiAgICBcIkB0c2NpcmN1aXQvY29yZVwiOiBcIl4wLjAuMjQ5XCIsXG4gICAgXCJAdHlwZXMvYnVuXCI6IFwiXjEuMS4xNVwiLFxuICAgIFwiQHR5cGVzL2NvbmZpZ3N0b3JlXCI6IFwiXjYuMC4yXCIsXG4gICAgXCJAdHlwZXMvcmVhY3RcIjogXCJeMTkuMC4xXCIsXG4gICAgXCJAdHlwZXMvc2VtdmVyXCI6IFwiXjcuNS44XCIsXG4gICAgXCJnZXQtcG9ydFwiOiBcIl43LjEuMFwiLFxuICAgIFwidGVtcHlcIjogXCJeMy4xLjBcIixcbiAgICBcInRzdXBcIjogXCJeOC4zLjVcIixcbiAgICBcInR5cGVkLWt5XCI6IFwiXjAuMC40XCJcbiAgfSxcbiAgXCJwZWVyRGVwZW5kZW5jaWVzXCI6IHtcbiAgICBcInR5cGVzY3JpcHRcIjogXCJeNS4wLjBcIlxuICB9LFxuICBcImRlcGVuZGVuY2llc1wiOiB7XG4gICAgXCJAdHNjaXJjdWl0L2ZpbGUtc2VydmVyXCI6IFwiXjAuMC4xM1wiLFxuICAgIFwiQHRzY2lyY3VpdC9ydW5mcmFtZVwiOiBcIl4wLjAuNDdcIixcbiAgICBcImNob2tpZGFyXCI6IFwiXjQuMC4xXCIsXG4gICAgXCJjb21tYW5kZXJcIjogXCJeMTIuMS4wXCIsXG4gICAgXCJjb25maWdzdG9yZVwiOiBcIl43LjAuMFwiLFxuICAgIFwiY29zbWljb25maWdcIjogXCJeOS4wLjBcIixcbiAgICBcImRlbGF5XCI6IFwiXjYuMC4wXCIsXG4gICAgXCJreVwiOiBcIl4xLjcuNFwiLFxuICAgIFwibWFrZS12ZnNcIjogXCJeMS4wLjE1XCIsXG4gICAgXCJwZXJmZWN0LWNsaVwiOiBcIl4xLjAuMjBcIixcbiAgICBcInNlbXZlclwiOiBcIl43LjYuM1wiXG4gIH1cbn1cbiIsICJpbXBvcnQgcGtnIGZyb20gXCIuLi8uLi9wYWNrYWdlLmpzb25cIlxuXG5leHBvcnQgY29uc3QgZ2V0SW5kZXggPSBhc3luYyAoKSA9PiB7XG4gIHJldHVybiBgPGh0bWw+XG4gICAgPGhlYWQ+XG4gICAgPC9oZWFkPlxuICAgIDxib2R5PlxuICAgICAgPHNjcmlwdCBzcmM9XCJodHRwczovL2Nkbi50YWlsd2luZGNzcy5jb21cIj48L3NjcmlwdD5cbiAgICAgIDxkaXYgaWQ9XCJyb290XCI+bG9hZGluZy4uLjwvZGl2PlxuICAgICAgPHNjcmlwdD5cbiAgICAgIGdsb2JhbFRoaXMucHJvY2VzcyA9IHsgZW52OiB7IE5PREVfRU5WOiBcInByb2R1Y3Rpb25cIiB9IH1cbiAgICAgIDwvc2NyaXB0PlxuICAgICAgPHNjcmlwdCBzcmM9XCIvc3RhbmRhbG9uZS5taW4uanNcIj48L3NjcmlwdD5cbiAgICA8L2JvZHk+XG4gIDwvaHRtbD5gXG59XG5cbi8vIDxzY3JpcHQgc3JjPVwiaHR0cHM6Ly9jZG4uanNkZWxpdnIubmV0L25wbS9AdHNjaXJjdWl0L3J1bmZyYW1lQCR7cGtnLmRlcGVuZGVuY2llc1tcIkB0c2NpcmN1aXQvcnVuZnJhbWVcIl0ucmVwbGFjZSgvXlteMC05XSsvLCBcIlwiKX0vZGlzdC9zdGFuZGFsb25lLm1pbi5qc1wiPjwvc2NyaXB0PlxuIiwgImltcG9ydCB7IEV2ZW50RW1pdHRlciB9IGZyb20gXCJldmVudHNcIlxuXG5pbnRlcmZhY2UgRXZlbnQge1xuICBldmVudF9pZDogc3RyaW5nXG4gIGNyZWF0ZWRfYXQ6IHN0cmluZ1xuICBldmVudF90eXBlOiBzdHJpbmdcbiAgW2tleTogc3RyaW5nXTogYW55XG59XG5cbmludGVyZmFjZSBFdmVudHNSZXNwb25zZSB7XG4gIGV2ZW50X2xpc3Q6IEV2ZW50W11cbn1cblxuZXhwb3J0IGNsYXNzIEV2ZW50c1dhdGNoZXIgZXh0ZW5kcyBFdmVudEVtaXR0ZXIge1xuICBwcml2YXRlIGxhc3RQb2xsVGltZTogc3RyaW5nXG4gIHByaXZhdGUgcG9sbEludGVydmFsOiBudW1iZXJcbiAgcHJpdmF0ZSBiYXNlVXJsOiBzdHJpbmdcbiAgcHJpdmF0ZSBwb2xsaW5nID0gZmFsc2VcbiAgcHJpdmF0ZSB0aW1lb3V0SWQ/OiBOb2RlSlMuVGltZW91dFxuXG4gIGNvbnN0cnVjdG9yKGJhc2VVcmwgPSBcImh0dHA6Ly9sb2NhbGhvc3Q6MzAwMFwiLCBwb2xsSW50ZXJ2YWwgPSAxMDAwKSB7XG4gICAgc3VwZXIoKVxuICAgIHRoaXMuYmFzZVVybCA9IGJhc2VVcmxcbiAgICB0aGlzLnBvbGxJbnRlcnZhbCA9IHBvbGxJbnRlcnZhbFxuICAgIHRoaXMubGFzdFBvbGxUaW1lID0gbmV3IERhdGUoKS50b0lTT1N0cmluZygpXG4gIH1cblxuICBhc3luYyBzdGFydCgpIHtcbiAgICBpZiAodGhpcy5wb2xsaW5nKSByZXR1cm5cbiAgICB0aGlzLnBvbGxpbmcgPSB0cnVlXG4gICAgYXdhaXQgdGhpcy5wb2xsKClcbiAgfVxuXG4gIHN0b3AoKSB7XG4gICAgdGhpcy5wb2xsaW5nID0gZmFsc2VcbiAgICBpZiAodGhpcy50aW1lb3V0SWQpIHtcbiAgICAgIGNsZWFyVGltZW91dCh0aGlzLnRpbWVvdXRJZClcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIHBvbGwoKSB7XG4gICAgaWYgKCF0aGlzLnBvbGxpbmcpIHJldHVyblxuXG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgZmV0Y2goXG4gICAgICAgIGAke3RoaXMuYmFzZVVybH0vYXBpL2V2ZW50cy9saXN0P3NpbmNlPSR7ZW5jb2RlVVJJQ29tcG9uZW50KHRoaXMubGFzdFBvbGxUaW1lKX1gLFxuICAgICAgKVxuXG4gICAgICBpZiAoIXJlc3BvbnNlLm9rKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgSFRUUCBlcnJvciEgc3RhdHVzOiAke3Jlc3BvbnNlLnN0YXR1c31gKVxuICAgICAgfVxuXG4gICAgICBjb25zdCBkYXRhOiBFdmVudHNSZXNwb25zZSA9IGF3YWl0IHJlc3BvbnNlLmpzb24oKVxuXG4gICAgICAvLyBVcGRhdGUgbGFzdCBwb2xsIHRpbWUgdG8gbGF0ZXN0IGV2ZW50IG9yIGN1cnJlbnQgdGltZVxuICAgICAgY29uc3QgbGF0ZXN0RXZlbnQgPSBkYXRhLmV2ZW50X2xpc3RbZGF0YS5ldmVudF9saXN0Lmxlbmd0aCAtIDFdXG4gICAgICB0aGlzLmxhc3RQb2xsVGltZSA9IGxhdGVzdEV2ZW50XG4gICAgICAgID8gbGF0ZXN0RXZlbnQuY3JlYXRlZF9hdFxuICAgICAgICA6IG5ldyBEYXRlKCkudG9JU09TdHJpbmcoKVxuXG4gICAgICAvLyBFbWl0IGV2ZW50cyBpbiBjaHJvbm9sb2dpY2FsIG9yZGVyXG4gICAgICBkYXRhLmV2ZW50X2xpc3QuZm9yRWFjaCgoZXZlbnQpID0+IHtcbiAgICAgICAgdGhpcy5lbWl0KGV2ZW50LmV2ZW50X3R5cGUsIGV2ZW50KVxuICAgICAgICB0aGlzLmVtaXQoXCIqXCIsIGV2ZW50KVxuICAgICAgfSlcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgdGhpcy5lbWl0KFwiZXJyb3JcIiwgZXJyb3IpXG4gICAgfVxuICAgIC8vIFNjaGVkdWxlIG5leHQgcG9sbFxuICAgIHRoaXMudGltZW91dElkID0gZ2xvYmFsVGhpcy5zZXRUaW1lb3V0KFxuICAgICAgKCkgPT4gdGhpcy5wb2xsKCksXG4gICAgICB0aGlzLnBvbGxJbnRlcnZhbCxcbiAgICApIGFzIHVua25vd24gYXMgTm9kZUpTLlRpbWVvdXRcbiAgfVxufVxuIiwgImltcG9ydCBDb25maWdzdG9yZSBmcm9tIFwiY29uZmlnc3RvcmVcIlxuaW1wb3J0IHR5cGUgeyBUeXBlZENvbmZpZ3N0b3JlIH0gZnJvbSBcIi4vVHlwZWRDb25maWdTdG9yZVwiXG5cbmV4cG9ydCBpbnRlcmZhY2UgQ2xpQ29uZmlnIHtcbiAgc2Vzc2lvblRva2VuPzogc3RyaW5nXG4gIGdpdGh1YlVzZXJuYW1lPzogc3RyaW5nXG4gIHJlZ2lzdHJ5QXBpVXJsPzogc3RyaW5nXG59XG5cbmV4cG9ydCBjb25zdCBjbGlDb25maWc6IFR5cGVkQ29uZmlnc3RvcmU8Q2xpQ29uZmlnPiA9IG5ldyBDb25maWdzdG9yZShcbiAgXCJ0c2NpcmN1aXRcIixcbilcblxuZXhwb3J0IGNvbnN0IGdldFJlZ2lzdHJ5QXBpVXJsID0gKCk6IHN0cmluZyA9PiB7XG4gIHJldHVybiBjbGlDb25maWcuZ2V0KFwicmVnaXN0cnlBcGlVcmxcIikgPz8gXCJodHRwczovL3JlZ2lzdHJ5LWFwaS50c2NpcmN1aXQuY29tXCJcbn1cbiIsICJpbXBvcnQgdHlwZSB7IENvbW1hbmQgfSBmcm9tIFwiY29tbWFuZGVyXCJcbmltcG9ydCB7IGNsaUNvbmZpZyB9IGZyb20gXCJsaWIvY2xpLWNvbmZpZ1wiXG5pbXBvcnQgZGVsYXkgZnJvbSBcImRlbGF5XCJcbmltcG9ydCB7IGdldEt5IH0gZnJvbSBcImxpYi9yZWdpc3RyeS1hcGkvZ2V0LWt5XCJcbmltcG9ydCB0eXBlIHsgRW5kcG9pbnRSZXNwb25zZSB9IGZyb20gXCJsaWIvcmVnaXN0cnktYXBpL2VuZHBvaW50LXR5cGVzXCJcblxuZXhwb3J0IGNvbnN0IHJlZ2lzdGVyQXV0aExvZ2luID0gKHByb2dyYW06IENvbW1hbmQpID0+IHtcbiAgLy8gRGVmaW5lIHRoZSBsb2dpbiBhY3Rpb24gb25jZSB0byBzaGFyZSBiZXR3ZWVuIGJvdGggY29tbWFuZHNcbiAgY29uc3QgbG9naW5BY3Rpb24gPSBhc3luYyAoKSA9PiB7XG4gICAgY29uc3Qga3kgPSBnZXRLeSgpXG5cbiAgICBjb25zdCB7IGxvZ2luX3BhZ2UgfSA9IGF3YWl0IGt5XG4gICAgICAucG9zdDxFbmRwb2ludFJlc3BvbnNlW1wic2Vzc2lvbnMvbG9naW5fcGFnZS9jcmVhdGVcIl0+KFxuICAgICAgICBcInNlc3Npb25zL2xvZ2luX3BhZ2UvY3JlYXRlXCIsXG4gICAgICAgIHtcbiAgICAgICAgICBqc29uOiB7fSxcbiAgICAgICAgfSxcbiAgICAgIClcbiAgICAgIC5qc29uKClcblxuICAgIGNvbnNvbGUubG9nKFwiUGxlYXNlIHZpc2l0IHRoZSBmb2xsb3dpbmcgVVJMIHRvIGxvZyBpbjpcIilcbiAgICBjb25zb2xlLmxvZyhsb2dpbl9wYWdlLnVybClcblxuICAgIC8vIFdhaXQgdW50aWwgd2UgcmVjZWl2ZSBjb25maXJtYXRpb25cbiAgICB3aGlsZSAodHJ1ZSkge1xuICAgICAgY29uc3QgeyBsb2dpbl9wYWdlOiBuZXdfbG9naW5fcGFnZSB9ID0gYXdhaXQga3lcbiAgICAgICAgLnBvc3Q8RW5kcG9pbnRSZXNwb25zZVtcInNlc3Npb25zL2xvZ2luX3BhZ2UvZ2V0XCJdPihcbiAgICAgICAgICBcInNlc3Npb25zL2xvZ2luX3BhZ2UvZ2V0XCIsXG4gICAgICAgICAge1xuICAgICAgICAgICAganNvbjoge1xuICAgICAgICAgICAgICBsb2dpbl9wYWdlX2lkOiBsb2dpbl9wYWdlLmxvZ2luX3BhZ2VfaWQsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgaGVhZGVyczoge1xuICAgICAgICAgICAgICBBdXRob3JpemF0aW9uOiBgQmVhcmVyICR7bG9naW5fcGFnZS5sb2dpbl9wYWdlX2F1dGhfdG9rZW59YCxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSxcbiAgICAgICAgKVxuICAgICAgICAuanNvbigpXG5cbiAgICAgIGlmIChuZXdfbG9naW5fcGFnZS53YXNfbG9naW5fc3VjY2Vzc2Z1bCkge1xuICAgICAgICBjb25zb2xlLmxvZyhcIkxvZ2dlZCBpbiEgR2VuZXJhdGluZyB0b2tlbi4uLlwiKVxuICAgICAgICBicmVha1xuICAgICAgfVxuXG4gICAgICBpZiAobmV3X2xvZ2luX3BhZ2UuaXNfZXhwaXJlZCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJMb2dpbiBwYWdlIGV4cGlyZWRcIilcbiAgICAgIH1cblxuICAgICAgYXdhaXQgZGVsYXkoMTAwMClcbiAgICB9XG5cbiAgICBjb25zdCB7IHNlc3Npb24gfSA9IGF3YWl0IGt5XG4gICAgICAucG9zdDxFbmRwb2ludFJlc3BvbnNlW1wic2Vzc2lvbnMvbG9naW5fcGFnZS9leGNoYW5nZV9mb3JfY2xpX3Nlc3Npb25cIl0+KFxuICAgICAgICBcInNlc3Npb25zL2xvZ2luX3BhZ2UvZXhjaGFuZ2VfZm9yX2NsaV9zZXNzaW9uXCIsXG4gICAgICAgIHtcbiAgICAgICAgICBqc29uOiB7XG4gICAgICAgICAgICBsb2dpbl9wYWdlX2lkOiBsb2dpbl9wYWdlLmxvZ2luX3BhZ2VfaWQsXG4gICAgICAgICAgfSxcbiAgICAgICAgICBoZWFkZXJzOiB7XG4gICAgICAgICAgICBBdXRob3JpemF0aW9uOiBgQmVhcmVyICR7bG9naW5fcGFnZS5sb2dpbl9wYWdlX2F1dGhfdG9rZW59YCxcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgKVxuICAgICAgLmpzb24oKVxuXG4gICAgY2xpQ29uZmlnLnNldChcInNlc3Npb25Ub2tlblwiLCBzZXNzaW9uLnRva2VuKVxuXG4gICAgY29uc29sZS5sb2coXCJSZWFkeSB0byB1c2UhXCIpXG4gIH1cblxuICAvLyBSZWdpc3RlciB0aGUgYXV0aCBsb2dpbiBzdWJjb21tYW5kXG4gIHByb2dyYW0uY29tbWFuZHNcbiAgICAuZmluZCgoYykgPT4gYy5uYW1lKCkgPT09IFwiYXV0aFwiKSFcbiAgICAuY29tbWFuZChcImxvZ2luXCIpXG4gICAgLmRlc2NyaXB0aW9uKFwiQXV0aGVudGljYXRlIENMSSwgbG9naW4gdG8gcmVnaXN0cnlcIilcbiAgICAuYWN0aW9uKGxvZ2luQWN0aW9uKVxuXG4gIC8vIFJlZ2lzdGVyIHRoZSB0b3AtbGV2ZWwgbG9naW4gY29tbWFuZCBhcyBhbiBhbGlhc1xuICBwcm9ncmFtXG4gICAgLmNvbW1hbmQoXCJsb2dpblwiKVxuICAgIC5kZXNjcmlwdGlvbihcIkxvZ2luIHRvIHRzY2lyY3VpdCByZWdpc3RyeVwiKVxuICAgIC5hY3Rpb24obG9naW5BY3Rpb24pXG59XG4iLCAiaW1wb3J0IHsgZ2V0UmVnaXN0cnlBcGlVcmwgfSBmcm9tIFwibGliL2NsaS1jb25maWdcIlxuaW1wb3J0IGt5LCB7IHR5cGUgQWZ0ZXJSZXNwb25zZUhvb2sgfSBmcm9tIFwia3lcIlxuXG5jb25zdCBwcmV0dHlSZXNwb25zZUVycm9ySG9vazogQWZ0ZXJSZXNwb25zZUhvb2sgPSBhc3luYyAoXG4gIF9yZXF1ZXN0LFxuICBfb3B0aW9ucyxcbiAgcmVzcG9uc2UsXG4pID0+IHtcbiAgaWYgKCFyZXNwb25zZS5vaykge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCBlcnJvckRhdGEgPSBhd2FpdCByZXNwb25zZS5qc29uKClcbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgYEZBSUwgWyR7cmVzcG9uc2Uuc3RhdHVzfV06ICR7X3JlcXVlc3QubWV0aG9kfSAke1xuICAgICAgICAgIG5ldyBVUkwoX3JlcXVlc3QudXJsKS5wYXRobmFtZVxuICAgICAgICB9IFxcblxcbiAke0pTT04uc3RyaW5naWZ5KGVycm9yRGF0YSwgbnVsbCwgMil9YCxcbiAgICAgIClcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICAvL2lnbm9yZSwgYWxsb3cgdGhlIGVycm9yIHRvIGJlIHRocm93blxuICAgIH1cbiAgfVxufVxuXG5leHBvcnQgY29uc3QgZ2V0S3kgPSAoKSA9PiB7XG4gIHJldHVybiBreS5jcmVhdGUoe1xuICAgIHByZWZpeFVybDogZ2V0UmVnaXN0cnlBcGlVcmwoKSxcbiAgICBob29rczoge1xuICAgICAgYWZ0ZXJSZXNwb25zZTogW3ByZXR0eVJlc3BvbnNlRXJyb3JIb29rXSxcbiAgICB9LFxuICB9KVxufVxuIiwgImltcG9ydCB0eXBlIHsgQ29tbWFuZCB9IGZyb20gXCJjb21tYW5kZXJcIlxuXG5leHBvcnQgY29uc3QgcmVnaXN0ZXJBdXRoTG9nb3V0ID0gKHByb2dyYW06IENvbW1hbmQpID0+IHtcbiAgcHJvZ3JhbS5jb21tYW5kc1xuICAgIC5maW5kKChjKSA9PiBjLm5hbWUoKSA9PT0gXCJhdXRoXCIpIVxuICAgIC5jb21tYW5kKFwibG9nb3V0XCIpXG4gICAgLmRlc2NyaXB0aW9uKFwiTG9nb3V0IGZyb20gcmVnaXN0cnlcIilcbiAgICAuYWN0aW9uKChhcmdzKSA9PiB7XG4gICAgICBjb25zb2xlLmxvZyhcImxvZ291dFwiKVxuICAgIH0pXG59XG4iLCAiaW1wb3J0IHR5cGUgeyBDb21tYW5kIH0gZnJvbSBcImNvbW1hbmRlclwiXG5cbmV4cG9ydCBjb25zdCByZWdpc3RlckF1dGggPSAocHJvZ3JhbTogQ29tbWFuZCkgPT4ge1xuICBwcm9ncmFtLmNvbW1hbmQoXCJhdXRoXCIpLmRlc2NyaXB0aW9uKFwiTG9naW4vbG9nb3V0XCIpXG59XG4iLCAiaW1wb3J0IHR5cGUgeyBDb21tYW5kIH0gZnJvbSBcImNvbW1hbmRlclwiXG5cbmV4cG9ydCBjb25zdCByZWdpc3RlckNvbmZpZyA9IChwcm9ncmFtOiBDb21tYW5kKSA9PiB7XG4gIHByb2dyYW0uY29tbWFuZChcImNvbmZpZ1wiKS5kZXNjcmlwdGlvbihcIk1hbmFnZSB0c2NpcmN1aXQgQ0xJIGNvbmZpZ3VyYXRpb25cIilcbn1cbiIsICJpbXBvcnQgdHlwZSB7IENvbW1hbmQgfSBmcm9tIFwiY29tbWFuZGVyXCJcbmltcG9ydCB7IGNsaUNvbmZpZyB9IGZyb20gXCJsaWIvY2xpLWNvbmZpZ1wiXG5cbmV4cG9ydCBjb25zdCByZWdpc3RlckNvbmZpZ1ByaW50ID0gKHByb2dyYW06IENvbW1hbmQpID0+IHtcbiAgcHJvZ3JhbS5jb21tYW5kc1xuICAgIC5maW5kKChjKSA9PiBjLm5hbWUoKSA9PT0gXCJjb25maWdcIikhXG4gICAgLmNvbW1hbmQoXCJwcmludFwiKVxuICAgIC5kZXNjcmlwdGlvbihcIlByaW50IHRoZSBjdXJyZW50IGNvbmZpZ1wiKVxuICAgIC5hY3Rpb24oKCkgPT4ge1xuICAgICAgY29uc29sZS5sb2coSlNPTi5zdHJpbmdpZnkoY2xpQ29uZmlnLmFsbCwgbnVsbCwgMikpXG4gICAgfSlcbn1cbiIsICJpbXBvcnQgdHlwZSB7IENvbW1hbmQgfSBmcm9tIFwiY29tbWFuZGVyXCJcbmltcG9ydCB7IGdldEt5IH0gZnJvbSBcImxpYi9yZWdpc3RyeS1hcGkvZ2V0LWt5XCJcbmltcG9ydCAqIGFzIGZzIGZyb20gXCJub2RlOmZzXCJcbmltcG9ydCAqIGFzIHBhdGggZnJvbSBcIm5vZGU6cGF0aFwiXG5cbmV4cG9ydCBjb25zdCByZWdpc3RlckNsb25lID0gKHByb2dyYW06IENvbW1hbmQpID0+IHtcbiAgcHJvZ3JhbVxuICAgIC5jb21tYW5kKFwiY2xvbmVcIilcbiAgICAuZGVzY3JpcHRpb24oXCJDbG9uZSBhIHNuaXBwZXQgZnJvbSB0aGUgcmVnaXN0cnlcIilcbiAgICAuYXJndW1lbnQoXCI8c25pcHBldD5cIiwgXCJTbmlwcGV0IHRvIGNsb25lIChlLmcuIGF1dGhvci9zbmlwcGV0TmFtZSlcIilcbiAgICAuYWN0aW9uKGFzeW5jIChzbmlwcGV0UGF0aDogc3RyaW5nKSA9PiB7XG4gICAgICBsZXQgYXV0aG9yOiBzdHJpbmdcbiAgICAgIGxldCBzbmlwcGV0TmFtZTogc3RyaW5nXG4gICAgICBpZiAoIXNuaXBwZXRQYXRoLnN0YXJ0c1dpdGgoXCJAdHNjaS9cIikgJiYgc25pcHBldFBhdGguaW5jbHVkZXMoXCIvXCIpKSB7XG4gICAgICAgIDtbYXV0aG9yLCBzbmlwcGV0TmFtZV0gPSBzbmlwcGV0UGF0aC5zcGxpdChcIi9cIilcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbnN0IHRyaW1tZWRQYXRoID0gc25pcHBldFBhdGgucmVwbGFjZShcIkB0c2NpL1wiLCBcIlwiKVxuICAgICAgICBjb25zdCBmaXJzdERvdEluZGV4ID0gdHJpbW1lZFBhdGguaW5kZXhPZihcIi5cIilcbiAgICAgICAgYXV0aG9yID0gdHJpbW1lZFBhdGguc2xpY2UoMCwgZmlyc3REb3RJbmRleClcbiAgICAgICAgc25pcHBldE5hbWUgPSB0cmltbWVkUGF0aC5zbGljZShmaXJzdERvdEluZGV4ICsgMSlcbiAgICAgIH1cblxuICAgICAgaWYgKCFhdXRob3IgfHwgIXNuaXBwZXROYW1lKSB7XG4gICAgICAgIGNvbnNvbGUuZXJyb3IoXG4gICAgICAgICAgXCJJbnZhbGlkIHNuaXBwZXQgcGF0aC4gVXNlIGZvcm1hdDogYXV0aG9yL3NuaXBwZXROYW1lLCBhdXRob3Iuc25pcHBldE5hbWUgb3IgQHRzY2kvYXV0aG9yLnNuaXBwZXROYW1lXCIsXG4gICAgICAgIClcbiAgICAgICAgcHJvY2Vzcy5leGl0KDEpXG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGt5ID0gZ2V0S3koKVxuXG4gICAgICB0cnkge1xuICAgICAgICBjb25zb2xlLmxvZyhgQ2xvbmluZyAke2F1dGhvcn0vJHtzbmlwcGV0TmFtZX0uLi5gKVxuXG4gICAgICAgIGNvbnN0IHBhY2thZ2VGaWxlTGlzdCA9IGF3YWl0IGt5XG4gICAgICAgICAgLnBvc3Q8e1xuICAgICAgICAgICAgcGFja2FnZV9maWxlczogQXJyYXk8e1xuICAgICAgICAgICAgICBwYWNrYWdlX2ZpbGVfaWQ6IHN0cmluZ1xuICAgICAgICAgICAgICBwYWNrYWdlX3JlbGVhc2VfaWQ6IHN0cmluZ1xuICAgICAgICAgICAgICBmaWxlX3BhdGg6IHN0cmluZ1xuICAgICAgICAgICAgICBjcmVhdGVkX2F0OiBzdHJpbmdcbiAgICAgICAgICAgIH0+XG4gICAgICAgICAgfT4oXCJwYWNrYWdlX2ZpbGVzL2xpc3RcIiwge1xuICAgICAgICAgICAganNvbjoge1xuICAgICAgICAgICAgICBwYWNrYWdlX25hbWU6IGAke2F1dGhvcn0vJHtzbmlwcGV0TmFtZX1gLFxuICAgICAgICAgICAgICB1c2VfbGF0ZXN0X3ZlcnNpb246IHRydWUsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0pXG4gICAgICAgICAgLmpzb24oKVxuXG4gICAgICAgIC8vIENyZWF0ZSBkaXJlY3RvcnkgaWYgaXQgZG9lc24ndCBleGlzdFxuICAgICAgICBjb25zdCBkaXJQYXRoID0gYC4vJHthdXRob3J9LiR7c25pcHBldE5hbWV9YFxuICAgICAgICBpZiAoIWZzLmV4aXN0c1N5bmMoZGlyUGF0aCkpIHtcbiAgICAgICAgICBmcy5ta2RpclN5bmMoZGlyUGF0aClcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIERvd25sb2FkIGVhY2ggZmlsZSB0aGF0IGRvZXNuJ3Qgc3RhcnQgd2l0aCBkaXN0L1xuICAgICAgICBmb3IgKGNvbnN0IGZpbGVJbmZvIG9mIHBhY2thZ2VGaWxlTGlzdC5wYWNrYWdlX2ZpbGVzKSB7XG4gICAgICAgICAgY29uc3QgZmlsZVBhdGggPSBmaWxlSW5mby5maWxlX3BhdGguc3RhcnRzV2l0aChcIi9cIilcbiAgICAgICAgICAgID8gZmlsZUluZm8uZmlsZV9wYXRoLnNsaWNlKDEpXG4gICAgICAgICAgICA6IGZpbGVJbmZvLmZpbGVfcGF0aFxuXG4gICAgICAgICAgaWYgKGZpbGVQYXRoLnN0YXJ0c1dpdGgoXCJkaXN0L1wiKSkgY29udGludWVcblxuICAgICAgICAgIGNvbnN0IGZpbGVDb250ZW50ID0gYXdhaXQga3lcbiAgICAgICAgICAgIC5wb3N0PHtcbiAgICAgICAgICAgICAgcGFja2FnZV9maWxlOiB7XG4gICAgICAgICAgICAgICAgY29udGVudF90ZXh0OiBzdHJpbmdcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfT4oXCJwYWNrYWdlX2ZpbGVzL2dldFwiLCB7XG4gICAgICAgICAgICAgIGpzb246IHtcbiAgICAgICAgICAgICAgICBwYWNrYWdlX25hbWU6IGAke2F1dGhvcn0vJHtzbmlwcGV0TmFtZX1gLFxuICAgICAgICAgICAgICAgIGZpbGVfcGF0aDogZmlsZUluZm8uZmlsZV9wYXRoLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIC5qc29uKClcblxuICAgICAgICAgIGNvbnN0IGZ1bGxQYXRoID0gcGF0aC5qb2luKGRpclBhdGgsIGZpbGVQYXRoKVxuICAgICAgICAgIGNvbnN0IGRpck5hbWUgPSBwYXRoLmRpcm5hbWUoZnVsbFBhdGgpXG5cbiAgICAgICAgICAvLyBDcmVhdGUgbmVzdGVkIGRpcmVjdG9yaWVzIGlmIHRoZXkgZG9uJ3QgZXhpc3RcbiAgICAgICAgICBpZiAoIWZzLmV4aXN0c1N5bmMoZGlyTmFtZSkpIHtcbiAgICAgICAgICAgIGZzLm1rZGlyU3luYyhkaXJOYW1lLCB7IHJlY3Vyc2l2ZTogdHJ1ZSB9KVxuICAgICAgICAgIH1cblxuICAgICAgICAgIGZzLndyaXRlRmlsZVN5bmMoZnVsbFBhdGgsIGZpbGVDb250ZW50LnBhY2thZ2VfZmlsZS5jb250ZW50X3RleHQpXG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBucG1yY1BhdGggPSBwYXRoLmpvaW4oZGlyUGF0aCwgXCIubnBtcmNcIilcbiAgICAgICAgZnMud3JpdGVGaWxlU3luYyhucG1yY1BhdGgsIFwiQHRzY2k6cmVnaXN0cnk9aHR0cHM6Ly9ucG0udHNjaXJjdWl0LmNvbVwiKVxuXG4gICAgICAgIGNvbnNvbGUubG9nKGBTdWNjZXNzZnVsbHkgY2xvbmVkIHRvIC4vJHthdXRob3J9LiR7c25pcHBldE5hbWV9L2ApXG4gICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICBpZiAoZXJyb3IgaW5zdGFuY2VvZiBFcnJvcikge1xuICAgICAgICAgIGNvbnNvbGUuZXJyb3IoXCJGYWlsZWQgdG8gY2xvbmUgc25pcHBldDpcIiwgZXJyb3IubWVzc2FnZSlcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBjb25zb2xlLmVycm9yKFwiRmFpbGVkIHRvIGNsb25lIHNuaXBwZXQ6XCIsIGVycm9yKVxuICAgICAgICB9XG4gICAgICAgIHByb2Nlc3MuZXhpdCgxKVxuICAgICAgfVxuICAgIH0pXG59XG4iLCAiaW1wb3J0IHR5cGUgeyBDb21tYW5kIH0gZnJvbSBcImNvbW1hbmRlclwiXG5pbXBvcnQgeyBjcmVhdGVDaXJjdWl0V2ViV29ya2VyIH0gZnJvbSBcIkB0c2NpcmN1aXQvZXZhbC13ZWJ3b3JrZXJcIlxuaW1wb3J0IHdlYldvcmtlckJ1bmRsZVVybCBmcm9tIFwiQHRzY2lyY3VpdC9ldmFsLXdlYndvcmtlci9ibG9iLXVybFwiXG5pbXBvcnQgeyBnZXRWaXJ0dWFsRmlsZVN5c3RlbUZyb21EaXJQYXRoIH0gZnJvbSBcIm1ha2UtdmZzXCJcbmltcG9ydCBwYXRoIGZyb20gXCJub2RlOnBhdGhcIlxuaW1wb3J0IGZzIGZyb20gXCJub2RlOmZzXCJcblxuY29uc3QgQUxMT1dFRF9GT1JNQVRTID0gW1xuICBcImpzb25cIixcbiAgXCJjaXJjdWl0LWpzb25cIixcbiAgXCJzY2hlbWF0aWMtc3ZnXCIsXG4gIFwicGNiLXN2Z1wiLFxuICBcImdlcmJlcnNcIixcbiAgXCJyZWFkYWJsZS1uZXRsaXN0XCIsXG4gIFwiZ2x0ZlwiLFxuICBcInNwZWNjdHJhLWRzblwiLFxuXSBhcyBjb25zdFxuXG50eXBlIEZvcm1hdCA9ICh0eXBlb2YgQUxMT1dFRF9GT1JNQVRTKVtudW1iZXJdXG5cbmNvbnN0IE9VVFBVVF9FWFRFTlNJT05TID0ge1xuICBqc29uOiBcIi5jaXJjdWl0Lmpzb25cIixcbiAgXCJjaXJjdWl0LWpzb25cIjogXCIuY2lyY3VpdC5qc29uXCIsXG4gIFwic2NoZW1hdGljLXN2Z1wiOiBcIi1zY2hlbWF0aWMuc3ZnXCIsXG4gIFwicGNiLXN2Z1wiOiBcIi1wY2Iuc3ZnXCIsXG4gIGdlcmJlcnM6IFwiLWdlcmJlcnMuemlwXCIsXG4gIFwicmVhZGFibGUtbmV0bGlzdFwiOiBcIi1yZWFkYWJsZS5uZXRsaXN0XCIsXG4gIGdsdGY6IFwiLmdsdGZcIixcbiAgXCJzcGVjY3RyYS1kc25cIjogXCIuZHNuXCIsXG59XG5cbmV4cG9ydCBjb25zdCByZWdpc3RlckV4cG9ydCA9IChwcm9ncmFtOiBDb21tYW5kKSA9PiB7XG4gIHByb2dyYW1cbiAgICAuY29tbWFuZChcImV4cG9ydFwiKVxuICAgIC5kZXNjcmlwdGlvbihcIkV4cG9ydCB0c2NpcmN1aXQgY29kZSB0byB2YXJpb3VzIGZvcm1hdHNcIilcbiAgICAuYXJndW1lbnQoXCI8ZmlsZT5cIiwgXCJQYXRoIHRvIHRoZSBzbmlwcGV0IGZpbGVcIilcbiAgICAub3B0aW9uKFwiLWYsIC0tZm9ybWF0IDxmb3JtYXQ+XCIsIFwiT3V0cHV0IGZvcm1hdFwiKVxuICAgIC5vcHRpb24oXCItbywgLS1vdXRwdXQgPHBhdGg+XCIsIFwiT3V0cHV0IGZpbGUgcGF0aFwiKVxuICAgIC5hY3Rpb24oYXN5bmMgKGZpbGUsIG9wdGlvbnMpID0+IHtcbiAgICAgIGNvbnN0IHsgZm9ybWF0ID0gXCJjaXJjdWl0LWpzb25cIiB9ID0gb3B0aW9uc1xuICAgICAgbGV0IHsgb3V0cHV0IH0gPSBvcHRpb25zXG4gICAgICBpZiAoIUFMTE9XRURfRk9STUFUUy5pbmNsdWRlcyhmb3JtYXQpKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgICBgSW52YWxpZCBmb3JtYXQ6ICR7Zm9ybWF0fVxcblN1cHBvcnRlZCBmb3JtYXRzOiAke0FMTE9XRURfRk9STUFUUy5qb2luKFwiLFwiKX1gLFxuICAgICAgICApXG4gICAgICB9XG5cbiAgICAgIGlmICghb3V0cHV0KSB7XG4gICAgICAgIG91dHB1dCA9IHBhdGguYmFzZW5hbWUoZmlsZSkucmVwbGFjZSgvXFwuW14uXSskLywgXCJcIilcbiAgICAgIH1cblxuICAgICAgY29uc3Qgd29ya2VyID0gYXdhaXQgY3JlYXRlQ2lyY3VpdFdlYldvcmtlcih7XG4gICAgICAgIHdlYldvcmtlclVybDogd2ViV29ya2VyQnVuZGxlVXJsLFxuICAgICAgfSlcblxuICAgICAgY29uc3QgcHJvamVjdERpciA9IHBhdGguZGlybmFtZShmaWxlKVxuXG4gICAgICBjb25zdCByZWxhdGl2ZUNvbXBvbmVudFBhdGggPSBwYXRoLnJlbGF0aXZlKHByb2plY3REaXIsIGZpbGUpXG5cbiAgICAgIGF3YWl0IHdvcmtlci5leGVjdXRlV2l0aEZzTWFwKHtcbiAgICAgICAgZW50cnlwb2ludDogXCJlbnRyeXBvaW50LnRzeFwiLFxuICAgICAgICBmc01hcDoge1xuICAgICAgICAgIC4uLigoYXdhaXQgZ2V0VmlydHVhbEZpbGVTeXN0ZW1Gcm9tRGlyUGF0aCh7XG4gICAgICAgICAgICBkaXJQYXRoOiBwcm9qZWN0RGlyLFxuICAgICAgICAgICAgY29udGVudEZvcm1hdDogXCJzdHJpbmdcIixcbiAgICAgICAgICB9KSkgYXMgUmVjb3JkPHN0cmluZywgc3RyaW5nPiksXG4gICAgICAgICAgXCJlbnRyeXBvaW50LnRzeFwiOiBgXG5pbXBvcnQgTXlDaXJjdWl0IGZyb20gXCIuLyR7cmVsYXRpdmVDb21wb25lbnRQYXRofVwiXG5cbmNpcmN1aXQuYWRkKDxNeUNpcmN1aXQgLz4pXG4gICAgICAgIGAsXG4gICAgICAgIH0sXG4gICAgICB9KVxuXG4gICAgICBhd2FpdCB3b3JrZXIucmVuZGVyVW50aWxTZXR0bGVkKClcblxuICAgICAgY29uc3QgY2lyY3VpdEpzb24gPSBhd2FpdCB3b3JrZXIuZ2V0Q2lyY3VpdEpzb24oKVxuXG4gICAgICBjb25zdCBvdXRwdXRQYXRoID0gcGF0aC5qb2luKFxuICAgICAgICBwcm9qZWN0RGlyLFxuICAgICAgICBgJHtvdXRwdXR9JHtPVVRQVVRfRVhURU5TSU9OU1tmb3JtYXQgYXMgRm9ybWF0XX1gLFxuICAgICAgKVxuXG4gICAgICBmcy53cml0ZUZpbGVTeW5jKG91dHB1dFBhdGgsIEpTT04uc3RyaW5naWZ5KGNpcmN1aXRKc29uKSlcblxuICAgICAgY29uc29sZS5sb2coYEV4cG9ydGVkIHRvICR7b3V0cHV0UGF0aH1gKVxuXG4gICAgICBwcm9jZXNzLmV4aXQoMClcbiAgICB9KVxufVxuIiwgImltcG9ydCB0eXBlIHsgQ29tbWFuZCB9IGZyb20gXCJjb21tYW5kZXJcIlxuaW1wb3J0IHsgY2xpQ29uZmlnIH0gZnJvbSBcImxpYi9jbGktY29uZmlnXCJcblxuZXhwb3J0IGNvbnN0IHJlZ2lzdGVyQXV0aFByaW50VG9rZW4gPSAocHJvZ3JhbTogQ29tbWFuZCkgPT4ge1xuICBwcm9ncmFtLmNvbW1hbmRzXG4gICAgLmZpbmQoKGMpID0+IGMubmFtZSgpID09PSBcImF1dGhcIikhXG4gICAgLmNvbW1hbmQoXCJwcmludC10b2tlblwiKVxuICAgIC5kZXNjcmlwdGlvbihcIlByaW50cyB5b3VyIGF1dGggdG9rZW5cIilcbiAgICAuYWN0aW9uKCgpID0+IHtcbiAgICAgIGNvbnN0IHRva2VuID0gY2xpQ29uZmlnLmdldChcInNlc3Npb25Ub2tlblwiKVxuICAgICAgaWYgKCF0b2tlbikgcmV0dXJuIGNvbnNvbGUubG9nKFwiWW91IG5lZWQgdG8gbG9nIGluIHRvIGFjY2VzcyB0aGlzLlwiKVxuICAgICAgY29uc29sZS5sb2coXCJZb3VyIFRva2VuOlxcblwiLCB0b2tlbilcbiAgICB9KVxufVxuIiwgImltcG9ydCB0eXBlIHsgQ29tbWFuZCB9IGZyb20gXCJjb21tYW5kZXJcIlxuaW1wb3J0IHsgY2xpQ29uZmlnIH0gZnJvbSBcImxpYi9jbGktY29uZmlnXCJcblxuZnVuY3Rpb24gdmFsaWRhdGVKV1RMZW5ndGgodG9rZW46IHN0cmluZykge1xuICBjb25zdCBwYXJ0cyA9IHRva2VuLnNwbGl0KFwiLlwiKVxuXG4gIGlmIChwYXJ0cy5sZW5ndGggPT09IDMgJiYgcGFydHMuZXZlcnkoKHBhcnQpID0+IHBhcnQubGVuZ3RoID4gMCkpIHtcbiAgICByZXR1cm4gdHJ1ZVxuICB9IGVsc2Uge1xuICAgIHJldHVybiBmYWxzZVxuICB9XG59XG5leHBvcnQgY29uc3QgcmVnaXN0ZXJBdXRoU2V0VG9rZW4gPSAocHJvZ3JhbTogQ29tbWFuZCkgPT4ge1xuICBwcm9ncmFtLmNvbW1hbmRzXG4gICAgLmZpbmQoKGMpID0+IGMubmFtZSgpID09PSBcImF1dGhcIikhXG4gICAgLmNvbW1hbmQoXCJzZXQtdG9rZW5cIilcbiAgICAuZGVzY3JpcHRpb24oXCJFeHBsaWNpdGx5IHNldCB5b3VyIGF1dGggdG9rZW5cIilcbiAgICAuYXJndW1lbnQoXCI8dG9rZW4+XCIsIFwiTmV3IHRva2VuIHRvIG1hbnVhbGx5IGNvbmZpZ3VyZVwiKVxuICAgIC5hY3Rpb24oKHRva2VuKSA9PiB7XG4gICAgICBpZiAoIXZhbGlkYXRlSldUTGVuZ3RoKHRva2VuKSlcbiAgICAgICAgcmV0dXJuIGNvbnNvbGUubG9nKFwiSW52YWxpZCB0b2tlbiBwcm92aWRlZFwiKVxuICAgICAgY2xpQ29uZmlnLnNldChcInNlc3Npb25Ub2tlblwiLCB0b2tlbilcbiAgICAgIGNvbnNvbGUubG9nKFwiVG9rZW4gbWFudWFsbHkgdXBkYXRlZC5cIilcbiAgICB9KVxufVxuIl0sCiAgIm1hcHBpbmdzIjogIjs7O0FBQ0EsU0FBUyxlQUFlOzs7QUNBeEIsWUFBWSxRQUFRO0FBQ3BCLFlBQVksVUFBVTtBQUVmLElBQU0sZUFBZSxDQUFDQSxhQUFxQjtBQUNoRCxFQUFBQSxTQUNHLFFB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O0FBQ2pCLFFBQUksQ0FBQyxrQkFBa0IsS0FBSztBQUMxQixhQUFPLFFBQVEsSUFBSSx3QkFBd0I7QUFDN0MsY0FBVSxJQUFJLGdCQUFnQixLQUFLO0FBQ25DLFlBQVEsSUFBSSx5QkFBeUI7QUFBQSxFQUN2QyxDQUFDO0FBQ0w7OztBbkJQQSxJQUFNLFVBQVUsSUFBSSxRQUFRO0FBRTVCLFFBQ0csS0FBSyxNQUFNLEVBQ1gsWUFBWSx1Q0FBdUMsRUFHbkQsUUFBUSxPQUFPLElBQUksZ0JBQUksU0FBUyxPQUFPLEtBQUssZ0JBQUksT0FBTztBQUUxRCxhQUFhLE9BQU87QUFFcEIsWUFBWSxPQUFPO0FBQ25CLGNBQWMsT0FBTztBQUVyQixhQUFhLE9BQU87QUFDcEIsa0JBQWtCLE9BQU87QUFDekIsbUJBQW1CLE9BQU87QUFDMUIsdUJBQXVCLE9BQU87QUFDOUIscUJBQXFCLE9BQU87QUFFNUIsZUFBZSxPQUFPO0FBQ3RCLG9CQUFvQixPQUFPO0FBRTNCLGVBQWUsT0FBTztBQUV0QixJQUFJLFFBQVEsS0FBSyxXQUFXLEdBQUc7QUFDN0IsYUFBVyxTQUFTLFFBQVEsSUFBSTtBQUNsQyxPQUFPO0FBQ0wsVUFBUSxNQUFNO0FBQ2hCOyIsCiAgIm5hbWVzIjogWyJwcm9ncmFtIiwgInBhdGgiLCAiZnMiLCAiZnMiLCAicGF0aCIsICJmcyIsICJwYXRoIiwgInJlc29sdmUiLCAicGF0aCIsICJmcyIsICJwcm9ncmFtIiwgImt5IiwgInByb2dyYW0iLCAia3kiLCAicHJvZ3JhbSIsICJwcm9ncmFtIiwgInByb2dyYW0iLCAicHJvZ3JhbSIsICJmcyIsICJwYXRoIiwgInByb2dyYW0iLCAia3kiLCAicGF0aCIsICJmcyIsICJwcm9ncmFtIiwgInByb2dyYW0iLCAicHJvZ3JhbSJdCn0K
849
+ //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vY2xpL21haW4udHMiLCAiLi4vY2xpL2luaXQvcmVnaXN0ZXIudHMiLCAiLi4vY2xpL2Rldi9yZWdpc3Rlci50cyIsICIuLi9saWIvZGVwZW5kZW5jeS1hbmFseXNpcy9pbnN0YWxsTm9kZU1vZHVsZVR5cGVzRm9yU25pcHBldC50cyIsICIuLi9jbGkvZGV2L0RldlNlcnZlci50cyIsICIuLi9saWIvc2VydmVyL2NyZWF0ZUh0dHBTZXJ2ZXIudHMiLCAiLi4vcGFja2FnZS5qc29uIiwgIi4uL2xpYi9zaXRlL2dldEluZGV4LnRzIiwgIi4uL2xpYi9zZXJ2ZXIvRXZlbnRzV2F0Y2hlci50cyIsICIuLi9saWIvZGVwZW5kZW5jeS1hbmFseXNpcy9GaWxlc3lzdGVtVHlwZXNIYW5kbGVyLnRzIiwgIi4uL2xpYi9kZXBlbmRlbmN5LWFuYWx5c2lzL2ZpbmRJbXBvcnRzSW5TbmlwcGV0LnRzIiwgIi4uL2xpYi9jbGktY29uZmlnL2luZGV4LnRzIiwgIi4uL2NsaS9hdXRoL2xvZ2luL3JlZ2lzdGVyLnRzIiwgIi4uL2xpYi9yZWdpc3RyeS1hcGkvZ2V0LWt5LnRzIiwgIi4uL2NsaS9hdXRoL2xvZ291dC9yZWdpc3Rlci50cyIsICIuLi9jbGkvYXV0aC9yZWdpc3Rlci50cyIsICIuLi9jbGkvY29uZmlnL3JlZ2lzdGVyLnRzIiwgIi4uL2NsaS9jb25maWcvcHJpbnQvcmVnaXN0ZXIudHMiLCAiLi4vY2xpL2Nsb25lL3JlZ2lzdGVyLnRzIiwgIi4uL2NsaS9leHBvcnQvcmVnaXN0ZXIudHMiLCAiLi4vY2xpL2F1dGgvcHJpbnQtdG9rZW4vcmVnaXN0ZXIudHMiLCAiLi4vY2xpL2F1dGgvc2V0LXRva2VuL3JlZ2lzdGVyLnRzIl0sCiAgInNvdXJjZXNDb250ZW50IjogWyIjIS91c3IvYmluL2VudiBub2RlXG5pbXBvcnQgeyBDb21tYW5kIH0gZnJvbSBcImNvbW1hbmRlclwiXG5pbXBvcnQgeyByZWdpc3RlckluaXQgfSBmcm9tIFwiLi9pbml0L3JlZ2lzdGVyXCJcbmltcG9ydCB7IHJlZ2lzdGVyRGV2IH0gZnJvbSBcIi4vZGV2L3JlZ2lzdGVyXCJcbmltcG9ydCB7IHJlZ2lzdGVyQXV0aExvZ2luIH0gZnJvbSBcIi4vYXV0aC9sb2dpbi9yZWdpc3RlclwiXG5pbXBvcnQgeyByZWdpc3RlckF1dGhMb2dvdXQgfSBmcm9tIFwiLi9hdXRoL2xvZ291dC9yZWdpc3RlclwiXG5pbXBvcnQgeyByZWdpc3RlckF1dGggfSBmcm9tIFwiLi9hdXRoL3JlZ2lzdGVyXCJcbmltcG9ydCB7IHJlZ2lzdGVyQ29uZmlnIH0gZnJvbSBcIi4vY29uZmlnL3JlZ2lzdGVyXCJcbmltcG9ydCB7IHJlZ2lzdGVyQ29uZmlnUHJpbnQgfSBmcm9tIFwiLi9jb25maWcvcHJpbnQvcmVnaXN0ZXJcIlxuaW1wb3J0IHsgcmVnaXN0ZXJDbG9uZSB9IGZyb20gXCIuL2Nsb25lL3JlZ2lzdGVyXCJcbmltcG9ydCB7IHBlcmZlY3RDbGkgfSBmcm9tIFwicGVyZmVjdC1jbGlcIlxuaW1wb3J0IHBrZyBmcm9tIFwiLi4vcGFja2FnZS5qc29uXCJcbmltcG9ydCBzZW12ZXIgZnJvbSBcInNlbXZlclwiXG5pbXBvcnQgeyByZWdpc3RlckV4cG9ydCB9IGZyb20gXCIuL2V4cG9ydC9yZWdpc3RlclwiXG5pbXBvcnQgeyByZWdpc3RlckF1dGhQcmludFRva2VuIH0gZnJvbSBcIi4vYXV0aC9wcmludC10b2tlbi9yZWdpc3RlclwiXG5pbXBvcnQgeyByZWdpc3RlckF1dGhTZXRUb2tlbiB9IGZyb20gXCIuL2F1dGgvc2V0LXRva2VuL3JlZ2lzdGVyXCJcblxuY29uc3QgcHJvZ3JhbSA9IG5ldyBDb21tYW5kKClcblxucHJvZ3JhbVxuICAubmFtZShcInRzY2lcIilcbiAgLmRlc2NyaXB0aW9uKFwiQ0xJIGZvciBkZXZlbG9waW5nIHRzY2lyY3VpdCBzbmlwcGV0c1wiKVxuICAvLyBIQUNLOiBhdCBidWlsZCB0aW1lIHRoZSB2ZXJzaW9uIGlzIG9sZCwgd2UgbmVlZCB0b1xuICAvLyBmaXggdGhpcyBhdCBzb21lIHBvaW50Li4uXG4gIC52ZXJzaW9uKHNlbXZlci5pbmMocGtnLnZlcnNpb24sIFwicGF0Y2hcIikgPz8gcGtnLnZlcnNpb24pXG5cbnJlZ2lzdGVySW5pdChwcm9ncmFtKVxuXG5yZWdpc3RlckRldihwcm9ncmFtKVxucmVnaXN0ZXJDbG9uZShwcm9ncmFtKVxuXG5yZWdpc3RlckF1dGgocHJvZ3JhbSlcbnJlZ2lzdGVyQXV0aExvZ2luKHByb2dyYW0pXG5yZWdpc3RlckF1dGhMb2dvdXQocHJvZ3JhbSlcbnJlZ2lzdGVyQXV0aFByaW50VG9rZW4ocHJvZ3JhbSlcbnJlZ2lzdGVyQXV0aFNldFRva2VuKHByb2dyYW0pXG5cbnJlZ2lzdGVyQ29uZmlnKHByb2dyYW0pXG5yZWdpc3RlckNvbmZpZ1ByaW50KHByb2dyYW0pXG5cbnJlZ2lzdGVyRXhwb3J0KHByb2dyYW0pXG5cbmlmIChwcm9jZXNzLmFyZ3YubGVuZ3RoID09PSAyKSB7XG4gIHBlcmZlY3RDbGkocHJvZ3JhbSwgcHJvY2Vzcy5hcmd2KVxufSBlbHNlIHtcbiAgcHJvZ3JhbS5wYXJzZSgpXG59XG4iLCAiaW1wb3J0IHR5cGUgeyBDb21tYW5kIH0gZnJvbSBcImNvbW1hbmRlclwiXG5pbXBvcnQgKiBhcyBmcyBmcm9tIFwibm9kZTpmc1wiXG5pbXBvcnQgKiBhcyBwYXRoIGZyb20gXCJub2RlOnBhdGhcIlxuXG5leHBvcnQgY29uc3QgcmVnaXN0ZXJJbml0ID0gKHByb2dyYW06IENvbW1hbmQpID0+IHtcbiAgcHJvZ3JhbVxuICAgIC5jb21tYW5kKFwiaW5pdFwiKVxuICAgIC5kZXNjcmlwdGlvbihcIkluaXRpYWxpemUgYSBuZXcgVFNDaXJjdWl0IHByb2plY3QgaW4gdGhlIGN1cnJlbnQgZGlyZWN0b3J5XCIpXG4gICAgLmFjdGlvbigoKSA9PiB7XG4gICAgICBjb25zdCBjdXJyZW50RGlyID0gcHJvY2Vzcy5jd2QoKVxuXG4gICAgICBjb25zdCBpbmRleEZpbGVQYXRoID0gcGF0aC5qb2luKGN1cnJlbnREaXIsIFwiaW5kZXgudHN4XCIpXG4gICAgICBjb25zdCBucG1yY0ZpbGVQYXRoID0gcGF0aC5qb2luKGN1cnJlbnREaXIsIFwiLm5wbXJjXCIpXG5cbiAgICAgIGNvbnN0IGluZGV4Q29udGVudCA9IGBcbmV4cG9ydCBkZWZhdWx0ICgpID0+IChcbiAgPGJvYXJkIHdpZHRoPVwiMTBtbVwiIGhlaWdodD1cIjEwbW1cIj5cbiAgICA8cmVzaXN0b3JcbiAgICAgIHJlc2lzdGFuY2U9XCIxa1wiXG4gICAgICBmb290cHJpbnQ9XCIwNDAyXCJcbiAgICAgIG5hbWU9XCJSMVwiXG4gICAgICBzY2hYPXszfVxuICAgICAgcGNiWD17M31cbiAgICAvPlxuICAgIDxjYXBhY2l0b3JcbiAgICAgIGNhcGFjaXRhbmNlPVwiMTAwMHBGXCJcbiAgICAgIGZvb3RwcmludD1cIjA0MDJcIlxuICAgICAgbmFtZT1cIkMxXCJcbiAgICAgIHNjaFg9ey0zfVxuICAgICAgcGNiWD17LTN9XG4gICAgLz5cbiAgICA8dHJhY2UgZnJvbT1cIi5SMSA+IC5waW4xXCIgdG89XCIuQzEgPiAucGluMVwiIC8+XG4gIDwvYm9hcmQ+XG4pO1xuYFxuXG4gICAgICBjb25zdCBucG1yY0NvbnRlbnQgPSBgXG5AdHNjaTpyZWdpc3RyeT1odHRwczovL25wbS50c2NpcmN1aXQuY29tXG5gXG5cbiAgICAgIGlmICghZnMuZXhpc3RzU3luYyhpbmRleEZpbGVQYXRoKSkge1xuICAgICAgICBmcy53cml0ZUZpbGVTeW5jKGluZGV4RmlsZVBhdGgsIGluZGV4Q29udGVudC50cmltU3RhcnQoKSlcbiAgICAgICAgY29uc29sZS5sb2coYENyZWF0ZWQ6ICR7aW5kZXhGaWxlUGF0aH1gKVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29uc29sZS5sb2coYFNraXBwZWQ6ICR7aW5kZXhGaWxlUGF0aH0gYWxyZWFkeSBleGlzdHNgKVxuICAgICAgfVxuXG4gICAgICBpZiAoIWZzLmV4aXN0c1N5bmMobnBtcmNGaWxlUGF0aCkpIHtcbiAgICAgICAgZnMud3JpdGVGaWxlU3luYyhucG1yY0ZpbGVQYXRoLCBucG1yY0NvbnRlbnQudHJpbVN0YXJ0KCkpXG4gICAgICAgIGNvbnNvbGUubG9nKGBDcmVhdGVkOiAke25wbXJjRmlsZVBhdGh9YClcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbnNvbGUubG9nKGBTa2lwcGVkOiAke25wbXJjRmlsZVBhdGh9IGFscmVhZHkgZXhpc3RzYClcbiAgICAgIH1cblxuICAgICAgY29uc29sZS5sb2coXG4gICAgICAgIGBJbml0aWFsaXphdGlvbiBjb21wbGV0ZS4gUnVuIFwidHNjaSBkZXZcIiB0byBzdGFydCBkZXZlbG9waW5nLmAsXG4gICAgICApXG4gICAgfSlcbn1cbiIsICJpbXBvcnQgdHlwZSB7IENvbW1hbmQgfSBmcm9tIFwiY29tbWFuZGVyXCJcbmltcG9ydCAqIGFzIHBhdGggZnJvbSBcIm5vZGU6cGF0aFwiXG5pbXBvcnQgKiBhcyBjaG9raWRhciBmcm9tIFwiY2hva2lkYXJcIlxuaW1wb3J0ICogYXMgZnMgZnJvbSBcIm5vZGU6ZnNcIlxuaW1wb3J0IHsgY3JlYXRlSHR0cFNlcnZlciB9IGZyb20gXCJsaWIvc2VydmVyL2NyZWF0ZUh0dHBTZXJ2ZXJcIlxuaW1wb3J0IHsgZ2V0TG9jYWxGaWxlRGVwZW5kZW5jaWVzIH0gZnJvbSBcImxpYi9kZXBlbmRlbmN5LWFuYWx5c2lzL2dldExvY2FsRmlsZURlcGVuZGVuY2llc1wiXG5pbXBvcnQgeyBpbnN0YWxsTm9kZU1vZHVsZVR5cGVzRm9yU25pcHBldCB9IGZyb20gXCIuLi8uLi9saWIvZGVwZW5kZW5jeS1hbmFseXNpcy9pbnN0YWxsTm9kZU1vZHVsZVR5cGVzRm9yU25pcHBldFwiXG5pbXBvcnQgeyBFdmVudHNXYXRjaGVyIH0gZnJvbSBcIi4uLy4uL2xpYi9zZXJ2ZXIvRXZlbnRzV2F0Y2hlclwiXG5pbXBvcnQgeyBEZXZTZXJ2ZXIgfSBmcm9tIFwiLi9EZXZTZXJ2ZXJcIlxuXG5leHBvcnQgY29uc3QgcmVnaXN0ZXJEZXYgPSAocHJvZ3JhbTogQ29tbWFuZCkgPT4ge1xuICBwcm9ncmFtXG4gICAgLmNvbW1hbmQoXCJkZXZcIilcbiAgICAuZGVzY3JpcHRpb24oXCJTdGFydCBkZXZlbG9wbWVudCBzZXJ2ZXIgZm9yIGEgc25pcHBldFwiKVxuICAgIC5hcmd1bWVudChcIltmaWxlXVwiLCBcIlBhdGggdG8gdGhlIHNuaXBwZXQgZmlsZVwiKVxuICAgIC5vcHRpb24oXCItcCwgLS1wb3J0IDxudW1iZXI+XCIsIFwiUG9ydCB0byBydW4gc2VydmVyIG9uXCIsIFwiMzAwMFwiKVxuICAgIC5hY3Rpb24oYXN5bmMgKGZpbGU6IHN0cmluZywgb3B0aW9uczogeyBwb3J0OiBzdHJpbmcgfSkgPT4ge1xuICAgICAgY29uc3QgcG9ydCA9IHBhcnNlSW50KG9wdGlvbnMucG9ydClcbiAgICAgIGxldCBhYnNvbHV0ZVBhdGg6IHN0cmluZ1xuXG4gICAgICBpZiAoZmlsZSkge1xuICAgICAgICBhYnNvbHV0ZVBhdGggPSBwYXRoLnJlc29sdmUoZmlsZSlcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbnN0IGVudHJ5cG9pbnRQYXRoID0gcGF0aC5yZXNvbHZlKFwiaW5kZXgudHN4XCIpXG4gICAgICAgIGlmIChmcy5leGlzdHNTeW5jKGVudHJ5cG9pbnRQYXRoKSkge1xuICAgICAgICAgIGFic29sdXRlUGF0aCA9IGVudHJ5cG9pbnRQYXRoXG4gICAgICAgICAgY29uc29sZS5sb2coXCJObyBmaWxlIHByb3ZpZGVkLiBVc2luZyAnaW5kZXgudHN4JyBhcyB0aGUgZW50cnlwb2ludC5cIilcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBjb25zb2xlLmxvZyhcbiAgICAgICAgICAgIFwiTm8gZW50cnlwb2ludCBmb3VuZC4gUnVuICd0c2NpIGluaXQnIHRvIGJvb3RzdHJhcCBhIGJhc2ljIHByb2plY3QuXCIsXG4gICAgICAgICAgKVxuICAgICAgICAgIHJldHVyblxuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGZpbGVEaXIgPSBwYXRoLmRpcm5hbWUoYWJzb2x1dGVQYXRoKVxuXG4gICAgICB0cnkge1xuICAgICAgICBjb25zb2xlLmxvZyhcIkluc3RhbGxpbmcgdHlwZXMgZm9yIGltcG9ydGVkIHNuaXBwZXRzLi4uXCIpXG4gICAgICAgIGF3YWl0IGluc3RhbGxOb2RlTW9kdWxlVHlwZXNGb3JTbmlwcGV0KGFic29sdXRlUGF0aClcbiAgICAgICAgY29uc29sZS5sb2coXCJUeXBlcyBpbnN0YWxsZWQgc3VjY2Vzc2Z1bGx5XCIpXG4gICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICBjb25zb2xlLndhcm4oXCJGYWlsZWQgdG8gaW5zdGFsbCB0eXBlczpcIiwgZXJyb3IpXG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHNlcnZlciA9IG5ldyBEZXZTZXJ2ZXIoe1xuICAgICAgICBwb3J0LFxuICAgICAgICBjb21wb25lbnRGaWxlUGF0aDogYWJzb2x1dGVQYXRoLFxuICAgICAgfSlcblxuICAgICAgYXdhaXQgc2VydmVyLnN0YXJ0KClcbiAgICAgIGF3YWl0IHNlcnZlci5hZGRFbnRyeXBvaW50KClcbiAgICB9KVxufVxuIiwgImltcG9ydCAqIGFzIGZzIGZyb20gXCJub2RlOmZzXCJcbmltcG9ydCAqIGFzIHBhdGggZnJvbSBcIm5vZGU6cGF0aFwiXG5pbXBvcnQgKiBhcyB0cyBmcm9tIFwidHlwZXNjcmlwdFwiXG5cbmludGVyZmFjZSBTbmlwcGV0QXBpUmVzcG9uc2Uge1xuICBzbmlwcGV0OiB7XG4gICAgZHRzOiBzdHJpbmdcbiAgfVxufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gaW5zdGFsbE5vZGVNb2R1bGVUeXBlc0ZvclNuaXBwZXQoc25pcHBldFBhdGg6IHN0cmluZykge1xuICBjb25zdCBjb250ZW50ID0gZnMucmVhZEZpbGVTeW5jKHNuaXBwZXRQYXRoLCBcInV0Zi04XCIpXG4gIGNvbnN0IHNvdXJjZUZpbGUgPSB0cy5jcmVhdGVTb3VyY2VGaWxlKFxuICAgIHNuaXBwZXRQYXRoLFxuICAgIGNvbnRlbnQsXG4gICAgdHMuU2NyaXB0VGFyZ2V0LkxhdGVzdCxcbiAgICB0cnVlLFxuICApXG5cbiAgY29uc3QgaW1wb3J0czogc3RyaW5nW10gPSBbXVxuXG4gIGZ1bmN0aW9uIHZpc2l0KG5vZGU6IHRzLk5vZGUpIHtcbiAgICBpZiAodHMuaXNJbXBvcnREZWNsYXJhdGlvbihub2RlKSkge1xuICAgICAgY29uc3QgbW9kdWxlU3BlY2lmaWVyID0gbm9kZS5tb2R1bGVTcGVjaWZpZXJcbiAgICAgIGlmIChtb2R1bGVTcGVjaWZpZXIgJiYgdHMuaXNTdHJpbmdMaXRlcmFsKG1vZHVsZVNwZWNpZmllcikpIHtcbiAgICAgICAgY29uc3QgaW1wb3J0UGF0aCA9IG1vZHVsZVNwZWNpZmllci50ZXh0XG4gICAgICAgIGlmIChpbXBvcnRQYXRoLnN0YXJ0c1dpdGgoXCJAdHNjaS9cIikpIHtcbiAgICAgICAgICBpbXBvcnRzLnB1c2goaW1wb3J0UGF0aClcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICB0cy5mb3JFYWNoQ2hpbGQobm9kZSwgdmlzaXQpXG4gIH1cblxuICB2aXNpdChzb3VyY2VGaWxlKVxuXG4gIGxldCBwcm9qZWN0Um9vdCA9IHBhdGguZGlybmFtZShzbmlwcGV0UGF0aClcbiAgd2hpbGUgKHByb2plY3RSb290ICE9PSBwYXRoLnBhcnNlKHByb2plY3RSb290KS5yb290KSB7XG4gICAgaWYgKGZzLmV4aXN0c1N5bmMocGF0aC5qb2luKHByb2plY3RSb290LCBcInBhY2thZ2UuanNvblwiKSkpIHtcbiAgICAgIGJyZWFrXG4gICAgfVxuICAgIHByb2plY3RSb290ID0gcGF0aC5kaXJuYW1lKHByb2plY3RSb290KVxuICB9XG5cbiAgZm9yIChjb25zdCBpbXBvcnRQYXRoIG9mIGltcG9ydHMpIHtcbiAgICBjb25zdCBbb3duZXIsIG5hbWVdID0gaW1wb3J0UGF0aC5yZXBsYWNlKFwiQHRzY2kvXCIsIFwiXCIpLnNwbGl0KFwiLlwiKVxuICAgIHRyeSB7XG4gICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGZldGNoKFxuICAgICAgICBgaHR0cHM6Ly9yZWdpc3RyeS1hcGkudHNjaXJjdWl0LmNvbS9zbmlwcGV0cy9nZXQ/b3duZXJfbmFtZT0ke293bmVyfSZ1bnNjb3BlZF9uYW1lPSR7bmFtZX1gLFxuICAgICAgKVxuXG4gICAgICBpZiAoIXJlc3BvbnNlLm9rKSB7XG4gICAgICAgIGNvbnNvbGUud2FybihgRmFpbGVkIHRvIGZldGNoIHR5cGVzIGZvciAke2ltcG9ydFBhdGh9YClcbiAgICAgICAgY29udGludWVcbiAgICAgIH1cblxuICAgICAgY29uc3QgZGF0YTogU25pcHBldEFwaVJlc3BvbnNlID0gYXdhaXQgcmVzcG9uc2UuanNvbigpXG5cbiAgICAgIGlmIChkYXRhLnNuaXBwZXQuZHRzKSB7XG4gICAgICAgIGNvbnN0IHBhY2thZ2VEaXIgPSBwYXRoLmpvaW4oXG4gICAgICAgICAgcHJvamVjdFJvb3QsXG4gICAgICAgICAgXCJub2RlX21vZHVsZXNcIixcbiAgICAgICAgICBcIkB0c2NpXCIsXG4gICAgICAgICAgYCR7b3duZXJ9LiR7bmFtZX1gLFxuICAgICAgICApXG4gICAgICAgIGZzLm1rZGlyU3luYyhwYWNrYWdlRGlyLCB7IHJlY3Vyc2l2ZTogdHJ1ZSB9KVxuXG4gICAgICAgIGZzLndyaXRlRmlsZVN5bmMocGF0aC5qb2luKHBhY2thZ2VEaXIsIFwiaW5kZXguZC50c1wiKSwgZGF0YS5zbmlwcGV0LmR0cylcbiAgICAgIH1cbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgY29uc29sZS53YXJuKGBFcnJvciBmZXRjaGluZyB0eXBlcyBmb3IgJHtpbXBvcnRQYXRofTpgLCBlcnJvcilcbiAgICB9XG4gIH1cbn1cbiIsICJpbXBvcnQga3kgZnJvbSBcImt5XCJcbmltcG9ydCB0eXBlIHsgRmlsZVNlcnZlclJvdXRlcyB9IGZyb20gXCJsaWIvZmlsZS1zZXJ2ZXIvRmlsZVNlcnZlclJvdXRlc1wiXG5pbXBvcnQgeyBjcmVhdGVIdHRwU2VydmVyIH0gZnJvbSBcImxpYi9zZXJ2ZXIvY3JlYXRlSHR0cFNlcnZlclwiXG5pbXBvcnQgeyBFdmVudHNXYXRjaGVyIH0gZnJvbSBcImxpYi9zZXJ2ZXIvRXZlbnRzV2F0Y2hlclwiXG5pbXBvcnQgdHlwZSBodHRwIGZyb20gXCJub2RlOmh0dHBcIlxuaW1wb3J0IHR5cGUgeyBUeXBlZEt5SW5zdGFuY2UgfSBmcm9tIFwidHlwZWQta3lcIlxuaW1wb3J0IHBhdGggZnJvbSBcIm5vZGU6cGF0aFwiXG5pbXBvcnQgZnMgZnJvbSBcIm5vZGU6ZnNcIlxuaW1wb3J0IHR5cGUgeyBGaWxlVXBkYXRlZEV2ZW50IH0gZnJvbSBcImxpYi9maWxlLXNlcnZlci9GaWxlU2VydmVyRXZlbnRcIlxuaW1wb3J0ICogYXMgY2hva2lkYXIgZnJvbSBcImNob2tpZGFyXCJcbmltcG9ydCB7IEZpbGVzeXN0ZW1UeXBlc0hhbmRsZXIgfSBmcm9tIFwibGliL2RlcGVuZGVuY3ktYW5hbHlzaXMvRmlsZXN5c3RlbVR5cGVzSGFuZGxlclwiXG5cbmV4cG9ydCBjbGFzcyBEZXZTZXJ2ZXIge1xuICBwb3J0OiBudW1iZXJcbiAgLyoqXG4gICAqIFRoZSBwYXRoIHRvIGEgY29tcG9uZW50IHRoYXQgZXhwb3J0cyBhIDxib2FyZCAvPiBvciA8Z3JvdXAgLz4gY29tcG9uZW50XG4gICAqL1xuICBjb21wb25lbnRGaWxlUGF0aDogc3RyaW5nXG5cbiAgcHJvamVjdERpcjogc3RyaW5nXG5cbiAgLyoqXG4gICAqIFRoZSBIVFRQIHNlcnZlciB0aGF0IGhvc3RzIHRoZSBmaWxlIHNlcnZlciBhbmQgZXZlbnQgYnVzLiBZb3UgY2FuIHVzZVxuICAgKiBmc0t5IHRvIGNvbW11bmljYXRlIHdpdGggdGhlIGZpbGUgc2VydmVyL2V2ZW50IGJ1c1xuICAgKi9cbiAgaHR0cFNlcnZlcj86IGh0dHAuU2VydmVyXG4gIC8qKlxuICAgKiBXYXRjaGVzIGZvciBldmVudHMgb24gdGhlIGV2ZW50IGJ1cyBieSBwb2xsaW5nIGBhcGkvZXZlbnRzL2xpc3RgXG4gICAqL1xuICBldmVudHNXYXRjaGVyPzogRXZlbnRzV2F0Y2hlclxuICAvKipcbiAgICogQSBreSBpbnN0YW5jZSB0aGF0IGNhbiBiZSB1c2VkIHRvIGNvbW11bmljYXRlIHdpdGggdGhlIGZpbGUgc2VydmVyIGFuZFxuICAgKiBldmVudCBidXNcbiAgICovXG4gIGZzS3k6IFR5cGVkS3lJbnN0YW5jZTxrZXlvZiBGaWxlU2VydmVyUm91dGVzLCBGaWxlU2VydmVyUm91dGVzPlxuICAvKipcbiAgICogQSBjaG9raWRhciBpbnN0YW5jZSB0aGF0IHdhdGNoZXMgdGhlIHByb2plY3QgZGlyZWN0b3J5IGZvciBmaWxlIGNoYW5nZXNcbiAgICovXG4gIGZpbGVzeXN0ZW1XYXRjaGVyPzogY2hva2lkYXIuRlNXYXRjaGVyXG5cbiAgcHJpdmF0ZSB0eXBlc0hhbmRsZXI/OiBGaWxlc3lzdGVtVHlwZXNIYW5kbGVyXG5cbiAgY29uc3RydWN0b3Ioe1xuICAgIHBvcnQsXG4gICAgY29tcG9uZW50RmlsZVBhdGgsXG4gIH06IHtcbiAgICBwb3J0OiBudW1iZXJcbiAgICBjb21wb25lbnRGaWxlUGF0aDogc3RyaW5nXG4gIH0pIHtcbiAgICB0aGlzLnBvcnQgPSBwb3J0XG4gICAgdGhpcy5jb21wb25lbnRGaWxlUGF0aCA9IGNvbXBvbmVudEZpbGVQYXRoXG4gICAgdGhpcy5wcm9qZWN0RGlyID0gcGF0aC5kaXJuYW1lKGNvbXBvbmVudEZpbGVQYXRoKVxuICAgIHRoaXMuZnNLeSA9IGt5LmNyZWF0ZSh7XG4gICAgICBwcmVmaXhVcmw6IGBodHRwOi8vbG9jYWxob3N0OiR7cG9ydH1gLFxuICAgIH0pIGFzIGFueVxuICAgIHRoaXMudHlwZXNIYW5kbGVyID0gbmV3IEZpbGVzeXN0ZW1UeXBlc0hhbmRsZXIodGhpcy5wcm9qZWN0RGlyKVxuICB9XG5cbiAgYXN5bmMgc3RhcnQoKSB7XG4gICAgY29uc3QgeyBzZXJ2ZXIgfSA9IGF3YWl0IGNyZWF0ZUh0dHBTZXJ2ZXIodGhpcy5wb3J0KVxuICAgIHRoaXMuaHR0cFNlcnZlciA9IHNlcnZlclxuXG4gICAgdGhpcy5ldmVudHNXYXRjaGVyID0gbmV3IEV2ZW50c1dhdGNoZXIoYGh0dHA6Ly9sb2NhbGhvc3Q6JHt0aGlzLnBvcnR9YClcbiAgICB0aGlzLmV2ZW50c1dhdGNoZXIuc3RhcnQoKVxuXG4gICAgdGhpcy5ldmVudHNXYXRjaGVyLm9uKFxuICAgICAgXCJGSUxFX1VQREFURURcIixcbiAgICAgIHRoaXMuaGFuZGxlRmlsZVVwZGF0ZWRFdmVudEZyb21TZXJ2ZXIuYmluZCh0aGlzKSxcbiAgICApXG5cbiAgICB0aGlzLmZpbGVzeXN0ZW1XYXRjaGVyID0gY2hva2lkYXIud2F0Y2godGhpcy5wcm9qZWN0RGlyLCB7XG4gICAgICBwZXJzaXN0ZW50OiB0cnVlLFxuICAgICAgaWdub3JlSW5pdGlhbDogdHJ1ZSxcbiAgICB9KVxuXG4gICAgdGhpcy5maWxlc3lzdGVtV2F0Y2hlci5vbihcImNoYW5nZVwiLCAoZmlsZVBhdGgpID0+XG4gICAgICB0aGlzLmhhbmRsZUZpbGVDaGFuZ2VkT25GaWxlc3lzdGVtKGZpbGVQYXRoKSxcbiAgICApXG4gICAgdGhpcy5maWxlc3lzdGVtV2F0Y2hlci5vbihcImFkZFwiLCAoZmlsZVBhdGgpID0+XG4gICAgICB0aGlzLmhhbmRsZUZpbGVDaGFuZ2VkT25GaWxlc3lzdGVtKGZpbGVQYXRoKSxcbiAgICApXG5cbiAgICB0aGlzLnVwc2VydEluaXRpYWxGaWxlcygpXG5cbiAgICB0aGlzLnR5cGVzSGFuZGxlcj8uaGFuZGxlSW5pdGlhbFR5cGVEZXBlbmRlbmNpZXModGhpcy5jb21wb25lbnRGaWxlUGF0aClcbiAgfVxuXG4gIGFzeW5jIGFkZEVudHJ5cG9pbnQoKSB7XG4gICAgY29uc3QgcmVsYXRpdmVDb21wb25lbnRGaWxlUGF0aCA9IHBhdGgucmVsYXRpdmUoXG4gICAgICB0aGlzLnByb2plY3REaXIsXG4gICAgICB0aGlzLmNvbXBvbmVudEZpbGVQYXRoLFxuICAgIClcbiAgICBhd2FpdCB0aGlzLmZzS3kucG9zdChcImFwaS9maWxlcy91cHNlcnRcIiwge1xuICAgICAganNvbjoge1xuICAgICAgICBmaWxlX3BhdGg6IFwiZW50cnlwb2ludC50c3hcIixcbiAgICAgICAgdGV4dF9jb250ZW50OiBgXG5pbXBvcnQgTXlDaXJjdWl0IGZyb20gXCIuLyR7cmVsYXRpdmVDb21wb25lbnRGaWxlUGF0aH1cIlxuXG5jaXJjdWl0LmFkZCg8TXlDaXJjdWl0IC8+KVxuYCxcbiAgICAgIH0sXG4gICAgfSlcbiAgfVxuXG4gIGFzeW5jIGhhbmRsZUZpbGVVcGRhdGVkRXZlbnRGcm9tU2VydmVyKGV2OiBGaWxlVXBkYXRlZEV2ZW50KSB7XG4gICAgaWYgKGV2LmluaXRpYXRvciA9PT0gXCJmaWxlc3lzdGVtX2NoYW5nZVwiKSByZXR1cm5cblxuICAgIGlmIChldi5maWxlX3BhdGggPT09IFwibWFudWFsLWVkaXRzLmpzb25cIikge1xuICAgICAgY29uc29sZS5sb2coXCJNYW51YWwgZWRpdHMgdXBkYXRlZCwgdXBkYXRpbmcgb24gZmlsZXN5c3RlbS4uLlwiKVxuICAgICAgY29uc3QgeyBmaWxlIH0gPSBhd2FpdCB0aGlzLmZzS3lcbiAgICAgICAgLmdldChcImFwaS9maWxlcy9nZXRcIiwge1xuICAgICAgICAgIHNlYXJjaFBhcmFtczogeyBmaWxlX3BhdGg6IGV2LmZpbGVfcGF0aCB9LFxuICAgICAgICB9KVxuICAgICAgICAuanNvbigpXG4gICAgICBmcy53cml0ZUZpbGVTeW5jKFxuICAgICAgICBwYXRoLmpvaW4odGhpcy5wcm9qZWN0RGlyLCBcIm1hbnVhbC1lZGl0cy5qc29uXCIpLFxuICAgICAgICBmaWxlLnRleHRfY29udGVudCxcbiAgICAgIClcbiAgICB9XG4gIH1cblxuICBhc3luYyBoYW5kbGVGaWxlQ2hhbmdlZE9uRmlsZXN5c3RlbShhYnNvbHV0ZUZpbGVQYXRoOiBzdHJpbmcpIHtcbiAgICBjb25zdCByZWxhdGl2ZUZpbGVQYXRoID0gcGF0aC5yZWxhdGl2ZSh0aGlzLnByb2plY3REaXIsIGFic29sdXRlRmlsZVBhdGgpXG4gICAgLy8gV2UndmUgdGVtcG9yYXJpbHkgZGlzYWJsZWQgdXBzZXJ0aW5nIG1hbnVhbCBlZGl0cyBmcm9tIGZpbGVzeXN0ZW0gY2hhbmdlc1xuICAgIC8vIGJlY2F1c2UgaXQgY2FuIGJlIGVkaXRlZCBieSB0aGUgYnJvd3NlclxuICAgIGlmIChyZWxhdGl2ZUZpbGVQYXRoLmluY2x1ZGVzKFwibWFudWFsLWVkaXRzLmpzb25cIikpIHJldHVyblxuXG4gICAgYXdhaXQgdGhpcy50eXBlc0hhbmRsZXI/LmhhbmRsZUZpbGVUeXBlRGVwZW5kZW5jaWVzKGFic29sdXRlRmlsZVBhdGgpXG5cbiAgICBjb25zb2xlLmxvZyhgJHtyZWxhdGl2ZUZpbGVQYXRofSBzYXZlZC4gQXBwbHlpbmcgY2hhbmdlcy4uLmApXG4gICAgYXdhaXQgdGhpcy5mc0t5XG4gICAgICAucG9zdChcImFwaS9maWxlcy91cHNlcnRcIiwge1xuICAgICAgICBqc29uOiB7XG4gICAgICAgICAgZmlsZV9wYXRoOiByZWxhdGl2ZUZpbGVQYXRoLFxuICAgICAgICAgIHRleHRfY29udGVudDogZnMucmVhZEZpbGVTeW5jKGFic29sdXRlRmlsZVBhdGgsIFwidXRmLThcIiksXG4gICAgICAgICAgaW5pdGlhdG9yOiBcImZpbGVzeXN0ZW1fY2hhbmdlXCIsXG4gICAgICAgIH0sXG4gICAgICB9KVxuICAgICAgLmpzb24oKVxuICB9XG5cbiAgYXN5bmMgdXBzZXJ0SW5pdGlhbEZpbGVzKCkge1xuICAgIC8vIFNjYW4gcHJvamVjdCBkaXJlY3RvcnkgZm9yIGFsbCBmaWxlcyBhbmQgdXBzZXJ0IHRoZW1cbiAgICBjb25zdCBmaWxlTmFtZXMgPSBmcy5yZWFkZGlyU3luYyh0aGlzLnByb2plY3REaXIpXG4gICAgZm9yIChjb25zdCBmaWxlTmFtZSBvZiBmaWxlTmFtZXMpIHtcbiAgICAgIGlmIChmcy5zdGF0U3luYyhwYXRoLmpvaW4odGhpcy5wcm9qZWN0RGlyLCBmaWxlTmFtZSkpLmlzRGlyZWN0b3J5KCkpXG4gICAgICAgIGNvbnRpbnVlXG4gICAgICBjb25zdCBmaWxlQ29udGVudCA9IGZzLnJlYWRGaWxlU3luYyhcbiAgICAgICAgcGF0aC5qb2luKHRoaXMucHJvamVjdERpciwgZmlsZU5hbWUpLFxuICAgICAgICBcInV0Zi04XCIsXG4gICAgICApXG4gICAgICBhd2FpdCB0aGlzLmZzS3kucG9zdChcImFwaS9maWxlcy91cHNlcnRcIiwge1xuICAgICAgICBqc29uOiB7XG4gICAgICAgICAgZmlsZV9wYXRoOiBmaWxlTmFtZSxcbiAgICAgICAgICB0ZXh0X2NvbnRlbnQ6IGZpbGVDb250ZW50LFxuICAgICAgICAgIGluaXRpYXRvcjogXCJmaWxlc3lzdGVtX2NoYW5nZVwiLFxuICAgICAgICB9LFxuICAgICAgfSlcbiAgICB9XG4gIH1cblxuICBhc3luYyBzdG9wKCkge1xuICAgIHRoaXMuaHR0cFNlcnZlcj8uY2xvc2UoKVxuICAgIHRoaXMuZXZlbnRzV2F0Y2hlcj8uc3RvcCgpXG4gIH1cbn1cbiIsICJpbXBvcnQgKiBhcyBodHRwIGZyb20gXCJub2RlOmh0dHBcIlxuaW1wb3J0ICogYXMgZnMgZnJvbSBcIm5vZGU6ZnNcIlxuaW1wb3J0ICogYXMgcGF0aCBmcm9tIFwibm9kZTpwYXRoXCJcbmltcG9ydCB7IGdldE5vZGVIYW5kbGVyIH0gZnJvbSBcIndpbnRlcnNwZWMvYWRhcHRlcnMvbm9kZVwiXG5pbXBvcnQgcGtnIGZyb20gXCIuLi8uLi9wYWNrYWdlLmpzb25cIlxuXG4vLyBAdHMtaWdub3JlXG5pbXBvcnQgd2ludGVyc3BlY0J1bmRsZSBmcm9tIFwiQHRzY2lyY3VpdC9maWxlLXNlcnZlci9kaXN0L2J1bmRsZS5qc1wiXG5pbXBvcnQgeyBnZXRJbmRleCB9IGZyb20gXCIuLi9zaXRlL2dldEluZGV4XCJcblxuZXhwb3J0IGNvbnN0IGNyZWF0ZUh0dHBTZXJ2ZXIgPSBhc3luYyAocG9ydCA9IDMwMDApID0+IHtcbiAgY29uc3QgZmlsZVNlcnZlckhhbmRsZXIgPSBnZXROb2RlSGFuZGxlcih3aW50ZXJzcGVjQnVuZGxlIGFzIGFueSwge30pXG5cbiAgY29uc3Qgc2VydmVyID0gaHR0cC5jcmVhdGVTZXJ2ZXIoYXN5bmMgKHJlcSwgcmVzKSA9PiB7XG4gICAgY29uc3QgdXJsID0gbmV3IFVSTChyZXEudXJsISwgYGh0dHA6Ly8ke3JlcS5oZWFkZXJzLmhvc3R9YClcblxuICAgIGlmICh1cmwucGF0aG5hbWUgPT09IFwiL3N0YW5kYWxvbmUubWluLmpzXCIpIHtcbiAgICAgIGNvbnN0IHN0YW5kYWxvbmVGaWxlUGF0aCA9XG4gICAgICAgIHByb2Nlc3MuZW52LlJVTkZSQU1FX1NUQU5EQUxPTkVfRklMRV9QQVRIIHx8XG4gICAgICAgIHBhdGgucmVzb2x2ZShcbiAgICAgICAgICBwcm9jZXNzLmN3ZCgpLFxuICAgICAgICAgIFwibm9kZV9tb2R1bGVzXCIsXG4gICAgICAgICAgXCJAdHNjaXJjdWl0L3J1bmZyYW1lL2Rpc3Qvc3RhbmRhbG9uZS5taW4uanNcIixcbiAgICAgICAgKVxuXG4gICAgICB0cnkge1xuICAgICAgICBjb25zdCBjb250ZW50ID0gZnMucmVhZEZpbGVTeW5jKHN0YW5kYWxvbmVGaWxlUGF0aCwgXCJ1dGY4XCIpXG4gICAgICAgIHJlcy53cml0ZUhlYWQoMjAwLCB7XG4gICAgICAgICAgXCJDb250ZW50LVR5cGVcIjogXCJhcHBsaWNhdGlvbi9qYXZhc2NyaXB0OyBjaGFyc2V0PXV0Zi04XCIsXG4gICAgICAgIH0pXG4gICAgICAgIHJlcy5lbmQoY29udGVudClcbiAgICAgICAgcmV0dXJuXG4gICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICBjb25zb2xlLmVycm9yKFwiRXJyb3Igc2VydmluZyBzdGFuZGFsb25lLm1pbi5qczpcIiwgZXJyb3IpXG4gICAgICB9XG5cbiAgICAgIHJlcy53cml0ZUhlYWQoMzAyLCB7XG4gICAgICAgIExvY2F0aW9uOiBgaHR0cHM6Ly9jZG4uanNkZWxpdnIubmV0L25wbS9AdHNjaXJjdWl0L3J1bmZyYW1lQCR7cGtnLmRlcGVuZGVuY2llc1tcIkB0c2NpcmN1aXQvcnVuZnJhbWVcIl0ucmVwbGFjZSgvXlteMC05XSsvLCBcIlwiKX0vZGlzdC9zdGFuZGFsb25lLm1pbi5qc2AsXG4gICAgICB9KVxuICAgICAgcmVzLmVuZCgpXG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICBpZiAodXJsLnBhdGhuYW1lID09PSBcIi9cIikge1xuICAgICAgY29uc3QgaHRtbCA9IGF3YWl0IGdldEluZGV4KClcbiAgICAgIHJlcy53cml0ZUhlYWQoMjAwLCB7IFwiQ29udGVudC1UeXBlXCI6IFwidGV4dC9odG1sXCIgfSlcbiAgICAgIHJlcy5lbmQoaHRtbClcbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIGlmICh1cmwucGF0aG5hbWUuc3RhcnRzV2l0aChcIi9hcGkvXCIpKSB7XG4gICAgICByZXEudXJsID0gcmVxLnVybCEucmVwbGFjZShcIi9hcGkvXCIsIFwiL1wiKVxuICAgICAgZmlsZVNlcnZlckhhbmRsZXIocmVxLCByZXMpXG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICByZXMud3JpdGVIZWFkKDQwNClcbiAgICByZXMuZW5kKFwiTm90IGZvdW5kXCIpXG4gIH0pXG5cbiAgcmV0dXJuIG5ldyBQcm9taXNlPHsgc2VydmVyOiBodHRwLlNlcnZlciB9PigocmVzb2x2ZSkgPT4ge1xuICAgIHNlcnZlci5saXN0ZW4ocG9ydCwgKCkgPT4ge1xuICAgICAgY29uc29sZS5sb2coYFNlcnZlciBydW5uaW5nIGF0IGh0dHA6Ly9sb2NhbGhvc3Q6JHtwb3J0fWApXG4gICAgICByZXNvbHZlKHsgc2VydmVyIH0pXG4gICAgfSlcbiAgfSlcbn1cbiIsICJ7XG4gIFwibmFtZVwiOiBcIkB0c2NpcmN1aXQvY2xpXCIsXG4gIFwibWFpblwiOiBcImRpc3QvbWFpbi5qc1wiLFxuICBcInR5cGVcIjogXCJtb2R1bGVcIixcbiAgXCJ2ZXJzaW9uXCI6IFwiMC4xLjE2XCIsXG4gIFwiYmluXCI6IHtcbiAgICBcInRzY2lcIjogXCIuL2Rpc3QvbWFpbi5qc1wiXG4gIH0sXG4gIFwic2NyaXB0c1wiOiB7XG4gICAgXCJzdGFydFwiOiBcImJ1biBydW4gZGV2XCIsXG4gICAgXCJkZXZcIjogXCJidW4gLS1ob3QgLi9jbGkvbWFpbi50cyBkZXYgLi9leGFtcGxlLWRpci9zbmlwcGV0MS1iYXNpYy50c3hcIixcbiAgICBcImJ1aWxkXCI6IFwidHN1cC1ub2RlIGNsaS9tYWluLnRzIC0tZm9ybWF0IGVzbSAtLXNvdXJjZW1hcCBpbmxpbmVcIixcbiAgICBcImZvcm1hdFwiOiBcImJpb21lIGZvcm1hdCAtLXdyaXRlIC5cIixcbiAgICBcImZvcm1hdDpjaGVja1wiOiBcImJpb21lIGZvcm1hdCAuXCIsXG4gICAgXCJjbGlcIjogXCJidW4gLi9jbGkvbWFpbi50c1wiXG4gIH0sXG4gIFwiZGV2RGVwZW5kZW5jaWVzXCI6IHtcbiAgICBcIkBiaW9tZWpzL2Jpb21lXCI6IFwiXjEuOS40XCIsXG4gICAgXCJAdHNjaXJjdWl0L2NvcmVcIjogXCJeMC4wLjI0OVwiLFxuICAgIFwiQHR5cGVzL2J1blwiOiBcIl4xLjEuMTVcIixcbiAgICBcIkB0eXBlcy9jb25maWdzdG9yZVwiOiBcIl42LjAuMlwiLFxuICAgIFwiQHR5cGVzL3JlYWN0XCI6IFwiXjE5LjAuMVwiLFxuICAgIFwiQHR5cGVzL3NlbXZlclwiOiBcIl43LjUuOFwiLFxuICAgIFwiZ2V0LXBvcnRcIjogXCJeNy4xLjBcIixcbiAgICBcInRlbXB5XCI6IFwiXjMuMS4wXCIsXG4gICAgXCJ0c3VwXCI6IFwiXjguMy41XCIsXG4gICAgXCJ0eXBlZC1reVwiOiBcIl4wLjAuNFwiXG4gIH0sXG4gIFwicGVlckRlcGVuZGVuY2llc1wiOiB7XG4gICAgXCJ0eXBlc2NyaXB0XCI6IFwiXjUuMC4wXCJcbiAgfSxcbiAgXCJkZXBlbmRlbmNpZXNcIjoge1xuICAgIFwiQHRzY2lyY3VpdC9maWxlLXNlcnZlclwiOiBcIl4wLjAuMTNcIixcbiAgICBcIkB0c2NpcmN1aXQvcnVuZnJhbWVcIjogXCJeMC4wLjQ3XCIsXG4gICAgXCJjaG9raWRhclwiOiBcIl40LjAuMVwiLFxuICAgIFwiY29tbWFuZGVyXCI6IFwiXjEyLjEuMFwiLFxuICAgIFwiY29uZmlnc3RvcmVcIjogXCJeNy4wLjBcIixcbiAgICBcImNvc21pY29uZmlnXCI6IFwiXjkuMC4wXCIsXG4gICAgXCJkZWxheVwiOiBcIl42LjAuMFwiLFxuICAgIFwia3lcIjogXCJeMS43LjRcIixcbiAgICBcIm1ha2UtdmZzXCI6IFwiXjEuMC4xNVwiLFxuICAgIFwicGVyZmVjdC1jbGlcIjogXCJeMS4wLjIwXCIsXG4gICAgXCJzZW12ZXJcIjogXCJeNy42LjNcIlxuICB9XG59XG4iLCAiaW1wb3J0IHBrZyBmcm9tIFwiLi4vLi4vcGFja2FnZS5qc29uXCJcblxuZXhwb3J0IGNvbnN0IGdldEluZGV4ID0gYXN5bmMgKCkgPT4ge1xuICByZXR1cm4gYDxodG1sPlxuICAgIDxoZWFkPlxuICAgIDwvaGVhZD5cbiAgICA8Ym9keT5cbiAgICAgIDxzY3JpcHQgc3JjPVwiaHR0cHM6Ly9jZG4udGFpbHdpbmRjc3MuY29tXCI+PC9zY3JpcHQ+XG4gICAgICA8ZGl2IGlkPVwicm9vdFwiPmxvYWRpbmcuLi48L2Rpdj5cbiAgICAgIDxzY3JpcHQ+XG4gICAgICBnbG9iYWxUaGlzLnByb2Nlc3MgPSB7IGVudjogeyBOT0RFX0VOVjogXCJwcm9kdWN0aW9uXCIgfSB9XG4gICAgICA8L3NjcmlwdD5cbiAgICAgIDxzY3JpcHQgc3JjPVwiL3N0YW5kYWxvbmUubWluLmpzXCI+PC9zY3JpcHQ+XG4gICAgPC9ib2R5PlxuICA8L2h0bWw+YFxufVxuXG4vLyA8c2NyaXB0IHNyYz1cImh0dHBzOi8vY2RuLmpzZGVsaXZyLm5ldC9ucG0vQHRzY2lyY3VpdC9ydW5mcmFtZUAke3BrZy5kZXBlbmRlbmNpZXNbXCJAdHNjaXJjdWl0L3J1bmZyYW1lXCJdLnJlcGxhY2UoL15bXjAtOV0rLywgXCJcIil9L2Rpc3Qvc3RhbmRhbG9uZS5taW4uanNcIj48L3NjcmlwdD5cbiIsICJpbXBvcnQgeyBFdmVudEVtaXR0ZXIgfSBmcm9tIFwiZXZlbnRzXCJcblxuaW50ZXJmYWNlIEV2ZW50IHtcbiAgZXZlbnRfaWQ6IHN0cmluZ1xuICBjcmVhdGVkX2F0OiBzdHJpbmdcbiAgZXZlbnRfdHlwZTogc3RyaW5nXG4gIFtrZXk6IHN0cmluZ106IGFueVxufVxuXG5pbnRlcmZhY2UgRXZlbnRzUmVzcG9uc2Uge1xuICBldmVudF9saXN0OiBFdmVudFtdXG59XG5cbmV4cG9ydCBjbGFzcyBFdmVudHNXYXRjaGVyIGV4dGVuZHMgRXZlbnRFbWl0dGVyIHtcbiAgcHJpdmF0ZSBsYXN0UG9sbFRpbWU6IHN0cmluZ1xuICBwcml2YXRlIHBvbGxJbnRlcnZhbDogbnVtYmVyXG4gIHByaXZhdGUgYmFzZVVybDogc3RyaW5nXG4gIHByaXZhdGUgcG9sbGluZyA9IGZhbHNlXG4gIHByaXZhdGUgdGltZW91dElkPzogTm9kZUpTLlRpbWVvdXRcblxuICBjb25zdHJ1Y3RvcihiYXNlVXJsID0gXCJodHRwOi8vbG9jYWxob3N0OjMwMDBcIiwgcG9sbEludGVydmFsID0gMTAwMCkge1xuICAgIHN1cGVyKClcbiAgICB0aGlzLmJhc2VVcmwgPSBiYXNlVXJsXG4gICAgdGhpcy5wb2xsSW50ZXJ2YWwgPSBwb2xsSW50ZXJ2YWxcbiAgICB0aGlzLmxhc3RQb2xsVGltZSA9IG5ldyBEYXRlKCkudG9JU09TdHJpbmcoKVxuICB9XG5cbiAgYXN5bmMgc3RhcnQoKSB7XG4gICAgaWYgKHRoaXMucG9sbGluZykgcmV0dXJuXG4gICAgdGhpcy5wb2xsaW5nID0gdHJ1ZVxuICAgIGF3YWl0IHRoaXMucG9sbCgpXG4gIH1cblxuICBzdG9wKCkge1xuICAgIHRoaXMucG9sbGluZyA9IGZhbHNlXG4gICAgaWYgKHRoaXMudGltZW91dElkKSB7XG4gICAgICBjbGVhclRpbWVvdXQodGhpcy50aW1lb3V0SWQpXG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBwb2xsKCkge1xuICAgIGlmICghdGhpcy5wb2xsaW5nKSByZXR1cm5cblxuICAgIHRyeSB7XG4gICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGZldGNoKFxuICAgICAgICBgJHt0aGlzLmJhc2VVcmx9L2FwaS9ldmVudHMvbGlzdD9zaW5jZT0ke2VuY29kZVVSSUNvbXBvbmVudCh0aGlzLmxhc3RQb2xsVGltZSl9YCxcbiAgICAgIClcblxuICAgICAgaWYgKCFyZXNwb25zZS5vaykge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEhUVFAgZXJyb3IhIHN0YXR1czogJHtyZXNwb25zZS5zdGF0dXN9YClcbiAgICAgIH1cblxuICAgICAgY29uc3QgZGF0YTogRXZlbnRzUmVzcG9uc2UgPSBhd2FpdCByZXNwb25zZS5qc29uKClcblxuICAgICAgLy8gVXBkYXRlIGxhc3QgcG9sbCB0aW1lIHRvIGxhdGVzdCBldmVudCBvciBjdXJyZW50IHRpbWVcbiAgICAgIGNvbnN0IGxhdGVzdEV2ZW50ID0gZGF0YS5ldmVudF9saXN0W2RhdGEuZXZlbnRfbGlzdC5sZW5ndGggLSAxXVxuICAgICAgdGhpcy5sYXN0UG9sbFRpbWUgPSBsYXRlc3RFdmVudFxuICAgICAgICA/IGxhdGVzdEV2ZW50LmNyZWF0ZWRfYXRcbiAgICAgICAgOiBuZXcgRGF0ZSgpLnRvSVNPU3RyaW5nKClcblxuICAgICAgLy8gRW1pdCBldmVudHMgaW4gY2hyb25vbG9naWNhbCBvcmRlclxuICAgICAgZGF0YS5ldmVudF9saXN0LmZvckVhY2goKGV2ZW50KSA9PiB7XG4gICAgICAgIHRoaXMuZW1pdChldmVudC5ldmVudF90eXBlLCBldmVudClcbiAgICAgICAgdGhpcy5lbWl0KFwiKlwiLCBldmVudClcbiAgICAgIH0pXG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIHRoaXMuZW1pdChcImVycm9yXCIsIGVycm9yKVxuICAgIH1cbiAgICAvLyBTY2hlZHVsZSBuZXh0IHBvbGxcbiAgICB0aGlzLnRpbWVvdXRJZCA9IGdsb2JhbFRoaXMuc2V0VGltZW91dChcbiAgICAgICgpID0+IHRoaXMucG9sbCgpLFxuICAgICAgdGhpcy5wb2xsSW50ZXJ2YWwsXG4gICAgKSBhcyB1bmtub3duIGFzIE5vZGVKUy5UaW1lb3V0XG4gIH1cbn1cbiIsICJpbXBvcnQgKiBhcyBmcyBmcm9tIFwibm9kZTpmc1wiXG5pbXBvcnQgKiBhcyBwYXRoIGZyb20gXCJub2RlOnBhdGhcIlxuaW1wb3J0IHsgZmluZEltcG9ydHNJblNuaXBwZXQgfSBmcm9tIFwiLi9maW5kSW1wb3J0c0luU25pcHBldFwiXG5pbXBvcnQgeyBpbnN0YWxsTm9kZU1vZHVsZVR5cGVzRm9yU25pcHBldCB9IGZyb20gXCIuL2luc3RhbGxOb2RlTW9kdWxlVHlwZXNGb3JTbmlwcGV0XCJcblxuZXhwb3J0IGNsYXNzIEZpbGVzeXN0ZW1UeXBlc0hhbmRsZXIge1xuICBwcml2YXRlIHByb2plY3RSb290OiBzdHJpbmdcblxuICBjb25zdHJ1Y3Rvcihpbml0aWFsRGlyOiBzdHJpbmcpIHtcbiAgICB0aGlzLnByb2plY3RSb290ID0gdGhpcy5maW5kUHJvamVjdFJvb3QoaW5pdGlhbERpcilcbiAgfVxuXG4gIGFzeW5jIGhhbmRsZUluaXRpYWxUeXBlRGVwZW5kZW5jaWVzKGZpbGVQYXRoOiBzdHJpbmcpIHtcbiAgICBjb25zb2xlLmxvZyhcIkNoZWNraW5nIGluaXRpYWwgdHlwZSBkZXBlbmRlbmNpZXMuLi5cIilcbiAgICB0cnkge1xuICAgICAgaWYgKCF0aGlzLmFyZVR5cGVzSW5zdGFsbGVkKGZpbGVQYXRoKSkge1xuICAgICAgICBjb25zb2xlLmxvZyhcIkluc3RhbGxpbmcgbWlzc2luZyBpbml0aWFsIHR5cGVzLi4uXCIpXG4gICAgICAgIGF3YWl0IGluc3RhbGxOb2RlTW9kdWxlVHlwZXNGb3JTbmlwcGV0KGZpbGVQYXRoKVxuICAgICAgfVxuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBjb25zb2xlLndhcm4oXCJFcnJvciBoYW5kbGluZyBpbml0aWFsIHR5cGUgZGVwZW5kZW5jaWVzOlwiLCBlcnJvcilcbiAgICB9XG4gIH1cblxuICBhc3luYyBoYW5kbGVGaWxlVHlwZURlcGVuZGVuY2llcyhmaWxlUGF0aDogc3RyaW5nKSB7XG4gICAgdHJ5IHtcbiAgICAgIGlmICghdGhpcy5hcmVUeXBlc0luc3RhbGxlZChmaWxlUGF0aCkpIHtcbiAgICAgICAgY29uc29sZS5sb2coXCJJbnN0YWxsaW5nIG1pc3NpbmcgZmlsZSB0eXBlcy4uLlwiKVxuICAgICAgICBhd2FpdCBpbnN0YWxsTm9kZU1vZHVsZVR5cGVzRm9yU25pcHBldChmaWxlUGF0aClcbiAgICAgIH1cbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgY29uc29sZS53YXJuKFwiRmFpbGVkIHRvIHZlcmlmeSB0eXBlczpcIiwgZXJyb3IpXG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBhcmVUeXBlc0luc3RhbGxlZChmaWxlUGF0aDogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgY29uc3QgaW1wb3J0cyA9IGZpbmRJbXBvcnRzSW5TbmlwcGV0KGZpbGVQYXRoKVxuICAgIHJldHVybiBpbXBvcnRzLmV2ZXJ5KChpbXApID0+IHRoaXMuY2hlY2tUeXBlRXhpc3RzKGltcCkpXG4gIH1cblxuICBwcml2YXRlIGNoZWNrVHlwZUV4aXN0cyhpbXBvcnRQYXRoOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICBpZiAoIWltcG9ydFBhdGguc3RhcnRzV2l0aChcIkB0c2NpL1wiKSkgcmV0dXJuIHRydWVcblxuICAgIGNvbnN0IHBhdGhXaXRob3V0UHJlZml4ID0gaW1wb3J0UGF0aC5yZXBsYWNlKFwiQHRzY2kvXCIsIFwiXCIpXG4gICAgY29uc3QgW293bmVyLCBuYW1lXSA9IHBhdGhXaXRob3V0UHJlZml4LnNwbGl0KFwiLlwiKVxuXG4gICAgY29uc3QgdHlwZVBhdGggPSBwYXRoLmpvaW4oXG4gICAgICB0aGlzLnByb2plY3RSb290LFxuICAgICAgXCJub2RlX21vZHVsZXNcIixcbiAgICAgIFwiQHRzY2lcIixcbiAgICAgIGAke293bmVyfS4ke25hbWV9YCxcbiAgICAgIFwiaW5kZXguZC50c1wiLFxuICAgIClcblxuICAgIHJldHVybiBmcy5leGlzdHNTeW5jKHR5cGVQYXRoKVxuICB9XG5cbiAgcHJpdmF0ZSBmaW5kUHJvamVjdFJvb3Qoc3RhcnREaXI6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgbGV0IHJvb3QgPSBwYXRoLnJlc29sdmUoc3RhcnREaXIpXG4gICAgd2hpbGUgKHJvb3QgIT09IHBhdGgucGFyc2Uocm9vdCkucm9vdCkge1xuICAgICAgaWYgKGZzLmV4aXN0c1N5bmMocGF0aC5qb2luKHJvb3QsIFwicGFja2FnZS5qc29uXCIpKSkge1xuICAgICAgICByZXR1cm4gcm9vdFxuICAgICAgfVxuICAgICAgcm9vdCA9IHBhdGguZGlybmFtZShyb290KVxuICAgIH1cbiAgICByZXR1cm4gc3RhcnREaXJcbiAgfVxufVxuIiwgImltcG9ydCAqIGFzIGZzIGZyb20gXCJub2RlOmZzXCJcbmltcG9ydCAqIGFzIHRzIGZyb20gXCJ0eXBlc2NyaXB0XCJcblxuZXhwb3J0IGZ1bmN0aW9uIGZpbmRJbXBvcnRzSW5TbmlwcGV0KHNuaXBwZXRQYXRoOiBzdHJpbmcpOiBzdHJpbmdbXSB7XG4gIGNvbnN0IGNvbnRlbnQgPSBmcy5yZWFkRmlsZVN5bmMoc25pcHBldFBhdGgsIFwidXRmLThcIilcbiAgY29uc3Qgc291cmNlRmlsZSA9IHRzLmNyZWF0ZVNvdXJjZUZpbGUoXG4gICAgc25pcHBldFBhdGgsXG4gICAgY29udGVudCxcbiAgICB0cy5TY3JpcHRUYXJnZXQuTGF0ZXN0LFxuICAgIHRydWUsXG4gIClcblxuICBjb25zdCBpbXBvcnRzOiBzdHJpbmdbXSA9IFtdXG5cbiAgZnVuY3Rpb24gdmlzaXQobm9kZTogdHMuTm9kZSkge1xuICAgIGlmICh0cy5pc0ltcG9ydERlY2xhcmF0aW9uKG5vZGUpKSB7XG4gICAgICBjb25zdCBtb2R1bGVTcGVjaWZpZXIgPSBub2RlLm1vZHVsZVNwZWNpZmllclxuICAgICAgaWYgKG1vZHVsZVNwZWNpZmllciAmJiB0cy5pc1N0cmluZ0xpdGVyYWwobW9kdWxlU3BlY2lmaWVyKSkge1xuICAgICAgICBjb25zdCBpbXBvcnRQYXRoID0gbW9kdWxlU3BlY2lmaWVyLnRleHRcbiAgICAgICAgaWYgKGltcG9ydFBhdGguc3RhcnRzV2l0aChcIkB0c2NpL1wiKSkge1xuICAgICAgICAgIGltcG9ydHMucHVzaChpbXBvcnRQYXRoKVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICAgIHRzLmZvckVhY2hDaGlsZChub2RlLCB2aXNpdClcbiAgfVxuXG4gIHZpc2l0KHNvdXJjZUZpbGUpXG5cbiAgcmV0dXJuIGltcG9ydHNcbn1cbiIsICJpbXBvcnQgQ29uZmlnc3RvcmUgZnJvbSBcImNvbmZpZ3N0b3JlXCJcbmltcG9ydCB0eXBlIHsgVHlwZWRDb25maWdzdG9yZSB9IGZyb20gXCIuL1R5cGVkQ29uZmlnU3RvcmVcIlxuXG5leHBvcnQgaW50ZXJmYWNlIENsaUNvbmZpZyB7XG4gIHNlc3Npb25Ub2tlbj86IHN0cmluZ1xuICBnaXRodWJVc2VybmFtZT86IHN0cmluZ1xuICByZWdpc3RyeUFwaVVybD86IHN0cmluZ1xufVxuXG5leHBvcnQgY29uc3QgY2xpQ29uZmlnOiBUeXBlZENvbmZpZ3N0b3JlPENsaUNvbmZpZz4gPSBuZXcgQ29uZmlnc3RvcmUoXG4gIFwidHNjaXJjdWl0XCIsXG4pXG5cbmV4cG9ydCBjb25zdCBnZXRSZWdpc3RyeUFwaVVybCA9ICgpOiBzdHJpbmcgPT4ge1xuICByZXR1cm4gY2xpQ29uZmlnLmdldChcInJlZ2lzdHJ5QXBpVXJsXCIpID8/IFwiaHR0cHM6Ly9yZWdpc3RyeS1hcGkudHNjaXJjdWl0LmNvbVwiXG59XG4iLCAiaW1wb3J0IHR5cGUgeyBDb21tYW5kIH0gZnJvbSBcImNvbW1hbmRlclwiXG5pbXBvcnQgeyBjbGlDb25maWcgfSBmcm9tIFwibGliL2NsaS1jb25maWdcIlxuaW1wb3J0IGRlbGF5IGZyb20gXCJkZWxheVwiXG5pbXBvcnQgeyBnZXRLeSB9IGZyb20gXCJsaWIvcmVnaXN0cnktYXBpL2dldC1reVwiXG5pbXBvcnQgdHlwZSB7IEVuZHBvaW50UmVzcG9uc2UgfSBmcm9tIFwibGliL3JlZ2lzdHJ5LWFwaS9lbmRwb2ludC10eXBlc1wiXG5cbmV4cG9ydCBjb25zdCByZWdpc3RlckF1dGhMb2dpbiA9IChwcm9ncmFtOiBDb21tYW5kKSA9PiB7XG4gIC8vIERlZmluZSB0aGUgbG9naW4gYWN0aW9uIG9uY2UgdG8gc2hhcmUgYmV0d2VlbiBib3RoIGNvbW1hbmRzXG4gIGNvbnN0IGxvZ2luQWN0aW9uID0gYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IGt5ID0gZ2V0S3koKVxuXG4gICAgY29uc3QgeyBsb2dpbl9wYWdlIH0gPSBhd2FpdCBreVxuICAgICAgLnBvc3Q8RW5kcG9pbnRSZXNwb25zZVtcInNlc3Npb25zL2xvZ2luX3BhZ2UvY3JlYXRlXCJdPihcbiAgICAgICAgXCJzZXNzaW9ucy9sb2dpbl9wYWdlL2NyZWF0ZVwiLFxuICAgICAgICB7XG4gICAgICAgICAganNvbjoge30sXG4gICAgICAgIH0sXG4gICAgICApXG4gICAgICAuanNvbigpXG5cbiAgICBjb25zb2xlLmxvZyhcIlBsZWFzZSB2aXNpdCB0aGUgZm9sbG93aW5nIFVSTCB0byBsb2cgaW46XCIpXG4gICAgY29uc29sZS5sb2cobG9naW5fcGFnZS51cmwpXG5cbiAgICAvLyBXYWl0IHVudGlsIHdlIHJlY2VpdmUgY29uZmlybWF0aW9uXG4gICAgd2hpbGUgKHRydWUpIHtcbiAgICAgIGNvbnN0IHsgbG9naW5fcGFnZTogbmV3X2xvZ2luX3BhZ2UgfSA9IGF3YWl0IGt5XG4gICAgICAgIC5wb3N0PEVuZHBvaW50UmVzcG9uc2VbXCJzZXNzaW9ucy9sb2dpbl9wYWdlL2dldFwiXT4oXG4gICAgICAgICAgXCJzZXNzaW9ucy9sb2dpbl9wYWdlL2dldFwiLFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIGpzb246IHtcbiAgICAgICAgICAgICAgbG9naW5fcGFnZV9pZDogbG9naW5fcGFnZS5sb2dpbl9wYWdlX2lkLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGhlYWRlcnM6IHtcbiAgICAgICAgICAgICAgQXV0aG9yaXphdGlvbjogYEJlYXJlciAke2xvZ2luX3BhZ2UubG9naW5fcGFnZV9hdXRoX3Rva2VufWAsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0sXG4gICAgICAgIClcbiAgICAgICAgLmpzb24oKVxuXG4gICAgICBpZiAobmV3X2xvZ2luX3BhZ2Uud2FzX2xvZ2luX3N1Y2Nlc3NmdWwpIHtcbiAgICAgICAgY29uc29sZS5sb2coXCJMb2dnZWQgaW4hIEdlbmVyYXRpbmcgdG9rZW4uLi5cIilcbiAgICAgICAgYnJlYWtcbiAgICAgIH1cblxuICAgICAgaWYgKG5ld19sb2dpbl9wYWdlLmlzX2V4cGlyZWQpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiTG9naW4gcGFnZSBleHBpcmVkXCIpXG4gICAgICB9XG5cbiAgICAgIGF3YWl0IGRlbGF5KDEwMDApXG4gICAgfVxuXG4gICAgY29uc3QgeyBzZXNzaW9uIH0gPSBhd2FpdCBreVxuICAgICAgLnBvc3Q8RW5kcG9pbnRSZXNwb25zZVtcInNlc3Npb25zL2xvZ2luX3BhZ2UvZXhjaGFuZ2VfZm9yX2NsaV9zZXNzaW9uXCJdPihcbiAgICAgICAgXCJzZXNzaW9ucy9sb2dpbl9wYWdlL2V4Y2hhbmdlX2Zvcl9jbGlfc2Vzc2lvblwiLFxuICAgICAgICB7XG4gICAgICAgICAganNvbjoge1xuICAgICAgICAgICAgbG9naW5fcGFnZV9pZDogbG9naW5fcGFnZS5sb2dpbl9wYWdlX2lkLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgaGVhZGVyczoge1xuICAgICAgICAgICAgQXV0aG9yaXphdGlvbjogYEJlYXJlciAke2xvZ2luX3BhZ2UubG9naW5fcGFnZV9hdXRoX3Rva2VufWAsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICAgIClcbiAgICAgIC5qc29uKClcblxuICAgIGNsaUNvbmZpZy5zZXQoXCJzZXNzaW9uVG9rZW5cIiwgc2Vzc2lvbi50b2tlbilcblxuICAgIGNvbnNvbGUubG9nKFwiUmVhZHkgdG8gdXNlIVwiKVxuICB9XG5cbiAgLy8gUmVnaXN0ZXIgdGhlIGF1dGggbG9naW4gc3ViY29tbWFuZFxuICBwcm9ncmFtLmNvbW1hbmRzXG4gICAgLmZpbmQoKGMpID0+IGMubmFtZSgpID09PSBcImF1dGhcIikhXG4gICAgLmNvbW1hbmQoXCJsb2dpblwiKVxuICAgIC5kZXNjcmlwdGlvbihcIkF1dGhlbnRpY2F0ZSBDTEksIGxvZ2luIHRvIHJlZ2lzdHJ5XCIpXG4gICAgLmFjdGlvbihsb2dpbkFjdGlvbilcblxuICAvLyBSZWdpc3RlciB0aGUgdG9wLWxldmVsIGxvZ2luIGNvbW1hbmQgYXMgYW4gYWxpYXNcbiAgcHJvZ3JhbVxuICAgIC5jb21tYW5kKFwibG9naW5cIilcbiAgICAuZGVzY3JpcHRpb24oXCJMb2dpbiB0byB0c2NpcmN1aXQgcmVnaXN0cnlcIilcbiAgICAuYWN0aW9uKGxvZ2luQWN0aW9uKVxufVxuIiwgImltcG9ydCB7IGdldFJlZ2lzdHJ5QXBpVXJsIH0gZnJvbSBcImxpYi9jbGktY29uZmlnXCJcbmltcG9ydCBreSwgeyB0eXBlIEFmdGVyUmVzcG9uc2VIb29rIH0gZnJvbSBcImt5XCJcblxuY29uc3QgcHJldHR5UmVzcG9uc2VFcnJvckhvb2s6IEFmdGVyUmVzcG9uc2VIb29rID0gYXN5bmMgKFxuICBfcmVxdWVzdCxcbiAgX29wdGlvbnMsXG4gIHJlc3BvbnNlLFxuKSA9PiB7XG4gIGlmICghcmVzcG9uc2Uub2spIHtcbiAgICB0cnkge1xuICAgICAgY29uc3QgZXJyb3JEYXRhID0gYXdhaXQgcmVzcG9uc2UuanNvbigpXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgIGBGQUlMIFske3Jlc3BvbnNlLnN0YXR1c31dOiAke19yZXF1ZXN0Lm1ldGhvZH0gJHtcbiAgICAgICAgICBuZXcgVVJMKF9yZXF1ZXN0LnVybCkucGF0aG5hbWVcbiAgICAgICAgfSBcXG5cXG4gJHtKU09OLnN0cmluZ2lmeShlcnJvckRhdGEsIG51bGwsIDIpfWAsXG4gICAgICApXG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgLy9pZ25vcmUsIGFsbG93IHRoZSBlcnJvciB0byBiZSB0aHJvd25cbiAgICB9XG4gIH1cbn1cblxuZXhwb3J0IGNvbnN0IGdldEt5ID0gKCkgPT4ge1xuICByZXR1cm4ga3kuY3JlYXRlKHtcbiAgICBwcmVmaXhVcmw6IGdldFJlZ2lzdHJ5QXBpVXJsKCksXG4gICAgaG9va3M6IHtcbiAgICAgIGFmdGVyUmVzcG9uc2U6IFtwcmV0dHlSZXNwb25zZUVycm9ySG9va10sXG4gICAgfSxcbiAgfSlcbn1cbiIsICJpbXBvcnQgdHlwZSB7IENvbW1hbmQgfSBmcm9tIFwiY29tbWFuZGVyXCJcblxuZXhwb3J0IGNvbnN0IHJlZ2lzdGVyQXV0aExvZ291dCA9IChwcm9ncmFtOiBDb21tYW5kKSA9PiB7XG4gIHByb2dyYW0uY29tbWFuZHNcbiAgICAuZmluZCgoYykgPT4gYy5uYW1lKCkgPT09IFwiYXV0aFwiKSFcbiAgICAuY29tbWFuZChcImxvZ291dFwiKVxuICAgIC5kZXNjcmlwdGlvbihcIkxvZ291dCBmcm9tIHJlZ2lzdHJ5XCIpXG4gICAgLmFjdGlvbigoYXJncykgPT4ge1xuICAgICAgY29uc29sZS5sb2coXCJsb2dvdXRcIilcbiAgICB9KVxufVxuIiwgImltcG9ydCB0eXBlIHsgQ29tbWFuZCB9IGZyb20gXCJjb21tYW5kZXJcIlxuXG5leHBvcnQgY29uc3QgcmVnaXN0ZXJBdXRoID0gKHByb2dyYW06IENvbW1hbmQpID0+IHtcbiAgcHJvZ3JhbS5jb21tYW5kKFwiYXV0aFwiKS5kZXNjcmlwdGlvbihcIkxvZ2luL2xvZ291dFwiKVxufVxuIiwgImltcG9ydCB0eXBlIHsgQ29tbWFuZCB9IGZyb20gXCJjb21tYW5kZXJcIlxuXG5leHBvcnQgY29uc3QgcmVnaXN0ZXJDb25maWcgPSAocHJvZ3JhbTogQ29tbWFuZCkgPT4ge1xuICBwcm9ncmFtLmNvbW1hbmQoXCJjb25maWdcIikuZGVzY3JpcHRpb24oXCJNYW5hZ2UgdHNjaXJjdWl0IENMSSBjb25maWd1cmF0aW9uXCIpXG59XG4iLCAiaW1wb3J0IHR5cGUgeyBDb21tYW5kIH0gZnJvbSBcImNvbW1hbmRlclwiXG5pbXBvcnQgeyBjbGlDb25maWcgfSBmcm9tIFwibGliL2NsaS1jb25maWdcIlxuXG5leHBvcnQgY29uc3QgcmVnaXN0ZXJDb25maWdQcmludCA9IChwcm9ncmFtOiBDb21tYW5kKSA9PiB7XG4gIHByb2dyYW0uY29tbWFuZHNcbiAgICAuZmluZCgoYykgPT4gYy5uYW1lKCkgPT09IFwiY29uZmlnXCIpIVxuICAgIC5jb21tYW5kKFwicHJpbnRcIilcbiAgICAuZGVzY3JpcHRpb24oXCJQcmludCB0aGUgY3VycmVudCBjb25maWdcIilcbiAgICAuYWN0aW9uKCgpID0+IHtcbiAgICAgIGNvbnNvbGUubG9nKEpTT04uc3RyaW5naWZ5KGNsaUNvbmZpZy5hbGwsIG51bGwsIDIpKVxuICAgIH0pXG59XG4iLCAiaW1wb3J0IHR5cGUgeyBDb21tYW5kIH0gZnJvbSBcImNvbW1hbmRlclwiXG5pbXBvcnQgeyBnZXRLeSB9IGZyb20gXCJsaWIvcmVnaXN0cnktYXBpL2dldC1reVwiXG5pbXBvcnQgKiBhcyBmcyBmcm9tIFwibm9kZTpmc1wiXG5pbXBvcnQgKiBhcyBwYXRoIGZyb20gXCJub2RlOnBhdGhcIlxuXG5leHBvcnQgY29uc3QgcmVnaXN0ZXJDbG9uZSA9IChwcm9ncmFtOiBDb21tYW5kKSA9PiB7XG4gIHByb2dyYW1cbiAgICAuY29tbWFuZChcImNsb25lXCIpXG4gICAgLmRlc2NyaXB0aW9uKFwiQ2xvbmUgYSBzbmlwcGV0IGZyb20gdGhlIHJlZ2lzdHJ5XCIpXG4gICAgLmFyZ3VtZW50KFwiPHNuaXBwZXQ+XCIsIFwiU25pcHBldCB0byBjbG9uZSAoZS5nLiBhdXRob3Ivc25pcHBldE5hbWUpXCIpXG4gICAgLmFjdGlvbihhc3luYyAoc25pcHBldFBhdGg6IHN0cmluZykgPT4ge1xuICAgICAgbGV0IGF1dGhvcjogc3RyaW5nXG4gICAgICBsZXQgc25pcHBldE5hbWU6IHN0cmluZ1xuICAgICAgaWYgKCFzbmlwcGV0UGF0aC5zdGFydHNXaXRoKFwiQHRzY2kvXCIpICYmIHNuaXBwZXRQYXRoLmluY2x1ZGVzKFwiL1wiKSkge1xuICAgICAgICA7W2F1dGhvciwgc25pcHBldE5hbWVdID0gc25pcHBldFBhdGguc3BsaXQoXCIvXCIpXG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjb25zdCB0cmltbWVkUGF0aCA9IHNuaXBwZXRQYXRoLnJlcGxhY2UoXCJAdHNjaS9cIiwgXCJcIilcbiAgICAgICAgY29uc3QgZmlyc3REb3RJbmRleCA9IHRyaW1tZWRQYXRoLmluZGV4T2YoXCIuXCIpXG4gICAgICAgIGF1dGhvciA9IHRyaW1tZWRQYXRoLnNsaWNlKDAsIGZpcnN0RG90SW5kZXgpXG4gICAgICAgIHNuaXBwZXROYW1lID0gdHJpbW1lZFBhdGguc2xpY2UoZmlyc3REb3RJbmRleCArIDEpXG4gICAgICB9XG5cbiAgICAgIGlmICghYXV0aG9yIHx8ICFzbmlwcGV0TmFtZSkge1xuICAgICAgICBjb25zb2xlLmVycm9yKFxuICAgICAgICAgIFwiSW52YWxpZCBzbmlwcGV0IHBhdGguIFVzZSBmb3JtYXQ6IGF1dGhvci9zbmlwcGV0TmFtZSwgYXV0aG9yLnNuaXBwZXROYW1lIG9yIEB0c2NpL2F1dGhvci5zbmlwcGV0TmFtZVwiLFxuICAgICAgICApXG4gICAgICAgIHByb2Nlc3MuZXhpdCgxKVxuICAgICAgfVxuXG4gICAgICBjb25zdCBreSA9IGdldEt5KClcblxuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc29sZS5sb2coYENsb25pbmcgJHthdXRob3J9LyR7c25pcHBldE5hbWV9Li4uYClcblxuICAgICAgICBjb25zdCBwYWNrYWdlRmlsZUxpc3QgPSBhd2FpdCBreVxuICAgICAgICAgIC5wb3N0PHtcbiAgICAgICAgICAgIHBhY2thZ2VfZmlsZXM6IEFycmF5PHtcbiAgICAgICAgICAgICAgcGFja2FnZV9maWxlX2lkOiBzdHJpbmdcbiAgICAgICAgICAgICAgcGFja2FnZV9yZWxlYXNlX2lkOiBzdHJpbmdcbiAgICAgICAgICAgICAgZmlsZV9wYXRoOiBzdHJpbmdcbiAgICAgICAgICAgICAgY3JlYXRlZF9hdDogc3RyaW5nXG4gICAgICAgICAgICB9PlxuICAgICAgICAgIH0+KFwicGFja2FnZV9maWxlcy9saXN0XCIsIHtcbiAgICAgICAgICAgIGpzb246IHtcbiAgICAgICAgICAgICAgcGFja2FnZV9uYW1lOiBgJHthdXRob3J9LyR7c25pcHBldE5hbWV9YCxcbiAgICAgICAgICAgICAgdXNlX2xhdGVzdF92ZXJzaW9uOiB0cnVlLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9KVxuICAgICAgICAgIC5qc29uKClcblxuICAgICAgICAvLyBDcmVhdGUgZGlyZWN0b3J5IGlmIGl0IGRvZXNuJ3QgZXhpc3RcbiAgICAgICAgY29uc3QgZGlyUGF0aCA9IGAuLyR7YXV0aG9yfS4ke3NuaXBwZXROYW1lfWBcbiAgICAgICAgaWYgKCFmcy5leGlzdHNTeW5jKGRpclBhdGgpKSB7XG4gICAgICAgICAgZnMubWtkaXJTeW5jKGRpclBhdGgpXG4gICAgICAgIH1cblxuICAgICAgICAvLyBEb3dubG9hZCBlYWNoIGZpbGUgdGhhdCBkb2Vzbid0IHN0YXJ0IHdpdGggZGlzdC9cbiAgICAgICAgZm9yIChjb25zdCBmaWxlSW5mbyBvZiBwYWNrYWdlRmlsZUxpc3QucGFja2FnZV9maWxlcykge1xuICAgICAgICAgIGNvbnN0IGZpbGVQYXRoID0gZmlsZUluZm8uZmlsZV9wYXRoLnN0YXJ0c1dpdGgoXCIvXCIpXG4gICAgICAgICAgICA/IGZpbGVJbmZvLmZpbGVfcGF0aC5zbGljZSgxKVxuICAgICAgICAgICAgOiBmaWxlSW5mby5maWxlX3BhdGhcblxuICAgICAgICAgIGlmIChmaWxlUGF0aC5zdGFydHNXaXRoKFwiZGlzdC9cIikpIGNvbnRpbnVlXG5cbiAgICAgICAgICBjb25zdCBmaWxlQ29udGVudCA9IGF3YWl0IGt5XG4gICAgICAgICAgICAucG9zdDx7XG4gICAgICAgICAgICAgIHBhY2thZ2VfZmlsZToge1xuICAgICAgICAgICAgICAgIGNvbnRlbnRfdGV4dDogc3RyaW5nXG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0+KFwicGFja2FnZV9maWxlcy9nZXRcIiwge1xuICAgICAgICAgICAgICBqc29uOiB7XG4gICAgICAgICAgICAgICAgcGFja2FnZV9uYW1lOiBgJHthdXRob3J9LyR7c25pcHBldE5hbWV9YCxcbiAgICAgICAgICAgICAgICBmaWxlX3BhdGg6IGZpbGVJbmZvLmZpbGVfcGF0aCxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAuanNvbigpXG5cbiAgICAgICAgICBjb25zdCBmdWxsUGF0aCA9IHBhdGguam9pbihkaXJQYXRoLCBmaWxlUGF0aClcbiAgICAgICAgICBjb25zdCBkaXJOYW1lID0gcGF0aC5kaXJuYW1lKGZ1bGxQYXRoKVxuXG4gICAgICAgICAgLy8gQ3JlYXRlIG5lc3RlZCBkaXJlY3RvcmllcyBpZiB0aGV5IGRvbid0IGV4aXN0XG4gICAgICAgICAgaWYgKCFmcy5leGlzdHNTeW5jKGRpck5hbWUpKSB7XG4gICAgICAgICAgICBmcy5ta2RpclN5bmMoZGlyTmFtZSwgeyByZWN1cnNpdmU6IHRydWUgfSlcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBmcy53cml0ZUZpbGVTeW5jKGZ1bGxQYXRoLCBmaWxlQ29udGVudC5wYWNrYWdlX2ZpbGUuY29udGVudF90ZXh0KVxuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgbnBtcmNQYXRoID0gcGF0aC5qb2luKGRpclBhdGgsIFwiLm5wbXJjXCIpXG4gICAgICAgIGZzLndyaXRlRmlsZVN5bmMobnBtcmNQYXRoLCBcIkB0c2NpOnJlZ2lzdHJ5PWh0dHBzOi8vbnBtLnRzY2lyY3VpdC5jb21cIilcblxuICAgICAgICBjb25zb2xlLmxvZyhgU3VjY2Vzc2Z1bGx5IGNsb25lZCB0byAuLyR7YXV0aG9yfS4ke3NuaXBwZXROYW1lfS9gKVxuICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgaWYgKGVycm9yIGluc3RhbmNlb2YgRXJyb3IpIHtcbiAgICAgICAgICBjb25zb2xlLmVycm9yKFwiRmFpbGVkIHRvIGNsb25lIHNuaXBwZXQ6XCIsIGVycm9yLm1lc3NhZ2UpXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgY29uc29sZS5lcnJvcihcIkZhaWxlZCB0byBjbG9uZSBzbmlwcGV0OlwiLCBlcnJvcilcbiAgICAgICAgfVxuICAgICAgICBwcm9jZXNzLmV4aXQoMSlcbiAgICAgIH1cbiAgICB9KVxufVxuIiwgImltcG9ydCB0eXBlIHsgQ29tbWFuZCB9IGZyb20gXCJjb21tYW5kZXJcIlxuaW1wb3J0IHsgY3JlYXRlQ2lyY3VpdFdlYldvcmtlciB9IGZyb20gXCJAdHNjaXJjdWl0L2V2YWwtd2Vid29ya2VyXCJcbmltcG9ydCB3ZWJXb3JrZXJCdW5kbGVVcmwgZnJvbSBcIkB0c2NpcmN1aXQvZXZhbC13ZWJ3b3JrZXIvYmxvYi11cmxcIlxuaW1wb3J0IHsgZ2V0VmlydHVhbEZpbGVTeXN0ZW1Gcm9tRGlyUGF0aCB9IGZyb20gXCJtYWtlLXZmc1wiXG5pbXBvcnQgcGF0aCBmcm9tIFwibm9kZTpwYXRoXCJcbmltcG9ydCBmcyBmcm9tIFwibm9kZTpmc1wiXG5cbmNvbnN0IEFMTE9XRURfRk9STUFUUyA9IFtcbiAgXCJqc29uXCIsXG4gIFwiY2lyY3VpdC1qc29uXCIsXG4gIFwic2NoZW1hdGljLXN2Z1wiLFxuICBcInBjYi1zdmdcIixcbiAgXCJnZXJiZXJzXCIsXG4gIFwicmVhZGFibGUtbmV0bGlzdFwiLFxuICBcImdsdGZcIixcbiAgXCJzcGVjY3RyYS1kc25cIixcbl0gYXMgY29uc3RcblxudHlwZSBGb3JtYXQgPSAodHlwZW9mIEFMTE9XRURfRk9STUFUUylbbnVtYmVyXVxuXG5jb25zdCBPVVRQVVRfRVhURU5TSU9OUyA9IHtcbiAganNvbjogXCIuY2lyY3VpdC5qc29uXCIsXG4gIFwiY2lyY3VpdC1qc29uXCI6IFwiLmNpcmN1aXQuanNvblwiLFxuICBcInNjaGVtYXRpYy1zdmdcIjogXCItc2NoZW1hdGljLnN2Z1wiLFxuICBcInBjYi1zdmdcIjogXCItcGNiLnN2Z1wiLFxuICBnZXJiZXJzOiBcIi1nZXJiZXJzLnppcFwiLFxuICBcInJlYWRhYmxlLW5ldGxpc3RcIjogXCItcmVhZGFibGUubmV0bGlzdFwiLFxuICBnbHRmOiBcIi5nbHRmXCIsXG4gIFwic3BlY2N0cmEtZHNuXCI6IFwiLmRzblwiLFxufVxuXG5leHBvcnQgY29uc3QgcmVnaXN0ZXJFeHBvcnQgPSAocHJvZ3JhbTogQ29tbWFuZCkgPT4ge1xuICBwcm9ncmFtXG4gICAgLmNvbW1hbmQoXCJleHBvcnRcIilcbiAgICAuZGVzY3JpcHRpb24oXCJFeHBvcnQgdHNjaXJjdWl0IGNvZGUgdG8gdmFyaW91cyBmb3JtYXRzXCIpXG4gICAgLmFyZ3VtZW50KFwiPGZpbGU+XCIsIFwiUGF0aCB0byB0aGUgc25pcHBldCBmaWxlXCIpXG4gICAgLm9wdGlvbihcIi1mLCAtLWZvcm1hdCA8Zm9ybWF0PlwiLCBcIk91dHB1dCBmb3JtYXRcIilcbiAgICAub3B0aW9uKFwiLW8sIC0tb3V0cHV0IDxwYXRoPlwiLCBcIk91dHB1dCBmaWxlIHBhdGhcIilcbiAgICAuYWN0aW9uKGFzeW5jIChmaWxlLCBvcHRpb25zKSA9PiB7XG4gICAgICBjb25zdCB7IGZvcm1hdCA9IFwiY2lyY3VpdC1qc29uXCIgfSA9IG9wdGlvbnNcbiAgICAgIGxldCB7IG91dHB1dCB9ID0gb3B0aW9uc1xuICAgICAgaWYgKCFBTExPV0VEX0ZPUk1BVFMuaW5jbHVkZXMoZm9ybWF0KSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICAgYEludmFsaWQgZm9ybWF0OiAke2Zvcm1hdH1cXG5TdXBwb3J0ZWQgZm9ybWF0czogJHtBTExPV0VEX0ZPUk1BVFMuam9pbihcIixcIil9YCxcbiAgICAgICAgKVxuICAgICAgfVxuXG4gICAgICBpZiAoIW91dHB1dCkge1xuICAgICAgICBvdXRwdXQgPSBwYXRoLmJhc2VuYW1lKGZpbGUpLnJlcGxhY2UoL1xcLlteLl0rJC8sIFwiXCIpXG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHdvcmtlciA9IGF3YWl0IGNyZWF0ZUNpcmN1aXRXZWJXb3JrZXIoe1xuICAgICAgICB3ZWJXb3JrZXJVcmw6IHdlYldvcmtlckJ1bmRsZVVybCxcbiAgICAgIH0pXG5cbiAgICAgIGNvbnN0IHByb2plY3REaXIgPSBwYXRoLmRpcm5hbWUoZmlsZSlcblxuICAgICAgY29uc3QgcmVsYXRpdmVDb21wb25lbnRQYXRoID0gcGF0aC5yZWxhdGl2ZShwcm9qZWN0RGlyLCBmaWxlKVxuXG4gICAgICBhd2FpdCB3b3JrZXIuZXhlY3V0ZVdpdGhGc01hcCh7XG4gICAgICAgIGVudHJ5cG9pbnQ6IFwiZW50cnlwb2ludC50c3hcIixcbiAgICAgICAgZnNNYXA6IHtcbiAgICAgICAgICAuLi4oKGF3YWl0IGdldFZpcnR1YWxGaWxlU3lzdGVtRnJvbURpclBhdGgoe1xuICAgICAgICAgICAgZGlyUGF0aDogcHJvamVjdERpcixcbiAgICAgICAgICAgIGNvbnRlbnRGb3JtYXQ6IFwic3RyaW5nXCIsXG4gICAgICAgICAgfSkpIGFzIFJlY29yZDxzdHJpbmcsIHN0cmluZz4pLFxuICAgICAgICAgIFwiZW50cnlwb2ludC50c3hcIjogYFxuaW1wb3J0IE15Q2lyY3VpdCBmcm9tIFwiLi8ke3JlbGF0aXZlQ29tcG9uZW50UGF0aH1cIlxuXG5jaXJjdWl0LmFkZCg8TXlDaXJjdWl0IC8+KVxuICAgICAgICBgLFxuICAgICAgICB9LFxuICAgICAgfSlcblxuICAgICAgYXdhaXQgd29ya2VyLnJlbmRlclVudGlsU2V0dGxlZCgpXG5cbiAgICAgIGNvbnN0IGNpcmN1aXRKc29uID0gYXdhaXQgd29ya2VyLmdldENpcmN1aXRKc29uKClcblxuICAgICAgY29uc3Qgb3V0cHV0UGF0aCA9IHBhdGguam9pbihcbiAgICAgICAgcHJvamVjdERpcixcbiAgICAgICAgYCR7b3V0cHV0fSR7T1VUUFVUX0VYVEVOU0lPTlNbZm9ybWF0IGFzIEZvcm1hdF19YCxcbiAgICAgIClcblxuICAgICAgZnMud3JpdGVGaWxlU3luYyhvdXRwdXRQYXRoLCBKU09OLnN0cmluZ2lmeShjaXJjdWl0SnNvbikpXG5cbiAgICAgIGNvbnNvbGUubG9nKGBFeHBvcnRlZCB0byAke291dHB1dFBhdGh9YClcblxuICAgICAgcHJvY2Vzcy5leGl0KDApXG4gICAgfSlcbn1cbiIsICJpbXBvcnQgdHlwZSB7IENvbW1hbmQgfSBmcm9tIFwiY29tbWFuZGVyXCJcbmltcG9ydCB7IGNsaUNvbmZpZyB9IGZyb20gXCJsaWIvY2xpLWNvbmZpZ1wiXG5cbmV4cG9ydCBjb25zdCByZWdpc3RlckF1dGhQcmludFRva2VuID0gKHByb2dyYW06IENvbW1hbmQpID0+IHtcbiAgcHJvZ3JhbS5jb21tYW5kc1xuICAgIC5maW5kKChjKSA9PiBjLm5hbWUoKSA9PT0gXCJhdXRoXCIpIVxuICAgIC5jb21tYW5kKFwicHJpbnQtdG9rZW5cIilcbiAgICAuZGVzY3JpcHRpb24oXCJQcmludHMgeW91ciBhdXRoIHRva2VuXCIpXG4gICAgLmFjdGlvbigoKSA9PiB7XG4gICAgICBjb25zdCB0b2tlbiA9IGNsaUNvbmZpZy5nZXQoXCJzZXNzaW9uVG9rZW5cIilcbiAgICAgIGlmICghdG9rZW4pIHJldHVybiBjb25zb2xlLmxvZyhcIllvdSBuZWVkIHRvIGxvZyBpbiB0byBhY2Nlc3MgdGhpcy5cIilcbiAgICAgIGNvbnNvbGUubG9nKFwiWW91ciBUb2tlbjpcXG5cIiwgdG9rZW4pXG4gICAgfSlcbn1cbiIsICJpbXBvcnQgdHlwZSB7IENvbW1hbmQgfSBmcm9tIFwiY29tbWFuZGVyXCJcbmltcG9ydCB7IGNsaUNvbmZpZyB9IGZyb20gXCJsaWIvY2xpLWNvbmZpZ1wiXG5cbmZ1bmN0aW9uIHZhbGlkYXRlSldUTGVuZ3RoKHRva2VuOiBzdHJpbmcpIHtcbiAgY29uc3QgcGFydHMgPSB0b2tlbi5zcGxpdChcIi5cIilcblxuICBpZiAocGFydHMubGVuZ3RoID09PSAzICYmIHBhcnRzLmV2ZXJ5KChwYXJ0KSA9PiBwYXJ0Lmxlbmd0aCA+IDApKSB7XG4gICAgcmV0dXJuIHRydWVcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gZmFsc2VcbiAgfVxufVxuZXhwb3J0IGNvbnN0IHJlZ2lzdGVyQXV0aFNldFRva2VuID0gKHByb2dyYW06IENvbW1hbmQpID0+IHtcbiAgcHJvZ3JhbS5jb21tYW5kc1xuICAgIC5maW5kKChjKSA9PiBjLm5hbWUoKSA9PT0gXCJhdXRoXCIpIVxuICAgIC5jb21tYW5kKFwic2V0LXRva2VuXCIpXG4gICAgLmRlc2NyaXB0aW9uKFwiRXhwbGljaXRseSBzZXQgeW91ciBhdXRoIHRva2VuXCIpXG4gICAgLmFyZ3VtZW50KFwiPHRva2VuPlwiLCBcIk5ldyB0b2tlbiB0byBtYW51YWxseSBjb25maWd1cmVcIilcbiAgICAuYWN0aW9uKCh0b2tlbikgPT4ge1xuICAgICAgaWYgKCF2YWxpZGF0ZUpXVExlbmd0aCh0b2tlbikpXG4gICAgICAgIHJldHVybiBjb25zb2xlLmxvZyhcIkludmFsaWQgdG9rZW4gcHJvdmlkZWRcIilcbiAgICAgIGNsaUNvbmZpZy5zZXQoXCJzZXNzaW9uVG9rZW5cIiwgdG9rZW4pXG4gICAgICBjb25zb2xlLmxvZyhcIlRva2VuIG1hbnVhbGx5IHVwZGF0ZWQuXCIpXG4gICAgfSlcbn1cbiJdLAogICJtYXBwaW5ncyI6ICI7OztBQUNBLFNBQVMsZUFBZTs7O0FDQXhCLFlBQVksUUFBUTtBQUNwQixZQUFZLFVBQVU7QUFFZixJQUFNLGVBQWUsQ0FBQ0EsYUFBcUI7QUFDaEQsRUFBQUEsU0FDRyxRQUFRLE1BQU0sRUFDZCxZQUFZLDZEQUE2RCxFQUN6RSxPQUFPLE1BQU07QUFDWixVQUFNLGFBQWEsUUFBUSxJQUFJO0FBRS9CLFVBQU0sZ0JBQXFCLFVBQUssWUFBWSxXQUFXO0FBQ3ZELFVBQU0sZ0JBQXFCLFVBQUssWUFBWSxRQUFRO0FBRXBELFVBQU0sZUFBZTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFzQnJCLFVBQU0sZUFBZTtBQUFBO0FBQUE7QUFJckIsUUFBSSxDQUFJLGNBQVcsYUFBYSxHQUFHO0FBQ2pDLE1BQUcsaUJBQWMsZUFBZSxhQUFhLFVBQVUsQ0FBQztBQUN4RCxjQUFRLElBQUksWUFBWSxhQUFhLEVBQUU7QUFBQSxJQUN6QyxPQUFPO0FBQ0wsY0FBUSxJQUFJLFlBQVksYUFBYSxpQkFBaUI7QUFBQSxJQUN4RDtBQUVBLFFBQUksQ0FBSSxjQUFXLGFBQWEsR0FBRztBQUNqQyxNQUFHLGlCQUFjLGVBQWUsYUFBYSxVQUFVLENBQUM7QUFDeEQsY0FBUSxJQUFJLFlBQVksYUFBYSxFQUFFO0FBQUEsSUFDekMsT0FBTztBQUNMLGNBQVEsSUFBSSxZQUFZLGFBQWEsaUJBQWlCO0FBQUEsSUFDeEQ7QUFFQSxZQUFRO0FBQUEsTUFDTjtBQUFBLElBQ0Y7QUFBQSxFQUNGLENBQUM7QUFDTDs7O0FDekRBLFlBQVlDLFdBQVU7QUFFdEIsWUFBWUMsU0FBUTs7O0FDSHBCLFlBQVlDLFNBQVE7QUFDcEIsWUFBWUMsV0FBVTtBQUN0QixZQUFZLFFBQVE7QUFRcEIsZUFBc0IsaUNBQWlDLGFBQXFCO0FBQzFFLFFBQU0sVUFBYSxpQkFBYSxhQUFhLE9BQU87QUFDcEQsUUFBTSxhQUFnQjtBQUFBLElBQ3BCO0FBQUEsSUFDQTtBQUFBLElBQ0csZ0JBQWE7QUFBQSxJQUNoQjtBQUFBLEVBQ0Y7QUFFQSxRQUFNLFVBQW9CLENBQUM7QUFFM0IsV0FBUyxNQUFNLE1BQWU7QUFDNUIsUUFBTyx1QkFBb0IsSUFBSSxHQUFHO0FBQ2hDLFlBQU0sa0JBQWtCLEtBQUs7QUFDN0IsVUFBSSxtQkFBc0IsbUJBQWdCLGVBQWUsR0FBRztBQUMxRCxjQUFNLGFBQWEsZ0JBQWdCO0FBQ25DLFlBQUksV0FBVyxXQUFXLFFBQVEsR0FBRztBQUNuQyxrQkFBUSxLQUFLLFVBQVU7QUFBQSxRQUN6QjtBQUFBLE1BQ0Y7QUFBQSxJQUNGO0FBQ0EsSUFBRyxnQkFBYSxNQUFNLEtBQUs7QUFBQSxFQUM3QjtBQUVBLFFBQU0sVUFBVTtBQUVoQixNQUFJLGNBQW1CLGNBQVEsV0FBVztBQUMxQyxTQUFPLGdCQUFxQixZQUFNLFdBQVcsRUFBRSxNQUFNO0FBQ25ELFFBQU8sZUFBZ0IsV0FBSyxhQUFhLGNBQWMsQ0FBQyxHQUFHO0FBQ3pEO0FBQUEsSUFDRjtBQUNBLGtCQUFtQixjQUFRLFdBQVc7QUFBQSxFQUN4QztBQUVBLGFBQVcsY0FBYyxTQUFTO0FBQ2hDLFVBQU0sQ0FBQyxPQUFPLElBQUksSUFBSSxXQUFXLFFBQVEsVUFBVSxFQUFFLEVBQUUsTUFBTSxHQUFHO0FBQ2hFLFFBQUk7QUFDRixZQUFNLFdBQVcsTUFBTTtBQUFBLFFBQ3JCLDhEQUE4RCxLQUFLLGtCQUFrQixJQUFJO0FBQUEsTUFDM0Y7QUFFQSxVQUFJLENBQUMsU0FBUyxJQUFJO0FBQ2hCLGdCQUFRLEtBQUssNkJBQTZCLFVBQVUsRUFBRTtBQUN0RDtBQUFBLE1BQ0Y7QUFFQSxZQUFNLE9BQTJCLE1BQU0sU0FBUyxLQUFLO0FBRXJELFVBQUksS0FBSyxRQUFRLEtBQUs7QUFDcEIsY0FBTSxhQUFrQjtBQUFBLFVBQ3RCO0FBQUEsVUFDQTtBQUFBLFVBQ0E7QUFBQSxVQUNBLEdBQUcsS0FBSyxJQUFJLElBQUk7QUFBQSxRQUNsQjtBQUNBLFFBQUcsY0FBVSxZQUFZLEVBQUUsV0FBVyxLQUFLLENBQUM7QUFFNUMsUUFBRyxrQkFBbUIsV0FBSyxZQUFZLFlBQVksR0FBRyxLQUFLLFFBQVEsR0FBRztBQUFBLE1BQ3hFO0FBQUEsSUFDRixTQUFTLE9BQU87QUFDZCxjQUFRLEtBQUssNEJBQTRCLFVBQVUsS0FBSyxLQUFLO0FBQUEsSUFDL0Q7QUFBQSxFQUNGO0FBQ0Y7OztBQ3pFQSxPQUFPLFFBQVE7OztBQ0FmLFlBQVksVUFBVTtBQUN0QixZQUFZQyxTQUFRO0FBQ3BCLFlBQVlDLFdBQVU7QUFDdEIsU0FBUyxzQkFBc0I7OztBQ0gvQjtBQUFBLEVBQ0UsTUFBUTtBQUFBLEVBQ1IsTUFBUTtBQUFBLEVBQ1IsTUFBUTtBQUFBLEVBQ1IsU0FBVztBQUFBLEVBQ1gsS0FBTztBQUFBLElBQ0wsTUFBUTtBQUFBLEVBQ1Y7QUFBQSxFQUNBLFNBQVc7QUFBQSxJQUNULE9BQVM7QUFBQSxJQUNULEtBQU87QUFBQSxJQUNQLE9BQVM7QUFBQSxJQUNULFFBQVU7QUFBQSxJQUNWLGdCQUFnQjtBQUFBLElBQ2hCLEtBQU87QUFBQSxFQUNUO0FBQUEsRUFDQSxpQkFBbUI7QUFBQSxJQUNqQixrQkFBa0I7QUFBQSxJQUNsQixtQkFBbUI7QUFBQSxJQUNuQixjQUFjO0FBQUEsSUFDZCxzQkFBc0I7QUFBQSxJQUN0QixnQkFBZ0I7QUFBQSxJQUNoQixpQkFBaUI7QUFBQSxJQUNqQixZQUFZO0FBQUEsSUFDWixPQUFTO0FBQUEsSUFDVCxNQUFRO0FBQUEsSUFDUixZQUFZO0FBQUEsRUFDZDtBQUFBLEVBQ0Esa0JBQW9CO0FBQUEsSUFDbEIsWUFBYztBQUFBLEVBQ2hCO0FBQUEsRUFDQSxjQUFnQjtBQUFBLElBQ2QsMEJBQTBCO0FBQUEsSUFDMUIsdUJBQXVCO0FBQUEsSUFDdkIsVUFBWTtBQUFBLElBQ1osV0FBYTtBQUFBLElBQ2IsYUFBZTtBQUFBLElBQ2YsYUFBZTtBQUFBLElBQ2YsT0FBUztBQUFBLElBQ1QsSUFBTTtBQUFBLElBQ04sWUFBWTtBQUFBLElBQ1osZUFBZTtBQUFBLElBQ2YsUUFBVTtBQUFBLEVBQ1o7QUFDRjs7O0FEckNBLE9BQU8sc0JBQXNCOzs7QUVMdEIsSUFBTSxXQUFXLFlBQVk7QUFDbEMsU0FBTztBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFZVDs7O0FGTE8sSUFBTSxtQkFBbUIsT0FBTyxPQUFPLFFBQVM7QUFDckQsUUFBTSxvQkFBb0IsZUFBZSxrQkFBeUIsQ0FBQyxDQUFDO0FBRXBFLFFBQU0sU0FBYyxrQkFBYSxPQUFPLEtBQUssUUFBUTtBQUNuRCxVQUFNLE1BQU0sSUFBSSxJQUFJLElBQUksS0FBTSxVQUFVLElBQUksUUFBUSxJQUFJLEVBQUU7QUFFMUQsUUFBSSxJQUFJLGFBQWEsc0JBQXNCO0FBQ3pDLFlBQU0scUJBQ0osUUFBUSxJQUFJLGlDQUNQO0FBQUEsUUFDSCxRQUFRLElBQUk7QUFBQSxRQUNaO0FBQUEsUUFDQTtBQUFBLE1BQ0Y7QUFFRixVQUFJO0FBQ0YsY0FBTSxVQUFhLGlCQUFhLG9CQUFvQixNQUFNO0FBQzFELFlBQUksVUFBVSxLQUFLO0FBQUEsVUFDakIsZ0JBQWdCO0FBQUEsUUFDbEIsQ0FBQztBQUNELFlBQUksSUFBSSxPQUFPO0FBQ2Y7QUFBQSxNQUNGLFNBQVMsT0FBTztBQUNkLGdCQUFRLE1BQU0sb0NBQW9DLEtBQUs7QUFBQSxNQUN6RDtBQUVBLFVBQUksVUFBVSxLQUFLO0FBQUEsUUFDakIsVUFBVSxvREFBb0QsZ0JBQUksYUFBYSxxQkFBcUIsRUFBRSxRQUFRLFlBQVksRUFBRSxDQUFDO0FBQUEsTUFDL0gsQ0FBQztBQUNELFVBQUksSUFBSTtBQUNSO0FBQUEsSUFDRjtBQUVBLFFBQUksSUFBSSxhQUFhLEtBQUs7QUFDeEIsWUFBTSxPQUFPLE1BQU0sU0FBUztBQUM1QixVQUFJLFVBQVUsS0FBSyxFQUFFLGdCQUFnQixZQUFZLENBQUM7QUFDbEQsVUFBSSxJQUFJLElBQUk7QUFDWjtBQUFBLElBQ0Y7QUFFQSxRQUFJLElBQUksU0FBUyxXQUFXLE9BQU8sR0FBRztBQUNwQyxVQUFJLE1BQU0sSUFBSSxJQUFLLFFBQVEsU0FBUyxHQUFHO0FBQ3ZDLHdCQUFrQixLQUFLLEdBQUc7QUFDMUI7QUFBQSxJQUNGO0FBRUEsUUFBSSxVQUFVLEdBQUc7QUFDakIsUUFBSSxJQUFJLFdBQVc7QUFBQSxFQUNyQixDQUFDO0FBRUQsU0FBTyxJQUFJLFFBQWlDLENBQUNDLGFBQVk7QUFDdkQsV0FBTyxPQUFPLE1BQU0sTUFBTTtBQUN4QixjQUFRLElBQUksc0NBQXNDLElBQUksRUFBRTtBQUN4RCxNQUFBQSxTQUFRLEVBQUUsT0FBTyxDQUFDO0FBQUEsSUFDcEIsQ0FBQztBQUFBLEVBQ0gsQ0FBQztBQUNIOzs7QUdsRUEsU0FBUyxvQkFBb0I7QUFhdEIsSUFBTSxnQkFBTixjQUE0QixhQUFhO0FBQUEsRUFDdEM7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0EsVUFBVTtBQUFBLEVBQ1Y7QUFBQSxFQUVSLFlBQVksVUFBVSx5QkFBeUIsZUFBZSxLQUFNO0FBQ2xFLFVBQU07QUFDTixTQUFLLFVBQVU7QUFDZixTQUFLLGVBQWU7QUFDcEIsU0FBSyxnQkFBZSxvQkFBSSxLQUFLLEdBQUUsWUFBWTtBQUFBLEVBQzdDO0FBQUEsRUFFQSxNQUFNLFFBQVE7QUFDWixRQUFJLEtBQUssUUFBUztBQUNsQixTQUFLLFVBQVU7QUFDZixVQUFNLEtBQUssS0FBSztBQUFBLEVBQ2xCO0FBQUEsRUFFQSxPQUFPO0FBQ0wsU0FBSyxVQUFVO0FBQ2YsUUFBSSxLQUFLLFdBQVc7QUFDbEIsbUJBQWEsS0FBSyxTQUFTO0FBQUEsSUFDN0I7QUFBQSxFQUNGO0FBQUEsRUFFQSxNQUFjLE9BQU87QUFDbkIsUUFBSSxDQUFDLEtBQUssUUFBUztBQUVuQixRQUFJO0FBQ0YsWUFBTSxXQUFXLE1BQU07QUFBQSxRQUNyQixHQUFHLEtBQUssT0FBTywwQkFBMEIsbUJBQW1CLEtBQUssWUFBWSxDQUFDO0FBQUEsTUFDaEY7QUFFQSxVQUFJLENBQUMsU0FBUyxJQUFJO0FBQ2hCLGNBQU0sSUFBSSxNQUFNLHVCQUF1QixTQUFTLE1BQU0sRUFBRTtBQUFBLE1BQzFEO0FBRUEsWUFBTSxPQUF1QixNQUFNLFNBQVMsS0FBSztBQUdqRCxZQUFNLGNBQWMsS0FBSyxXQUFXLEtBQUssV0FBVyxTQUFTLENBQUM7QUFDOUQsV0FBSyxlQUFlLGNBQ2hCLFlBQVksY0FDWixvQkFBSSxLQUFLLEdBQUUsWUFBWTtBQUczQixXQUFLLFdBQVcsUUFBUSxDQUFDLFVBQVU7QUFDakMsYUFBSyxLQUFLLE1BQU0sWUFBWSxLQUFLO0FBQ2pDLGFBQUssS0FBSyxLQUFLLEtBQUs7QUFBQSxNQUN0QixDQUFDO0FBQUEsSUFDSCxTQUFTLE9BQU87QUFDZCxXQUFLLEtBQUssU0FBUyxLQUFLO0FBQUEsSUFDMUI7QUFFQSxTQUFLLFlBQVksV0FBVztBQUFBLE1BQzFCLE1BQU0sS0FBSyxLQUFLO0FBQUEsTUFDaEIsS0FBSztBQUFBLElBQ1A7QUFBQSxFQUNGO0FBQ0Y7OztBSnBFQSxPQUFPQyxXQUFVO0FBQ2pCLE9BQU9DLFNBQVE7QUFFZixZQUFZLGNBQWM7OztBS1QxQixZQUFZQyxTQUFRO0FBQ3BCLFlBQVlDLFdBQVU7OztBQ0R0QixZQUFZQyxTQUFRO0FBQ3BCLFlBQVlDLFNBQVE7QUFFYixTQUFTLHFCQUFxQixhQUErQjtBQUNsRSxRQUFNLFVBQWEsaUJBQWEsYUFBYSxPQUFPO0FBQ3BELFFBQU0sYUFBZ0I7QUFBQSxJQUNwQjtBQUFBLElBQ0E7QUFBQSxJQUNHLGlCQUFhO0FBQUEsSUFDaEI7QUFBQSxFQUNGO0FBRUEsUUFBTSxVQUFvQixDQUFDO0FBRTNCLFdBQVMsTUFBTSxNQUFlO0FBQzVCLFFBQU8sd0JBQW9CLElBQUksR0FBRztBQUNoQyxZQUFNLGtCQUFrQixLQUFLO0FBQzdCLFVBQUksbUJBQXNCLG9CQUFnQixlQUFlLEdBQUc7QUFDMUQsY0FBTSxhQUFhLGdCQUFnQjtBQUNuQyxZQUFJLFdBQVcsV0FBVyxRQUFRLEdBQUc7QUFDbkMsa0JBQVEsS0FBSyxVQUFVO0FBQUEsUUFDekI7QUFBQSxNQUNGO0FBQUEsSUFDRjtBQUNBLElBQUcsaUJBQWEsTUFBTSxLQUFLO0FBQUEsRUFDN0I7QUFFQSxRQUFNLFVBQVU7QUFFaEIsU0FBTztBQUNUOzs7QUR6Qk8sSUFBTSx5QkFBTixNQUE2QjtBQUFBLEVBQzFCO0FBQUEsRUFFUixZQUFZLFlBQW9CO0FBQzlCLFNBQUssY0FBYyxLQUFLLGdCQUFnQixVQUFVO0FBQUEsRUFDcEQ7QUFBQSxFQUVBLE1BQU0sOEJBQThCLFVBQWtCO0FBQ3BELFlBQVEsSUFBSSx1Q0FBdUM7QUFDbkQsUUFBSTtBQUNGLFVBQUksQ0FBQyxLQUFLLGtCQUFrQixRQUFRLEdBQUc7QUFDckMsZ0JBQVEsSUFBSSxxQ0FBcUM7QUFDakQsY0FBTSxpQ0FBaUMsUUFBUTtBQUFBLE1BQ2pEO0FBQUEsSUFDRixTQUFTLE9BQU87QUFDZCxjQUFRLEtBQUssNkNBQTZDLEtBQUs7QUFBQSxJQUNqRTtBQUFBLEVBQ0Y7QUFBQSxFQUVBLE1BQU0sMkJBQTJCLFVBQWtCO0FBQ2pELFFBQUk7QUFDRixVQUFJLENBQUMsS0FBSyxrQkFBa0IsUUFBUSxHQUFHO0FBQ3JDLGdCQUFRLElBQUksa0NBQWtDO0FBQzlDLGNBQU0saUNBQWlDLFFBQVE7QUFBQSxNQUNqRDtBQUFBLElBQ0YsU0FBUyxPQUFPO0FBQ2QsY0FBUSxLQUFLLDJCQUEyQixLQUFLO0FBQUEsSUFDL0M7QUFBQSxFQUNGO0FBQUEsRUFFUSxrQkFBa0IsVUFBMkI7QUFDbkQsVUFBTSxVQUFVLHFCQUFxQixRQUFRO0FBQzdDLFdBQU8sUUFBUSxNQUFNLENBQUMsUUFBUSxLQUFLLGdCQUFnQixHQUFHLENBQUM7QUFBQSxFQUN6RDtBQUFBLEVBRVEsZ0JBQWdCLFlBQTZCO0FBQ25ELFFBQUksQ0FBQyxXQUFXLFdBQVcsUUFBUSxFQUFHLFFBQU87QUFFN0MsVUFBTSxvQkFBb0IsV0FBVyxRQUFRLFVBQVUsRUFBRTtBQUN6RCxVQUFNLENBQUMsT0FBTyxJQUFJLElBQUksa0JBQWtCLE1BQU0sR0FBRztBQUVqRCxVQUFNLFdBQWdCO0FBQUEsTUFDcEIsS0FBSztBQUFBLE1BQ0w7QUFBQSxNQUNBO0FBQUEsTUFDQSxHQUFHLEtBQUssSUFBSSxJQUFJO0FBQUEsTUFDaEI7QUFBQSxJQUNGO0FBRUEsV0FBVSxlQUFXLFFBQVE7QUFBQSxFQUMvQjtBQUFBLEVBRVEsZ0JBQWdCLFVBQTBCO0FBQ2hELFFBQUksT0FBWSxjQUFRLFFBQVE7QUFDaEMsV0FBTyxTQUFjLFlBQU0sSUFBSSxFQUFFLE1BQU07QUFDckMsVUFBTyxlQUFnQixXQUFLLE1BQU0sY0FBYyxDQUFDLEdBQUc7QUFDbEQsZUFBTztBQUFBLE1BQ1Q7QUFDQSxhQUFZLGNBQVEsSUFBSTtBQUFBLElBQzFCO0FBQ0EsV0FBTztBQUFBLEVBQ1Q7QUFDRjs7O0FMdkRPLElBQU0sWUFBTixNQUFnQjtBQUFBLEVBQ3JCO0FBQUE7QUFBQTtBQUFBO0FBQUEsRUFJQTtBQUFBLEVBRUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBLEVBTUE7QUFBQTtBQUFBO0FBQUE7QUFBQSxFQUlBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQSxFQUtBO0FBQUE7QUFBQTtBQUFBO0FBQUEsRUFJQTtBQUFBLEVBRVE7QUFBQSxFQUVSLFlBQVk7QUFBQSxJQUNWO0FBQUEsSUFDQTtBQUFBLEVBQ0YsR0FHRztBQUNELFNBQUssT0FBTztBQUNaLFNBQUssb0JBQW9CO0FBQ3pCLFNBQUssYUFBYUMsTUFBSyxRQUFRLGlCQUFpQjtBQUNoRCxTQUFLLE9BQU8sR0FBRyxPQUFPO0FBQUEsTUFDcEIsV0FBVyxvQkFBb0IsSUFBSTtBQUFBLElBQ3JDLENBQUM7QUFDRCxTQUFLLGVBQWUsSUFBSSx1QkFBdUIsS0FBSyxVQUFVO0FBQUEsRUFDaEU7QUFBQSxFQUVBLE1BQU0sUUFBUTtBQUNaLFVBQU0sRUFBRSxPQUFPLElBQUksTUFBTSxpQkFBaUIsS0FBSyxJQUFJO0FBQ25ELFNBQUssYUFBYTtBQUVsQixTQUFLLGdCQUFnQixJQUFJLGNBQWMsb0JBQW9CLEtBQUssSUFBSSxFQUFFO0FBQ3RFLFNBQUssY0FBYyxNQUFNO0FBRXpCLFNBQUssY0FBYztBQUFBLE1BQ2pCO0FBQUEsTUFDQSxLQUFLLGlDQUFpQyxLQUFLLElBQUk7QUFBQSxJQUNqRDtBQUVBLFNBQUssb0JBQTZCLGVBQU0sS0FBSyxZQUFZO0FBQUEsTUFDdkQsWUFBWTtBQUFBLE1BQ1osZUFBZTtBQUFBLElBQ2pCLENBQUM7QUFFRCxTQUFLLGtCQUFrQjtBQUFBLE1BQUc7QUFBQSxNQUFVLENBQUMsYUFDbkMsS0FBSyw4QkFBOEIsUUFBUTtBQUFBLElBQzdDO0FBQ0EsU0FBSyxrQkFBa0I7QUFBQSxNQUFHO0FBQUEsTUFBTyxDQUFDLGFBQ2hDLEtBQUssOEJBQThCLFFBQVE7QUFBQSxJQUM3QztBQUVBLFNBQUssbUJBQW1CO0FBRXhCLFNBQUssY0FBYyw4QkFBOEIsS0FBSyxpQkFBaUI7QUFBQSxFQUN6RTtBQUFBLEVBRUEsTUFBTSxnQkFBZ0I7QUFDcEIsVUFBTSw0QkFBNEJBLE1BQUs7QUFBQSxNQUNyQyxLQUFLO0FBQUEsTUFDTCxLQUFLO0FBQUEsSUFDUDtBQUNBLFVBQU0sS0FBSyxLQUFLLEtBQUssb0JBQW9CO0FBQUEsTUFDdkMsTUFBTTtBQUFBLFFBQ0osV0FBVztBQUFBLFFBQ1gsY0FBYztBQUFBLDJCQUNLLHlCQUF5QjtBQUFBO0FBQUE7QUFBQTtBQUFBLE1BSTlDO0FBQUEsSUFDRixDQUFDO0FBQUEsRUFDSDtBQUFBLEVBRUEsTUFBTSxpQ0FBaUMsSUFBc0I7QUFDM0QsUUFBSSxHQUFHLGNBQWMsb0JBQXFCO0FBRTFDLFFBQUksR0FBRyxjQUFjLHFCQUFxQjtBQUN4QyxjQUFRLElBQUksaURBQWlEO0FBQzdELFlBQU0sRUFBRSxLQUFLLElBQUksTUFBTSxLQUFLLEtBQ3pCLElBQUksaUJBQWlCO0FBQUEsUUFDcEIsY0FBYyxFQUFFLFdBQVcsR0FBRyxVQUFVO0FBQUEsTUFDMUMsQ0FBQyxFQUNBLEtBQUs7QUFDUixNQUFBQyxJQUFHO0FBQUEsUUFDREQsTUFBSyxLQUFLLEtBQUssWUFBWSxtQkFBbUI7QUFBQSxRQUM5QyxLQUFLO0FBQUEsTUFDUDtBQUFBLElBQ0Y7QUFBQSxFQUNGO0FBQUEsRUFFQSxNQUFNLDhCQUE4QixrQkFBMEI7QUFDNUQsVUFBTSxtQkFBbUJBLE1BQUssU0FBUyxLQUFLLFlBQVksZ0JBQWdCO0FBR3hFLFFBQUksaUJBQWlCLFNBQVMsbUJBQW1CLEVBQUc7QUFFcEQsVUFBTSxLQUFLLGNBQWMsMkJBQTJCLGdCQUFnQjtBQUVwRSxZQUFRLElBQUksR0FBRyxnQkFBZ0IsNkJBQTZCO0FBQzVELFVBQU0sS0FBSyxLQUNSLEtBQUssb0JBQW9CO0FBQUEsTUFDeEIsTUFBTTtBQUFBLFFBQ0osV0FBVztBQUFBLFFBQ1gsY0FBY0MsSUFBRyxhQUFhLGtCQUFrQixPQUFPO0FBQUEsUUFDdkQsV0FBVztBQUFBLE1BQ2I7QUFBQSxJQUNGLENBQUMsRUFDQSxLQUFLO0FBQUEsRUFDVjtBQUFBLEVBRUEsTUFBTSxxQkFBcUI7QUFFekIsVUFBTSxZQUFZQSxJQUFHLFlBQVksS0FBSyxVQUFVO0FBQ2hELGVBQVcsWUFBWSxXQUFXO0FBQ2hDLFVBQUlBLElBQUcsU0FBU0QsTUFBSyxLQUFLLEtBQUssWUFBWSxRQUFRLENBQUMsRUFBRSxZQUFZO0FBQ2hFO0FBQ0YsWUFBTSxjQUFjQyxJQUFHO0FBQUEsUUFDckJELE1BQUssS0FBSyxLQUFLLFlBQVksUUFBUTtBQUFBLFFBQ25DO0FBQUEsTUFDRjtBQUNBLFlBQU0sS0FBSyxLQUFLLEtBQUssb0JBQW9CO0FBQUEsUUFDdkMsTUFBTTtBQUFBLFVBQ0osV0FBVztBQUFBLFVBQ1gsY0FBYztBQUFBLFVBQ2QsV0FBVztBQUFBLFFBQ2I7QUFBQSxNQUNGLENBQUM7QUFBQSxJQUNIO0FBQUEsRUFDRjtBQUFBLEVBRUEsTUFBTSxPQUFPO0FBQ1gsU0FBSyxZQUFZLE1BQU07QUFDdkIsU0FBSyxlQUFlLEtBQUs7QUFBQSxFQUMzQjtBQUNGOzs7QUYzSk8sSUFBTSxjQUFjLENBQUNFLGFBQXFCO0FBQy9DLEVBQUFBLFNBQ0csUUFBUSxLQUFLLEVBQ2IsWUFBWSx3Q0FBd0MsRUFDcEQsU0FBUyxVQUFVLDBCQUEwQixFQUM3QyxPQUFPLHVCQUF1Qix5QkFBeUIsTUFBTSxFQUM3RCxPQUFPLE9BQU8sTUFBYyxZQUE4QjtBQUN6RCxVQUFNLE9BQU8sU0FBUyxRQUFRLElBQUk7QUFDbEMsUUFBSTtBQUVKLFFBQUksTUFBTTtBQUNSLHFCQUFvQixjQUFRLElBQUk7QUFBQSxJQUNsQyxPQUFPO0FBQ0wsWUFBTSxpQkFBc0IsY0FBUSxXQUFXO0FBQy9DLFVBQU8sZUFBVyxjQUFjLEdBQUc7QUFDakMsdUJBQWU7QUFDZixnQkFBUSxJQUFJLHdEQUF3RDtBQUFBLE1BQ3RFLE9BQU87QUFDTCxnQkFBUTtBQUFBLFVBQ047QUFBQSxRQUNGO0FBQ0E7QUFBQSxNQUNGO0FBQUEsSUFDRjtBQUVBLFVBQU0sVUFBZSxjQUFRLFlBQVk7QUFFekMsUUFBSTtBQUNGLGNBQVEsSUFBSSwyQ0FBMkM7QUFDdkQsWUFBTSxpQ0FBaUMsWUFBWTtBQUNuRCxjQUFRLElBQUksOEJBQThCO0FBQUEsSUFDNUMsU0FBUyxPQUFPO0FBQ2QsY0FBUSxLQUFLLDRCQUE0QixLQUFLO0FBQUEsSUFDaEQ7QUFFQSxVQUFNLFNBQVMsSUFBSSxVQUFVO0FBQUEsTUFDM0I7QUFBQSxNQUNBLG1CQUFtQjtBQUFBLElBQ3JCLENBQUM7QUFFRCxVQUFNLE9BQU8sTUFBTTtBQUNuQixVQUFNLE9BQU8sY0FBYztBQUFBLEVBQzdCLENBQUM7QUFDTDs7O0FTckRBLE9BQU8saUJBQWlCO0FBU2pCLElBQU0sWUFBeUMsSUFBSTtBQUFBLEVBQ3hEO0FBQ0Y7QUFFTyxJQUFNLG9CQUFvQixNQUFjO0FBQzdDLFNBQU8sVUFBVSxJQUFJLGdCQUFnQixLQUFLO0FBQzVDOzs7QUNiQSxPQUFPLFdBQVc7OztBQ0RsQixPQUFPQyxTQUFvQztBQUUzQyxJQUFNLDBCQUE2QyxPQUNqRCxVQUNBLFVBQ0EsYUFDRztBQUNILE1BQUksQ0FBQyxTQUFTLElBQUk7QUFDaEIsUUFBSTtBQUNGLFlBQU0sWUFBWSxNQUFNLFNBQVMsS0FBSztBQUN0QyxZQUFNLElBQUk7QUFBQSxRQUNSLFNBQVMsU0FBUyxNQUFNLE1BQU0sU0FBUyxNQUFNLElBQzNDLElBQUksSUFBSSxTQUFTLEdBQUcsRUFBRSxRQUN4QjtBQUFBO0FBQUEsR0FBUyxLQUFLLFVBQVUsV0FBVyxNQUFNLENBQUMsQ0FBQztBQUFBLE1BQzdDO0FBQUEsSUFDRixTQUFTLEdBQUc7QUFBQSxJQUVaO0FBQUEsRUFDRjtBQUNGO0FBRU8sSUFBTSxRQUFRLE1BQU07QUFDekIsU0FBT0EsSUFBRyxPQUFPO0FBQUEsSUFDZixXQUFXLGtCQUFrQjtBQUFBLElBQzdCLE9BQU87QUFBQSxNQUNMLGVBQWUsQ0FBQyx1QkFBdUI7QUFBQSxJQUN6QztBQUFBLEVBQ0YsQ0FBQztBQUNIOzs7QUR2Qk8sSUFBTSxvQkFBb0IsQ0FBQ0MsYUFBcUI7QUFFckQsUUFBTSxjQUFjLFlBQVk7QUFDOUIsVUFBTUMsTUFBSyxNQUFNO0FBRWpCLFVBQU0sRUFBRSxXQUFXLElBQUksTUFBTUEsSUFDMUI7QUFBQSxNQUNDO0FBQUEsTUFDQTtBQUFBLFFBQ0UsTUFBTSxDQUFDO0FBQUEsTUFDVDtBQUFBLElBQ0YsRUFDQyxLQUFLO0FBRVIsWUFBUSxJQUFJLDJDQUEyQztBQUN2RCxZQUFRLElBQUksV0FBVyxHQUFHO0FBRzFCLFdBQU8sTUFBTTtBQUNYLFlBQU0sRUFBRSxZQUFZLGVBQWUsSUFBSSxNQUFNQSxJQUMxQztBQUFBLFFBQ0M7QUFBQSxRQUNBO0FBQUEsVUFDRSxNQUFNO0FBQUEsWUFDSixlQUFlLFdBQVc7QUFBQSxVQUM1QjtBQUFBLFVBQ0EsU0FBUztBQUFBLFlBQ1AsZUFBZSxVQUFVLFdBQVcscUJBQXFCO0FBQUEsVUFDM0Q7QUFBQSxRQUNGO0FBQUEsTUFDRixFQUNDLEtBQUs7QUFFUixVQUFJLGVBQWUsc0JBQXNCO0FBQ3ZDLGdCQUFRLElBQUksZ0NBQWdDO0FBQzVDO0FBQUEsTUFDRjtBQUVBLFVBQUksZUFBZSxZQUFZO0FBQzdCLGNBQU0sSUFBSSxNQUFNLG9CQUFvQjtBQUFBLE1BQ3RDO0FBRUEsWUFBTSxNQUFNLEdBQUk7QUFBQSxJQUNsQjtBQUVBLFVBQU0sRUFBRSxRQUFRLElBQUksTUFBTUEsSUFDdkI7QUFBQSxNQUNDO0FBQUEsTUFDQTtBQUFBLFFBQ0UsTUFBTTtBQUFBLFVBQ0osZUFBZSxXQUFXO0FBQUEsUUFDNUI7QUFBQSxRQUNBLFNBQVM7QUFBQSxVQUNQLGVBQWUsVUFBVSxXQUFXLHFCQUFxQjtBQUFBLFFBQzNEO0FBQUEsTUFDRjtBQUFBLElBQ0YsRUFDQyxLQUFLO0FBRVIsY0FBVSxJQUFJLGdCQUFnQixRQUFRLEtBQUs7QUFFM0MsWUFBUSxJQUFJLGVBQWU7QUFBQSxFQUM3QjtBQUdBLEVBQUFELFNBQVEsU0FDTCxLQUFLLENBQUMsTUFBTSxFQUFFLEtBQUssTUFBTSxNQUFNLEVBQy9CLFFBQVEsT0FBTyxFQUNmLFlBQVkscUNBQXFDLEVBQ2pELE9BQU8sV0FBVztBQUdyQixFQUFBQSxTQUNHLFFBQVEsT0FBTyxFQUNmLFlBQVksNkJBQTZCLEVBQ3pDLE9BQU8sV0FBVztBQUN2Qjs7O0FFaEZPLElBQU0scUJBQXFCLENBQUNFLGFBQXFCO0FBQ3RELEVBQUFBLFNBQVEsU0FDTCxLQUFLLENBQUMsTUFBTSxFQUFFLEtBQUssTUFBTSxNQUFNLEVBQy9CLFFBQVEsUUFBUSxFQUNoQixZQUFZLHNCQUFzQixFQUNsQyxPQUFPLENBQUMsU0FBUztBQUNoQixZQUFRLElBQUksUUFBUTtBQUFBLEVBQ3RCLENBQUM7QUFDTDs7O0FDUk8sSUFBTSxlQUFlLENBQUNDLGFBQXFCO0FBQ2hELEVBQUFBLFNBQVEsUUFBUSxNQUFNLEVBQUUsWUFBWSxjQUFjO0FBQ3BEOzs7QUNGTyxJQUFNLGlCQUFpQixDQUFDQyxhQUFxQjtBQUNsRCxFQUFBQSxTQUFRLFFBQVEsUUFBUSxFQUFFLFlBQVksb0NBQW9DO0FBQzVFOzs7QUNETyxJQUFNLHNCQUFzQixDQUFDQyxhQUFxQjtBQUN2RCxFQUFBQSxTQUFRLFNBQ0wsS0FBSyxDQUFDLE1BQU0sRUFBRSxLQUFLLE1BQU0sUUFBUSxFQUNqQyxRQUFRLE9BQU8sRUFDZixZQUFZLDBCQUEwQixFQUN0QyxPQUFPLE1BQU07QUFDWixZQUFRLElBQUksS0FBSyxVQUFVLFVBQVUsS0FBSyxNQUFNLENBQUMsQ0FBQztBQUFBLEVBQ3BELENBQUM7QUFDTDs7O0FDVEEsWUFBWUMsU0FBUTtBQUNwQixZQUFZQyxXQUFVO0FBRWYsSUFBTSxnQkFBZ0IsQ0FBQ0MsYUFBcUI7QUFDakQsRUFBQUEsU0FDRyxRQUFRLE9BQU8sRUFDZixZQUFZLG1DQUFtQyxFQUMvQyxTQUFTLGFBQWEsNENBQTRDLEVBQ2xFLE9BQU8sT0FBTyxnQkFBd0I7QUFDckMsUUFBSTtBQUNKLFFBQUk7QUFDSixRQUFJLENBQUMsWUFBWSxXQUFXLFFBQVEsS0FBSyxZQUFZLFNBQVMsR0FBRyxHQUFHO0FBQ2xFO0FBQUMsT0FBQyxRQUFRLFdBQVcsSUFBSSxZQUFZLE1BQU0sR0FBRztBQUFBLElBQ2hELE9BQU87QUFDTCxZQUFNLGNBQWMsWUFBWSxRQUFRLFVBQVUsRUFBRTtBQUNwRCxZQUFNLGdCQUFnQixZQUFZLFFBQVEsR0FBRztBQUM3QyxlQUFTLFlBQVksTUFBTSxHQUFHLGFBQWE7QUFDM0Msb0JBQWMsWUFBWSxNQUFNLGdCQUFnQixDQUFDO0FBQUEsSUFDbkQ7QUFFQSxRQUFJLENBQUMsVUFBVSxDQUFDLGFBQWE7QUFDM0IsY0FBUTtBQUFBLFFBQ047QUFBQSxNQUNGO0FBQ0EsY0FBUSxLQUFLLENBQUM7QUFBQSxJQUNoQjtBQUVBLFVBQU1DLE1BQUssTUFBTTtBQUVqQixRQUFJO0FBQ0YsY0FBUSxJQUFJLFdBQVcsTUFBTSxJQUFJLFdBQVcsS0FBSztBQUVqRCxZQUFNLGtCQUFrQixNQUFNQSxJQUMzQixLQU9FLHNCQUFzQjtBQUFBLFFBQ3ZCLE1BQU07QUFBQSxVQUNKLGNBQWMsR0FBRyxNQUFNLElBQUksV0FBVztBQUFBLFVBQ3RDLG9CQUFvQjtBQUFBLFFBQ3RCO0FBQUEsTUFDRixDQUFDLEVBQ0EsS0FBSztBQUdSLFlBQU0sVUFBVSxLQUFLLE1BQU0sSUFBSSxXQUFXO0FBQzFDLFVBQUksQ0FBSSxlQUFXLE9BQU8sR0FBRztBQUMzQixRQUFHLGNBQVUsT0FBTztBQUFBLE1BQ3RCO0FBR0EsaUJBQVcsWUFBWSxnQkFBZ0IsZUFBZTtBQUNwRCxjQUFNLFdBQVcsU0FBUyxVQUFVLFdBQVcsR0FBRyxJQUM5QyxTQUFTLFVBQVUsTUFBTSxDQUFDLElBQzFCLFNBQVM7QUFFYixZQUFJLFNBQVMsV0FBVyxPQUFPLEVBQUc7QUFFbEMsY0FBTSxjQUFjLE1BQU1BLElBQ3ZCLEtBSUUscUJBQXFCO0FBQUEsVUFDdEIsTUFBTTtBQUFBLFlBQ0osY0FBYyxHQUFHLE1BQU0sSUFBSSxXQUFXO0FBQUEsWUFDdEMsV0FBVyxTQUFTO0FBQUEsVUFDdEI7QUFBQSxRQUNGLENBQUMsRUFDQSxLQUFLO0FBRVIsY0FBTSxXQUFnQixXQUFLLFNBQVMsUUFBUTtBQUM1QyxjQUFNLFVBQWUsY0FBUSxRQUFRO0FBR3JDLFlBQUksQ0FBSSxlQUFXLE9BQU8sR0FBRztBQUMzQixVQUFHLGNBQVUsU0FBUyxFQUFFLFdBQVcsS0FBSyxDQUFDO0FBQUEsUUFDM0M7QUFFQSxRQUFHLGtCQUFjLFVBQVUsWUFBWSxhQUFhLFlBQVk7QUFBQSxNQUNsRTtBQUVBLFlBQU0sWUFBaUIsV0FBSyxTQUFTLFFBQVE7QUFDN0MsTUFBRyxrQkFBYyxXQUFXLDBDQUEwQztBQUV0RSxjQUFRLElBQUksNEJBQTRCLE1BQU0sSUFBSSxXQUFXLEdBQUc7QUFBQSxJQUNsRSxTQUFTLE9BQU87QUFDZCxVQUFJLGlCQUFpQixPQUFPO0FBQzFCLGdCQUFRLE1BQU0sNEJBQTRCLE1BQU0sT0FBTztBQUFBLE1BQ3pELE9BQU87QUFDTCxnQkFBUSxNQUFNLDRCQUE0QixLQUFLO0FBQUEsTUFDakQ7QUFDQSxjQUFRLEtBQUssQ0FBQztBQUFBLElBQ2hCO0FBQUEsRUFDRixDQUFDO0FBQ0w7OztBbEIzRkEsU0FBUyxrQkFBa0I7QUFFM0IsT0FBTyxZQUFZOzs7QW1CWG5CLFNBQVMsOEJBQThCO0FBQ3ZDLE9BQU8sd0JBQXdCO0FBQy9CLFNBQVMsdUNBQXVDO0FBQ2hELE9BQU9DLFdBQVU7QUFDakIsT0FBT0MsU0FBUTtBQUVmLElBQU0sa0JBQWtCO0FBQUEsRUFDdEI7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQ0Y7QUFJQSxJQUFNLG9CQUFvQjtBQUFBLEVBQ3hCLE1BQU07QUFBQSxFQUNOLGdCQUFnQjtBQUFBLEVBQ2hCLGlCQUFpQjtBQUFBLEVBQ2pCLFdBQVc7QUFBQSxFQUNYLFNBQVM7QUFBQSxFQUNULG9CQUFvQjtBQUFBLEVBQ3BCLE1BQU07QUFBQSxFQUNOLGdCQUFnQjtBQUNsQjtBQUVPLElBQU0saUJBQWlCLENBQUNDLGFBQXFCO0FBQ2xELEVBQUFBLFNBQ0csUUFBUSxRQUFRLEVBQ2hCLFlBQVksMENBQTBDLEVBQ3RELFNBQVMsVUFBVSwwQkFBMEIsRUFDN0MsT0FBTyx5QkFBeUIsZUFBZSxFQUMvQyxPQUFPLHVCQUF1QixrQkFBa0IsRUFDaEQsT0FBTyxPQUFPLE1BQU0sWUFBWTtBQUMvQixVQUFNLEVBQUUsU0FBUyxlQUFlLElBQUk7QUFDcEMsUUFBSSxFQUFFLE9BQU8sSUFBSTtBQUNqQixRQUFJLENBQUMsZ0JBQWdCLFNBQVMsTUFBTSxHQUFHO0FBQ3JDLFlBQU0sSUFBSTtBQUFBLFFBQ1IsbUJBQW1CLE1BQU07QUFBQSxxQkFBd0IsZ0JBQWdCLEtBQUssR0FBRyxDQUFDO0FBQUEsTUFDNUU7QUFBQSxJQUNGO0FBRUEsUUFBSSxDQUFDLFFBQVE7QUFDWCxlQUFTRixNQUFLLFNBQVMsSUFBSSxFQUFFLFFBQVEsWUFBWSxFQUFFO0FBQUEsSUFDckQ7QUFFQSxVQUFNLFNBQVMsTUFBTSx1QkFBdUI7QUFBQSxNQUMxQyxjQUFjO0FBQUEsSUFDaEIsQ0FBQztBQUVELFVBQU0sYUFBYUEsTUFBSyxRQUFRLElBQUk7QUFFcEMsVUFBTSx3QkFBd0JBLE1BQUssU0FBUyxZQUFZLElBQUk7QUFFNUQsVUFBTSxPQUFPLGlCQUFpQjtBQUFBLE1BQzVCLFlBQVk7QUFBQSxNQUNaLE9BQU87QUFBQSxRQUNMLEdBQUssTUFBTSxnQ0FBZ0M7QUFBQSxVQUN6QyxTQUFTO0FBQUEsVUFDVCxlQUFlO0FBQUEsUUFDakIsQ0FBQztBQUFBLFFBQ0Qsa0JBQWtCO0FBQUEsMkJBQ0QscUJBQXFCO0FBQUE7QUFBQTtBQUFBO0FBQUEsTUFJeEM7QUFBQSxJQUNGLENBQUM7QUFFRCxVQUFNLE9BQU8sbUJBQW1CO0FBRWhDLFVBQU0sY0FBYyxNQUFNLE9BQU8sZUFBZTtBQUVoRCxVQUFNLGFBQWFBLE1BQUs7QUFBQSxNQUN0QjtBQUFBLE1BQ0EsR0FBRyxNQUFNLEdBQUcsa0JBQWtCLE1BQWdCLENBQUM7QUFBQSxJQUNqRDtBQUVBLElBQUFDLElBQUcsY0FBYyxZQUFZLEtBQUssVUFBVSxXQUFXLENBQUM7QUFFeEQsWUFBUSxJQUFJLGVBQWUsVUFBVSxFQUFFO0FBRXZDLFlBQVEsS0FBSyxDQUFDO0FBQUEsRUFDaEIsQ0FBQztBQUNMOzs7QUN0Rk8sSUFBTSx5QkFBeUIsQ0FBQ0UsYUFBcUI7QUFDMUQsRUFBQUEsU0FBUSxTQUNMLEtBQUssQ0FBQyxNQUFNLEVBQUUsS0FBSyxNQUFNLE1BQU0sRUFDL0IsUUFBUSxhQUFhLEVBQ3JCLFlBQVksd0JBQXdCLEVBQ3BDLE9BQU8sTUFBTTtBQUNaLFVBQU0sUUFBUSxVQUFVLElBQUksY0FBYztBQUMxQyxRQUFJLENBQUMsTUFBTyxRQUFPLFFBQVEsSUFBSSxvQ0FBb0M7QUFDbkUsWUFBUSxJQUFJLGlCQUFpQixLQUFLO0FBQUEsRUFDcEMsQ0FBQztBQUNMOzs7QUNWQSxTQUFTLGtCQUFrQixPQUFlO0FBQ3hDLFFBQU0sUUFBUSxNQUFNLE1BQU0sR0FBRztBQUU3QixNQUFJLE1BQU0sV0FBVyxLQUFLLE1BQU0sTUFBTSxDQUFDLFNBQVMsS0FBSyxTQUFTLENBQUMsR0FBRztBQUNoRSxXQUFPO0FBQUEsRUFDVCxPQUFPO0FBQ0wsV0FBTztBQUFBLEVBQ1Q7QUFDRjtBQUNPLElBQU0sdUJBQXVCLENBQUNDLGFBQXFCO0FBQ3hELEVBQUFBLFNBQVEsU0FDTCxLQUFLLENBQUMsTUFBTSxFQUFFLEtBQUssTUFBTSxNQUFNLEVBQy9CLFFBQVEsV0FBVyxFQUNuQixZQUFZLGdDQUFnQyxFQUM1QyxTQUFTLFdBQVcsaUNBQWlDLEVBQ3JELE9BQU8sQ0FBQyxVQUFVO0FBQ2pCLFFBQUksQ0FBQyxrQkFBa0IsS0FBSztBQUMxQixhQUFPLFFBQVEsSUFBSSx3QkFBd0I7QUFDN0MsY0FBVSxJQUFJLGdCQUFnQixLQUFLO0FBQ25DLFlBQVEsSUFBSSx5QkFBeUI7QUFBQSxFQUN2QyxDQUFDO0FBQ0w7OztBckJQQSxJQUFNLFVBQVUsSUFBSSxRQUFRO0FBRTVCLFFBQ0csS0FBSyxNQUFNLEVBQ1gsWUFBWSx1Q0FBdUMsRUFHbkQsUUFBUSxPQUFPLElBQUksZ0JBQUksU0FBUyxPQUFPLEtBQUssZ0JBQUksT0FBTztBQUUxRCxhQUFhLE9BQU87QUFFcEIsWUFBWSxPQUFPO0FBQ25CLGNBQWMsT0FBTztBQUVyQixhQUFhLE9BQU87QUFDcEIsa0JBQWtCLE9BQU87QUFDekIsbUJBQW1CLE9BQU87QUFDMUIsdUJBQXVCLE9BQU87QUFDOUIscUJBQXFCLE9BQU87QUFFNUIsZUFBZSxPQUFPO0FBQ3RCLG9CQUFvQixPQUFPO0FBRTNCLGVBQWUsT0FBTztBQUV0QixJQUFJLFFBQVEsS0FBSyxXQUFXLEdBQUc7QUFDN0IsYUFBVyxTQUFTLFFBQVEsSUFBSTtBQUNsQyxPQUFPO0FBQ0wsVUFBUSxNQUFNO0FBQ2hCOyIsCiAgIm5hbWVzIjogWyJwcm9ncmFtIiwgInBhdGgiLCAiZnMiLCAiZnMiLCAicGF0aCIsICJmcyIsICJwYXRoIiwgInJlc29sdmUiLCAicGF0aCIsICJmcyIsICJmcyIsICJwYXRoIiwgImZzIiwgInRzIiwgInBhdGgiLCAiZnMiLCAicHJvZ3JhbSIsICJreSIsICJwcm9ncmFtIiwgImt5IiwgInByb2dyYW0iLCAicHJvZ3JhbSIsICJwcm9ncmFtIiwgInByb2dyYW0iLCAiZnMiLCAicGF0aCIsICJwcm9ncmFtIiwgImt5IiwgInBhdGgiLCAiZnMiLCAicHJvZ3JhbSIsICJwcm9ncmFtIiwgInByb2dyYW0iXQp9Cg==
@@ -0,0 +1,68 @@
1
+ import * as fs from "node:fs"
2
+ import * as path from "node:path"
3
+ import { findImportsInSnippet } from "./findImportsInSnippet"
4
+ import { installNodeModuleTypesForSnippet } from "./installNodeModuleTypesForSnippet"
5
+
6
+ export class FilesystemTypesHandler {
7
+ private projectRoot: string
8
+
9
+ constructor(initialDir: string) {
10
+ this.projectRoot = this.findProjectRoot(initialDir)
11
+ }
12
+
13
+ async handleInitialTypeDependencies(filePath: string) {
14
+ console.log("Checking initial type dependencies...")
15
+ try {
16
+ if (!this.areTypesInstalled(filePath)) {
17
+ console.log("Installing missing initial types...")
18
+ await installNodeModuleTypesForSnippet(filePath)
19
+ }
20
+ } catch (error) {
21
+ console.warn("Error handling initial type dependencies:", error)
22
+ }
23
+ }
24
+
25
+ async handleFileTypeDependencies(filePath: string) {
26
+ try {
27
+ if (!this.areTypesInstalled(filePath)) {
28
+ console.log("Installing missing file types...")
29
+ await installNodeModuleTypesForSnippet(filePath)
30
+ }
31
+ } catch (error) {
32
+ console.warn("Failed to verify types:", error)
33
+ }
34
+ }
35
+
36
+ private areTypesInstalled(filePath: string): boolean {
37
+ const imports = findImportsInSnippet(filePath)
38
+ return imports.every((imp) => this.checkTypeExists(imp))
39
+ }
40
+
41
+ private checkTypeExists(importPath: string): boolean {
42
+ if (!importPath.startsWith("@tsci/")) return true
43
+
44
+ const pathWithoutPrefix = importPath.replace("@tsci/", "")
45
+ const [owner, name] = pathWithoutPrefix.split(".")
46
+
47
+ const typePath = path.join(
48
+ this.projectRoot,
49
+ "node_modules",
50
+ "@tsci",
51
+ `${owner}.${name}`,
52
+ "index.d.ts",
53
+ )
54
+
55
+ return fs.existsSync(typePath)
56
+ }
57
+
58
+ private findProjectRoot(startDir: string): string {
59
+ let root = path.resolve(startDir)
60
+ while (root !== path.parse(root).root) {
61
+ if (fs.existsSync(path.join(root, "package.json"))) {
62
+ return root
63
+ }
64
+ root = path.dirname(root)
65
+ }
66
+ return startDir
67
+ }
68
+ }
@@ -0,0 +1,31 @@
1
+ import * as fs from "node:fs"
2
+ import * as ts from "typescript"
3
+
4
+ export function findImportsInSnippet(snippetPath: string): string[] {
5
+ const content = fs.readFileSync(snippetPath, "utf-8")
6
+ const sourceFile = ts.createSourceFile(
7
+ snippetPath,
8
+ content,
9
+ ts.ScriptTarget.Latest,
10
+ true,
11
+ )
12
+
13
+ const imports: string[] = []
14
+
15
+ function visit(node: ts.Node) {
16
+ if (ts.isImportDeclaration(node)) {
17
+ const moduleSpecifier = node.moduleSpecifier
18
+ if (moduleSpecifier && ts.isStringLiteral(moduleSpecifier)) {
19
+ const importPath = moduleSpecifier.text
20
+ if (importPath.startsWith("@tsci/")) {
21
+ imports.push(importPath)
22
+ }
23
+ }
24
+ }
25
+ ts.forEachChild(node, visit)
26
+ }
27
+
28
+ visit(sourceFile)
29
+
30
+ return imports
31
+ }
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@tscircuit/cli",
3
3
  "main": "dist/main.js",
4
4
  "type": "module",
5
- "version": "0.1.16",
5
+ "version": "0.1.17",
6
6
  "bin": {
7
7
  "tsci": "./dist/main.js"
8
8
  },
@@ -0,0 +1,65 @@
1
+ import { test, expect, afterEach } from "bun:test"
2
+ import { DevServer } from "cli/dev/DevServer"
3
+ import { getTestFixture } from "tests/fixtures/get-test-fixture"
4
+ import fs from "node:fs"
5
+ import path from "node:path"
6
+
7
+ async function waitForFile(
8
+ filePath: string,
9
+ timeout: number = 5000,
10
+ interval: number = 500,
11
+ ): Promise<boolean> {
12
+ const endTime = Date.now() + timeout
13
+ while (Date.now() < endTime) {
14
+ if (fs.existsSync(filePath)) {
15
+ return true
16
+ }
17
+ await new Promise((resolve) => setTimeout(resolve, interval))
18
+ }
19
+ return false
20
+ }
21
+
22
+ test("types are installed and refreshed when files change", async () => {
23
+ const { tempDirPath, devServerPort } = await getTestFixture({
24
+ vfs: {
25
+ "snippet.tsx": `
26
+ import { useRedLed } from "@tsci/seveibar.red-led"
27
+ export const MyCircuit = () => <></>
28
+ `,
29
+ "package.json": "{}",
30
+ },
31
+ })
32
+
33
+ const devServer = new DevServer({
34
+ port: devServerPort,
35
+ componentFilePath: `${tempDirPath}/snippet.tsx`,
36
+ })
37
+
38
+ await devServer.start()
39
+
40
+ // Wait for the initial type file to be installed
41
+ const typePath = path.join(
42
+ tempDirPath,
43
+ "node_modules/@tsci/seveibar.red-led/index.d.ts",
44
+ )
45
+ const typeFileExists = await waitForFile(typePath)
46
+ expect(typeFileExists).toBe(true)
47
+
48
+ // Simulate file change with new import
49
+ const updatedContent = `
50
+ import { useUsbC } from "@tsci/seveibar.smd-usb-c"
51
+ export const MyCircuit = () => <></>
52
+ `
53
+ fs.writeFileSync(`${tempDirPath}/snippet.tsx`, updatedContent)
54
+
55
+ // Wait for the new type file to be installed after update
56
+ const typePath2 = path.join(
57
+ tempDirPath,
58
+ "node_modules/@tsci/seveibar.smd-usb-c/index.d.ts",
59
+ )
60
+ const typeFileExists2 = await waitForFile(typePath2)
61
+ expect(typeFileExists2).toBe(true)
62
+
63
+ // Stop the dev server after the test
64
+ await devServer.stop()
65
+ }, 10_000)