@cdktn/hcl2cdk 0.21.0

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 (61) hide show
  1. package/README.md +95 -0
  2. package/ambient.d.ts +14 -0
  3. package/jest.config.js +16 -0
  4. package/lib/__tests__/coerceType.test.d.ts +2 -0
  5. package/lib/__tests__/coerceType.test.js +165 -0
  6. package/lib/__tests__/expressionToTs.test.d.ts +6 -0
  7. package/lib/__tests__/expressionToTs.test.js +693 -0
  8. package/lib/__tests__/expressions.test.d.ts +4 -0
  9. package/lib/__tests__/expressions.test.js +415 -0
  10. package/lib/__tests__/findExpressionType.test.d.ts +6 -0
  11. package/lib/__tests__/findExpressionType.test.js +105 -0
  12. package/lib/__tests__/functions.test.d.ts +6 -0
  13. package/lib/__tests__/functions.test.js +605 -0
  14. package/lib/__tests__/generation.test.d.ts +6 -0
  15. package/lib/__tests__/generation.test.js +45 -0
  16. package/lib/__tests__/jsii-rosetta-workarounds.test.d.ts +2 -0
  17. package/lib/__tests__/jsii-rosetta-workarounds.test.js +86 -0
  18. package/lib/__tests__/partialCode.test.d.ts +6 -0
  19. package/lib/__tests__/partialCode.test.js +390 -0
  20. package/lib/__tests__/terraformSchema.test.d.ts +6 -0
  21. package/lib/__tests__/terraformSchema.test.js +105 -0
  22. package/lib/__tests__/testHelpers.d.ts +7 -0
  23. package/lib/__tests__/testHelpers.js +16 -0
  24. package/lib/coerceType.d.ts +7 -0
  25. package/lib/coerceType.js +240 -0
  26. package/lib/dynamic-blocks.d.ts +8 -0
  27. package/lib/dynamic-blocks.js +44 -0
  28. package/lib/expressions.d.ts +9 -0
  29. package/lib/expressions.js +634 -0
  30. package/lib/function-bindings/functions.d.ts +31 -0
  31. package/lib/function-bindings/functions.generated.d.ts +806 -0
  32. package/lib/function-bindings/functions.generated.js +1142 -0
  33. package/lib/function-bindings/functions.js +73 -0
  34. package/lib/generation.d.ts +26 -0
  35. package/lib/generation.js +676 -0
  36. package/lib/index.d.ts +136 -0
  37. package/lib/index.js +364 -0
  38. package/lib/iteration.d.ts +23 -0
  39. package/lib/iteration.js +87 -0
  40. package/lib/jsii-rosetta-workarounds.d.ts +5 -0
  41. package/lib/jsii-rosetta-workarounds.js +126 -0
  42. package/lib/partialCode.d.ts +11 -0
  43. package/lib/partialCode.js +116 -0
  44. package/lib/provider.d.ts +8 -0
  45. package/lib/provider.js +40 -0
  46. package/lib/references.d.ts +11 -0
  47. package/lib/references.js +141 -0
  48. package/lib/schema.d.ts +297 -0
  49. package/lib/schema.js +81 -0
  50. package/lib/telemetryAllowList.json +24 -0
  51. package/lib/terraformSchema.d.ts +6 -0
  52. package/lib/terraformSchema.js +136 -0
  53. package/lib/types.d.ts +50 -0
  54. package/lib/types.js +3 -0
  55. package/lib/utils.d.ts +6 -0
  56. package/lib/utils.js +25 -0
  57. package/lib/variables.d.ts +10 -0
  58. package/lib/variables.js +172 -0
  59. package/package.json +71 -0
  60. package/package.sh +9 -0
  61. package/tsconfig.json +42 -0
