@cdktn/cli-core 0.22.0-pre.2

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 (154) hide show
  1. package/README.md +3 -0
  2. package/ambient.d.ts +13 -0
  3. package/eslint.config.mjs +82 -0
  4. package/jest.config.js +20 -0
  5. package/package.json +139 -0
  6. package/src/lib/cdktf-config.d.ts +16 -0
  7. package/src/lib/cdktf-config.d.ts.map +1 -0
  8. package/src/lib/cdktf-config.js +108 -0
  9. package/src/lib/cdktf-project-io-handler.d.ts +20 -0
  10. package/src/lib/cdktf-project-io-handler.d.ts.map +1 -0
  11. package/src/lib/cdktf-project-io-handler.js +84 -0
  12. package/src/lib/cdktf-project.d.ts +111 -0
  13. package/src/lib/cdktf-project.d.ts.map +1 -0
  14. package/src/lib/cdktf-project.js +371 -0
  15. package/src/lib/cdktf-stack.d.ts +134 -0
  16. package/src/lib/cdktf-stack.d.ts.map +1 -0
  17. package/src/lib/cdktf-stack.js +386 -0
  18. package/src/lib/convert.d.ts +6 -0
  19. package/src/lib/convert.d.ts.map +1 -0
  20. package/src/lib/convert.js +51 -0
  21. package/src/lib/dependencies/cdktf-config-manager.d.ts +12 -0
  22. package/src/lib/dependencies/cdktf-config-manager.d.ts.map +1 -0
  23. package/src/lib/dependencies/cdktf-config-manager.js +36 -0
  24. package/src/lib/dependencies/dependency-manager.d.ts +84 -0
  25. package/src/lib/dependencies/dependency-manager.d.ts.map +1 -0
  26. package/src/lib/dependencies/dependency-manager.js +365 -0
  27. package/src/lib/dependencies/package-manager.d.ts +18 -0
  28. package/src/lib/dependencies/package-manager.d.ts.map +1 -0
  29. package/src/lib/dependencies/package-manager.js +574 -0
  30. package/src/lib/dependencies/prebuilt-providers.d.ts +18 -0
  31. package/src/lib/dependencies/prebuilt-providers.d.ts.map +1 -0
  32. package/src/lib/dependencies/prebuilt-providers.js +204 -0
  33. package/src/lib/dependencies/registry-api.d.ts +8 -0
  34. package/src/lib/dependencies/registry-api.d.ts.map +1 -0
  35. package/src/lib/dependencies/registry-api.js +77 -0
  36. package/src/lib/dependencies/version-constraints.d.ts +8 -0
  37. package/src/lib/dependencies/version-constraints.d.ts.map +1 -0
  38. package/src/lib/dependencies/version-constraints.js +95 -0
  39. package/src/lib/error-reporting.d.ts +10 -0
  40. package/src/lib/error-reporting.d.ts.map +1 -0
  41. package/src/lib/error-reporting.js +133 -0
  42. package/src/lib/errors.d.ts +6 -0
  43. package/src/lib/errors.d.ts.map +1 -0
  44. package/src/lib/errors.js +10 -0
  45. package/src/lib/execution-logs.d.ts +3 -0
  46. package/src/lib/execution-logs.d.ts.map +1 -0
  47. package/src/lib/execution-logs.js +47 -0
  48. package/src/lib/get.d.ts +25 -0
  49. package/src/lib/get.d.ts.map +1 -0
  50. package/src/lib/get.js +90 -0
  51. package/src/lib/helpers/stack-helpers.d.ts +16 -0
  52. package/src/lib/helpers/stack-helpers.d.ts.map +1 -0
  53. package/src/lib/helpers/stack-helpers.js +155 -0
  54. package/src/lib/index.d.ts +15 -0
  55. package/src/lib/index.d.ts.map +1 -0
  56. package/src/lib/index.js +44 -0
  57. package/src/lib/init.d.ts +37 -0
  58. package/src/lib/init.d.ts.map +1 -0
  59. package/src/lib/init.js +131 -0
  60. package/src/lib/local-provider-constraints.d.ts +28 -0
  61. package/src/lib/local-provider-constraints.d.ts.map +1 -0
  62. package/src/lib/local-provider-constraints.js +95 -0
  63. package/src/lib/local-provider-versions.d.ts +12 -0
  64. package/src/lib/local-provider-versions.d.ts.map +1 -0
  65. package/src/lib/local-provider-versions.js +73 -0
  66. package/src/lib/models/deploy-machine.d.ts +128 -0
  67. package/src/lib/models/deploy-machine.d.ts.map +1 -0
  68. package/src/lib/models/deploy-machine.js +280 -0
  69. package/src/lib/models/pty-process.d.ts +29 -0
  70. package/src/lib/models/pty-process.d.ts.map +1 -0
  71. package/src/lib/models/pty-process.js +132 -0
  72. package/src/lib/models/schema.d.ts +2307 -0
  73. package/src/lib/models/schema.d.ts.map +1 -0
  74. package/src/lib/models/schema.js +181 -0
  75. package/src/lib/models/terraform-cli.d.ts +72 -0
  76. package/src/lib/models/terraform-cli.d.ts.map +1 -0
  77. package/src/lib/models/terraform-cli.js +357 -0
  78. package/src/lib/models/terraform.d.ts +125 -0
  79. package/src/lib/models/terraform.d.ts.map +1 -0
  80. package/src/lib/models/terraform.js +72 -0
  81. package/src/lib/output.d.ts +23 -0
  82. package/src/lib/output.d.ts.map +1 -0
  83. package/src/lib/output.js +211 -0
  84. package/src/lib/provider-add.d.ts +15 -0
  85. package/src/lib/provider-add.d.ts.map +1 -0
  86. package/src/lib/provider-add.js +30 -0
  87. package/src/lib/server/terraform-logs.d.ts +2 -0
  88. package/src/lib/server/terraform-logs.d.ts.map +1 -0
  89. package/src/lib/server/terraform-logs.js +19 -0
  90. package/src/lib/synth-stack.d.ts +29 -0
  91. package/src/lib/synth-stack.d.ts.map +1 -0
  92. package/src/lib/synth-stack.js +251 -0
  93. package/src/lib/synth.d.ts +7 -0
  94. package/src/lib/synth.d.ts.map +1 -0
  95. package/src/lib/synth.js +67 -0
  96. package/src/lib/terraform-json.d.ts +1015 -0
  97. package/src/lib/terraform-json.d.ts.map +1 -0
  98. package/src/lib/terraform-json.js +82 -0
  99. package/src/lib/terraform-provider-lock.d.ts +25 -0
  100. package/src/lib/terraform-provider-lock.d.ts.map +1 -0
  101. package/src/lib/terraform-provider-lock.js +95 -0
  102. package/src/lib/watch.d.ts +16 -0
  103. package/src/lib/watch.d.ts.map +1 -0
  104. package/src/lib/watch.js +155 -0
  105. package/templates/csharp/.hooks.sscaff.js +63 -0
  106. package/templates/csharp/MainStack.cs +15 -0
  107. package/templates/csharp/MyTerraformStack.csproj +13 -0
  108. package/templates/csharp/Program.cs +17 -0
  109. package/templates/csharp/TestProgram.cs +42 -0
  110. package/templates/csharp/cdktf.json +11 -0
  111. package/templates/csharp/help +42 -0
  112. package/templates/csharp/{{}}.gitignore +345 -0
  113. package/templates/go/.hooks.sscaff.js +70 -0
  114. package/templates/go/cdktf.json +12 -0
  115. package/templates/go/go.mod +8 -0
  116. package/templates/go/help +32 -0
  117. package/templates/go/main.go +22 -0
  118. package/templates/go/main_test.go +42 -0
  119. package/templates/go/{{}}.gitignore +21 -0
  120. package/templates/java/.hooks.sscaff.js +64 -0
  121. package/templates/java/build.gradle +55 -0
  122. package/templates/java/cdktf.json +12 -0
  123. package/templates/java/gradle.properties +1 -0
  124. package/templates/java/gradlew +248 -0
  125. package/templates/java/gradlew.bat +92 -0
  126. package/templates/java/help +35 -0
  127. package/templates/java/settings.gradle +5 -0
  128. package/templates/java/src/main/java/com/mycompany/app/Main.java +16 -0
  129. package/templates/java/src/main/java/com/mycompany/app/MainStack.java +14 -0
  130. package/templates/java/src/test/java/com/company/app/MainTest.java +38 -0
  131. package/templates/java/{{}}.gitignore +14 -0
  132. package/templates/python/.hooks.sscaff.js +59 -0
  133. package/templates/python/Pipfile +7 -0
  134. package/templates/python/cdktf.json +12 -0
  135. package/templates/python/help +42 -0
  136. package/templates/python/main-test.py +26 -0
  137. package/templates/python/main.py +16 -0
  138. package/templates/python/{{}}.gitignore +7 -0
  139. package/templates/python-pip/.hooks.sscaff.js +63 -0
  140. package/templates/python-pip/cdktf.json +12 -0
  141. package/templates/python-pip/help +35 -0
  142. package/templates/python-pip/main-test.py +23 -0
  143. package/templates/python-pip/main.py +16 -0
  144. package/templates/python-pip/{{}}.gitignore +7 -0
  145. package/templates/typescript/.hooks.sscaff.js +78 -0
  146. package/templates/typescript/__tests__/main-test.ts +89 -0
  147. package/templates/typescript/cdktf.json +11 -0
  148. package/templates/typescript/help +51 -0
  149. package/templates/typescript/jest.config.js +187 -0
  150. package/templates/typescript/main.ts +14 -0
  151. package/templates/typescript/package.json +22 -0
  152. package/templates/typescript/setup.js +2 -0
  153. package/templates/typescript/tsconfig.json +35 -0
  154. package/templates/typescript/{{}}.gitignore +11 -0
