@cdktn/provider-generator 0.23.0-pre.36 → 0.23.0-pre.39

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (179) hide show
  1. package/build/__tests__/edge-provider-schema/builder.js +106 -0
  2. package/build/__tests__/edge-provider-schema/cli.js +67 -0
  3. package/build/__tests__/edge-provider-schema/index.js +154 -0
  4. package/build/__tests__/edge-provider-schema.test.js +46 -0
  5. package/build/__tests__/provider.test.js +158 -0
  6. package/build/get/__tests__/constructs-maker.test.js +113 -0
  7. package/build/get/__tests__/generator/complex-computed-types.test.js +42 -0
  8. package/build/get/__tests__/generator/deep-nested-attributes.test.js +50 -0
  9. package/build/get/__tests__/generator/description-escaping.test.js +65 -0
  10. package/build/get/__tests__/generator/empty-provider-resources.test.js +40 -0
  11. package/build/get/__tests__/generator/export-sharding.test.js +82 -0
  12. package/build/get/__tests__/generator/module-generator.test.js +476 -0
  13. package/build/get/__tests__/generator/nested-types.test.js +51 -0
  14. package/build/get/__tests__/generator/provider.test.js +51 -0
  15. package/build/get/__tests__/generator/resource-types.test.js +78 -0
  16. package/build/get/__tests__/generator/skipped-attributes.test.js +55 -0
  17. package/build/get/__tests__/generator/types.test.js +289 -0
  18. package/build/get/__tests__/generator/versions-file.test.js +74 -0
  19. package/build/get/__tests__/util.js +59 -0
  20. package/{lib → build}/get/constructs-maker.d.ts +1 -1
  21. package/build/get/constructs-maker.js +530 -0
  22. package/build/get/generator/custom-defaults.js +403 -0
  23. package/build/get/generator/emitter/attributes-emitter.js +161 -0
  24. package/{lib → build}/get/generator/emitter/index.js +1 -1
  25. package/build/get/generator/emitter/resource-emitter.js +144 -0
  26. package/build/get/generator/emitter/struct-emitter.js +500 -0
  27. package/build/get/generator/loop-detection.js +56 -0
  28. package/build/get/generator/models/attribute-model.js +160 -0
  29. package/build/get/generator/models/attribute-type-model.js +376 -0
  30. package/{lib → build}/get/generator/models/index.js +1 -1
  31. package/build/get/generator/models/resource-model.js +106 -0
  32. package/build/get/generator/models/scope.js +36 -0
  33. package/build/get/generator/models/struct.js +90 -0
  34. package/build/get/generator/module-generator.js +184 -0
  35. package/build/get/generator/provider-generator.js +225 -0
  36. package/build/get/generator/resource-parser.js +497 -0
  37. package/build/get/generator/sanitized-comments.js +44 -0
  38. package/build/get/generator/skipped-attributes.js +29 -0
  39. package/{lib → build}/index.js +1 -1
  40. package/build/util.js +30 -0
  41. package/package.json +6 -6
  42. package/tsconfig.json +5 -3
  43. package/lib/__tests__/edge-provider-schema/builder.js +0 -106
  44. package/lib/__tests__/edge-provider-schema/cli.js +0 -67
  45. package/lib/__tests__/edge-provider-schema/index.js +0 -154
  46. package/lib/__tests__/edge-provider-schema.test.js +0 -46
  47. package/lib/__tests__/provider.test.js +0 -158
  48. package/lib/get/__tests__/constructs-maker.test.js +0 -113
  49. package/lib/get/__tests__/generator/complex-computed-types.test.js +0 -42
  50. package/lib/get/__tests__/generator/deep-nested-attributes.test.js +0 -50
  51. package/lib/get/__tests__/generator/description-escaping.test.js +0 -65
  52. package/lib/get/__tests__/generator/empty-provider-resources.test.js +0 -40
  53. package/lib/get/__tests__/generator/export-sharding.test.js +0 -82
  54. package/lib/get/__tests__/generator/module-generator.test.js +0 -476
  55. package/lib/get/__tests__/generator/nested-types.test.js +0 -51
  56. package/lib/get/__tests__/generator/provider.test.js +0 -51
  57. package/lib/get/__tests__/generator/resource-types.test.js +0 -78
  58. package/lib/get/__tests__/generator/skipped-attributes.test.js +0 -55
  59. package/lib/get/__tests__/generator/types.test.js +0 -289
  60. package/lib/get/__tests__/generator/versions-file.test.js +0 -74
  61. package/lib/get/__tests__/util.js +0 -59
  62. package/lib/get/constructs-maker.js +0 -530
  63. package/lib/get/generator/custom-defaults.js +0 -403
  64. package/lib/get/generator/emitter/attributes-emitter.js +0 -161
  65. package/lib/get/generator/emitter/resource-emitter.js +0 -144
  66. package/lib/get/generator/emitter/struct-emitter.js +0 -500
  67. package/lib/get/generator/loop-detection.js +0 -56
  68. package/lib/get/generator/models/attribute-model.js +0 -160
  69. package/lib/get/generator/models/attribute-type-model.js +0 -376
  70. package/lib/get/generator/models/resource-model.js +0 -106
  71. package/lib/get/generator/models/scope.js +0 -36
  72. package/lib/get/generator/models/struct.js +0 -90
  73. package/lib/get/generator/module-generator.js +0 -184
  74. package/lib/get/generator/provider-generator.js +0 -225
  75. package/lib/get/generator/resource-parser.js +0 -497
  76. package/lib/get/generator/sanitized-comments.js +0 -44
  77. package/lib/get/generator/skipped-attributes.js +0 -29
  78. package/lib/util.js +0 -30
  79. /package/{lib → build}/__tests__/edge-provider-schema/builder.d.ts +0 -0
  80. /package/{lib → build}/__tests__/edge-provider-schema/cli.d.ts +0 -0
  81. /package/{lib → build}/__tests__/edge-provider-schema/index.d.ts +0 -0
  82. /package/{lib → build}/__tests__/edge-provider-schema.test.d.ts +0 -0
  83. /package/{lib → build}/__tests__/provider.test.d.ts +0 -0
  84. /package/{lib → build}/get/__tests__/constructs-maker.test.d.ts +0 -0
  85. /package/{lib → build}/get/__tests__/generator/complex-computed-types.test.d.ts +0 -0
  86. /package/{lib → build}/get/__tests__/generator/deep-nested-attributes.test.d.ts +0 -0
  87. /package/{lib → build}/get/__tests__/generator/description-escaping.test.d.ts +0 -0
  88. /package/{lib → build}/get/__tests__/generator/empty-provider-resources.test.d.ts +0 -0
  89. /package/{lib → build}/get/__tests__/generator/export-sharding.test.d.ts +0 -0
  90. /package/{lib → build}/get/__tests__/generator/module-generator.test.d.ts +0 -0
  91. /package/{lib → build}/get/__tests__/generator/nested-types.test.d.ts +0 -0
  92. /package/{lib → build}/get/__tests__/generator/provider.test.d.ts +0 -0
  93. /package/{lib → build}/get/__tests__/generator/resource-types.test.d.ts +0 -0
  94. /package/{lib → build}/get/__tests__/generator/skipped-attributes.test.d.ts +0 -0
  95. /package/{lib → build}/get/__tests__/generator/types.test.d.ts +0 -0
  96. /package/{lib → build}/get/__tests__/generator/versions-file.test.d.ts +0 -0
  97. /package/{lib → build}/get/__tests__/util.d.ts +0 -0
  98. /package/{lib → build}/get/generator/custom-defaults.d.ts +0 -0
  99. /package/{lib → build}/get/generator/emitter/attributes-emitter.d.ts +0 -0
  100. /package/{lib → build}/get/generator/emitter/index.d.ts +0 -0
  101. /package/{lib → build}/get/generator/emitter/resource-emitter.d.ts +0 -0
  102. /package/{lib → build}/get/generator/emitter/struct-emitter.d.ts +0 -0
  103. /package/{lib → build}/get/generator/loop-detection.d.ts +0 -0
  104. /package/{lib → build}/get/generator/models/attribute-model.d.ts +0 -0
  105. /package/{lib → build}/get/generator/models/attribute-type-model.d.ts +0 -0
  106. /package/{lib → build}/get/generator/models/index.d.ts +0 -0
  107. /package/{lib → build}/get/generator/models/resource-model.d.ts +0 -0
  108. /package/{lib → build}/get/generator/models/scope.d.ts +0 -0
  109. /package/{lib → build}/get/generator/models/struct.d.ts +0 -0
  110. /package/{lib → build}/get/generator/module-generator.d.ts +0 -0
  111. /package/{lib → build}/get/generator/provider-generator.d.ts +0 -0
  112. /package/{lib → build}/get/generator/resource-parser.d.ts +0 -0
  113. /package/{lib → build}/get/generator/sanitized-comments.d.ts +0 -0
  114. /package/{lib → build}/get/generator/skipped-attributes.d.ts +0 -0
  115. /package/{lib → build}/index.d.ts +0 -0
  116. /package/{lib → build}/util.d.ts +0 -0
  117. /package/{lib → src}/__tests__/__snapshots__/edge-provider-schema.test.ts.snap +0 -0
  118. /package/{lib → src}/__tests__/__snapshots__/provider.test.ts.snap +0 -0
  119. /package/{lib → src}/get/__tests__/generator/__snapshots__/complex-computed-types.test.ts.snap +0 -0
  120. /package/{lib → src}/get/__tests__/generator/__snapshots__/description-escaping.test.ts.snap +0 -0
  121. /package/{lib → src}/get/__tests__/generator/__snapshots__/export-sharding.test.ts.snap +0 -0
  122. /package/{lib → src}/get/__tests__/generator/__snapshots__/module-generator.test.ts.snap +0 -0
  123. /package/{lib → src}/get/__tests__/generator/__snapshots__/nested-types.test.ts.snap +0 -0
  124. /package/{lib → src}/get/__tests__/generator/__snapshots__/provider.test.ts.snap +0 -0
  125. /package/{lib → src}/get/__tests__/generator/__snapshots__/resource-types.test.ts.snap +0 -0
  126. /package/{lib → src}/get/__tests__/generator/__snapshots__/skipped-attributes.test.ts.snap +0 -0
  127. /package/{lib → src}/get/__tests__/generator/__snapshots__/types.test.ts.snap +0 -0
  128. /package/{lib → src}/get/__tests__/generator/fixtures/aws-provider.test.fixture.json +0 -0
  129. /package/{lib → src}/get/__tests__/generator/fixtures/aws_acm_certificate.test.fixture.json +0 -0
  130. /package/{lib → src}/get/__tests__/generator/fixtures/aws_cloudfront_distribution.test.fixture.json +0 -0
  131. /package/{lib → src}/get/__tests__/generator/fixtures/aws_fms_admin_account.test.fixture.json +0 -0
  132. /package/{lib → src}/get/__tests__/generator/fixtures/aws_quicksight_template.test.fixture.json +0 -0
  133. /package/{lib → src}/get/__tests__/generator/fixtures/aws_s3_bucket.test.fixture.json +0 -0
  134. /package/{lib → src}/get/__tests__/generator/fixtures/aws_security_group.test.fixture.json +0 -0
  135. /package/{lib → src}/get/__tests__/generator/fixtures/aws_wafv2_web_acl.test.fixture.json +0 -0
  136. /package/{lib → src}/get/__tests__/generator/fixtures/block-type-nested-computed-list.test.fixture.json +0 -0
  137. /package/{lib → src}/get/__tests__/generator/fixtures/block-type-set-list.test.fixture.json +0 -0
  138. /package/{lib → src}/get/__tests__/generator/fixtures/boolean-list.test.fixture.json +0 -0
  139. /package/{lib → src}/get/__tests__/generator/fixtures/boolean-map.test.fixture.json +0 -0
  140. /package/{lib → src}/get/__tests__/generator/fixtures/comment-ending-sequence.test.fixture.json +0 -0
  141. /package/{lib → src}/get/__tests__/generator/fixtures/computed-complex-nested.test.fixture.json +0 -0
  142. /package/{lib → src}/get/__tests__/generator/fixtures/computed-complex.test.fixture.json +0 -0
  143. /package/{lib → src}/get/__tests__/generator/fixtures/computed-optional-complex.test.fixture.json +0 -0
  144. /package/{lib → src}/get/__tests__/generator/fixtures/data_aws_quicksight_analysis.fixture.json +0 -0
  145. /package/{lib → src}/get/__tests__/generator/fixtures/datadog_dashboard.test.fixture.json +0 -0
  146. /package/{lib → src}/get/__tests__/generator/fixtures/datadog_spans_metric.test.fixture.json +0 -0
  147. /package/{lib → src}/get/__tests__/generator/fixtures/deep-attributes.test.fixture.json +0 -0
  148. /package/{lib → src}/get/__tests__/generator/fixtures/deeply-nested-block-types.test.fixture.json +0 -0
  149. /package/{lib → src}/get/__tests__/generator/fixtures/description-escaping.test.fixture.json +0 -0
  150. /package/{lib → src}/get/__tests__/generator/fixtures/elasticstack-provider.test.fixture.json +0 -0
  151. /package/{lib → src}/get/__tests__/generator/fixtures/empty-provider-resources.test.fixture.json +0 -0
  152. /package/{lib → src}/get/__tests__/generator/fixtures/ignored-attributes.test.fixture.json +0 -0
  153. /package/{lib → src}/get/__tests__/generator/fixtures/incompatible-attribute-names.test.fixture.json +0 -0
  154. /package/{lib → src}/get/__tests__/generator/fixtures/incompatible-resource-names.test.fixture.json +0 -0
  155. /package/{lib → src}/get/__tests__/generator/fixtures/list-list-object.test.fixture.json +0 -0
  156. /package/{lib → src}/get/__tests__/generator/fixtures/list-list-string.test.fixture.json +0 -0
  157. /package/{lib → src}/get/__tests__/generator/fixtures/list-of-string-map.test.fixture.json +0 -0
  158. /package/{lib → src}/get/__tests__/generator/fixtures/map-of-map-of-string.test.fixture.json +0 -0
  159. /package/{lib → src}/get/__tests__/generator/fixtures/map-of-string-list.test.fixture.json +0 -0
  160. /package/{lib → src}/get/__tests__/generator/fixtures/markdown-description-with-code-blocks.test.fixture.json +0 -0
  161. /package/{lib → src}/get/__tests__/generator/fixtures/module-get-x.test.fixture.tf +0 -0
  162. /package/{lib → src}/get/__tests__/generator/fixtures/module-no-newline-1.test.fixture.tf +0 -0
  163. /package/{lib → src}/get/__tests__/generator/fixtures/module-no-newline-2.test.fixture.tf +0 -0
  164. /package/{lib → src}/get/__tests__/generator/fixtures/module-no-outputs.test.fixture.tf +0 -0
  165. /package/{lib → src}/get/__tests__/generator/fixtures/module-no-variable-type.test.fixture.tf +0 -0
  166. /package/{lib → src}/get/__tests__/generator/fixtures/module-with-star-default.test.fixture.tf +0 -0
  167. /package/{lib → src}/get/__tests__/generator/fixtures/name-conflict.test.fixture.json +0 -0
  168. /package/{lib → src}/get/__tests__/generator/fixtures/nested-type-without-attributes.test.fixture.json +0 -0
  169. /package/{lib → src}/get/__tests__/generator/fixtures/nested-types.test.fixture.json +0 -0
  170. /package/{lib → src}/get/__tests__/generator/fixtures/number-list.test.fixture.json +0 -0
  171. /package/{lib → src}/get/__tests__/generator/fixtures/number-map.test.fixture.json +0 -0
  172. /package/{lib → src}/get/__tests__/generator/fixtures/primitive-boolean.test.fixture.json +0 -0
  173. /package/{lib → src}/get/__tests__/generator/fixtures/primitive-dynamic.test.fixture.json +0 -0
  174. /package/{lib → src}/get/__tests__/generator/fixtures/primitive-number.test.fixture.json +0 -0
  175. /package/{lib → src}/get/__tests__/generator/fixtures/primitive-string.test.fixture.json +0 -0
  176. /package/{lib → src}/get/__tests__/generator/fixtures/single-block-type.test.fixture.json +0 -0
  177. /package/{lib → src}/get/__tests__/generator/fixtures/string-list.test.fixture.json +0 -0
  178. /package/{lib → src}/get/__tests__/generator/fixtures/string-map.test.fixture.json +0 -0
  179. /package/{lib → src}/get/__tests__/generator/fixtures/stripe-schema.test.fixture.json +0 -0