@@ -0,0 +1,676 @@
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.generateConfigType = exports.buildImports = exports.providerConstructImports = exports.wrapCodeInConstructor = exports.addImportForCodeContainer = exports.gen = exports.moduleImports = exports.providerImports = exports.constructsImport = exports.cdktfImport = exports.provider = exports.imports = exports.modules = exports.local = exports.variable = exports.variableTypeToAst = exports.output = exports.resource = exports.backendToExpression = exports.valueToTs = exports.attributeNameToCdktfName = void 0;
30
+ // Copyright (c) HashiCorp, Inc
31
+ // SPDX-License-Identifier: MPL-2.0
32
+ const generator_1 = __importDefault(require("@babel/generator"));
33
+ const template_1 = __importDefault(require("@babel/template"));
34
+ const t = __importStar(require("@babel/types"));
35
+ const prettier_1 = __importDefault(require("prettier"));
36
+ const utils_1 = require("./utils");
37
+ const expressions_1 = require("./expressions");
38
+ const references_1 = require("./references");
39
+ const provider_generator_1 = require("@cdktn/provider-generator");
40
+ const terraformSchema_1 = require("./terraformSchema");
41
+ const commons_1 = require("@cdktn/commons");
42
+ const hcl2json_1 = require("@cdktn/hcl2json");
43
+ const dynamic_blocks_1 = require("./dynamic-blocks");
44
+ const variables_1 = require("./variables");
45
+ const util_1 = require("cdktn/lib/util");
46
+ const partialCode_1 = require("./partialCode");
47
+ function getReference(graph, id) {
48
+ utils_1.logger.debug(`Finding reference for ${id}`);
49
+ const neighbors = graph.outNeighbors(id);
50
+ if (neighbors.length > 0) {
51
+ utils_1.logger.debug(`Found neighbors ${neighbors} for ${id}`);
52
+ const edge = graph.directedEdge(id, neighbors[0]);
53
+ if (edge) {
54
+ utils_1.logger.debug(`Found first edge ${edge} for ${id}`);
55
+ utils_1.logger.debug(`Returning reference ${graph.getEdgeAttribute(edge, "ref")}`);
56
+ return graph.getEdgeAttribute(edge, "ref");
57
+ }
58
+ else {
59
+ utils_1.logger.debug(`Found no edge for ${id}`);
60
+ return undefined;
61
+ }
62
+ }
63
+ else {
64
+ return undefined;
65
+ }
66
+ }
67
+ function attributeNameToCdktfName(name) {
68
+ return (0, provider_generator_1.escapeAttributeName)((0, utils_1.camelCase)(name));
69
+ }
70
+ exports.attributeNameToCdktfName = attributeNameToCdktfName;
71
+ const valueToTs = async (scope, item, path, isModule = false) => {
72
+ switch (typeof item) {
73
+ case "string":
74
+ if ((await (0, references_1.findUsedReferences)(scope.nodeIds, item)).some((ref) => path.startsWith(ref.referencee.id))) {
75
+ return t.stringLiteral(item);
76
+ }
77
+ return await (0, expressions_1.convertTerraformExpressionToTs)(scope, `"${item}"`, () => (0, terraformSchema_1.getDesiredType)(scope, path));
78
+ case "boolean":
79
+ return await (0, expressions_1.convertTerraformExpressionToTs)(scope, `${item}`, () => (0, terraformSchema_1.getDesiredType)(scope, path));
80
+ case "number":
81
+ return await (0, expressions_1.convertTerraformExpressionToTs)(scope, `${item}`, () => (0, terraformSchema_1.getDesiredType)(scope, path));
82
+ case "object": {
83
+ if (item === undefined || item === null) {
84
+ return t.nullLiteral();
85
+ }
86
+ // For iterators and dynamic blocks we put the correct TS expression in the config ahead of time
87
+ if (t.isNode(item) && t.isExpression(item)) {
88
+ return item;
89
+ }
90
+ const attributeType = (0, terraformSchema_1.getTypeAtPath)(scope.providerSchema, path);
91
+ function shouldRemoveArrayBasedOnType(attributeType) {
92
+ if (!attributeType) {
93
+ return false; // The default assumption is we need the array
94
+ }
95
+ // maps and object don't need to be wrapped in an array
96
+ if (Array.isArray(attributeType) &&
97
+ (attributeType[0] === "map" || attributeType[0] === "object")) {
98
+ return true;
99
+ }
100
+ // If it's a block type with max_items = 1 we don't need to wrap it in an array
101
+ if (typeof attributeType === "object" &&
102
+ "max_items" in attributeType &&
103
+ attributeType.max_items === 1) {
104
+ return true;
105
+ }
106
+ return false;
107
+ }
108
+ const unwrappedItem = Array.isArray(item) &&
109
+ (shouldRemoveArrayBasedOnType(attributeType) ||
110
+ path.endsWith("lifecycle") ||
111
+ path.endsWith("connection"))
112
+ ? item[0]
113
+ : item;
114
+ if (Array.isArray(unwrappedItem)) {
115
+ return t.arrayExpression(await Promise.all(unwrappedItem.map((i) => (0, exports.valueToTs)(scope, i, `${path}.[]`))));
116
+ }
117
+ return t.objectExpression((await Promise.all(Object.entries(unwrappedItem).map(async ([key, value]) => {
118
+ if (value === undefined) {
119
+ return undefined;
120
+ }
121
+ if (key === "dynamic") {
122
+ const { for_each, ...others } = value;
123
+ const dynamicRef = Object.keys(others)[0];
124
+ return t.objectProperty(t.identifier(scope.withinOverrideExpression
125
+ ? dynamicRef
126
+ : (0, provider_generator_1.escapeAttributeName)((0, utils_1.camelCase)(dynamicRef))), t.arrayExpression());
127
+ }
128
+ const itemPath = `${path}.${key}`;
129
+ const itemAttributeType = (0, terraformSchema_1.getTypeAtPath)(scope.providerSchema, itemPath);
130
+ const typeMetadata = (0, terraformSchema_1.getTypeAtPath)(scope.providerSchema, itemPath);
131
+ const isSingleItemBlock = typeMetadata &&
132
+ typeof typeMetadata === "object" &&
133
+ Object.prototype.hasOwnProperty.call(typeMetadata, "max_items")
134
+ ? typeMetadata.max_items === 1
135
+ : false;
136
+ const shouldBeArray = typeof value === "object" &&
137
+ !Array.isArray(value) &&
138
+ !(t.isNode(value) && t.isExpression(value)) &&
139
+ !isSingleItemBlock &&
140
+ // Map type attributes must not be wrapped in arrays
141
+ !(0, terraformSchema_1.isMapAttribute)(itemAttributeType) &&
142
+ key !== "tags" &&
143
+ key !== "forEach" &&
144
+ key !== "lifecycle";
145
+ const keepKeyName = !isModule &&
146
+ key !== "depends_on" &&
147
+ !path.includes("lifecycle") &&
148
+ (key === "for_each" ||
149
+ !typeMetadata ||
150
+ (0, terraformSchema_1.isMapAttribute)(attributeType)) &&
151
+ !(path.startsWith("var.") && path.includes("validation"));
152
+ return t.objectProperty(t.stringLiteral(keepKeyName ? key : attributeNameToCdktfName(key)), shouldBeArray
153
+ ? t.arrayExpression([await (0, exports.valueToTs)(scope, value, itemPath)])
154
+ : await (0, exports.valueToTs)(scope, value, itemPath));
155
+ }))).filter((expr) => expr !== undefined));
156
+ }
157
+ }
158
+ throw new Error("Unsupported type " + item);
159
+ };
160
+ exports.valueToTs = valueToTs;
161
+ async function backendToExpression(scope, tf) {
162
+ return (await Promise.all(Object.entries(tf || {}).map(async ([type, [config]]) => {
163
+ const backendIdentifier = (0, utils_1.pascalCase)(`${type}Backend`);
164
+ scope.importables.push({
165
+ constructName: backendIdentifier,
166
+ provider: "cdktn",
167
+ });
168
+ return t.expressionStatement(t.newExpression(t.identifier(backendIdentifier), [
169
+ t.thisExpression(),
170
+ t.objectExpression((await Promise.all(Object.entries(config).map(async ([property, value]) => t.objectProperty(t.identifier((0, utils_1.camelCase)(property)), await (0, exports.valueToTs)(scope, value, "path-for-backends-can-be-ignored"))))).reduce((carry, item) => [...carry, item], [])),
171
+ ]));
172
+ }))).reduce((carry, item) => [...carry, item], []);
173
+ }
174
+ exports.backendToExpression = backendToExpression;
175
+ function addOverrideExpression(variable, path, value, explanatoryComment) {
176
+ const ast = t.expressionStatement(t.callExpression(t.memberExpression(t.identifier(variable), t.identifier("addOverride")), [t.stringLiteral(path), value]));
177
+ if (explanatoryComment) {
178
+ t.addComment(ast, "leading", explanatoryComment);
179
+ }
180
+ return ast;
181
+ }
182
+ function addOverrideLogicalIdExpression(variable, logicalId) {
183
+ const ast = t.expressionStatement(t.callExpression(t.memberExpression(t.identifier(variable), t.identifier("overrideLogicalId")), [t.stringLiteral(logicalId)]));
184
+ t.addComment(ast, "leading", "This allows the Terraform resource name to match the original name. You can remove the call if you don't need them to match.");
185
+ return ast;
186
+ }
187
+ function getRemoteStateType(item) {
188
+ const backendRecord = item.find((val) => val.backend);
189
+ if (backendRecord) {
190
+ const backend = backendRecord.backend;
191
+ switch (backend) {
192
+ case "remote":
193
+ return "";
194
+ case "etcdv3":
195
+ return "_etcd_v3";
196
+ default:
197
+ return `_${backend}`;
198
+ }
199
+ }
200
+ else {
201
+ return "";
202
+ }
203
+ }
204
+ function resourceType(provider, name, item) {
205
+ switch (provider) {
206
+ case "data.terraform":
207
+ return `cdktn.data_terraform_${name.join("_")}${getRemoteStateType(item)}`;
208
+ case "null":
209
+ return `NullProvider.${name.join("_")}`;
210
+ default:
211
+ return `${provider}.${name.join("_")}`;
212
+ }
213
+ }
214
+ function mapConfigPerResourceType(resource, item) {
215
+ // Backends have a slightly different API
216
+ if (resource.startsWith("cdktn.data_terraform_")) {
217
+ return item.config;
218
+ }
219
+ return item;
220
+ }
221
+ const loopComment = `In most cases loops should be handled in the programming language context and
222
+ not inside of the Terraform context. If you are looping over something external, e.g. a variable or a file input
223
+ you should consider using a for loop. If you are looping over something only known to Terraform, e.g. a result of a data source
224
+ you need to keep this like it is.`;
225
+ async function resource(scope, type, key, id, item, graph) {
226
+ const [provider, ...name] = type.split("_");
227
+ const resource = resourceType(provider, name, item);
228
+ if (!provider) {
229
+ throw new Error(`Could not parse resource type '${type}'`);
230
+ }
231
+ let expressions = [];
232
+ const varName = (0, variables_1.variableName)(scope, resource, key);
233
+ const { for_each, count, provisioner, ...config } = item[0];
234
+ const mappedConfig = mapConfigPerResourceType(resource, config);
235
+ let forEachIteratorName;
236
+ if (for_each) {
237
+ forEachIteratorName = (0, variables_1.variableName)(scope, resource, `${key}_for_each_iterator`);
238
+ const referenceAst = await (0, expressions_1.convertTerraformExpressionToTs)(scope, `"${for_each}"`, () => ["list", "dynamic"]);
239
+ scope.importables.push({
240
+ provider: "cdktn",
241
+ constructName: "TerraformIterator",
242
+ });
243
+ const iterator = t.variableDeclaration("const", [
244
+ t.variableDeclarator(t.identifier(forEachIteratorName), t.callExpression(t.memberExpression(t.identifier("TerraformIterator"), t.identifier("fromList")), [referenceAst])),
245
+ ]);
246
+ t.addComment(iterator, "leading", loopComment);
247
+ expressions.push(iterator);
248
+ mappedConfig.forEach = t.identifier(forEachIteratorName);
249
+ }
250
+ let countIteratorName;
251
+ if (count) {
252
+ countIteratorName = (0, variables_1.variableName)(scope, resource, `${key}_count`);
253
+ const referenceAst = await (0, expressions_1.convertTerraformExpressionToTs)(scope, `"${count}"`, () => "number");
254
+ scope.importables.push({
255
+ provider: "cdktn",
256
+ constructName: "TerraformCount",
257
+ });
258
+ const iterator = t.variableDeclaration("const", [
259
+ t.variableDeclarator(t.identifier(countIteratorName), t.callExpression(t.memberExpression(t.identifier("TerraformCount"), t.identifier("of")), [referenceAst])),
260
+ ]);
261
+ t.addComment(iterator, "leading", loopComment);
262
+ mappedConfig.count = t.identifier(countIteratorName);
263
+ expressions.push(iterator);
264
+ }
265
+ const dynBlocks = (0, dynamic_blocks_1.extractDynamicBlocks)(mappedConfig);
266
+ const nestedDynamicBlocks = dynBlocks.filter((block) => (0, dynamic_blocks_1.isNestedDynamicBlock)(dynBlocks, block));
267
+ const dynamicBlocksUsingOverrides = dynBlocks.filter((block) =>
268
+ // nested blocks need overrides
269
+ nestedDynamicBlocks.includes(block) ||
270
+ // blocks that contain nested blocks need them as well
271
+ nestedDynamicBlocks.some((nestedBlock) => nestedBlock.path.startsWith(block.path)));
272
+ // all others can be handled by the CDKTN runtime
273
+ const dynamicBlocksUsingRuntime = dynBlocks.filter((block) => !dynamicBlocksUsingOverrides.includes(block));
274
+ for (const [i, block] of dynamicBlocksUsingRuntime.entries()) {
275
+ const dynamicBlockIteratorName = (0, variables_1.variableName)(scope, resource, `${key}_dynamic_iterator_${i}`);
276
+ const referenceAst = await (0, expressions_1.convertTerraformExpressionToTs)(scope, `"${block.for_each}"`, () => ["list", "dynamic"]);
277
+ scope.importables.push({
278
+ provider: "cdktn",
279
+ constructName: "TerraformIterator",
280
+ });
281
+ const iterator = t.variableDeclaration("const", [
282
+ t.variableDeclarator(t.identifier(dynamicBlockIteratorName), t.callExpression(t.memberExpression(t.identifier("TerraformIterator"), t.identifier("fromList")), [referenceAst])),
283
+ ]);
284
+ t.addComment(iterator, "leading", loopComment);
285
+ expressions.push(iterator);
286
+ const dynamicCallExpression = t.callExpression(t.memberExpression(t.identifier(dynamicBlockIteratorName), t.identifier("dynamic")), [
287
+ await (0, exports.valueToTs)({
288
+ ...scope,
289
+ scopedVariables: {
290
+ [block.scopedVar]: dynamicBlockIteratorName,
291
+ },
292
+ }, (0, partialCode_1.fillWithConfigAccessors)(scope, Array.isArray(block.content) ? block.content[0] : block.content, block.path.replace(block.scopedVar, "")), block.path.replace(block.scopedVar, ""), false),
293
+ ]);
294
+ const parts = block.path
295
+ .replace(`dynamic.${block.scopedVar}`, "")
296
+ .split(".")
297
+ .filter((p) => p.length > 0);
298
+ const parent = parts.reduce((acc, part) => {
299
+ if (Array.isArray(acc) && !Number.isNaN(parseInt(part, 10))) {
300
+ return acc[parseInt(part, 10)];
301
+ }
302
+ else {
303
+ return acc[part];
304
+ }
305
+ }, mappedConfig);
306
+ parent[block.scopedVar] = dynamicCallExpression;
307
+ delete parent.dynamic;
308
+ }
309
+ const overrideReference = dynamicBlocksUsingOverrides.length
310
+ ? {
311
+ start: 0,
312
+ end: 0,
313
+ referencee: {
314
+ id: `${type}.${key}`,
315
+ full: `${type}.${key}`,
316
+ },
317
+ }
318
+ : undefined;
319
+ if (provisioner) {
320
+ mappedConfig.provisioners = await Promise.all(Object.entries(provisioner).flatMap(([type, p]) => p.map((pp) => (0, exports.valueToTs)(scope, { type, ...pp }, "path-for-provisioners-can-be-ignored"))));
321
+ }
322
+ const importGraphId = `import.${resource.replace(".", "_")}.${key}`;
323
+ const importDefinition = graph.hasNode(importGraphId)
324
+ ? graph.getNodeAttribute(importGraphId, "value")
325
+ : undefined;
326
+ expressions = expressions.concat(await asExpression({ ...scope, forEachIteratorName, countIteratorName }, resource, key, mappedConfig, false, false, getReference(graph, id) || overrideReference, importDefinition));
327
+ // Check for dynamic blocks
328
+ expressions = expressions.concat(await Promise.all(dynamicBlocksUsingOverrides.map(async ({ path, for_each, content }) => {
329
+ // We need to let the expression conversion know all available
330
+ // dynamic block names, so we don't replace them. The "dynamic-block"
331
+ // scoped variable indicates to the expression conversion to use the
332
+ // key name instead of an iterator
333
+ const scopedVariablesInPath = Object.fromEntries(path
334
+ .substring(1) // The path starts with a dot that results in an empty split
335
+ .split(".")
336
+ .filter((p) => !["dynamic", "content"].includes(p) && isNaN(parseInt(p)))
337
+ .map((p) => [p, "dynamic-block"]));
338
+ return addOverrideExpression(varName, path.substring(1), // The path starts with a dot that we don't want
339
+ await (0, exports.valueToTs)({
340
+ ...scope,
341
+ withinOverrideExpression: true,
342
+ scopedVariables: scopedVariablesInPath,
343
+ }, {
344
+ for_each,
345
+ content,
346
+ }, "path-for-dynamic-blocks-can-be-ignored"), loopComment);
347
+ })));
348
+ return expressions;
349
+ }
350
+ exports.resource = resource;
351
+ async function asExpression(scope, type, name, config, isModuleImport, isProvider, reference, imported) {
352
+ const { providers, ...otherOptions } = config;
353
+ const constructId = (0, utils_1.uniqueId)(scope.constructs, name);
354
+ const overrideId = !isProvider && constructId !== name;
355
+ const completeObject = (0, partialCode_1.fillWithConfigAccessors)(scope, otherOptions, type);
356
+ const expression = t.newExpression((0, variables_1.constructAst)(scope, type, isModuleImport), [
357
+ t.thisExpression(),
358
+ t.stringLiteral(constructId),
359
+ await (0, exports.valueToTs)(scope, {
360
+ ...completeObject,
361
+ providers: providers && Object.keys(providers).length
362
+ ? Object.entries(providers).map(([key, value]) => ({
363
+ moduleAlias: key,
364
+ provider: value,
365
+ }))
366
+ : undefined,
367
+ }, `${type}`, isModuleImport),
368
+ ]);
369
+ const statements = [];
370
+ const varName = reference
371
+ ? (0, variables_1.referenceToVariableName)(scope, reference)
372
+ : (0, variables_1.variableName)(scope, type, name);
373
+ if (reference || overrideId || imported) {
374
+ statements.push(t.variableDeclaration("const", [
375
+ t.variableDeclarator(t.identifier(varName), expression),
376
+ ]));
377
+ }
378
+ else {
379
+ statements.push(t.expressionStatement(expression));
380
+ }
381
+ if (overrideId) {
382
+ statements.push(addOverrideLogicalIdExpression(varName, name));
383
+ }
384
+ if (imported) {
385
+ // Adds myVar.importFrom("my-arn")
386
+ const importExpression = t.expressionStatement(t.callExpression(t.memberExpression(t.identifier(varName), t.identifier("importFrom")), [t.stringLiteral(imported.id)]));
387
+ if (imported.provider) {
388
+ t.addComment(importExpression, "leading", `This import was configured with a provider. CDKTN does support this, but the cdktn convert command does not yet. Please add the provider reference manually. See https://developer.hashicorp.com/terraform/cdktf/concepts/resources#importing-resources for more information.`);
389
+ }
390
+ statements.push(importExpression);
391
+ }
392
+ return statements;
393
+ }
394
+ async function output(scope, key, _id, item, _graph) {
395
+ const [{ value, description, sensitive }] = item;
396
+ return asExpression(scope, "cdktn.TerraformOutput", key, {
397
+ value,
398
+ description,
399
+ sensitive,
400
+ }, false, false, undefined, undefined);
401
+ }
402
+ exports.output = output;
403
+ async function variableTypeToAst(scope, type) {
404
+ const addVariableTypeToImports = () => scope.importables.push({
405
+ constructName: "VariableType",
406
+ provider: "cdktn",
407
+ });
408
+ function parsedTypeToAst(type) {
409
+ if (hcl2json_1.TFExpressionSyntaxTree.isScopeTraversalExpression(type)) {
410
+ addVariableTypeToImports();
411
+ switch (type.meta.value) {
412
+ case "string":
413
+ return t.identifier("VariableType.STRING");
414
+ case "number":
415
+ return t.identifier("VariableType.NUMBER");
416
+ case "bool":
417
+ return t.identifier("VariableType.BOOL");
418
+ case "any":
419
+ default:
420
+ return t.identifier("VariableType.ANY");
421
+ }
422
+ }
423
+ if (hcl2json_1.TFExpressionSyntaxTree.isFunctionCallExpression(type)) {
424
+ addVariableTypeToImports();
425
+ switch (type.meta.name) {
426
+ case "list":
427
+ case "set":
428
+ case "map":
429
+ case "tuple":
430
+ case "object":
431
+ return t.callExpression(t.identifier(`VariableType.${type.meta.name}`), type.children.map((child) => parsedTypeToAst(child)));
432
+ }
433
+ }
434
+ if (hcl2json_1.TFExpressionSyntaxTree.isObjectExpression(type)) {
435
+ return t.objectExpression(Object.entries(type.meta.items).map(([key, value]) => t.objectProperty(t.stringLiteral(key),
436
+ // This does not deal with complex types nested within objects
437
+ // If such a type is found it will result in an Any type
438
+ // e.g. { foo: list(string) } will result in { foo: any }
439
+ parsedTypeToAst({
440
+ type: "scopeTraversal",
441
+ meta: { value },
442
+ }))));
443
+ }
444
+ addVariableTypeToImports();
445
+ return t.identifier("VariableType.ANY");
446
+ }
447
+ return parsedTypeToAst(await (0, expressions_1.expressionAst)(type));
448
+ }
449
+ exports.variableTypeToAst = variableTypeToAst;
450
+ async function variable(scope, key, id, item, graph) {
451
+ const [{ type, ...props }] = item;
452
+ if (!getReference(graph, id)) {
453
+ return [];
454
+ }
455
+ return asExpression(scope, id, key, { ...props, type: type ? await variableTypeToAst(scope, type) : undefined }, false, false, getReference(graph, id), undefined);
456
+ }
457
+ exports.variable = variable;
458
+ async function local(scope, key, id, item, graph) {
459
+ utils_1.logger.debug(`Initializing local resource ${key} with id ${id}`);
460
+ if (!getReference(graph, id)) {
461
+ utils_1.logger.debug(`No reference found for ${key}`);
462
+ return [];
463
+ }
464
+ return [
465
+ t.variableDeclaration("const", [
466
+ t.variableDeclarator(t.identifier((0, variables_1.variableName)(scope, "local", key)), await (0, exports.valueToTs)(scope, item, "path-for-local-blocks-can-be-ignored")),
467
+ ]),
468
+ ];
469
+ }
470
+ exports.local = local;
471
+ async function modules(scope, key, id, item, graph) {
472
+ const [{ source, version, ...props }] = item;
473
+ const moduleConstraint = new provider_generator_1.TerraformModuleConstraint(source);
474
+ return asExpression(scope, moduleConstraint.className, key, props, true, false, getReference(graph, id), undefined);
475
+ }
476
+ exports.modules = modules;
477
+ async function imports(scope, _id, item, graph) {
478
+ // Move from ${aws_instance.example} to aws_instance.example
479
+ const target = item.to.startsWith("${") && item.to.endsWith("}")
480
+ ? item.to.substring(2, item.to.length - 1)
481
+ : item.to;
482
+ // Check if the import goes into a module
483
+ if (target.startsWith("module.")) {
484
+ return [
485
+ t.addComment(t.emptyStatement(), "leading", `CDKTN does not support imports into modules yet, please remove the import block importing ${item.id} into ${target} from your configuration`),
486
+ ];
487
+ }
488
+ // We now know that the import goes into a resource, e.g. aws_instance.example
489
+ const [resourceTypeIdentifier, resourceName] = target.split(".");
490
+ if (resourceName.includes("[")) {
491
+ return [
492
+ t.addComment(t.emptyStatement(), "leading", `CDKTN does not support imports into resources with count or for_each yet, please remove the import block importing ${item.id} into ${target} from your configuration`),
493
+ ];
494
+ }
495
+ // Check if we have a existing resource config with the given name
496
+ if (graph.hasNode(target)) {
497
+ // We will handle this case in the resource function
498
+ // so we can skip over it
499
+ return [];
500
+ }
501
+ const [provider, ...resourceTypeNameParts] = resourceTypeIdentifier.split("_");
502
+ const constructId = (0, utils_1.uniqueId)(scope.constructs, (0, utils_1.camelCase)(resourceName));
503
+ const constructClass = (0, variables_1.constructAst)(scope, `${provider}.${resourceTypeNameParts.join("_")}`, false);
504
+ return [
505
+ t.expressionStatement(t.callExpression(t.memberExpression(constructClass, t.identifier("generateConfigForImport")), [
506
+ t.thisExpression(),
507
+ t.stringLiteral(constructId),
508
+ t.stringLiteral(item.id),
509
+ ])),
510
+ ];
511
+ }
512
+ exports.imports = imports;
513
+ async function provider(scope, key, id, item, graph) {
514
+ const { version, ...props } = item;
515
+ const importKey = key === "null" ? "NullProvider" : key;
516
+ return asExpression(scope, `${importKey}.${(0, utils_1.pascalCase)(key)}Provider`, key, props, false, true, getReference(graph, id), undefined);
517
+ }
518
+ exports.provider = provider;
519
+ exports.cdktfImport = (0, template_1.default)(`import * as cdktn from "cdktn"`)();
520
+ exports.constructsImport = (0, template_1.default)(`import * as constructs from "constructs"`)();
521
+ const providerImports = (providers) => providers.map((providerName) => {
522
+ const parts = providerName.split("/");
523
+ const name = parts.length > 1 ? parts[1] : parts[0];
524
+ const importName = name === "null" ? "NullProvider" : name;
525
+ return (0, template_1.default)(`import * as ${importName} from "./.gen/providers/${name.replace("./", "")}"`)();
526
+ });
527
+ exports.providerImports = providerImports;
528
+ const moduleImports = (modules) => {
529
+ const uniqueModules = new Set();
530
+ Object.values(modules || {}).map(([module]) => uniqueModules.add(module.source));
531
+ const imports = [];
532
+ uniqueModules.forEach((m) => {
533
+ const moduleConstraint = new provider_generator_1.TerraformModuleConstraint(m);
534
+ imports.push(template_1.default.ast(`import * as ${moduleConstraint.className} from "./.gen/modules/${moduleConstraint.fileName}"`));
535
+ });
536
+ return imports;
537
+ };
538
+ exports.moduleImports = moduleImports;
539
+ async function gen(statements) {
540
+ utils_1.logger.debug(`Generating code for ${JSON.stringify(statements, null, 2)}`);
541
+ const code = prettier_1.default.format((0, generator_1.default)(t.program(statements)).code, {
542
+ parser: "babel",
543
+ });
544
+ utils_1.logger.debug(`Generated code:\n${code}`);
545
+ return code;
546
+ }
547
+ exports.gen = gen;
548
+ function addImportForCodeContainer(scope, codeContainer) {
549
+ switch (codeContainer) {
550
+ case "constructs.Construct":
551
+ scope.importables.push({
552
+ provider: "constructs",
553
+ constructName: "Construct",
554
+ });
555
+ break;
556
+ case "cdktn.TerraformStack":
557
+ scope.importables.push({
558
+ provider: "cdktn",
559
+ constructName: "TerraformStack",
560
+ });
561
+ break;
562
+ case "cdktf.TerraformStack":
563
+ scope.importables.push({
564
+ provider: "cdktf",
565
+ constructName: "TerraformStack",
566
+ });
567
+ break;
568
+ default:
569
+ throw commons_1.Errors.Internal("Unsupported code container: " + codeContainer);
570
+ }
571
+ }
572
+ exports.addImportForCodeContainer = addImportForCodeContainer;
573
+ function wrapCodeInConstructor(codeContainer, code, className, configTypeName) {
574
+ let baseContainerClass;
575
+ switch (codeContainer) {
576
+ case "constructs.Construct":
577
+ baseContainerClass = t.identifier("Construct");
578
+ break;
579
+ case "cdktn.TerraformStack":
580
+ baseContainerClass = t.identifier("TerraformStack");
581
+ break;
582
+ default:
583
+ throw commons_1.Errors.Internal("Unsupported code container: " + codeContainer);
584
+ }
585
+ if (configTypeName) {
586
+ return template_1.default.statement(`
587
+ class %%className%% extends %%base%% {
588
+ constructor(scope: Construct, name: string, config: ${configTypeName}) {
589
+ super(scope, name);
590
+ %%code%%
591
+ }
592
+ }
593
+ `, { syntacticPlaceholders: true, plugins: ["typescript"] })({
594
+ code,
595
+ base: baseContainerClass,
596
+ className: t.identifier(className),
597
+ });
598
+ }
599
+ return template_1.default.statement(`
600
+ class %%className%% extends %%base%% {
601
+ constructor(scope: Construct, name: string) {
602
+ super(scope, name);
603
+ %%code%%
604
+ }
605
+ }
606
+ `, { syntacticPlaceholders: true, plugins: ["typescript"] })({
607
+ code,
608
+ base: baseContainerClass,
609
+ className: t.identifier(className),
610
+ });
611
+ }
612
+ exports.wrapCodeInConstructor = wrapCodeInConstructor;
613
+ const providerConstructImports = (importable) => {
614
+ let provider = importable[0].provider;
615
+ let namespace = importable[0].namespace;
616
+ const names = importable.map((i) => i.constructName);
617
+ if (provider === "cdktn" || provider === "constructs") {
618
+ return (0, template_1.default)(`import { ${names.join(", ")} } from "${provider}"`)();
619
+ }
620
+ if (namespace) {
621
+ namespace = (0, util_1.snakeCase)(namespace).replace(/_/g, "-");
622
+ }
623
+ // Special cases to undo provider names that we override
624
+ if (provider === "NullProvider") {
625
+ provider = "null";
626
+ }
627
+ return (0, template_1.default)(`import { ${names.join(", ")} } from "./.gen/providers/${provider}/${namespace}"`)();
628
+ };
629
+ exports.providerConstructImports = providerConstructImports;
630
+ function buildImports(importables) {
631
+ const groupedImportables = importables.reduce((acc, importable) => {
632
+ const ns = importable.namespace || "";
633
+ // Doing some hacky ordering of the imports to make them look a bit nicer
634
+ const prefix = importable.provider === "constructs"
635
+ ? "1"
636
+ : importable.provider === "cdktn"
637
+ ? "2"
638
+ : importable.provider === "cdktf"
639
+ ? "3"
640
+ : "4";
641
+ const groupName = `${prefix}.${importable.provider}.${ns}`;
642
+ const fullName = `${importable.provider}.${ns}.${importable.constructName}`;
643
+ if (acc[groupName]) {
644
+ const existsAlready = acc[groupName].some((importable) => `${importable.provider}.${ns}.${importable.constructName}` ===
645
+ fullName);
646
+ if (existsAlready) {
647
+ return acc;
648
+ }
649
+ acc[groupName].push(importable);
650
+ acc[groupName].sort();
651
+ }
652
+ else {
653
+ acc[groupName] = [importable];
654
+ }
655
+ return acc;
656
+ }, {});
657
+ let commentAdded = false;
658
+ const constructImports = Object.keys(groupedImportables)
659
+ .sort()
660
+ .map((groupName) => {
661
+ const importStatement = (0, exports.providerConstructImports)(groupedImportables[groupName]);
662
+ if (groupName.startsWith("4.") && !commentAdded) {
663
+ commentAdded = true;
664
+ t.addComment(importStatement, "leading", `\n* Provider bindings are generated by running \`cdktn get\`.
665
+ * See https://cdk.tf/provider-generation for more details.\n`);
666
+ }
667
+ return importStatement;
668
+ });
669
+ return constructImports;
670
+ }
671
+ exports.buildImports = buildImports;
672
+ function generateConfigType(name, config) {
673
+ return t.tsInterfaceDeclaration(t.identifier(name), undefined, undefined, t.tsInterfaceBody(Object.entries(config).map(([key, _value]) => t.tsPropertySignature(t.identifier(key), t.tSTypeAnnotation(t.tsAnyKeyword())))));
674
+ }
675
+ exports.generateConfigType = generateConfigType;
676
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ2VuZXJhdGlvbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbImdlbmVyYXRpb24udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQSwrQkFBK0I7QUFDL0IsbUNBQW1DO0FBQ25DLGlFQUF3QztBQUN4QywrREFBdUM7QUFDdkMsZ0RBQWtDO0FBRWxDLHdEQUFnQztBQVNoQyxtQ0FBa0U7QUFVbEUsK0NBQThFO0FBRTlFLDZDQUFrRDtBQUNsRCxrRUFHbUM7QUFDbkMsdURBSTJCO0FBQzNCLDRDQUEwRTtBQUMxRSw4Q0FBZ0U7QUFDaEUscURBQThFO0FBQzlFLDJDQUlxQjtBQUNyQix5Q0FBMkM7QUFDM0MsK0NBQXdEO0FBRXhELFNBQVMsWUFBWSxDQUFDLEtBQW9CLEVBQUUsRUFBVTtJQUNwRCxjQUFNLENBQUMsS0FBSyxDQUFDLHlCQUF5QixFQUFFLEVBQUUsQ0FBQyxDQUFDO0lBQzVDLE1BQU0sU0FBUyxHQUFHLEtBQUssQ0FBQyxZQUFZLENBQUMsRUFBRSxDQUFDLENBQUM7SUFFekMsSUFBSSxTQUFTLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRSxDQUFDO1FBQ3pCLGNBQU0sQ0FBQyxLQUFLLENBQUMsbUJBQW1CLFNBQVMsUUFBUSxFQUFFLEVBQUUsQ0FBQyxDQUFDO1FBQ3ZELE1BQU0sSUFBSSxHQUFHLEtBQUssQ0FBQyxZQUFZLENBQUMsRUFBRSxFQUFFLFNBQVMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBRWxELElBQUksSUFBSSxFQUFFLENBQUM7WUFDVCxjQUFNLENBQUMsS0FBSyxDQUFDLG9CQUFvQixJQUFJLFFBQVEsRUFBRSxFQUFFLENBQUMsQ0FBQztZQUNuRCxjQUFNLENBQUMsS0FBSyxDQUNWLHVCQUF1QixLQUFLLENBQUMsZ0JBQWdCLENBQUMsSUFBSSxFQUFFLEtBQUssQ0FBQyxFQUFFLENBQzdELENBQUM7WUFDRixPQUFPLEtBQUssQ0FBQyxnQkFBZ0IsQ0FBQyxJ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LGtCQUFrQixDQUNoQyxJQUFZLEVBQ1osTUFBcUM7SUFFckMsT0FBTyxDQUFDLENBQUMsc0JBQXNCLENBQzdCLENBQUMsQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLEVBQ2xCLFNBQVMsRUFDVCxTQUFTLEVBQ1QsQ0FBQyxDQUFDLGVBQWUsQ0FDZixNQUFNLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxFQUFFLE1BQU0sQ0FBQyxFQUFFLEVBQUUsQ0FDM0MsQ0FBQyxDQUFDLG1CQUFtQixDQUNuQixDQUFDLENBQUMsVUFBVSxDQUFDLEdBQUcsQ0FBQyxFQUNqQixDQUFDLENBQUMsZ0JBQWdCLENBQUMsQ0FBQyxDQUFDLFlBQVksRUFBRSxDQUFDLENBQ3JDLENBQ0YsQ0FDRixDQUNGLENBQUM7QUFDSixDQUFDO0FBakJELGdEQWlCQyIsInNvdXJjZXNDb250ZW50IjpbIi8vIENvcHlyaWdodCAoYykgSGFzaGlDb3JwLCBJbmNcbi8vIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBNUEwtMi4wXG5pbXBvcnQgZ2VuZXJhdGUgZnJvbSBcIkBiYWJlbC9nZW5lcmF0b3JcIjtcbmltcG9ydCB0ZW1wbGF0ZSBmcm9tIFwiQGJhYmVsL3RlbXBsYXRlXCI7XG5pbXBvcnQgKiBhcyB0IGZyb20gXCJAYmFiZWwvdHlwZXNcIjtcbmltcG9ydCB7IERpcmVjdGVkR3JhcGggfSBmcm9tIFwiZ3JhcGhvbG9neVwiO1xuaW1wb3J0IHByZXR0aWVyIGZyb20gXCJwcmV0dGllclwiO1xuXG5pbXBvcnQge1xuICBUZXJyYWZvcm1SZXNvdXJjZUJsb2NrLFxuICBQcm9ncmFtU2NvcGUsXG4gIFJlc291cmNlU2NvcGUsXG4gIEltcG9ydGFibGVDb25zdHJ1Y3QsXG4gIEF0dHJpYnV0ZVBhdGgsXG59IGZyb20gXCIuL3R5cGVzXCI7XG5pbXBvcnQgeyBjYW1lbENhc2UsIGxvZ2dlciwgcGFzY2FsQ2FzZSwgdW5pcXVlSWQgfSBmcm9tIFwiLi91dGlsc1wiO1xuaW1wb3J0IHtcbiAgUmVzb3VyY2UsXG4gIFRlcnJhZm9ybUNvbmZpZyxcbiAgTW9kdWxlLFxuICBQcm92aWRlcixcbiAgVmFyaWFibGUsXG4gIE91dHB1dCxcbiAgSW1wb3J0LFxufSBmcm9tIFwiLi9zY2hlbWFcIjtcbmltcG9ydCB7IGNvbnZlcnRUZXJyYWZvcm1FeHByZXNzaW9uVG9UcywgZXhwcmVzc2lvbkFzdCB9IGZyb20gXCIuL2V4cHJlc3Npb25zXCI7XG5pbXBvcnQgeyBSZWZlcmVuY2UgfSBmcm9tIFwiLi90eXBlc1wiO1xuaW1wb3J0IHsgZmluZFVzZWRSZWZlcmVuY2VzIH0gZnJvbSBcIi4vcmVmZXJlbmNlc1wiO1xuaW1wb3J0IHtcbiAgVGVycmFmb3JtTW9kdWxlQ29uc3RyYWludCxcbiAgZXNjYXBlQXR0cmlidXRlTmFtZSxcbn0gZnJvbSBcIkBjZGt0bi9wcm92aWRlci1nZW5lcmF0b3JcIjtcbmltcG9ydCB7XG4gIGdldFR5cGVBdFBhdGgsXG4gIGlzTWFwQXR0cmlidXRlLFxuICBnZXREZXNpcmVkVHlwZSxcbn0gZnJvbSBcIi4vdGVycmFmb3JtU2NoZW1hXCI7XG5pbXBvcnQgeyBFcnJvcnMsIEF0dHJpYnV0ZVR5cGUsIEJsb2NrVHlwZSwgU2NoZW1hIH0gZnJvbSBcIkBjZGt0bi9jb21tb25zXCI7XG5pbXBvcnQgeyBURkV4cHJlc3Npb25TeW50YXhUcmVlIGFzIHRleCB9IGZyb20gXCJAY2RrdG4vaGNsMmpzb25cIjtcbmltcG9ydCB7IGV4dHJhY3REeW5hbWljQmxvY2tzLCBpc05lc3RlZER5bmFtaWNCbG9jayB9IGZyb20gXCIuL2R5bmFtaWMtYmxvY2tzXCI7XG5pbXBvcnQge1xuICBjb25zdHJ1Y3RBc3QsXG4gIHJlZmVyZW5jZVRvVmFyaWFibGVOYW1lLFxuICB2YXJpYWJsZU5hbWUsXG59IGZyb20gXCIuL3ZhcmlhYmxlc1wiO1xuaW1wb3J0IHsgc25ha2VDYXNlIH0gZnJvbSBcImNka3RuL2xpYi91dGlsXCI7XG5pbXBvcnQgeyBmaWxsV2l0aENvbmZpZ0FjY2Vzc29ycyB9IGZyb20gXCIuL3BhcnRpYWxDb2RlXCI7XG5cbmZ1bmN0aW9uIGdldFJlZmVyZW5jZShncmFwaDogRGlyZWN0ZWRHcmFwaCwgaWQ6IHN0cmluZykge1xuICBsb2dnZXIuZGVidWcoYEZpbmRpbmcgcmVmZXJlbmNlIGZvciAke2lkfWApO1xuICBjb25zdCBuZWlnaGJvcnMgPSBncmFwaC5vdXROZWlnaGJvcnMoaWQpO1xuXG4gIGlmIChuZWlnaGJvcnMubGVuZ3RoID4gMCkge1xuICAgIGxvZ2dlci5kZWJ1ZyhgRm91bmQgbmVpZ2hib3JzICR7bmVpZ2hib3JzfSBmb3IgJHtpZH1gKTtcbiAgICBjb25zdCBlZGdlID0gZ3JhcGguZGlyZWN0ZWRFZGdlKGlkLCBuZWlnaGJvcnNbMF0pO1xuXG4gICAgaWYgKGVkZ2UpIHtcbiAgICAgIGxvZ2dlci5kZWJ1ZyhgRm91bmQgZmlyc3QgZWRnZSAke2VkZ2V9IGZvciAke2lkfWApO1xuICAgICAgbG9nZ2VyLmRlYnVnKFxuICAgICAgICBgUmV0dXJuaW5nIHJlZmVyZW5jZSAke2dyYXBoLmdldEVkZ2VBdHRyaWJ1dGUoZWRnZSwgXCJyZWZcIil9YCxcbiAgICAgICk7XG4gICAgICByZXR1cm4gZ3JhcGguZ2V0RWRnZUF0dHJpYnV0ZShlZGdlLCBcInJlZlwiKSBhcyBSZWZlcmVuY2U7XG4gICAgfSBlbHNlIHtcbiAgICAgIGxvZ2dlci5kZWJ1ZyhgRm91bmQgbm8gZWRnZSBmb3IgJHtpZH1gKTtcbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGF0dHJpYnV0ZU5hbWVUb0Nka3RmTmFtZShuYW1lOiBzdHJpbmcpIHtcbiAgcmV0dXJuIGVzY2FwZUF0dHJpYnV0ZU5hbWUoY2FtZWxDYXNlKG5hbWUpKTtcbn1cblxuZXhwb3J0IGNvbnN0IHZhbHVlVG9UcyA9IGFzeW5jIChcbiAgc2NvcGU6IFJlc291cmNlU2NvcGUsXG4gIGl0ZW06IFRlcnJhZm9ybVJlc291cmNlQmxvY2ssXG4gIHBhdGg6IHN0cmluZyxcbiAgaXNNb2R1bGUgPSBmYWxzZSxcbik6IFByb21pc2U8dC5FeHByZXNzaW9uPiA9PiB7XG4gIHN3aXRjaCAodHlwZW9mIGl0ZW0pIHtcbiAgICBjYXNlIFwic3RyaW5nXCI6XG4gICAgICBpZiAoXG4gICAgICAgIChhd2FpdCBmaW5kVXNlZFJlZmVyZW5jZXMoc2NvcGUubm9kZUlkcywgaXRlbSkpLnNvbWUoKHJlZikgPT5cbiAgICAgICAgICBwYXRoLnN0YXJ0c1dpdGgocmVmLnJlZmVyZW5jZWUuaWQpLFxuICAgICAgICApXG4gICAgICApIHtcbiAgICAgICAgcmV0dXJuIHQuc3RyaW5nTGl0ZXJhbChpdGVtKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIGF3YWl0IGNvbnZlcnRUZXJyYWZvcm1FeHByZXNzaW9uVG9UcyhzY29wZSwgYFwiJHtpdGVtfVwiYCwgKCkgPT5cbiAgICAgICAgZ2V0RGVzaXJlZFR5cGUoc2NvcGUsIHBhdGgpLFxuICAgICAgKTtcblxuICAgIGNhc2UgXCJib29sZWFuXCI6XG4gICAgICByZXR1cm4gYXdhaXQgY29udmVydFRlcnJhZm9ybUV4cHJlc3Npb25Ub1RzKHNjb3BlLCBgJHtpdGVtfWAsICgpID0+XG4gICAgICAgIGdldERlc2lyZWRUeXBlKHNjb3BlLCBwYXRoKSxcbiAgICAgICk7XG4gICAgY2FzZSBcIm51bWJlclwiOlxuICAgICAgcmV0dXJuIGF3YWl0IGNvbnZlcnRUZXJyYWZvcm1FeHByZXNzaW9uVG9UcyhzY29wZSwgYCR7aXRlbX1gLCAoKSA9PlxuICAgICAgICBnZXREZXNpcmVkVHlwZShzY29wZSwgcGF0aCksXG4gICAgICApO1xuICAgIGNhc2UgXCJvYmplY3RcIjoge1xuICAgICAgaWYgKGl0ZW0gPT09IHVuZGVmaW5lZCB8fCBpdGVtID09PSBudWxsKSB7XG4gICAgICAgIHJldHVybiB0Lm51bGxMaXRlcmFsKCk7XG4gICAgICB9XG5cbiAgICAgIC8vIEZvciBpdGVyYXRvcnMgYW5kIGR5bmFtaWMgYmxvY2tzIHdlIHB1dCB0aGUgY29ycmVjdCBUUyBleHByZXNzaW9uIGluIHRoZSBjb25maWcgYWhlYWQgb2YgdGltZVxuICAgICAgaWYgKHQuaXNOb2RlKGl0ZW0pICYmIHQuaXNFeHByZXNzaW9uKGl0ZW0pKSB7XG4gICAgICAgIHJldHVybiBpdGVtO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBhdHRyaWJ1dGVUeXBlID0gZ2V0VHlwZUF0UGF0aChzY29wZS5wcm92aWRlclNjaGVtYSwgcGF0aCk7XG5cbiAgICAgIGZ1bmN0aW9uIHNob3VsZFJlbW92ZUFycmF5QmFzZWRPblR5cGUoXG4gICAgICAgIGF0dHJpYnV0ZVR5cGU6IFNjaGVtYSB8IEF0dHJpYnV0ZVR5cGUgfCBCbG9ja1R5cGUgfCBudWxsLFxuICAgICAgKTogYm9vbGVhbiB7XG4gICAgICAgIGlmICghYXR0cmlidXRlVHlwZSkge1xuICAgICAgICAgIHJldHVybiBmYWxzZTsgLy8gVGhlIGRlZmF1bHQgYXNzdW1wdGlvbiBpcyB3ZSBuZWVkIHRoZSBhcnJheVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gbWFwcyBhbmQgb2JqZWN0IGRvbid0IG5lZWQgdG8gYmUgd3JhcHBlZCBpbiBhbiBhcnJheVxuICAgICAgICBpZiAoXG4gICAgICAgICAgQXJyYXkuaXNBcnJheShhdHRyaWJ1dGVUeXBlKSAmJlxuICAgICAgICAgIChhdHRyaWJ1dGVUeXBlWzBdID09PSBcIm1hcFwiIHx8IGF0dHJpYnV0ZVR5cGVbMF0gPT09IFwib2JqZWN0XCIpXG4gICAgICAgICkge1xuICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gSWYgaXQncyBhIGJsb2NrIHR5cGUgd2l0aCBtYXhfaXRlbXMgPSAxIHdlIGRvbid0IG5lZWQgdG8gd3JhcCBpdCBpbiBhbiBhcnJheVxuICAgICAgICBpZiAoXG4gICAgICAgICAgdHlwZW9mIGF0dHJpYnV0ZVR5cGUgPT09IFwib2JqZWN0XCIgJiZcbiAgICAgICAgICBcIm1heF9pdGVtc1wiIGluIGF0dHJpYnV0ZVR5cGUgJiZcbiAgICAgICAgICBhdHRyaWJ1dGVUeXBlLm1heF9pdGVtcyA9PT0gMVxuICAgICAgICApIHtcbiAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgdW53cmFwcGVkSXRlbSA9XG4gICAgICAgIEFycmF5LmlzQXJyYXkoaXRlbSkgJiZcbiAgICAgICAgKHNob3VsZFJlbW92ZUFycmF5QmFzZWRPblR5cGUoYXR0cmlidXRlVHlwZSkgfHxcbiAgICAgICAgICBwYXRoLmVuZHNXaXRoKFwibGlmZWN5Y2xlXCIpIHx8XG4gICAgICAgICAgcGF0aC5lbmRzV2l0aChcImNvbm5lY3Rpb25cIikpXG4gICAgICAgICAgPyBpdGVtWzBdXG4gICAgICAgICAgOiBpdGVtO1xuXG4gICAgICBpZiAoQXJyYXkuaXNBcnJheSh1bndyYXBwZWRJdGVtKSkge1xuICAgICAgICByZXR1cm4gdC5hcnJheUV4cHJlc3Npb24oXG4gICAgICAgICAgYXdhaXQgUHJvbWlzZS5hbGwoXG4gICAgICAgICAgICB1bndyYXBwZWRJdGVtLm1hcCgoaSkgPT4gdmFsdWVUb1RzKHNjb3BlLCBpLCBgJHtwYXRofS5bXWApKSxcbiAgICAgICAgICApLFxuICAgICAgICApO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gdC5vYmplY3RFeHByZXNzaW9uKFxuICAgICAgICAoXG4gICAgICAgICAgYXdhaXQgUHJvbWlzZS5hbGwoXG4gICAgICAgICAgICBPYmplY3QuZW50cmllcyh1bndyYXBwZWRJdGVtKS5tYXAoYXN5bmMgKFtrZXksIHZhbHVlXSkgPT4ge1xuICAgICAgICAgICAgICBpZiAodmFsdWUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICBpZiAoa2V5ID09PSBcImR5bmFtaWNcIikge1xuICAgICAgICAgICAgICAgIGNvbnN0IHsgZm9yX2VhY2gsIC4uLm90aGVycyB9ID0gdmFsdWUgYXMgYW55O1xuICAgICAgICAgICAgICAgIGNvbnN0IGR5bmFtaWNSZWYgPSBPYmplY3Qua2V5cyhvdGhlcnMpWzBdO1xuICAgICAgICAgICAgICAgIHJldHVybiB0Lm9iamVjdFByb3BlcnR5KFxuICAgICAgICAgICAgICAgICAgdC5pZGVudGlmaWVyKFxuICAgICAgICAgICAgICAgICAgICBzY29wZS53aXRoaW5PdmVycmlkZUV4cHJlc3Npb25cbiAgICAgICAgICAgICAgICAgICAgICA/IGR5bmFtaWNSZWZcbiAgICAgICAgICAgICAgICAgICAgICA6IGVzY2FwZUF0dHJpYnV0ZU5hbWUoY2FtZWxDYXNlKGR5bmFtaWNSZWYpKSxcbiAgICAgICAgICAgICAgICAgICksXG4gICAgICAgICAgICAgICAgICB0LmFycmF5RXhwcmVzc2lvbigpLFxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICBjb25zdCBpdGVtUGF0aCA9IGAke3BhdGh9LiR7a2V5fWA7XG4gICAgICAgICAgICAgIGNvbnN0IGl0ZW1BdHRyaWJ1dGVUeXBlID0gZ2V0VHlwZUF0UGF0aChcbiAgICAgICAgICAgICAgICBzY29wZS5wcm92aWRlclNjaGVtYSxcbiAgICAgICAgICAgICAgICBpdGVtUGF0aCxcbiAgICAgICAgICAgICAgKTtcblxuICAgICAgICAgICAgICBjb25zdCB0eXBlTWV0YWRhdGEgPSBnZXRUeXBlQXRQYXRoKFxuICAgICAgICAgICAgICAgIHNjb3BlLnByb3ZpZGVyU2NoZW1hLFxuICAgICAgICAgICAgICAgIGl0ZW1QYXRoLFxuICAgICAgICAgICAgICApO1xuXG4gICAgICAgICAgICAgIGNvbnN0IGlzU2luZ2xlSXRlbUJsb2NrID1cbiAgICAgICAgICAgICAgICB0eXBlTWV0YWRhdGEgJiZcbiAgICAgICAgICAgICAgICB0eXBlb2YgdHlwZU1ldGFkYXRhID09PSBcIm9iamVjdFwiICYmXG4gICAgICAgICAgICAgICAgT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHR5cGVNZXRhZGF0YSwgXCJtYXhfaXRlbXNcIilcbiAgICAgICAgICAgICAgICAgID8gKHR5cGVNZXRhZGF0YSBhcyBhbnkpLm1heF9pdGVtcyA9PT0gMVxuICAgICAgICAgICAgICAgICAgOiBmYWxzZTtcblxuICAgICAgICAgICAgICBjb25zdCBzaG91bGRCZUFycmF5ID1cbiAgICAgICAgICAgICAgICB0eXBlb2YgdmFsdWUgPT09IFwib2JqZWN0XCIgJiZcbiAgICAgICAgICAgICAgICAhQXJyYXkuaXNBcnJheSh2YWx1ZSkgJiZcbiAgICAgICAgICAgICAgICAhKHQuaXNOb2RlKHZhbHVlKSAmJiB0LmlzRXhwcmVzc2lvbih2YWx1ZSkpICYmXG4gICAgICAgICAgICAgICAgIWlzU2luZ2xlSXRlbUJsb2NrICYmXG4gICAgICAgICAgICAgICAgLy8gTWFwIHR5cGUgYXR0cmlidXRlcyBtdXN0IG5vdCBiZSB3cmFwcGVkIGluIGFycmF5c1xuICAgICAgICAgICAgICAgICFpc01hcEF0dHJpYnV0ZShpdGVtQXR0cmlidXRlVHlwZSkgJiZcbiAgICAgICAgICAgICAgICBrZXkgIT09IFwidGFnc1wiICYmXG4gICAgICAgICAgICAgICAga2V5ICE9PSBcImZvckVhY2hcIiAmJlxuICAgICAgICAgICAgICAgIGtleSAhPT0gXCJsaWZlY3ljbGVcIjtcblxuICAgICAgICAgICAgICBjb25zdCBrZWVwS2V5TmFtZTogYm9vbGVhbiA9XG4gICAgICAgICAgICAgICAgIWlzTW9kdWxlICYmXG4gICAgICAgICAgICAgICAga2V5ICE9PSBcImRlcGVuZHNfb25cIiAmJlxuICAgICAgICAgICAgICAgICFwYXRoLmluY2x1ZGVzKFwibGlmZWN5Y2xlXCIpICYmXG4gICAgICAgICAgICAgICAgKGtleSA9PT0gXCJmb3JfZWFjaFwiIHx8XG4gICAgICAgICAgICAgICAgICAhdHlwZU1ldGFkYXRhIHx8XG4gICAgICAgICAgICAgICAgICBpc01hcEF0dHJpYnV0ZShhdHRyaWJ1dGVUeXBlKSkgJiZcbiAgICAgICAgICAgICAgICAhKHBhdGguc3RhcnRzV2l0aChcInZhci5cIikgJiYgcGF0aC5pbmNsdWRlcyhcInZhbGlkYXRpb25cIikpO1xuXG4gICAgICAgICAgICAgIHJldHVybiB0Lm9iamVjdFByb3BlcnR5KFxuICAgICAgICAgICAgICAgIHQuc3RyaW5nTGl0ZXJhbChcbiAgICAgICAgICAgICAgICAgIGtlZXBLZXlOYW1lID8ga2V5IDogYXR0cmlidXRlTmFtZVRvQ2RrdGZOYW1lKGtleSksXG4gICAgICAgICAgICAgICAgKSxcbiAgICAgICAgICAgICAgICBzaG91bGRCZUFycmF5XG4gICAgICAgICAgICAgICAgICA/IHQuYXJyYXlFeHByZXNzaW9uKFthd2FpdCB2YWx1ZVRvVHMoc2NvcGUsIHZhbHVlLCBpdGVtUGF0aCldKVxuICAgICAgICAgICAgICAgICAgOiBhd2FpdCB2YWx1ZVRvVHMoc2NvcGUsIHZhbHVlLCBpdGVtUGF0aCksXG4gICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9KSxcbiAgICAgICAgICApXG4gICAgICAgICkuZmlsdGVyKChleHByKSA9PiBleHByICE9PSB1bmRlZmluZWQpIGFzIHQuT2JqZWN0UHJvcGVydHlbXSxcbiAgICAgICk7XG4gICAgfVxuICB9XG4gIHRocm93IG5ldyBFcnJvcihcIlVuc3VwcG9ydGVkIHR5cGUgXCIgKyBpdGVtKTtcbn07XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBiYWNrZW5kVG9FeHByZXNzaW9uKFxuICBzY29wZTogUHJvZ3JhbVNjb3BlLFxuICB0ZjogVGVycmFmb3JtQ29uZmlnW1wiYmFja2VuZFwiXSxcbik6IFByb21pc2U8dC5TdGF0ZW1lbnRbXT4ge1xuICByZXR1cm4gKFxuICAgIGF3YWl0IFByb21pc2UuYWxsKFxuICAgICAgT2JqZWN0LmVudHJpZXModGYgfHwge30pLm1hcChhc3luYyAoW3R5cGUsIFtjb25maWddXSkgPT4ge1xuICAgICAgICBjb25zdCBiYWNrZW5kSWRlbnRpZmllciA9IHBhc2NhbENhc2UoYCR7dHlwZX1CYWNrZW5kYCk7XG4gICAgICAgIHNjb3BlLmltcG9ydGFibGVzLnB1c2goe1xuICAgICAgICAgIGNvbnN0cnVjdE5hbWU6IGJhY2tlbmRJZGVudGlmaWVyLFxuICAgICAgICAgIHByb3ZpZGVyOiBcImNka3RuXCIsXG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gdC5leHByZXNzaW9uU3RhdGVtZW50KFxuICAgICAgICAgIHQubmV3RXhwcmVzc2lvbih0LmlkZW50aWZpZXIoYmFja2VuZElkZW50aWZpZXIpLCBbXG4gICAgICAgICAgICB0LnRoaXNFeHByZXNzaW9uKCksXG4gICAgICAgICAgICB0Lm9iamVjdEV4cHJlc3Npb24oXG4gICAgICAgICAgICAgIChcbiAgICAgICAgICAgICAgICBhd2FpdCBQcm9taXNlLmFsbChcbiAgICAgICAgICAgICAgICAgIE9iamVjdC5lbnRyaWVzKGNvbmZpZykubWFwKGFzeW5jIChbcHJvcGVydHksIHZhbHVlXSkgPT5cbiAgICAgICAgICAgICAgICAgICAgdC5vYmplY3RQcm9wZXJ0eShcbiAgICAgICAgICAgICAgICAgICAgICB0LmlkZW50aWZpZXIoY2FtZWxDYXNlKHByb3BlcnR5KSksXG4gICAgICAgICAgICAgICAgICAgICAgYXdhaXQgdmFsdWVUb1RzKFxuICAgICAgICAgICAgICAgICAgICAgICAgc2NvcGUsXG4gICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIFwicGF0aC1mb3ItYmFja2VuZHMtY2FuLWJlLWlnbm9yZWRcIixcbiAgICAgICAgICAgICAgICAgICAgICApLFxuICAgICAgICAgICAgICAgICAgICApLFxuICAgICAgICAgICAgICAgICAgKSxcbiAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgICkucmVkdWNlKFxuICAgICAgICAgICAgICAgIChjYXJyeSwgaXRlbSkgPT4gWy4uLmNhcnJ5LCBpdGVtXSxcbiAgICAgICAgICAgICAgICBbXSBhcyB0Lk9iamVjdFByb3BlcnR5W10sXG4gICAgICAgICAgICAgICksXG4gICAgICAgICAgICApLFxuICAgICAgICAgIF0pLFxuICAgICAgICApO1xuICAgICAgfSksXG4gICAgKVxuICApLnJlZHVjZSgoY2FycnksIGl0ZW0pID0+IFsuLi5jYXJyeSwgaXRlbV0sIFtdIGFzIHQuU3RhdGVtZW50W10pO1xufVxuXG5mdW5jdGlvbiBhZGRPdmVycmlkZUV4cHJlc3Npb24oXG4gIHZhcmlhYmxlOiBzdHJpbmcsXG4gIHBhdGg6IHN0cmluZyxcbiAgdmFsdWU6IHQuRXhwcmVzc2lvbixcbiAgZXhwbGFuYXRvcnlDb21tZW50Pzogc3RyaW5nLFxuKSB7XG4gIGNvbnN0IGFzdCA9IHQuZXhwcmVzc2lvblN0YXRlbWVudChcbiAgICB0LmNhbGxFeHByZXNzaW9uKFxuICAgICAgdC5tZW1iZXJFeHByZXNzaW9uKHQuaWRlbnRpZmllcih2YXJpYWJsZSksIHQuaWRlbnRpZmllcihcImFkZE92ZXJyaWRlXCIpKSxcbiAgICAgIFt0LnN0cmluZ0xpdGVyYWwocGF0aCksIHZhbHVlXSxcbiAgICApLFxuICApO1xuXG4gIGlmIChleHBsYW5hdG9yeUNvbW1lbnQpIHtcbiAgICB0LmFkZENvbW1lbnQoYXN0LCBcImxlYWRpbmdcIiwgZXhwbGFuYXRvcnlDb21tZW50KTtcbiAgfVxuXG4gIHJldHVybiBhc3Q7XG59XG5cbmZ1bmN0aW9uIGFkZE92ZXJyaWRlTG9naWNhbElkRXhwcmVzc2lvbih2YXJpYWJsZTogc3RyaW5nLCBsb2dpY2FsSWQ6IHN0cmluZykge1xuICBjb25zdCBhc3QgPSB0LmV4cHJlc3Npb25TdGF0ZW1lbnQoXG4gICAgdC5jYWxsRXhwcmVzc2lvbihcbiAgICAgIHQubWVtYmVyRXhwcmVzc2lvbihcbiAgICAgICAgdC5pZGVudGlmaWVyKHZhcmlhYmxlKSxcbiAgICAgICAgdC5pZGVudGlmaWVyKFwib3ZlcnJpZGVMb2dpY2FsSWRcIiksXG4gICAgICApLFxuICAgICAgW3Quc3RyaW5nTGl0ZXJhbChsb2dpY2FsSWQpXSxcbiAgICApLFxuICApO1xuXG4gIHQuYWRkQ29tbWVudChcbiAgICBhc3QsXG4gICAgXCJsZWFkaW5nXCIsXG4gICAgXCJUaGlzIGFsbG93cyB0aGUgVGVycmFmb3JtIHJlc291cmNlIG5hbWUgdG8gbWF0Y2ggdGhlIG9yaWdpbmFsIG5hbWUuIFlvdSBjYW4gcmVtb3ZlIHRoZSBjYWxsIGlmIHlvdSBkb24ndCBuZWVkIHRoZW0gdG8gbWF0Y2guXCIsXG4gICk7XG5cbiAgcmV0dXJuIGFzdDtcbn1cblxuZnVuY3Rpb24gZ2V0UmVtb3RlU3RhdGVUeXBlKGl0ZW06IFJlc291cmNlKSB7XG4gIGNvbnN0IGJhY2tlbmRSZWNvcmQgPSBpdGVtLmZpbmQoKHZhbCkgPT4gdmFsLmJhY2tlbmQpO1xuICBpZiAoYmFja2VuZFJlY29yZCkge1xuICAgIGNvbnN0IGJhY2tlbmQgPSBiYWNrZW5kUmVjb3JkLmJhY2tlbmQ7XG4gICAgc3dpdGNoIChiYWNrZW5kKSB7XG4gICAgICBjYXNlIFwicmVtb3RlXCI6XG4gICAgICAgIHJldHVybiBcIlwiO1xuICAgICAgY2FzZSBcImV0Y2R2M1wiOlxuICAgICAgICByZXR1cm4gXCJfZXRjZF92M1wiO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgcmV0dXJuIGBfJHtiYWNrZW5kfWA7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIHJldHVybiBcIlwiO1xuICB9XG59XG5cbmZ1bmN0aW9uIHJlc291cmNlVHlwZShwcm92aWRlcjogc3RyaW5nLCBuYW1lOiBzdHJpbmdbXSwgaXRlbTogUmVzb3VyY2UpIHtcbiAgc3dpdGNoIChwcm92aWRlcikge1xuICAgIGNhc2UgXCJkYXRhLnRlcnJhZm9ybVwiOlxuICAgICAgcmV0dXJuIGBjZGt0bi5kYXRhX3RlcnJhZm9ybV8ke25hbWUuam9pbihcIl9cIil9JHtnZXRSZW1vdGVTdGF0ZVR5cGUoXG4gICAgICAgIGl0ZW0sXG4gICAgICApfWA7XG4gICAgY2FzZSBcIm51bGxcIjpcbiAgICAgIHJldHVybiBgTnVsbFByb3ZpZGVyLiR7bmFtZS5qb2luKFwiX1wiKX1gO1xuICAgIGRlZmF1bHQ6XG4gICAgICByZXR1cm4gYCR7cHJvdmlkZXJ9LiR7bmFtZS5qb2luKFwiX1wiKX1gO1xuICB9XG59XG5cbmZ1bmN0aW9uIG1hcENvbmZpZ1BlclJlc291cmNlVHlwZShyZXNvdXJjZTogc3RyaW5nLCBpdGVtOiBSZXNvdXJjZVswXSkge1xuICAvLyBCYWNrZW5kcyBoYXZlIGEgc2xpZ2h0bHkgZGlmZmVyZW50IEFQSVxuICBpZiAocmVzb3VyY2Uuc3RhcnRzV2l0aChcImNka3RuLmRhdGFfdGVycmFmb3JtX1wiKSkge1xuICAgIHJldHVybiBpdGVtLmNvbmZpZztcbiAgfVxuICByZXR1cm4gaXRlbTtcbn1cblxuY29uc3QgbG9vcENvbW1lbnQgPSBgSW4gbW9zdCBjYXNlcyBsb29wcyBzaG91bGQgYmUgaGFuZGxlZCBpbiB0aGUgcHJvZ3JhbW1pbmcgbGFuZ3VhZ2UgY29udGV4dCBhbmRcbm5vdCBpbnNpZGUgb2YgdGhlIFRlcnJhZm9ybSBjb250ZXh0LiBJZiB5b3UgYXJlIGxvb3Bpbmcgb3ZlciBzb21ldGhpbmcgZXh0ZXJuYWwsIGUuZy4gYSB2YXJpYWJsZSBvciBhIGZpbGUgaW5wdXRcbnlvdSBzaG91bGQgY29uc2lkZXIgdXNpbmcgYSBmb3IgbG9vcC4gSWYgeW91IGFyZSBsb29waW5nIG92ZXIgc29tZXRoaW5nIG9ubHkga25vd24gdG8gVGVycmFmb3JtLCBlLmcuIGEgcmVzdWx0IG9mIGEgZGF0YSBzb3VyY2VcbnlvdSBuZWVkIHRvIGtlZXAgdGhpcyBsaWtlIGl0IGlzLmA7XG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gcmVzb3VyY2UoXG4gIHNjb3BlOiBQcm9ncmFtU2NvcGUsXG4gIHR5cGU6IHN0cmluZyxcbiAga2V5OiBzdHJpbmcsXG4gIGlkOiBzdHJpbmcsXG4gIGl0ZW06IFJlc291cmNlLFxuICBncmFwaDogRGlyZWN0ZWRHcmFwaCxcbik6IFByb21pc2U8dC5TdGF0ZW1lbnRbXT4ge1xuICBjb25zdCBbcHJvdmlkZXIsIC4uLm5hbWVdID0gdHlwZS5zcGxpdChcIl9cIik7XG4gIGNvbnN0IHJlc291cmNlID0gcmVzb3VyY2VUeXBlKHByb3ZpZGVyLCBuYW1lLCBpdGVtKTtcblxuICBpZiAoIXByb3ZpZGVyKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBDb3VsZCBub3QgcGFyc2UgcmVzb3VyY2UgdHlwZSAnJHt0eXBlfSdgKTtcbiAgfVxuICBsZXQgZXhwcmVzc2lvbnM6IHQuU3RhdGVtZW50W10gPSBbXTtcbiAgY29uc3QgdmFyTmFtZSA9IHZhcmlhYmxlTmFtZShzY29wZSwgcmVzb3VyY2UsIGtleSk7XG4gIGNvbnN0IHsgZm9yX2VhY2gsIGNvdW50LCBwcm92aXNpb25lciwgLi4uY29uZmlnIH0gPSBpdGVtWzBdO1xuICBjb25zdCBtYXBwZWRDb25maWcgPSBtYXBDb25maWdQZXJSZXNvdXJjZVR5cGUocmVzb3VyY2UsIGNvbmZpZyk7XG5cbiAgbGV0IGZvckVhY2hJdGVyYXRvck5hbWU6IHN0cmluZyB8IHVuZGVmaW5lZDtcbiAgaWYgKGZvcl9lYWNoKSB7XG4gICAgZm9yRWFjaEl0ZXJhdG9yTmFtZSA9IHZhcmlhYmxlTmFtZShcbiAgICAgIHNjb3BlLFxuICAgICAgcmVzb3VyY2UsXG4gICAgICBgJHtrZXl9X2Zvcl9lYWNoX2l0ZXJhdG9yYCxcbiAgICApO1xuICAgIGNvbnN0IHJlZmVyZW5jZUFzdCA9IGF3YWl0IGNvbnZlcnRUZXJyYWZvcm1FeHByZXNzaW9uVG9UcyhcbiAgICAgIHNjb3BlLFxuICAgICAgYFwiJHtmb3JfZWFjaH1cImAsXG4gICAgICAoKSA9PiBbXCJsaXN0XCIsIFwiZHluYW1pY1wiXSxcbiAgICApO1xuXG4gICAgc2NvcGUuaW1wb3J0YWJsZXMucHVzaCh7XG4gICAgICBwcm92aWRlcjogXCJjZGt0blwiLFxuICAgICAgY29uc3RydWN0TmFtZTogXCJUZXJyYWZvcm1JdGVyYXRvclwiLFxuICAgIH0pO1xuXG4gICAgY29uc3QgaXRlcmF0b3IgPSB0LnZhcmlhYmxlRGVjbGFyYXRpb24oXCJjb25zdFwiLCBbXG4gICAgICB0LnZhcmlhYmxlRGVjbGFyYXRvcihcbiAgICAgICAgdC5pZGVudGlmaWVyKGZvckVhY2hJdGVyYXRvck5hbWUpLFxuICAgICAgICB0LmNhbGxFeHByZXNzaW9uKFxuICAgICAgICAgIHQubWVtYmVyRXhwcmVzc2lvbihcbiAgICAgICAgICAgIHQuaWRlbnRpZmllcihcIlRlcnJhZm9ybUl0ZXJhdG9yXCIpLFxuICAgICAgICAgICAgdC5pZGVudGlmaWVyKFwiZnJvbUxpc3RcIiksXG4gICAgICAgICAgKSxcblxuICAgICAgICAgIFtyZWZlcmVuY2VBc3RdLFxuICAgICAgICApLFxuICAgICAgKSxcbiAgICBdKTtcbiAgICB0LmFkZENvbW1lbnQoaXRlcmF0b3IsIFwibGVhZGluZ1wiLCBsb29wQ29tbWVudCk7XG4gICAgZXhwcmVzc2lvbnMucHVzaChpdGVyYXRvcik7XG5cbiAgICBtYXBwZWRDb25maWcuZm9yRWFjaCA9IHQuaWRlbnRpZmllcihmb3JFYWNoSXRlcmF0b3JOYW1lKTtcbiAgfVxuXG4gIGxldCBjb3VudEl0ZXJhdG9yTmFtZTogc3RyaW5nIHwgdW5kZWZpbmVkO1xuICBpZiAoY291bnQpIHtcbiAgICBjb3VudEl0ZXJhdG9yTmFtZSA9IHZhcmlhYmxlTmFtZShzY29wZSwgcmVzb3VyY2UsIGAke2tleX1fY291bnRgKTtcbiAgICBjb25zdCByZWZlcmVuY2VBc3QgPSBhd2FpdCBjb252ZXJ0VGVycmFmb3JtRXhwcmVzc2lvblRvVHMoXG4gICAgICBzY29wZSxcbiAgICAgIGBcIiR7Y291bnR9XCJgLFxuICAgICAgKCkgPT4gXCJudW1iZXJcIixcbiAgICApO1xuXG4gICAgc2NvcGUuaW1wb3J0YWJsZXMucHVzaCh7XG4gICAgICBwcm92aWRlcjogXCJjZGt0blwiLFxuICAgICAgY29uc3RydWN0TmFtZTogXCJUZXJyYWZvcm1Db3VudFwiLFxuICAgIH0pO1xuXG4gICAgY29uc3QgaXRlcmF0b3IgPSB0LnZhcmlhYmxlRGVjbGFyYXRpb24oXCJjb25zdFwiLCBbXG4gICAgICB0LnZhcmlhYmxlRGVjbGFyYXRvcihcbiAgICAgICAgdC5pZGVudGlmaWVyKGNvdW50SXRlcmF0b3JOYW1lKSxcbiAgICAgICAgdC5jYWxsRXhwcmVzc2lvbihcbiAgICAgICAgICB0Lm1lbWJlckV4cHJlc3Npb24oXG4gICAgICAgICAgICB0LmlkZW50aWZpZXIoXCJUZXJyYWZvcm1Db3VudFwiKSxcbiAgICAgICAgICAgIHQuaWRlbnRpZmllcihcIm9mXCIpLFxuICAgICAgICAgICksXG4gICAgICAgICAgW3JlZmVyZW5jZUFzdF0sXG4gICAgICAgICksXG4gICAgICApLFxuICAgIF0pO1xuICAgIHQuYWRkQ29tbWVudChpdGVyYXRvciwgXCJsZWFkaW5nXCIsIGxvb3BDb21tZW50KTtcbiAgICBtYXBwZWRDb25maWcuY291bnQgPSB0LmlkZW50aWZpZXIoY291bnRJdGVyYXRvck5hbWUpO1xuICAgIGV4cHJlc3Npb25zLnB1c2goaXRlcmF0b3IpO1xuICB9XG5cbiAgY29uc3QgZHluQmxvY2tzID0gZXh0cmFjdER5bmFtaWNCbG9ja3MobWFwcGVkQ29uZmlnKTtcbiAgY29uc3QgbmVzdGVkRHluYW1pY0Jsb2NrcyA9IGR5bkJsb2Nrcy5maWx0ZXIoKGJsb2NrKSA9PlxuICAgIGlzTmVzdGVkRHluYW1pY0Jsb2NrKGR5bkJsb2NrcywgYmxvY2spLFxuICApO1xuICBjb25zdCBkeW5hbWljQmxvY2tzVXNpbmdPdmVycmlkZXMgPSBkeW5CbG9ja3MuZmlsdGVyKFxuICAgIChibG9jaykgPT5cbiAgICAgIC8vIG5lc3RlZCBibG9ja3MgbmVlZCBvdmVycmlkZXNcbiAgICAgIG5lc3RlZER5bmFtaWNCbG9ja3MuaW5jbHVkZXMoYmxvY2spIHx8XG4gICAgICAvLyBibG9ja3MgdGhhdCBjb250YWluIG5lc3RlZCBibG9ja3MgbmVlZCB0aGVtIGFzIHdlbGxcbiAgICAgIG5lc3RlZER5bmFtaWNCbG9ja3Muc29tZSgobmVzdGVkQmxvY2spID0+XG4gICAgICAgIG5lc3RlZEJsb2NrLnBhdGguc3RhcnRzV2l0aChibG9jay5wYXRoKSxcbiAgICAgICksXG4gICk7XG4gIC8vIGFsbCBvdGhlcnMgY2FuIGJlIGhhbmRsZWQgYnkgdGhlIENES1ROIHJ1bnRpbWVcbiAgY29uc3QgZHluYW1pY0Jsb2Nrc1VzaW5nUnVudGltZSA9IGR5bkJsb2Nrcy5maWx0ZXIoXG4gICAgKGJsb2NrKSA9PiAhZHluYW1pY0Jsb2Nrc1VzaW5nT3ZlcnJpZGVzLmluY2x1ZGVzKGJsb2NrKSxcbiAgKTtcblxuICBmb3IgKGNvbnN0IFtpLCBibG9ja10gb2YgZHluYW1pY0Jsb2Nrc1VzaW5nUnVudGltZS5lbnRyaWVzKCkpIHtcbiAgICBjb25zdCBkeW5hbWljQmxvY2tJdGVyYXRvck5hbWUgPSB2YXJpYWJsZU5hbWUoXG4gICAgICBzY29wZSxcbiAgICAgIHJlc291cmNlLFxuICAgICAgYCR7a2V5fV9keW5hbWljX2l0ZXJhdG9yXyR7aX1gLFxuICAgICk7XG5cbiAgICBjb25zdCByZWZlcmVuY2VBc3QgPSBhd2FpdCBjb252ZXJ0VGVycmFmb3JtRXhwcmVzc2lvblRvVHMoXG4gICAgICBzY29wZSxcbiAgICAgIGBcIiR7YmxvY2suZm9yX2VhY2h9XCJgLFxuICAgICAgKCkgPT4gW1wibGlzdFwiLCBcImR5bmFtaWNcIl0sXG4gICAgKTtcblxuICAgIHNjb3BlLmltcG9ydGFibGVzLnB1c2goe1xuICAgICAgcHJvdmlkZXI6IFwiY2RrdG5cIixcbiAgICAgIGNvbnN0cnVjdE5hbWU6IFwiVGVycmFmb3JtSXRlcmF0b3JcIixcbiAgICB9KTtcblxuICAgIGNvbnN0IGl0ZXJhdG9yID0gdC52YXJpYWJsZURlY2xhcmF0aW9uKFwiY29uc3RcIiwgW1xuICAgICAgdC52YXJpYWJsZURlY2xhcmF0b3IoXG4gICAgICAgIHQuaWRlbnRpZmllcihkeW5hbWljQmxvY2tJdGVyYXRvck5hbWUpLFxuICAgICAgICB0LmNhbGxFeHByZXNzaW9uKFxuICAgICAgICAgIHQubWVtYmVyRXhwcmVzc2lvbihcbiAgICAgICAgICAgIHQuaWRlbnRpZmllcihcIlRlcnJhZm9ybUl0ZXJhdG9yXCIpLFxuICAgICAgICAgICAgdC5pZGVudGlmaWVyKFwiZnJvbUxpc3RcIiksXG4gICAgICAgICAgKSxcbiAgICAgICAgICBbcmVmZXJlbmNlQXN0XSxcbiAgICAgICAgKSxcbiAgICAgICksXG4gICAgXSk7XG4gICAgdC5hZGRDb21tZW50KGl0ZXJhdG9yLCBcImxlYWRpbmdcIiwgbG9vcENvbW1lbnQpO1xuICAgIGV4cHJlc3Npb25zLnB1c2goaXRlcmF0b3IpO1xuICAgIGNvbnN0IGR5bmFtaWNDYWxsRXhwcmVzc2lvbiA9IHQuY2FsbEV4cHJlc3Npb24oXG4gICAgICB0Lm1lbWJlckV4cHJlc3Npb24oXG4gICAgICAgIHQuaWRlbnRpZmllcihkeW5hbWljQmxvY2tJdGVyYXRvck5hbWUpLFxuICAgICAgICB0LmlkZW50aWZpZXIoXCJkeW5hbWljXCIpLFxuICAgICAgKSxcbiAgICAgIFtcbiAgICAgICAgYXdhaXQgdmFsdWVUb1RzKFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIC4uLnNjb3BlLFxuICAgICAgICAgICAgc2NvcGVkVmFyaWFibGVzOiB7XG4gICAgICAgICAgICAgIFtibG9jay5zY29wZWRWYXJdOiBkeW5hbWljQmxvY2tJdGVyYXRvck5hbWUsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0sXG4gICAgICAgICAgZmlsbFdpdGhDb25maWdBY2Nlc3NvcnMoXG4gICAgICAgICAgICBzY29wZSxcbiAgICAgICAgICAgIEFycmF5LmlzQXJyYXkoYmxvY2suY29udGVudCkgPyBibG9jay5jb250ZW50WzBdIDogYmxvY2suY29udGVudCxcbiAgICAgICAgICAgIGJsb2NrLnBhdGgucmVwbGFjZShibG9jay5zY29wZWRWYXIsIFwiXCIpLFxuICAgICAgICAgICksXG4gICAgICAgICAgYmxvY2sucGF0aC5yZXBsYWNlKGJsb2NrLnNjb3BlZFZhciwgXCJcIiksXG4gICAgICAgICAgZmFsc2UsXG4gICAgICAgICksXG4gICAgICBdLFxuICAgICk7XG5cbiAgICBjb25zdCBwYXJ0cyA9IGJsb2NrLnBhdGhcbiAgICAgIC5yZXBsYWNlKGBkeW5hbWljLiR7YmxvY2suc2NvcGVkVmFyfWAsIFwiXCIpXG4gICAgICAuc3BsaXQoXCIuXCIpXG4gICAgICAuZmlsdGVyKChwKSA9PiBwLmxlbmd0aCA+IDApO1xuXG4gICAgY29uc3QgcGFyZW50ID0gcGFydHMucmVkdWNlKChhY2MsIHBhcnQpID0+IHtcbiAgICAgIGlmIChBcnJheS5pc0FycmF5KGFjYykgJiYgIU51bWJlci5pc05hTihwYXJzZUludChwYXJ0LCAxMCkpKSB7XG4gICAgICAgIHJldHVybiBhY2NbcGFyc2VJbnQocGFydCwgMTApXTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBhY2NbcGFydF07XG4gICAgICB9XG4gICAgfSwgbWFwcGVkQ29uZmlnKTtcbiAgICBwYXJlbnRbYmxvY2suc2NvcGVkVmFyXSA9IGR5bmFtaWNDYWxsRXhwcmVzc2lvbjtcbiAgICBkZWxldGUgcGFyZW50LmR5bmFtaWM7XG4gIH1cblxuICBjb25zdCBvdmVycmlkZVJlZmVyZW5jZSA9IGR5bmFtaWNCbG9ja3NVc2luZ092ZXJyaWRlcy5sZW5ndGhcbiAgICA/IHtcbiAgICAgICAgc3RhcnQ6IDAsXG4gICAgICAgIGVuZDogMCxcbiAgICAgICAgcmVmZXJlbmNlZToge1xuICAgICAgICAgIGlkOiBgJHt0eXBlfS4ke2tleX1gLFxuICAgICAgICAgIGZ1bGw6IGAke3R5cGV9LiR7a2V5fWAsXG4gICAgICAgIH0sXG4gICAgICB9XG4gICAgOiB1bmRlZmluZWQ7XG5cbiAgaWYgKHByb3Zpc2lvbmVyKSB7XG4gICAgbWFwcGVkQ29uZmlnLnByb3Zpc2lvbmVycyA9IGF3YWl0IFByb21pc2UuYWxsKFxuICAgICAgT2JqZWN0LmVudHJpZXMocHJvdmlzaW9uZXIpLmZsYXRNYXAoKFt0eXBlLCBwXTogW3N0cmluZywgYW55XSkgPT5cbiAgICAgICAgcC5tYXAoKHBwOiBSZWNvcmQ8c3RyaW5nLCBhbnk+KSA9PlxuICAgICAgICAgIHZhbHVlVG9UcyhcbiAgICAgICAgICAgIHNjb3BlLFxuICAgICAgICAgICAgeyB0eXBlLCAuLi5wcCB9LFxuICAgICAgICAgICAgXCJwYXRoLWZvci1wcm92aXNpb25lcnMtY2FuLWJlLWlnbm9yZWRcIixcbiAgICAgICAgICApLFxuICAgICAgICApLFxuICAgICAgKSxcbiAgICApO1xuICB9XG5cbiAgY29uc3QgaW1wb3J0R3JhcGhJZCA9IGBpbXBvcnQuJHtyZXNvdXJjZS5yZXBsYWNlKFwiLlwiLCBcIl9cIil9LiR7a2V5fWA7XG4gIGNvbnN0IGltcG9ydERlZmluaXRpb246IEltcG9ydCB8IHVuZGVmaW5lZCA9IGdyYXBoLmhhc05vZGUoaW1wb3J0R3JhcGhJZClcbiAgICA/IGdyYXBoLmdldE5vZGVBdHRyaWJ1dGUoaW1wb3J0R3JhcGhJZCwgXCJ2YWx1ZVwiKVxuICAgIDogdW5kZWZpbmVkO1xuXG4gIGV4cHJlc3Npb25zID0gZXhwcmVzc2lvbnMuY29uY2F0KFxuICAgIGF3YWl0IGFzRXhwcmVzc2lvbihcbiAgICAgIHsgLi4uc2NvcGUsIGZvckVhY2hJdGVyYXRvck5hbWUsIGNvdW50SXRlcmF0b3JOYW1lIH0sXG4gICAgICByZXNvdXJjZSxcbiAgICAgIGtleSxcbiAgICAgIG1hcHBlZENvbmZpZyxcbiAgICAgIGZhbHNlLFxuICAgICAgZmFsc2UsXG4gICAgICBnZXRSZWZlcmVuY2UoZ3JhcGgsIGlkKSB8fCBvdmVycmlkZVJlZmVyZW5jZSxcbiAgICAgIGltcG9ydERlZmluaXRpb24sXG4gICAgKSxcbiAgKTtcblxuICAvLyBDaGVjayBmb3IgZHluYW1pYyBibG9ja3NcbiAgZXhwcmVzc2lvbnMgPSBleHByZXNzaW9ucy5jb25jYXQoXG4gICAgYXdhaXQgUHJvbWlzZS5hbGwoXG4gICAgICBkeW5hbWljQmxvY2tzVXNpbmdPdmVycmlkZXMubWFwKGFzeW5jICh7IHBhdGgsIGZvcl9lYWNoLCBjb250ZW50IH0pID0+IHtcbiAgICAgICAgLy8gV2UgbmVlZCB0byBsZXQgdGhlIGV4cHJlc3Npb24gY29udmVyc2lvbiBrbm93IGFsbCBhdmFpbGFibGVcbiAgICAgICAgLy8gZHluYW1pYyBibG9jayBuYW1lcywgc28gd2UgZG9uJ3QgcmVwbGFjZSB0aGVtLiBUaGUgXCJkeW5hbWljLWJsb2NrXCJcbiAgICAgICAgLy8gc2NvcGVkIHZhcmlhYmxlIGluZGljYXRlcyB0byB0aGUgZXhwcmVzc2lvbiBjb252ZXJzaW9uIHRvIHVzZSB0aGVcbiAgICAgICAgLy8ga2V5IG5hbWUgaW5zdGVhZCBvZiBhbiBpdGVyYXRvclxuICAgICAgICBjb25zdCBzY29wZWRWYXJpYWJsZXNJblBhdGggPSBPYmplY3QuZnJvbUVudHJpZXMoXG4gICAgICAgICAgcGF0aFxuICAgICAgICAgICAgLnN1YnN0cmluZygxKSAvLyBUaGUgcGF0aCBzdGFydHMgd2l0aCBhIGRvdCB0aGF0IHJlc3VsdHMgaW4gYW4gZW1wdHkgc3BsaXRcbiAgICAgICAgICAgIC5zcGxpdChcIi5cIilcbiAgICAgICAgICAgIC5maWx0ZXIoXG4gICAgICAgICAgICAgIChwKSA9PiAhW1wiZHluYW1pY1wiLCBcImNvbnRlbnRcIl0uaW5jbHVkZXMocCkgJiYgaXNOYU4ocGFyc2VJbnQocCkpLFxuICAgICAgICAgICAgKVxuICAgICAgICAgICAgLm1hcCgocCkgPT4gW3AsIFwiZHluYW1pYy1ibG9ja1wiXSksXG4gICAgICAgICk7XG5cbiAgICAgICAgcmV0dXJuIGFkZE92ZXJyaWRlRXhwcmVzc2lvbihcbiAgICAgICAgICB2YXJOYW1lLFxuICAgICAgICAgIHBhdGguc3Vic3RyaW5nKDEpLCAvLyBUaGUgcGF0aCBzdGFydHMgd2l0aCBhIGRvdCB0aGF0IHdlIGRvbid0IHdhbnRcbiAgICAgICAgICBhd2FpdCB2YWx1ZVRvVHMoXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIC4uLnNjb3BlLFxuICAgICAgICAgICAgICB3aXRoaW5PdmVycmlkZUV4cHJlc3Npb246IHRydWUsXG4gICAgICAgICAgICAgIHNjb3BlZFZhcmlhYmxlczogc2NvcGVkVmFyaWFibGVzSW5QYXRoLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgZm9yX2VhY2gsXG4gICAgICAgICAgICAgIGNvbnRlbnQsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgXCJwYXRoLWZvci1keW5hbWljLWJsb2Nrcy1jYW4tYmUtaWdub3JlZFwiLFxuICAgICAgICAgICksXG4gICAgICAgICAgbG9vcENvbW1lbnQsXG4gICAgICAgICk7XG4gICAgICB9KSxcbiAgICApLFxuICApO1xuXG4gIHJldHVybiBleHByZXNzaW9ucztcbn1cblxuYXN5bmMgZnVuY3Rpb24gYXNFeHByZXNzaW9uKFxuICBzY29wZTogUmVzb3VyY2VTY29wZSxcbiAgdHlwZTogc3RyaW5nLFxuICBuYW1lOiBzdHJpbmcsXG4gIGNvbmZpZzogVGVycmFmb3JtUmVzb3VyY2VCbG9jayxcbiAgaXNNb2R1bGVJbXBvcnQ6IGJvb2xlYW4sXG4gIGlzUHJvdmlkZXI6IGJvb2xlYW4sXG4gIHJlZmVyZW5jZT86IFJlZmVyZW5jZSxcbiAgaW1wb3J0ZWQ/OiBJbXBvcnQsXG4pIHtcbiAgY29uc3QgeyBwcm92aWRlcnMsIC4uLm90aGVyT3B0aW9ucyB9ID0gY29uZmlnIGFzIGFueTtcblxuICBjb25zdCBjb25zdHJ1Y3RJZCA9IHVuaXF1ZUlkKHNjb3BlLmNvbnN0cnVjdHMsIG5hbWUpO1xuICBjb25zdCBvdmVycmlkZUlkID0gIWlzUHJvdmlkZXIgJiYgY29uc3RydWN0SWQgIT09IG5hbWU7XG5cbiAgY29uc3QgY29tcGxldGVPYmplY3QgPSBmaWxsV2l0aENvbmZpZ0FjY2Vzc29ycyhzY29wZSwgb3RoZXJPcHRpb25zLCB0eXBlKTtcblxuICBjb25zdCBleHByZXNzaW9uID0gdC5uZXdFeHByZXNzaW9uKFxuICAgIGNvbnN0cnVjdEFzdChzY29wZSwgdHlwZSwgaXNNb2R1bGVJbXBvcnQpLFxuICAgIFtcbiAgICAgIHQudGhpc0V4cHJlc3Npb24oKSxcbiAgICAgIHQuc3RyaW5nTGl0ZXJhbChjb25zdHJ1Y3RJZCksXG5cbiAgICAgIGF3YWl0IHZhbHVlVG9UcyhcbiAgICAgICAgc2NvcGUsXG4gICAgICAgIHtcbiAgICAgICAgICAuLi5jb21wbGV0ZU9iamVjdCxcbiAgICAgICAgICBwcm92aWRlcnM6XG4gICAgICAgICAgICBwcm92aWRlcnMgJiYgT2JqZWN0LmtleXMocHJvdmlkZXJzKS5sZW5ndGhcbiAgICAgICAgICAgICAgPyBPYmplY3QuZW50cmllcyhwcm92aWRlcnMpLm1hcCgoW2tleSwgdmFsdWVdKSA9PiAoe1xuICAgICAgICAgICAgICAgICAgbW9kdWxlQWxpYXM6IGtleSxcbiAgICAgICAgICAgICAgICAgIHByb3ZpZGVyOiB2YWx1ZSxcbiAgICAgICAgICAgICAgICB9KSlcbiAgICAgICAgICAgICAgOiB1bmRlZmluZWQsXG4gICAgICAgIH0sXG4gICAgICAgIGAke3R5cGV9YCxcbiAgICAgICAgaXNNb2R1bGVJbXBvcnQsXG4gICAgICApLFxuICAgIF0sXG4gICk7XG5cbiAgY29uc3Qgc3RhdGVtZW50cyA9IFtdO1xuICBjb25zdCB2YXJOYW1lID0gcmVmZXJlbmNlXG4gICAgPyByZWZlcmVuY2VUb1ZhcmlhYmxlTmFtZShzY29wZSwgcmVmZXJlbmNlKVxuICAgIDogdmFyaWFibGVOYW1lKHNjb3BlLCB0eXBlLCBuYW1lKTtcblxuICBpZiAocmVmZXJlbmNlIHx8IG92ZXJyaWRlSWQgfHwgaW1wb3J0ZWQpIHtcbiAgICBzdGF0ZW1lbnRzLnB1c2goXG4gICAgICB0LnZhcmlhYmxlRGVjbGFyYXRpb24oXCJjb25zdFwiLCBbXG4gICAgICAgIHQudmFyaWFibGVEZWNsYXJhdG9yKHQuaWRlbnRpZmllcih2YXJOYW1lKSwgZXhwcmVzc2lvbiksXG4gICAgICBdKSxcbiAgICApO1xuICB9IGVsc2Uge1xuICAgIHN0YXRlbWVudHMucHVzaCh0LmV4cHJlc3Npb25TdGF0ZW1lbnQoZXhwcmVzc2lvbikpO1xuICB9XG5cbiAgaWYgKG92ZXJyaWRlSWQpIHtcbiAgICBzdGF0ZW1lbnRzLnB1c2goYWRkT3ZlcnJpZGVMb2dpY2FsSWRFeHByZXNzaW9uKHZhck5hbWUsIG5hbWUpKTtcbiAgfVxuXG4gIGlmIChpbXBvcnRlZCkge1xuICAgIC8vIEFkZHMgbXlWYXIuaW1wb3J0RnJvbShcIm15LWFyblwiKVxuICAgIGNvbnN0IGltcG9ydEV4cHJlc3Npb24gPSB0LmV4cHJlc3Npb25TdGF0ZW1lbnQoXG4gICAgICB0LmNhbGxFeHByZXNzaW9uKFxuICAgICAgICB0Lm1lbWJlckV4cHJlc3Npb24odC5pZGVudGlmaWVyKHZhck5hbWUpLCB0LmlkZW50aWZpZXIoXCJpbXBvcnRGcm9tXCIpKSxcbiAgICAgICAgW3Quc3RyaW5nTGl0ZXJhbChpbXBvcnRlZC5pZCldLFxuICAgICAgKSxcbiAgICApO1xuXG4gICAgaWYgKGltcG9ydGVkLnByb3ZpZGVyKSB7XG4gICAgICB0LmFkZENvbW1lbnQoXG4gICAgICAgIGltcG9ydEV4cHJlc3Npb24sXG4gICAgICAgIFwibGVhZGluZ1wiLFxuICAgICAgICBgVGhpcyBpbXBvcnQgd2FzIGNvbmZpZ3VyZWQgd2l0aCBhIHByb3ZpZGVyLiBDREtUTiBkb2VzIHN1cHBvcnQgdGhpcywgYnV0IHRoZSBjZGt0biBjb252ZXJ0IGNvbW1hbmQgZG9lcyBub3QgeWV0LiBQbGVhc2UgYWRkIHRoZSBwcm92aWRlciByZWZlcmVuY2UgbWFudWFsbHkuIFNlZSBodHRwczovL2RldmVsb3Blci5oYXNoaWNvcnAuY29tL3RlcnJhZm9ybS9jZGt0Zi9jb25jZXB0cy9yZXNvdXJjZXMjaW1wb3J0aW5nLXJlc291cmNlcyBmb3IgbW9yZSBpbmZvcm1hdGlvbi5gLFxuICAgICAgKTtcbiAgICB9XG5cbiAgICBzdGF0ZW1lbnRzLnB1c2goaW1wb3J0RXhwcmVzc2lvbik7XG4gIH1cblxuICByZXR1cm4gc3RhdGVtZW50cztcbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIG91dHB1dChcbiAgc2NvcGU6IFByb2dyYW1TY29wZSxcbiAga2V5OiBzdHJpbmcsXG4gIF9pZDogc3RyaW5nLFxuICBpdGVtOiBPdXRwdXQsXG4gIF9ncmFwaDogRGlyZWN0ZWRHcmFwaCxcbikge1xuICBjb25zdCBbeyB2YWx1ZSwgZGVzY3JpcHRpb24sIHNlbnNpdGl2ZSB9XSA9IGl0ZW07XG5cbiAgcmV0dXJuIGFzRXhwcmVzc2lvbihcbiAgICBzY29wZSxcbiAgICBcImNka3RuLlRlcnJhZm9ybU91dHB1dFwiLFxuICAgIGtleSxcbiAgICB7XG4gICAgICB2YWx1ZSxcbiAgICAgIGRlc2NyaXB0aW9uLFxuICAgICAgc2Vuc2l0aXZlLFxuICAgIH0sXG4gICAgZmFsc2UsXG4gICAgZmFsc2UsXG4gICAgdW5kZWZpbmVkLFxuICAgIHVuZGVmaW5lZCxcbiAgKTtcbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHZhcmlhYmxlVHlwZVRvQXN0KFxuICBzY29wZTogUHJvZ3JhbVNjb3BlLFxuICB0eXBlOiBzdHJpbmcsXG4pOiBQcm9taXNlPHQuRXhwcmVzc2lvbj4ge1xuICBjb25zdCBhZGRWYXJpYWJsZVR5cGVUb0ltcG9ydHMgPSAoKSA9PlxuICAgIHNjb3BlLmltcG9ydGFibGVzLnB1c2goe1xuICAgICAgY29uc3RydWN0TmFtZTogXCJWYXJpYWJsZVR5cGVcIixcbiAgICAgIHByb3ZpZGVyOiBcImNka3RuXCIsXG4gICAgfSk7XG5cbiAgZnVuY3Rpb24gcGFyc2VkVHlwZVRvQXN0KHR5cGU6IHRleC5FeHByZXNzaW9uVHlwZSk6IHQuRXhwcmVzc2lvbiB7XG4gICAgaWYgKHRleC5pc1Njb3BlVHJhdmVyc2FsRXhwcmVzc2lvbih0eXBlKSkge1xuICAgICAgYWRkVmFyaWFibGVUeXBlVG9JbXBvcnRzKCk7XG4gICAgICBzd2l0Y2ggKHR5cGUubWV0YS52YWx1ZSkge1xuICAgICAgICBjYXNlIFwic3RyaW5nXCI6XG4gICAgICAgICAgcmV0dXJuIHQuaWRlbnRpZmllcihcIlZhcmlhYmxlVHlwZS5TVFJJTkdcIik7XG4gICAgICAgIGNhc2UgXCJudW1iZXJcIjpcbiAgICAgICAgICByZXR1cm4gdC5pZGVudGlmaWVyKFwiVmFyaWFibGVUeXBlLk5VTUJFUlwiKTtcbiAgICAgICAgY2FzZSBcImJvb2xcIjpcbiAgICAgICAgICByZXR1cm4gdC5pZGVudGlmaWVyKFwiVmFyaWFibGVUeXBlLkJPT0xcIik7XG4gICAgICAgIGNhc2UgXCJhbnlcIjpcbiAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICByZXR1cm4gdC5pZGVudGlmaWVyKFwiVmFyaWFibGVUeXBlLkFOWVwiKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAodGV4LmlzRnVuY3Rpb25DYWxsRXhwcmVzc2lvbih0eXBlKSkge1xuICAgICAgYWRkVmFyaWFibGVUeXBlVG9JbXBvcnRzKCk7XG4gICAgICBzd2l0Y2ggKHR5cGUubWV0YS5uYW1lKSB7XG4gICAgICAgIGNhc2UgXCJsaXN0XCI6XG4gICAgICAgIGNhc2UgXCJzZXRcIjpcbiAgICAgICAgY2FzZSBcIm1hcFwiOlxuICAgICAgICBjYXNlIFwidHVwbGVcIjpcbiAgICAgICAgY2FzZSBcIm9iamVjdFwiOlxuICAgICAgICAgIHJldHVybiB0LmNhbGxFeHByZXNzaW9uKFxuICAgICAgICAgICAgdC5pZGVudGlmaWVyKGBWYXJpYWJsZVR5cGUuJHt0eXBlLm1ldGEubmFtZX1gKSxcbiAgICAgICAgICAgIHR5cGUuY2hpbGRyZW4ubWFwKChjaGlsZCkgPT4gcGFyc2VkVHlwZVRvQXN0KGNoaWxkKSksXG4gICAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAodGV4LmlzT2JqZWN0RXhwcmVzc2lvbih0eXBlKSkge1xuICAgICAgcmV0dXJuIHQub2JqZWN0RXhwcmVzc2lvbihcbiAgICAgICAgT2JqZWN0LmVudHJpZXModHlwZS5tZXRhLml0ZW1zKS5tYXAoKFtrZXksIHZhbHVlXSkgPT5cbiAgICAgICAgICB0Lm9iamVjdFByb3BlcnR5KFxuICAgICAgICAgICAgdC5zdHJpbmdMaXRlcmFsKGtleSksXG4gICAgICAgICAgICAvLyBUaGlzIGRvZXMgbm90IGRlYWwgd2l0aCBjb21wbGV4IHR5cGVzIG5lc3RlZCB3aXRoaW4gb2JqZWN0c1xuICAgICAgICAgICAgLy8gSWYgc3VjaCBhIHR5cGUgaXMgZm91bmQgaXQgd2lsbCByZXN1bHQgaW4gYW4gQW55IHR5cGVcbiAgICAgICAgICAgIC8vIGUuZy4geyBmb286IGxpc3Qoc3RyaW5nKSB9IHdpbGwgcmVzdWx0IGluIHsgZm9vOiBhbnkgfVxuICAgICAgICAgICAgcGFyc2VkVHlwZVRvQXN0KHtcbiAgICAgICAgICAgICAgdHlwZTogXCJzY29wZVRyYXZlcnNhbFwiLFxuICAgICAgICAgICAgICBtZXRhOiB7IHZhbHVlIH0sXG4gICAgICAgICAgICB9IGFzIGFueSksXG4gICAgICAgICAgKSxcbiAgICAgICAgKSxcbiAgICAgICk7XG4gICAgfVxuXG4gICAgYWRkVmFyaWFibGVUeXBlVG9JbXBvcnRzKCk7XG4gICAgcmV0dXJuIHQuaWRlbnRpZmllcihcIlZhcmlhYmxlVHlwZS5BTllcIik7XG4gIH1cblxuICByZXR1cm4gcGFyc2VkVHlwZVRvQXN0KGF3YWl0IGV4cHJlc3Npb25Bc3QodHlwZSkpO1xufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gdmFyaWFibGUoXG4gIHNjb3BlOiBQcm9ncmFtU2NvcGUsXG4gIGtleTogc3RyaW5nLFxuICBpZDogc3RyaW5nLFxuICBpdGVtOiBWYXJpYWJsZSxcbiAgZ3JhcGg6IERpcmVjdGVkR3JhcGgsXG4pIHtcbiAgY29uc3QgW3sgdHlwZSwgLi4ucHJvcHMgfV0gPSBpdGVtO1xuXG4gIGlmICghZ2V0UmVmZXJlbmNlKGdyYXBoLCBpZCkpIHtcbiAgICByZXR1cm4gW107XG4gIH1cblxuICByZXR1cm4gYXNFeHByZXNzaW9uKFxuICAgIHNjb3BlLFxuICAgIGlkLFxuICAgIGtleSxcbiAgICB7IC4uLnByb3BzLCB0eXBlOiB0eXBlID8gYXdhaXQgdmFyaWFibGVUeXBlVG9Bc3Qoc2NvcGUsIHR5cGUpIDogdW5kZWZpbmVkIH0sXG4gICAgZmFsc2UsXG4gICAgZmFsc2UsXG4gICAgZ2V0UmVmZXJlbmNlKGdyYXBoLCBpZCksXG4gICAgdW5kZWZpbmVkLFxuICApO1xufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gbG9jYWwoXG4gIHNjb3BlOiBQcm9ncmFtU2NvcGUsXG4gIGtleTogc3RyaW5nLFxuICBpZDogc3RyaW5nLFxuICBpdGVtOiBUZXJyYWZvcm1SZXNvdXJjZUJsb2NrLFxuICBncmFwaDogRGlyZWN0ZWRHcmFwaCxcbik6IFByb21pc2U8dC5WYXJpYWJsZURlY2xhcmF0aW9uW10+IHtcbiAgbG9nZ2VyLmRlYnVnKGBJbml0aWFsaXppbmcgbG9jYWwgcmVzb3VyY2UgJHtrZXl9IHdpdGggaWQgJHtpZH1gKTtcbiAgaWYgKCFnZXRSZWZlcmVuY2UoZ3JhcGgsIGlkKSkge1xuICAgIGxvZ2dlci5kZWJ1ZyhgTm8gcmVmZXJlbmNlIGZvdW5kIGZvciAke2tleX1gKTtcbiAgICByZXR1cm4gW107XG4gIH1cbiAgcmV0dXJuIFtcbiAgICB0LnZhcmlhYmxlRGVjbGFyYXRpb24oXCJjb25zdFwiLCBbXG4gICAgICB0LnZhcmlhYmxlRGVjbGFyYXRvcihcbiAgICAgICAgdC5pZGVudGlmaWVyKHZhcmlhYmxlTmFtZShzY29wZSwgXCJsb2NhbFwiLCBrZXkpKSxcbiAgICAgICAgYXdhaXQgdmFsdWVUb1RzKHNjb3BlLCBpdGVtLCBcInBhdGgtZm9yLWxvY2FsLWJsb2Nrcy1jYW4tYmUtaWdub3JlZFwiKSxcbiAgICAgICksXG4gICAgXSksXG4gIF07XG59XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBtb2R1bGVzKFxuICBzY29wZTogUHJvZ3JhbVNjb3BlLFxuICBrZXk6IHN0cmluZyxcbiAgaWQ6IHN0cmluZyxcbiAgaXRlbTogTW9kdWxlLFxuICBncmFwaDogRGlyZWN0ZWRHcmFwaCxcbikge1xuICBjb25zdCBbeyBzb3VyY2UsIHZlcnNpb24sIC4uLnByb3BzIH1dID0gaXRlbTtcblxuICBjb25zdCBtb2R1bGVDb25zdHJhaW50ID0gbmV3IFRlcnJhZm9ybU1vZHVsZUNvbnN0cmFpbnQoc291cmNlKTtcblxuICByZXR1cm4gYXNFeHByZXNzaW9uKFxuICAgIHNjb3BlLFxuICAgIG1vZHVsZUNvbnN0cmFpbnQuY2xhc3NOYW1lLFxuICAgIGtleSxcbiAgICBwcm9wcyxcbiAgICB0cnVlLFxuICAgIGZhbHNlLFxuICAgIGdldFJlZmVyZW5jZShncmFwaCwgaWQpLFxuICAgIHVuZGVmaW5lZCxcbiAgKTtcbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGltcG9ydHMoXG4gIHNjb3BlOiBQcm9ncmFtU2NvcGUsXG4gIF9pZDogc3RyaW5nLFxuICBpdGVtOiBJbXBvcnQsXG4gIGdyYXBoOiBEaXJlY3RlZEdyYXBoLFxuKSB7XG4gIC8vIE1vdmUgZnJvbSAke2F3c19pbnN0YW5jZS5leGFtcGxlfSB0byBhd3NfaW5zdGFuY2UuZXhhbXBsZVxuICBjb25zdCB0YXJnZXQgPVxuICAgIGl0ZW0udG8uc3RhcnRzV2l0aChcIiR7XCIpICYmIGl0ZW0udG8uZW5kc1dpdGgoXCJ9XCIpXG4gICAgICA/IGl0ZW0udG8uc3Vic3RyaW5nKDIsIGl0ZW0udG8ubGVuZ3RoIC0gMSlcbiAgICAgIDogaXRlbS50bztcblxuICAvLyBDaGVjayBpZiB0aGUgaW1wb3J0IGdvZXMgaW50byBhIG1vZHVsZVxuICBpZiAodGFyZ2V0LnN0YXJ0c1dpdGgoXCJtb2R1bGUuXCIpKSB7XG4gICAgcmV0dXJuIFtcbiAgICAgIHQuYWRkQ29tbWVudChcbiAgICAgICAgdC5lbXB0eVN0YXRlbWVudCgpLFxuICAgICAgICBcImxlYWRpbmdcIixcbiAgICAgICAgYENES1ROIGRvZXMgbm90IHN1cHBvcnQgaW1wb3J0cyBpbnRvIG1vZHVsZXMgeWV0LCBwbGVhc2UgcmVtb3ZlIHRoZSBpbXBvcnQgYmxvY2sgaW1wb3J0aW5nICR7aXRlbS5pZH0gaW50byAke3RhcmdldH0gZnJvbSB5b3VyIGNvbmZpZ3VyYXRpb25gLFxuICAgICAgKSxcbiAgICBdO1xuICB9XG5cbiAgLy8gV2Ugbm93IGtub3cgdGhhdCB0aGUgaW1wb3J0IGdvZXMgaW50byBhIHJlc291cmNlLCBlLmcuIGF3c19pbnN0YW5jZS5leGFtcGxlXG4gIGNvbnN0IFtyZXNvdXJjZVR5cGVJZGVudGlmaWVyLCByZXNvdXJjZU5hbWVdID0gdGFyZ2V0LnNwbGl0KFwiLlwiKTtcbiAgaWYgKHJlc291cmNlTmFtZS5pbmNsdWRlcyhcIltcIikpIHtcbiAgICByZXR1cm4gW1xuICAgICAgdC5hZGRDb21tZW50KFxuICAgICAgICB0LmVtcHR5U3RhdGVtZW50KCksXG4gICAgICAgIFwibGVhZGluZ1wiLFxuICAgICAgICBgQ0RLVE4gZG9lcyBub3Qgc3VwcG9ydCBpbXBvcnRzIGludG8gcmVzb3VyY2VzIHdpdGggY291bnQgb3IgZm9yX2VhY2ggeWV0LCBwbGVhc2UgcmVtb3ZlIHRoZSBpbXBvcnQgYmxvY2sgaW1wb3J0aW5nICR7aXRlbS5pZH0gaW50byAke3RhcmdldH0gZnJvbSB5b3VyIGNvbmZpZ3VyYXRpb25gLFxuICAgICAgKSxcbiAgICBdO1xuICB9XG5cbiAgLy8gQ2hlY2sgaWYgd2UgaGF2ZSBhIGV4aXN0aW5nIHJlc291cmNlIGNvbmZpZyB3aXRoIHRoZSBnaXZlbiBuYW1lXG4gIGlmIChncmFwaC5oYXNOb2RlKHRhcmdldCkpIHtcbiAgICAvLyBXZSB3aWxsIGhhbmRsZSB0aGlzIGNhc2UgaW4gdGhlIHJlc291cmNlIGZ1bmN0aW9uXG4gICAgLy8gc28gd2UgY2FuIHNraXAgb3ZlciBpdFxuICAgIHJldHVybiBbXTtcbiAgfVxuXG4gIGNvbnN0IFtwcm92aWRlciwgLi4ucmVzb3VyY2VUeXBlTmFtZVBhcnRzXSA9XG4gICAgcmVzb3VyY2VUeXBlSWRlbnRpZmllci5zcGxpdChcIl9cIik7XG5cbiAgY29uc3QgY29uc3RydWN0SWQgPSB1bmlxdWVJZChzY29wZS5jb25zdHJ1Y3RzLCBjYW1lbENhc2UocmVzb3VyY2VOYW1lKSk7XG4gIGNvbnN0IGNvbnN0cnVjdENsYXNzID0gY29uc3RydWN0QXN0KFxuICAgIHNjb3BlLFxuICAgIGAke3Byb3ZpZGVyfS4ke3Jlc291cmNlVHlwZU5hbWVQYXJ0cy5qb2luKFwiX1wiKX1gLFxuICAgIGZhbHNlLFxuICApO1xuICByZXR1cm4gW1xuICAgIHQuZXhwcmVzc2lvblN0YXRlbWVudChcbiAgICAgIHQuY2FsbEV4cHJlc3Npb24oXG4gICAgICAgIHQubWVtYmVyRXhwcmVzc2lvbihcbiAgICAgICAgICBjb25zdHJ1Y3RDbGFzcyxcbiAgICAgICAgICB0LmlkZW50aWZpZXIoXCJnZW5lcmF0ZUNvbmZpZ0ZvckltcG9ydFwiKSxcbiAgICAgICAgKSxcbiAgICAgICAgW1xuICAgICAgICAgIHQudGhpc0V4cHJlc3Npb24oKSxcbiAgICAgICAgICB0LnN0cmluZ0xpdGVyYWwoY29uc3RydWN0SWQpLFxuICAgICAgICAgIHQuc3RyaW5nTGl0ZXJhbChpdGVtLmlkKSxcbiAgICAgICAgXSxcbiAgICAgICksXG4gICAgKSxcbiAgXTtcbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHByb3ZpZGVyKFxuICBzY29wZTogUHJvZ3JhbVNjb3BlLFxuICBrZXk6IHN0cmluZyxcbiAgaWQ6IHN0cmluZyxcbiAgaXRlbTogUHJvdmlkZXJbMF0sXG4gIGdyYXBoOiBEaXJlY3RlZEdyYXBoLFxuKSB7XG4gIGNvbnN0IHsgdmVyc2lvbiwgLi4ucHJvcHMgfSA9IGl0ZW07XG5cbiAgY29uc3QgaW1wb3J0S2V5ID0ga2V5ID09PSBcIm51bGxcIiA/IFwiTnVsbFByb3ZpZGVyXCIgOiBrZXk7XG5cbiAgcmV0dXJuIGFzRXhwcmVzc2lvbihcbiAgICBzY29wZSxcbiAgICBgJHtpbXBvcnRLZXl9LiR7cGFzY2FsQ2FzZShrZXkpfVByb3ZpZGVyYCxcbiAgICBrZXksXG4gICAgcHJvcHMsXG4gICAgZmFsc2UsXG4gICAgdHJ1ZSxcbiAgICBnZXRSZWZlcmVuY2UoZ3JhcGgsIGlkKSxcbiAgICB1bmRlZmluZWQsXG4gICk7XG59XG5cbmV4cG9ydCBjb25zdCBjZGt0ZkltcG9ydCA9IHRlbXBsYXRlKFxuICBgaW1wb3J0ICogYXMgY2RrdG4gZnJvbSBcImNka3RuXCJgLFxuKSgpIGFzIHQuU3RhdGVtZW50O1xuXG5leHBvcnQgY29uc3QgY29uc3RydWN0c0ltcG9ydCA9IHRlbXBsYXRlKFxuICBgaW1wb3J0ICogYXMgY29uc3RydWN0cyBmcm9tIFwiY29uc3RydWN0c1wiYCxcbikoKSBhcyB0LlN0YXRlbWVudDtcblxuZXhwb3J0IGNvbnN0IHByb3ZpZGVySW1wb3J0cyA9IChwcm92aWRlcnM6IHN0cmluZ1tdKSA9PlxuICBwcm92aWRlcnMubWFwKChwcm92aWRlck5hbWUpID0+IHtcbiAgICBjb25zdCBwYXJ0cyA9IHByb3ZpZGVyTmFtZS5zcGxpdChcIi9cIik7XG4gICAgY29uc3QgbmFtZSA9IHBhcnRzLmxlbmd0aCA+IDEgPyBwYXJ0c1sxXSA6IHBhcnRzWzBdO1xuICAgIGNvbnN0IGltcG9ydE5hbWUgPSBuYW1lID09PSBcIm51bGxcIiA/IFwiTnVsbFByb3ZpZGVyXCIgOiBuYW1lO1xuICAgIHJldHVybiB0ZW1wbGF0ZShcbiAgICAgIGBpbXBvcnQgKiBhcyAke2ltcG9ydE5hbWV9IGZyb20gXCIuLy5nZW4vcHJvdmlkZXJzLyR7bmFtZS5yZXBsYWNlKFxuICAgICAgICBcIi4vXCIsXG4gICAgICAgIFwiXCIsXG4gICAgICApfVwiYCxcbiAgICApKCkgYXMgdC5TdGF0ZW1lbnQ7XG4gIH0pO1xuXG5leHBvcnQgY29uc3QgbW9kdWxlSW1wb3J0cyA9IChtb2R1bGVzOiBSZWNvcmQ8c3RyaW5nLCBNb2R1bGU+IHwgdW5kZWZpbmVkKSA9PiB7XG4gIGNvbnN0IHVuaXF1ZU1vZHVsZXMgPSBuZXcgU2V0PHN0cmluZz4oKTtcbiAgT2JqZWN0LnZhbHVlcyhtb2R1bGVzIHx8IHt9KS5tYXAoKFttb2R1bGVdKSA9PlxuICAgIHVuaXF1ZU1vZHVsZXMuYWRkKG1vZHVsZS5zb3VyY2UpLFxuICApO1xuXG4gIGNvbnN0IGltcG9ydHM6IHQuU3RhdGVtZW50W10gPSBbXTtcbiAgdW5pcXVlTW9kdWxlcy5mb3JFYWNoKChtKSA9PiB7XG4gICAgY29uc3QgbW9kdWxlQ29uc3RyYWludCA9IG5ldyBUZXJyYWZvcm1Nb2R1bGVDb25zdHJhaW50KG0pO1xuICAgIGltcG9ydHMucHVzaChcbiAgICAgIHRlbXBsYXRlLmFzdChcbiAgICAgICAgYGltcG9ydCAqIGFzICR7bW9kdWxlQ29uc3RyYWludC5jbGFzc05hbWV9IGZyb20gXCIuLy5nZW4vbW9kdWxlcy8ke21vZHVsZUNvbnN0cmFpbnQuZmlsZU5hbWV9XCJgLFxuICAgICAgKSBhcyB0LlN0YXRlbWVudCxcbiAgICApO1xuICB9KTtcbiAgcmV0dXJuIGltcG9ydHM7XG59O1xuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gZ2VuKHN0YXRlbWVudHM6IHQuU3RhdGVtZW50W10pIHtcbiAgbG9nZ2VyLmRlYnVnKGBHZW5lcmF0aW5nIGNvZGUgZm9yICR7SlNPTi5zdHJpbmdpZnkoc3RhdGVtZW50cywgbnVsbCwgMil9YCk7XG4gIGNvbnN0IGNvZGUgPSBwcmV0dGllci5mb3JtYXQoZ2VuZXJhdGUodC5wcm9ncmFtKHN0YXRlbWVudHMpIGFzIGFueSkuY29kZSwge1xuICAgIHBhcnNlcjogXCJiYWJlbFwiLFxuICB9KTtcblxuICBsb2dnZXIuZGVidWcoYEdlbmVyYXRlZCBjb2RlOlxcbiR7Y29kZX1gKTtcblxuICByZXR1cm4gY29kZTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGFkZEltcG9ydEZvckNvZGVDb250YWluZXIoXG4gIHNjb3BlOiBQcm9ncmFtU2NvcGUsXG4gIGNvZGVDb250YWluZXI6IHN0cmluZyxcbikge1xuICBzd2l0Y2ggKGNvZGVDb250YWluZXIpIHtcbiAgICBjYXNlIFwiY29uc3RydWN0cy5Db25zdHJ1Y3RcIjpcbiAgICAgIHNjb3BlLmltcG9ydGFibGVzLnB1c2goe1xuICAgICAgICBwcm92aWRlcjogXCJjb25zdHJ1Y3RzXCIsXG4gICAgICAgIGNvbnN0cnVjdE5hbWU6IFwiQ29uc3RydWN0XCIsXG4gICAgICB9KTtcbiAgICAgIGJyZWFrO1xuXG4gICAgY2FzZSBcImNka3RuLlRlcnJhZm9ybVN0YWNrXCI6XG4gICAgICBzY29wZS5pbXBvcnRhYmxlcy5wdXNoKHtcbiAgICAgICAgcHJvdmlkZXI6IFwiY2RrdG5cIixcbiAgICAgICAgY29uc3RydWN0TmFtZTogXCJUZXJyYWZvcm1TdGFja1wiLFxuICAgICAgfSk7XG4gICAgICBicmVhaztcblxuICAgIGNhc2UgXCJjZGt0Zi5UZXJyYWZvcm1TdGFja1wiOlxuICAgICAgc2NvcGUuaW1wb3J0YWJsZXMucHVzaCh7XG4gICAgICAgIHByb3ZpZGVyOiBcImNka3RmXCIsXG4gICAgICAgIGNvbnN0cnVjdE5hbWU6IFwiVGVycmFmb3JtU3RhY2tcIixcbiAgICAgIH0pO1xuICAgICAgYnJlYWs7XG4gICAgZGVmYXVsdDpcbiAgICAgIHRocm93IEVycm9ycy5JbnRlcm5hbChcIlVuc3VwcG9ydGVkIGNvZGUgY29udGFpbmVyOiBcIiArIGNvZGVDb250YWluZXIpO1xuICB9XG59XG5cbmV4cG9ydCBmdW5jdGlvbiB3cmFwQ29kZUluQ29uc3RydWN0b3IoXG4gIGNvZGVDb250YWluZXI6IHN0cmluZyxcbiAgY29kZTogdC5TdGF0ZW1lbnRbXSxcbiAgY2xhc3NOYW1lOiBzdHJpbmcsXG4gIGNvbmZpZ1R5cGVOYW1lPzogc3RyaW5nLFxuKTogdC5TdGF0ZW1lbnQge1xuICBsZXQgYmFzZUNvbnRhaW5lckNsYXNzOiB0LklkZW50aWZpZXI7XG4gIHN3aXRjaCAoY29kZUNvbnRhaW5lcikge1xuICAgIGNhc2UgXCJjb25zdHJ1Y3RzLkNvbnN0cnVjdFwiOlxuICAgICAgYmFzZUNvbnRhaW5lckNsYXNzID0gdC5pZGVudGlmaWVyKFwiQ29uc3RydWN0XCIpO1xuICAgICAgYnJlYWs7XG5cbiAgICBjYXNlIFwiY2RrdG4uVGVycmFmb3JtU3RhY2tcIjpcbiAgICAgIGJhc2VDb250YWluZXJDbGFzcyA9IHQuaWRlbnRpZmllcihcIlRlcnJhZm9ybVN0YWNrXCIpO1xuICAgICAgYnJlYWs7XG4gICAgZGVmYXVsdDpcbiAgICAgIHRocm93IEVycm9ycy5JbnRlcm5hbChcIlVuc3VwcG9ydGVkIGNvZGUgY29udGFpbmVyOiBcIiArIGNvZGVDb250YWluZXIpO1xuICB9XG4gIGlmIChjb25maWdUeXBlTmFtZSkge1xuICAgIHJldHVybiB0ZW1wbGF0ZS5zdGF0ZW1lbnQoXG4gICAgICBgXG4gIGNsYXNzICUlY2xhc3NOYW1lJSUgZXh0ZW5kcyAlJWJhc2UlJSB7XG4gICAgY29uc3RydWN0b3Ioc2NvcGU6IENvbnN0cnVjdCwgbmFtZTogc3RyaW5nLCBjb25maWc6ICR7Y29uZmlnVHlwZU5hbWV9KSB7XG4gICAgICBzdXBlcihzY29wZSwgbmFtZSk7XG4gICAgICAlJWNvZGUlJVxuICAgIH1cbiAgfVxuYCxcbiAgICAgIHsgc3ludGFjdGljUGxhY2Vob2xkZXJzOiB0cnVlLCBwbHVnaW5zOiBbXCJ0eXBlc2NyaXB0XCJdIH0sXG4gICAgKSh7XG4gICAgICBjb2RlLFxuICAgICAgYmFzZTogYmFzZUNvbnRhaW5lckNsYXNzLFxuICAgICAgY2xhc3NOYW1lOiB0LmlkZW50aWZpZXIoY2xhc3NOYW1lKSxcbiAgICB9KSBhcyB0LlN0YXRlbWVudDtcbiAgfVxuICByZXR1cm4gdGVtcGxhdGUuc3RhdGVtZW50KFxuICAgIGBcbiAgY2xhc3MgJSVjbGFzc05hbWUlJSBleHRlbmRzICUlYmFzZSUlIHtcbiAgICBjb25zdHJ1Y3RvcihzY29wZTogQ29uc3RydWN0LCBuYW1lOiBzdHJpbmcpIHtcbiAgICAgIHN1cGVyKHNjb3BlLCBuYW1lKTtcbiAgICAgICUlY29kZSUlXG4gICAgfVxuICB9XG5gLFxuICAgIHsgc3ludGFjdGljUGxhY2Vob2xkZXJzOiB0cnVlLCBwbHVnaW5zOiBbXCJ0eXBlc2NyaXB0XCJdIH0sXG4gICkoe1xuICAgIGNvZGUsXG4gICAgYmFzZTogYmFzZUNvbnRhaW5lckNsYXNzLFxuICAgIGNsYXNzTmFtZTogdC5pZGVudGlmaWVyKGNsYXNzTmFtZSksXG4gIH0pIGFzIHQuU3RhdGVtZW50O1xufVxuXG5leHBvcnQgY29uc3QgcHJvdmlkZXJDb25zdHJ1Y3RJbXBvcnRzID0gKGltcG9ydGFibGU6IEltcG9ydGFibGVDb25zdHJ1Y3RbXSkgPT4ge1xuICBsZXQgcHJvdmlkZXIgPSBpbXBvcnRhYmxlWzBdLnByb3ZpZGVyO1xuICBsZXQgbmFtZXNwYWNlID0gaW1wb3J0YWJsZVswXS5uYW1lc3BhY2U7XG4gIGNvbnN0IG5hbWVzID0gaW1wb3J0YWJsZS5tYXAoKGkpID0+IGkuY29uc3RydWN0TmFtZSk7XG5cbiAgaWYgKHByb3ZpZGVyID09PSBcImNka3RuXCIgfHwgcHJvdmlkZXIgPT09IFwiY29uc3RydWN0c1wiKSB7XG4gICAgcmV0dXJuIHRlbXBsYXRlKFxuICAgICAgYGltcG9ydCB7ICR7bmFtZXMuam9pbihcIiwgXCIpfSB9IGZyb20gXCIke3Byb3ZpZGVyfVwiYCxcbiAgICApKCkgYXMgdC5TdGF0ZW1lbnQ7XG4gIH1cblxuICBpZiAobmFtZXNwYWNlKSB7XG4gICAgbmFtZXNwYWNlID0gc25ha2VDYXNlKG5hbWVzcGFjZSkucmVwbGFjZSgvXy9nLCBcIi1cIik7XG4gIH1cblxuICAvLyBTcGVjaWFsIGNhc2VzIHRvIHVuZG8gcHJvdmlkZXIgbmFtZXMgdGhhdCB3ZSBvdmVycmlkZVxuICBpZiAocHJvdmlkZXIgPT09IFwiTnVsbFByb3ZpZGVyXCIpIHtcbiAgICBwcm92aWRlciA9IFwibnVsbFwiO1xuICB9XG5cbiAgcmV0dXJuIHRlbXBsYXRlKFxuICAgIGBpbXBvcnQgeyAke25hbWVzLmpvaW4oXG4gICAgICBcIiwgXCIsXG4gICAgKX0gfSBmcm9tIFwiLi8uZ2VuL3Byb3ZpZGVycy8ke3Byb3ZpZGVyfS8ke25hbWVzcGFjZX1cImAsXG4gICkoKSBhcyB0LlN0YXRlbWVudDtcbn07XG5cbmV4cG9ydCBmdW5jdGlvbiBidWlsZEltcG9ydHMoaW1wb3J0YWJsZXM6IEltcG9ydGFibGVDb25zdHJ1Y3RbXSkge1xuICBjb25zdCBncm91cGVkSW1wb3J0YWJsZXMgPSBpbXBvcnRhYmxlcy5yZWR1Y2UoXG4gICAgKGFjYywgaW1wb3J0YWJsZSkgPT4ge1xuICAgICAgY29uc3QgbnMgPSBpbXBvcnRhYmxlLm5hbWVzcGFjZSB8fCBcIlwiO1xuICAgICAgLy8gRG9pbmcgc29tZSBoYWNreSBvcmRlcmluZyBvZiB0aGUgaW1wb3J0cyB0byBtYWtlIHRoZW0gbG9vayBhIGJpdCBuaWNlclxuICAgICAgY29uc3QgcHJlZml4ID1cbiAgICAgICAgaW1wb3J0YWJsZS5wcm92aWRlciA9PT0gXCJjb25zdHJ1Y3RzXCJcbiAgICAgICAgICA/IFwiMVwiXG4gICAgICAgICAgOiBpbXBvcnRhYmxlLnByb3ZpZGVyID09PSBcImNka3RuXCJcbiAgICAgICAgICAgID8gXCIyXCJcbiAgICAgICAgICAgIDogaW1wb3J0YWJsZS5wcm92aWRlciA9PT0gXCJjZGt0ZlwiXG4gICAgICAgICAgICAgID8gXCIzXCJcbiAgICAgICAgICAgICAgOiBcIjRcIjtcbiAgICAgIGNvbnN0IGdyb3VwTmFtZSA9IGAke3ByZWZpeH0uJHtpbXBvcnRhYmxlLnByb3ZpZGVyfS4ke25zfWA7XG4gICAgICBjb25zdCBmdWxsTmFtZSA9IGAke2ltcG9ydGFibGUucHJvdmlkZXJ9LiR7bnN9LiR7aW1wb3J0YWJsZS5jb25zdHJ1Y3ROYW1lfWA7XG5cbiAgICAgIGlmIChhY2NbZ3JvdXBOYW1lXSkge1xuICAgICAgICBjb25zdCBleGlzdHNBbHJlYWR5ID0gYWNjW2dyb3VwTmFtZV0uc29tZShcbiAgICAgICAgICAoaW1wb3J0YWJsZSkgPT5cbiAgICAgICAgICAgIGAke2ltcG9ydGFibGUucHJvdmlkZXJ9LiR7bnN9LiR7aW1wb3J0YWJsZS5jb25zdHJ1Y3ROYW1lfWAgPT09XG4gICAgICAgICAgICBmdWxsTmFtZSxcbiAgICAgICAgKTtcbiAgICAgICAgaWYgKGV4aXN0c0FscmVhZHkpIHtcbiAgICAgICAgICByZXR1cm4gYWNjO1xuICAgICAgICB9XG4gICAgICAgIGFjY1tncm91cE5hbWVdLnB1c2goaW1wb3J0YWJsZSk7XG4gICAgICAgIGFjY1tncm91cE5hbWVdLnNvcnQoKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGFjY1tncm91cE5hbWVdID0gW2ltcG9ydGFibGVdO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gYWNjO1xuICAgIH0sXG4gICAge30gYXMgUmVjb3JkPHN0cmluZywgSW1wb3J0YWJsZUNvbnN0cnVjdFtdPixcbiAgKTtcblxuICBsZXQgY29tbWVudEFkZGVkID0gZmFsc2U7XG4gIGNvbnN0IGNvbnN0cnVjdEltcG9ydHMgPSBPYmplY3Qua2V5cyhncm91cGVkSW1wb3J0YWJsZXMpXG4gICAgLnNvcnQoKVxuICAgIC5tYXAoKGdyb3VwTmFtZSkgPT4ge1xuICAgICAgY29uc3QgaW1wb3J0U3RhdGVtZW50ID0gcHJvdmlkZXJDb25zdHJ1Y3RJbXBvcnRzKFxuICAgICAgICBncm91cGVkSW1wb3J0YWJsZXNbZ3JvdXBOYW1lXSxcbiAgICAgICk7XG5cbiAgICAgIGlmIChncm91cE5hbWUuc3RhcnRzV2l0aChcIjQuXCIpICYmICFjb21tZW50QWRkZWQpIHtcbiAgICAgICAgY29tbWVudEFkZGVkID0gdHJ1ZTtcbiAgICAgICAgdC5hZGRDb21tZW50KFxuICAgICAgICAgIGltcG9ydFN0YXRlbWVudCxcbiAgICAgICAgICBcImxlYWRpbmdcIixcbiAgICAgICAgICBgXFxuKiBQcm92aWRlciBiaW5kaW5ncyBhcmUgZ2VuZXJhdGVkIGJ5IHJ1bm5pbmcgXFxgY2RrdG4gZ2V0XFxgLlxuKiBTZWUgaHR0cHM6Ly9jZGsudGYvcHJvdmlkZXItZ2VuZXJhdGlvbiBmb3IgbW9yZSBkZXRhaWxzLlxcbmAsXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgICByZXR1cm4gaW1wb3J0U3RhdGVtZW50O1xuICAgIH0pO1xuXG4gIHJldHVybiBjb25zdHJ1Y3RJbXBvcnRzO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2VuZXJhdGVDb25maWdUeXBlKFxuICBuYW1lOiBzdHJpbmcsXG4gIGNvbmZpZzogUmVjb3JkPHN0cmluZywgQXR0cmlidXRlUGF0aD4sXG4pOiB0LlN0YXRlbWVudCB7XG4gIHJldHVybiB0LnRzSW50ZXJmYWNlRGVjbGFyYXRpb24oXG4gICAgdC5pZGVudGlmaWVyKG5hbWUpLFxuICAgIHVuZGVmaW5lZCxcbiAgICB1bmRlZmluZWQsXG4gICAgdC50c0ludGVyZmFjZUJvZHkoXG4gICAgICBPYmplY3QuZW50cmllcyhjb25maWcpLm1hcCgoW2tleSwgX3ZhbHVlXSkgPT5cbiAgICAgICAgdC50c1Byb3BlcnR5U2lnbmF0dXJlKFxuICAgICAgICAgIHQuaWRlbnRpZmllcihrZXkpLFxuICAgICAgICAgIHQudFNUeXBlQW5ub3RhdGlvbih0LnRzQW55S2V5d29yZCgpKSwgLy8gVE9ETzogVHJ5IHRvIG1ha2UgdGhpcyBiZXR0ZXIgdGhhbiBhbnlcbiAgICAgICAgKSxcbiAgICAgICksXG4gICAgKSxcbiAgKTtcbn1cbiJdfQ==