@@ -0,0 +1,574 @@
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
+ var __importDefault = (this && this.__importDefault) || function (mod) {
26
+ return (mod && mod.__esModule) ? mod : { "default": mod };
27
+ };
28
+ Object.defineProperty(exports, "__esModule", { value: true });
29
+ exports.PackageManager = void 0;
30
+ // Copyright (c) HashiCorp, Inc
31
+ // SPDX-License-Identifier: MPL-2.0
32
+ const commons_1 = require("@cdktn/commons");
33
+ const fs_extra_1 = require("fs-extra");
34
+ const path_1 = __importDefault(require("path"));
35
+ const xml_js_1 = require("xml-js");
36
+ const fs = __importStar(require("fs-extra"));
37
+ const semver = __importStar(require("semver"));
38
+ const node_fetch_1 = __importDefault(require("node-fetch"));
39
+ const z = __importStar(require("zod"));
40
+ // Can't use CDKTF_ as prefix because yargs .env("CDKTF") in strict mode does not allow us to
41
+ // Refer to: https://github.com/yargs/yargs/issues/873
42
+ const { GITHUB_API_TOKEN_CDKTF } = process.env;
43
+ // {
44
+ // "version": "1.0.0",
45
+ // "name": "testUSHasF",
46
+ // "problems": [
47
+ // "extraneous: archiver-utils@2.1.0 /private/var/folders/z_/v03l33d55fb57nrr3b1q03ch0000gq/T/testUSHasF/node_modules/archiver-utils",
48
+ // ],
49
+ // "dependencies": {
50
+ // "@cdktf/provider-random": {
51
+ // "version": "3.0.11",
52
+ // "resolved": "https://registry.npmjs.org/@cdktf/provider-random/-/provider-random-3.0.11.tgz"
53
+ // },
54
+ const npmListSchema = z
55
+ .object({
56
+ dependencies: z.record(z
57
+ .object({
58
+ version: z.string(),
59
+ })
60
+ .nonstrict()),
61
+ })
62
+ .deepPartial()
63
+ .nonstrict();
64
+ // {
65
+ // "type": "tree",
66
+ // "data": {
67
+ // "type": "list",
68
+ // "trees": [
69
+ // {
70
+ // "name": "@cdktf/provider-random@3.0.11",
71
+ // "children": [],
72
+ // "hint": null,
73
+ // "color": "bold",
74
+ // "depth": 0
75
+ // }
76
+ // ]
77
+ // }
78
+ // }
79
+ const yarnListSchema = z
80
+ .object({
81
+ data: z
82
+ .object({
83
+ trees: z.array(z
84
+ .object({
85
+ name: z.string(),
86
+ })
87
+ .nonstrict()),
88
+ })
89
+ .nonstrict(),
90
+ })
91
+ .deepPartial()
92
+ .nonstrict();
93
+ // [
94
+ // {
95
+ // "name": "appdirs",
96
+ // "version": "1.4.4"
97
+ // },
98
+ // {
99
+ const pipPackageSchema = z.array(z.object({ name: z.string(), version: z.string() }).nonstrict());
100
+ /**
101
+ * manages installing, updating, and removing dependencies
102
+ * in the package system used by the target language of a CDKTN
103
+ * project
104
+ */
105
+ class PackageManager {
106
+ constructor(workingDirectory) {
107
+ this.workingDirectory = workingDirectory;
108
+ }
109
+ static forLanguage(language, workingDirectory) {
110
+ switch (language) {
111
+ case commons_1.Language.GO:
112
+ return new GoPackageManager(workingDirectory);
113
+ case commons_1.Language.TYPESCRIPT:
114
+ return new NodePackageManager(workingDirectory);
115
+ case commons_1.Language.PYTHON:
116
+ return new PythonPackageManager(workingDirectory);
117
+ case commons_1.Language.CSHARP:
118
+ return new NugetPackageManager(workingDirectory);
119
+ case commons_1.Language.JAVA:
120
+ if (GradlePackageManager.isGradleProject(workingDirectory)) {
121
+ return new GradlePackageManager(workingDirectory);
122
+ }
123
+ return new MavenPackageManager(workingDirectory);
124
+ default:
125
+ throw new Error(`Unknown language: ${language}`);
126
+ }
127
+ }
128
+ }
129
+ exports.PackageManager = PackageManager;
130
+ class NodePackageManager extends PackageManager {
131
+ hasYarnLockfile() {
132
+ return (0, fs_extra_1.existsSync)(path_1.default.join(this.workingDirectory, "yarn.lock"));
133
+ }
134
+ async addPackage(packageName, packageVersion, silent) {
135
+ console.log(`Adding package ${packageName} @ ${packageVersion}`);
136
+ // probe for package-lock.json or yarn.lock
137
+ let command = "npm";
138
+ let args = ["install"];
139
+ if (this.hasYarnLockfile()) {
140
+ command = "yarn";
141
+ args = ["add"];
142
+ }
143
+ args.push(packageVersion ? packageName + "@" + packageVersion : packageName);
144
+ if (silent) {
145
+ args.push("--silent");
146
+ args.push("--no-progress");
147
+ }
148
+ // Install exact version
149
+ // Yarn: https://classic.yarnpkg.com/lang/en/docs/cli/add/#toc-yarn-add-exact-e
150
+ // Npm: https://docs.npmjs.com/cli/v8/commands/npm-install#save-exact
151
+ args.push("-E");
152
+ commons_1.logger.info(`Installing package ${packageName} @ ${packageVersion} using ${command}.`);
153
+ await (0, commons_1.exec)(command, args, { cwd: this.workingDirectory });
154
+ commons_1.logger.info("Package installed.");
155
+ }
156
+ async isNpmVersionAvailable(_packageName, _packageVersion) {
157
+ // We get the list of available versions from npm, no need to check here
158
+ return true;
159
+ }
160
+ async listYarnPackages() {
161
+ var _a;
162
+ try {
163
+ const stdout = await (0, commons_1.exec)("yarn", ["list", "--json"], {
164
+ cwd: this.workingDirectory,
165
+ });
166
+ commons_1.logger.debug(`Listing yarn packages using "yarn list --json": ${stdout}`);
167
+ const json = yarnListSchema.parse(JSON.parse(stdout));
168
+ return (((_a = json === null || json === void 0 ? void 0 : json.data) === null || _a === void 0 ? void 0 : _a.trees) || [])
169
+ .filter((dep) => dep.name.startsWith("@cdktf/provider-"))
170
+ .map((dep) => ({
171
+ name: `@${dep.name.split("@")[1]}`,
172
+ version: dep.name.split("@")[2],
173
+ }));
174
+ }
175
+ catch (e) {
176
+ throw new Error(`Could not determine installed packages using 'yarn list --json': ${e.message}`);
177
+ }
178
+ }
179
+ async listNpmPackages() {
180
+ try {
181
+ const stdout = await (0, commons_1.exec)("npm", ["list", "--json"], {
182
+ cwd: this.workingDirectory,
183
+ });
184
+ commons_1.logger.debug(`Listing npm packages using "npm list --json": ${stdout}`);
185
+ const json = npmListSchema.parse(JSON.parse(stdout));
186
+ return Object.entries((json === null || json === void 0 ? void 0 : json.dependencies) || {})
187
+ .filter(([depName]) => depName.startsWith("@cdktf/provider-"))
188
+ .map(([name, dep]) => ({ name, version: dep.version }));
189
+ }
190
+ catch (e) {
191
+ throw new Error(`Could not determine installed packages using 'npm list --json': ${e.message}`);
192
+ }
193
+ }
194
+ async listProviderPackages() {
195
+ return this.hasYarnLockfile()
196
+ ? this.listYarnPackages()
197
+ : this.listNpmPackages();
198
+ }
199
+ }
200
+ class PythonPackageManager extends PackageManager {
201
+ get appCommand() {
202
+ try {
203
+ return JSON.parse(fs.readFileSync(path_1.default.resolve(this.workingDirectory, "cdktf.json"), "utf8"))["app"];
204
+ }
205
+ catch (e) {
206
+ throw commons_1.Errors.Usage(`Could not find find and parse cdktf.json in ${this.workingDirectory}`, e);
207
+ }
208
+ }
209
+ async addPackage(packageName, packageVersion) {
210
+ const usePipenv = this.appCommand.includes("pipenv");
211
+ if (usePipenv) {
212
+ console.log(`Installing package ${packageName} @ ${packageVersion} using pipenv.`);
213
+ await (0, commons_1.exec)("pipenv", ["install", `${packageName}~=${packageVersion}`], {
214
+ cwd: this.workingDirectory,
215
+ env: {
216
+ ...process.env,
217
+ PIPENV_QUIET: "1",
218
+ },
219
+ stdio: ["inherit", 1, 1],
220
+ });
221
+ console.log("Package installed.");
222
+ }
223
+ else {
224
+ console.log(`Installing package ${packageName} @ ${packageVersion} using pip.`);
225
+ const requirementsFilePath = path_1.default.join(this.workingDirectory, "requirements.txt");
226
+ if (!fs.existsSync(requirementsFilePath)) {
227
+ throw commons_1.Errors.Usage(`Could not find requirements.txt in ${this.workingDirectory}`);
228
+ }
229
+ const requirements = await fs.readFile(requirementsFilePath, "utf8");
230
+ const requirementLine = requirements
231
+ .split("\n")
232
+ .find((line) => line.includes(packageName));
233
+ commons_1.logger.debug(`Read requirements.txt file and found line including ${packageName}: ${requirementLine}`);
234
+ if (requirementLine) {
235
+ if (packageVersion ? requirementLine.includes(packageVersion) : true) {
236
+ commons_1.logger.info(`Package ${packageName} already installed. Skipping installation.`);
237
+ return;
238
+ }
239
+ else {
240
+ commons_1.logger.debug(`Found the package but with a different version, continuing`);
241
+ }
242
+ }
243
+ const newRequirements = requirements
244
+ .split("\n")
245
+ .filter((line) => !line.startsWith(packageName))
246
+ .join("\n") +
247
+ `\n${packageName}${packageVersion ? `~=${packageVersion}` : ""}`;
248
+ await fs.writeFile(requirementsFilePath, newRequirements, "utf8");
249
+ await (0, commons_1.exec)("pip", ["install", "-r", "requirements.txt"], {
250
+ cwd: this.workingDirectory,
251
+ stdio: ["inherit", 1, 1],
252
+ });
253
+ console.log("Package installed.");
254
+ }
255
+ }
256
+ async isNpmVersionAvailable(packageName, packageVersion) {
257
+ commons_1.logger.debug(`Checking if ${packageName}@${packageVersion} is available for Python`);
258
+ const url = `https://pypi.org/pypi/${packageName}/${packageVersion}/json`;
259
+ commons_1.logger.debug(`Fetching package information for ${packageName} from ${url}`);
260
+ const response = await (0, node_fetch_1.default)(url);
261
+ const json = (await response.json());
262
+ commons_1.logger.debug(`Got response from PyPI for ${packageName}@${packageVersion}: ${JSON.stringify(json)}`);
263
+ if (json.info) {
264
+ // We found the version, so it exists
265
+ return true;
266
+ }
267
+ else {
268
+ commons_1.logger.debug(`Could not get PyPI package info, got: ${JSON.stringify(json)}`);
269
+ return false;
270
+ }
271
+ }
272
+ async listPipenvPackages() {
273
+ try {
274
+ const stdout = await (0, commons_1.exec)("pipenv", ["run", "pip", "list", "--format=json"], {
275
+ cwd: this.workingDirectory,
276
+ });
277
+ commons_1.logger.debug(`Listing pipenv packages using "pipenv run pip list --format=json": ${stdout}`);
278
+ const list = pipPackageSchema.parse(JSON.parse(stdout));
279
+ return list.filter((item) => item.name.startsWith("cdktf-cdktf-provider"));
280
+ }
281
+ catch (e) {
282
+ throw new Error(`Could not determine installed packages using 'pipenv run pip list --format=json': ${e.message}`);
283
+ }
284
+ }
285
+ async listPipPackages() {
286
+ try {
287
+ const stdout = await (0, commons_1.exec)("pip", ["list", "--format=json"], {
288
+ cwd: this.workingDirectory,
289
+ });
290
+ commons_1.logger.debug(`Listing pipenv packages using "pip list --format=json": ${stdout}`);
291
+ const list = pipPackageSchema.parse(JSON.parse(stdout));
292
+ return list.filter((item) => item.name.startsWith("cdktf-cdktf-provider"));
293
+ }
294
+ catch (e) {
295
+ throw new Error(`Could not determine installed packages using 'pip list --format=json': ${e.message}`);
296
+ }
297
+ }
298
+ async listProviderPackages() {
299
+ return this.appCommand.includes("pipenv")
300
+ ? this.listPipenvPackages()
301
+ : this.listPipPackages();
302
+ }
303
+ }
304
+ class NugetPackageManager extends PackageManager {
305
+ async addPackage(packageName, packageVersion) {
306
+ const command = "dotnet";
307
+ const args = ["add", "package", packageName];
308
+ if (packageVersion) {
309
+ args.push("--version", packageVersion);
310
+ }
311
+ console.log(`Installing package ${packageName} @ ${packageVersion} using "${command} ${args.join(" ")}".`);
312
+ await (0, commons_1.exec)(command, args, { cwd: this.workingDirectory });
313
+ console.log("Package installed.");
314
+ }
315
+ async isNpmVersionAvailable(packageName, packageVersion) {
316
+ var _a, _b, _c;
317
+ commons_1.logger.debug(`Checking if ${packageName}@${packageVersion} is available`);
318
+ const [owner, ...rest] = packageName.split(".");
319
+ const id = rest[rest.length - 1];
320
+ const url = `https://azuresearch-usnc.nuget.org/query?q=owner:${owner}%20id:${id}&prerelease=false&semVerLevel=2.0.0`;
321
+ commons_1.logger.debug(`Fetching package metadata from Nuget: '${url}'`);
322
+ const response = await (0, node_fetch_1.default)(url);
323
+ const json = (await response.json());
324
+ commons_1.logger.debug(`Got response from NuGet for ${packageName} : ${JSON.stringify(json)}`);
325
+ if (!((_a = json === null || json === void 0 ? void 0 : json.data) === null || _a === void 0 ? void 0 : _a.length)) {
326
+ return false; // No package found
327
+ }
328
+ const packageVersions = (_c = (_b = json.data.find((p) => p.id === packageName)) === null || _b === void 0 ? void 0 : _b.versions) !== null && _c !== void 0 ? _c : [];
329
+ if (!packageVersions.length) {
330
+ return false; // No package release matching the id found
331
+ }
332
+ return packageVersions.some((v) => v.version === packageVersion);
333
+ }
334
+ async listProviderPackages() {
335
+ try {
336
+ const stdout = await (0, commons_1.exec)("dotnet", ["list", "package"], {
337
+ cwd: this.workingDirectory,
338
+ });
339
+ commons_1.logger.debug(`Listing pipenv packages using "dotnet list package": ${stdout}`);
340
+ const regex = /^\s*>\s(HashiCorp\.Cdktf\.Providers\.[\w.]+)\s+((?:\d+\.){2}\d+(?:-\S+)?)\s+((?:\d+\.){2}\d+(?:-\S+)?)\s*$/;
341
+ return stdout
342
+ .split("\n")
343
+ .map((line) => {
344
+ // Example output:
345
+ // Project 'MyTerraformStack' has the following package references
346
+ // [net6.0]:
347
+ // Top-level Package Requested Resolved
348
+ // > HashiCorp.Cdktf 0.0.0 0.0.0
349
+ // match[0] = full match
350
+ // match[1] = package name
351
+ // match[2] = requested version
352
+ // match[3] = resolved version
353
+ return regex.exec(line);
354
+ })
355
+ .filter((match) => !!match)
356
+ .map((match) => ({ name: match[1], version: match[3] }));
357
+ }
358
+ catch (e) {
359
+ throw new Error(`Could not determine installed packages using 'dotnet list package': ${e.message}`);
360
+ }
361
+ }
362
+ }
363
+ class JavaPackageManager extends PackageManager {
364
+ async isNpmVersionAvailable(packageName, packageVersion) {
365
+ var _a, _b;
366
+ commons_1.logger.debug(`Checking if ${packageName}@${packageVersion} is available`);
367
+ const parts = packageName.split(".");
368
+ if (parts.length !== 3) {
369
+ throw commons_1.Errors.Internal(`Expected package name to be in format "group.artifact", e.g. "com.hashicorp.cdktf-provider-google", got: ${packageName}`);
370
+ }
371
+ const packageIdentifier = parts.pop();
372
+ const groupId = parts.join(".");
373
+ const url = `https://search.maven.org/solrsearch/select?q=g:${groupId}+AND+a:${packageIdentifier}+AND+v:${packageVersion}&rows=5&wt=json`;
374
+ commons_1.logger.debug(`Trying to find package version by querying Maven Central under '${url}'`);
375
+ const response = await (0, node_fetch_1.default)(url);
376
+ const json = (await response.json());
377
+ commons_1.logger.debug(`Got response from the Maven package search for ${packageName}: ${JSON.stringify(json)}`);
378
+ return ((_b = (_a = json === null || json === void 0 ? void 0 : json.response) === null || _a === void 0 ? void 0 : _a.numFound) !== null && _b !== void 0 ? _b : 0) > 0;
379
+ }
380
+ }
381
+ class MavenPackageManager extends JavaPackageManager {
382
+ async addPackage(packageName, packageVersion = "LATEST") {
383
+ var _a, _b, _c, _d;
384
+ console.log(`Adding ${packageName} @ ${packageVersion} to pom.xml`);
385
+ // Assert pom.xml exists
386
+ const pomPath = path_1.default.join(this.workingDirectory, "pom.xml");
387
+ if (!(0, fs_extra_1.existsSync)(pomPath)) {
388
+ throw commons_1.Errors.Usage("No pom.xml found in current working directory. Please run the command from the root of your project.");
389
+ }
390
+ const pom = await fs.readFile(pomPath, "utf8");
391
+ const pomXml = (await (0, xml_js_1.xml2js)(pom, {}));
392
+ // Mutate dependencies
393
+ const nameParts = packageName.split(".");
394
+ const groupId = nameParts.slice(0, nameParts.length - 1).join(".");
395
+ const artifactId = nameParts[nameParts.length - 1];
396
+ const newDependency = (await (0, xml_js_1.xml2js)(`<dependency>
397
+ <groupId>${groupId}</groupId>
398
+ <artifactId>${artifactId}</artifactId>
399
+ <version>${packageVersion}</version>
400
+ </dependency>`));
401
+ const dependencies = (_c = (_b = (_a = pomXml.elements) === null || _a === void 0 ? void 0 : _a.find((el) => el.name === "project")) === null || _b === void 0 ? void 0 : _b.elements) === null || _c === void 0 ? void 0 : _c.find((el) => el.name === "dependencies");
402
+ if (!dependencies) {
403
+ throw commons_1.Errors.Usage(`Could not find dependencies section in the pom.xml`);
404
+ }
405
+ dependencies.elements = ((dependencies === null || dependencies === void 0 ? void 0 : dependencies.elements) || []).filter((el) => {
406
+ var _a, _b;
407
+ return ((_a = el.elements) === null || _a === void 0 ? void 0 : _a.some((group) => { var _a; return group.name === "groupId" && ((_a = group.elements) === null || _a === void 0 ? void 0 : _a[0].text) !== groupId; })) ||
408
+ ((_b = el.elements) === null || _b === void 0 ? void 0 : _b.some((artifact) => {
409
+ var _a;
410
+ return artifact.name === "artifactId" &&
411
+ ((_a = artifact.elements) === null || _a === void 0 ? void 0 : _a[0].text) !== artifactId;
412
+ }));
413
+ });
414
+ (_d = dependencies === null || dependencies === void 0 ? void 0 : dependencies.elements) === null || _d === void 0 ? void 0 : _d.push(newDependency.elements[0]);
415
+ // Write new pom.xml
416
+ await fs.writeFile(pomPath, (0, xml_js_1.js2xml)(pomXml, { spaces: 2 }));
417
+ // Install
418
+ await (0, commons_1.exec)("mvn", ["install"], { cwd: this.workingDirectory });
419
+ console.log("Package installed.");
420
+ }
421
+ async listProviderPackages() {
422
+ var _a, _b, _c, _d, _e;
423
+ try {
424
+ const pomPath = path_1.default.join(this.workingDirectory, "pom.xml");
425
+ if (!(0, fs_extra_1.existsSync)(pomPath)) {
426
+ throw commons_1.Errors.Usage("No pom.xml found in current working directory. Please run the command from the root of your project.");
427
+ }
428
+ const pom = await fs.readFile(pomPath, "utf8");
429
+ const pomXml = (await (0, xml_js_1.xml2js)(pom, {}));
430
+ const dependencies = (_e = (_d = (_c = (_b = (_a = pomXml.elements) === null || _a === void 0 ? void 0 : _a.find((el) => el.name === "project")) === null || _b === void 0 ? void 0 : _b.elements) === null || _c === void 0 ? void 0 : _c.find((el) => el.name === "dependencies")) === null || _d === void 0 ? void 0 : _d.elements) !== null && _e !== void 0 ? _e : [];
431
+ return dependencies
432
+ .map((dep) => {
433
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j;
434
+ return ({
435
+ name: `${(_c = (_b = (_a = dep.elements) === null || _a === void 0 ? void 0 : _a.find((el) => el.name === "groupId")) === null || _b === void 0 ? void 0 : _b.elements) === null || _c === void 0 ? void 0 : _c[0].text}.${(_f = (_e = (_d = dep.elements) === null || _d === void 0 ? void 0 : _d.find((el) => el.name === "artifactId")) === null || _e === void 0 ? void 0 : _e.elements) === null || _f === void 0 ? void 0 : _f[0].text}`,
436
+ version: (_j = (_h = (_g = dep.elements) === null || _g === void 0 ? void 0 : _g.find((el) => el.name === "version")) === null || _h === void 0 ? void 0 : _h.elements) === null || _j === void 0 ? void 0 : _j[0].text,
437
+ });
438
+ })
439
+ .filter((dep) => dep.name.startsWith("com.hashicorp.cdktf-provider-"));
440
+ }
441
+ catch (e) {
442
+ throw new Error(`Could not determine installed packages reading the pom.xml: ${e.message}`);
443
+ }
444
+ }
445
+ }
446
+ class GradlePackageManager extends JavaPackageManager {
447
+ static isGradleProject(workingDirectory) {
448
+ return (0, commons_1.isGradleProject)(workingDirectory);
449
+ }
450
+ async addPackage(packageFQN, packageVersion = "latest.release") {
451
+ const buildGradlePath = path_1.default.join(this.workingDirectory, "build.gradle");
452
+ const buildGradle = await fs.readFile(buildGradlePath, "utf8");
453
+ const buildGradleLines = buildGradle.split(/\r?\n/);
454
+ const dependenciesRegex = /dependencies\s+\{/i;
455
+ const dependencyBlockStart = buildGradleLines.findIndex((line) => dependenciesRegex.test(line));
456
+ if (dependencyBlockStart === -1) {
457
+ throw commons_1.Errors.Usage("Could not find dependencies section in the build.gradle");
458
+ }
459
+ const packageSegments = packageFQN.split(".");
460
+ const packageName = packageSegments.pop();
461
+ const groupName = packageSegments.join(".");
462
+ const dependencySpecifier = `${groupName}:${packageName}`;
463
+ const dependencyAndVersionSpecifier = `${dependencySpecifier}:${packageVersion}`;
464
+ const existingDependency = buildGradleLines.findIndex((line) => line.includes(dependencySpecifier));
465
+ if (existingDependency !== -1) {
466
+ buildGradleLines.splice(existingDependency, 1);
467
+ }
468
+ const newPackageDependency = `\timplementation '${dependencyAndVersionSpecifier}'`;
469
+ buildGradleLines.splice(dependencyBlockStart + 1, 0, newPackageDependency);
470
+ await fs.writeFile(buildGradlePath, buildGradleLines.join("\n"));
471
+ }
472
+ async listProviderPackages() {
473
+ const dependencies = await (0, commons_1.getGradleDependencies)();
474
+ if (!dependencies) {
475
+ throw commons_1.Errors.Usage("Could not find any dependencies");
476
+ }
477
+ const dependencyList = dependencies
478
+ .map((line) => (0, commons_1.getDependencyInformationFromLine)(line))
479
+ .filter((dep) => {
480
+ if (!dep) {
481
+ return false;
482
+ }
483
+ return dep.name.includes("cdktf-provider-");
484
+ })
485
+ .map((dep) => ({
486
+ name: `com.hashicorp.${dep.name}`,
487
+ version: dep.version,
488
+ }));
489
+ return dependencyList;
490
+ }
491
+ }
492
+ class GoPackageManager extends PackageManager {
493
+ async addPackage(packageName, packageVersion) {
494
+ console.log(`Adding package ${packageName} @ ${packageVersion}`);
495
+ const majorVersion = packageVersion
496
+ ? semver.major(packageVersion)
497
+ : undefined;
498
+ let versionPackageSuffix = "";
499
+ if (typeof majorVersion === "number" && majorVersion > 1) {
500
+ versionPackageSuffix = `/v${majorVersion}`;
501
+ }
502
+ commons_1.logger.debug(`Running 'go get ${packageName}${versionPackageSuffix}@v${packageVersion}'`);
503
+ // Install
504
+ await (0, commons_1.exec)("go", ["get", `${packageName}${versionPackageSuffix}@v${packageVersion}`], {
505
+ cwd: this.workingDirectory,
506
+ });
507
+ console.log("Package installed.");
508
+ }
509
+ async isNpmVersionAvailable(packageName, packageVersion) {
510
+ commons_1.logger.debug(`Checking if ${packageName}@${packageVersion} is available`);
511
+ // e.g. github.com/cdktf/cdktf-provider-google-go/google
512
+ const parts = packageName.split("/");
513
+ if (parts.length !== 4) {
514
+ throw commons_1.Errors.Internal(`Expecting Go package name to be in the format of github.com/<org>/<repo>/<package>, got ${packageName}`);
515
+ }
516
+ const org = parts[1];
517
+ const repo = parts[2];
518
+ const packagePath = parts[3];
519
+ const url = `https://api.github.com/repos/${org}/${repo}/git/ref/tags/${packagePath}/v${packageVersion}`;
520
+ commons_1.logger.debug(`Fetching tags for ${org}/${repo} from '${url}'`);
521
+ const response = await (0, node_fetch_1.default)(url, {
522
+ headers: {
523
+ Accept: "application/vnd.github+json",
524
+ "User-Agent": "OpenConstructs/cdktn-cli",
525
+ ...(GITHUB_API_TOKEN_CDKTF
526
+ ? { Authorization: `Bearer ${GITHUB_API_TOKEN_CDKTF}` }
527
+ : {}),
528
+ },
529
+ });
530
+ const json = (await response.json());
531
+ commons_1.logger.debug(`Got response from GitHubs repository tag endpoint for ${packageName}: ${JSON.stringify(json)}`);
532
+ if (json && json.ref) {
533
+ return true;
534
+ }
535
+ commons_1.logger.info(`Could not find the tag ${packagePath}/v${packageVersion} in the repository ${org}/${repo}: ${JSON.stringify(json)}}`);
536
+ return false;
537
+ }
538
+ async listProviderPackages() {
539
+ try {
540
+ const goSumPath = path_1.default.join(this.workingDirectory, "go.sum");
541
+ if (!(0, fs_extra_1.existsSync)(goSumPath)) {
542
+ throw commons_1.Errors.Usage("No go.sum found in current working directory. Please run the command from the root of your project.");
543
+ }
544
+ const goSum = await fs.readFile(goSumPath, "utf8");
545
+ const dedupedProviderNames = new Set();
546
+ return goSum
547
+ .split("\n")
548
+ .filter((line) => line.startsWith("github.com/hashicorp/cdktf-provider") ||
549
+ line.startsWith("github.com/cdktf/cdktf-provider"))
550
+ .map((line) => {
551
+ const parts = line.split(" ");
552
+ if (parts.length !== 3) {
553
+ throw commons_1.Errors.Internal(`Expected line in go.sum to be in the format of '<package> <version> <checksum>', got: ${line}`);
554
+ }
555
+ // part[0] could be github.com/aws/constructs-go/constructs/v10
556
+ const name = parts[0].split("/").slice(0, 4).join("/");
557
+ const version = parts[1].split("/")[0];
558
+ if (dedupedProviderNames.has(name)) {
559
+ return { name: "", version: "" };
560
+ }
561
+ dedupedProviderNames.add(name);
562
+ return {
563
+ name,
564
+ version,
565
+ };
566
+ })
567
+ .filter((providerInfo) => !!providerInfo.name && !!providerInfo.version);
568
+ }
569
+ catch (e) {
570
+ throw new Error(`Could not determine installed packages reading the go.sum: ${e.message}`);
571
+ }
572
+ }
573
+ }
574
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGFja2FnZS1tYW5hZ2VyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsicGFja2FnZS1tYW5hZ2VyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUEsK0JBQStCO0FBQy9CLG1DQUFtQztBQUNuQyw0Q0FRd0I7QUFDeEIsdUNBQXNDO0FBQ3RDLGdEQUF3QjtBQUN4QixtQ0FBaUQ7QUFDakQsNkNBQStCO0FBQy9CLCtDQUFpQztBQUNqQyw0REFBK0I7QUFDL0IsdUNBQXlCO0FBRXpCLDZGQUE2RjtBQUM3RixzREFBc0Q7QUFDdEQsTUFBTSxFQUFFLHNCQUFzQixFQUFFLEdBQUcsT0FBTyxDQUFDLEdBQUcsQ0FBQztBQUUvQyxJQUFJO0FBQ0osd0JBQXdCO0FBQ3hCLDBCQUEwQjtBQUMxQixrQkFBa0I7QUFDbEIsMElBQTBJO0FBQzFJLE9BQU87QUFDUCxzQkFBc0I7QUFDdEIsa0NBQWtDO0FBQ2xDLDZCQUE2QjtBQUM3QixxR0FBcUc7QUFDckcsU0FBUztBQUNULE1BQU0sYUFBYSxHQUFHLENBQUM7S0FDcEIsTUFBTSxDQUFDO0lBQ04sWUFBWSxFQUFFLENBQUMsQ0FBQyxNQUFNLENBQ3BCLENBQUM7U0FDRSxNQUFNLENBQUM7UUFDTixPQUFPLEVBQUUsQ0FBQyxDQUFDLE1BQU0sRUFBRTtLQUNwQixDQUFDO1NBQ0QsU0FBUyxFQUFFLENBQ2Y7Q0FDRixDQUFDO0tBQ0QsV0FBVyxFQUFFO0tBQ2IsU0FBUyxFQUFFLENBQUM7QUFFZixJQUFJO0FBQ0osb0JBQW9CO0FBQ3BCLGNBQWM7QUFDZCxzQkFBc0I7QUFDdEIsaUJBQWlCO0FBQ2pCLFVBQVU7QUFDVixtREFBbUQ7QUFDbkQsMEJBQTBCO0FBQzFCLHdCQUF3QjtBQUN4QiwyQkFBMkI7QUFDM0IscUJBQXFCO0FBQ3JCLFVBQVU7QUFDVixRQUFRO0FBQ1IsTUFBTTtBQUNOLElBQUk7QUFDSixNQUFNLGNBQWMsR0FBRyxDQUFDO0tBQ3JCLE1BQU0sQ0FBQztJQUNOLElBQUksRUFBRSxDQUFDO1NBQ0osTUFBTSxDQUFDO1FBQ04sS0FBSyxFQUFFLENBQUMsQ0FBQyxLQUFLLENBQ1osQ0FBQzthQUNFLE1BQU0sQ0FBQztZQUNOLElBQUksRUFBRSxDQUFDLENBQUMsTUFBTSxFQUFFO1NBQ2pCLENBQUM7YUFDRCxTQUFTLEVBQUUsQ0FDZjtLQUNGLENBQUM7U0FDRCxTQUFTLEVBQUU7Q0FDZixDQUFDO0tBQ0QsV0FBVyxFQUFFO0tBQ2IsU0FBUyxFQUFFLENBQUM7QUFFZixJQUFJO0FBQ0osTUFBTTtBQUNOLHlCQUF5QjtBQUN6Qix5QkFBeUI7QUFDekIsT0FBTztBQUNQLE1BQU07QUFDTixNQUFNLGdCQUFnQixHQUFHLENBQUMsQ0FBQyxLQUFLLENBQzlCLENBQUMsQ0FBQyxNQUFNLENBQUMsRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDLE1BQU0sRUFBRSxFQUFFLE9BQU8sRUFBRSxDQUFDLENBQUMsTUFBTSxFQUFFLEVBQUUsQ0FBQyxDQUFDLFNBQVMsRUFBRSxDQUNoRSxDQUFDO0FBRUY7Ozs7R0FJRztBQUNILE1BQXNCLGNBQWM7SUFDbEMsWUFBK0IsZ0JBQXdCO1FBQXhCLHFCQUFnQixHQUFoQixnQkFBZ0IsQ0FBUTtJQUFHLENBQUM7SUFFcEQsTUFBTSxDQUFDLFdBQVcsQ0FDdkIsUUFBa0IsRUFDbEIsZ0JBQXdCO1FBRXhCLFFBQVEsUUFBUSxFQUFFLENBQUM7WUFDakIsS0FBSyxrQkFBUSxDQUFDLEVBQUU7Z0JBQ2QsT0FBTyxJQUFJLGdCQUFnQixDQUFDLGdCQUFnQixDQUFDLENBQUM7WUFDaEQsS0FBSyxrQkFBUSxDQUFDLFVBQVU7Z0JBQ3RCLE9BQU8sSUFBSSxrQkFBa0IsQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO1lBQ2xELEtBQUssa0JBQVEsQ0FBQyxNQUFNO2dCQUNsQixPQUFPLElBQUksb0JBQW9CLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztZQUNwRCxLQUFLLGtCQUFRLENBQUMsTUFBTTtnQkFDbEIsT0FBTyxJQUFJLG1CQUFtQixDQUFDLGdCQUFnQixDQUFDLENBQUM7WUFDbkQsS0FBSyxrQkFBUSxDQUFDLElBQUk7Z0JBQ2hCLElBQUksb0JBQW9CLENBQUMsZUFBZSxDQUFDLGdCQUFnQixDQUFDLEVBQUUsQ0FBQztvQkFDM0QsT0FBTyxJQUFJLG9CQUFvQixDQUFDLGdCQUFnQixDQUFDLENBQUM7Z0JBQ3BELENBQUM7Z0JBQ0QsT0FBTyxJQUFJLG1CQUFtQixDQUFDLGdCQUFnQixDQUFDLENBQUM7WUFDbkQ7Z0JBQ0UsTUFBTSxJQUFJLEtBQUssQ0FBQyxxQkFBcUIsUUFBUSxFQUFFLENBQUMsQ0FBQztRQUNyRCxDQUFDO0lBQ0gsQ0FBQztDQWlCRjtBQXpDRCx3Q0F5Q0M7QUFFRCxNQUFNLGtCQUFtQixTQUFRLGNBQWM7SUFDckMsZUFBZTtRQUNyQixPQUFPLElBQUEscUJBQVUsRUFBQyxjQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxnQkFBZ0IsRUFBRSxXQUFXLENBQUMsQ0FBQyxDQUFDO0lBQ25FLENBQUM7SUFFTSxLQUFLLENBQUMsVUFBVSxDQUNyQixXQUFtQixFQUNuQixjQUF1QixFQUN2QixNQUFnQjtRQUVoQixPQUFPLENBQUMsR0FBRyxDQUFDLGtCQUFrQixXQUFXLE1BQU0sY0FBYyxFQUFFLENBQUMsQ0FBQztRQUVqRSwyQ0FBMkM7UUFDM0MsSUFBSSxPQUFPLEdBQUcsS0FBSyxDQUFDO1FBQ3BCLElBQUksSUFBSSxHQUFHLENBQUMsU0FBUyxDQUFDLENBQUM7UUFFdkIsSUFBSSxJQUFJLENBQUMsZUFBZSxFQUFFLEVBQUUsQ0FBQztZQUMzQixPQUFPLEdBQUcsTUFBTSxDQUFDO1lBQ2pCLElBQUksR0FBRyxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQ2pCLENBQUM7UUFDRCxJQUFJLENBQUMsSUFBSSxDQUNQLGNBQWMsQ0FBQyxDQUFDLENBQUMsV0FBVyxHQUFHLEdBQUcsR0FBRyxjQUFjLENBQUMsQ0FBQyxDQUFDLFdBQVcsQ0FDbEUsQ0FBQztRQUVGLElBQUksTUFBTSxFQUFFLENBQUM7WUFDWCxJQUFJLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDO1lBQ3RCLElBQUksQ0FBQyxJQUFJLENBQUMsZUFBZSxDQUFDLENBQUM7UUFDN0IsQ0FBQztRQUVELHdCQUF3QjtRQUN4QiwrRUFBK0U7UUFDL0UscUVBQXFFO1FBQ3JFLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7UUFFaEIsZ0JBQU0sQ0FBQyxJQUFJLENBQ1Qsc0JBQXNCLFdBQVcsTUFBTSxjQUFjLFVBQVUsT0FBTyxHQUFHLENBQzFFLENBQUM7UUFFRixNQUFNLElBQUEsY0FBSSxFQUFDLE9BQU8sRUFBRSxJQUFJLEVBQUUsRUFBRSxHQUFHLEVBQUUsSUFBSSxDQUFDLGdCQUFnQixFQUFFLENBQUMsQ0FBQztRQUUxRCxnQkFBTSxDQUFDLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxDQUFDO0lBQ3BDLENBQUM7SUFFTSxLQUFLLENBQUMscUJBQXFCLENBQ2hDLFlBQW9CLEVBQ3BCLGVBQXVCO1FBRXZCLHdFQUF3RTtRQUN4RSxPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7SUFFTyxLQUFLLENBQUMsZ0JBQWdCOztRQUc1QixJQUFJLENBQUM7WUFDSCxNQUFNLE1BQU0sR0FBRyxNQUFNLElBQUEsY0FBSSxFQUFDLE1BQU0sRUFBRSxDQUFDLE1BQU0sRUFBRSxRQUFRLENBQUMsRUFBRTtnQkFDcEQsR0FBRyxFQUFFLElBQUksQ0FBQyxnQkFBZ0I7YUFDM0IsQ0FBQyxDQUFDO1lBRUgsZ0JBQU0sQ0FBQyxLQUFLLENBQUMsbURBQW1ELE1BQU0sRUFBRSxDQUFDLENBQUM7WUFFMUUsTUFBTSxJQUFJLEdBQUcsY0FBYyxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUM7WUFFdEQsT0FBTyxDQUFDLENBQUEsTUFBQSxJQUFJLGFBQUosSUFBSSx1QkFBSixJQUFJLENBQUUsSUFBSSwwQ0FBRSxLQUFLLEtBQUksRUFBRSxDQUFDO2lCQUM3QixNQUFNLENBQUMsQ0FBQyxHQUFRLEVBQUUsRUFBRSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLGtCQUFrQixDQUFDLENBQUM7aUJBQzdELEdBQUcsQ0FBQyxDQUFDLEdBQVEsRUFBRSxFQUFFLENBQUMsQ0FBQztnQkFDbEIsSUFBSSxFQUFFLElBQUksR0FBRyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUU7Z0JBQ2xDLE9BQU8sRUFBRSxHQUFHLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7YUFDaEMsQ0FBQyxDQUFDLENBQUM7UUFDUixDQUFDO1FBQUMsT0FBTyxDQUFNLEVBQUUsQ0FBQztZQUNoQixNQUFNLElBQUksS0FBSyxDQUNiLG9FQUFvRSxDQUFDLENBQUMsT0FBTyxFQUFFLENBQ2hGLENBQUM7UUFDSixDQUFDO0lBQ0gsQ0FBQztJQUVPLEtBQUssQ0FBQyxlQUFlO1FBRzNCLElBQUksQ0FBQztZQUNILE1BQU0sTUFBTSxHQUFHLE1BQU0sSUFBQSxjQUFJLEVBQUMsS0FBSyxFQUFFLENBQUMsTUFBTSxFQUFFLFFBQVEsQ0FBQyxFQUFFO2dCQUNuRCxHQUFHLEVBQUUsSUFBSSxDQUFDLGdCQUFnQjthQUMzQixDQUFDLENBQUM7WUFFSCxnQkFBTSxDQUFDLEtBQUssQ0FBQyxpREFBaUQsTUFBTSxFQUFFLENBQUMsQ0FBQztZQUN4RSxNQUFNLElBQUksR0FBRyxhQUFhLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQztZQUVyRCxPQUFPLE1BQU0sQ0FBQyxPQUFPLENBQUMsQ0FBQSxJQUFJLGFBQUosSUFBSSx1QkFBSixJQUFJLENBQUUsWUFBWSxLQUFJLEVBQUUsQ0FBQztpQkFDNUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsRUFBRSxFQUFFLENBQUMsT0FBTyxDQUFDLFVBQVUsQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDO2lCQUM3RCxHQUFHLENBQUMsQ0FBQyxDQUFDLElBQUksRUFBRSxHQUFHLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxFQUFFLElBQUksRUFBRSxPQUFPLEVBQUUsR0FBRyxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQUMsQ0FBQztRQUM1RCxDQUFDO1FBQUMsT0FBTyxDQUFNLEVBQUUsQ0FBQztZQUNoQixNQUFNLElBQUksS0FBSyxDQUNiLG1FQUFtRSxDQUFDLENBQUMsT0FBTyxFQUFFLENBQy9FLENBQUM7UUFDSixDQUFDO0lBQ0gsQ0FBQztJQUVNLEtBQUssQ0FBQyxvQkFBb0I7UUFHL0IsT0FBTyxJQUFJLENBQUMsZUFBZSxFQUFFO1lBQzNCLENBQUMsQ0FBQyxJQUFJLENBQUMsZ0JBQWdCLEVBQUU7WUFDekIsQ0FBQyxDQUFDLElBQUksQ0FBQyxlQUFlLEVBQUUsQ0FBQztJQUM3QixDQUFDO0NBQ0Y7QUFFRCxNQUFNLG9CQUFxQixTQUFRLGNBQWM7SUFDL0MsSUFBWSxVQUFVO1FBQ3BCLElBQUksQ0FBQztZQUNILE9BQU8sSUFBSSxDQUFDLEtBQUssQ0FDZixFQUFFLENBQUMsWUFBWSxDQUNiLGNBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLGdCQUFnQixFQUFFLFlBQVksQ0FBQyxFQUNqRCxNQUFNLENBQ1AsQ0FDRixDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQ1gsQ0FBQztRQUFDLE9BQU8sQ0FBTSxFQUFFLENBQUM7WUFDaEIsTUFBTSxnQkFBTSxDQUFDLEtBQUssQ0FDaEIsK0NBQStDLElBQUksQ0FBQyxnQkFBZ0IsRUFBRSxFQUN0RSxDQUFDLENBQ0YsQ0FBQztRQUNKLENBQUM7SUFDSCxDQUFDO0lBRU0sS0FBSyxDQUFDLFVBQVUsQ0FDckIsV0FBbUIsRUFDbkIsY0FBdUI7UUFFdkIsTUFBTSxTQUFTLEdBQUcsSUFBSSxDQUFDLFVBQVUsQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDLENBQUM7UUFFckQsSUFBSSxTQUFTLEVBQUUsQ0FBQztZQUNkLE9BQU8sQ0FBQyxHQUFHLENBQ1Qsc0JBQXNCLFdBQVcsTUFBTSxjQUFjLGdCQUFnQixDQUN0RSxDQUFDO1lBRUYsTUFBTSxJQUFBLGNBQUksRUFBQyxRQUFRLEVBQUUsQ0FBQyxTQUFTLEVBQUUsR0FBRyxXQUFXLEtBQUssY0FBYyxFQUFFLENBQUMsRUFBRTtnQkFDckUsR0FBRyxFQUFFLElBQUksQ0FBQyxnQkFBZ0I7Z0JBQzFCLEdBQUcsRUFBRTtvQkFDSCxHQUFHLE9BQU8sQ0FBQyxHQUFHO29CQUNkLFlBQVksRUFBRSxHQUFHO2lCQUNsQjtnQkFDRCxLQUFLLEVBQUUsQ0FBQyxTQUFTLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQzthQUN6QixDQUFDLENBQUM7WUFFSCxPQUFPLENBQUMsR0FBRyxDQUFDLG9CQUFvQixDQUFDLENBQUM7UUFDcEMsQ0FBQzthQUFNLENBQUM7WUFDTixPQUFPLENBQUMsR0FBRyxDQUNULHNCQUFzQixXQUFXLE1BQU0sY0FBYyxhQUFhLENBQ25FLENBQUM7WUFFRixNQUFNLG9CQUFvQixHQUFHLGNBQUksQ0FBQyxJQUFJLENBQ3BDLElBQUksQ0FBQyxnQkFBZ0IsRUFDckIsa0JBQWtCLENBQ25CLENBQUM7WUFDRixJQUFJLENBQUMsRUFBRSxDQUFDLFVBQVUsQ0FBQyxvQkFBb0IsQ0FBQyxFQUFFLENBQUM7Z0JBQ3pDLE1BQU0sZ0JBQU0sQ0FBQyxLQUFLLENBQ2hCLHNDQUFzQyxJQUFJLENBQUMsZ0JBQWdCLEVBQUUsQ0FDOUQsQ0FBQztZQUNKLENBQUM7WUFFRCxNQUFNLFlBQVksR0FBRyxNQUFNLEVBQUUsQ0FBQyxRQUFRLENBQUMsb0JBQW9CLEVBQUUsTUFBTSxDQUFDLENBQUM7WUFDckUsTUFBTSxlQUFlLEdBQUcsWUFBWTtpQkFDakMsS0FBSyxDQUFDLElBQUksQ0FBQztpQkFDWCxJQUFJLENBQUMsQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQztZQUU5QyxnQkFBTSxDQUFDLEtBQUssQ0FDVix1REFBdUQsV0FBVyxLQUFLLGVBQWUsRUFBRSxDQUN6RixDQUFDO1lBRUYsSUFBSSxlQUFlLEVBQUUsQ0FBQztnQkFDcEIsSUFBSSxjQUFjLENBQUMsQ0FBQyxDQUFDLGVBQWUsQ0FBQyxRQUFRLENBQUMsY0FBYyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksRUFBRSxDQUFDO29CQUNyRSxnQkFBTSxDQUFDLElBQUksQ0FDVCxXQUFXLFdBQVcsNENBQTRDLENBQ25FLENBQUM7b0JBQ0YsT0FBTztnQkFDVCxDQUFDO3FCQUFNLENBQUM7b0JBQ04sZ0JBQU0sQ0FBQyxLQUFLLENBQ1YsNERBQTRELENBQzdELENBQUM7Z0JBQ0osQ0FBQztZQUNILENBQUM7WUFFRCxNQUFNLGVBQWUsR0FDbkIsWUFBWTtpQkFDVCxLQUFLLENBQUMsSUFBSSxDQUFDO2lCQUNYLE1BQU0sQ0FBQyxDQUFDLElBQUksRUFBRSxFQUFFLENBQUMsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLFdBQVcsQ0FBQyxDQUFDO2lCQUMvQyxJQUFJLENBQUMsSUFBSSxDQUFDO2dCQUNiLEtBQUssV0FBVyxHQUFHLGNBQWMsQ0FBQyxDQUFDLENBQUMsS0FBSyxjQUFjLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUM7WUFDbkUsTUFBTSxFQUFFLENBQUMsU0FBUyxDQUFDLG9CQUFvQixFQUFFLGVBQWUsRUFBRSxNQUFNLENBQUMsQ0FBQztZQUVsRSxNQUFNLElBQUEsY0FBSSxFQUFDLEtBQUssRUFBRSxDQUFDLFNBQVMsRUFBRSxJQUFJLEVBQUUsa0JBQWtCLENBQUMsRUFBRTtnQkFDdkQsR0FBRyxFQUFFLElBQUksQ0FBQyxnQkFBZ0I7Z0JBQzFCLEtBQUssRUFBRSxDQUFDLFNBQVMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDO2FBQ3pCLENBQUMsQ0FBQztZQUVILE9BQU8sQ0FBQyxHQUFHLENBQUMsb0JBQW9CLENBQUMsQ0FBQztRQUNwQyxDQUFDO0lBQ0gsQ0FBQztJQUVNLEtBQUssQ0FBQyxxQkFBcUIsQ0FDaEMsV0FBbUIsRUFDbkIsY0FBc0I7UUFFdEIsZ0JBQU0sQ0FBQyxLQUFLLENBQ1YsZUFBZSxXQUFXLElBQUksY0FBYywwQkFBMEIsQ0FDdkUsQ0FBQztRQUNGLE1BQU0sR0FBRyxHQUFHLHlCQUF5QixXQUFXLElBQUksY0FBYyxPQUFPLENBQUM7UUFDMUUsZ0JBQU0sQ0FBQyxLQUFLLENBQUMsb0NBQW9DLFdBQVcsU0FBUyxHQUFHLEVBQUUsQ0FBQyxDQUFDO1FBRTVFLE1BQU0sUUFBUSxHQUFHLE1BQU0sSUFBQSxvQkFBSyxFQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQ2xDLE1BQU0sSUFBSSxHQUFHLENBQUMsTUFBTSxRQUFRLENBQUMsSUFBSSxFQUFFLENBQVEsQ0FBQztRQUM1QyxnQkFBTSxDQUFDLEtBQUssQ0FDViw4QkFBOEIsV0FBVyxJQUFJLGNBQWMsS0FBSyxJQUFJLENBQUMsU0FBUyxDQUM1RSxJQUFJLENBQ0wsRUFBRSxDQUNKLENBQUM7UUFFRixJQUFJLElBQUksQ0FBQyxJQUFJLEVBQUUsQ0FBQztZQUNkLHFDQUFxQztZQUNyQyxPQUFPLElBQUksQ0FBQztRQUNkLENBQUM7YUFBTSxDQUFDO1lBQ04sZ0JBQU0sQ0FBQyxLQUFLLENBQ1YseUNBQXlDLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FDaEUsQ0FBQztZQUNGLE9BQU8sS0FBSyxDQUFDO1FBQ2YsQ0FBQztJQUNILENBQUM7SUFFTSxLQUFLLENBQUMsa0JBQWtCO1FBRzdCLElBQUksQ0FBQztZQUNILE1BQU0sTUFBTSxHQUFHLE1BQU0sSUFBQSxjQUFJLEVBQ3ZCLFFBQVEsRUFDUixDQUFDLEtBQUssRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFLGVBQWUsQ0FBQyxFQUN2QztnQkFDRSxHQUFHLEVBQUUsSUFBSSxDQUFDLGdCQUFnQjthQUMzQixDQUNGLENBQUM7WUFDRixnQkFBTSxDQUFDLEtBQUssQ0FDVixzRUFBc0UsTUFBTSxFQUFFLENBQy9FLENBQUM7WUFFRixNQUFNLElBQUksR0FBRyxnQkFBZ0IsQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDO1lBQ3hELE9BQU8sSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLElBQUksRUFBRSxFQUFFLENBQzFCLElBQUksQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLHNCQUFzQixDQUFDLENBQzdDLENBQUM7UUFDSixDQUFDO1FBQUMsT0FBTyxDQUFNLEVBQUUsQ0FBQztZQUNoQixNQUFNLElBQUksS0FBSyxDQUNiLHFGQUFxRixDQUFDLENBQUMsT0FBTyxFQUFFLENBQ2pHLENBQUM7UUFDSixDQUFDO0lBQ0gsQ0FBQztJQUVNLEtBQUssQ0FBQyxlQUFlO1FBQzFCLElBQUksQ0FBQztZQUNILE1BQU0sTUFBTSxHQUFHLE1BQU0sSUFBQSxjQUFJLEVBQUMsS0FBSyxFQUFFLENBQUMsTUFBTSxFQUFFLGVBQWUsQ0FBQyxFQUFFO2dCQUMxRCxHQUFHLEVBQUUsSUFBSSxDQUFDLGdCQUFnQjthQUMzQixDQUFDLENBQUM7WUFDSCxnQkFBTSxDQUFDLEtBQUssQ0FDViwyREFBMkQsTUFBTSxFQUFFLENBQ3BFLENBQUM7WUFFRixNQUFNLElBQUksR0FBRyxnQkFBZ0IsQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDO1lBQ3hELE9BQU8sSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLElBQUksRUFBRSxFQUFFLENBQzFCLElBQUksQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLHNCQUFzQixDQUFDLENBQzdDLENBQUM7UUFDSixDQUFDO1FBQUMsT0FBTyxDQUFNLEVBQUUsQ0FBQztZQUNoQixNQUFNLElBQUksS0FBSyxDQUNiLDBFQUEwRSxDQUFDLENBQUMsT0FBTyxFQUFFLENBQ3RGLENBQUM7UUFDSixDQUFDO0lBQ0gsQ0FBQztJQUVNLEtBQUssQ0FBQyxvQkFBb0I7UUFHL0IsT0FBTyxJQUFJLENBQUMsVUFBVSxDQUFDLFFBQVEsQ0FBQyxRQUFRLENBQUM7WUFDdkMsQ0FBQyxDQUFDLElBQUksQ0FBQyxrQkFBa0IsRUFBRTtZQUMzQixDQUFDLENBQUMsSUFBSSxDQUFDLGVBQWUsRUFBRSxDQUFDO0lBQzdCLENBQUM7Q0FDRjtBQUVELE1BQU0sbUJBQW9CLFNBQVEsY0FBYztJQUN2QyxLQUFLLENBQUMsVUFBVSxDQUNyQixXQUFtQixFQUNuQixjQUF1QjtRQUV2QixNQUFNLE9BQU8sR0FBRyxRQUFRLENBQUM7UUFDekIsTUFBTSxJQUFJLEdBQUcsQ0FBQyxLQUFLLEVBQUUsU0FBUyxFQUFFLFdBQVcsQ0FBQyxDQUFDO1FBQzdDLElBQUksY0FBYyxFQUFFLENBQUM7WUFDbkIsSUFBSSxDQUFDLElBQUksQ0FBQyxXQUFXLEVBQUUsY0FBYyxDQUFDLENBQUM7UUFDekMsQ0FBQztRQUNELE9BQU8sQ0FBQyxHQUFHLENBQ1Qsc0JBQXNCLFdBQVcsTUFBTSxjQUFjLFdBQVcsT0FBTyxJQUFJLElBQUksQ0FBQyxJQUFJLENBQ2xGLEdBQUcsQ0FDSixJQUFJLENBQ04sQ0FBQztRQUVGLE1BQU0sSUFBQSxjQUFJLEVBQUMsT0FBTyxFQUFFLElBQUksRUFBRSxFQUFFLEdBQUcsRUFBRSxJQUFJLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQyxDQUFDO1FBRTFELE9BQU8sQ0FBQyxHQUFHLENBQUMsb0JBQW9CLENBQUMsQ0FBQztJQUNwQyxDQUFDO0lBRU0sS0FBSyxDQUFDLHFCQUFxQixDQUNoQyxXQUFtQixFQUNuQixjQUFzQjs7UUFFdEIsZ0JBQU0sQ0FBQyxLQUFLLENBQUMsZUFBZSxXQUFXLElBQUksY0FBYyxlQUFlLENBQUMsQ0FBQztRQUUxRSxNQUFNLENBQUMsS0FBSyxFQUFFLEdBQUcsSUFBSSxDQUFDLEdBQUcsV0FBVyxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUNoRCxNQUFNLEVBQUUsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUMsQ0FBQztRQUNqQyxNQUFNLEdBQUcsR0FBRyxvREFBb0QsS0FBSyxTQUFTLEVBQUUscUNBQXFDLENBQUM7UUFDdEgsZ0JBQU0sQ0FBQyxLQUFLLENBQUMsMENBQTBDLEdBQUcsR0FBRyxDQUFDLENBQUM7UUFFL0QsTUFBTSxRQUFRLEdBQUcsTUFBTSxJQUFBLG9CQUFLLEVBQUMsR0FBRyxDQUFDLENBQUM7UUFDbEMsTUFBTSxJQUFJLEdBQUcsQ0FBQyxNQUFNLFFBQVEsQ0FBQyxJQUFJLEVBQUUsQ0FFbEMsQ0FBQztRQUNGLGdCQUFNLENBQUMsS0FBSyxDQUNWLCtCQUErQixXQUFXLE1BQU0sSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUN2RSxDQUFDO1FBRUYsSUFBSSxDQUFDLENBQUEsTUFBQSxJQUFJLGFBQUosSUFBSSx1QkFBSixJQUFJLENBQUUsSUFBSSwwQ0FBRSxNQUFNLENBQUEsRUFBRSxDQUFDO1lBQ3hCLE9BQU8sS0FBSyxDQUFDLENBQUMsbUJBQW1CO1FBQ25DLENBQUM7UUFFRCxNQUFNLGVBQWUsR0FDbkIsTUFBQSxNQUFBLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxLQUFLLFdBQVcsQ0FBQywwQ0FBRSxRQUFRLG1DQUFJLEVBQUUsQ0FBQztRQUU5RCxJQUFJLENBQUMsZUFBZSxDQUFDLE1BQU0sRUFBRSxDQUFDO1lBQzVCLE9BQU8sS0FBSyxDQUFDLENBQUMsMkNBQTJDO1FBQzNELENBQUM7UUFFRCxPQUFPLGVBQWUsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxPQUFPLEtBQUssY0FBYyxDQUFDLENBQUM7SUFDbkUsQ0FBQztJQUVNLEtBQUssQ0FBQyxvQkFBb0I7UUFHL0IsSUFBSSxDQUFDO1lBQ0gsTUFBTSxNQUFNLEdBQUcsTUFBTSxJQUFBLGNBQUksRUFBQyxRQUFRLEVBQUUsQ0FBQyxNQUFNLEVBQUUsU0FBUyxDQUFDLEVBQUU7Z0JBQ3ZELEdBQUcsRUFBRSxJQUFJLENBQUMsZ0JBQWdCO2FBQzNCLENBQUMsQ0FBQztZQUNILGdCQUFNLENBQUMsS0FBSyxDQUNWLHdEQUF3RCxNQUFNLEVBQUUsQ0FDakUsQ0FBQztZQUVGLE1BQU0sS0FBSyxHQUNULDRHQUE0RyxDQUFDO1lBRS9HLE9BQU8sTUFBTTtpQkFDVixLQUFLLENBQUMsSUFBSSxDQUFDO2lCQUNYLEdBQUcsQ0FBQyxDQUFDLElBQVksRUFBRSxFQUFFO2dCQUNwQixrQkFBa0I7Z0JBQ2xCLGtFQUFrRTtnQkFDbEUsYUFBYTtnQkFDYiwrQ0FBK0M7Z0JBQy9DLDRDQUE0QztnQkFDNUMsd0JBQXdCO2dCQUN4QiwwQkFBMEI7Z0JBQzFCLCtCQUErQjtnQkFDL0IsOEJBQThCO2dCQUM5QixPQUFPLEtBQUssQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDMUIsQ0FBQyxDQUFDO2lCQUNELE1BQU0sQ0FBQyxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQztpQkFDMUIsR0FBRyxDQUFDLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FBQyxDQUFDLEVBQUUsSUFBSSxFQUFFLEtBQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxPQUFPLEVBQUUsS0FBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBQy9ELENBQUM7UUFBQyxPQUFPLENBQU0sRUFBRSxDQUFDO1lBQ2hCLE1BQU0sSUFBSSxLQUFLLENBQ2IsdUVBQXVFLENBQUMsQ0FBQyxPQUFPLEVBQUUsQ0FDbkYsQ0FBQztRQUNKLENBQUM7SUFDSCxDQUFDO0NBQ0Y7QUFFRCxNQUFlLGtCQUFtQixTQUFRLGNBQWM7SUFDL0MsS0FBSyxDQUFDLHFCQUFxQixDQUNoQyxXQUFtQixFQUNuQixjQUFzQjs7UUFFdEIsZ0JBQU0sQ0FBQyxLQUFLLENBQUMsZUFBZSxXQUFXLElBQUksY0FBYyxlQUFlLENBQUMsQ0FBQztRQUUxRSxNQUFNLEtBQUssR0FBRyxXQUFXLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQ3JDLElBQUksS0FBSyxDQUFDLE1BQU0sS0FBSyxDQUFDLEVBQUUsQ0FBQztZQUN2QixNQUFNLGdCQUFNLENBQUMsUUFBUSxDQUNuQiw0R0FBNEcsV0FBVyxFQUFFLENBQzFILENBQUM7UUFDSixDQUFDO1FBRUQsTUFBTSxpQkFBaUIsR0FBRyxLQUFLLENBQUMsR0FBRyxFQUFFLENBQUM7UUFDdEMsTUFBTSxPQUFPLEdBQUcsS0FBSyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUVoQyxNQUFNLEdBQUcsR0FBRyxrREFBa0QsT0FBTyxVQUFVLGlCQUFpQixVQUFVLGNBQWMsaUJBQWlCLENBQUM7UUFDMUksZ0JBQU0sQ0FBQyxLQUFLLENBQ1YsbUVBQW1FLEdBQUcsR0FBRyxDQUMxRSxDQUFDO1FBQ0YsTUFBTSxRQUFRLEdBQUcsTUFBTSxJQUFBLG9CQUFLLEVBQUMsR0FBRyxDQUFDLENBQUM7UUFFbEMsTUFBTSxJQUFJLEdBQUcsQ0FBQyxNQUFNLFFBQVEsQ0FBQyxJQUFJLEVBQUUsQ0FBUSxDQUFDO1FBQzVDLGdCQUFNLENBQUMsS0FBSyxDQUNWLGtEQUFrRCxXQUFXLEtBQUssSUFBSSxDQUFDLFNBQVMsQ0FDOUUsSUFBSSxDQUNMLEVBQUUsQ0FDSixDQUFDO1FBRUYsT0FBTyxDQUFDLE1BQUEsTUFBQSxJQUFJLGFBQUosSUFBSSx1QkFBSixJQUFJLENBQUUsUUFBUSwwQ0FBRSxRQUFRLG1DQUFJLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUM3QyxDQUFDO0NBQ0Y7QUFFRCxNQUFNLG1CQUFvQixTQUFRLGtCQUFrQjtJQUMzQyxLQUFLLENBQUMsVUFBVSxDQUNyQixXQUFtQixFQUNuQixjQUFjLEdBQUcsUUFBUTs7UUFFekIsT0FBTyxDQUFDLEdBQUcsQ0FBQyxVQUFVLFdBQVcsTUFBTSxjQUFjLGFBQWEsQ0FBQyxDQUFDO1FBQ3BFLHdCQUF3QjtRQUN4QixNQUFNLE9BQU8sR0FBRyxjQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxnQkFBZ0IsRUFBRSxTQUFTLENBQUMsQ0FBQztRQUM1RCxJQUFJLENBQUMsSUFBQSxxQkFBVSxFQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUM7WUFDekIsTUFBTSxnQkFBTSxDQUFDLEtBQUssQ0FDaEIsc0dBQXNHLENBQ3ZHLENBQUM7UUFDSixDQUFDO1FBRUQsTUFBTSxHQUFHLEdBQUcsTUFBTSxFQUFFLENBQUMsUUFBUSxDQUFDLE9BQU8sRUFBRSxNQUFNLENBQUMsQ0FBQztRQUMvQyxNQUFNLE1BQU0sR0FBRyxDQUFDLE1BQU0sSUFBQSxlQUFNLEVBQUMsR0FBRyxFQUFFLEVBQUUsQ0FBQyxDQUFZLENBQUM7UUFFbEQsc0JBQXNCO1FBQ3RCLE1BQU0sU0FBUyxHQUFHLFdBQVcsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDekMsTUFBTSxPQUFPLEdBQUcsU0FBUyxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsU0FBUyxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDbkUsTUFBTSxVQUFVLEdBQUcsU0FBUyxDQUFDLFNBQVMsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDLENBQUM7UUFFbkQsTUFBTSxhQUFhLEdBQUcsQ0FBQyxNQUFNLElBQUEsZUFBTSxFQUNqQztlQUNTLE9BQU87a0JBQ0osVUFBVTtlQUNiLGNBQWM7Y0FDZixDQUNULENBQVksQ0FBQztRQUVkLE1BQU0sWUFBWSxHQUFHLE1BQUEsTUFBQSxNQUFBLE1BQU0sQ0FBQyxRQUFRLDBDQUNoQyxJQUFJLENBQUMsQ0FBQyxFQUFFLEVBQUUsRUFBRSxDQUFDLEVBQUUsQ0FBQyxJQUFJLEtBQUssU0FBUyxDQUFDLDBDQUNuQyxRQUFRLDBDQUFFLElBQUksQ0FBQyxDQUFDLEVBQUUsRUFBRSxFQUFFLENBQUMsRUFBRSxDQUFDLElBQUksS0FBSyxjQUFjLENBQUMsQ0FBQztRQUV2RCxJQUFJLENBQUMsWUFBWSxFQUFFLENBQUM7WUFDbEIsTUFBTSxnQkFBTSxDQUFDLEtBQUssQ0FBQyxvREFBb0QsQ0FBQyxDQUFDO1FBQzNFLENBQUM7UUFDRCxZQUFZLENBQUMsUUFBUSxHQUFHLENBQUMsQ0FBQSxZQUFZLGFBQVosWUFBWSx1QkFBWixZQUFZLENBQUUsUUFBUSxLQUFJLEVBQUUsQ0FBQyxDQUFDLE1BQU0sQ0FDM0QsQ0FBQyxFQUFFLEVBQUUsRUFBRTs7WUFDTCxPQUFBLENBQUEsTUFBQSxFQUFFLENBQUMsUUFBUSwwQ0FBRSxJQUFJLENBQ2YsQ0FBQyxLQUFLLEVBQUUsRUFBRSxXQUNSLE9BQUEsS0FBSyxDQUFDLElBQUksS0FBSyxTQUFTLElBQUksQ0FBQSxNQUFBLEtBQUssQ0FBQyxRQUFRLDBDQUFHLENBQUMsRUFBRSxJQUFJLE1BQUssT0FBTyxDQUFBLEVBQUEsQ0FDbkU7aUJBQ0QsTUFBQSxFQUFFLENBQUMsUUFBUSwwQ0FBRSxJQUFJLENBQ2YsQ0FBQyxRQUFRLEVBQUUsRUFBRTs7b0JBQ1gsT0FBQSxRQUFRLENBQUMsSUFBSSxLQUFLLFlBQVk7d0JBQzlCLENBQUEsTUFBQSxRQUFRLENBQUMsUUFBUSwwQ0FBRyxDQUFDLEVBQUUsSUFBSSxNQUFLLFVBQVUsQ0FBQTtpQkFBQSxDQUM3QyxDQUFBLENBQUE7U0FBQSxDQUNKLENBQUM7UUFDRixNQUFBLFlBQVksYUFBWixZQUFZLHVCQUFaLFlBQVksQ0FBRSxRQUFRLDBDQUFFLElBQUksQ0FBQyxhQUFhLENBQUMsUUFBUyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFFekQsb0JBQW9CO1FBQ3BCLE1BQU0sRUFBRSxDQUFDLFNBQVMsQ0FBQyxPQUFPLEVBQUUsSUFBQSxlQUFNLEVBQUMsTUFBTSxFQUFFLEVBQUUsTUFBTSxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztRQUUzRCxVQUFVO1FBQ1YsTUFBTSxJQUFBLGNBQUksRUFBQyxLQUFLLEVBQUUsQ0FBQyxTQUFTLENBQUMsRUFBRSxFQUFFLEdBQUcsRUFBRSxJQUFJLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQyxDQUFDO1FBQy9ELE9BQU8sQ0FBQyxHQUFHLENBQUMsb0JBQW9CLENBQUMsQ0FBQztJQUNwQyxDQUFDO0lBRU0sS0FBSyxDQUFDLG9CQUFvQjs7UUFHL0IsSUFBSSxDQUFDO1lBQ0gsTUFBTSxPQUFPLEdBQUcsY0FBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsZ0JBQWdCLEVBQUUsU0FBUyxDQUFDLENBQUM7WUFDNUQsSUFBSSxDQUFDLElBQUEscUJBQVUsRUFBQyxPQUFPLENBQUMsRUFBRSxDQUFDO2dCQUN6QixNQUFNLGdCQUFNLENBQUMsS0FBSyxDQUNoQixzR0FBc0csQ0FDdkcsQ0FBQztZQUNKLENBQUM7WUFFRCxNQUFNLEdBQUcsR0FBRyxNQUFNLEVBQUUsQ0FBQyxRQUFRLENBQUMsT0FBTyxFQUFFLE1BQU0sQ0FBQyxDQUFDO1lBQy9DLE1BQU0sTUFBTSxHQUFHLENBQUMsTUFBTSxJQUFBLGVBQU0sRUFBQyxHQUFHLEVBQUUsRUFBRSxDQUFDLENBQVksQ0FBQztZQUVsRCxNQUFNLFlBQVksR0FDaEIsTUFBQSxNQUFBLE1BQUEsTUFBQSxNQUFBLE1BQU0sQ0FBQyxRQUFRLDBDQUNYLElBQUksQ0FBQyxDQUFDLEVBQUUsRUFBRSxFQUFFLENBQUMsRUFBRSxDQUFDLElBQUksS0FBSyxTQUFTLENBQUMsMENBQ25DLFFBQVEsMENBQUUsSUFBSSxDQUFDLENBQUMsRUFBRSxFQUFFLEVBQUUsQ0FBQyxFQUFFLENBQUMsSUFBSSxLQUFLLGNBQWMsQ0FBQywwQ0FBRSxRQUFRLG1DQUFJLEVBQUUsQ0FBQztZQUV6RSxPQUFPLFlBQVk7aUJBQ2hCLEdBQUcsQ0FBQyxDQUFDLEdBQUcsRUFBRSxFQUFFOztnQkFBQyxPQUFBLENBQUM7b0JBQ2IsSUFBSSxFQUFFLEdBQ0osTUFBQSxNQUFBLE1BQUEsR0FBRyxDQUFDLFFBQVEsMENBQUUsSUFBSSxDQUFDLENBQUMsRUFBRSxFQUFFLEVBQUUsQ0FBQyxFQUFFLENBQUMsSUFBSSxLQUFLLFNBQVMsQ0FBQywwQ0FBRSxRQUFRLDBDQUFHLENBQUMsRUFDNUQsSUFDTCxJQUNFLE1BQUEsTUFBQSxNQUFBLEdBQUcsQ0FBQyxRQUFRLDBDQUFFLElBQUksQ0FBQyxDQUFDLEVBQUUsRUFBRSxFQUFFLENBQUMsRUFBRSxDQUFDLElBQUksS0FBSyxZQUFZLENBQUMsMENBQUUsUUFBUSwwQ0FBRyxDQUFDLEVBQy9ELElBQ0wsRUFBRTtvQkFDRixPQUFPLEVBQUUsTUFBQSxNQUFBLE1BQUEsR0FBRyxDQUFDLFFBQVEsMENBQUUsSUFBSSxDQUFDLENBQUMsRUFBRSxFQUFFLEVBQUUsQ0FBQyxFQUFFLENBQUMsSUFBSSxLQUFLLFNBQVMsQ0FBQywwQ0FDdEQsUUFBUSwwQ0FBRyxDQUFDLEVBQUUsSUFBYztpQkFDakMsQ0FBQyxDQUFBO2FBQUEsQ0FBQztpQkFDRixNQUFNLENBQUMsQ0FBQyxHQUFHLEVBQUUsRUFBRSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLCtCQUErQixDQUFDLENBQUMsQ0FBQztRQUMzRSxDQUFDO1FBQUMsT0FBTyxDQUFNLEVBQUUsQ0FBQztZQUNoQixNQUFNLElBQUksS0FBSyxDQUNiLCtEQUErRCxDQUFDLENBQUMsT0FBTyxFQUFFLENBQzNFLENBQUM7UUFDSixDQUFDO0lBQ0gsQ0FBQztDQUNGO0FBRUQsTUFBTSxvQkFBcUIsU0FBUSxrQkFBa0I7SUFDNUMsTUFBTSxDQUFDLGVBQWUsQ0FBQyxnQkFBd0I7UUFDcEQsT0FBTyxJQUFBLHlCQUFlLEVBQUMsZ0JBQWdCLENBQUMsQ0FBQztJQUMzQyxDQUFDO0lBRU0sS0FBSyxDQUFDLFVBQVUsQ0FDckIsVUFBa0IsRUFDbEIsY0FBYyxHQUFHLGdCQUFnQjtRQUVqQyxNQUFNLGVBQWUsR0FBRyxjQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxnQkFBZ0IsRUFBRSxjQUFjLENBQUMsQ0FBQztRQUN6RSxNQUFNLFdBQVcsR0FBRyxNQUFNLEVBQUUsQ0FBQyxRQUFRLENBQUMsZUFBZSxFQUFFLE1BQU0sQ0FBQyxDQUFDO1FBQy9ELE1BQU0sZ0JBQWdCLEdBQUcsV0FBVyxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUVwRCxNQUFNLGlCQUFpQixHQUFHLG9CQUFvQixDQUFDO1FBQy9DLE1BQU0sb0JBQW9CLEdBQUcsZ0JBQWdCLENBQUMsU0FBUyxDQUFDLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FDL0QsaUJBQWlCLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUM3QixDQUFDO1FBQ0YsSUFBSSxvQkFBb0IsS0FBSyxDQUFDLENBQUMsRUFBRSxDQUFDO1lBQ2hDLE1BQU0sZ0JBQU0sQ0FBQyxLQUFLLENBQ2hCLHlEQUF5RCxDQUMxRCxDQUFDO1FBQ0osQ0FBQztRQUVELE1BQU0sZUFBZSxHQUFHLFVBQVUsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDOUMsTUFBTSxXQUFXLEdBQUcsZUFBZSxDQUFDLEdBQUcsRUFBRSxDQUFDO1FBQzFDLE1BQU0sU0FBUyxHQUFHLGVBQWUsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDNUMsTUFBTSxtQkFBbUIsR0FBRyxHQUFHLFNBQVMsSUFBSSxXQUFXLEVBQUUsQ0FBQztRQUMxRCxNQUFNLDZCQUE2QixHQUFHLEdBQUcsbUJBQW1CLElBQUksY0FBYyxFQUFFLENBQUM7UUFFakYsTUFBTSxrQkFBa0IsR0FBRyxnQkFBZ0IsQ0FBQyxTQUFTLENBQUMsQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUM3RCxJQUFJLENBQUMsUUFBUSxDQUFDLG1CQUFtQixDQUFDLENBQ25DLENBQUM7UUFDRixJQUFJLGtCQUFrQixLQUFLLENBQUMsQ0FBQyxFQUFFLENBQUM7WUFDOUIsZ0JBQWdCLENBQUMsTUFBTSxDQUFDLGtCQUFrQixFQUFFLENBQUMsQ0FBQyxDQUFDO1FBQ2pELENBQUM7UUFFRCxNQUFNLG9CQUFvQixHQUFHLHFCQUFxQiw2QkFBNkIsR0FBRyxDQUFDO1FBQ25GLGdCQUFnQixDQUFDLE1BQU0sQ0FBQyxvQkFBb0IsR0FBRyxDQUFDLEVBQUUsQ0FBQyxFQUFFLG9CQUFvQixDQUFDLENBQUM7UUFFM0UsTUFBTSxFQUFFLENBQUMsU0FBUyxDQUFDLGVBQWUsRUFBRSxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQztJQUNuRSxDQUFDO0lBRU0sS0FBSyxDQUFDLG9CQUFvQjtRQUcvQixNQUFNLFlBQVksR0FBRyxNQUFNLElBQUEsK0JBQXFCLEdBQUUsQ0FBQztRQUNuRCxJQUFJLENBQUMsWUFBWSxFQUFFLENBQUM7WUFDbEIsTUFBTSxnQkFBTSxDQUFDLEtBQUssQ0FBQyxpQ0FBaUMsQ0FBQyxDQUFDO1FBQ3hELENBQUM7UUFFRCxNQUFNLGNBQWMsR0FBRyxZQUFZO2FBQ2hDLEdBQUcsQ0FBQyxDQUFDLElBQUksRUFBRSxFQUFFLENBQUMsSUFBQSwwQ0FBZ0MsRUFBQyxJQUFJLENBQUMsQ0FBQzthQUNyRCxNQUFNLENBQUMsQ0FBQyxHQUFHLEVBQUUsRUFBRTtZQUNkLElBQUksQ0FBQyxHQUFHLEVBQUUsQ0FBQztnQkFDVCxPQUFPLEtBQUssQ0FBQztZQUNmLENBQUM7WUFDRCxPQUFPLEdBQUcsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLGlCQUFpQixDQUFDLENBQUM7UUFDOUMsQ0FBQyxDQUFDO2FBQ0QsR0FBRyxDQUFDLENBQUMsR0FBRyxFQUFFLEVBQUUsQ0FBQyxDQUFDO1lBQ2IsSUFBSSxFQUFFLGlCQUFpQixHQUFJLENBQUMsSUFBSSxFQUFFO1lBQ2xDLE9BQU8sRUFBRSxHQUFJLENBQUMsT0FBTztTQUN0QixDQUFDLENBQUMsQ0FBQztRQUVOLE9BQU8sY0FBYyxDQUFDO0lBQ3hCLENBQUM7Q0FDRjtBQUVELE1BQU0sZ0JBQWlCLFNBQVEsY0FBYztJQUNwQyxLQUFLLENBQUMsVUFBVSxDQUNyQixXQUFtQixFQUNuQixjQUF1QjtRQUV2QixPQUFPLENBQUMsR0FBRyxDQUFDLGtCQUFrQixXQUFXLE1BQU0sY0FBYyxFQUFFLENBQUMsQ0FBQztRQUVqRSxNQUFNLFlBQVksR0FBdUIsY0FBYztZQUNyRCxDQUFDLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxjQUFjLENBQUM7WUFDOUIsQ0FBQyxDQUFDLFNBQVMsQ0FBQztRQUVkLElBQUksb0JBQW9CLEdBQUcsRUFBRSxDQUFDO1FBQzlCLElBQUksT0FBTyxZQUFZLEtBQUssUUFBUSxJQUFJLFlBQVksR0FBRyxDQUFDLEVBQUUsQ0FBQztZQUN6RCxvQkFBb0IsR0FBRyxLQUFLLFlBQVksRUFBRSxDQUFDO1FBQzdDLENBQUM7UUFFRCxnQkFBTSxDQUFDLEtBQUssQ0FDVixtQkFBbUIsV0FBVyxHQUFHLG9CQUFvQixLQUFLLGNBQWMsR0FBRyxDQUM1RSxDQUFDO1FBQ0YsVUFBVTtRQUNWLE1BQU0sSUFBQSxjQUFJLEVBQ1IsSUFBSSxFQUNKLENBQUMsS0FBSyxFQUFFLEdBQUcsV0FBVyxHQUFHLG9CQUFvQixLQUFLLGNBQWMsRUFBRSxDQUFDLEVBQ25FO1lBQ0UsR0FBRyxFQUFFLElBQUksQ0FBQyxnQkFBZ0I7U0FDM0IsQ0FDRixDQUFDO1FBRUYsT0FBTyxDQUFDLEdBQUcsQ0FBQyxvQkFBb0IsQ0FBQyxDQUFDO0lBQ3BDLENBQUM7SUFFTSxLQUFLLENBQUMscUJBQXFCLENBQ2hDLFdBQW1CLEVBQ25CLGNBQXNCO1FBRXRCLGdCQUFNLENBQUMsS0FBSyxDQUFDLGVBQWUsV0FBVyxJQUFJLGNBQWMsZUFBZSxDQUFDLENBQUM7UUFFMUUsd0RBQXdEO1FBQ3hELE1BQU0sS0FBSyxHQUFHLFdBQVcsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDckMsSUFBSSxLQUFLLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBRSxDQUFDO1lBQ3ZCLE1BQU0sZ0JBQU0sQ0FBQyxRQUFRLENBQ25CLDJGQUEyRixXQUFXLEVBQUUsQ0FDekcsQ0FBQztRQUNKLENBQUM7UUFFRCxNQUFNLEdBQUcsR0FBRyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDckIsTUFBTSxJQUFJLEdBQUcsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3RCLE1BQU0sV0FBVyxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUU3QixNQUFNLEdBQUcsR0FBRyxnQ0FBZ0MsR0FBRyxJQUFJLElBQUksaUJBQWlCLFdBQVcsS0FBSyxjQUFjLEVBQUUsQ0FBQztRQUN6RyxnQkFBTSxDQUFDLEtBQUssQ0FBQyxxQkFBcUIsR0FBRyxJQUFJLElBQUksVUFBVSxHQUFHLEdBQUcsQ0FBQyxDQUFDO1FBQy9ELE1BQU0sUUFBUSxHQUFHLE1BQU0sSUFBQSxvQkFBSyxFQUFDLEdBQUcsRUFBRTtZQUNoQyxPQUFPLEVBQUU7Z0JBQ1AsTUFBTSxFQUFFLDZCQUE2QjtnQkFDckMsWUFBWSxFQUFFLDBCQUEwQjtnQkFDeEMsR0FBRyxDQUFDLHNCQUFzQjtvQkFDeEIsQ0FBQyxDQUFDLEVBQUUsYUFBYSxFQUFFLFVBQVUsc0JBQXNCLEVBQUUsRUFBRTtvQkFDdkQsQ0FBQyxDQUFDLEVBQUUsQ0FBQzthQUNSO1NBQ0YsQ0FBQyxDQUFDO1FBRUgsTUFBTSxJQUFJLEdBQUcsQ0FBQyxNQUFNLFFBQVEsQ0FBQyxJQUFJLEVBQUUsQ0FBUSxDQUFDO1FBQzVDLGdCQUFNLENBQUMsS0FBSyxDQUNWLHlEQUF5RCxXQUFXLEtBQUssSUFBSSxDQUFDLFNBQVMsQ0FDckYsSUFBSSxDQUNMLEVBQUUsQ0FDSixDQUFDO1FBRUYsSUFBSSxJQUFJLElBQUksSUFBSSxDQUFDLEdBQUcsRUFBRSxDQUFDO1lBQ3JCLE9BQU8sSUFBSSxDQUFDO1FBQ2QsQ0FBQztRQUVELGdCQUFNLENBQUMsSUFBSSxDQUNULDBCQUEwQixXQUFXLEtBQUssY0FBYyxzQkFBc0IsR0FBRyxJQUFJLElBQUksS0FBSyxJQUFJLENBQUMsU0FBUyxDQUMxRyxJQUFJLENBQ0wsR0FBRyxDQUNMLENBQUM7UUFFRixPQUFPLEtBQUssQ0FBQztJQUNmLENBQUM7SUFFTSxLQUFLLENBQUMsb0JBQW9CO1FBRy9CLElBQUksQ0FBQztZQUNILE1BQU0sU0FBUyxHQUFHLGNBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLGdCQUFnQixFQUFFLFFBQVEsQ0FBQyxDQUFDO1lBQzdELElBQUksQ0FBQyxJQUFBLHFCQUFVLEVBQUMsU0FBUyxDQUFDLEVBQUUsQ0FBQztnQkFDM0IsTUFBTSxnQkFBTSxDQUFDLEtBQUssQ0FDaEIscUdBQXFHLENBQ3RHLENBQUM7WUFDSixDQUFDO1lBRUQsTUFBTSxLQUFLLEdBQUcsTUFBTSxFQUFFLENBQUMsUUFBUSxDQUFDLFNBQVMsRUFBRSxNQUFNLENBQUMsQ0FBQztZQUNuRCxNQUFNLG9CQUFvQixHQUFHLElBQUksR0FBRyxFQUFFLENBQUM7WUFFdkMsT0FBTyxLQUFLO2lCQUNULEtBQUssQ0FBQyxJQUFJLENBQUM7aUJBQ1gsTUFBTSxDQUNMLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FDUCxJQUFJLENBQUMsVUFBVSxDQUFDLHFDQUFxQyxDQUFDO2dCQUN0RCxJQUFJLENBQUMsVUFBVSxDQUFDLGlDQUFpQyxDQUFDLENBQ3JEO2lCQUNBLEdBQUcsQ0FBQyxDQUFDLElBQUksRUFBRSxFQUFFO2dCQUNaLE1BQU0sS0FBSyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUM7Z0JBQzlCLElBQUksS0FBSyxDQUFDLE1BQU0sS0FBSyxDQUFDLEVBQUUsQ0FBQztvQkFDdkIsTUFBTSxnQkFBTSxDQUFDLFFBQVEsQ0FDbkIseUZBQXlGLElBQUksRUFBRSxDQUNoRyxDQUFDO2dCQUNKLENBQUM7Z0JBRUQsK0RBQStEO2dCQUMvRCxNQUFNLElBQUksR0FBRyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDO2dCQUV2RCxNQUFNLE9BQU8sR0FBRyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO2dCQUV2QyxJQUFJLG9CQUFvQixDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDO29CQUNuQyxPQUFPLEVBQUUsSUFBSSxFQUFFLEVBQUUsRUFBRSxPQUFPLEVBQUUsRUFBRSxFQUFFLENBQUM7Z0JBQ25DLENBQUM7Z0JBRUQsb0JBQW9CLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDO2dCQUUvQixPQUFPO29CQUNMLElBQUk7b0JBQ0osT0FBTztpQkFDUixDQUFDO1lBQ0osQ0FBQyxDQUFDO2lCQUNELE1BQU0sQ0FDTCxDQUFDLFlBQVksRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLFlBQVksQ0FBQyxJQUFJLElBQUksQ0FBQyxDQUFDLFlBQVksQ0FBQyxPQUFPLENBQ2hFLENBQUM7UUFDTixDQUFDO1FBQUMsT0FBTyxDQUFNLEVBQUUsQ0FBQztZQUNoQixNQUFNLElBQUksS0FBSyxDQUNiLDhEQUE4RCxDQUFDLENBQUMsT0FBTyxFQUFFLENBQzFFLENBQUM7UUFDSixDQUFDO0lBQ0gsQ0FBQztDQUNGIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQ29weXJpZ2h0IChjKSBIYXNoaUNvcnAsIEluY1xuLy8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IE1QTC0yLjBcbmltcG9ydCB7XG4gIExhbmd1YWdlLFxuICBleGVjLFxuICBFcnJvcnMsXG4gIGxvZ2dlcixcbiAgaXNHcmFkbGVQcm9qZWN0LFxuICBnZXRHcmFkbGVEZXBlbmRlbmNpZXMsXG4gIGdldERlcGVuZGVuY3lJbmZvcm1hdGlvbkZyb21MaW5lLFxufSBmcm9tIFwiQGNka3RuL2NvbW1vbnNcIjtcbmltcG9ydCB7IGV4aXN0c1N5bmMgfSBmcm9tIFwiZnMtZXh0cmFcIjtcbmltcG9ydCBwYXRoIGZyb20gXCJwYXRoXCI7XG5pbXBvcnQgeyB4bWwyanMsIGpzMnhtbCwgRWxlbWVudCB9IGZyb20gXCJ4bWwtanNcIjtcbmltcG9ydCAqIGFzIGZzIGZyb20gXCJmcy1leHRyYVwiO1xuaW1wb3J0ICogYXMgc2VtdmVyIGZyb20gXCJzZW12ZXJcIjtcbmltcG9ydCBmZXRjaCBmcm9tIFwibm9kZS1mZXRjaFwiO1xuaW1wb3J0ICogYXMgeiBmcm9tIFwiem9kXCI7XG5cbi8vIENhbid0IHVzZSBDREtURl8gYXMgcHJlZml4IGJlY2F1c2UgeWFyZ3MgLmVudihcIkNES1RGXCIpIGluIHN0cmljdCBtb2RlIGRvZXMgbm90IGFsbG93IHVzIHRvXG4vLyBSZWZlciB0bzogaHR0cHM6Ly9naXRodWIuY29tL3lhcmdzL3lhcmdzL2lzc3Vlcy84NzNcbmNvbnN0IHsgR0lUSFVCX0FQSV9UT0tFTl9DREtURiB9ID0gcHJvY2Vzcy5lbnY7XG5cbi8vIHtcbi8vICAgXCJ2ZXJzaW9uXCI6IFwiMS4wLjBcIixcbi8vICAgXCJuYW1lXCI6IFwidGVzdFVTSGFzRlwiLFxuLy8gICBcInByb2JsZW1zXCI6IFtcbi8vICAgICBcImV4dHJhbmVvdXM6IGFyY2hpdmVyLXV0aWxzQDIuMS4wIC9wcml2YXRlL3Zhci9mb2xkZXJzL3pfL3YwM2wzM2Q1NWZiNTducnIzYjFxMDNjaDAwMDBncS9UL3Rlc3RVU0hhc0Yvbm9kZV9tb2R1bGVzL2FyY2hpdmVyLXV0aWxzXCIsXG4vLyAgIF0sXG4vLyAgIFwiZGVwZW5kZW5jaWVzXCI6IHtcbi8vICAgICBcIkBjZGt0Zi9wcm92aWRlci1yYW5kb21cIjoge1xuLy8gICAgICAgXCJ2ZXJzaW9uXCI6IFwiMy4wLjExXCIsXG4vLyAgICAgICBcInJlc29sdmVkXCI6IFwiaHR0cHM6Ly9yZWdpc3RyeS5ucG1qcy5vcmcvQGNka3RmL3Byb3ZpZGVyLXJhbmRvbS8tL3Byb3ZpZGVyLXJhbmRvbS0zLjAuMTEudGd6XCJcbi8vICAgICB9LFxuY29uc3QgbnBtTGlzdFNjaGVtYSA9IHpcbiAgLm9iamVjdCh7XG4gICAgZGVwZW5kZW5jaWVzOiB6LnJlY29yZChcbiAgICAgIHpcbiAgICAgICAgLm9iamVjdCh7XG4gICAgICAgICAgdmVyc2lvbjogei5zdHJpbmcoKSxcbiAgICAgICAgfSlcbiAgICAgICAgLm5vbnN0cmljdCgpLFxuICAgICksXG4gIH0pXG4gIC5kZWVwUGFydGlhbCgpXG4gIC5ub25zdHJpY3QoKTtcblxuLy8ge1xuLy8gICBcInR5cGVcIjogXCJ0cmVlXCIsXG4vLyAgIFwiZGF0YVwiOiB7XG4vLyAgICAgXCJ0eXBlXCI6IFwibGlzdFwiLFxuLy8gICAgIFwidHJlZXNcIjogW1xuLy8gICAgICAge1xuLy8gICAgICAgICBcIm5hbWVcIjogXCJAY2RrdGYvcHJvdmlkZXItcmFuZG9tQDMuMC4xMVwiLFxuLy8gICAgICAgICBcImNoaWxkcmVuXCI6IFtdLFxuLy8gICAgICAgICBcImhpbnRcIjogbnVsbCxcbi8vICAgICAgICAgXCJjb2xvclwiOiBcImJvbGRcIixcbi8vICAgICAgICAgXCJkZXB0aFwiOiAwXG4vLyAgICAgICB9XG4vLyAgICAgXVxuLy8gICB9XG4vLyB9XG5jb25zdCB5YXJuTGlzdFNjaGVtYSA9IHpcbiAgLm9iamVjdCh7XG4gICAgZGF0YTogelxuICAgICAgLm9iamVjdCh7XG4gICAgICAgIHRyZWVzOiB6LmFycmF5KFxuICAgICAgICAgIHpcbiAgICAgICAgICAgIC5vYmplY3Qoe1xuICAgICAgICAgICAgICBuYW1lOiB6LnN0cmluZygpLFxuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIC5ub25zdHJpY3QoKSxcbiAgICAgICAgKSxcbiAgICAgIH0pXG4gICAgICAubm9uc3RyaWN0KCksXG4gIH0pXG4gIC5kZWVwUGFydGlhbCgpXG4gIC5ub25zdHJpY3QoKTtcblxuLy8gW1xuLy8gICB7XG4vLyAgICAgXCJuYW1lXCI6IFwiYXBwZGlyc1wiLFxuLy8gICAgIFwidmVyc2lvblwiOiBcIjEuNC40XCJcbi8vICAgfSxcbi8vICAge1xuY29uc3QgcGlwUGFja2FnZVNjaGVtYSA9IHouYXJyYXkoXG4gIHoub2JqZWN0KHsgbmFtZTogei5zdHJpbmcoKSwgdmVyc2lvbjogei5zdHJpbmcoKSB9KS5ub25zdHJpY3QoKSxcbik7XG5cbi8qKlxuICogbWFuYWdlcyBpbnN0YWxsaW5nLCB1cGRhdGluZywgYW5kIHJlbW92aW5nIGRlcGVuZGVuY2llc1xuICogaW4gdGhlIHBhY2thZ2Ugc3lzdGVtIHVzZWQgYnkgdGhlIHRhcmdldCBsYW5ndWFnZSBvZiBhIENES1ROXG4gKiBwcm9qZWN0XG4gKi9cbmV4cG9ydCBhYnN0cmFjdCBjbGFzcyBQYWNrYWdlTWFuYWdlciB7XG4gIGNvbnN0cnVjdG9yKHByb3RlY3RlZCByZWFkb25seSB3b3JraW5nRGlyZWN0b3J5OiBzdHJpbmcpIHt9XG5cbiAgcHVibGljIHN0YXRpYyBmb3JMYW5ndWFnZShcbiAgICBsYW5ndWFnZTogTGFuZ3VhZ2UsXG4gICAgd29ya2luZ0RpcmVjdG9yeTogc3RyaW5nLFxuICApOiBQYWNrYWdlTWFuYWdlciB7XG4gICAgc3dpdGNoIChsYW5ndWFnZSkge1xuICAgICAgY2FzZSBMYW5ndWFnZS5HTzpcbiAgICAgICAgcmV0dXJuIG5ldyBHb1BhY2thZ2VNYW5hZ2VyKHdvcmtpbmdEaXJlY3RvcnkpO1xuICAgICAgY2FzZSBMYW5ndWFnZS5UWVBFU0NSSVBUOlxuICAgICAgICByZXR1cm4gbmV3IE5vZGVQYWNrYWdlTWFuYWdlcih3b3JraW5nRGlyZWN0b3J5KTtcbiAgICAgIGNhc2UgTGFuZ3VhZ2UuUFlUSE9OOlxuICAgICAgICByZXR1cm4gbmV3IFB5dGhvblBhY2thZ2VNYW5hZ2VyKHdvcmtpbmdEaXJlY3RvcnkpO1xuICAgICAgY2FzZSBMYW5ndWFnZS5DU0hBUlA6XG4gICAgICAgIHJldHVybiBuZXcgTnVnZXRQYWNrYWdlTWFuYWdlcih3b3JraW5nRGlyZWN0b3J5KTtcbiAgICAgIGNhc2UgTGFuZ3VhZ2UuSkFWQTpcbiAgICAgICAgaWYgKEdyYWRsZVBhY2thZ2VNYW5hZ2VyLmlzR3JhZGxlUHJvamVjdCh3b3JraW5nRGlyZWN0b3J5KSkge1xuICAgICAgICAgIHJldHVybiBuZXcgR3JhZGxlUGFja2FnZU1hbmFnZXIod29ya2luZ0RpcmVjdG9yeSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG5ldyBNYXZlblBhY2thZ2VNYW5hZ2VyKHdvcmtpbmdEaXJlY3RvcnkpO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBVbmtub3duIGxhbmd1YWdlOiAke2xhbmd1YWdlfWApO1xuICAgIH1cbiAgfVxuXG4gIHB1YmxpYyBhYnN0cmFjdCBhZGRQYWNrYWdlKFxuICAgIHBhY2thZ2VOYW1lOiBzdHJpbmcsXG4gICAgcGFja2FnZVZlcnNpb24/OiBzdHJpbmcsXG4gICAgc2lsZW50PzogYm9vbGVhbixcbiAgKTogUHJvbWlzZTx2b2lkPjtcbiAgLy8gYWRkIGNoZWNrIGlmIHBhY2thZ2UgZXhpc3RzIGFscmVhZHkuIG1pZ2h0IHF1ZXJ5IHZlcnNpb24gaW4gdGhlIGZ1dHVyZSBhbmQgb2ZmZXIgdG8gdXBncmFkZT9cblxuICBwdWJsaWMgYWJzdHJhY3QgaXNOcG1WZXJzaW9uQXZhaWxhYmxlKFxuICAgIHBhY2thZ2VOYW1lOiBzdHJpbmcsXG4gICAgcGFja2FnZVZlcnNpb246IHN0cmluZyxcbiAgKTogUHJvbWlzZTxib29sZWFuPjtcblxuICBwdWJsaWMgYWJzdHJhY3QgbGlzdFByb3ZpZGVyUGFja2FnZXMoKTogUHJvbWlzZTxcbiAgICB7IG5hbWU6IHN0cmluZzsgdmVyc2lvbjogc3RyaW5nIH1bXVxuICA+O1xufVxuXG5jbGFzcyBOb2RlUGFja2FnZU1hbmFnZXIgZXh0ZW5kcyBQYWNrYWdlTWFuYWdlciB7XG4gIHByaXZhdGUgaGFzWWFybkxvY2tmaWxlKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiBleGlzdHNTeW5jKHBhdGguam9pbih0aGlzLndvcmtpbmdEaXJlY3RvcnksIFwieWFybi5sb2NrXCIpKTtcbiAgfVxuXG4gIHB1YmxpYyBhc3luYyBhZGRQYWNrYWdlKFxuICAgIHBhY2thZ2VOYW1lOiBzdHJpbmcsXG4gICAgcGFja2FnZVZlcnNpb24/OiBzdHJpbmcsXG4gICAgc2lsZW50PzogYm9vbGVhbixcbiAgKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc29sZS5sb2coYEFkZGluZyBwYWNrYWdlICR7cGFja2FnZU5hbWV9IEAgJHtwYWNrYWdlVmVyc2lvbn1gKTtcblxuICAgIC8vIHByb2JlIGZvciBwYWNrYWdlLWxvY2suanNvbiBvciB5YXJuLmxvY2tcbiAgICBsZXQgY29tbWFuZCA9IFwibnBtXCI7XG4gICAgbGV0IGFyZ3MgPSBbXCJpbnN0YWxsXCJdO1xuXG4gICAgaWYgKHRoaXMuaGFzWWFybkxvY2tmaWxlKCkpIHtcbiAgICAgIGNvbW1hbmQgPSBcInlhcm5cIjtcbiAgICAgIGFyZ3MgPSBbXCJhZGRcIl07XG4gICAgfVxuICAgIGFyZ3MucHVzaChcbiAgICAgIHBhY2thZ2VWZXJzaW9uID8gcGFja2FnZU5hbWUgKyBcIkBcIiArIHBhY2thZ2VWZXJzaW9uIDogcGFja2FnZU5hbWUsXG4gICAgKTtcblxuICAgIGlmIChzaWxlbnQpIHtcbiAgICAgIGFyZ3MucHVzaChcIi0tc2lsZW50XCIpO1xuICAgICAgYXJncy5wdXNoKFwiLS1uby1wcm9ncmVzc1wiKTtcbiAgICB9XG5cbiAgICAvLyBJbnN0YWxsIGV4YWN0IHZlcnNpb25cbiAgICAvLyBZYXJuOiBodHRwczovL2NsYXNzaWMueWFybnBrZy5jb20vbGFuZy9lbi9kb2NzL2NsaS9hZGQvI3RvYy15YXJuLWFkZC1leGFjdC1lXG4gICAgLy8gTnBtOiBodHRwczovL2RvY3MubnBtanMuY29tL2NsaS92OC9jb21tYW5kcy9ucG0taW5zdGFsbCNzYXZlLWV4YWN0XG4gICAgYXJncy5wdXNoKFwiLUVcIik7XG5cbiAgICBsb2dnZXIuaW5mbyhcbiAgICAgIGBJbnN0YWxsaW5nIHBhY2thZ2UgJHtwYWNrYWdlTmFtZX0gQCAke3BhY2thZ2VWZXJzaW9ufSB1c2luZyAke2NvbW1hbmR9LmAsXG4gICAgKTtcblxuICAgIGF3YWl0IGV4ZWMoY29tbWFuZCwgYXJncywgeyBjd2Q6IHRoaXMud29ya2luZ0RpcmVjdG9yeSB9KTtcblxuICAgIGxvZ2dlci5pbmZvKFwiUGFja2FnZSBpbnN0YWxsZWQuXCIpO1xuICB9XG5cbiAgcHVibGljIGFzeW5jIGlzTnBtVmVyc2lvbkF2YWlsYWJsZShcbiAgICBfcGFja2FnZU5hbWU6IHN0cmluZyxcbiAgICBfcGFja2FnZVZlcnNpb246IHN0cmluZyxcbiAgKTogUHJvbWlzZTxib29sZWFuPiB7XG4gICAgLy8gV2UgZ2V0IHRoZSBsaXN0IG9mIGF2YWlsYWJsZSB2ZXJzaW9ucyBmcm9tIG5wbSwgbm8gbmVlZCB0byBjaGVjayBoZXJlXG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIGxpc3RZYXJuUGFja2FnZXMoKTogUHJvbWlzZTxcbiAgICB7IG5hbWU6IHN0cmluZzsgdmVyc2lvbjogc3RyaW5nIH1bXVxuICA+IHtcbiAgICB0cnkge1xuICAgICAgY29uc3Qgc3Rkb3V0ID0gYXdhaXQgZXhlYyhcInlhcm5cIiwgW1wibGlzdFwiLCBcIi0tanNvblwiXSwge1xuICAgICAgICBjd2Q6IHRoaXMud29ya2luZ0RpcmVjdG9yeSxcbiAgICAgIH0pO1xuXG4gICAgICBsb2dnZXIuZGVidWcoYExpc3RpbmcgeWFybiBwYWNrYWdlcyB1c2luZyBcInlhcm4gbGlzdCAtLWpzb25cIjogJHtzdGRvdXR9YCk7XG5cbiAgICAgIGNvbnN0IGpzb24gPSB5YXJuTGlzdFNjaGVtYS5wYXJzZShKU09OLnBhcnNlKHN0ZG91dCkpO1xuXG4gICAgICByZXR1cm4gKGpzb24/LmRhdGE/LnRyZWVzIHx8IFtdKVxuICAgICAgICAuZmlsdGVyKChkZXA6IGFueSkgPT4gZGVwLm5hbWUuc3RhcnRzV2l0aChcIkBjZGt0Zi9wcm92aWRlci1cIikpXG4gICAgICAgIC5tYXAoKGRlcDogYW55KSA9PiAoe1xuICAgICAgICAgIG5hbWU6IGBAJHtkZXAubmFtZS5zcGxpdChcIkBcIilbMV19YCxcbiAgICAgICAgICB2ZXJzaW9uOiBkZXAubmFtZS5zcGxpdChcIkBcIilbMl0sXG4gICAgICAgIH0pKTtcbiAgICB9IGNhdGNoIChlOiBhbnkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgYENvdWxkIG5vdCBkZXRlcm1pbmUgaW5zdGFsbGVkIHBhY2thZ2VzIHVzaW5nICd5YXJuIGxpc3QgLS1qc29uJzogJHtlLm1lc3NhZ2V9YCxcbiAgICAgICk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBsaXN0TnBtUGFja2FnZXMoKTogUHJvbWlzZTxcbiAgICB7IG5hbWU6IHN0cmluZzsgdmVyc2lvbjogc3RyaW5nIH1bXVxuICA+IHtcbiAgICB0cnkge1xuICAgICAgY29uc3Qgc3Rkb3V0ID0gYXdhaXQgZXhlYyhcIm5wbVwiLCBbXCJsaXN0XCIsIFwiLS1qc29uXCJdLCB7XG4gICAgICAgIGN3ZDogdGhpcy53b3JraW5nRGlyZWN0b3J5LFxuICAgICAgfSk7XG5cbiAgICAgIGxvZ2dlci5kZWJ1ZyhgTGlzdGluZyBucG0gcGFja2FnZXMgdXNpbmcgXCJucG0gbGlzdCAtLWpzb25cIjogJHtzdGRvdXR9YCk7XG4gICAgICBjb25zdCBqc29uID0gbnBtTGlzdFNjaGVtYS5wYXJzZShKU09OLnBhcnNlKHN0ZG91dCkpO1xuXG4gICAgICByZXR1cm4gT2JqZWN0LmVudHJpZXMoanNvbj8uZGVwZW5kZW5jaWVzIHx8IHt9KVxuICAgICAgICAuZmlsdGVyKChbZGVwTmFtZV0pID0+IGRlcE5hbWUuc3RhcnRzV2l0aChcIkBjZGt0Zi9wcm92aWRlci1cIikpXG4gICAgICAgIC5tYXAoKFtuYW1lLCBkZXBdKSA9PiAoeyBuYW1lLCB2ZXJzaW9uOiBkZXAudmVyc2lvbiB9KSk7XG4gICAgfSBjYXRjaCAoZTogYW55KSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgIGBDb3VsZCBub3QgZGV0ZXJtaW5lIGluc3RhbGxlZCBwYWNrYWdlcyB1c2luZyAnbnBtIGxpc3QgLS1qc29uJzogJHtlLm1lc3NhZ2V9YCxcbiAgICAgICk7XG4gICAgfVxuICB9XG5cbiAgcHVibGljIGFzeW5jIGxpc3RQcm92aWRlclBhY2thZ2VzKCk6IFByb21pc2U8XG4gICAgeyBuYW1lOiBzdHJpbmc7IHZlcnNpb246IHN0cmluZyB9W11cbiAgPiB7XG4gICAgcmV0dXJuIHRoaXMuaGFzWWFybkxvY2tmaWxlKClcbiAgICAgID8gdGhpcy5saXN0WWFyblBhY2thZ2VzKClcbiAgICAgIDogdGhpcy5saXN0TnBtUGFja2FnZXMoKTtcbiAgfVxufVxuXG5jbGFzcyBQeXRob25QYWNrYWdlTWFuYWdlciBleHRlbmRzIFBhY2thZ2VNYW5hZ2VyIHtcbiAgcHJpdmF0ZSBnZXQgYXBwQ29tbWFuZCgpIHtcbiAgICB0cnkge1xuICAgICAgcmV0dXJuIEpTT04ucGFyc2UoXG4gICAgICAgIGZzLnJlYWRGaWxlU3luYyhcbiAgICAgICAgICBwYXRoLnJlc29sdmUodGhpcy53b3JraW5nRGlyZWN0b3J5LCBcImNka3RmLmpzb25cIiksXG4gICAgICAgICAgXCJ1dGY4XCIsXG4gICAgICAgICksXG4gICAgICApW1wiYXBwXCJdO1xuICAgIH0gY2F0Y2ggKGU6IGFueSkge1xuICAgICAgdGhyb3cgRXJyb3JzLlVzYWdlKFxuICAgICAgICBgQ291bGQgbm90IGZpbmQgZmluZCBhbmQgcGFyc2UgY2RrdGYuanNvbiBpbiAke3RoaXMud29ya2luZ0RpcmVjdG9yeX1gLFxuICAgICAgICBlLFxuICAgICAgKTtcbiAgICB9XG4gIH1cblxuICBwdWJsaWMgYXN5bmMgYWRkUGFja2FnZShcbiAgICBwYWNrYWdlTmFtZTogc3RyaW5nLFxuICAgIHBhY2thZ2VWZXJzaW9uPzogc3RyaW5nLFxuICApOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCB1c2VQaXBlbnYgPSB0aGlzLmFwcENvbW1hbmQuaW5jbHVkZXMoXCJwaXBlbnZcIik7XG5cbiAgICBpZiAodXNlUGlwZW52KSB7XG4gICAgICBjb25zb2xlLmxvZyhcbiAgICAgICAgYEluc3RhbGxpbmcgcGFja2FnZSAke3BhY2thZ2VOYW1lfSBAICR7cGFja2FnZVZlcnNpb259IHVzaW5nIHBpcGVudi5gLFxuICAgICAgKTtcblxuICAgICAgYXdhaXQgZXhlYyhcInBpcGVudlwiLCBbXCJpbnN0YWxsXCIsIGAke3BhY2thZ2VOYW1lfX49JHtwYWNrYWdlVmVyc2lvbn1gXSwge1xuICAgICAgICBjd2Q6IHRoaXMud29ya2luZ0RpcmVjdG9yeSxcbiAgICAgICAgZW52OiB7XG4gICAgICAgICAgLi4ucHJvY2Vzcy5lbnYsXG4gICAgICAgICAgUElQRU5WX1FVSUVUOiBcIjFcIixcbiAgICAgICAgfSxcbiAgICAgICAgc3RkaW86IFtcImluaGVyaXRcIiwgMSwgMV0sXG4gICAgICB9KTtcblxuICAgICAgY29uc29sZS5sb2coXCJQYWNrYWdlIGluc3RhbGxlZC5cIik7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnNvbGUubG9nKFxuICAgICAgICBgSW5zdGFsbGluZyBwYWNrYWdlICR7cGFja2FnZU5hbWV9IEAgJHtwYWNrYWdlVmVyc2lvbn0gdXNpbmcgcGlwLmAsXG4gICAgICApO1xuXG4gICAgICBjb25zdCByZXF1aXJlbWVudHNGaWxlUGF0aCA9IHBhdGguam9pbihcbiAgICAgICAgdGhpcy53b3JraW5nRGlyZWN0b3J5LFxuICAgICAgICBcInJlcXVpcmVtZW50cy50eHRcIixcbiAgICAgICk7XG4gICAgICBpZiAoIWZzLmV4aXN0c1N5bmMocmVxdWlyZW1lbnRzRmlsZVBhdGgpKSB7XG4gICAgICAgIHRocm93IEVycm9ycy5Vc2FnZShcbiAgICAgICAgICBgQ291bGQgbm90IGZpbmQgcmVxdWlyZW1lbnRzLnR4dCBpbiAke3RoaXMud29ya2luZ0RpcmVjdG9yeX1gLFxuICAgICAgICApO1xuICAgICAgfVxuXG4gICAgICBjb25zdCByZXF1aXJlbWVudHMgPSBhd2FpdCBmcy5yZWFkRmlsZShyZXF1aXJlbWVudHNGaWxlUGF0aCwgXCJ1dGY4XCIpO1xuICAgICAgY29uc3QgcmVxdWlyZW1lbnRMaW5lID0gcmVxdWlyZW1lbnRzXG4gICAgICAgIC5zcGxpdChcIlxcblwiKVxuICAgICAgICAuZmluZCgobGluZSkgPT4gbGluZS5pbmNsdWRlcyhwYWNrYWdlTmFtZSkpO1xuXG4gICAgICBsb2dnZXIuZGVidWcoXG4gICAgICAgIGBSZWFkIHJlcXVpcmVtZW50cy50eHQgZmlsZSBhbmQgZm91bmQgbGluZSBpbmNsdWRpbmcgJHtwYWNrYWdlTmFtZX06ICR7cmVxdWlyZW1lbnRMaW5lfWAsXG4gICAgICApO1xuXG4gICAgICBpZiAocmVxdWlyZW1lbnRMaW5lKSB7XG4gICAgICAgIGlmIChwYWNrYWdlVmVyc2lvbiA/IHJlcXVpcmVtZW50TGluZS5pbmNsdWRlcyhwYWNrYWdlVmVyc2lvbikgOiB0cnVlKSB7XG4gICAgICAgICAgbG9nZ2VyLmluZm8oXG4gICAgICAgICAgICBgUGFja2FnZSAke3BhY2thZ2VOYW1lfSBhbHJlYWR5IGluc3RhbGxlZC4gU2tpcHBpbmcgaW5zdGFsbGF0aW9uLmAsXG4gICAgICAgICAgKTtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgbG9nZ2VyLmRlYnVnKFxuICAgICAgICAgICAgYEZvdW5kIHRoZSBwYWNrYWdlIGJ1dCB3aXRoIGEgZGlmZmVyZW50IHZlcnNpb24sIGNvbnRpbnVpbmdgLFxuICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgY29uc3QgbmV3UmVxdWlyZW1lbnRzID1cbiAgICAgICAgcmVxdWlyZW1lbnRzXG4gICAgICAgICAgLnNwbGl0KFwiXFxuXCIpXG4gICAgICAgICAgLmZpbHRlcigobGluZSkgPT4gIWxpbmUuc3RhcnRzV2l0aChwYWNrYWdlTmFtZSkpXG4gICAgICAgICAgLmpvaW4oXCJcXG5cIikgK1xuICAgICAgICBgXFxuJHtwYWNrYWdlTmFtZX0ke3BhY2thZ2VWZXJzaW9uID8gYH49JHtwYWNrYWdlVmVyc2lvbn1gIDogXCJcIn1gO1xuICAgICAgYXdhaXQgZnMud3JpdGVGaWxlKHJlcXVpcmVtZW50c0ZpbGVQYXRoLCBuZXdSZXF1aXJlbWVudHMsIFwidXRmOFwiKTtcblxuICAgICAgYXdhaXQgZXhlYyhcInBpcFwiLCBbXCJpbnN0YWxsXCIsIFwiLXJcIiwgXCJyZXF1aXJlbWVudHMudHh0XCJdLCB7XG4gICAgICAgIGN3ZDogdGhpcy53b3JraW5nRGlyZWN0b3J5LFxuICAgICAgICBzdGRpbzogW1wiaW5oZXJpdFwiLCAxLCAxXSxcbiAgICAgIH0pO1xuXG4gICAgICBjb25zb2xlLmxvZyhcIlBhY2thZ2UgaW5zdGFsbGVkLlwiKTtcbiAgICB9XG4gIH1cblxuICBwdWJsaWMgYXN5bmMgaXNOcG1WZXJzaW9uQXZhaWxhYmxlKFxuICAgIHBhY2thZ2VOYW1lOiBzdHJpbmcsXG4gICAgcGFja2FnZVZlcnNpb246IHN0cmluZyxcbiAgKTogUHJvbWlzZTxib29sZWFuPiB7XG4gICAgbG9nZ2VyLmRlYnVnKFxuICAgICAgYENoZWNraW5nIGlmICR7cGFja2FnZU5hbWV9QCR7cGFja2FnZVZlcnNpb259IGlzIGF2YWlsYWJsZSBmb3IgUHl0aG9uYCxcbiAgICApO1xuICAgIGNvbnN0IHVybCA9IGBodHRwczovL3B5cGkub3JnL3B5cGkvJHtwYWNrYWdlTmFtZX0vJHtwYWNrYWdlVmVyc2lvbn0vanNvbmA7XG4gICAgbG9nZ2VyLmRlYnVnKGBGZXRjaGluZyBwYWNrYWdlIGluZm9ybWF0aW9uIGZvciAke3BhY2thZ2VOYW1lfSBmcm9tICR7dXJsfWApO1xuXG4gICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBmZXRjaCh1cmwpO1xuICAgIGNvbnN0IGpzb24gPSAoYXdhaXQgcmVzcG9uc2UuanNvbigpKSBhcyBhbnk7XG4gICAgbG9nZ2VyLmRlYnVnKFxuICAgICAgYEdvdCByZXNwb25zZSBmcm9tIFB5UEkgZm9yICR7cGFja2FnZU5hbWV9QCR7cGFja2FnZVZlcnNpb259OiAke0pTT04uc3RyaW5naWZ5KFxuICAgICAgICBqc29uLFxuICAgICAgKX1gLFxuICAgICk7XG5cbiAgICBpZiAoanNvbi5pbmZvKSB7XG4gICAgICAvLyBXZSBmb3VuZCB0aGUgdmVyc2lvbiwgc28gaXQgZXhpc3RzXG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9IGVsc2Uge1xuICAgICAgbG9nZ2VyLmRlYnVnKFxuICAgICAgICBgQ291bGQgbm90IGdldCBQeVBJIHBhY2thZ2UgaW5mbywgZ290OiAke0pTT04uc3RyaW5naWZ5KGpzb24pfWAsXG4gICAgICApO1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfVxuXG4gIHB1YmxpYyBhc3luYyBsaXN0UGlwZW52UGFja2FnZXMoKTogUHJvbWlzZTxcbiAgICB7IG5hbWU6IHN0cmluZzsgdmVyc2lvbjogc3RyaW5nIH1bXVxuICA+IHtcbiAgICB0cnkge1xuICAgICAgY29uc3Qgc3Rkb3V0ID0gYXdhaXQgZXhlYyhcbiAgICAgICAgXCJwaXBlbnZcIixcbiAgICAgICAgW1wicnVuXCIsIFwicGlwXCIsIFwibGlzdFwiLCBcIi0tZm9ybWF0PWpzb25cIl0sXG4gICAgICAgIHtcbiAgICAgICAgICBjd2Q6IHRoaXMud29ya2luZ0RpcmVjdG9yeSxcbiAgICAgICAgfSxcbiAgICAgICk7XG4gICAgICBsb2dnZXIuZGVidWcoXG4gICAgICAgIGBMaXN0aW5nIHBpcGVudiBwYWNrYWdlcyB1c2luZyBcInBpcGVudiBydW4gcGlwIGxpc3QgLS1mb3JtYXQ9anNvblwiOiAke3N0ZG91dH1gLFxuICAgICAgKTtcblxuICAgICAgY29uc3QgbGlzdCA9IHBpcFBhY2thZ2VTY2hlbWEucGFyc2UoSlNPTi5wYXJzZShzdGRvdXQpKTtcbiAgICAgIHJldHVybiBsaXN0LmZpbHRlcigoaXRlbSkgPT5cbiAgICAgICAgaXRlbS5uYW1lLnN0YXJ0c1dpdGgoXCJjZGt0Zi1jZGt0Zi1wcm92aWRlclwiKSxcbiAgICAgICk7XG4gICAgfSBjYXRjaCAoZTogYW55KSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgIGBDb3VsZCBub3QgZGV0ZXJtaW5lIGluc3RhbGxlZCBwYWNrYWdlcyB1c2luZyAncGlwZW52IHJ1biBwaXAgbGlzdCAtLWZvcm1hdD1qc29uJzogJHtlLm1lc3NhZ2V9YCxcbiAgICAgICk7XG4gICAgfVxuICB9XG5cbiAgcHVibGljIGFzeW5jIGxpc3RQaXBQYWNrYWdlcygpOiBQcm9taXNlPHsgbmFtZTogc3RyaW5nOyB2ZXJzaW9uOiBzdHJpbmcgfVtdPiB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHN0ZG91dCA9IGF3YWl0IGV4ZWMoXCJwaXBcIiwgW1wibGlzdFwiLCBcIi0tZm9ybWF0PWpzb25cIl0sIHtcbiAgICAgICAgY3dkOiB0aGlzLndvcmtpbmdEaXJlY3RvcnksXG4gICAgICB9KTtcbiAgICAgIGxvZ2dlci5kZWJ1ZyhcbiAgICAgICAgYExpc3RpbmcgcGlwZW52IHBhY2thZ2VzIHVzaW5nIFwicGlwIGxpc3QgLS1mb3JtYXQ9anNvblwiOiAke3N0ZG91dH1gLFxuICAgICAgKTtcblxuICAgICAgY29uc3QgbGlzdCA9IHBpcFBhY2thZ2VTY2hlbWEucGFyc2UoSlNPTi5wYXJzZShzdGRvdXQpKTtcbiAgICAgIHJldHVybiBsaXN0LmZpbHRlcigoaXRlbSkgPT5cbiAgICAgICAgaXRlbS5uYW1lLnN0YXJ0c1dpdGgoXCJjZGt0Zi1jZGt0Zi1wcm92aWRlclwiKSxcbiAgICAgICk7XG4gICAgfSBjYXRjaCAoZTogYW55KSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgIGBDb3VsZCBub3QgZGV0ZXJtaW5lIGluc3RhbGxlZCBwYWNrYWdlcyB1c2luZyAncGlwIGxpc3QgLS1mb3JtYXQ9anNvbic6ICR7ZS5tZXNzYWdlfWAsXG4gICAgICApO1xuICAgIH1cbiAgfVxuXG4gIHB1YmxpYyBhc3luYyBsaXN0UHJvdmlkZXJQYWNrYWdlcygpOiBQcm9taXNlPFxuICAgIHsgbmFtZTogc3RyaW5nOyB2ZXJzaW9uOiBzdHJpbmcgfVtdXG4gID4ge1xuICAgIHJldHVybiB0aGlzLmFwcENvbW1hbmQuaW5jbHVkZXMoXCJwaXBlbnZcIilcbiAgICAgID8gdGhpcy5saXN0UGlwZW52UGFja2FnZXMoKVxuICAgICAgOiB0aGlzLmxpc3RQaXBQYWNrYWdlcygpO1xuICB9XG59XG5cbmNsYXNzIE51Z2V0UGFja2FnZU1hbmFnZXIgZXh0ZW5kcyBQYWNrYWdlTWFuYWdlciB7XG4gIHB1YmxpYyBhc3luYyBhZGRQYWNrYWdlKFxuICAgIHBhY2thZ2VOYW1lOiBzdHJpbmcsXG4gICAgcGFja2FnZVZlcnNpb24/OiBzdHJpbmcsXG4gICk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IGNvbW1hbmQgPSBcImRvdG5ldFwiO1xuICAgIGNvbnN0IGFyZ3MgPSBbXCJhZGRcIiwgXCJwYWNrYWdlXCIsIHBhY2thZ2VOYW1lXTtcbiAgICBpZiAocGFja2FnZVZlcnNpb24pIHtcbiAgICAgIGFyZ3MucHVzaChcIi0tdmVyc2lvblwiLCBwYWNrYWdlVmVyc2lvbik7XG4gICAgfVxuICAgIGNvbnNvbGUubG9nKFxuICAgICAgYEluc3RhbGxpbmcgcGFja2FnZSAke3BhY2thZ2VOYW1lfSBAICR7cGFja2FnZVZlcnNpb259IHVzaW5nIFwiJHtjb21tYW5kfSAke2FyZ3Muam9pbihcbiAgICAgICAgXCIgXCIsXG4gICAgICApfVwiLmAsXG4gICAgKTtcblxuICAgIGF3YWl0IGV4ZWMoY29tbWFuZCwgYXJncywgeyBjd2Q6IHRoaXMud29ya2luZ0RpcmVjdG9yeSB9KTtcblxuICAgIGNvbnNvbGUubG9nKFwiUGFja2FnZSBpbnN0YWxsZWQuXCIpO1xuICB9XG5cbiAgcHVibGljIGFzeW5jIGlzTnBtVmVyc2lvbkF2YWlsYWJsZShcbiAgICBwYWNrYWdlTmFtZTogc3RyaW5nLFxuICAgIHBhY2thZ2VWZXJzaW9uOiBzdHJpbmcsXG4gICk6IFByb21pc2U8Ym9vbGVhbj4ge1xuICAgIGxvZ2dlci5kZWJ1ZyhgQ2hlY2tpbmcgaWYgJHtwYWNrYWdlTmFtZX1AJHtwYWNrYWdlVmVyc2lvbn0gaXMgYXZhaWxhYmxlYCk7XG5cbiAgICBjb25zdCBbb3duZXIsIC4uLnJlc3RdID0gcGFja2FnZU5hbWUuc3BsaXQoXCIuXCIpO1xuICAgIGNvbnN0IGlkID0gcmVzdFtyZXN0Lmxlbmd0aCAtIDFdO1xuICAgIGNvbnN0IHVybCA9IGBodHRwczovL2F6dXJlc2VhcmNoLXVzbmMubnVnZXQub3JnL3F1ZXJ5P3E9b3duZXI6JHtvd25lcn0lMjBpZDoke2lkfSZwcmVyZWxlYXNlPWZhbHNlJnNlbVZlckxldmVsPTIuMC4wYDtcbiAgICBsb2dnZXIuZGVidWcoYEZldGNoaW5nIHBhY2thZ2UgbWV0YWRhdGEgZnJvbSBOdWdldDogJyR7dXJsfSdgKTtcblxuICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgZmV0Y2godXJsKTtcbiAgICBjb25zdCBqc29uID0gKGF3YWl0IHJlc3BvbnNlLmpzb24oKSkgYXMge1xuICAgICAgZGF0YTogeyBpZDogc3RyaW5nOyB2ZXJzaW9uczogeyB2ZXJzaW9uOiBzdHJpbmcgfVtdIH1bXTtcbiAgICB9O1xuICAgIGxvZ2dlci5kZWJ1ZyhcbiAgICAgIGBHb3QgcmVzcG9uc2UgZnJvbSBOdUdldCBmb3IgJHtwYWNrYWdlTmFtZX0gOiAke0pTT04uc3RyaW5naWZ5KGpzb24pfWAsXG4gICAgKTtcblxuICAgIGlmICghanNvbj8uZGF0YT8ubGVuZ3RoKSB7XG4gICAgICByZXR1cm4gZmFsc2U7IC8vIE5vIHBhY2thZ2UgZm91bmRcbiAgICB9XG5cbiAgICBjb25zdCBwYWNrYWdlVmVyc2lvbnMgPVxuICAgICAganNvbi5kYXRhLmZpbmQoKHApID0+IHAuaWQgPT09IHBhY2thZ2VOYW1lKT8udmVyc2lvbnMgPz8gW107XG5cbiAgICBpZiAoIXBhY2thZ2VWZXJzaW9ucy5sZW5ndGgpIHtcbiAgICAgIHJldHVybiBmYWxzZTsgLy8gTm8gcGFja2FnZSByZWxlYXNlIG1hdGNoaW5nIHRoZSBpZCBmb3VuZFxuICAgIH1cblxuICAgIHJldHVybiBwYWNrYWdlVmVyc2lvbnMuc29tZSgodikgPT4gdi52ZXJzaW9uID09PSBwYWNrYWdlVmVyc2lvbik7XG4gIH1cblxuICBwdWJsaWMgYXN5bmMgbGlzdFByb3ZpZGVyUGFja2FnZXMoKTogUHJvbWlzZTxcbiAgICB7IG5hbWU6IHN0cmluZzsgdmVyc2lvbjogc3RyaW5nIH1bXVxuICA+IHtcbiAgICB0cnkge1xuICAgICAgY29uc3Qgc3Rkb3V0ID0gYXdhaXQgZXhlYyhcImRvdG5ldFwiLCBbXCJsaXN0XCIsIFwicGFja2FnZVwiXSwge1xuICAgICAgICBjd2Q6IHRoaXMud29ya2luZ0RpcmVjdG9yeSxcbiAgICAgIH0pO1xuICAgICAgbG9nZ2VyLmRlYnVnKFxuICAgICAgICBgTGlzdGluZyBwaXBlbnYgcGFja2FnZXMgdXNpbmcgXCJkb3RuZXQgbGlzdCBwYWNrYWdlXCI6ICR7c3Rkb3V0fWAsXG4gICAgICApO1xuXG4gICAgICBjb25zdCByZWdleCA9XG4gICAgICAgIC9eXFxzKj5cXHMoSGFzaGlDb3JwXFwuQ2RrdGZcXC5Qcm92aWRlcnNcXC5bXFx3Ll0rKVxccysoKD86XFxkK1xcLil7Mn1cXGQrKD86LVxcUyspPylcXHMrKCg/OlxcZCtcXC4pezJ9XFxkKyg/Oi1cXFMrKT8pXFxzKiQvO1xuXG4gICAgICByZXR1cm4gc3Rkb3V0XG4gICAgICAgIC5zcGxpdChcIlxcblwiKVxuICAgICAgICAubWFwKChsaW5lOiBzdHJpbmcpID0+IHtcbiAgICAgICAgICAvLyBFeGFtcGxlIG91dHB1dDpcbiAgICAgICAgICAvLyBQcm9qZWN0ICdNeVRlcnJhZm9ybVN0YWNrJyBoYXMgdGhlIGZvbGxvd2luZyBwYWNrYWdlIHJlZmVyZW5jZXNcbiAgICAgICAgICAvLyAgW25ldDYuMF06XG4gICAgICAgICAgLy8gIFRvcC1sZXZlbCBQYWNrYWdlICAgICAgUmVxdWVzdGVkICAgUmVzb2x2ZWRcbiAgICAgICAgICAvLyAgPiBIYXNoaUNvcnAuQ2RrdGYgICAgICAwLjAuMCAgICAgICAwLjAuMFxuICAgICAgICAgIC8vIG1hdGNoWzBdID0gZnVsbCBtYXRjaFxuICAgICAgICAgIC8vIG1hdGNoWzFdID0gcGFja2FnZSBuYW1lXG4gICAgICAgICAgLy8gbWF0Y2hbMl0gPSByZXF1ZXN0ZWQgdmVyc2lvblxuICAgICAgICAgIC8vIG1hdGNoWzNdID0gcmVzb2x2ZWQgdmVyc2lvblxuICAgICAgICAgIHJldHVybiByZWdleC5leGVjKGxpbmUpO1xuICAgICAgICB9KVxuICAgICAgICAuZmlsdGVyKChtYXRjaCkgPT4gISFtYXRjaClcbiAgICAgICAgLm1hcCgobWF0Y2gpID0+ICh7IG5hbWU6IG1hdGNoIVsxXSwgdmVyc2lvbjogbWF0Y2ghWzNdIH0pKTtcbiAgICB9IGNhdGNoIChlOiBhbnkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgYENvdWxkIG5vdCBkZXRlcm1pbmUgaW5zdGFsbGVkIHBhY2thZ2VzIHVzaW5nICdkb3RuZXQgbGlzdCBwYWNrYWdlJzogJHtlLm1lc3NhZ2V9YCxcbiAgICAgICk7XG4gICAgfVxuICB9XG59XG5cbmFic3RyYWN0IGNsYXNzIEphdmFQYWNrYWdlTWFuYWdlciBleHRlbmRzIFBhY2thZ2VNYW5hZ2VyIHtcbiAgcHVibGljIGFzeW5jIGlzTnBtVmVyc2lvbkF2YWlsYWJsZShcbiAgICBwYWNrYWdlTmFtZTogc3RyaW5nLFxuICAgIHBhY2thZ2VWZXJzaW9uOiBzdHJpbmcsXG4gICk6IFByb21pc2U8Ym9vbGVhbj4ge1xuICAgIGxvZ2dlci5kZWJ1ZyhgQ2hlY2tpbmcgaWYgJHtwYWNrYWdlTmFtZX1AJHtwYWNrYWdlVmVyc2lvbn0gaXMgYXZhaWxhYmxlYCk7XG5cbiAgICBjb25zdCBwYXJ0cyA9IHBhY2thZ2VOYW1lLnNwbGl0KFwiLlwiKTtcbiAgICBpZiAocGFydHMubGVuZ3RoICE9PSAzKSB7XG4gICAgICB0aHJvdyBFcnJvcnMuSW50ZXJuYWwoXG4gICAgICAgIGBFeHBlY3RlZCBwYWNrYWdlIG5hbWUgdG8gYmUgaW4gZm9ybWF0IFwiZ3JvdXAuYXJ0aWZhY3RcIiwgZS5nLiBcImNvbS5oYXNoaWNvcnAuY2RrdGYtcHJvdmlkZXItZ29vZ2xlXCIsIGdvdDogJHtwYWNrYWdlTmFtZX1gLFxuICAgICAgKTtcbiAgICB9XG5cbiAgICBjb25zdCBwYWNrYWdlSWRlbnRpZmllciA9IHBhcnRzLnBvcCgpO1xuICAgIGNvbnN0IGdyb3VwSWQgPSBwYXJ0cy5qb2luKFwiLlwiKTtcblxuICAgIGNvbnN0IHVybCA9IGBodHRwczovL3NlYXJjaC5tYXZlbi5vcmcvc29scnNlYXJjaC9zZWxlY3Q/cT1nOiR7Z3JvdXBJZH0rQU5EK2E6JHtwYWNrYWdlSWRlbnRpZmllcn0rQU5EK3Y6JHtwYWNrYWdlVmVyc2lvbn0mcm93cz01Jnd0PWpzb25gO1xuICAgIGxvZ2dlci5kZWJ1ZyhcbiAgICAgIGBUcnlpbmcgdG8gZmluZCBwYWNrYWdlIHZlcnNpb24gYnkgcXVlcnlpbmcgTWF2ZW4gQ2VudHJhbCB1bmRlciAnJHt1cmx9J2AsXG4gICAgKTtcbiAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGZldGNoKHVybCk7XG5cbiAgICBjb25zdCBqc29uID0gKGF3YWl0IHJlc3BvbnNlLmpzb24oKSkgYXMgYW55O1xuICAgIGxvZ2dlci5kZWJ1ZyhcbiAgICAgIGBHb3QgcmVzcG9uc2UgZnJvbSB0aGUgTWF2ZW4gcGFja2FnZSBzZWFyY2ggZm9yICR7cGFja2FnZU5hbWV9OiAke0pTT04uc3RyaW5naWZ5KFxuICAgICAgICBqc29uLFxuICAgICAgKX1gLFxuICAgICk7XG5cbiAgICByZXR1cm4gKGpzb24/LnJlc3BvbnNlPy5udW1Gb3VuZCA/PyAwKSA+IDA7XG4gIH1cbn1cblxuY2xhc3MgTWF2ZW5QYWNrYWdlTWFuYWdlciBleHRlbmRzIEphdmFQYWNrYWdlTWFuYWdlciB7XG4gIHB1YmxpYyBhc3luYyBhZGRQYWNrYWdlKFxuICAgIHBhY2thZ2VOYW1lOiBzdHJpbmcsXG4gICAgcGFja2FnZVZlcnNpb24gPSBcIkxBVEVTVFwiLCAvLyB0aGUgbGF0ZXN0IG9wdGlvbiBpcyBkZXByZWNhdGVkIGluIG1hdmVuIDMuNVxuICApOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zb2xlLmxvZyhgQWRkaW5nICR7cGFja2FnZU5hbWV9IEAgJHtwYWNrYWdlVmVyc2lvbn0gdG8gcG9tLnhtbGApO1xuICAgIC8vIEFzc2VydCBwb20ueG1sIGV4aXN0c1xuICAgIGNvbnN0IHBvbVBhdGggPSBwYXRoLmpvaW4odGhpcy53b3JraW5nRGlyZWN0b3J5LCBcInBvbS54bWxcIik7XG4gICAgaWYgKCFleGlzdHNTeW5jKHBvbVBhdGgpKSB7XG4gICAgICB0aHJvdyBFcnJvcnMuVXNhZ2UoXG4gICAgICAgIFwiTm8gcG9tLnhtbCBmb3VuZCBpbiBjdXJyZW50IHdvcmtpbmcgZGlyZWN0b3J5LiBQbGVhc2UgcnVuIHRoZSBjb21tYW5kIGZyb20gdGhlIHJvb3Qgb2YgeW91ciBwcm9qZWN0LlwiLFxuICAgICAgKTtcbiAgICB9XG5cbiAgICBjb25zdCBwb20gPSBhd2FpdCBmcy5yZWFkRmlsZShwb21QYXRoLCBcInV0ZjhcIik7XG4gICAgY29uc3QgcG9tWG1sID0gKGF3YWl0IHhtbDJqcyhwb20sIHt9KSkgYXMgRWxlbWVudDtcblxuICAgIC8vIE11dGF0ZSBkZXBlbmRlbmNpZXNcbiAgICBjb25zdCBuYW1lUGFydHMgPSBwYWNrYWdlTmFtZS5zcGxpdChcIi5cIik7XG4gICAgY29uc3QgZ3JvdXBJZCA9IG5hbWVQYXJ0cy5zbGljZSgwLCBuYW1lUGFydHMubGVuZ3RoIC0gMSkuam9pbihcIi5cIik7XG4gICAgY29uc3QgYXJ0aWZhY3RJZCA9IG5hbWVQYXJ0c1tuYW1lUGFydHMubGVuZ3RoIC0gMV07XG5cbiAgICBjb25zdCBuZXdEZXBlbmRlbmN5ID0gKGF3YWl0IHhtbDJqcyhcbiAgICAgIGA8ZGVwZW5kZW5jeT5cbiAgICA8Z3JvdXBJZD4ke2dyb3VwSWR9PC9ncm91cElkPlxuICAgIDxhcnRpZmFjdElkPiR7YXJ0aWZhY3RJZH08L2FydGlmYWN0SWQ+XG4gICAgPHZlcnNpb24+JHtwYWNrYWdlVmVyc2lvbn08L3ZlcnNpb24+XG48L2RlcGVuZGVuY3k+YCxcbiAgICApKSBhcyBFbGVtZW50O1xuXG4gICAgY29uc3QgZGVwZW5kZW5jaWVzID0gcG9tWG1sLmVsZW1lbnRzXG4gICAgICA/LmZpbmQoKGVsKSA9PiBlbC5uYW1lID09PSBcInByb2plY3RcIilcbiAgICAgID8uZWxlbWVudHM/LmZpbmQoKGVsKSA9PiBlbC5uYW1lID09PSBcImRlcGVuZGVuY2llc1wiKTtcblxuICAgIGlmICghZGVwZW5kZW5jaWVzKSB7XG4gICAgICB0aHJvdyBFcnJvcnMuVXNhZ2UoYENvdWxkIG5vdCBmaW5kIGRlcGVuZGVuY2llcyBzZWN0aW9uIGluIHRoZSBwb20ueG1sYCk7XG4gICAgfVxuICAgIGRlcGVuZGVuY2llcy5lbGVtZW50cyA9IChkZXBlbmRlbmNpZXM/LmVsZW1lbnRzIHx8IFtdKS5maWx0ZXIoXG4gICAgICAoZWwpID0+XG4gICAgICAgIGVsLmVsZW1lbnRzPy5zb21lKFxuICAgICAgICAgIChncm91cCkgPT5cbiAgICAgICAgICAgIGdyb3VwLm5hbWUgPT09IFwiZ3JvdXBJZFwiICYmIGdyb3VwLmVsZW1lbnRzPy5bMF0udGV4dCAhPT0gZ3JvdXBJZCxcbiAgICAgICAgKSB8fFxuICAgICAgICBlbC5lbGVtZW50cz8uc29tZShcbiAgICAgICAgICAoYXJ0aWZhY3QpID0+XG4gICAgICAgICAgICBhcnRpZmFjdC5uYW1lID09PSBcImFydGlmYWN0SWRcIiAmJlxuICAgICAgICAgICAgYXJ0aWZhY3QuZWxlbWVudHM/LlswXS50ZXh0ICE9PSBhcnRpZmFjdElkLFxuICAgICAgICApLFxuICAgICk7XG4gICAgZGVwZW5kZW5jaWVzPy5lbGVtZW50cz8ucHVzaChuZXdEZXBlbmRlbmN5LmVsZW1lbnRzIVswXSk7XG5cbiAgICAvLyBXcml0ZSBuZXcgcG9tLnhtbFxuICAgIGF3YWl0IGZzLndyaXRlRmlsZShwb21QYXRoLCBqczJ4bWwocG9tWG1sLCB7IHNwYWNlczogMiB9KSk7XG5cbiAgICAvLyBJbnN0YWxsXG4gICAgYXdhaXQgZXhlYyhcIm12blwiLCBbXCJpbnN0YWxsXCJdLCB7IGN3ZDogdGhpcy53b3JraW5nRGlyZWN0b3J5IH0pO1xuICAgIGNvbnNvbGUubG9nKFwiUGFja2FnZSBpbnN0YWxsZWQuXCIpO1xuICB9XG5cbiAgcHVibGljIGFzeW5jIGxpc3RQcm92aWRlclBhY2thZ2VzKCk6IFByb21pc2U8XG4gICAgeyBuYW1lOiBzdHJpbmc7IHZlcnNpb246IHN0cmluZyB9W11cbiAgPiB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHBvbVBhdGggPSBwYXRoLmpvaW4odGhpcy53b3JraW5nRGlyZWN0b3J5LCBcInBvbS54bWxcIik7XG4gICAgICBpZiAoIWV4aXN0c1N5bmMocG9tUGF0aCkpIHtcbiAgICAgICAgdGhyb3cgRXJyb3JzLlVzYWdlKFxuICAgICAgICAgIFwiTm8gcG9tLnhtbCBmb3VuZCBpbiBjdXJyZW50IHdvcmtpbmcgZGlyZWN0b3J5LiBQbGVhc2UgcnVuIHRoZSBjb21tYW5kIGZyb20gdGhlIHJvb3Qgb2YgeW91ciBwcm9qZWN0LlwiLFxuICAgICAgICApO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBwb20gPSBhd2FpdCBmcy5yZWFkRmlsZShwb21QYXRoLCBcInV0ZjhcIik7XG4gICAgICBjb25zdCBwb21YbWwgPSAoYXdhaXQgeG1sMmpzKHBvbSwge30pKSBhcyBFbGVtZW50O1xuXG4gICAgICBjb25zdCBkZXBlbmRlbmNpZXMgPVxuICAgICAgICBwb21YbWwuZWxlbWVudHNcbiAgICAgICAgICA/LmZpbmQoKGVsKSA9PiBlbC5uYW1lID09PSBcInByb2plY3RcIilcbiAgICAgICAgICA/LmVsZW1lbnRzPy5maW5kKChlbCkgPT4gZWwubmFtZSA9PT0gXCJkZXBlbmRlbmNpZXNcIik/LmVsZW1lbnRzID8/IFtdO1xuXG4gICAgICByZXR1cm4gZGVwZW5kZW5jaWVzXG4gICAgICAgIC5tYXAoKGRlcCkgPT4gKHtcbiAgICAgICAgICBuYW1lOiBgJHtcbiAgICAgICAgICAgIGRlcC5lbGVtZW50cz8uZmluZCgoZWwpID0+IGVsLm5hbWUgPT09IFwiZ3JvdXBJZFwiKT8uZWxlbWVudHM/LlswXVxuICAgICAgICAgICAgICAudGV4dFxuICAgICAgICAgIH0uJHtcbiAgICAgICAgICAgIGRlcC5lbGVtZW50cz8uZmluZCgoZWwpID0+IGVsLm5hbWUgPT09IFwiYXJ0aWZhY3RJZFwiKT8uZWxlbWVudHM/LlswXVxuICAgICAgICAgICAgICAudGV4dFxuICAgICAgICAgIH1gLFxuICAgICAgICAgIHZlcnNpb246IGRlcC5lbGVtZW50cz8uZmluZCgoZWwpID0+IGVsLm5hbWUgPT09IFwidmVyc2lvblwiKVxuICAgICAgICAgICAgPy5lbGVtZW50cz8uWzBdLnRleHQgYXMgc3RyaW5nLFxuICAgICAgICB9KSlcbiAgICAgICAgLmZpbHRlcigoZGVwKSA9PiBkZXAubmFtZS5zdGFydHNXaXRoKFwiY29tLmhhc2hpY29ycC5jZGt0Zi1wcm92aWRlci1cIikpO1xuICAgIH0gY2F0Y2ggKGU6IGFueSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICBgQ291bGQgbm90IGRldGVybWluZSBpbnN0YWxsZWQgcGFja2FnZXMgcmVhZGluZyB0aGUgcG9tLnhtbDogJHtlLm1lc3NhZ2V9YCxcbiAgICAgICk7XG4gICAgfVxuICB9XG59XG5cbmNsYXNzIEdyYWRsZVBhY2thZ2VNYW5hZ2VyIGV4dGVuZHMgSmF2YVBhY2thZ2VNYW5hZ2VyIHtcbiAgcHVibGljIHN0YXRpYyBpc0dyYWRsZVByb2plY3Qod29ya2luZ0RpcmVjdG9yeTogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIGlzR3JhZGxlUHJvamVjdCh3b3JraW5nRGlyZWN0b3J5KTtcbiAgfVxuXG4gIHB1YmxpYyBhc3luYyBhZGRQYWNrYWdlKFxuICAgIHBhY2thZ2VGUU46IHN0cmluZyxcbiAgICBwYWNrYWdlVmVyc2lvbiA9IFwibGF0ZXN0LnJlbGVhc2VcIixcbiAgKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgYnVpbGRHcmFkbGVQYXRoID0gcGF0aC5qb2luKHRoaXMud29ya2luZ0RpcmVjdG9yeSwgXCJidWlsZC5ncmFkbGVcIik7XG4gICAgY29uc3QgYnVpbGRHcmFkbGUgPSBhd2FpdCBmcy5yZWFkRmlsZShidWlsZEdyYWRsZVBhdGgsIFwidXRmOFwiKTtcbiAgICBjb25zdCBidWlsZEdyYWRsZUxpbmVzID0gYnVpbGRHcmFkbGUuc3BsaXQoL1xccj9cXG4vKTtcblxuICAgIGNvbnN0IGRlcGVuZGVuY2llc1JlZ2V4ID0gL2RlcGVuZGVuY2llc1xccytcXHsvaTtcbiAgICBjb25zdCBkZXBlbmRlbmN5QmxvY2tTdGFydCA9IGJ1aWxkR3JhZGxlTGluZXMuZmluZEluZGV4KChsaW5lKSA9PlxuICAgICAgZGVwZW5kZW5jaWVzUmVnZXgudGVzdChsaW5lKSxcbiAgICApO1xuICAgIGlmIChkZXBlbmRlbmN5QmxvY2tTdGFydCA9PT0gLTEpIHtcbiAgICAgIHRocm93IEVycm9ycy5Vc2FnZShcbiAgICAgICAgXCJDb3VsZCBub3QgZmluZCBkZXBlbmRlbmNpZXMgc2VjdGlvbiBpbiB0aGUgYnVpbGQuZ3JhZGxlXCIsXG4gICAgICApO1xuICAgIH1cblxuICAgIGNvbnN0IHBhY2thZ2VTZWdtZW50cyA9IHBhY2thZ2VGUU4uc3BsaXQoXCIuXCIpO1xuICAgIGNvbnN0IHBhY2thZ2VOYW1lID0gcGFja2FnZVNlZ21lbnRzLnBvcCgpO1xuICAgIGNvbnN0IGdyb3VwTmFtZSA9IHBhY2thZ2VTZWdtZW50cy5qb2luKFwiLlwiKTtcbiAgICBjb25zdCBkZXBlbmRlbmN5U3BlY2lmaWVyID0gYCR7Z3JvdXBOYW1lfToke3BhY2thZ2VOYW1lfWA7XG4gICAgY29uc3QgZGVwZW5kZW5jeUFuZFZlcnNpb25TcGVjaWZpZXIgPSBgJHtkZXBlbmRlbmN5U3BlY2lmaWVyfToke3BhY2thZ2VWZXJzaW9ufWA7XG5cbiAgICBjb25zdCBleGlzdGluZ0RlcGVuZGVuY3kgPSBidWlsZEdyYWRsZUxpbmVzLmZpbmRJbmRleCgobGluZSkgPT5cbiAgICAgIGxpbmUuaW5jbHVkZXMoZGVwZW5kZW5jeVNwZWNpZmllciksXG4gICAgKTtcbiAgICBpZiAoZXhpc3RpbmdEZXBlbmRlbmN5ICE9PSAtMSkge1xuICAgICAgYnVpbGRHcmFkbGVMaW5lcy5zcGxpY2UoZXhpc3RpbmdEZXBlbmRlbmN5LCAxKTtcbiAgICB9XG5cbiAgICBjb25zdCBuZXdQYWNrYWdlRGVwZW5kZW5jeSA9IGBcXHRpbXBsZW1lbnRhdGlvbiAnJHtkZXBlbmRlbmN5QW5kVmVyc2lvblNwZWNpZmllcn0nYDtcbiAgICBidWlsZEdyYWRsZUxpbmVzLnNwbGljZShkZXBlbmRlbmN5QmxvY2tTdGFydCArIDEsIDAsIG5ld1BhY2thZ2VEZXBlbmRlbmN5KTtcblxuICAgIGF3YWl0IGZzLndyaXRlRmlsZShidWlsZEdyYWRsZVBhdGgsIGJ1aWxkR3JhZGxlTGluZXMuam9pbihcIlxcblwiKSk7XG4gIH1cblxuICBwdWJsaWMgYXN5bmMgbGlzdFByb3ZpZGVyUGFja2FnZXMoKTogUHJvbWlzZTxcbiAgICB7IG5hbWU6IHN0cmluZzsgdmVyc2lvbjogc3RyaW5nIH1bXVxuICA+IHtcbiAgICBjb25zdCBkZXBlbmRlbmNpZXMgPSBhd2FpdCBnZXRHcmFkbGVEZXBlbmRlbmNpZXMoKTtcbiAgICBpZiAoIWRlcGVuZGVuY2llcykge1xuICAgICAgdGhyb3cgRXJyb3JzLlVzYWdlKFwiQ291bGQgbm90IGZpbmQgYW55IGRlcGVuZGVuY2llc1wiKTtcbiAgICB9XG5cbiAgICBjb25zdCBkZXBlbmRlbmN5TGlzdCA9IGRlcGVuZGVuY2llc1xuICAgICAgLm1hcCgobGluZSkgPT4gZ2V0RGVwZW5kZW5jeUluZm9ybWF0aW9uRnJvbUxpbmUobGluZSkpXG4gICAgICAuZmlsdGVyKChkZXApID0+IHtcbiAgICAgICAgaWYgKCFkZXApIHtcbiAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGRlcC5uYW1lLmluY2x1ZGVzKFwiY2RrdGYtcHJvdmlkZXItXCIpO1xuICAgICAgfSlcbiAgICAgIC5tYXAoKGRlcCkgPT4gKHtcbiAgICAgICAgbmFtZTogYGNvbS5oYXNoaWNvcnAuJHtkZXAhLm5hbWV9YCxcbiAgICAgICAgdmVyc2lvbjogZGVwIS52ZXJzaW9uLFxuICAgICAgfSkpO1xuXG4gICAgcmV0dXJuIGRlcGVuZGVuY3lMaXN0O1xuICB9XG59XG5cbmNsYXNzIEdvUGFja2FnZU1hbmFnZXIgZXh0ZW5kcyBQYWNrYWdlTWFuYWdlciB7XG4gIHB1YmxpYyBhc3luYyBhZGRQYWNrYWdlKFxuICAgIHBhY2thZ2VOYW1lOiBzdHJpbmcsXG4gICAgcGFja2FnZVZlcnNpb24/OiBzdHJpbmcsXG4gICk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnNvbGUubG9nKGBBZGRpbmcgcGFja2FnZSAke3BhY2thZ2VOYW1lfSBAICR7cGFja2FnZVZlcnNpb259YCk7XG5cbiAgICBjb25zdCBtYWpvclZlcnNpb246IG51bWJlciB8IHVuZGVmaW5lZCA9IHBhY2thZ2VWZXJzaW9uXG4gICAgICA/IHNlbXZlci5tYWpvcihwYWNrYWdlVmVyc2lvbilcbiAgICAgIDogdW5kZWZpbmVkO1xuXG4gICAgbGV0IHZlcnNpb25QYWNrYWdlU3VmZml4ID0gXCJcIjtcbiAgICBpZiAodHlwZW9mIG1ham9yVmVyc2lvbiA9PT0gXCJudW1iZXJcIiAmJiBtYWpvclZlcnNpb24gPiAxKSB7XG4gICAgICB2ZXJzaW9uUGFja2FnZVN1ZmZpeCA9IGAvdiR7bWFqb3JWZXJzaW9ufWA7XG4gICAgfVxuXG4gICAgbG9nZ2VyLmRlYnVnKFxuICAgICAgYFJ1bm5pbmcgJ2dvIGdldCAke3BhY2thZ2VOYW1lfSR7dmVyc2lvblBhY2thZ2VTdWZmaXh9QHYke3BhY2thZ2VWZXJzaW9ufSdgLFxuICAgICk7XG4gICAgLy8gSW5zdGFsbFxuICAgIGF3YWl0IGV4ZWMoXG4gICAgICBcImdvXCIsXG4gICAgICBbXCJnZXRcIiwgYCR7cGFja2FnZU5hbWV9JHt2ZXJzaW9uUGFja2FnZVN1ZmZpeH1AdiR7cGFja2FnZVZlcnNpb259YF0sXG4gICAgICB7XG4gICAgICAgIGN3ZDogdGhpcy53b3JraW5nRGlyZWN0b3J5LFxuICAgICAgfSxcbiAgICApO1xuXG4gICAgY29uc29sZS5sb2coXCJQYWNrYWdlIGluc3RhbGxlZC5cIik7XG4gIH1cblxuICBwdWJsaWMgYXN5bmMgaXNOcG1WZXJzaW9uQXZhaWxhYmxlKFxuICAgIHBhY2thZ2VOYW1lOiBzdHJpbmcsXG4gICAgcGFja2FnZVZlcnNpb246IHN0cmluZyxcbiAgKTogUHJvbWlzZTxib29sZWFuPiB7XG4gICAgbG9nZ2VyLmRlYnVnKGBDaGVja2luZyBpZiAke3BhY2thZ2VOYW1lfUAke3BhY2thZ2VWZXJzaW9ufSBpcyBhdmFpbGFibGVgKTtcblxuICAgIC8vIGUuZy4gZ2l0aHViLmNvbS9jZGt0Zi9jZGt0Zi1wcm92aWRlci1nb29nbGUtZ28vZ29vZ2xlXG4gICAgY29uc3QgcGFydHMgPSBwYWNrYWdlTmFtZS5zcGxpdChcIi9cIik7XG4gICAgaWYgKHBhcnRzLmxlbmd0aCAhPT0gNCkge1xuICAgICAgdGhyb3cgRXJyb3JzLkludGVybmFsKFxuICAgICAgICBgRXhwZWN0aW5nIEdvIHBhY2thZ2UgbmFtZSB0byBiZSBpbiB0aGUgZm9ybWF0IG9mIGdpdGh1Yi5jb20vPG9yZz4vPHJlcG8+LzxwYWNrYWdlPiwgZ290ICR7cGFja2FnZU5hbWV9YCxcbiAgICAgICk7XG4gICAgfVxuXG4gICAgY29uc3Qgb3JnID0gcGFydHNbMV07XG4gICAgY29uc3QgcmVwbyA9IHBhcnRzWzJdO1xuICAgIGNvbnN0IHBhY2thZ2VQYXRoID0gcGFydHNbM107XG5cbiAgICBjb25zdCB1cmwgPSBgaHR0cHM6Ly9hcGkuZ2l0aHViLmNvbS9yZXBvcy8ke29yZ30vJHtyZXBvfS9naXQvcmVmL3RhZ3MvJHtwYWNrYWdlUGF0aH0vdiR7cGFja2FnZVZlcnNpb259YDtcbiAgICBsb2dnZXIuZGVidWcoYEZldGNoaW5nIHRhZ3MgZm9yICR7b3JnfS8ke3JlcG99IGZyb20gJyR7dXJsfSdgKTtcbiAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGZldGNoKHVybCwge1xuICAgICAgaGVhZGVyczoge1xuICAgICAgICBBY2NlcHQ6IFwiYXBwbGljYXRpb24vdm5kLmdpdGh1Yitqc29uXCIsXG4gICAgICAgIFwiVXNlci1BZ2VudFwiOiBcIk9wZW5Db25zdHJ1Y3RzL2Nka3RuLWNsaVwiLFxuICAgICAgICAuLi4oR0lUSFVCX0FQSV9UT0tFTl9DREtURlxuICAgICAgICAgID8geyBBdXRob3JpemF0aW9uOiBgQmVhcmVyICR7R0lUSFVCX0FQSV9UT0tFTl9DREtURn1gIH1cbiAgICAgICAgICA6IHt9KSxcbiAgICAgIH0sXG4gICAgfSk7XG5cbiAgICBjb25zdCBqc29uID0gKGF3YWl0IHJlc3BvbnNlLmpzb24oKSkgYXMgYW55O1xuICAgIGxvZ2dlci5kZWJ1ZyhcbiAgICAgIGBHb3QgcmVzcG9uc2UgZnJvbSBHaXRIdWJzIHJlcG9zaXRvcnkgdGFnIGVuZHBvaW50IGZvciAke3BhY2thZ2VOYW1lfTogJHtKU09OLnN0cmluZ2lmeShcbiAgICAgICAganNvbixcbiAgICAgICl9YCxcbiAgICApO1xuXG4gICAgaWYgKGpzb24gJiYganNvbi5yZWYpIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIGxvZ2dlci5pbmZvKFxuICAgICAgYENvdWxkIG5vdCBmaW5kIHRoZSB0YWcgJHtwYWNrYWdlUGF0aH0vdiR7cGFja2FnZVZlcnNpb259IGluIHRoZSByZXBvc2l0b3J5ICR7b3JnfS8ke3JlcG99OiAke0pTT04uc3RyaW5naWZ5KFxuICAgICAgICBqc29uLFxuICAgICAgKX19YCxcbiAgICApO1xuXG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgcHVibGljIGFzeW5jIGxpc3RQcm92aWRlclBhY2thZ2VzKCk6IFByb21pc2U8XG4gICAgeyBuYW1lOiBzdHJpbmc7IHZlcnNpb246IHN0cmluZyB9W11cbiAgPiB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IGdvU3VtUGF0aCA9IHBhdGguam9pbih0aGlzLndvcmtpbmdEaXJlY3RvcnksIFwiZ28uc3VtXCIpO1xuICAgICAgaWYgKCFleGlzdHNTeW5jKGdvU3VtUGF0aCkpIHtcbiAgICAgICAgdGhyb3cgRXJyb3JzLlVzYWdlKFxuICAgICAgICAgIFwiTm8gZ28uc3VtIGZvdW5kIGluIGN1cnJlbnQgd29ya2luZyBkaXJlY3RvcnkuIFBsZWFzZSBydW4gdGhlIGNvbW1hbmQgZnJvbSB0aGUgcm9vdCBvZiB5b3VyIHByb2plY3QuXCIsXG4gICAgICAgICk7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGdvU3VtID0gYXdhaXQgZnMucmVhZEZpbGUoZ29TdW1QYXRoLCBcInV0ZjhcIik7XG4gICAgICBjb25zdCBkZWR1cGVkUHJvdmlkZXJOYW1lcyA9IG5ldyBTZXQoKTtcblxuICAgICAgcmV0dXJuIGdvU3VtXG4gICAgICAgIC5zcGxpdChcIlxcblwiKVxuICAgICAgICAuZmlsdGVyKFxuICAgICAgICAgIChsaW5lKSA9PlxuICAgICAgICAgICAgbGluZS5zdGFydHNXaXRoKFwiZ2l0aHViLmNvbS9oYXNoaWNvcnAvY2RrdGYtcHJvdmlkZXJcIikgfHxcbiAgICAgICAgICAgIGxpbmUuc3RhcnRzV2l0aChcImdpdGh1Yi5jb20vY2RrdGYvY2RrdGYtcHJvdmlkZXJcIiksXG4gICAgICAgIClcbiAgICAgICAgLm1hcCgobGluZSkgPT4ge1xuICAgICAgICAgIGNvbnN0IHBhcnRzID0gbGluZS5zcGxpdChcIiBcIik7XG4gICAgICAgICAgaWYgKHBhcnRzLmxlbmd0aCAhPT0gMykge1xuICAgICAgICAgICAgdGhyb3cgRXJyb3JzLkludGVybmFsKFxuICAgICAgICAgICAgICBgRXhwZWN0ZWQgbGluZSBpbiBnby5zdW0gdG8gYmUgaW4gdGhlIGZvcm1hdCBvZiAnPHBhY2thZ2U+IDx2ZXJzaW9uPiA8Y2hlY2tzdW0+JywgZ290OiAke2xpbmV9YCxcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgLy8gcGFydFswXSBjb3VsZCBiZSBnaXRodWIuY29tL2F3cy9jb25zdHJ1Y3RzLWdvL2NvbnN0cnVjdHMvdjEwXG4gICAgICAgICAgY29uc3QgbmFtZSA9IHBhcnRzWzBdLnNwbGl0KFwiL1wiKS5zbGljZSgwLCA0KS5qb2luKFwiL1wiKTtcblxuICAgICAgICAgIGNvbnN0IHZlcnNpb24gPSBwYXJ0c1sxXS5zcGxpdChcIi9cIilbMF07XG5cbiAgICAgICAgICBpZiAoZGVkdXBlZFByb3ZpZGVyTmFtZXMuaGFzKG5hbWUpKSB7XG4gICAgICAgICAgICByZXR1cm4geyBuYW1lOiBcIlwiLCB2ZXJzaW9uOiBcIlwiIH07XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgZGVkdXBlZFByb3ZpZGVyTmFtZXMuYWRkKG5hbWUpO1xuXG4gICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIG5hbWUsXG4gICAgICAgICAgICB2ZXJzaW9uLFxuICAgICAgICAgIH07XG4gICAgICAgIH0pXG4gICAgICAgIC5maWx0ZXIoXG4gICAgICAgICAgKHByb3ZpZGVySW5mbykgPT4gISFwcm92aWRlckluZm8ubmFtZSAmJiAhIXByb3ZpZGVySW5mby52ZXJzaW9uLFxuICAgICAgICApO1xuICAgIH0gY2F0Y2ggKGU6IGFueSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICBgQ291bGQgbm90IGRldGVybWluZSBpbnN0YWxsZWQgcGFja2FnZXMgcmVhZGluZyB0aGUgZ28uc3VtOiAke2UubWVzc2FnZX1gLFxuICAgICAgKTtcbiAgICB9XG4gIH1cbn1cbiJdfQ==