@@ -0,0 +1,530 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ Object.defineProperty(exports, "__esModule", { value: true });
26
+ exports.determineGoModuleName = exports.ConstructsMaker = exports.generateJsiiLanguage = void 0;
27
+ // Copyright (c) HashiCorp, Inc
28
+ // SPDX-License-Identifier: MPL-2.0
29
+ const fs = __importStar(require("fs-extra"));
30
+ const path = __importStar(require("path"));
31
+ const codemaker_1 = require("codemaker");
32
+ const commons_1 = require("@cdktn/commons");
33
+ const commons_2 = require("@cdktn/commons");
34
+ const commons_3 = require("@cdktn/commons");
35
+ const provider_generator_1 = require("./generator/provider-generator");
36
+ const module_generator_1 = require("./generator/module-generator");
37
+ const glob_1 = require("glob");
38
+ const provider_schema_1 = require("@cdktn/provider-schema");
39
+ const pacmakModule = require.resolve("jsii-pacmak/bin/jsii-pacmak");
40
+ const jsiiModule = require.resolve("jsii/bin/jsii");
41
+ async function generateJsiiLanguage(code, opts, outputPath, disallowedFileGlobs = []) {
42
+ await (0, commons_1.mkdtemp)(async (staging) => {
43
+ // this is not typescript, so we generate in a staging directory and
44
+ // use jsii-srcmak to compile and extract the language-specific source
45
+ // into our project.
46
+ await code.save(staging);
47
+ // as the above generated the Typescript code for all providers and modules,
48
+ // we need to filter out the ones we don't need so they don't end up in the JSII bundle over and over again.
49
+ const filesToDelete = disallowedFileGlobs.flatMap((pattern) => glob_1.glob.sync(pattern, { cwd: staging }));
50
+ await Promise.all(filesToDelete.map((file) => fs.remove(path.join(staging, file))));
51
+ // Compile with JSII
52
+ const jsiiArgs = ["--silence-warnings", "reserved-word"];
53
+ const jsiiEntrypoint = opts.entrypoint;
54
+ const basepath = path.join(path.dirname(jsiiEntrypoint), path.basename(jsiiEntrypoint, ".ts"));
55
+ const moduleKey = opts.moduleKey.replace(/\./g, "").replace(/\//g, "");
56
+ const moduleDirs = opts.deps;
57
+ const targets = {};
58
+ const deps = {};
59
+ for (const dir of moduleDirs) {
60
+ // read module metadata
61
+ const metadata = await fs.readJson(path.join(dir, "package.json"));
62
+ const moduleName = metadata.name;
63
+ const moduleVersion = metadata.version;
64
+ const targetdir = path.join(path.join(staging, "node_modules"), moduleName);
65
+ await fs.mkdirp(path.dirname(targetdir));
66
+ await fs.copy(dir, targetdir);
67
+ // add to "deps" and "peer deps"
68
+ if (!moduleName.startsWith("@types/")) {
69
+ deps[moduleName] = moduleVersion;
70
+ }
71
+ }
72
+ const pkg = {
73
+ name: moduleKey,
74
+ version: "0.0.0",
75
+ author: "generated@generated.com",
76
+ main: `${basepath}.js`,
77
+ types: `${basepath}.d.ts`,
78
+ license: "UNLICENSED",
79
+ repository: { url: "http://generated", type: "git" },
80
+ jsii: {
81
+ outdir: "dist",
82
+ targets: targets,
83
+ },
84
+ dependencies: deps,
85
+ peerDependencies: deps,
86
+ };
87
+ if (opts.exports) {
88
+ pkg.exports = opts.exports;
89
+ }
90
+ if (opts.python) {
91
+ targets.python = {
92
+ distName: "generated",
93
+ module: opts.python.moduleName,
94
+ };
95
+ }
96
+ if (opts.java) {
97
+ targets.java = {
98
+ package: opts.java.package,
99
+ maven: {
100
+ groupId: "generated",
101
+ artifactId: "generated",
102
+ },
103
+ };
104
+ }
105
+ if (opts.csharp) {
106
+ targets.dotnet = {
107
+ namespace: opts.csharp.namespace,
108
+ packageId: opts.csharp.namespace,
109
+ };
110
+ }
111
+ if (opts.golang) {
112
+ targets.go = {
113
+ moduleName: opts.golang.moduleName,
114
+ packageName: opts.golang.packageName,
115
+ };
116
+ }
117
+ await fs.writeFile(path.join(staging, "package.json"), JSON.stringify(pkg, undefined, 2));
118
+ const endJsiiTimer = (0, commons_2.logTimespan)("jsii");
119
+ await (0, commons_1.exec)(jsiiModule, jsiiArgs, {
120
+ cwd: staging,
121
+ });
122
+ endJsiiTimer();
123
+ // extract .jsii if requested
124
+ if (opts.jsii) {
125
+ await fs.copy(path.join(staging, ".jsii"), opts.jsii.path);
126
+ }
127
+ // run pacmak to generate code
128
+ const endJsiiPacmakTimer = (0, commons_2.logTimespan)("jsii-pacmak");
129
+ await (0, commons_1.exec)(pacmakModule, ["--code-only"], { cwd: staging });
130
+ endJsiiPacmakTimer();
131
+ if (opts.python) {
132
+ const reldir = opts.python.moduleName.replace(/\./g, "/"); // jsii replaces "." with "/"
133
+ const source = path.resolve(path.join(staging, "dist/python/src", reldir));
134
+ const target = path.join(opts.python.outdir, reldir);
135
+ await fs.move(source, target, { overwrite: true });
136
+ }
137
+ if (opts.java) {
138
+ const source = path.resolve(path.join(staging, "dist/java/src/"));
139
+ const target = path.join(opts.java.outdir, "src/");
140
+ await fs.mkdirp(target); // make sure target directory exists
141
+ await fs.copy(source, target, { recursive: true, overwrite: false });
142
+ }
143
+ if (opts.csharp) {
144
+ const reldir = opts.csharp.namespace;
145
+ const source = path.resolve(path.join(staging, "dist/dotnet/", reldir));
146
+ const target = path.join(opts.csharp.outdir, reldir);
147
+ await fs.move(source, target, { overwrite: true });
148
+ }
149
+ if (opts.golang) {
150
+ const reldir = opts.golang.packageName;
151
+ const source = path.resolve(path.join(staging, "dist/go/", reldir));
152
+ const target = path.join(opts.golang.outdir, reldir);
153
+ await fs.move(source, target, { overwrite: true });
154
+ // remove go.mod as this would make it a submodule
155
+ await fs.remove(path.join(target, "go.mod"));
156
+ }
157
+ ["versions.json", "constraints.json"].forEach((file) => {
158
+ try {
159
+ fs.copySync(path.resolve(staging, file), path.resolve(outputPath, file));
160
+ }
161
+ catch (e) {
162
+ commons_2.logger.debug(`Failed to copy ${file}: ${e}`);
163
+ }
164
+ });
165
+ });
166
+ }
167
+ exports.generateJsiiLanguage = generateJsiiLanguage;
168
+ class ConstructsMaker {
169
+ constructor(options, schemaCachePath, reportTelemetry = async () => { }) {
170
+ this.options = options;
171
+ this.schemaCachePath = schemaCachePath;
172
+ this.reportTelemetry = reportTelemetry;
173
+ this.codeMakerOutdir = path.resolve(this.options.codeMakerOutput);
174
+ fs.mkdirpSync(this.codeMakerOutdir);
175
+ this.code = new codemaker_1.CodeMaker();
176
+ this.versions = {};
177
+ }
178
+ async generateTypescriptProvider(target, schema) {
179
+ const endTSTimer = (0, commons_2.logTimespan)(`Generate Typescript for ${target.name}`);
180
+ const generator = new provider_generator_1.TerraformProviderGenerator(this.code, schema);
181
+ generator.generate(target);
182
+ this.versions = { ...this.versions, ...generator.versions };
183
+ endTSTimer();
184
+ }
185
+ async filterAlreadyGenerated(constraints) {
186
+ let constraintsFile = "{}";
187
+ try {
188
+ constraintsFile = await fs.readFile(path.join(this.codeMakerOutdir, "constraints.json"), "utf8");
189
+ }
190
+ catch (e) {
191
+ commons_2.logger.debug(`Could not find constraints.json file while filtering: ${e}. This means no providers were generated, so all constraints need to be generated.`);
192
+ return constraints;
193
+ }
194
+ commons_2.logger.debug(`Found constraints.json file: ${constraintsFile}`);
195
+ let previousConstraints = {};
196
+ try {
197
+ previousConstraints = JSON.parse(constraintsFile);
198
+ }
199
+ catch (e) {
200
+ commons_2.logger.info(`Could not parse constraints.json file while filtering: ${e}. Generating all constraints.`);
201
+ return constraints;
202
+ }
203
+ commons_2.logger.debug(`Found previous constraints: ${JSON.stringify(previousConstraints, null, 2)}`);
204
+ if (!previousConstraints.providers ||
205
+ typeof previousConstraints.providers !== "object") {
206
+ commons_2.logger.info(`Could not find providers in constraints.json file, generating all constraints. The constraints file was ${JSON.stringify(previousConstraints, null, 2)}`);
207
+ return constraints;
208
+ }
209
+ if (previousConstraints.cdktf !== commons_3.DISPLAY_VERSION) {
210
+ commons_2.logger.info(`The CDKTN version has changed, generating all constraints. The previous version was ${previousConstraints.cdktf}, the current version is ${commons_3.DISPLAY_VERSION}`);
211
+ return constraints;
212
+ }
213
+ const constraintsToGenerate = constraints.filter((constraint) => {
214
+ const constraintMatches = previousConstraints.providers[constraint.fqn] === constraint.version;
215
+ let providerFolderExists = false;
216
+ switch (this.options.targetLanguage) {
217
+ case commons_3.Language.TYPESCRIPT:
218
+ providerFolderExists = fs.existsSync(path.join(this.codeMakerOutdir, "providers", constraint.name));
219
+ break;
220
+ case commons_3.Language.PYTHON:
221
+ case commons_3.Language.JAVA:
222
+ case commons_3.Language.CSHARP:
223
+ providerFolderExists = fs.existsSync(path.join(this.codeMakerOutdir, constraint.name));
224
+ break;
225
+ case commons_3.Language.GO:
226
+ providerFolderExists = fs.existsSync(path.join(this.codeMakerOutdir, constraint.namespace || "hashicorp", constraint.name));
227
+ break;
228
+ }
229
+ const providerExists = constraintMatches && providerFolderExists;
230
+ return !providerExists;
231
+ });
232
+ commons_2.logger.debug(`Constraints to generate: ${JSON.stringify(constraintsToGenerate, null, 2)}`);
233
+ return constraintsToGenerate;
234
+ }
235
+ async generateTypescriptModule(target, schema) {
236
+ const endTSTimer = (0, commons_2.logTimespan)(`Generate Typescript for ${target.name}`);
237
+ target.spec = schema;
238
+ new module_generator_1.ModuleGenerator(this.code, [target]);
239
+ endTSTimer();
240
+ }
241
+ async generateTypescript(target, schemas) {
242
+ var _a;
243
+ if (target.isModule) {
244
+ const schema = (_a = schemas.moduleSchema) === null || _a === void 0 ? void 0 : _a[target.moduleKey];
245
+ if (!schema) {
246
+ throw commons_2.Errors.Internal(`Could not generate schema for module ${target.moduleKey}`);
247
+ }
248
+ await this.generateTypescriptModule(target, schema);
249
+ }
250
+ else if (target.isProvider) {
251
+ if (!schemas.providerSchema) {
252
+ throw commons_2.Errors.Internal(`Could not generate schema for providers`);
253
+ }
254
+ await this.generateTypescriptProvider(target, schemas.providerSchema);
255
+ }
256
+ else {
257
+ throw new Error(`Unknown target type used to generate bindings: ${target.name}`);
258
+ }
259
+ }
260
+ // emits a versions.json file with a map of the used version for each provider fqpn
261
+ updateVersionsFile(allowedConstraints) {
262
+ commons_2.logger.debug(`Updating versions file with generated versions ${JSON.stringify(this.versions, null, 2)} with allowed constraints ${JSON.stringify(allowedConstraints, null, 2)}`);
263
+ const filePath = "versions.json";
264
+ let previousVersions = {};
265
+ try {
266
+ previousVersions = JSON.parse(fs.readFileSync(path.resolve(this.codeMakerOutdir, filePath), "utf8"));
267
+ commons_2.logger.debug(`Read existing versions file: ${JSON.stringify(previousVersions, null, 2)}`);
268
+ }
269
+ catch (e) {
270
+ // ignore
271
+ commons_2.logger.debug(`Could not read versions file, this is expected if there are no pre-existing local providers: ${e}`);
272
+ }
273
+ const versions = allowedConstraints.reduce((acc, constraint) => {
274
+ const provider = Object.entries(previousVersions).find(([name]) =>
275
+ // This could be more refined, but it's good enough for now
276
+ name.endsWith(constraint.fqn));
277
+ if (provider) {
278
+ const [name, version] = provider;
279
+ return { ...acc, [name]: version };
280
+ }
281
+ return acc;
282
+ }, {});
283
+ commons_2.logger.debug(`Writing versions file (${filePath}): ${JSON.stringify(versions, null, 2)}`);
284
+ this.code.openFile(filePath);
285
+ this.code.line(JSON.stringify({ ...versions, ...this.versions }, null, 2));
286
+ this.code.closeFile(filePath);
287
+ return filePath;
288
+ }
289
+ async removeFoldersThatShouldNotExist(constraintsThatShouldExist) {
290
+ commons_2.logger.debug(`Removing providers except for ${JSON.stringify(constraintsThatShouldExist, null, 2)}`);
291
+ // All languages besides TS keep their providers in the same folders as modules
292
+ // this makes it impossible for us to distinguish a no longer required provider
293
+ // from a manually written construct or a module
294
+ if (!this.isJavascriptTarget) {
295
+ return;
296
+ }
297
+ let filesInProviders = [];
298
+ const providersFolder = path.resolve(this.codeMakerOutdir, "providers");
299
+ try {
300
+ filesInProviders = await fs.readdir(providersFolder);
301
+ }
302
+ catch (e) {
303
+ commons_2.logger.debug(`Error listing files in providers folder '${providersFolder}': ${e}`);
304
+ }
305
+ const folders = filesInProviders.filter((file) => fs
306
+ .statSync(path.resolve(this.codeMakerOutdir, "providers", file))
307
+ .isDirectory());
308
+ return folders.forEach((folder) => {
309
+ const shouldExist = constraintsThatShouldExist.some((constraint) => constraint.name === folder);
310
+ if (!shouldExist) {
311
+ commons_2.logger.debug(`Removing folder ${folder} from providers`);
312
+ fs.removeSync(path.resolve(this.codeMakerOutdir, "providers", folder));
313
+ }
314
+ });
315
+ }
316
+ // emits a constraints.json file with a map of the used provider fqpns and version constraints
317
+ // this is used for caching purposes
318
+ emitConstraintsFile(allowedConstraints) {
319
+ const filePath = "constraints.json";
320
+ const content = {
321
+ cdktf: commons_3.DISPLAY_VERSION,
322
+ providers: allowedConstraints
323
+ .sort((a, b) => a.fqn.localeCompare(b.fqn))
324
+ .reduce((carry, item) => ({
325
+ ...carry,
326
+ [item.fqn]: item.version,
327
+ }), {}),
328
+ };
329
+ this.code.openFile(filePath);
330
+ this.code.line(JSON.stringify(content, null, 2));
331
+ this.code.closeFile(filePath);
332
+ return filePath;
333
+ }
334
+ async generateJsiiLanguage(target) {
335
+ var _a;
336
+ // these are the module dependencies we compile against
337
+ const deps = ["@types/node", "constructs", "cdktn"];
338
+ const opts = {
339
+ entrypoint: target.fileName,
340
+ deps: deps.map((dep) => path.dirname(require.resolve(`${dep}/package.json`))),
341
+ moduleKey: target.moduleKey,
342
+ exports: target.isProvider // Modules are small enough that we don't need this optimization
343
+ ? {
344
+ ".": {
345
+ import: `./providers/${target.name}/index.js`,
346
+ require: `./providers/${target.name}/lazy-index.js`,
347
+ },
348
+ }
349
+ : undefined,
350
+ };
351
+ // used for testing.
352
+ if (this.options.outputJsii) {
353
+ opts.jsii = { path: this.options.outputJsii };
354
+ }
355
+ if (this.isPythonTarget) {
356
+ opts.python = {
357
+ outdir: this.codeMakerOutdir,
358
+ moduleName: target.srcMakName,
359
+ };
360
+ }
361
+ if (this.isJavaTarget) {
362
+ if (this.options.codeMakerOutput.includes("/") ||
363
+ this.options.codeMakerOutput.includes("\\")) {
364
+ throw commons_2.Errors.Usage(`When using Java the "codeMakerOutput" option in the cdktf.json must be the organization identifier for your project (e.g. com.my-company), not a path. The generated Java code will be placed in a subdirectory of the given directory. If you are migrating from a < 0.19 version of cdktf you want to change the codemakerOutput to "imports".`);
365
+ }
366
+ opts.java = {
367
+ outdir: ".", // generated java files aren't packaged, so just include directly in app
368
+ package: `${this.options.codeMakerOutput}.${target.srcMakName}`,
369
+ };
370
+ }
371
+ if (this.isCsharpTarget) {
372
+ opts.csharp = {
373
+ outdir: this.codeMakerOutdir,
374
+ namespace: target.srcMakName,
375
+ };
376
+ }
377
+ if (this.isGoTarget) {
378
+ // TODO: check if needed for modules somehow
379
+ // const targetType = target.isProvider ? 'provider' : 'module';
380
+ // jsii-srcmac will produce a folder inside this dir named after "packageName"
381
+ // so this results in e.g. .gen/hashicorp/random
382
+ const outdir = path.join(this.codeMakerOutdir, (_a = target.namespace) !== null && _a !== void 0 ? _a : "");
383
+ opts.golang = {
384
+ outdir,
385
+ moduleName: await (0, exports.determineGoModuleName)(outdir), // e.g. `github.com/org/userproject/.gen/hashicorp`
386
+ packageName: target.srcMakName, // package will be named e.g. random for hashicorp/random
387
+ };
388
+ }
389
+ if (process.env.NODE_OPTIONS &&
390
+ !process.env.NODE_OPTIONS.includes(`--max-old-space-size`)) {
391
+ commons_2.logger.warn(`found NODE_OPTIONS environment variable without a setting for --max-old-space-size.
392
+ The provider generation needs a substantial amount of memory (~13GB) for some providers and languages.
393
+ So cdktn-cli sets it to NODE_OPTIONS="--max-old-space-size=16384" by default. As your environment already contains
394
+ a NODE_OPTIONS variable, we won't override it. Hence, the provider generation might fail with an out of memory error.`);
395
+ }
396
+ else {
397
+ // increase memory to allow generating large providers (i.e. aws or azurerm for Go)
398
+ // srcmak is going to spawn a childprocess (for jsii-pacmak) which is going to be affected by this env var
399
+ process.env.NODE_OPTIONS = "--max-old-space-size=16384";
400
+ }
401
+ const jsiiTimer = (0, commons_2.logTimespan)("JSII");
402
+ await generateJsiiLanguage(this.code, opts, this.codeMakerOutdir, [
403
+ target.isModule ? "providers/**" : "modules/**",
404
+ ]);
405
+ jsiiTimer();
406
+ }
407
+ async getSchemas(targets) {
408
+ return await (0, provider_schema_1.readSchema)(targets, this.schemaCachePath);
409
+ }
410
+ async generate(allConstraints, constraintsToGenerate = allConstraints) {
411
+ const targets = constraintsToGenerate.map((constraint) => commons_2.ConstructsMakerTarget.from(constraint, this.options.targetLanguage));
412
+ const endSchemaTimer = (0, commons_2.logTimespan)("Gathering schema");
413
+ const schemas = await this.getSchemas(constraintsToGenerate);
414
+ endSchemaTimer();
415
+ const endGenerateTimer = (0, commons_2.logTimespan)("Generate TS");
416
+ await Promise.all(targets.map((target) => this.generateTypescript(target, schemas)));
417
+ endGenerateTimer();
418
+ this.updateVersionsFile(allConstraints);
419
+ this.emitConstraintsFile(allConstraints);
420
+ if (this.isJavascriptTarget) {
421
+ await this.save();
422
+ }
423
+ if (!this.isJavascriptTarget || this.options.outputJsii) {
424
+ const numberOfWorkers = Math.max(1, this.options.jsiiParallelism === -1
425
+ ? targets.length
426
+ : this.options.jsiiParallelism || 1);
427
+ const work = [...targets];
428
+ const workers = new Array(numberOfWorkers).fill(async () => {
429
+ let target;
430
+ while ((target = work.pop())) {
431
+ const endJsiiTarget = (0, commons_2.logTimespan)(`Generating JSII bindings for ${target.name}`);
432
+ await this.generateJsiiLanguage(target);
433
+ endJsiiTarget();
434
+ }
435
+ });
436
+ await Promise.all(workers.map((fn) => fn()));
437
+ }
438
+ for (const target of targets) {
439
+ await this.reportTelemetry({
440
+ trackingPayload: target.trackingPayload,
441
+ targetLanguage: target.targetLanguage,
442
+ });
443
+ }
444
+ if (this.isPythonTarget) {
445
+ const endPythonTimer = (0, commons_2.logTimespan)("Python post-processing");
446
+ // Remove from . import ... statements from root level __init__.py
447
+ // This removes root-level imports of namespaces, but saves 25s synth time for the aws provider alone
448
+ const allInitPyPaths = glob_1.glob
449
+ .sync("**/__init__.py", {
450
+ cwd: this.codeMakerOutdir,
451
+ })
452
+ // sort by depth, so we start with the shallowest files
453
+ .sort((a, b) => a.split("/").length - b.split("/").length);
454
+ const visitedDirectories = [];
455
+ for (const initPyPath of allInitPyPaths) {
456
+ const directoryPath = path.dirname(initPyPath);
457
+ if (visitedDirectories.some((dir) => directoryPath.startsWith(dir))) {
458
+ // we already processed this directory
459
+ continue;
460
+ }
461
+ visitedDirectories.push(directoryPath);
462
+ const absoluteInitPyPath = path.join(this.codeMakerOutdir, initPyPath);
463
+ const initPy = await fs.readFile(absoluteInitPyPath, "utf8");
464
+ const initPyWithoutImports = initPy.replace(/from \. import .*\n/g, "");
465
+ await fs.writeFile(absoluteInitPyPath, initPyWithoutImports);
466
+ }
467
+ endPythonTimer();
468
+ }
469
+ }
470
+ async save(outdir = this.codeMakerOutdir) {
471
+ await this.code.save(outdir);
472
+ }
473
+ get isJavascriptTarget() {
474
+ return this.options.targetLanguage === commons_3.Language.TYPESCRIPT;
475
+ }
476
+ get isPythonTarget() {
477
+ return this.options.targetLanguage === commons_3.Language.PYTHON;
478
+ }
479
+ get isJavaTarget() {
480
+ return this.options.targetLanguage === commons_3.Language.JAVA;
481
+ }
482
+ get isCsharpTarget() {
483
+ return this.options.targetLanguage === commons_3.Language.CSHARP;
484
+ }
485
+ get isGoTarget() {
486
+ return this.options.targetLanguage === commons_3.Language.GO;
487
+ }
488
+ }
489
+ exports.ConstructsMaker = ConstructsMaker;
490
+ /**
491
+ * searches for the closest `go.mod` file and returns the nested go module name for `dir`
492
+ * e.g. (/dir/.gen/) => cdk.tf/stack/.gen if the parent dir of .gen has a go.mod for "module cdk.tf/stack"
493
+ *
494
+ * @param dir the directory to start the search from (searches upwards)
495
+ * @returns the package name for `dir`
496
+ * @throws an Error if no go.mod was found
497
+ */
498
+ const determineGoModuleName = async (dir) => {
499
+ let previousDir;
500
+ let currentDir = path.resolve(dir);
501
+ do {
502
+ let files = [];
503
+ try {
504
+ files = await fs.readdir(currentDir);
505
+ }
506
+ catch (e) {
507
+ // directory might not exist yet, but we still walk upwards from there, so ignore 'ENOENT'
508
+ if (e.code !== "ENOENT") {
509
+ throw e;
510
+ }
511
+ }
512
+ if (files.includes("go.mod")) {
513
+ const file = path.resolve(currentDir, "go.mod");
514
+ const gomod = await fs.readFile(file);
515
+ const match = /^module\s*(\S*)\s*$/m.exec(gomod.toString());
516
+ if (match && match[1]) {
517
+ const childdir = path.relative(currentDir, dir).replace(/\\/g, "/"); // replace '\' with '/' for windows paths
518
+ return childdir.length > 0 ? `${match[1]}/${childdir}` : match[1];
519
+ }
520
+ throw new Error(`Could not determine the root Go module name. Found ${file} but failed to regex match the module name directive`);
521
+ }
522
+ // go up one directory. As dirname('/') will return '/' we cancel the loop
523
+ // as soon as the dir does not change anymore.
524
+ previousDir = currentDir;
525
+ currentDir = path.dirname(currentDir);
526
+ } while (currentDir !== previousDir);
527
+ throw new Error(`Could not determine the root Go module name. No go.mod found in ${dir} and any parent directories`);
528
+ };
529
+ exports.determineGoModuleName = determineGoModuleName;
530
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29uc3RydWN0cy1tYWtlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9nZXQvY29uc3RydWN0cy1tYWtlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBLCtCQUErQjtBQUMvQixtQ0FBbUM7QUFDbkMsNkNBQStCO0FBQy9CLDJDQUE2QjtBQUM3Qix5Q0FBc0M7QUFDdEMsNENBQStDO0FBQy9DLDRDQVV3QjtBQUN4Qiw0Q0FBMkQ7QUFDM0QsdUVBQTRFO0FBQzVFLG1FQUErRDtBQUMvRCwrQkFBNEI7QUFDNUIsNERBQW9EO0FBRXBELE1BQU0sWUFBWSxHQUFHLE9BQU8sQ0FBQyxPQUFPLENBQUMsNkJBQTZCLENBQUMsQ0FBQztBQUNwRSxNQUFNLFVBQVUsR0FBRyxPQUFPLENBQUMsT0FBTyxDQUFDLGVBQWUsQ0FBQyxDQUFDO0FBaUQ3QyxLQUFLLFVBQVUsb0JBQW9CLENBQ3hDLElBQWUsRUFDZixJQUF5QixFQUN6QixVQUFrQixFQUNsQixzQkFBZ0MsRUFBRTtJQUVsQyxNQUFNLElBQUEsaUJBQU8sRUFBQyxLQUFLLEVBQUUsT0FBTyxFQUFFLEVBQUU7UUFDOUIsb0VBQW9FO1FBQ3BFLHNFQUFzRTtRQUN0RSxvQkFBb0I7UUFDcEIsTUFBTSxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBRXpCLDRFQUE0RTtRQUM1RSw0R0FBNEc7UUFDNUcsTUFBTSxhQUFhLEdBQUcsbUJBQW1CLENBQUMsT0FBTyxDQUFDLENBQUMsT0FBTyxFQUFFLEVBQUUsQ0FDNUQsV0FBSSxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsRUFBRSxHQUFHLEVBQUUsT0FBTyxFQUFFLENBQUMsQ0FDckMsQ0FBQztRQUNGLE1BQU0sT0FBTyxDQUFDLEdBQUcsQ0FDZixhQUFhLENBQUMsR0FBRyxDQUFDLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FBQyxFQUFFLENBQUMsTUFBTSxDQUFDLElB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Q0FBQyxFQUFFLENBQUM7Z0JBQ3RCLE1BQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsVUFBVSxFQUFFLEdBQUcsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxLQUFLLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyx5Q0FBeUM7Z0JBQzlHLE9BQU8sUUFBUSxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsS0FBSyxDQUFDLENBQUMsQ0FBQyxJQUFJLFFBQVEsRUFBRSxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDcEUsQ0FBQztZQUNELE1BQU0sSUFBSSxLQUFLLENBQ2Isc0RBQXNELElBQUksc0RBQXNELENBQ2pILENBQUM7UUFDSixDQUFDO1FBQ0QsMEVBQTBFO1FBQzFFLDhDQUE4QztRQUM5QyxXQUFXLEdBQUcsVUFBVSxDQUFDO1FBQ3pCLFVBQVUsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLFVBQVUsQ0FBQyxDQUFDO0lBQ3hDLENBQUMsUUFBUSxVQUFVLEtBQUssV0FBVyxFQUFFO0lBRXJDLE1BQU0sSUFBSSxLQUFLLENBQ2IsbUVBQW1FLEdBQUcsNkJBQTZCLENBQ3BHLENBQUM7QUFDSixDQUFDLENBQUM7QUFuQ1csUUFBQSxxQkFBcUIseUJBbUNoQyIsInNvdXJjZXNDb250ZW50IjpbIi8vIENvcHlyaWdodCAoYykgSGFzaGlDb3JwLCBJbmNcbi8vIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBNUEwtMi4wXG5pbXBvcnQgKiBhcyBmcyBmcm9tIFwiZnMtZXh0cmFcIjtcbmltcG9ydCAqIGFzIHBhdGggZnJvbSBcInBhdGhcIjtcbmltcG9ydCB7IENvZGVNYWtlciB9IGZyb20gXCJjb2RlbWFrZXJcIjtcbmltcG9ydCB7IGV4ZWMsIG1rZHRlbXAgfSBmcm9tIFwiQGNka3RuL2NvbW1vbnNcIjtcbmltcG9ydCB7XG4gIFRlcnJhZm9ybURlcGVuZGVuY3lDb25zdHJhaW50LFxuICBsb2dnZXIsXG4gIGxvZ1RpbWVzcGFuLFxuICBDb25zdHJ1Y3RzTWFrZXJQcm92aWRlclRhcmdldCxcbiAgQ29uc3RydWN0c01ha2VyTW9kdWxlVGFyZ2V0LFxuICBDb25zdHJ1Y3RzTWFrZXJUYXJnZXQsXG4gIFByb3ZpZGVyU2NoZW1hLFxuICBNb2R1bGVTY2hlbWEsXG4gIEVycm9ycyxcbn0gZnJvbSBcIkBjZGt0bi9jb21tb25zXCI7XG5pbXBvcnQgeyBESVNQTEFZX1ZFUlNJT04sIExhbmd1YWdlIH0gZnJvbSBcIkBjZGt0bi9jb21tb25zXCI7XG5pbXBvcnQgeyBUZXJyYWZvcm1Qcm92aWRlckdlbmVyYXRvciB9IGZyb20gXCIuL2dlbmVyYXRvci9wcm92aWRlci1nZW5lcmF0b3JcIjtcbmltcG9ydCB7IE1vZHVsZUdlbmVyYXRvciB9IGZyb20gXCIuL2dlbmVyYXRvci9tb2R1bGUtZ2VuZXJhdG9yXCI7XG5pbXBvcnQgeyBnbG9iIH0gZnJvbSBcImdsb2JcIjtcbmltcG9ydCB7IHJlYWRTY2hlbWEgfSBmcm9tIFwiQGNka3RuL3Byb3ZpZGVyLXNjaGVtYVwiO1xuXG5jb25zdCBwYWNtYWtNb2R1bGUgPSByZXF1aXJlLnJlc29sdmUoXCJqc2lpLXBhY21hay9iaW4vanNpaS1wYWNtYWtcIik7XG5jb25zdCBqc2lpTW9kdWxlID0gcmVxdWlyZS5yZXNvbHZlKFwianNpaS9iaW4vanNpaVwiKTtcblxuZXhwb3J0IGludGVyZmFjZSBHZW5lcmF0ZUpTSUlPcHRpb25zIHtcbiAgZW50cnlwb2ludDogc3RyaW5nO1xuICBkZXBzOiBzdHJpbmdbXTtcbiAgbW9kdWxlS2V5OiBzdHJpbmc7XG4gIGV4cG9ydHM/OiBSZWNvcmQ8c3RyaW5nLCBFeHBvcnREZWZpbml0aW9uIHwgc3RyaW5nPjtcbiAganNpaT86IEpzaWlPdXRwdXRPcHRpb25zO1xuICBweXRob24/OiBQeXRob25PdXRwdXRPcHRpb25zO1xuICBqYXZhPzogSmF2YU91dHB1dE9wdGlvbnM7XG4gIGNzaGFycD86IENTaGFycE91dHB1dE9wdGlvbnM7XG4gIGdvbGFuZz86IEdvTGFuZ091dHB1dE9wdGlvbnM7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgSnNpaU91dHB1dE9wdGlvbnMge1xuICBwYXRoOiBzdHJpbmc7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgUHl0aG9uT3V0cHV0T3B0aW9ucyB7XG4gIG91dGRpcjogc3RyaW5nO1xuICBtb2R1bGVOYW1lOiBzdHJpbmc7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgSmF2YU91dHB1dE9wdGlvbnMge1xuICBvdXRkaXI6IHN0cmluZztcbiAgcGFja2FnZTogc3RyaW5nO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIENTaGFycE91dHB1dE9wdGlvbnMge1xuICBvdXRkaXI6IHN0cmluZztcbiAgbmFtZXNwYWNlOiBzdHJpbmc7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgR29MYW5nT3V0cHV0T3B0aW9ucyB7XG4gIG91dGRpcjogc3RyaW5nO1xuICBtb2R1bGVOYW1lOiBzdHJpbmc7XG4gIHBhY2thZ2VOYW1lOiBzdHJpbmc7XG59XG5cbi8qKlxuICogU2VlIGh0dHBzOi8vbm9kZWpzLm9yZy9hcGkvcGFja2FnZXMuaHRtbCNjb25kaXRpb25hbC1leHBvcnRzIGZvciBtb3JlIGluZm9ybWF0aW9uXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgRXhwb3J0RGVmaW5pdGlvbiB7XG4gIG5vZGU/OiBzdHJpbmc7XG4gIGltcG9ydD86IHN0cmluZztcbiAgcmVxdWlyZT86IHN0cmluZztcbiAgZGVmYXVsdD86IHN0cmluZztcbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGdlbmVyYXRlSnNpaUxhbmd1YWdlKFxuICBjb2RlOiBDb2RlTWFrZXIsXG4gIG9wdHM6IEdlbmVyYXRlSlNJSU9wdGlvbnMsXG4gIG91dHB1dFBhdGg6IHN0cmluZyxcbiAgZGlzYWxsb3dlZEZpbGVHbG9iczogc3RyaW5nW10gPSBbXSxcbikge1xuICBhd2FpdCBta2R0ZW1wKGFzeW5jIChzdGFnaW5nKSA9PiB7XG4gICAgLy8gdGhpcyBpcyBub3QgdHlwZXNjcmlwdCwgc28gd2UgZ2VuZXJhdGUgaW4gYSBzdGFnaW5nIGRpcmVjdG9yeSBhbmRcbiAgICAvLyB1c2UganNpaS1zcmNtYWsgdG8gY29tcGlsZSBhbmQgZXh0cmFjdCB0aGUgbGFuZ3VhZ2Utc3BlY2lmaWMgc291cmNlXG4gICAgLy8gaW50byBvdXIgcHJvamVjdC5cbiAgICBhd2FpdCBjb2RlLnNhdmUoc3RhZ2luZyk7XG5cbiAgICAvLyBhcyB0aGUgYWJvdmUgZ2VuZXJhdGVkIHRoZSBUeXBlc2NyaXB0IGNvZGUgZm9yIGFsbCBwcm92aWRlcnMgYW5kIG1vZHVsZXMsXG4gICAgLy8gd2UgbmVlZCB0byBmaWx0ZXIgb3V0IHRoZSBvbmVzIHdlIGRvbid0IG5lZWQgc28gdGhleSBkb24ndCBlbmQgdXAgaW4gdGhlIEpTSUkgYnVuZGxlIG92ZXIgYW5kIG92ZXIgYWdhaW4uXG4gICAgY29uc3QgZmlsZXNUb0RlbGV0ZSA9IGRpc2FsbG93ZWRGaWxlR2xvYnMuZmxhdE1hcCgocGF0dGVybikgPT5cbiAgICAgIGdsb2Iuc3luYyhwYXR0ZXJuLCB7IGN3ZDogc3RhZ2luZyB9KSxcbiAgICApO1xuICAgIGF3YWl0IFByb21pc2UuYWxsKFxuICAgICAgZmlsZXNUb0RlbGV0ZS5tYXAoKGZpbGUpID0+IGZzLnJlbW92ZShwYXRoLmpvaW4oc3RhZ2luZywgZmlsZSkpKSxcbiAgICApO1xuXG4gICAgLy8gQ29tcGlsZSB3aXRoIEpTSUlcbiAgICBjb25zdCBqc2lpQXJncyA9IFtcIi0tc2lsZW5jZS13YXJuaW5nc1wiLCBcInJlc2VydmVkLXdvcmRcIl07XG4gICAgY29uc3QganNpaUVudHJ5cG9pbnQgPSBvcHRzLmVudHJ5cG9pbnQ7XG4gICAgY29uc3QgYmFzZXBhdGggPSBwYXRoLmpvaW4oXG4gICAgICBwYXRoLmRpcm5hbWUoanNpaUVudHJ5cG9pbnQpLFxuICAgICAgcGF0aC5iYXNlbmFtZShqc2lpRW50cnlwb2ludCwgXCIudHNcIiksXG4gICAgKTtcblxuICAgIGNvbnN0IG1vZHVsZUtleSA9IG9wdHMubW9kdWxlS2V5LnJlcGxhY2UoL1xcLi9nLCBcIlwiKS5yZXBsYWNlKC9cXC8vZywgXCJcIik7XG4gICAgY29uc3QgbW9kdWxlRGlycyA9IG9wdHMuZGVwcztcbiAgICBjb25zdCB0YXJnZXRzOiBSZWNvcmQ8c3RyaW5nLCBhbnk+ID0ge307XG4gICAgY29uc3QgZGVwczogUmVjb3JkPHN0cmluZywgc3RyaW5nPiA9IHt9O1xuICAgIGZvciAoY29uc3QgZGlyIG9mIG1vZHVsZURpcnMpIHtcbiAgICAgIC8vIHJlYWQgbW9kdWxlIG1ldGFkYXRhXG4gICAgICBjb25zdCBtZXRhZGF0YSA9IGF3YWl0IGZzLnJlYWRKc29uKHBhdGguam9pbihkaXIsIFwicGFja2FnZS5qc29uXCIpKTtcbiAgICAgIGNvbnN0IG1vZHVsZU5hbWU6IHN0cmluZyA9IG1ldGFkYXRhLm5hbWU7XG4gICAgICBjb25zdCBtb2R1bGVWZXJzaW9uOiBzdHJpbmcgPSBtZXRhZGF0YS52ZXJzaW9uO1xuXG4gICAgICBjb25zdCB0YXJnZXRkaXIgPSBwYXRoLmpvaW4oXG4gICAgICAgIHBhdGguam9pbihzdGFnaW5nLCBcIm5vZGVfbW9kdWxlc1wiKSxcbiAgICAgICAgbW9kdWxlTmFtZSxcbiAgICAgICk7XG4gICAgICBhd2FpdCBmcy5ta2RpcnAocGF0aC5kaXJuYW1lKHRhcmdldGRpcikpO1xuICAgICAgYXdhaXQgZnMuY29weShkaXIsIHRhcmdldGRpcik7XG5cbiAgICAgIC8vIGFkZCB0byBcImRlcHNcIiBhbmQgXCJwZWVyIGRlcHNcIlxuICAgICAgaWYgKCFtb2R1bGVOYW1lLnN0YXJ0c1dpdGgoXCJAdHlwZXMvXCIpKSB7XG4gICAgICAgIGRlcHNbbW9kdWxlTmFtZV0gPSBtb2R1bGVWZXJzaW9uO1xuICAgICAgfVxuICAgIH1cbiAgICBjb25zdCBwa2cgPSB7XG4gICAgICBuYW1lOiBtb2R1bGVLZXksXG4gICAgICB2ZXJzaW9uOiBcIjAuMC4wXCIsXG4gICAgICBhdXRob3I6IFwiZ2VuZXJhdGVkQGdlbmVyYXRlZC5jb21cIixcbiAgICAgIG1haW46IGAke2Jhc2VwYXRofS5qc2AsXG4gICAgICB0eXBlczogYCR7YmFzZXBhdGh9LmQudHNgLFxuICAgICAgbGljZW5zZTogXCJVTkxJQ0VOU0VEXCIsXG4gICAgICByZXBvc2l0b3J5OiB7IHVybDogXCJodHRwOi8vZ2VuZXJhdGVkXCIsIHR5cGU6IFwiZ2l0XCIgfSxcbiAgICAgIGpzaWk6IHtcbiAgICAgICAgb3V0ZGlyOiBcImRpc3RcIixcbiAgICAgICAgdGFyZ2V0czogdGFyZ2V0cyxcbiAgICAgIH0sXG4gICAgICBkZXBlbmRlbmNpZXM6IGRlcHMsXG4gICAgICBwZWVyRGVwZW5kZW5jaWVzOiBkZXBzLFxuICAgIH07XG5cbiAgICBpZiAob3B0cy5leHBvcnRzKSB7XG4gICAgICAocGtnIGFzIFJlY29yZDxzdHJpbmcsIGFueT4pLmV4cG9ydHMgPSBvcHRzLmV4cG9ydHM7XG4gICAgfVxuICAgIGlmIChvcHRzLnB5dGhvbikge1xuICAgICAgdGFyZ2V0cy5weXRob24gPSB7XG4gICAgICAgIGRpc3ROYW1lOiBcImdlbmVyYXRlZFwiLFxuICAgICAgICBtb2R1bGU6IG9wdHMucHl0aG9uLm1vZHVsZU5hbWUsXG4gICAgICB9O1xuICAgIH1cblxuICAgIGlmIChvcHRzLmphdmEpIHtcbiAgICAgIHRhcmdldHMuamF2YSA9IHtcbiAgICAgICAgcGFja2FnZTogb3B0cy5qYXZhLnBhY2thZ2UsXG4gICAgICAgIG1hdmVuOiB7XG4gICAgICAgICAgZ3JvdXBJZDogXCJnZW5lcmF0ZWRcIixcbiAgICAgICAgICBhcnRpZmFjdElkOiBcImdlbmVyYXRlZFwiLFxuICAgICAgICB9LFxuICAgICAgfTtcbiAgICB9XG5cbiAgICBpZiAob3B0cy5jc2hhcnApIHtcbiAgICAgIHRhcmdldHMuZG90bmV0ID0ge1xuICAgICAgICBuYW1lc3BhY2U6IG9wdHMuY3NoYXJwLm5hbWVzcGFjZSxcbiAgICAgICAgcGFja2FnZUlkOiBvcHRzLmNzaGFycC5uYW1lc3BhY2UsXG4gICAgICB9O1xuICAgIH1cblxuICAgIGlmIChvcHRzLmdvbGFuZykge1xuICAgICAgdGFyZ2V0cy5nbyA9IHtcbiAgICAgICAgbW9kdWxlTmFtZTogb3B0cy5nb2xhbmcubW9kdWxlTmFtZSxcbiAgICAgICAgcGFja2FnZU5hbWU6IG9wdHMuZ29sYW5nLnBhY2thZ2VOYW1lLFxuICAgICAgfTtcbiAgICB9XG5cbiAgICBhd2FpdCBmcy53cml0ZUZpbGUoXG4gICAgICBwYXRoLmpvaW4oc3RhZ2luZywgXCJwYWNrYWdlLmpzb25cIiksXG4gICAgICBKU09OLnN0cmluZ2lmeShwa2csIHVuZGVmaW5lZCwgMiksXG4gICAgKTtcblxuICAgIGNvbnN0IGVuZEpzaWlUaW1lciA9IGxvZ1RpbWVzcGFuKFwianNpaVwiKTtcbiAgICBhd2FpdCBleGVjKGpzaWlNb2R1bGUsIGpzaWlBcmdzLCB7XG4gICAgICBjd2Q6IHN0YWdpbmcsXG4gICAgfSk7XG4gICAgZW5kSnNpaVRpbWVyKCk7XG5cbiAgICAvLyBleHRyYWN0IC5qc2lpIGlmIHJlcXVlc3RlZFxuICAgIGlmIChvcHRzLmpzaWkpIHtcbiAgICAgIGF3YWl0IGZzLmNvcHkocGF0aC5qb2luKHN0YWdpbmcsIFwiLmpzaWlcIiksIG9wdHMuanNpaS5wYXRoKTtcbiAgICB9XG5cbiAgICAvLyBydW4gcGFjbWFrIHRvIGdlbmVyYXRlIGNvZGVcbiAgICBjb25zdCBlbmRKc2lpUGFjbWFrVGltZXIgPSBsb2dUaW1lc3BhbihcImpzaWktcGFjbWFrXCIpO1xuICAgIGF3YWl0IGV4ZWMocGFjbWFrTW9kdWxlLCBbXCItLWNvZGUtb25seVwiXSwgeyBjd2Q6IHN0YWdpbmcgfSk7XG4gICAgZW5kSnNpaVBhY21ha1RpbWVyKCk7XG5cbiAgICBpZiAob3B0cy5weXRob24pIHtcbiAgICAgIGNvbnN0IHJlbGRpciA9IG9wdHMucHl0aG9uLm1vZHVsZU5hbWUucmVwbGFjZSgvXFwuL2csIFwiL1wiKTsgLy8ganNpaSByZXBsYWNlcyBcIi5cIiB3aXRoIFwiL1wiXG4gICAgICBjb25zdCBzb3VyY2UgPSBwYXRoLnJlc29sdmUoXG4gICAgICAgIHBhdGguam9pbihzdGFnaW5nLCBcImRpc3QvcHl0aG9uL3NyY1wiLCByZWxkaXIpLFxuICAgICAgKTtcbiAgICAgIGNvbnN0IHRhcmdldCA9IHBhdGguam9pbihvcHRzLnB5dGhvbi5vdXRkaXIsIHJlbGRpcik7XG4gICAgICBhd2FpdCBmcy5tb3ZlKHNvdXJjZSwgdGFyZ2V0LCB7IG92ZXJ3cml0ZTogdHJ1ZSB9KTtcbiAgICB9XG5cbiAgICBpZiAob3B0cy5qYXZhKSB7XG4gICAgICBjb25zdCBzb3VyY2UgPSBwYXRoLnJlc29sdmUocGF0aC5qb2luKHN0YWdpbmcsIFwiZGlzdC9qYXZhL3NyYy9cIikpO1xuICAgICAgY29uc3QgdGFyZ2V0ID0gcGF0aC5qb2luKG9wdHMuamF2YS5vdXRkaXIsIFwic3JjL1wiKTtcbiAgICAgIGF3YWl0IGZzLm1rZGlycCh0YXJnZXQpOyAvLyBtYWtlIHN1cmUgdGFyZ2V0IGRpcmVjdG9yeSBleGlzdHNcbiAgICAgIGF3YWl0IGZzLmNvcHkoc291cmNlLCB0YXJnZXQsIHsgcmVjdXJzaXZlOiB0cnVlLCBvdmVyd3JpdGU6IGZhbHNlIH0pO1xuICAgIH1cblxuICAgIGlmIChvcHRzLmNzaGFycCkge1xuICAgICAgY29uc3QgcmVsZGlyID0gb3B0cy5jc2hhcnAubmFtZXNwYWNlO1xuICAgICAgY29uc3Qgc291cmNlID0gcGF0aC5yZXNvbHZlKHBhdGguam9pbihzdGFnaW5nLCBcImRpc3QvZG90bmV0L1wiLCByZWxkaXIpKTtcbiAgICAgIGNvbnN0IHRhcmdldCA9IHBhdGguam9pbihvcHRzLmNzaGFycC5vdXRkaXIsIHJlbGRpcik7XG4gICAgICBhd2FpdCBmcy5tb3ZlKHNvdXJjZSwgdGFyZ2V0LCB7IG92ZXJ3cml0ZTogdHJ1ZSB9KTtcbiAgICB9XG5cbiAgICBpZiAob3B0cy5nb2xhbmcpIHtcbiAgICAgIGNvbnN0IHJlbGRpciA9IG9wdHMuZ29sYW5nLnBhY2thZ2VOYW1lO1xuICAgICAgY29uc3Qgc291cmNlID0gcGF0aC5yZXNvbHZlKHBhdGguam9pbihzdGFnaW5nLCBcImRpc3QvZ28vXCIsIHJlbGRpcikpO1xuICAgICAgY29uc3QgdGFyZ2V0ID0gcGF0aC5qb2luKG9wdHMuZ29sYW5nLm91dGRpciwgcmVsZGlyKTtcbiAgICAgIGF3YWl0IGZzLm1vdmUoc291cmNlLCB0YXJnZXQsIHsgb3ZlcndyaXRlOiB0cnVlIH0pO1xuICAgICAgLy8gcmVtb3ZlIGdvLm1vZCBhcyB0aGlzIHdvdWxkIG1ha2UgaXQgYSBzdWJtb2R1bGVcbiAgICAgIGF3YWl0IGZzLnJlbW92ZShwYXRoLmpvaW4odGFyZ2V0LCBcImdvLm1vZFwiKSk7XG4gICAgfVxuXG4gICAgW1widmVyc2lvbnMuanNvblwiLCBcImNvbnN0cmFpbnRzLmpzb25cIl0uZm9yRWFjaCgoZmlsZSkgPT4ge1xuICAgICAgdHJ5IHtcbiAgICAgICAgZnMuY29weVN5bmMoXG4gICAgICAgICAgcGF0aC5yZXNvbHZlKHN0YWdpbmcsIGZpbGUpLFxuICAgICAgICAgIHBhdGgucmVzb2x2ZShvdXRwdXRQYXRoLCBmaWxlKSxcbiAgICAgICAgKTtcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgbG9nZ2VyLmRlYnVnKGBGYWlsZWQgdG8gY29weSAke2ZpbGV9OiAke2V9YCk7XG4gICAgICB9XG4gICAgfSk7XG4gIH0pO1xufVxuXG50eXBlIENvbnN0cmFpbnRGaWxlID0geyBwcm92aWRlcnM6IFJlY29yZDxzdHJpbmcsIHN0cmluZz47IGNka3RmOiBzdHJpbmcgfTtcblxuZXhwb3J0IGludGVyZmFjZSBHZXRPcHRpb25zIHtcbiAgcmVhZG9ubHkgdGFyZ2V0TGFuZ3VhZ2U6IExhbmd1YWdlO1xuICByZWFkb25seSBjb2RlTWFrZXJPdXRwdXQ6IHN0cmluZztcbiAgcmVhZG9ubHkganNpaVBhcmFsbGVsaXNtPzogbnVtYmVyO1xuICAvKipcbiAgICogUGF0aCB0byBjb3B5IHRoZSBvdXRwdXQgLmpzaWkgZmlsZS5cbiAgICogQGRlZmF1bHQgLSBqc2lpIGZpbGUgaXMgbm90IGVtaXR0ZWRcbiAgICovXG4gIHJlYWRvbmx5IG91dHB1dEpzaWk/OiBzdHJpbmc7XG59XG5cbmV4cG9ydCBjbGFzcyBDb25zdHJ1Y3RzTWFrZXIge1xuICBwcml2YXRlIHJlYWRvbmx5IGNvZGVNYWtlck91dGRpcjogc3RyaW5nO1xuICBwcml2YXRlIHJlYWRvbmx5IGNvZGU6IENvZGVNYWtlcjtcbiAgcHJpdmF0ZSB2ZXJzaW9uczogeyBbcHJvdmlkZXJOYW1lOiBzdHJpbmddOiBzdHJpbmcgfCB1bmRlZmluZWQgfTtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIHJlYWRvbmx5IG9wdGlvbnM6IEdldE9wdGlvbnMsXG4gICAgcHJpdmF0ZSByZWFkb25seSBzY2hlbWFDYWNoZVBhdGg/OiBzdHJpbmcsXG4gICAgcHJpdmF0ZSByZWFkb25seSByZXBvcnRUZWxlbWV0cnk6IChwYXlsb2FkOiB7XG4gICAgICB0YXJnZXRMYW5ndWFnZTogc3RyaW5nO1xuICAgICAgdHJhY2tpbmdQYXlsb2FkOiBSZWNvcmQ8c3RyaW5nLCBhbnk+O1xuICAgIH0pID0+IFByb21pc2U8dm9pZD4gPSBhc3luYyAoKSA9PiB7fSxcbiAgKSB7XG4gICAgdGhpcy5jb2RlTWFrZXJPdXRkaXIgPSBwYXRoLnJlc29sdmUodGhpcy5vcHRpb25zLmNvZGVNYWtlck91dHB1dCk7XG4gICAgZnMubWtkaXJwU3luYyh0aGlzLmNvZGVNYWtlck91dGRpcik7XG4gICAgdGhpcy5jb2RlID0gbmV3IENvZGVNYWtlcigpO1xuICAgIHRoaXMudmVyc2lvbnMgPSB7fTtcbiAgfVxuICBwcml2YXRlIGFzeW5jIGdlbmVyYXRlVHlwZXNjcmlwdFByb3ZpZGVyKFxuICAgIHRhcmdldDogQ29uc3RydWN0c01ha2VyUHJvdmlkZXJUYXJnZXQsXG4gICAgc2NoZW1hOiBQcm92aWRlclNjaGVtYSxcbiAgKSB7XG4gICAgY29uc3QgZW5kVFNUaW1lciA9IGxvZ1RpbWVzcGFuKGBHZW5lcmF0ZSBUeXBlc2NyaXB0IGZvciAke3RhcmdldC5uYW1lfWApO1xuICAgIGNvbnN0IGdlbmVyYXRvciA9IG5ldyBUZXJyYWZvcm1Qcm92aWRlckdlbmVyYXRvcih0aGlzLmNvZGUsIHNjaGVtYSk7XG4gICAgZ2VuZXJhdG9yLmdlbmVyYXRlKHRhcmdldCk7XG5cbiAgICB0aGlzLnZlcnNpb25zID0geyAuLi50aGlzLnZlcnNpb25zLCAuLi5nZW5lcmF0b3IudmVyc2lvbnMgfTtcbiAgICBlbmRUU1RpbWVyKCk7XG4gIH1cblxuICBwdWJsaWMgYXN5bmMgZmlsdGVyQWxyZWFkeUdlbmVyYXRlZChcbiAgICBjb25zdHJhaW50czogVGVycmFmb3JtRGVwZW5kZW5jeUNvbnN0cmFpbnRbXSxcbiAgKSB7XG4gICAgbGV0IGNvbnN0cmFpbnRzRmlsZSA9IFwie31cIjtcbiAgICB0cnkge1xuICAgICAgY29uc3RyYWludHNGaWxlID0gYXdhaXQgZnMucmVhZEZpbGUoXG4gICAgICAgIHBhdGguam9pbih0aGlzLmNvZGVNYWtlck91dGRpciwgXCJjb25zdHJhaW50cy5qc29uXCIpLFxuICAgICAgICBcInV0ZjhcIixcbiAgICAgICk7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgbG9nZ2VyLmRlYnVnKFxuICAgICAgICBgQ291bGQgbm90IGZpbmQgY29uc3RyYWludHMuanNvbiBmaWxlIHdoaWxlIGZpbHRlcmluZzogJHtlfS4gVGhpcyBtZWFucyBubyBwcm92aWRlcnMgd2VyZSBnZW5lcmF0ZWQsIHNvIGFsbCBjb25zdHJhaW50cyBuZWVkIHRvIGJlIGdlbmVyYXRlZC5gLFxuICAgICAgKTtcbiAgICAgIHJldHVybiBjb25zdHJhaW50cztcbiAgICB9XG4gICAgbG9nZ2VyLmRlYnVnKGBGb3VuZCBjb25zdHJhaW50cy5qc29uIGZpbGU6ICR7Y29uc3RyYWludHNGaWxlfWApO1xuXG4gICAgbGV0IHByZXZpb3VzQ29uc3RyYWludHM6IFBhcnRpYWw8Q29uc3RyYWludEZpbGU+ID0ge307XG4gICAgdHJ5IHtcbiAgICAgIHByZXZpb3VzQ29uc3RyYWludHMgPSBKU09OLnBhcnNlKGNvbnN0cmFpbnRzRmlsZSk7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgbG9nZ2VyLmluZm8oXG4gICAgICAgIGBDb3VsZCBub3QgcGFyc2UgY29uc3RyYWludHMuanNvbiBmaWxlIHdoaWxlIGZpbHRlcmluZzogJHtlfS4gR2VuZXJhdGluZyBhbGwgY29uc3RyYWludHMuYCxcbiAgICAgICk7XG4gICAgICByZXR1cm4gY29uc3RyYWludHM7XG4gICAgfVxuXG4gICAgbG9nZ2VyLmRlYnVnKFxuICAgICAgYEZvdW5kIHByZXZpb3VzIGNvbnN0cmFpbnRzOiAke0pTT04uc3RyaW5naWZ5KFxuICAgICAgICBwcmV2aW91c0NvbnN0cmFpbnRzLFxuICAgICAgICBudWxsLFxuICAgICAgICAyLFxuICAgICAgKX1gLFxuICAgICk7XG5cbiAgICBpZiAoXG4gICAgICAhcHJldmlvdXNDb25zdHJhaW50cy5wcm92aWRlcnMgfHxcbiAgICAgIHR5cGVvZiBwcmV2aW91c0NvbnN0cmFpbnRzLnByb3ZpZGVycyAhPT0gXCJvYmplY3RcIlxuICAgICkge1xuICAgICAgbG9nZ2VyLmluZm8oXG4gICAgICAgIGBDb3VsZCBub3QgZmluZCBwcm92aWRlcnMgaW4gY29uc3RyYWludHMuanNvbiBmaWxlLCBnZW5lcmF0aW5nIGFsbCBjb25zdHJhaW50cy4gVGhlIGNvbnN0cmFpbnRzIGZpbGUgd2FzICR7SlNPTi5zdHJpbmdpZnkoXG4gICAgICAgICAgcHJldmlvdXNDb25zdHJhaW50cyxcbiAgICAgICAgICBudWxsLFxuICAgICAgICAgIDIsXG4gICAgICAgICl9YCxcbiAgICAgICk7XG4gICAgICByZXR1cm4gY29uc3RyYWludHM7XG4gICAgfVxuXG4gICAgaWYgKHByZXZpb3VzQ29uc3RyYWludHMuY2RrdGYgIT09IERJU1BMQVlfVkVSU0lPTikge1xuICAgICAgbG9nZ2VyLmluZm8oXG4gICAgICAgIGBUaGUgQ0RLVE4gdmVyc2lvbiBoYXMgY2hhbmdlZCwgZ2VuZXJhdGluZyBhbGwgY29uc3RyYWludHMuIFRoZSBwcmV2aW91cyB2ZXJzaW9uIHdhcyAke3ByZXZpb3VzQ29uc3RyYWludHMuY2RrdGZ9LCB0aGUgY3VycmVudCB2ZXJzaW9uIGlzICR7RElTUExBWV9WRVJTSU9OfWAsXG4gICAgICApO1xuICAgICAgcmV0dXJuIGNvbnN0cmFpbnRzO1xuICAgIH1cblxuICAgIGNvbnN0IGNvbnN0cmFpbnRzVG9HZW5lcmF0ZSA9IGNvbnN0cmFpbnRzLmZpbHRlcigoY29uc3RyYWludCkgPT4ge1xuICAgICAgY29uc3QgY29uc3RyYWludE1hdGNoZXMgPVxuICAgICAgICBwcmV2aW91c0NvbnN0cmFpbnRzLnByb3ZpZGVycyFbY29uc3RyYWludC5mcW5dID09PSBjb25zdHJhaW50LnZlcnNpb247XG4gICAgICBsZXQgcHJvdmlkZXJGb2xkZXJFeGlzdHMgPSBmYWxzZTtcblxuICAgICAgc3dpdGNoICh0aGlzLm9wdGlvbnMudGFyZ2V0TGFuZ3VhZ2UpIHtcbiAgICAgICAgY2FzZSBMYW5ndWFnZS5UWVBFU0NSSVBUOlxuICAgICAgICAgIHByb3ZpZGVyRm9sZGVyRXhpc3RzID0gZnMuZXhpc3RzU3luYyhcbiAgICAgICAgICAgIHBhdGguam9pbih0aGlzLmNvZGVNYWtlck91dGRpciwgXCJwcm92aWRlcnNcIiwgY29uc3RyYWludC5uYW1lKSxcbiAgICAgICAgICApO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlIExhbmd1YWdlLlBZVEhPTjpcbiAgICAgICAgY2FzZSBMYW5ndWFnZS5KQVZBOlxuICAgICAgICBjYXNlIExhbmd1YWdlLkNTSEFSUDpcbiAgICAgICAgICBwcm92aWRlckZvbGRlckV4aXN0cyA9IGZzLmV4aXN0c1N5bmMoXG4gICAgICAgICAgICBwYXRoLmpvaW4odGhpcy5jb2RlTWFrZXJPdXRkaXIsIGNvbnN0cmFpbnQubmFtZSksXG4gICAgICAgICAgKTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSBMYW5ndWFnZS5HTzpcbiAgICAgICAgICBwcm92aWRlckZvbGRlckV4aXN0cyA9IGZzLmV4aXN0c1N5bmMoXG4gICAgICAgICAgICBwYXRoLmpvaW4oXG4gICAgICAgICAgICAgIHRoaXMuY29kZU1ha2VyT3V0ZGlyLFxuICAgICAgICAgICAgICBjb25zdHJhaW50Lm5hbWVzcGFjZSB8fCBcImhhc2hpY29ycFwiLFxuICAgICAgICAgICAgICBjb25zdHJhaW50Lm5hbWUsXG4gICAgICAgICAgICApLFxuICAgICAgICAgICk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHByb3ZpZGVyRXhpc3RzID0gY29uc3RyYWludE1hdGNoZXMgJiYgcHJvdmlkZXJGb2xkZXJFeGlzdHM7XG4gICAgICByZXR1cm4gIXByb3ZpZGVyRXhpc3RzO1xuICAgIH0pO1xuXG4gICAgbG9nZ2VyLmRlYnVnKFxuICAgICAgYENvbnN0cmFpbnRzIHRvIGdlbmVyYXRlOiAke0pTT04uc3RyaW5naWZ5KFxuICAgICAgICBjb25zdHJhaW50c1RvR2VuZXJhdGUsXG4gICAgICAgIG51bGwsXG4gICAgICAgIDIsXG4gICAgICApfWAsXG4gICAgKTtcblxuICAgIHJldHVybiBjb25zdHJhaW50c1RvR2VuZXJhdGU7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIGdlbmVyYXRlVHlwZXNjcmlwdE1vZHVsZShcbiAgICB0YXJnZXQ6IENvbnN0cnVjdHNNYWtlck1vZHVsZVRhcmdldCxcbiAgICBzY2hlbWE6IE1vZHVsZVNjaGVtYSxcbiAgKSB7XG4gICAgY29uc3QgZW5kVFNUaW1lciA9IGxvZ1RpbWVzcGFuKGBHZW5lcmF0ZSBUeXBlc2NyaXB0IGZvciAke3RhcmdldC5uYW1lfWApO1xuICAgIHRhcmdldC5zcGVjID0gc2NoZW1hO1xuICAgIG5ldyBNb2R1bGVHZW5lcmF0b3IodGhpcy5jb2RlLCBbdGFyZ2V0XSk7XG4gICAgZW5kVFNUaW1lcigpO1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBnZW5lcmF0ZVR5cGVzY3JpcHQoXG4gICAgdGFyZ2V0OiBDb25zdHJ1Y3RzTWFrZXJUYXJnZXQsXG4gICAgc2NoZW1hczogQXdhaXRlZDxSZXR1cm5UeXBlPHR5cGVvZiByZWFkU2NoZW1hPj4sXG4gICkge1xuICAgIGlmICh0YXJnZXQuaXNNb2R1bGUpIHtcbiAgICAgIGNvbnN0IHNjaGVtYSA9IHNjaGVtYXMubW9kdWxlU2NoZW1hPy5bdGFyZ2V0Lm1vZHVsZUtleV07XG4gICAgICBpZiAoIXNjaGVtYSkge1xuICAgICAgICB0aHJvdyBFcnJvcnMuSW50ZXJuYWwoXG4gICAgICAgICAgYENvdWxkIG5vdCBnZW5lcmF0ZSBzY2hlbWEgZm9yIG1vZHVsZSAke3RhcmdldC5tb2R1bGVLZXl9YCxcbiAgICAgICAgKTtcbiAgICAgIH1cblxuICAgICAgYXdhaXQgdGhpcy5nZW5lcmF0ZVR5cGVzY3JpcHRNb2R1bGUoXG4gICAgICAgIHRhcmdldCBhcyBDb25zdHJ1Y3RzTWFrZXJNb2R1bGVUYXJnZXQsXG4gICAgICAgIHNjaGVtYSxcbiAgICAgICk7XG4gICAgfSBlbHNlIGlmICh0YXJnZXQuaXNQcm92aWRlcikge1xuICAgICAgaWYgKCFzY2hlbWFzLnByb3ZpZGVyU2NoZW1hKSB7XG4gICAgICAgIHRocm93IEVycm9ycy5JbnRlcm5hbChgQ291bGQgbm90IGdlbmVyYXRlIHNjaGVtYSBmb3IgcHJvdmlkZXJzYCk7XG4gICAgICB9XG5cbiAgICAgIGF3YWl0IHRoaXMuZ2VuZXJhdGVUeXBlc2NyaXB0UHJvdmlkZXIoXG4gICAgICAgIHRhcmdldCBhcyBDb25zdHJ1Y3RzTWFrZXJQcm92aWRlclRhcmdldCxcbiAgICAgICAgc2NoZW1hcy5wcm92aWRlclNjaGVtYSxcbiAgICAgICk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgYFVua25vd24gdGFyZ2V0IHR5cGUgdXNlZCB0byBnZW5lcmF0ZSBiaW5kaW5nczogJHt0YXJnZXQubmFtZX1gLFxuICAgICAgKTtcbiAgICB9XG4gIH1cblxuICAvLyBlbWl0cyBhIHZlcnNpb25zLmpzb24gZmlsZSB3aXRoIGEgbWFwIG9mIHRoZSB1c2VkIHZlcnNpb24gZm9yIGVhY2ggcHJvdmlkZXIgZnFwblxuICBwcml2YXRlIHVwZGF0ZVZlcnNpb25zRmlsZShcbiAgICBhbGxvd2VkQ29uc3RyYWludHM6IFRlcnJhZm9ybURlcGVuZGVuY3lDb25zdHJhaW50W10sXG4gICkge1xuICAgIGxvZ2dlci5kZWJ1ZyhcbiAgICAgIGBVcGRhdGluZyB2ZXJzaW9ucyBmaWxlIHdpdGggZ2VuZXJhdGVkIHZlcnNpb25zICR7SlNPTi5zdHJpbmdpZnkoXG4gICAgICAgIHRoaXMudmVyc2lvbnMsXG4gICAgICAgIG51bGwsXG4gICAgICAgIDIsXG4gICAgICApfSB3aXRoIGFsbG93ZWQgY29uc3RyYWludHMgJHtKU09OLnN0cmluZ2lmeShcbiAgICAgICAgYWxsb3dlZENvbnN0cmFpbnRzLFxuICAgICAgICBudWxsLFxuICAgICAgICAyLFxuICAgICAgKX1gLFxuICAgICk7XG4gICAgY29uc3QgZmlsZVBhdGggPSBcInZlcnNpb25zLmpzb25cIjtcbiAgICBsZXQgcHJldmlvdXNWZXJzaW9uczogUmVjb3JkPHN0cmluZywgc3RyaW5nPiA9IHt9O1xuICAgIHRyeSB7XG4gICAgICBwcmV2aW91c1ZlcnNpb25zID0gSlNPTi5wYXJzZShcbiAgICAgICAgZnMucmVhZEZpbGVTeW5jKHBhdGgucmVzb2x2ZSh0aGlzLmNvZGVNYWtlck91dGRpciwgZmlsZVBhdGgpLCBcInV0ZjhcIiksXG4gICAgICApO1xuXG4gICAgICBsb2dnZXIuZGVidWcoXG4gICAgICAgIGBSZWFkIGV4aXN0aW5nIHZlcnNpb25zIGZpbGU6ICR7SlNPTi5zdHJpbmdpZnkoXG4gICAgICAgICAgcHJldmlvdXNWZXJzaW9ucyxcbiAgICAgICAgICBudWxsLFxuICAgICAgICAgIDIsXG4gICAgICAgICl9YCxcbiAgICAgICk7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgLy8gaWdub3JlXG4gICAgICBsb2dnZXIuZGVidWcoXG4gICAgICAgIGBDb3VsZCBub3QgcmVhZCB2ZXJzaW9ucyBmaWxlLCB0aGlzIGlzIGV4cGVjdGVkIGlmIHRoZXJlIGFyZSBubyBwcmUtZXhpc3RpbmcgbG9jYWwgcHJvdmlkZXJzOiAke2V9YCxcbiAgICAgICk7XG4gICAgfVxuXG4gICAgY29uc3QgdmVyc2lvbnMgPSBhbGxvd2VkQ29uc3RyYWludHMucmVkdWNlKChhY2MsIGNvbnN0cmFpbnQpID0+IHtcbiAgICAgIGNvbnN0IHByb3ZpZGVyID0gT2JqZWN0LmVudHJpZXMocHJldmlvdXNWZXJzaW9ucykuZmluZCgoW25hbWVdKSA9PlxuICAgICAgICAvLyBUaGlzIGNvdWxkIGJlIG1vcmUgcmVmaW5lZCwgYnV0IGl0J3MgZ29vZCBlbm91Z2ggZm9yIG5vd1xuICAgICAgICBuYW1lLmVuZHNXaXRoKGNvbnN0cmFpbnQuZnFuKSxcbiAgICAgICk7XG5cbiAgICAgIGlmIChwcm92aWRlcikge1xuICAgICAgICBjb25zdCBbbmFtZSwgdmVyc2lvbl0gPSBwcm92aWRlcjtcbiAgICAgICAgcmV0dXJuIHsgLi4uYWNjLCBbbmFtZV06IHZlcnNpb24gfTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIGFjYztcbiAgICB9LCB7fSk7XG5cbiAgICBsb2dnZXIuZGVidWcoXG4gICAgICBgV3JpdGluZyB2ZXJzaW9ucyBmaWxlICgke2ZpbGVQYXRofSk6ICR7SlNPTi5zdHJpbmdpZnkoXG4gICAgICAgIHZlcnNpb25zLFxuICAgICAgICBudWxsLFxuICAgICAgICAyLFxuICAgICAgKX1gLFxuICAgICk7XG5cbiAgICB0aGlzLmNvZGUub3BlbkZpbGUoZmlsZVBhdGgpO1xuICAgIHRoaXMuY29kZS5saW5lKEpTT04uc3RyaW5naWZ5KHsgLi4udmVyc2lvbnMsIC4uLnRoaXMudmVyc2lvbnMgfSwgbnVsbCwgMikpO1xuICAgIHRoaXMuY29kZS5jbG9zZUZpbGUoZmlsZVBhdGgpO1xuICAgIHJldHVybiBmaWxlUGF0aDtcbiAgfVxuXG4gIHB1YmxpYyBhc3luYyByZW1vdmVGb2xkZXJzVGhhdFNob3VsZE5vdEV4aXN0KFxuICAgIGNvbnN0cmFpbnRzVGhhdFNob3VsZEV4aXN0OiBUZXJyYWZvcm1EZXBlbmRlbmN5Q29uc3RyYWludFtdLFxuICApIHtcbiAgICBsb2dnZXIuZGVidWcoXG4gICAgICBgUmVtb3ZpbmcgcHJvdmlkZXJzIGV4Y2VwdCBmb3IgJHtKU09OLnN0cmluZ2lmeShcbiAgICAgICAgY29uc3RyYWludHNUaGF0U2hvdWxkRXhpc3QsXG4gICAgICAgIG51bGwsXG4gICAgICAgIDIsXG4gICAgICApfWAsXG4gICAgKTtcblxuICAgIC8vIEFsbCBsYW5ndWFnZXMgYmVzaWRlcyBUUyBrZWVwIHRoZWlyIHByb3ZpZGVycyBpbiB0aGUgc2FtZSBmb2xkZXJzIGFzIG1vZHVsZXNcbiAgICAvLyB0aGlzIG1ha2VzIGl0IGltcG9zc2libGUgZm9yIHVzIHRvIGRpc3Rpbmd1aXNoIGEgbm8gbG9uZ2VyIHJlcXVpcmVkIHByb3ZpZGVyXG4gICAgLy8gZnJvbSBhIG1hbnVhbGx5IHdyaXR0ZW4gY29uc3RydWN0IG9yIGEgbW9kdWxlXG4gICAgaWYgKCF0aGlzLmlzSmF2YXNjcmlwdFRhcmdldCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGxldCBmaWxlc0luUHJvdmlkZXJzOiBzdHJpbmdbXSA9IFtdO1xuICAgIGNvbnN0IHByb3ZpZGVyc0ZvbGRlciA9IHBhdGgucmVzb2x2ZSh0aGlzLmNvZGVNYWtlck91dGRpciwgXCJwcm92aWRlcnNcIik7XG4gICAgdHJ5IHtcbiAgICAgIGZpbGVzSW5Qcm92aWRlcnMgPSBhd2FpdCBmcy5yZWFkZGlyKHByb3ZpZGVyc0ZvbGRlcik7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgbG9nZ2VyLmRlYnVnKFxuICAgICAgICBgRXJyb3IgbGlzdGluZyBmaWxlcyBpbiBwcm92aWRlcnMgZm9sZGVyICcke3Byb3ZpZGVyc0ZvbGRlcn0nOiAke2V9YCxcbiAgICAgICk7XG4gICAgfVxuXG4gICAgY29uc3QgZm9sZGVycyA9IGZpbGVzSW5Qcm92aWRlcnMuZmlsdGVyKChmaWxlKSA9PlxuICAgICAgZnNcbiAgICAgICAgLnN0YXRTeW5jKHBhdGgucmVzb2x2ZSh0aGlzLmNvZGVNYWtlck91dGRpciwgXCJwcm92aWRlcnNcIiwgZmlsZSkpXG4gICAgICAgIC5pc0RpcmVjdG9yeSgpLFxuICAgICk7XG5cbiAgICByZXR1cm4gZm9sZGVycy5mb3JFYWNoKChmb2xkZXIpID0+IHtcbiAgICAgIGNvbnN0IHNob3VsZEV4aXN0ID0gY29uc3RyYWludHNUaGF0U2hvdWxkRXhpc3Quc29tZShcbiAgICAgICAgKGNvbnN0cmFpbnQpID0+IGNvbnN0cmFpbnQubmFtZSA9PT0gZm9sZGVyLFxuICAgICAgKTtcblxuICAgICAgaWYgKCFzaG91bGRFeGlzdCkge1xuICAgICAgICBsb2dnZXIuZGVidWcoYFJlbW92aW5nIGZvbGRlciAke2ZvbGRlcn0gZnJvbSBwcm92aWRlcnNgKTtcbiAgICAgICAgZnMucmVtb3ZlU3luYyhwYXRoLnJlc29sdmUodGhpcy5jb2RlTWFrZXJPdXRkaXIsIFwicHJvdmlkZXJzXCIsIGZvbGRlcikpO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgLy8gZW1pdHMgYSBjb25zdHJhaW50cy5qc29uIGZpbGUgd2l0aCBhIG1hcCBvZiB0aGUgdXNlZCBwcm92aWRlciBmcXBucyBhbmQgdmVyc2lvbiBjb25zdHJhaW50c1xuICAvLyB0aGlzIGlzIHVzZWQgZm9yIGNhY2hpbmcgcHVycG9zZXNcbiAgcHJpdmF0ZSBlbWl0Q29uc3RyYWludHNGaWxlKFxuICAgIGFsbG93ZWRDb25zdHJhaW50czogVGVycmFmb3JtRGVwZW5kZW5jeUNvbnN0cmFpbnRbXSxcbiAgKSB7XG4gICAgY29uc3QgZmlsZVBhdGggPSBcImNvbnN0cmFpbnRzLmpzb25cIjtcblxuICAgIGNvbnN0IGNvbnRlbnQ6IENvbnN0cmFpbnRGaWxlID0ge1xuICAgICAgY2RrdGY6IERJU1BMQVlfVkVSU0lPTixcbiAgICAgIHByb3ZpZGVyczogYWxsb3dlZENvbnN0cmFpbnRzXG4gICAgICAgIC5zb3J0KChhLCBiKSA9PiBhLmZxbi5sb2NhbGVDb21wYXJlKGIuZnFuKSlcbiAgICAgICAgLnJlZHVjZShcbiAgICAgICAgICAoY2FycnksIGl0ZW0pID0+ICh7XG4gICAgICAgICAgICAuLi5jYXJyeSxcbiAgICAgICAgICAgIFtpdGVtLmZxbl06IGl0ZW0udmVyc2lvbixcbiAgICAgICAgICB9KSxcbiAgICAgICAgICB7fSxcbiAgICAgICAgKSxcbiAgICB9O1xuXG4gICAgdGhpcy5jb2RlLm9wZW5GaWxlKGZpbGVQYXRoKTtcbiAgICB0aGlzLmNvZGUubGluZShKU09OLnN0cmluZ2lmeShjb250ZW50LCBudWxsLCAyKSk7XG4gICAgdGhpcy5jb2RlLmNsb3NlRmlsZShmaWxlUGF0aCk7XG4gICAgcmV0dXJuIGZpbGVQYXRoO1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBnZW5lcmF0ZUpzaWlMYW5ndWFnZSh0YXJnZXQ6IENvbnN0cnVjdHNNYWtlclRhcmdldCkge1xuICAgIC8vIHRoZXNlIGFyZSB0aGUgbW9kdWxlIGRlcGVuZGVuY2llcyB3ZSBjb21waWxlIGFnYWluc3RcbiAgICBjb25zdCBkZXBzID0gW1wiQHR5cGVzL25vZGVcIiwgXCJjb25zdHJ1Y3RzXCIsIFwiY2RrdG5cIl07XG4gICAgY29uc3Qgb3B0czogR2VuZXJhdGVKU0lJT3B0aW9ucyA9IHtcbiAgICAgIGVudHJ5cG9pbnQ6IHRhcmdldC5maWxlTmFtZSxcbiAgICAgIGRlcHM6IGRlcHMubWFwKChkZXApID0+XG4gICAgICAgIHBhdGguZGlybmFtZShyZXF1aXJlLnJlc29sdmUoYCR7ZGVwfS9wYWNrYWdlLmpzb25gKSksXG4gICAgICApLFxuICAgICAgbW9kdWxlS2V5OiB0YXJnZXQubW9kdWxlS2V5LFxuICAgICAgZXhwb3J0czogdGFyZ2V0LmlzUHJvdmlkZXIgLy8gTW9kdWxlcyBhcmUgc21hbGwgZW5vdWdoIHRoYXQgd2UgZG9uJ3QgbmVlZCB0aGlzIG9wdGltaXphdGlvblxuICAgICAgICA/IHtcbiAgICAgICAgICAgIFwiLlwiOiB7XG4gICAgICAgICAgICAgIGltcG9ydDogYC4vcHJvdmlkZXJzLyR7dGFyZ2V0Lm5hbWV9L2luZGV4LmpzYCxcbiAgICAgICAgICAgICAgcmVxdWlyZTogYC4vcHJvdmlkZXJzLyR7dGFyZ2V0Lm5hbWV9L2xhenktaW5kZXguanNgLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9XG4gICAgICAgIDogdW5kZWZpbmVkLFxuICAgIH07XG5cbiAgICAvLyB1c2VkIGZvciB0ZXN0aW5nLlxuICAgIGlmICh0aGlzLm9wdGlvbnMub3V0cHV0SnNpaSkge1xuICAgICAgb3B0cy5qc2lpID0geyBwYXRoOiB0aGlzLm9wdGlvbnMub3V0cHV0SnNpaSB9O1xuICAgIH1cblxuICAgIGlmICh0aGlzLmlzUHl0aG9uVGFyZ2V0KSB7XG4gICAgICBvcHRzLnB5dGhvbiA9IHtcbiAgICAgICAgb3V0ZGlyOiB0aGlzLmNvZGVNYWtlck91dGRpcixcbiAgICAgICAgbW9kdWxlTmFtZTogdGFyZ2V0LnNyY01ha05hbWUsXG4gICAgICB9O1xuICAgIH1cblxuICAgIGlmICh0aGlzLmlzSmF2YVRhcmdldCkge1xuICAgICAgaWYgKFxuICAgICAgICB0aGlzLm9wdGlvbnMuY29kZU1ha2VyT3V0cHV0LmluY2x1ZGVzKFwiL1wiKSB8fFxuICAgICAgICB0aGlzLm9wdGlvbnMuY29kZU1ha2VyT3V0cHV0LmluY2x1ZGVzKFwiXFxcXFwiKVxuICAgICAgKSB7XG4gICAgICAgIHRocm93IEVycm9ycy5Vc2FnZShcbiAgICAgICAgICBgV2hlbiB1c2luZyBKYXZhIHRoZSBcImNvZGVNYWtlck91dHB1dFwiIG9wdGlvbiBpbiB0aGUgY2RrdGYuanNvbiBtdXN0IGJlIHRoZSBvcmdhbml6YXRpb24gaWRlbnRpZmllciBmb3IgeW91ciBwcm9qZWN0IChlLmcuIGNvbS5teS1jb21wYW55KSwgbm90IGEgcGF0aC4gVGhlIGdlbmVyYXRlZCBKYXZhIGNvZGUgd2lsbCBiZSBwbGFjZWQgaW4gYSBzdWJkaXJlY3Rvcnkgb2YgdGhlIGdpdmVuIGRpcmVjdG9yeS4gSWYgeW91IGFyZSBtaWdyYXRpbmcgZnJvbSBhIDwgMC4xOSB2ZXJzaW9uIG9mIGNka3RmIHlvdSB3YW50IHRvIGNoYW5nZSB0aGUgY29kZW1ha2VyT3V0cHV0IHRvIFwiaW1wb3J0c1wiLmAsXG4gICAgICAgICk7XG4gICAgICB9XG5cbiAgICAgIG9wdHMuamF2YSA9IHtcbiAgICAgICAgb3V0ZGlyOiBcIi5cIiwgLy8gZ2VuZXJhdGVkIGphdmEgZmlsZXMgYXJlbid0IHBhY2thZ2VkLCBzbyBqdXN0IGluY2x1ZGUgZGlyZWN0bHkgaW4gYXBwXG4gICAgICAgIHBhY2thZ2U6IGAke3RoaXMub3B0aW9ucy5jb2RlTWFrZXJPdXRwdXR9LiR7dGFyZ2V0LnNyY01ha05hbWV9YCxcbiAgICAgIH07XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuaXNDc2hhcnBUYXJnZXQpIHtcbiAgICAgIG9wdHMuY3NoYXJwID0ge1xuICAgICAgICBvdXRkaXI6IHRoaXMuY29kZU1ha2VyT3V0ZGlyLFxuICAgICAgICBuYW1lc3BhY2U6IHRhcmdldC5zcmNNYWtOYW1lLFxuICAgICAgfTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5pc0dvVGFyZ2V0KSB7XG4gICAgICAvLyBUT0RPOiBjaGVjayBpZiBuZWVkZWQgZm9yIG1vZHVsZXMgc29tZWhvd1xuICAgICAgLy8gY29uc3QgdGFyZ2V0VHlwZSA9IHRhcmdldC5pc1Byb3ZpZGVyID8gJ3Byb3ZpZGVyJyA6ICdtb2R1bGUnO1xuXG4gICAgICAvLyBqc2lpLXNyY21hYyB3aWxsIHByb2R1Y2UgYSBmb2xkZXIgaW5zaWRlIHRoaXMgZGlyIG5hbWVkIGFmdGVyIFwicGFja2FnZU5hbWVcIlxuICAgICAgLy8gc28gdGhpcyByZXN1bHRzIGluIGUuZy4gLmdlbi9oYXNoaWNvcnAvcmFuZG9tXG4gICAgICBjb25zdCBvdXRkaXIgPSBwYXRoLmpvaW4odGhpcy5jb2RlTWFrZXJPdXRkaXIsIHRhcmdldC5uYW1lc3BhY2UgPz8gXCJcIik7XG5cbiAgICAgIG9wdHMuZ29sYW5nID0ge1xuICAgICAgICBvdXRkaXIsXG4gICAgICAgIG1vZHVsZU5hbWU6IGF3YWl0IGRldGVybWluZUdvTW9kdWxlTmFtZShvdXRkaXIpLCAvLyBlLmcuIGBnaXRodWIuY29tL29yZy91c2VycHJvamVjdC8uZ2VuL2hhc2hpY29ycGBcbiAgICAgICAgcGFja2FnZU5hbWU6IHRhcmdldC5zcmNNYWtOYW1lLCAvLyBwYWNrYWdlIHdpbGwgYmUgbmFtZWQgZS5nLiByYW5kb20gZm9yIGhhc2hpY29ycC9yYW5kb21cbiAgICAgIH07XG4gICAgfVxuXG4gICAgaWYgKFxuICAgICAgcHJvY2Vzcy5lbnYuTk9ERV9PUFRJT05TICYmXG4gICAgICAhcHJvY2Vzcy5lbnYuTk9ERV9PUFRJT05TLmluY2x1ZGVzKGAtLW1heC1vbGQtc3BhY2Utc2l6ZWApXG4gICAgKSB7XG4gICAgICBsb2dnZXIud2FybihgZm91bmQgTk9ERV9PUFRJT05TIGVudmlyb25tZW50IHZhcmlhYmxlIHdpdGhvdXQgYSBzZXR0aW5nIGZvciAtLW1heC1vbGQtc3BhY2Utc2l6ZS5cblRoZSBwcm92aWRlciBnZW5lcmF0aW9uIG5lZWRzIGEgc3Vic3RhbnRpYWwgYW1vdW50IG9mIG1lbW9yeSAofjEzR0IpIGZvciBzb21lIHByb3ZpZGVycyBhbmQgbGFuZ3VhZ2VzLlxuU28gY2RrdG4tY2xpIHNldHMgaXQgdG8gTk9ERV9PUFRJT05TPVwiLS1tYXgtb2xkLXNwYWNlLXNpemU9MTYzODRcIiBieSBkZWZhdWx0LiBBcyB5b3VyIGVudmlyb25tZW50IGFscmVhZHkgY29udGFpbnNcbmEgTk9ERV9PUFRJT05TIHZhcmlhYmxlLCB3ZSB3b24ndCBvdmVycmlkZSBpdC4gSGVuY2UsIHRoZSBwcm92aWRlciBnZW5lcmF0aW9uIG1pZ2h0IGZhaWwgd2l0aCBhbiBvdXQgb2YgbWVtb3J5IGVycm9yLmApO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBpbmNyZWFzZSBtZW1vcnkgdG8gYWxsb3cgZ2VuZXJhdGluZyBsYXJnZSBwcm92aWRlcnMgKGkuZS4gYXdzIG9yIGF6dXJlcm0gZm9yIEdvKVxuICAgICAgLy8gc3JjbWFrIGlzIGdvaW5nIHRvIHNwYXduIGEgY2hpbGRwcm9jZXNzIChmb3IganNpaS1wYWNtYWspIHdoaWNoIGlzIGdvaW5nIHRvIGJlIGFmZmVjdGVkIGJ5IHRoaXMgZW52IHZhclxuICAgICAgcHJvY2Vzcy5lbnYuTk9ERV9PUFRJT05TID0gXCItLW1heC1vbGQtc3BhY2Utc2l6ZT0xNjM4NFwiO1xuICAgIH1cblxuICAgIGNvbnN0IGpzaWlUaW1lciA9IGxvZ1RpbWVzcGFuKFwiSlNJSVwiKTtcbiAgICBhd2FpdCBnZW5lcmF0ZUpzaWlMYW5ndWFnZSh0aGlzLmNvZGUsIG9wdHMsIHRoaXMuY29kZU1ha2VyT3V0ZGlyLCBbXG4gICAgICB0YXJnZXQuaXNNb2R1bGUgPyBcInByb3ZpZGVycy8qKlwiIDogXCJtb2R1bGVzLyoqXCIsXG4gICAgXSk7XG4gICAganNpaVRpbWVyKCk7XG4gIH1cblxuICBwdWJsaWMgYXN5bmMgZ2V0U2NoZW1hcyh0YXJnZXRzOiBUZXJyYWZvcm1EZXBlbmRlbmN5Q29uc3RyYWludFtdKSB7XG4gICAgcmV0dXJuIGF3YWl0IHJlYWRTY2hlbWEodGFyZ2V0cywgdGhpcy5zY2hlbWFDYWNoZVBhdGgpO1xuICB9XG5cbiAgcHVibGljIGFzeW5jIGdlbmVyYXRlKFxuICAgIGFsbENvbnN0cmFpbnRzOiBUZXJyYWZvcm1EZXBlbmRlbmN5Q29uc3RyYWludFtdLFxuICAgIGNvbnN0cmFpbnRzVG9HZW5lcmF0ZSA9IGFsbENvbnN0cmFpbnRzLFxuICApIHtcbiAgICBjb25zdCB0YXJnZXRzID0gY29uc3RyYWludHNUb0dlbmVyYXRlLm1hcCgoY29uc3RyYWludCkgPT5cbiAgICAgIENvbnN0cnVjdHNNYWtlclRhcmdldC5mcm9tKGNvbnN0cmFpbnQsIHRoaXMub3B0aW9ucy50YXJnZXRMYW5ndWFnZSksXG4gICAgKTtcblxuICAgIGNvbnN0IGVuZFNjaGVtYVRpbWVyID0gbG9nVGltZXNwYW4oXCJHYXRoZXJpbmcgc2NoZW1hXCIpO1xuICAgIGNvbnN0IHNjaGVtYXMgPSBhd2FpdCB0aGlzLmdldFNjaGVtYXMoY29uc3RyYWludHNUb0dlbmVyYXRlKTtcbiAgICBlbmRTY2hlbWFUaW1lcigpO1xuXG4gICAgY29uc3QgZW5kR2VuZXJhdGVUaW1lciA9IGxvZ1RpbWVzcGFuKFwiR2VuZXJhdGUgVFNcIik7XG4gICAgYXdhaXQgUHJvbWlzZS5hbGwoXG4gICAgICB0YXJnZXRzLm1hcCgodGFyZ2V0KSA9PiB0aGlzLmdlbmVyYXRlVHlwZXNjcmlwdCh0YXJnZXQsIHNjaGVtYXMpKSxcbiAgICApO1xuICAgIGVuZEdlbmVyYXRlVGltZXIoKTtcblxuICAgIHRoaXMudXBkYXRlVmVyc2lvbnNGaWxlKGFsbENvbnN0cmFpbnRzKTtcbiAgICB0aGlzLmVtaXRDb25zdHJhaW50c0ZpbGUoYWxsQ29uc3RyYWludHMpO1xuXG4gICAgaWYgKHRoaXMuaXNKYXZhc2NyaXB0VGFyZ2V0KSB7XG4gICAgICBhd2FpdCB0aGlzLnNhdmUoKTtcbiAgICB9XG5cbiAgICBpZiAoIXRoaXMuaXNKYXZhc2NyaXB0VGFyZ2V0IHx8IHRoaXMub3B0aW9ucy5vdXRwdXRKc2lpKSB7XG4gICAgICBjb25zdCBudW1iZXJPZldvcmtlcnMgPSBNYXRoLm1heChcbiAgICAgICAgMSxcbiAgICAgICAgdGhpcy5vcHRpb25zLmpzaWlQYXJhbGxlbGlzbSA9PT0gLTFcbiAgICAgICAgICA/IHRhcmdldHMubGVuZ3RoXG4gICAgICAgICAgOiB0aGlzLm9wdGlvbnMuanNpaVBhcmFsbGVsaXNtIHx8IDEsXG4gICAgICApO1xuXG4gICAgICBjb25zdCB3b3JrID0gWy4uLnRhcmdldHNdO1xuICAgICAgY29uc3Qgd29ya2VycyA9IG5ldyBBcnJheShudW1iZXJPZldvcmtlcnMpLmZpbGwoYXN5bmMgKCkgPT4ge1xuICAgICAgICBsZXQgdGFyZ2V0OiBDb25zdHJ1Y3RzTWFrZXJUYXJnZXQgfCB1bmRlZmluZWQ7XG4gICAgICAgIHdoaWxlICgodGFyZ2V0ID0gd29yay5wb3AoKSkpIHtcbiAgICAgICAgICBjb25zdCBlbmRKc2lpVGFyZ2V0ID0gbG9nVGltZXNwYW4oXG4gICAgICAgICAgICBgR2VuZXJhdGluZyBKU0lJIGJpbmRpbmdzIGZvciAke3RhcmdldC5uYW1lfWAsXG4gICAgICAgICAgKTtcbiAgICAgICAgICBhd2FpdCB0aGlzLmdlbmVyYXRlSnNpaUxhbmd1YWdlKHRhcmdldCk7XG4gICAgICAgICAgZW5kSnNpaVRhcmdldCgpO1xuICAgICAgICB9XG4gICAgICB9KTtcblxuICAgICAgYXdhaXQgUHJvbWlzZS5hbGwod29ya2Vycy5tYXAoKGZuKSA9PiBmbigpKSk7XG4gICAgfVxuXG4gICAgZm9yIChjb25zdCB0YXJnZXQgb2YgdGFyZ2V0cykge1xuICAgICAgYXdhaXQgdGhpcy5yZXBvcnRUZWxlbWV0cnkoe1xuICAgICAgICB0cmFja2luZ1BheWxvYWQ6IHRhcmdldC50cmFja2luZ1BheWxvYWQsXG4gICAgICAgIHRhcmdldExhbmd1YWdlOiB0YXJnZXQudGFyZ2V0TGFuZ3VhZ2UsXG4gICAgICB9KTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5pc1B5dGhvblRhcmdldCkge1xuICAgICAgY29uc3QgZW5kUHl0aG9uVGltZXIgPSBsb2dUaW1lc3BhbihcIlB5dGhvbiBwb3N0LXByb2Nlc3NpbmdcIik7XG4gICAgICAvLyBSZW1vdmUgZnJvbSAuIGltcG9ydCAuLi4gc3RhdGVtZW50cyBmcm9tIHJvb3QgbGV2ZWwgX19pbml0X18ucHlcbiAgICAgIC8vIFRoaXMgcmVtb3ZlcyByb290LWxldmVsIGltcG9ydHMgb2YgbmFtZXNwYWNlcywgYnV0IHNhdmVzIDI1cyBzeW50aCB0aW1lIGZvciB0aGUgYXdzIHByb3ZpZGVyIGFsb25lXG4gICAgICBjb25zdCBhbGxJbml0UHlQYXRocyA9IGdsb2JcbiAgICAgICAgLnN5bmMoXCIqKi9fX2luaXRfXy5weVwiLCB7XG4gICAgICAgICAgY3dkOiB0aGlzLmNvZGVNYWtlck91dGRpcixcbiAgICAgICAgfSlcbiAgICAgICAgLy8gc29ydCBieSBkZXB0aCwgc28gd2Ugc3RhcnQgd2l0aCB0aGUgc2hhbGxvd2VzdCBmaWxlc1xuICAgICAgICAuc29ydCgoYSwgYikgPT4gYS5zcGxpdChcIi9cIikubGVuZ3RoIC0gYi5zcGxpdChcIi9cIikubGVuZ3RoKTtcblxuICAgICAgY29uc3QgdmlzaXRlZERpcmVjdG9yaWVzOiBzdHJpbmdbXSA9IFtdO1xuICAgICAgZm9yIChjb25zdCBpbml0UHlQYXRoIG9mIGFsbEluaXRQeVBhdGhzKSB7XG4gICAgICAgIGNvbnN0IGRpcmVjdG9yeVBhdGggPSBwYXRoLmRpcm5hbWUoaW5pdFB5UGF0aCk7XG4gICAgICAgIGlmICh2aXNpdGVkRGlyZWN0b3JpZXMuc29tZSgoZGlyKSA9PiBkaXJlY3RvcnlQYXRoLnN0YXJ0c1dpdGgoZGlyKSkpIHtcbiAgICAgICAgICAvLyB3ZSBhbHJlYWR5IHByb2Nlc3NlZCB0aGlzIGRpcmVjdG9yeVxuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG4gICAgICAgIHZpc2l0ZWREaXJlY3Rvcmllcy5wdXNoKGRpcmVjdG9yeVBhdGgpO1xuXG4gICAgICAgIGNvbnN0IGFic29sdXRlSW5pdFB5UGF0aCA9IHBhdGguam9pbih0aGlzLmNvZGVNYWtlck91dGRpciwgaW5pdFB5UGF0aCk7XG4gICAgICAgIGNvbnN0IGluaXRQeSA9IGF3YWl0IGZzLnJlYWRGaWxlKGFic29sdXRlSW5pdFB5UGF0aCwgXCJ1dGY4XCIpO1xuICAgICAgICBjb25zdCBpbml0UHlXaXRob3V0SW1wb3J0cyA9IGluaXRQeS5yZXBsYWNlKC9mcm9tIFxcLiBpbXBvcnQgLipcXG4vZywgXCJcIik7XG4gICAgICAgIGF3YWl0IGZzLndyaXRlRmlsZShhYnNvbHV0ZUluaXRQeVBhdGgsIGluaXRQeVdpdGhvdXRJbXBvcnRzKTtcbiAgICAgIH1cblxuICAgICAgZW5kUHl0aG9uVGltZXIoKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIHNhdmUob3V0ZGlyID0gdGhpcy5jb2RlTWFrZXJPdXRkaXIpIHtcbiAgICBhd2FpdCB0aGlzLmNvZGUuc2F2ZShvdXRkaXIpO1xuICB9XG5cbiAgcHJpdmF0ZSBnZXQgaXNKYXZhc2NyaXB0VGFyZ2V0KCkge1xuICAgIHJldHVybiB0aGlzLm9wdGlvbnMudGFyZ2V0TGFuZ3VhZ2UgPT09IExhbmd1YWdlLlRZUEVTQ1JJUFQ7XG4gIH1cblxuICBwcml2YXRlIGdldCBpc1B5dGhvblRhcmdldCgpIHtcbiAgICByZXR1cm4gdGhpcy5vcHRpb25zLnRhcmdldExhbmd1YWdlID09PSBMYW5ndWFnZS5QWVRIT047XG4gIH1cblxuICBwcml2YXRlIGdldCBpc0phdmFUYXJnZXQoKSB7XG4gICAgcmV0dXJuIHRoaXMub3B0aW9ucy50YXJnZXRMYW5ndWFnZSA9PT0gTGFuZ3VhZ2UuSkFWQTtcbiAgfVxuXG4gIHByaXZhdGUgZ2V0IGlzQ3NoYXJwVGFyZ2V0KCkge1xuICAgIHJldHVybiB0aGlzLm9wdGlvbnMudGFyZ2V0TGFuZ3VhZ2UgPT09IExhbmd1YWdlLkNTSEFSUDtcbiAgfVxuXG4gIHByaXZhdGUgZ2V0IGlzR29UYXJnZXQoKSB7XG4gICAgcmV0dXJuIHRoaXMub3B0aW9ucy50YXJnZXRMYW5ndWFnZSA9PT0gTGFuZ3VhZ2UuR087XG4gIH1cbn1cblxuLyoqXG4gKiBzZWFyY2hlcyBmb3IgdGhlIGNsb3Nlc3QgYGdvLm1vZGAgZmlsZSBhbmQgcmV0dXJucyB0aGUgbmVzdGVkIGdvIG1vZHVsZSBuYW1lIGZvciBgZGlyYFxuICogZS5nLiAoL2Rpci8uZ2VuLykgPT4gY2RrLnRmL3N0YWNrLy5nZW4gaWYgdGhlIHBhcmVudCBkaXIgb2YgLmdlbiBoYXMgYSBnby5tb2QgZm9yIFwibW9kdWxlIGNkay50Zi9zdGFja1wiXG4gKlxuICogQHBhcmFtIGRpciB0aGUgZGlyZWN0b3J5IHRvIHN0YXJ0IHRoZSBzZWFyY2ggZnJvbSAoc2VhcmNoZXMgdXB3YXJkcylcbiAqIEByZXR1cm5zIHRoZSBwYWNrYWdlIG5hbWUgZm9yIGBkaXJgXG4gKiBAdGhyb3dzIGFuIEVycm9yIGlmIG5vIGdvLm1vZCB3YXMgZm91bmRcbiAqL1xuZXhwb3J0IGNvbnN0IGRldGVybWluZUdvTW9kdWxlTmFtZSA9IGFzeW5jIChkaXI6IHN0cmluZyk6IFByb21pc2U8c3RyaW5nPiA9PiB7XG4gIGxldCBwcmV2aW91c0RpcjtcbiAgbGV0IGN1cnJlbnREaXIgPSBwYXRoLnJlc29sdmUoZGlyKTtcblxuICBkbyB7XG4gICAgbGV0IGZpbGVzOiBzdHJpbmdbXSA9IFtdO1xuICAgIHRyeSB7XG4gICAgICBmaWxlcyA9IGF3YWl0IGZzLnJlYWRkaXIoY3VycmVudERpcik7XG4gICAgfSBjYXRjaCAoZTogYW55KSB7XG4gICAgICAvLyBkaXJlY3RvcnkgbWlnaHQgbm90IGV4aXN0IHlldCwgYnV0IHdlIHN0aWxsIHdhbGsgdXB3YXJkcyBmcm9tIHRoZXJlLCBzbyBpZ25vcmUgJ0VOT0VOVCdcbiAgICAgIGlmIChlLmNvZGUgIT09IFwiRU5PRU5UXCIpIHtcbiAgICAgICAgdGhyb3cgZTtcbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKGZpbGVzLmluY2x1ZGVzKFwiZ28ubW9kXCIpKSB7XG4gICAgICBjb25zdCBmaWxlID0gcGF0aC5yZXNvbHZlKGN1cnJlbnREaXIsIFwiZ28ubW9kXCIpO1xuICAgICAgY29uc3QgZ29tb2QgPSBhd2FpdCBmcy5yZWFkRmlsZShmaWxlKTtcbiAgICAgIGNvbnN0IG1hdGNoID0gL15tb2R1bGVcXHMqKFxcUyopXFxzKiQvbS5leGVjKGdvbW9kLnRvU3RyaW5nKCkpO1xuICAgICAgaWYgKG1hdGNoICYmIG1hdGNoWzFdKSB7XG4gICAgICAgIGNvbnN0IGNoaWxkZGlyID0gcGF0aC5yZWxhdGl2ZShjdXJyZW50RGlyLCBkaXIpLnJlcGxhY2UoL1xcXFwvZywgXCIvXCIpOyAvLyByZXBsYWNlICdcXCcgd2l0aCAnLycgZm9yIHdpbmRvd3MgcGF0aHNcbiAgICAgICAgcmV0dXJuIGNoaWxkZGlyLmxlbmd0aCA+IDAgPyBgJHttYXRjaFsxXX0vJHtjaGlsZGRpcn1gIDogbWF0Y2hbMV07XG4gICAgICB9XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgIGBDb3VsZCBub3QgZGV0ZXJtaW5lIHRoZSByb290IEdvIG1vZHVsZSBuYW1lLiBGb3VuZCAke2ZpbGV9IGJ1dCBmYWlsZWQgdG8gcmVnZXggbWF0Y2ggdGhlIG1vZHVsZSBuYW1lIGRpcmVjdGl2ZWAsXG4gICAgICApO1xuICAgIH1cbiAgICAvLyBnbyB1cCBvbmUgZGlyZWN0b3J5LiBBcyBkaXJuYW1lKCcvJykgd2lsbCByZXR1cm4gJy8nIHdlIGNhbmNlbCB0aGUgbG9vcFxuICAgIC8vIGFzIHNvb24gYXMgdGhlIGRpciBkb2VzIG5vdCBjaGFuZ2UgYW55bW9yZS5cbiAgICBwcmV2aW91c0RpciA9IGN1cnJlbnREaXI7XG4gICAgY3VycmVudERpciA9IHBhdGguZGlybmFtZShjdXJyZW50RGlyKTtcbiAgfSB3aGlsZSAoY3VycmVudERpciAhPT0gcHJldmlvdXNEaXIpO1xuXG4gIHRocm93IG5ldyBFcnJvcihcbiAgICBgQ291bGQgbm90IGRldGVybWluZSB0aGUgcm9vdCBHbyBtb2R1bGUgbmFtZS4gTm8gZ28ubW9kIGZvdW5kIGluICR7ZGlyfSBhbmQgYW55IHBhcmVudCBkaXJlY3Rvcmllc2AsXG4gICk7XG59O1xuIl19