@cdktn/hcl2cdk 0.23.0-pre.7 → 0.23.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 (85) hide show
  1. package/ambient.d.ts +0 -1
  2. package/build/__tests__/coerceType.test.js +165 -0
  3. package/build/__tests__/expressionToTs.test.js +693 -0
  4. package/build/__tests__/expressions.test.js +415 -0
  5. package/build/__tests__/findExpressionType.test.js +105 -0
  6. package/build/__tests__/functions.test.js +605 -0
  7. package/build/__tests__/generation.test.js +45 -0
  8. package/build/__tests__/jsii-rosetta-workarounds.test.js +86 -0
  9. package/build/__tests__/partialCode.test.js +390 -0
  10. package/build/__tests__/terraformSchema.test.js +105 -0
  11. package/build/__tests__/testHelpers.js +16 -0
  12. package/build/coerceType.js +240 -0
  13. package/build/dynamic-blocks.js +44 -0
  14. package/build/expressions.js +633 -0
  15. package/build/function-bindings/functions.generated.js +1142 -0
  16. package/build/function-bindings/functions.js +73 -0
  17. package/{lib → build}/generation.js +4 -4
  18. package/{lib → build}/index.d.ts +2 -2
  19. package/build/index.js +364 -0
  20. package/build/iteration.js +87 -0
  21. package/build/jsii-rosetta-workarounds.js +126 -0
  22. package/build/partialCode.js +116 -0
  23. package/build/provider.js +40 -0
  24. package/build/references.js +141 -0
  25. package/build/schema.js +81 -0
  26. package/build/telemetryAllowList.json +24 -0
  27. package/build/terraformSchema.js +136 -0
  28. package/build/types.js +3 -0
  29. package/build/utils.js +25 -0
  30. package/build/variables.js +172 -0
  31. package/package.json +13 -14
  32. package/tsconfig.json +4 -2
  33. package/lib/__tests__/coerceType.test.js +0 -165
  34. package/lib/__tests__/expressionToTs.test.js +0 -693
  35. package/lib/__tests__/expressions.test.js +0 -415
  36. package/lib/__tests__/findExpressionType.test.js +0 -105
  37. package/lib/__tests__/functions.test.js +0 -605
  38. package/lib/__tests__/generation.test.js +0 -45
  39. package/lib/__tests__/jsii-rosetta-workarounds.test.js +0 -86
  40. package/lib/__tests__/partialCode.test.js +0 -390
  41. package/lib/__tests__/terraformSchema.test.js +0 -105
  42. package/lib/__tests__/testHelpers.js +0 -16
  43. package/lib/coerceType.js +0 -240
  44. package/lib/dynamic-blocks.js +0 -44
  45. package/lib/expressions.js +0 -634
  46. package/lib/function-bindings/functions.generated.js +0 -1142
  47. package/lib/function-bindings/functions.js +0 -73
  48. package/lib/index.js +0 -364
  49. package/lib/iteration.js +0 -87
  50. package/lib/jsii-rosetta-workarounds.js +0 -126
  51. package/lib/partialCode.js +0 -116
  52. package/lib/provider.js +0 -40
  53. package/lib/references.js +0 -141
  54. package/lib/schema.js +0 -81
  55. package/lib/terraformSchema.js +0 -136
  56. package/lib/types.js +0 -3
  57. package/lib/utils.js +0 -25
  58. package/lib/variables.js +0 -172
  59. /package/{lib → build}/__tests__/coerceType.test.d.ts +0 -0
  60. /package/{lib → build}/__tests__/expressionToTs.test.d.ts +0 -0
  61. /package/{lib → build}/__tests__/expressions.test.d.ts +0 -0
  62. /package/{lib → build}/__tests__/findExpressionType.test.d.ts +0 -0
  63. /package/{lib → build}/__tests__/functions.test.d.ts +0 -0
  64. /package/{lib → build}/__tests__/generation.test.d.ts +0 -0
  65. /package/{lib → build}/__tests__/jsii-rosetta-workarounds.test.d.ts +0 -0
  66. /package/{lib → build}/__tests__/partialCode.test.d.ts +0 -0
  67. /package/{lib → build}/__tests__/terraformSchema.test.d.ts +0 -0
  68. /package/{lib → build}/__tests__/testHelpers.d.ts +0 -0
  69. /package/{lib → build}/coerceType.d.ts +0 -0
  70. /package/{lib → build}/dynamic-blocks.d.ts +0 -0
  71. /package/{lib → build}/expressions.d.ts +0 -0
  72. /package/{lib → build}/function-bindings/functions.d.ts +0 -0
  73. /package/{lib → build}/function-bindings/functions.generated.d.ts +0 -0
  74. /package/{lib → build}/generation.d.ts +0 -0
  75. /package/{lib → build}/iteration.d.ts +0 -0
  76. /package/{lib → build}/jsii-rosetta-workarounds.d.ts +0 -0
  77. /package/{lib → build}/partialCode.d.ts +0 -0
  78. /package/{lib → build}/provider.d.ts +0 -0
  79. /package/{lib → build}/references.d.ts +0 -0
  80. /package/{lib → build}/schema.d.ts +0 -0
  81. /package/{lib → build}/terraformSchema.d.ts +0 -0
  82. /package/{lib → build}/types.d.ts +0 -0
  83. /package/{lib → build}/utils.d.ts +0 -0
  84. /package/{lib → build}/variables.d.ts +0 -0
  85. /package/{lib → src}/telemetryAllowList.json +0 -0
@@ -1,634 +0,0 @@
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.dynamicVariableToAst = exports.extractIteratorVariablesFromExpression = exports.convertTerraformExpressionToTs = exports.expressionAst = void 0;
30
- // Copyright (c) HashiCorp, Inc
31
- // SPDX-License-Identifier: MPL-2.0
32
- const t = __importStar(require("@babel/types"));
33
- const template_1 = __importDefault(require("@babel/template"));
34
- const utils_1 = require("./utils");
35
- const hcl2json_1 = require("@cdktn/hcl2json");
36
- const hcl2json_2 = require("@cdktn/hcl2json");
37
- const functions_1 = require("./function-bindings/functions");
38
- const coerceType_1 = require("./coerceType");
39
- const terraformSchema_1 = require("./terraformSchema");
40
- const references_1 = require("./references");
41
- const variables_1 = require("./variables");
42
- const syntax_tree_1 = require("@cdktn/hcl2json/lib/syntax-tree");
43
- const tfBinaryOperatorsToCdktf = {
44
- logicalOr: "or",
45
- logicalAnd: "and",
46
- greaterThan: "gt",
47
- greaterThanOrEqual: "gte",
48
- lessThan: "lt",
49
- lessThanOrEqual: "lte",
50
- equal: "eq",
51
- notEqual: "neq",
52
- add: "add",
53
- subtract: "sub",
54
- multiply: "mul",
55
- divide: "div",
56
- modulo: "mod",
57
- };
58
- const tfUnaryOperatorsToCdktf = {
59
- logicalNot: "not",
60
- negate: "negate",
61
- };
62
- function traversalPartsToString(traversals, asSuffix = false) {
63
- let seed = "";
64
- if (asSuffix && hcl2json_2.TFExpressionSyntaxTree.isNameTraversalPart(traversals[0])) {
65
- seed = ".";
66
- }
67
- return traversals.reduce((acc, part) => {
68
- if (part.type === "nameTraversal") {
69
- if (acc === seed) {
70
- return `${acc}${part.segment}`;
71
- }
72
- return `${acc}.${part.segment}`;
73
- }
74
- return `${acc}[${part.segment}]`;
75
- }, seed);
76
- }
77
- function canUseFqn(expression) {
78
- if (!hcl2json_2.TFExpressionSyntaxTree.isScopeTraversalExpression(expression)) {
79
- return false;
80
- }
81
- const rootSegment = expression.meta.traversal[0].segment;
82
- return !["var", "local"].includes(rootSegment);
83
- }
84
- function traversalToVariableName(scope, node) {
85
- if (!hcl2json_2.TFExpressionSyntaxTree.isScopeTraversalExpression(node)) {
86
- utils_1.logger.error(`Unexpected expression type ${node.type} with value ${node.meta.value} passed to convert to a variable.
87
- ${utils_1.leaveCommentText}`);
88
- return "";
89
- }
90
- const segments = node.meta.traversal;
91
- if (segments.length === 1) {
92
- return node.meta.fullAccessor;
93
- }
94
- const rootSegment = segments[0].segment;
95
- const resource = rootSegment === "data"
96
- ? `${segments[0].segment}.${segments[1].segment}`
97
- : rootSegment;
98
- const name = rootSegment === "data" ? segments[2].segment : segments[1].segment;
99
- return (0, variables_1.variableName)(scope, resource, name);
100
- }
101
- function expressionForSerialStringConcatenation(scope, nodes) {
102
- const reducedNodes = nodes.reduce((acc, node) => {
103
- const prev = acc[acc.length - 1];
104
- if (!prev)
105
- return [node];
106
- if (t.isStringLiteral(prev) && t.isStringLiteral(node)) {
107
- acc.pop();
108
- acc.push(t.stringLiteral(prev.value + node.value));
109
- return acc;
110
- }
111
- acc.push(node);
112
- return acc;
113
- }, []);
114
- return reducedNodes.reduce((acc, node) => {
115
- if (!acc) {
116
- return node;
117
- }
118
- // wrap access to dynamic blocks in Token.asString() as they return a Lazy
119
- // for .key and .value which can't be concatenated in languages like Python
120
- // because JSII currently has no support for the toString() method in
121
- // languages other than TypeScript: https://github.com/aws/jsii/issues/380
122
- // example: dynamic_iterator0.key / dynamic_iterator0.value
123
- if (t.isMemberExpression(node) &&
124
- t.isIdentifier(node.object) &&
125
- Object.values(scope.scopedVariables || {}).includes(node.object.name) &&
126
- t.isIdentifier(node.property) &&
127
- ["key", "value"].includes(node.property.name)) {
128
- node = (0, coerceType_1.coerceType)(scope, node, "dynamic", "string");
129
- }
130
- return t.binaryExpression("+", acc, node);
131
- });
132
- }
133
- function getTfResourcePathFromNode(node) {
134
- const segments = node.meta.traversal;
135
- let resource = segments[0].segment;
136
- let result = [];
137
- let attributes = [];
138
- if (segments[0].segment === "data") {
139
- result.push(segments[0].segment);
140
- resource = segments[1].segment;
141
- attributes = segments.slice(3); // we want to skip the variable name
142
- }
143
- else {
144
- attributes = segments.slice(2); // we want to skip the variable name
145
- }
146
- const [provider, ...resourceNameFragments] = resource.split("_");
147
- // Hack: This happens in the case of `external` provider
148
- // where the data source does not have a provider name prefix
149
- if (resourceNameFragments.length === 0) {
150
- resourceNameFragments.push(provider);
151
- }
152
- result.push(provider);
153
- result.push(resourceNameFragments.join("_"));
154
- result = [
155
- ...result,
156
- ...attributes.map((seg) => {
157
- if (hcl2json_2.TFExpressionSyntaxTree.isIndexTraversalPart(seg)) {
158
- return `[${seg.segment}]`;
159
- }
160
- return seg.segment;
161
- }),
162
- ];
163
- return result.join(".");
164
- }
165
- function convertLiteralValueExpressionToTs(_scope, node) {
166
- const literalType = node.meta.type;
167
- if (literalType === "number") {
168
- return t.numericLiteral(Number(node.meta.value));
169
- }
170
- if (literalType === "bool") {
171
- return t.booleanLiteral(node.meta.value === "true" ? true : false);
172
- }
173
- return t.stringLiteral(node.meta.value);
174
- }
175
- function convertScopeTraversalExpressionToTs(scope, node) {
176
- var _a;
177
- const hasReference = (0, references_1.containsReference)(node);
178
- const segments = node.meta.traversal;
179
- if (segments[0].segment === "each" && scope.forEachIteratorName) {
180
- return dynamicVariableToAst(scope, node, scope.forEachIteratorName);
181
- }
182
- if (segments[0].segment === "count" && scope.countIteratorName) {
183
- return dynamicVariableToAst(scope, node, scope.countIteratorName, "count");
184
- }
185
- if (segments[0].segment === "self") {
186
- scope.importables.push({
187
- constructName: "TerraformSelf",
188
- provider: "cdktn",
189
- });
190
- return t.callExpression(t.memberExpression(t.identifier("TerraformSelf"), t.identifier("getAny")), [t.stringLiteral(traversalPartsToString(segments.slice(1)))]);
191
- }
192
- // setting.value, setting.value[1].id
193
- const dynamicBlock = (_a = scope.scopedVariables) === null || _a === void 0 ? void 0 : _a[segments[0].segment];
194
- if (dynamicBlock) {
195
- if (dynamicBlock === "dynamic-block") {
196
- return dynamicVariableToAst(scope, node, dynamicBlock, traversalPartsToString(segments));
197
- }
198
- return dynamicVariableToAst(scope, node, dynamicBlock, segments[0].segment);
199
- }
200
- // This may be a variable reference that we don't understand yet, so we wrap it in a template string
201
- // for Terraform to handle
202
- let varIdentifier = t.stringLiteral(`\${${node.meta.fullAccessor}}`);
203
- if (hasReference) {
204
- varIdentifier = t.identifier((0, utils_1.camelCase)(traversalToVariableName(scope, node)));
205
- }
206
- if (["var", "local"].includes(segments[0].segment)) {
207
- const variableAccessor = segments[0].segment === "var"
208
- ? t.memberExpression(varIdentifier, t.identifier("value"))
209
- : varIdentifier;
210
- if (segments.length > 2) {
211
- scope.importables.push({
212
- constructName: "Fn",
213
- provider: "cdktn",
214
- });
215
- const callee = t.memberExpression(t.identifier("Fn"), t.identifier("lookupNested"));
216
- return t.callExpression(callee, [
217
- variableAccessor,
218
- t.arrayExpression(segments.slice(2).map((s) => t.stringLiteral(s.segment))),
219
- ]);
220
- }
221
- return variableAccessor;
222
- }
223
- if (!hasReference || scope.withinOverrideExpression) {
224
- return varIdentifier;
225
- }
226
- const rootSegment = segments[0].segment;
227
- const attributeIndex = rootSegment === "data" ? 3 : 2;
228
- const attributeSegments = segments.slice(attributeIndex);
229
- const numericAccessorIndex = attributeSegments.findIndex((seg) => hcl2json_2.TFExpressionSyntaxTree.isIndexTraversalPart(seg));
230
- let minAccessorIndex = numericAccessorIndex;
231
- let mapAccessorIndex = -1;
232
- if (numericAccessorIndex === -1) {
233
- // only do this if we have to, if we already have a
234
- // numeric accessor, we don't have to do this additional work
235
- const resourcePath = getTfResourcePathFromNode(node);
236
- let usingSubPathType = false;
237
- let parts = resourcePath.split(".").filter((p) => p !== "");
238
- const minParts = attributeIndex; // we need to stop before data.aws.resource_name or aws.resource_name
239
- const originalParts = parts.length;
240
- let hasMapAccessor = false;
241
- while (parts.length >= minParts) {
242
- const type = (0, terraformSchema_1.getTypeAtPath)(scope.providerSchema, parts.join("."));
243
- if (type !== null) {
244
- if (Array.isArray(type) && type[0] === "map" && usingSubPathType) {
245
- hasMapAccessor = true;
246
- break;
247
- }
248
- }
249
- parts.pop();
250
- usingSubPathType = true;
251
- }
252
- if (hasMapAccessor) {
253
- mapAccessorIndex = originalParts - parts.length - 1;
254
- minAccessorIndex = mapAccessorIndex;
255
- }
256
- }
257
- const needsPropertyAccess = minAccessorIndex >= 0;
258
- const refSegments = needsPropertyAccess
259
- ? attributeSegments.slice(0, minAccessorIndex)
260
- : attributeSegments;
261
- const nonRefSegments = needsPropertyAccess
262
- ? attributeSegments.slice(minAccessorIndex)
263
- : [];
264
- const ref = refSegments.reduce((acc, seg, index) => t.memberExpression(acc, t.identifier(index === 0 && rootSegment === "module"
265
- ? (0, utils_1.camelCase)(seg.segment + "Output")
266
- : (0, utils_1.camelCase)(seg.segment))), varIdentifier);
267
- if (nonRefSegments.length === 0) {
268
- return ref;
269
- }
270
- scope.importables.push({
271
- constructName: "Fn",
272
- provider: "cdktn",
273
- });
274
- const callee = t.memberExpression(t.identifier("Fn"), t.identifier("lookupNested"));
275
- return t.callExpression(callee, [
276
- ref,
277
- t.arrayExpression(nonRefSegments.map((s) => t.stringLiteral(s.segment))),
278
- ]);
279
- }
280
- function convertUnaryOpExpressionToTs(scope, node) {
281
- const operand = convertTFExpressionAstToTs(scope, hcl2json_2.TFExpressionSyntaxTree.getChildWithValue(node, node.meta.valueExpression));
282
- let fnName = node.meta.operator;
283
- if (tfUnaryOperatorsToCdktf[fnName]) {
284
- fnName = tfUnaryOperatorsToCdktf[fnName];
285
- }
286
- else {
287
- throw new Error(`Cannot convert unknown operator ${node.meta.operator}`);
288
- }
289
- scope.importables.push({
290
- constructName: "Op",
291
- provider: "cdktn",
292
- });
293
- const fn = t.memberExpression(t.identifier("Op"), t.identifier(fnName));
294
- return t.callExpression(fn, [operand]);
295
- }
296
- function convertBinaryOpExpressionToTs(scope, node) {
297
- const left = convertTFExpressionAstToTs(scope, hcl2json_2.TFExpressionSyntaxTree.getChildWithValue(node, node.meta.lhsExpression));
298
- const right = convertTFExpressionAstToTs(scope, hcl2json_2.TFExpressionSyntaxTree.getChildWithValue(node, node.meta.rhsExpression));
299
- let fnName = node.meta.operator;
300
- if (tfBinaryOperatorsToCdktf[fnName]) {
301
- fnName = tfBinaryOperatorsToCdktf[fnName];
302
- }
303
- else {
304
- throw new Error(`Cannot convert unknown operator ${node.meta.operator}`);
305
- }
306
- scope.importables.push({
307
- constructName: "Op",
308
- provider: "cdktn",
309
- });
310
- const fn = t.memberExpression(t.identifier("Op"), t.identifier(fnName));
311
- return t.callExpression(fn, [left, right]);
312
- }
313
- function convertTemplateExpressionToTs(scope, node) {
314
- const parts = node.children.map((child) => ({
315
- node: child,
316
- expr: convertTFExpressionAstToTs(scope, child),
317
- }));
318
- const lastPart = parts[parts.length - 1];
319
- if (t.isStringLiteral(lastPart.expr) && lastPart.expr.value === "\n") {
320
- // This is a bit of a hack, but the trailing newline we add due to
321
- // heredocs looks ugly and unnecessary in the generated code, so we
322
- // try to remove it
323
- parts.pop();
324
- }
325
- if (parts.length === 0) {
326
- return t.stringLiteral(node.meta.value);
327
- }
328
- if (parts.length === 1) {
329
- return parts[0].expr;
330
- }
331
- let isScopedTraversal = false;
332
- let expressions = [];
333
- for (const { node, expr } of parts) {
334
- if (hcl2json_2.TFExpressionSyntaxTree.isScopeTraversalExpression(node) &&
335
- !t.isStringLiteral(expr) &&
336
- !t.isCallExpression(expr)) {
337
- expressions.push(t.stringLiteral("${"));
338
- isScopedTraversal = true;
339
- }
340
- else if (
341
- // we should ideally be doing type coercion more
342
- // carefully here, because it may not always be needed
343
- t.isCallExpression(expr)) {
344
- scope.importables.push({
345
- constructName: "Token",
346
- provider: "cdktn",
347
- });
348
- expressions.push(template_1.default.expression(`Token.asString(%%expr%%)`)({
349
- expr,
350
- }));
351
- continue;
352
- }
353
- else {
354
- if (isScopedTraversal) {
355
- expressions.push(t.stringLiteral("}"));
356
- isScopedTraversal = false;
357
- }
358
- }
359
- expressions.push(expr);
360
- }
361
- if (isScopedTraversal) {
362
- expressions.push(t.stringLiteral("}"));
363
- }
364
- return expressionForSerialStringConcatenation(scope, expressions);
365
- }
366
- function convertObjectExpressionToTs(scope, node) {
367
- return t.objectExpression(Object.entries(node.meta.items)
368
- .map(([key, value]) => {
369
- const valueChild = (0, syntax_tree_1.getChildWithValue)(node, value);
370
- if (!valueChild) {
371
- utils_1.logger.error(`Unable to value for object key '${key}': ${value}`);
372
- return null;
373
- }
374
- return t.objectProperty(t.identifier(key), convertTFExpressionAstToTs(scope, valueChild));
375
- })
376
- .filter((s) => s !== null));
377
- }
378
- function convertFunctionCallExpressionToTs(scope, node) {
379
- const functionName = node.meta.name;
380
- const mapping = functions_1.functionsMap[functionName];
381
- if (!mapping) {
382
- utils_1.logger.error(`Unknown function ${functionName} encountered. ${utils_1.leaveCommentText}`);
383
- const argumentExpressions = node.children.map((child) => convertTFExpressionAstToTs(scope, child));
384
- return t.callExpression(t.identifier(functionName), argumentExpressions);
385
- }
386
- let transformedNode = mapping.transformer
387
- ? mapping.transformer(node)
388
- : node;
389
- const argumentExpressions = transformedNode.children.map((child) => convertTFExpressionAstToTs(scope, child));
390
- scope.importables.push({
391
- constructName: "Fn",
392
- provider: "cdktn",
393
- });
394
- const callee = t.memberExpression(t.identifier("Fn"), t.identifier(mapping.name));
395
- if (mapping.parameters.length > 0 &&
396
- mapping.parameters[mapping.parameters.length - 1].variadic) {
397
- const lastParameterType = mapping.parameters[mapping.parameters.length - 1].type;
398
- const nonVariadicArguments = argumentExpressions.slice(0, mapping.parameters.length - 1);
399
- const fnCallArguments = [
400
- ...nonVariadicArguments.map((argExpr, index) => (0, coerceType_1.coerceType)(scope, argExpr, (0, coerceType_1.findExpressionType)(scope, argExpr), mapping.parameters[index].type)),
401
- t.arrayExpression(argumentExpressions
402
- .slice(mapping.parameters.length - 1)
403
- .map((argExpr) => (0, coerceType_1.coerceType)(scope, argExpr, (0, coerceType_1.findExpressionType)(scope, argExpr), lastParameterType))),
404
- ];
405
- return t.callExpression(callee, fnCallArguments);
406
- }
407
- return t.callExpression(callee, argumentExpressions.map((argExpr, index) => (0, coerceType_1.coerceType)(scope, argExpr, (0, coerceType_1.findExpressionType)(scope, argExpr), mapping.parameters[index].type)));
408
- }
409
- function convertIndexExpressionToTs(scope, node) {
410
- const collectionExpressionChild = hcl2json_2.TFExpressionSyntaxTree.getChildWithValue(node, node.meta.collectionExpression);
411
- const keyExpressionChild = hcl2json_2.TFExpressionSyntaxTree.getChildWithValue(node, node.meta.keyExpression);
412
- const collectionExpression = convertTFExpressionAstToTs(scope, collectionExpressionChild);
413
- const keyExpression = convertTFExpressionAstToTs(scope, keyExpressionChild);
414
- scope.importables.push({
415
- constructName: "Fn",
416
- provider: "cdktn",
417
- });
418
- const callee = t.memberExpression(t.identifier("Fn"), t.identifier("lookupNested"));
419
- return t.callExpression(callee, [
420
- collectionExpression,
421
- t.arrayExpression([keyExpression]),
422
- ]);
423
- }
424
- function convertSplatExpressionToTs(scope, node) {
425
- const sourceExpressionChild = hcl2json_2.TFExpressionSyntaxTree.getChildWithValue(node, node.meta.sourceExpression);
426
- let sourceExpression = convertTFExpressionAstToTs(scope, sourceExpressionChild);
427
- // We don't convert the relative expression because everything after the splat is going to be
428
- // a string
429
- let relativeExpression = node.meta.eachExpression.startsWith(node.meta.anonSymbolExpression)
430
- ? node.meta.eachExpression.slice(node.meta.anonSymbolExpression.length)
431
- : node.meta.eachExpression;
432
- const segments = relativeExpression.split(/\.|\[|\]/).filter((s) => s);
433
- scope.importables.push({
434
- constructName: "Fn",
435
- provider: "cdktn",
436
- });
437
- const callee = t.memberExpression(t.identifier("Fn"), t.identifier("lookupNested"));
438
- return t.callExpression(callee, [
439
- sourceExpression,
440
- t.arrayExpression([
441
- // we don't need to use the anonSymbolExpression here because
442
- // it only changes between .* and [*] which we don't care about
443
- t.stringLiteral("*"),
444
- ...segments.map(t.stringLiteral),
445
- ]),
446
- ]);
447
- }
448
- function convertConditionalExpressionToTs(scope, node) {
449
- const conditionChild = hcl2json_2.TFExpressionSyntaxTree.getChildWithValue(node, node.meta.conditionExpression);
450
- let condition = convertTFExpressionAstToTs(scope, conditionChild);
451
- if (t.isIdentifier(condition) && canUseFqn(conditionChild)) {
452
- // We have a resource or data source here, which we would need to
453
- // reference using fqn
454
- condition = t.memberExpression(condition, t.identifier("fqn"));
455
- }
456
- const trueExpression = convertTFExpressionAstToTs(scope, hcl2json_2.TFExpressionSyntaxTree.getChildWithValue(node, node.meta.trueExpression));
457
- const falseExpression = convertTFExpressionAstToTs(scope, hcl2json_2.TFExpressionSyntaxTree.getChildWithValue(node, node.meta.falseExpression));
458
- scope.importables.push({
459
- constructName: "conditional",
460
- provider: "cdktn",
461
- });
462
- return t.callExpression(t.identifier("conditional"), [
463
- condition,
464
- trueExpression,
465
- falseExpression,
466
- ]);
467
- }
468
- function convertTupleExpressionToTs(scope, node) {
469
- const expressions = node.children.map((child) => convertTFExpressionAstToTs(scope, child));
470
- return t.arrayExpression(expressions);
471
- }
472
- function convertRelativeTraversalExpressionToTs(scope, node) {
473
- const segments = node.meta.traversal;
474
- // The left hand side / source of a relative traversal is not a proper
475
- // object / resource / data thing that is being referenced
476
- const source = convertTFExpressionAstToTs(scope, hcl2json_2.TFExpressionSyntaxTree.getChildWithValue(node, node.meta.sourceExpression));
477
- scope.importables.push({
478
- constructName: "Fn",
479
- provider: "cdktn",
480
- });
481
- const callee = t.memberExpression(t.identifier("Fn"), t.identifier("lookupNested"));
482
- return t.callExpression(callee, [
483
- source,
484
- t.arrayExpression(segments.map((s) => t.stringLiteral(s.segment))),
485
- ]);
486
- }
487
- function convertForExpressionToTs(scope, node) {
488
- const collectionChild = hcl2json_2.TFExpressionSyntaxTree.getChildWithValue(node, node.meta.collectionExpression);
489
- let collectionExpression = convertTFExpressionAstToTs(scope, collectionChild);
490
- if (t.isIdentifier(collectionExpression) && canUseFqn(collectionChild)) {
491
- // We have a resource or data source here, which we would need to
492
- // reference using fqn
493
- collectionExpression = t.memberExpression(collectionExpression, t.identifier("fqn"));
494
- }
495
- const collectionRequiresWrapping = !t.isStringLiteral(collectionExpression);
496
- const expressions = [];
497
- const conditionBody = node.meta.keyVar
498
- ? `${node.meta.keyVar}, ${node.meta.valVar}`
499
- : node.meta.valVar;
500
- const openBrace = node.meta.openRangeValue;
501
- const closeBrace = node.meta.closeRangeValue;
502
- const grouped = node.meta.groupedValue ? "..." : "";
503
- const valueExpression = `${node.meta.valueExpression}${grouped}`;
504
- const prefix = `\${${openBrace} for ${conditionBody} in `;
505
- const keyValue = node.meta.keyExpression
506
- ? ` : ${node.meta.keyExpression} => ${valueExpression}`
507
- : ` : ${valueExpression}`;
508
- const conditional = node.meta.conditionalExpression;
509
- const suffix = `${keyValue}${conditional ? ` if ${conditional}` : ""}${closeBrace}}`;
510
- expressions.push(t.stringLiteral(prefix));
511
- if (collectionRequiresWrapping) {
512
- expressions.push(t.stringLiteral("${"));
513
- }
514
- expressions.push(collectionExpression);
515
- if (collectionRequiresWrapping) {
516
- expressions.push(t.stringLiteral("}"));
517
- }
518
- expressions.push(t.stringLiteral(suffix));
519
- return expressionForSerialStringConcatenation(scope, expressions);
520
- }
521
- function convertTFExpressionAstToTs(scope, node) {
522
- if (hcl2json_2.TFExpressionSyntaxTree.isLiteralValueExpression(node)) {
523
- return convertLiteralValueExpressionToTs(scope, node);
524
- }
525
- if (hcl2json_2.TFExpressionSyntaxTree.isScopeTraversalExpression(node)) {
526
- return convertScopeTraversalExpressionToTs(scope, node);
527
- }
528
- if (hcl2json_2.TFExpressionSyntaxTree.isUnaryOpExpression(node)) {
529
- return convertUnaryOpExpressionToTs(scope, node);
530
- }
531
- if (hcl2json_2.TFExpressionSyntaxTree.isBinaryOpExpression(node)) {
532
- return convertBinaryOpExpressionToTs(scope, node);
533
- }
534
- if (hcl2json_2.TFExpressionSyntaxTree.isTemplateExpression(node) || hcl2json_2.TFExpressionSyntaxTree.isTemplateWrapExpression(node)) {
535
- return convertTemplateExpressionToTs(scope, node);
536
- }
537
- if (hcl2json_2.TFExpressionSyntaxTree.isObjectExpression(node)) {
538
- return convertObjectExpressionToTs(scope, node);
539
- }
540
- if (hcl2json_2.TFExpressionSyntaxTree.isFunctionCallExpression(node)) {
541
- return convertFunctionCallExpressionToTs(scope, node);
542
- }
543
- if (hcl2json_2.TFExpressionSyntaxTree.isIndexExpression(node)) {
544
- return convertIndexExpressionToTs(scope, node);
545
- }
546
- if (hcl2json_2.TFExpressionSyntaxTree.isSplatExpression(node)) {
547
- return convertSplatExpressionToTs(scope, node);
548
- }
549
- if (hcl2json_2.TFExpressionSyntaxTree.isConditionalExpression(node)) {
550
- return convertConditionalExpressionToTs(scope, node);
551
- }
552
- if (hcl2json_2.TFExpressionSyntaxTree.isTupleExpression(node)) {
553
- return convertTupleExpressionToTs(scope, node);
554
- }
555
- if (hcl2json_2.TFExpressionSyntaxTree.isRelativeTraversalExpression(node)) {
556
- return convertRelativeTraversalExpressionToTs(scope, node);
557
- }
558
- if (hcl2json_2.TFExpressionSyntaxTree.isForExpression(node)) {
559
- return convertForExpressionToTs(scope, node);
560
- }
561
- return t.stringLiteral("");
562
- }
563
- async function expressionAst(input) {
564
- const { wrap, wrapOffset } = (0, hcl2json_2.wrapTerraformExpression)(input);
565
- const ast = await (0, hcl2json_1.getExpressionAst)("main.tf", wrap);
566
- if (!ast) {
567
- throw new Error(`Unable to parse terraform expression: ${input}`);
568
- }
569
- if (wrapOffset != 0 && hcl2json_2.TFExpressionSyntaxTree.isTemplateWrapExpression(ast)) {
570
- return ast.children[0];
571
- }
572
- return ast;
573
- }
574
- exports.expressionAst = expressionAst;
575
- async function convertTerraformExpressionToTs(scope, input, targetType) {
576
- utils_1.logger.debug(`convertTerraformExpressionToTs(${input})`);
577
- const tsExpression = convertTFExpressionAstToTs(scope, await expressionAst(input));
578
- return (0, coerceType_1.coerceType)(scope, tsExpression, (0, coerceType_1.findExpressionType)(scope, tsExpression), targetType());
579
- }
580
- exports.convertTerraformExpressionToTs = convertTerraformExpressionToTs;
581
- async function extractIteratorVariablesFromExpression(input) {
582
- const possibleVariableSpots = await (0, hcl2json_1.getReferencesInExpression)("main.tf", input);
583
- return possibleVariableSpots
584
- .filter((spot) => spot.value.startsWith("each."))
585
- .map((spot) => ({
586
- start: spot.startPosition,
587
- end: spot.endPosition,
588
- value: spot.value,
589
- }));
590
- }
591
- exports.extractIteratorVariablesFromExpression = extractIteratorVariablesFromExpression;
592
- function dynamicVariableToAst(scope, node, iteratorName, block = "each") {
593
- if (iteratorName === "dynamic-block") {
594
- return expressionForSerialStringConcatenation(scope, [
595
- t.stringLiteral("${"),
596
- t.stringLiteral(block),
597
- t.stringLiteral("}"),
598
- ]);
599
- }
600
- if (node.meta.value === `${block}.key`) {
601
- return t.memberExpression(t.identifier(iteratorName), t.identifier("key"));
602
- }
603
- if (node.meta.value === `${block}.value`) {
604
- return t.memberExpression(t.identifier(iteratorName), t.identifier("value"));
605
- }
606
- if (block === "count" && node.meta.value === `${block}.index`) {
607
- return t.memberExpression(t.identifier(iteratorName), t.identifier("index"));
608
- }
609
- const segments = node.meta.traversal;
610
- if (segments.length > 2 &&
611
- segments[0].segment === block &&
612
- segments[1].segment === "value") {
613
- const segmentsAfterEachValue = segments.slice(2);
614
- scope.importables.push({
615
- constructName: "Fn",
616
- provider: "cdktn",
617
- });
618
- const callee = t.memberExpression(t.identifier("Fn"), t.identifier("lookupNested"));
619
- return t.callExpression(callee, [
620
- t.memberExpression(t.identifier(iteratorName), t.identifier("value")),
621
- t.arrayExpression(segmentsAfterEachValue.map((part) => {
622
- if (part.type === "nameTraversal") {
623
- return t.stringLiteral(part.segment);
624
- }
625
- else {
626
- return t.stringLiteral(`[${part.segment}]`);
627
- }
628
- })),
629
- ]);
630
- }
631
- throw new Error(`Can not create AST for iterator variable of '${node.meta.value}'`);
632
- }
633
- exports.dynamicVariableToAst = dynamicVariableToAst;
634
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXhwcmVzc2lvbnMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJleHByZXNzaW9ucy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBLCtCQUErQjtBQUMvQixtQ0FBbUM7QUFDbkMsZ0RBQWtDO0FBQ2xDLCtEQUF1QztBQUN2QyxtQ0FBOEQ7QUFNOUQsOENBQThFO0FBQzlFLDhDQUd5QjtBQUN6Qiw2REFBNkQ7QUFDN0QsNkNBQThEO0FBRTlELHVEQUFrRDtBQUNsRCw2Q0FBaUQ7QUFDakQsMkNBQTJDO0FBQzNDLGlFQUFvRTtBQUVwRSxNQUFNLHdCQUF3QixHQUFHO0lBQy9CLFNBQVMsRUFBRSxJQUFJO0lBQ2YsVUFBVSxFQUFFLEtBQUs7SUFDakIsV0FBVyxFQUFFLElBQUk7SUFDakIsa0JBQWtCLEVBQUUsS0FBSztJQUN6QixRQUFRLEVBQUUsSUFBSTtJQUNkLGVBQWUsRUFBRSxLQUFLO0lBQ3RCLEtBQUssRUFBRSxJQUFJO0lBQ1gsUUFBUSxFQUFFLEtBQUs7SUFDZixHQUFHLEVBQUUsS0FBSztJQUNWLFFBQVEsRUFBRSxLQUFLO0lBQ2YsUUFBUSxFQUFFLEtBQUs7SUFDZixNQUFNLEVBQUUsS0FBSztJQUNiLE1BQU0sRUFBRSxLQUFLO0NBQ2QsQ0FBQztBQUVGLE1BQU0sdUJBQXVCLEdBQUc7SUFDOUIsVUFBVSxFQUFFLEtBQUs7SUFDakIsTUFBTSxFQUFFLFFBQVE7Q0FDakIsQ0FBQztBQUtGLFNBQVMsc0JBQXNCLENBQzdCLFVBQXdDLEVBQ3hDLFFBQVEsR0FBRyxLQUFLO0lBRWhCLElBQUksSUFBSSxHQUFHLEVBQUUsQ0FBQztJQUNkLElBQUksUUFBUSxJQUFJLGlDQUFHLENBQUMsbUJBQW1CLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQztRQUN2RCxJQUFJLEdBQUcsR0FBRyxDQUFDO0lBQ2IsQ0FBQztJQUNELE9BQU8sVUFBVSxDQUFDLE1BQU0sQ0FB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cUJBQU0sQ0FBQztvQkFDTixPQUFPLENBQUMsQ0FBQyxhQUFhLENBQUMsSUFBSSxJQUFJLENBQUMsT0FBTyxHQUFHLENBQUMsQ0FBQztnQkFDOUMsQ0FBQztZQUNILENBQUMsQ0FBQyxDQUNIO1NBQ0YsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVELE1BQU0sSUFBSSxLQUFLLENBQ2IsZ0RBQWdELElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxHQUFHLENBQ25FLENBQUM7QUFDSixDQUFDO0FBL0RELG9EQStEQyIsInNvdXJjZXNDb250ZW50IjpbIi8vIENvcHlyaWdodCAoYykgSGFzaGlDb3JwLCBJbmNcbi8vIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBNUEwtMi4wXG5pbXBvcnQgKiBhcyB0IGZyb20gXCJAYmFiZWwvdHlwZXNcIjtcbmltcG9ydCB0ZW1wbGF0ZSBmcm9tIFwiQGJhYmVsL3RlbXBsYXRlXCI7XG5pbXBvcnQgeyBjYW1lbENhc2UsIGxlYXZlQ29tbWVudFRleHQsIGxvZ2dlciB9IGZyb20gXCIuL3V0aWxzXCI7XG5pbXBvcnQge1xuICBJdGVyYXRvclZhcmlhYmxlUmVmZXJlbmNlLFxuICBQcm9ncmFtU2NvcGUsXG4gIFJlc291cmNlU2NvcGUsXG59IGZyb20gXCIuL3R5cGVzXCI7XG5pbXBvcnQgeyBnZXRSZWZlcmVuY2VzSW5FeHByZXNzaW9uLCBnZXRFeHByZXNzaW9uQXN0IH0gZnJvbSBcIkBjZGt0bi9oY2wyanNvblwiO1xuaW1wb3J0IHtcbiAgVEZFeHByZXNzaW9uU3ludGF4VHJlZSBhcyB0ZXgsXG4gIHdyYXBUZXJyYWZvcm1FeHByZXNzaW9uLFxufSBmcm9tIFwiQGNka3RuL2hjbDJqc29uXCI7XG5pbXBvcnQgeyBmdW5jdGlvbnNNYXAgfSBmcm9tIFwiLi9mdW5jdGlvbi1iaW5kaW5ncy9mdW5jdGlvbnNcIjtcbmltcG9ydCB7IGNvZXJjZVR5cGUsIGZpbmRFeHByZXNzaW9uVHlwZSB9IGZyb20gXCIuL2NvZXJjZVR5cGVcIjtcbmltcG9ydCB7IEF0dHJpYnV0ZVR5cGUgfSBmcm9tIFwiQGNka3RuL2NvbW1vbnNcIjtcbmltcG9ydCB7IGdldFR5cGVBdFBhdGggfSBmcm9tIFwiLi90ZXJyYWZvcm1TY2hlbWFcIjtcbmltcG9ydCB7IGNvbnRhaW5zUmVmZXJlbmNlIH0gZnJvbSBcIi4vcmVmZXJlbmNlc1wiO1xuaW1wb3J0IHsgdmFyaWFibGVOYW1lIH0gZnJvbSBcIi4vdmFyaWFibGVzXCI7XG5pbXBvcnQgeyBnZXRDaGlsZFdpdGhWYWx1ZSB9IGZyb20gXCJAY2RrdG4vaGNsMmpzb24vbGliL3N5bnRheC10cmVlXCI7XG5cbmNvbnN0IHRmQmluYXJ5T3BlcmF0b3JzVG9DZGt0ZiA9IHtcbiAgbG9naWNhbE9yOiBcIm9yXCIsXG4gIGxvZ2ljYWxBbmQ6IFwiYW5kXCIsXG4gIGdyZWF0ZXJUaGFuOiBcImd0XCIsXG4gIGdyZWF0ZXJUaGFuT3JFcXVhbDogXCJndGVcIixcbiAgbGVzc1RoYW46IFwibHRcIixcbiAgbGVzc1RoYW5PckVxdWFsOiBcImx0ZVwiLFxuICBlcXVhbDogXCJlcVwiLFxuICBub3RFcXVhbDogXCJuZXFcIixcbiAgYWRkOiBcImFkZFwiLFxuICBzdWJ0cmFjdDogXCJzdWJcIixcbiAgbXVsdGlwbHk6IFwibXVsXCIsXG4gIGRpdmlkZTogXCJkaXZcIixcbiAgbW9kdWxvOiBcIm1vZFwiLFxufTtcblxuY29uc3QgdGZVbmFyeU9wZXJhdG9yc1RvQ2RrdGYgPSB7XG4gIGxvZ2ljYWxOb3Q6IFwibm90XCIsXG4gIG5lZ2F0ZTogXCJuZWdhdGVcIixcbn07XG5cbnR5cGUgc3VwcG9ydGVkQmluYXJ5T3BlcmF0b3JzID0ga2V5b2YgdHlwZW9mIHRmQmluYXJ5T3BlcmF0b3JzVG9DZGt0ZjtcbnR5cGUgc3VwcG9ydGVkVW5hcnlPcGVyYXRvcnMgPSBrZXlvZiB0eXBlb2YgdGZVbmFyeU9wZXJhdG9yc1RvQ2RrdGY7XG5cbmZ1bmN0aW9uIHRyYXZlcnNhbFBhcnRzVG9TdHJpbmcoXG4gIHRyYXZlcnNhbHM6IHRleC5UZXJyYWZvcm1UcmF2ZXJzYWxQYXJ0W10sXG4gIGFzU3VmZml4ID0gZmFsc2UsXG4pIHtcbiAgbGV0IHNlZWQgPSBcIlwiO1xuICBpZiAoYXNTdWZmaXggJiYgdGV4LmlzTmFtZVRyYXZlcnNhbFBhcnQodHJhdmVyc2Fsc1swXSkpIHtcbiAgICBzZWVkID0gXCIuXCI7XG4gIH1cbiAgcmV0dXJuIHRyYXZlcnNhbHMucmVkdWNlKChhY2MsIHBhcnQpID0+IHtcbiAgICBpZiAocGFydC50eXBlID09PSBcIm5hbWVUcmF2ZXJzYWxcIikge1xuICAgICAgaWYgKGFjYyA9PT0gc2VlZCkge1xuICAgICAgICByZXR1cm4gYCR7YWNjfSR7cGFydC5zZWdtZW50fWA7XG4gICAgICB9XG4gICAgICByZXR1cm4gYCR7YWNjfS4ke3BhcnQuc2VnbWVudH1gO1xuICAgIH1cbiAgICByZXR1cm4gYCR7YWNjfVske3BhcnQuc2VnbWVudH1dYDtcbiAgfSwgc2VlZCk7XG59XG5cbmZ1bmN0aW9uIGNhblVzZUZxbihleHByZXNzaW9uOiB0ZXguRXhwcmVzc2lvblR5cGUpIHtcbiAgaWYgKCF0ZXguaXNTY29wZVRyYXZlcnNhbEV4cHJlc3Npb24oZXhwcmVzc2lvbikpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICBjb25zdCByb290U2VnbWVudCA9IGV4cHJlc3Npb24ubWV0YS50cmF2ZXJzYWxbMF0uc2VnbWVudDtcblxuICByZXR1cm4gIVtcInZhclwiLCBcImxvY2FsXCJdLmluY2x1ZGVzKHJvb3RTZWdtZW50KTtcbn1cblxuZnVuY3Rpb24gdHJhdmVyc2FsVG9WYXJpYWJsZU5hbWUoXG4gIHNjb3BlOiBQcm9ncmFtU2NvcGUsXG4gIG5vZGU6IHRleC5FeHByZXNzaW9uVHlwZSxcbikge1xuICBpZiAoIXRleC5pc1Njb3BlVHJhdmVyc2FsRXhwcmVzc2lvbihub2RlKSkge1xuICAgIGxvZ2dlci5lcnJvcihcbiAgICAgIGBVbmV4cGVjdGVkIGV4cHJlc3Npb24gdHlwZSAke25vZGUudHlwZX0gd2l0aCB2YWx1ZSAke25vZGUubWV0YS52YWx1ZX0gcGFzc2VkIHRvIGNvbnZlcnQgdG8gYSB2YXJpYWJsZS4gXG4gICAgICAgICR7bGVhdmVDb21tZW50VGV4dH1gLFxuICAgICk7XG4gICAgcmV0dXJuIFwiXCI7XG4gIH1cblxuICBjb25zdCBzZWdtZW50cyA9IG5vZGUubWV0YS50cmF2ZXJzYWw7XG4gIGlmIChzZWdtZW50cy5sZW5ndGggPT09IDEpIHtcbiAgICByZXR1cm4gbm9kZS5tZXRhLmZ1bGxBY2Nlc3NvcjtcbiAgfVxuICBjb25zdCByb290U2VnbWVudCA9IHNlZ21lbnRzWzBdLnNlZ21lbnQ7XG4gIGNvbnN0IHJlc291cmNlID1cbiAgICByb290U2VnbWVudCA9PT0gXCJkYXRhXCJcbiAgICAgID8gYCR7c2VnbWVudHNbMF0uc2VnbWVudH0uJHtzZWdtZW50c1sxXS5zZWdtZW50fWBcbiAgICAgIDogcm9vdFNlZ21lbnQ7XG4gIGNvbnN0IG5hbWUgPVxuICAgIHJvb3RTZWdtZW50ID09PSBcImRhdGFcIiA/IHNlZ21lbnRzWzJdLnNlZ21lbnQgOiBzZWdtZW50c1sxXS5zZWdtZW50O1xuXG4gIHJldHVybiB2YXJpYWJsZU5hbWUoc2NvcGUsIHJlc291cmNlLCBuYW1lKTtcbn1cblxuZnVuY3Rpb24gZXhwcmVzc2lvbkZvclNlcmlhbFN0cmluZ0NvbmNhdGVuYXRpb24oXG4gIHNjb3BlOiBSZXNvdXJjZVNjb3BlLFxuICBub2RlczogdC5FeHByZXNzaW9uW10sXG4pIHtcbiAgY29uc3QgcmVkdWNlZE5vZGVzID0gbm9kZXMucmVkdWNlKChhY2MsIG5vZGUpID0+IHtcbiAgICBjb25zdCBwcmV2ID0gYWNjW2FjYy5sZW5ndGggLSAxXTtcbiAgICBpZiAoIXByZXYpIHJldHVybiBbbm9kZV07XG5cbiAgICBpZiAodC5pc1N0cmluZ0xpdGVyYWwocHJldikgJiYgdC5pc1N0cmluZ0xpdGVyYWwobm9kZSkpIHtcbiAgICAgIGFjYy5wb3AoKTtcbiAgICAgIGFjYy5wdXNoKHQuc3RyaW5nTGl0ZXJhbChwcmV2LnZhbHVlICsgbm9kZS52YWx1ZSkpO1xuICAgICAgcmV0dXJuIGFjYztcbiAgICB9XG5cbiAgICBhY2MucHVzaChub2RlKTtcbiAgICByZXR1cm4gYWNjO1xuICB9LCBbXSBhcyB0LkV4cHJlc3Npb25bXSk7XG5cbiAgcmV0dXJuIHJlZHVjZWROb2Rlcy5yZWR1Y2UoXG4gICAgKGFjYzogdC5FeHByZXNzaW9uIHwgdW5kZWZpbmVkLCBub2RlOiB0LkV4cHJlc3Npb24pID0+IHtcbiAgICAgIGlmICghYWNjKSB7XG4gICAgICAgIHJldHVybiBub2RlO1xuICAgICAgfVxuXG4gICAgICAvLyB3cmFwIGFjY2VzcyB0byBkeW5hbWljIGJsb2NrcyBpbiBUb2tlbi5hc1N0cmluZygpIGFzIHRoZXkgcmV0dXJuIGEgTGF6eVxuICAgICAgLy8gZm9yIC5rZXkgYW5kIC52YWx1ZSB3aGljaCBjYW4ndCBiZSBjb25jYXRlbmF0ZWQgaW4gbGFuZ3VhZ2VzIGxpa2UgUHl0aG9uXG4gICAgICAvLyBiZWNhdXNlIEpTSUkgY3VycmVudGx5IGhhcyBubyBzdXBwb3J0IGZvciB0aGUgdG9TdHJpbmcoKSBtZXRob2QgaW5cbiAgICAgIC8vIGxhbmd1YWdlcyBvdGhlciB0aGFuIFR5cGVTY3JpcHQ6IGh0dHBzOi8vZ2l0aHViLmNvbS9hd3MvanNpaS9pc3N1ZXMvMzgwXG4gICAgICAvLyBleGFtcGxlOiBkeW5hbWljX2l0ZXJhdG9yMC5rZXkgLyBkeW5hbWljX2l0ZXJhdG9yMC52YWx1ZVxuICAgICAgaWYgKFxuICAgICAgICB0LmlzTWVtYmVyRXhwcmVzc2lvbihub2RlKSAmJlxuICAgICAgICB0LmlzSWRlbnRpZmllcihub2RlLm9iamVjdCkgJiZcbiAgICAgICAgT2JqZWN0LnZhbHVlcyhzY29wZS5zY29wZWRWYXJpYWJsZXMgfHwge30pLmluY2x1ZGVzKG5vZGUub2JqZWN0Lm5hbWUpICYmXG4gICAgICAgIHQuaXNJZGVudGlmaWVyKG5vZGUucHJvcGVydHkpICYmXG4gICAgICAgIFtcImtleVwiLCBcInZhbHVlXCJdLmluY2x1ZGVzKG5vZGUucHJvcGVydHkubmFtZSlcbiAgICAgICkge1xuICAgICAgICBub2RlID0gY29lcmNlVHlwZShzY29wZSwgbm9kZSwgXCJkeW5hbWljXCIsIFwic3RyaW5nXCIpO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gdC5iaW5hcnlFeHByZXNzaW9uKFwiK1wiLCBhY2MgYXMgdC5FeHByZXNzaW9uLCBub2RlKTtcbiAgICB9LFxuICApO1xufVxuXG5mdW5jdGlvbiBnZXRUZlJlc291cmNlUGF0aEZyb21Ob2RlKG5vZGU6IHRleC5TY29wZVRyYXZlcnNhbEV4cHJlc3Npb24pIHtcbiAgY29uc3Qgc2VnbWVudHMgPSBub2RlLm1ldGEudHJhdmVyc2FsO1xuICBsZXQgcmVzb3VyY2UgPSBzZWdtZW50c1swXS5zZWdtZW50O1xuICBsZXQgcmVzdWx0ID0gW107XG4gIGxldCBhdHRyaWJ1dGVzID0gW107XG5cbiAgaWYgKHNlZ21lbnRzWzBdLnNlZ21lbnQgPT09IFwiZGF0YVwiKSB7XG4gICAgcmVzdWx0LnB1c2goc2VnbWVudHNbMF0uc2VnbWVudCk7XG4gICAgcmVzb3VyY2UgPSBzZWdtZW50c1sxXS5zZWdtZW50O1xuICAgIGF0dHJpYnV0ZXMgPSBzZWdtZW50cy5zbGljZSgzKTsgLy8gd2Ugd2FudCB0byBza2lwIHRoZSB2YXJpYWJsZSBuYW1lXG4gIH0gZWxzZSB7XG4gICAgYXR0cmlidXRlcyA9IHNlZ21lbnRzLnNsaWNlKDIpOyAvLyB3ZSB3YW50IHRvIHNraXAgdGhlIHZhcmlhYmxlIG5hbWVcbiAgfVxuXG4gIGNvbnN0IFtwcm92aWRlciwgLi4ucmVzb3VyY2VOYW1lRnJhZ21lbnRzXSA9IHJlc291cmNlLnNwbGl0KFwiX1wiKTtcblxuICAvLyBIYWNrOiBUaGlzIGhhcHBlbnMgaW4gdGhlIGNhc2Ugb2YgYGV4dGVybmFsYCBwcm92aWRlclxuICAvLyB3aGVyZSB0aGUgZGF0YSBzb3VyY2UgZG9lcyBub3QgaGF2ZSBhIHByb3ZpZGVyIG5hbWUgcHJlZml4XG4gIGlmIChyZXNvdXJjZU5hbWVGcmFnbWVudHMubGVuZ3RoID09PSAwKSB7XG4gICAgcmVzb3VyY2VOYW1lRnJhZ21lbnRzLnB1c2gocHJvdmlkZXIpO1xuICB9XG5cbiAgcmVzdWx0LnB1c2gocHJvdmlkZXIpO1xuICByZXN1bHQucHVzaChyZXNvdXJjZU5hbWVGcmFnbWVudHMuam9pbihcIl9cIikpO1xuICByZXN1bHQgPSBbXG4gICAgLi4ucmVzdWx0LFxuICAgIC4uLmF0dHJpYnV0ZXMubWFwKChzZWcpID0+IHtcbiAgICAgIGlmICh0ZXguaXNJbmRleFRyYXZlcnNhbFBhcnQoc2VnKSkge1xuICAgICAgICByZXR1cm4gYFske3NlZy5zZWdtZW50fV1gO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHNlZy5zZWdtZW50O1xuICAgIH0pLFxuICBdO1xuXG4gIHJldHVybiByZXN1bHQuam9pbihcIi5cIik7XG59XG5cbmZ1bmN0aW9uIGNvbnZlcnRMaXRlcmFsVmFsdWVFeHByZXNzaW9uVG9UcyhcbiAgX3Njb3BlOiBSZXNvdXJjZVNjb3BlLFxuICBub2RlOiB0ZXguTGl0ZXJhbFZhbHVlRXhwcmVzc2lvbixcbikge1xuICBjb25zdCBsaXRlcmFsVHlwZSA9IG5vZGUubWV0YS50eXBlO1xuICBpZiAobGl0ZXJhbFR5cGUgPT09IFwibnVtYmVyXCIpIHtcbiAgICByZXR1cm4gdC5udW1lcmljTGl0ZXJhbChOdW1iZXIobm9kZS5tZXRhLnZhbHVlKSk7XG4gIH1cbiAgaWYgKGxpdGVyYWxUeXBlID09PSBcImJvb2xcIikge1xuICAgIHJldHVybiB0LmJvb2xlYW5MaXRlcmFsKG5vZGUubWV0YS52YWx1ZSA9PT0gXCJ0cnVlXCIgPyB0cnVlIDogZmFsc2UpO1xuICB9XG5cbiAgcmV0dXJuIHQuc3RyaW5nTGl0ZXJhbChub2RlLm1ldGEudmFsdWUpO1xufVxuXG5mdW5jdGlvbiBjb252ZXJ0U2NvcGVUcmF2ZXJzYWxFeHByZXNzaW9uVG9UcyhcbiAgc2NvcGU6IFJlc291cmNlU2NvcGUsXG4gIG5vZGU6IHRleC5TY29wZVRyYXZlcnNhbEV4cHJlc3Npb24sXG4pIHtcbiAgY29uc3QgaGFzUmVmZXJlbmNlID0gY29udGFpbnNSZWZlcmVuY2Uobm9kZSk7XG5cbiAgY29uc3Qgc2VnbWVudHMgPSBub2RlLm1ldGEudHJhdmVyc2FsO1xuXG4gIGlmIChzZWdtZW50c1swXS5zZWdtZW50ID09PSBcImVhY2hcIiAmJiBzY29wZS5mb3JFYWNoSXRlcmF0b3JOYW1lKSB7XG4gICAgcmV0dXJuIGR5bmFtaWNWYXJpYWJsZVRvQXN0KHNjb3BlLCBub2RlLCBzY29wZS5mb3JFYWNoSXRlcmF0b3JOYW1lKTtcbiAgfVxuXG4gIGlmIChzZWdtZW50c1swXS5zZWdtZW50ID09PSBcImNvdW50XCIgJiYgc2NvcGUuY291bnRJdGVyYXRvck5hbWUpIHtcbiAgICByZXR1cm4gZHluYW1pY1ZhcmlhYmxlVG9Bc3Qoc2NvcGUsIG5vZGUsIHNjb3BlLmNvdW50SXRlcmF0b3JOYW1lLCBcImNvdW50XCIpO1xuICB9XG5cbiAgaWYgKHNlZ21lbnRzWzBdLnNlZ21lbnQgPT09IFwic2VsZlwiKSB7XG4gICAgc2NvcGUuaW1wb3J0YWJsZXMucHVzaCh7XG4gICAgICBjb25zdHJ1Y3ROYW1lOiBcIlRlcnJhZm9ybVNlbGZcIixcbiAgICAgIHByb3ZpZGVyOiBcImNka3RuXCIsXG4gICAgfSk7XG5cbiAgICByZXR1cm4gdC5jYWxsRXhwcmVzc2lvbihcbiAgICAgIHQubWVtYmVyRXhwcmVzc2lvbih0LmlkZW50aWZpZXIoXCJUZXJyYWZvcm1TZWxmXCIpLCB0LmlkZW50aWZpZXIoXCJnZXRBbnlcIikpLFxuXG4gICAgICBbdC5zdHJpbmdMaXRlcmFsKHRyYXZlcnNhbFBhcnRzVG9TdHJpbmcoc2VnbWVudHMuc2xpY2UoMSkpKV0sXG4gICAgKTtcbiAgfVxuXG4gIC8vIHNldHRpbmcudmFsdWUsIHNldHRpbmcudmFsdWVbMV0uaWRcbiAgY29uc3QgZHluYW1pY0Jsb2NrID0gc2NvcGUuc2NvcGVkVmFyaWFibGVzPy5bc2VnbWVudHNbMF0uc2VnbWVudF07XG4gIGlmIChkeW5hbWljQmxvY2spIHtcbiAgICBpZiAoZHluYW1pY0Jsb2NrID09PSBcImR5bmFtaWMtYmxvY2tcIikge1xuICAgICAgcmV0dXJuIGR5bmFtaWNWYXJpYWJsZVRvQXN0KFxuICAgICAgICBzY29wZSxcbiAgICAgICAgbm9kZSxcbiAgICAgICAgZHluYW1pY0Jsb2NrLFxuICAgICAgICB0cmF2ZXJzYWxQYXJ0c1RvU3RyaW5nKHNlZ21lbnRzKSxcbiAgICAgICk7XG4gICAgfVxuICAgIHJldHVybiBkeW5hbWljVmFyaWFibGVUb0FzdChzY29wZSwgbm9kZSwgZHluYW1pY0Jsb2NrLCBzZWdtZW50c1swXS5zZWdtZW50KTtcbiAgfVxuXG4gIC8vIFRoaXMgbWF5IGJlIGEgdmFyaWFibGUgcmVmZXJlbmNlIHRoYXQgd2UgZG9uJ3QgdW5kZXJzdGFuZCB5ZXQsIHNvIHdlIHdyYXAgaXQgaW4gYSB0ZW1wbGF0ZSBzdHJpbmdcbiAgLy8gZm9yIFRlcnJhZm9ybSB0byBoYW5kbGVcbiAgbGV0IHZhcklkZW50aWZpZXI6IHQuRXhwcmVzc2lvbiA9IHQuc3RyaW5nTGl0ZXJhbChcbiAgICBgXFwkeyR7bm9kZS5tZXRhLmZ1bGxBY2Nlc3Nvcn19YCxcbiAgKTtcblxuICBpZiAoaGFzUmVmZXJlbmNlKSB7XG4gICAgdmFySWRlbnRpZmllciA9IHQuaWRlbnRpZmllcihcbiAgICAgIGNhbWVsQ2FzZSh0cmF2ZXJzYWxUb1ZhcmlhYmxlTmFtZShzY29wZSwgbm9kZSkpLFxuICAgICk7XG4gIH1cblxuICBpZiAoW1widmFyXCIsIFwibG9jYWxcIl0uaW5jbHVkZXMoc2VnbWVudHNbMF0uc2VnbWVudCkpIHtcbiAgICBjb25zdCB2YXJpYWJsZUFjY2Vzc29yID1cbiAgICAgIHNlZ21lbnRzWzBdLnNlZ21lbnQgPT09IFwidmFyXCJcbiAgICAgICAgPyB0Lm1lbWJlckV4cHJlc3Npb24odmFySWRlbnRpZmllciwgdC5pZGVudGlmaWVyKFwidmFsdWVcIikpXG4gICAgICAgIDogdmFySWRlbnRpZmllcjtcblxuICAgIGlmIChzZWdtZW50cy5sZW5ndGggPiAyKSB7XG4gICAgICBzY29wZS5pbXBvcnRhYmxlcy5wdXNoKHtcbiAgICAgICAgY29uc3RydWN0TmFtZTogXCJGblwiLFxuICAgICAgICBwcm92aWRlcjogXCJjZGt0blwiLFxuICAgICAgfSk7XG4gICAgICBjb25zdCBjYWxsZWUgPSB0Lm1lbWJlckV4cHJlc3Npb24oXG4gICAgICAgIHQuaWRlbnRpZmllcihcIkZuXCIpLFxuICAgICAgICB0LmlkZW50aWZpZXIoXCJsb29rdXBOZXN0ZWRcIiksXG4gICAgICApO1xuICAgICAgcmV0dXJuIHQuY2FsbEV4cHJlc3Npb24oY2FsbGVlLCBbXG4gICAgICAgIHZhcmlhYmxlQWNjZXNzb3IsXG4gICAgICAgIHQuYXJyYXlFeHByZXNzaW9uKFxuICAgICAgICAgIHNlZ21lbnRzLnNsaWNlKDIpLm1hcCgocykgPT4gdC5zdHJpbmdMaXRlcmFsKHMuc2VnbWVudCkpLFxuICAgICAgICApLFxuICAgICAgXSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHZhcmlhYmxlQWNjZXNzb3I7XG4gIH1cblxuICBpZiAoIWhhc1JlZmVyZW5jZSB8fCBzY29wZS53aXRoaW5PdmVycmlkZUV4cHJlc3Npb24pIHtcbiAgICByZXR1cm4gdmFySWRlbnRpZmllcjtcbiAgfVxuXG4gIGNvbnN0IHJvb3RTZWdtZW50ID0gc2VnbWVudHNbMF0uc2VnbWVudDtcbiAgY29uc3QgYXR0cmlidXRlSW5kZXggPSByb290U2VnbWVudCA9PT0gXCJkYXRhXCIgPyAzIDogMjtcbiAgY29uc3QgYXR0cmlidXRlU2VnbWVudHMgPSBzZWdtZW50cy5zbGljZShhdHRyaWJ1dGVJbmRleCk7XG4gIGNvbnN0IG51bWVyaWNBY2Nlc3NvckluZGV4ID0gYXR0cmlidXRlU2VnbWVudHMuZmluZEluZGV4KChzZWcpID0+XG4gICAgdGV4LmlzSW5kZXhUcmF2ZXJzYWxQYXJ0KHNlZyksXG4gICk7XG4gIGxldCBtaW5BY2Nlc3NvckluZGV4ID0gbnVtZXJpY0FjY2Vzc29ySW5kZXg7XG4gIGxldCBtYXBBY2Nlc3NvckluZGV4ID0gLTE7XG4gIGlmIChudW1lcmljQWNjZXNzb3JJbmRleCA9PT0gLTEpIHtcbiAgICAvLyBvbmx5IGRvIHRoaXMgaWYgd2UgaGF2ZSB0bywgaWYgd2UgYWxyZWFkeSBoYXZlIGFcbiAgICAvLyBudW1lcmljIGFjY2Vzc29yLCB3ZSBkb24ndCBoYXZlIHRvIGRvIHRoaXMgYWRkaXRpb25hbCB3b3JrXG4gICAgY29uc3QgcmVzb3VyY2VQYXRoID0gZ2V0VGZSZXNvdXJjZVBhdGhGcm9tTm9kZShub2RlKTtcbiAgICBsZXQgdXNpbmdTdWJQYXRoVHlwZSA9IGZhbHNlO1xuICAgIGxldCBwYXJ0cyA9IHJlc291cmNlUGF0aC5zcGxpdChcIi5cIikuZmlsdGVyKChwKSA9PiBwICE9PSBcIlwiKTtcbiAgICBjb25zdCBtaW5QYXJ0cyA9IGF0dHJpYnV0ZUluZGV4OyAvLyB3ZSBuZWVkIHRvIHN0b3AgYmVmb3JlIGRhdGEuYXdzLnJlc291cmNlX25hbWUgb3IgYXdzLnJlc291cmNlX25hbWVcbiAgICBjb25zdCBvcmlnaW5hbFBhcnRzID0gcGFydHMubGVuZ3RoO1xuICAgIGxldCBoYXNNYXBBY2Nlc3NvciA9IGZhbHNlO1xuICAgIHdoaWxlIChwYXJ0cy5sZW5ndGggPj0gbWluUGFydHMpIHtcbiAgICAgIGNvbnN0IHR5cGUgPSBnZXRUeXBlQXRQYXRoKHNjb3BlLnByb3ZpZGVyU2NoZW1hLCBwYXJ0cy5qb2luKFwiLlwiKSk7XG4gICAgICBpZiAodHlwZSAhPT0gbnVsbCkge1xuICAgICAgICBpZiAoQXJyYXkuaXNBcnJheSh0eXBlKSAmJiB0eXBlWzBdID09PSBcIm1hcFwiICYmIHVzaW5nU3ViUGF0aFR5cGUpIHtcbiAgICAgICAgICBoYXNNYXBBY2Nlc3NvciA9IHRydWU7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHBhcnRzLnBvcCgpO1xuICAgICAgdXNpbmdTdWJQYXRoVHlwZSA9IHRydWU7XG4gICAgfVxuXG4gICAgaWYgKGhhc01hcEFjY2Vzc29yKSB7XG4gICAgICBtYXBBY2Nlc3NvckluZGV4ID0gb3JpZ2luYWxQYXJ0cyAtIHBhcnRzLmxlbmd0aCAtIDE7XG4gICAgICBtaW5BY2Nlc3NvckluZGV4ID0gbWFwQWNjZXNzb3JJbmRleDtcbiAgICB9XG4gIH1cblxuICBjb25zdCBuZWVkc1Byb3BlcnR5QWNjZXNzID0gbWluQWNjZXNzb3JJbmRleCA+PSAwO1xuXG4gIGNvbnN0IHJlZlNlZ21lbnRzID0gbmVlZHNQcm9wZXJ0eUFjY2Vzc1xuICAgID8gYXR0cmlidXRlU2VnbWVudHMuc2xpY2UoMCwgbWluQWNjZXNzb3JJbmRleClcbiAgICA6IGF0dHJpYnV0ZVNlZ21lbnRzO1xuICBjb25zdCBub25SZWZTZWdtZW50cyA9IG5lZWRzUHJvcGVydHlBY2Nlc3NcbiAgICA/IGF0dHJpYnV0ZVNlZ21lbnRzLnNsaWNlKG1pbkFjY2Vzc29ySW5kZXgpXG4gICAgOiBbXTtcblxuICBjb25zdCByZWYgPSByZWZTZWdtZW50cy5yZWR1Y2UoXG4gICAgKGFjYzogdC5FeHByZXNzaW9uLCBzZWcsIGluZGV4KSA9PlxuICAgICAgdC5tZW1iZXJFeHByZXNzaW9uKFxuICAgICAgICBhY2MsXG4gICAgICAgIHQuaWRlbnRpZmllcihcbiAgICAgICAgICBpbmRleCA9PT0gMCAmJiByb290U2VnbWVudCA9PT0gXCJtb2R1bGVcIlxuICAgICAgICAgICAgPyBjYW1lbENhc2Uoc2VnLnNlZ21lbnQgKyBcIk91dHB1dFwiKVxuICAgICAgICAgICAgOiBjYW1lbENhc2Uoc2VnLnNlZ21lbnQpLFxuICAgICAgICApLFxuICAgICAgKSxcbiAgICB2YXJJZGVudGlmaWVyLFxuICApO1xuXG4gIGlmIChub25SZWZTZWdtZW50cy5sZW5ndGggPT09IDApIHtcbiAgICByZXR1cm4gcmVmO1xuICB9XG5cbiAgc2NvcGUuaW1wb3J0YWJsZXMucHVzaCh7XG4gICAgY29uc3RydWN0TmFtZTogXCJGblwiLFxuICAgIHByb3ZpZGVyOiBcImNka3RuXCIsXG4gIH0pO1xuICBjb25zdCBjYWxsZWUgPSB0Lm1lbWJlckV4cHJlc3Npb24oXG4gICAgdC5pZGVudGlmaWVyKFwiRm5cIiksXG4gICAgdC5pZGVudGlmaWVyKFwibG9va3VwTmVzdGVkXCIpLFxuICApO1xuICByZXR1cm4gdC5jYWxsRXhwcmVzc2lvbihjYWxsZWUsIFtcbiAgICByZWYsXG4gICAgdC5hcnJheUV4cHJlc3Npb24obm9uUmVmU2VnbWVudHMubWFwKChzKSA9PiB0LnN0cmluZ0xpdGVyYWwocy5zZWdtZW50KSkpLFxuICBdKTtcbn1cblxuZnVuY3Rpb24gY29udmVydFVuYXJ5T3BFeHByZXNzaW9uVG9UcyhcbiAgc2NvcGU6IFJlc291cmNlU2NvcGUsXG4gIG5vZGU6IHRleC5VbmFyeU9wRXhwcmVzc2lvbixcbikge1xuICBjb25zdCBvcGVyYW5kID0gY29udmVydFRGRXhwcmVzc2lvbkFzdFRvVHMoXG4gICAgc2NvcGUsXG4gICAgdGV4LmdldENoaWxkV2l0aFZhbHVlKG5vZGUsIG5vZGUubWV0YS52YWx1ZUV4cHJlc3Npb24pISxcbiAgKTtcblxuICBsZXQgZm5OYW1lID0gbm9kZS5tZXRhLm9wZXJhdG9yO1xuICBpZiAodGZVbmFyeU9wZXJhdG9yc1RvQ2RrdGZbZm5OYW1lIGFzIHN1cHBvcnRlZFVuYXJ5T3BlcmF0b3JzXSkge1xuICAgIGZuTmFtZSA9IHRmVW5hcnlPcGVyYXRvcnNUb0Nka3RmW2ZuTmFtZSBhcyBzdXBwb3J0ZWRVbmFyeU9wZXJhdG9yc107XG4gIH0gZWxzZSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBDYW5ub3QgY29udmVydCB1bmtub3duIG9wZXJhdG9yICR7bm9kZS5tZXRhLm9wZXJhdG9yfWApO1xuICB9XG5cbiAgc2NvcGUuaW1wb3J0YWJsZXMucHVzaCh7XG4gICAgY29uc3RydWN0TmFtZTogXCJPcFwiLFxuICAgIHByb3ZpZGVyOiBcImNka3RuXCIsXG4gIH0pO1xuXG4gIGNvbnN0IGZuID0gdC5tZW1iZXJFeHByZXNzaW9uKHQuaWRlbnRpZmllcihcIk9wXCIpLCB0LmlkZW50aWZpZXIoZm5OYW1lKSk7XG5cbiAgcmV0dXJuIHQuY2FsbEV4cHJlc3Npb24oZm4sIFtvcGVyYW5kXSk7XG59XG5cbmZ1bmN0aW9uIGNvbnZlcnRCaW5hcnlPcEV4cHJlc3Npb25Ub1RzKFxuICBzY29wZTogUmVzb3VyY2VTY29wZSxcbiAgbm9kZTogdGV4LkJpbmFyeU9wRXhwcmVzc2lvbixcbikge1xuICBjb25zdCBsZWZ0ID0gY29udmVydFRGRXhwcmVzc2lvbkFzdFRvVHMoXG4gICAgc2NvcGUsXG4gICAgdGV4LmdldENoaWxkV2l0aFZhbHVlKG5vZGUsIG5vZGUubWV0YS5saHNFeHByZXNzaW9uKSEsXG4gICk7XG4gIGNvbnN0IHJpZ2h0ID0gY29udmVydFRGRXhwcmVzc2lvbkFzdFRvVHMoXG4gICAgc2NvcGUsXG4gICAgdGV4LmdldENoaWxkV2l0aFZhbHVlKG5vZGUsIG5vZGUubWV0YS5yaHNFeHByZXNzaW9uKSEsXG4gICk7XG5cbiAgbGV0IGZuTmFtZSA9IG5vZGUubWV0YS5vcGVyYXRvcjtcbiAgaWYgKHRmQmluYXJ5T3BlcmF0b3JzVG9DZGt0Zltmbk5hbWUgYXMgc3VwcG9ydGVkQmluYXJ5T3BlcmF0b3JzXSkge1xuICAgIGZuTmFtZSA9IHRmQmluYXJ5T3BlcmF0b3JzVG9DZGt0Zltmbk5hbWUgYXMgc3VwcG9ydGVkQmluYXJ5T3BlcmF0b3JzXTtcbiAgfSBlbHNlIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYENhbm5vdCBjb252ZXJ0IHVua25vd24gb3BlcmF0b3IgJHtub2RlLm1ldGEub3BlcmF0b3J9YCk7XG4gIH1cblxuICBzY29wZS5pbXBvcnRhYmxlcy5wdXNoKHtcbiAgICBjb25zdHJ1Y3ROYW1lOiBcIk9wXCIsXG4gICAgcHJvdmlkZXI6IFwiY2RrdG5cIixcbiAgfSk7XG5cbiAgY29uc3QgZm4gPSB0Lm1lbWJlckV4cHJlc3Npb24odC5pZGVudGlmaWVyKFwiT3BcIiksIHQuaWRlbnRpZmllcihmbk5hbWUpKTtcbiAgcmV0dXJuIHQuY2FsbEV4cHJlc3Npb24oZm4sIFtsZWZ0LCByaWdodF0pO1xufVxuXG5mdW5jdGlvbiBjb252ZXJ0VGVtcGxhdGVFeHByZXNzaW9uVG9UcyhcbiAgc2NvcGU6IFJlc291cmNlU2NvcGUsXG4gIG5vZGU6IHRleC5UZW1wbGF0ZUV4cHJlc3Npb24gfCB0ZXguVGVtcGxhdGVXcmFwRXhwcmVzc2lvbixcbikge1xuICBjb25zdCBwYXJ0cyA9IG5vZGUuY2hpbGRyZW4ubWFwKChjaGlsZCkgPT4gKHtcbiAgICBub2RlOiBjaGlsZCxcbiAgICBleHByOiBjb252ZXJ0VEZFeHByZXNzaW9uQXN0VG9UcyhzY29wZSwgY2hpbGQpLFxuICB9KSk7XG5cbiAgY29uc3QgbGFzdFBhcnQgPSBwYXJ0c1twYXJ0cy5sZW5ndGggLSAxXTtcbiAgaWYgKHQuaXNTdHJpbmdMaXRlcmFsKGxhc3RQYXJ0LmV4cHIpICYmIGxhc3RQYXJ0LmV4cHIudmFsdWUgPT09IFwiXFxuXCIpIHtcbiAgICAvLyBUaGlzIGlzIGEgYml0IG9mIGEgaGFjaywgYnV0IHRoZSB0cmFpbGluZyBuZXdsaW5lIHdlIGFkZCBkdWUgdG9cbiAgICAvLyBoZXJlZG9jcyBsb29rcyB1Z2x5IGFuZCB1bm5lY2Vzc2FyeSBpbiB0aGUgZ2VuZXJhdGVkIGNvZGUsIHNvIHdlXG4gICAgLy8gdHJ5IHRvIHJlbW92ZSBpdFxuICAgIHBhcnRzLnBvcCgpO1xuICB9XG5cbiAgaWYgKHBhcnRzLmxlbmd0aCA9PT0gMCkge1xuICAgIHJldHVybiB0LnN0cmluZ0xpdGVyYWwobm9kZS5tZXRhLnZhbHVlKTtcbiAgfVxuXG4gIGlmIChwYXJ0cy5sZW5ndGggPT09IDEpIHtcbiAgICByZXR1cm4gcGFydHNbMF0uZXhwcjtcbiAgfVxuXG4gIGxldCBpc1Njb3BlZFRyYXZlcnNhbCA9IGZhbHNlO1xuICBsZXQgZXhwcmVzc2lvbnM6IHQuRXhwcmVzc2lvbltdID0gW107XG4gIGZvciAoY29uc3QgeyBub2RlLCBleHByIH0gb2YgcGFydHMpIHtcbiAgICBpZiAoXG4gICAgICB0ZXguaXNTY29wZVRyYXZlcnNhbEV4cHJlc3Npb24obm9kZSkgJiZcbiAgICAgICF0LmlzU3RyaW5nTGl0ZXJhbChleHByKSAmJlxuICAgICAgIXQuaXNDYWxsRXhwcmVzc2lvbihleHByKVxuICAgICkge1xuICAgICAgZXhwcmVzc2lvbnMucHVzaCh0LnN0cmluZ0xpdGVyYWwoXCIke1wiKSk7XG4gICAgICBpc1Njb3BlZFRyYXZlcnNhbCA9IHRydWU7XG4gICAgfSBlbHNlIGlmIChcbiAgICAgIC8vIHdlIHNob3VsZCBpZGVhbGx5IGJlIGRvaW5nIHR5cGUgY29lcmNpb24gbW9yZVxuICAgICAgLy8gY2FyZWZ1bGx5IGhlcmUsIGJlY2F1c2UgaXQgbWF5IG5vdCBhbHdheXMgYmUgbmVlZGVkXG4gICAgICB0LmlzQ2FsbEV4cHJlc3Npb24oZXhwcilcbiAgICApIHtcbiAgICAgIHNjb3BlLmltcG9ydGFibGVzLnB1c2goe1xuICAgICAgICBjb25zdHJ1Y3ROYW1lOiBcIlRva2VuXCIsXG4gICAgICAgIHByb3ZpZGVyOiBcImNka3RuXCIsXG4gICAgICB9KTtcblxuICAgICAgZXhwcmVzc2lvbnMucHVzaChcbiAgICAgICAgdGVtcGxhdGUuZXhwcmVzc2lvbihgVG9rZW4uYXNTdHJpbmcoJSVleHByJSUpYCkoe1xuICAgICAgICAgIGV4cHIsXG4gICAgICAgIH0pIGFzIHQuRXhwcmVzc2lvbixcbiAgICAgICk7XG4gICAgICBjb250aW51ZTtcbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKGlzU2NvcGVkVHJhdmVyc2FsKSB7XG4gICAgICAgIGV4cHJlc3Npb25zLnB1c2godC5zdHJpbmdMaXRlcmFsKFwifVwiKSk7XG4gICAgICAgIGlzU2NvcGVkVHJhdmVyc2FsID0gZmFsc2U7XG4gICAgICB9XG4gICAgfVxuICAgIGV4cHJlc3Npb25zLnB1c2goZXhwcik7XG4gIH1cblxuICBpZiAoaXNTY29wZWRUcmF2ZXJzYWwpIHtcbiAgICBleHByZXNzaW9ucy5wdXNoKHQuc3RyaW5nTGl0ZXJhbChcIn1cIikpO1xuICB9XG5cbiAgcmV0dXJuIGV4cHJlc3Npb25Gb3JTZXJpYWxTdHJpbmdDb25jYXRlbmF0aW9uKHNjb3BlLCBleHByZXNzaW9ucyk7XG59XG5cbmZ1bmN0aW9uIGNvbnZlcnRPYmplY3RFeHByZXNzaW9uVG9UcyhcbiAgc2NvcGU6IFJlc291cmNlU2NvcGUsXG4gIG5vZGU6IHRleC5PYmplY3RFeHByZXNzaW9uLFxuKSB7XG4gIHJldHVybiB0Lm9iamVjdEV4cHJlc3Npb24oXG4gICAgT2JqZWN0LmVudHJpZXMobm9kZS5tZXRhLml0ZW1zKVxuICAgICAgLm1hcCgoW2tleSwgdmFsdWVdKSA9PiB7XG4gICAgICAgIGNvbnN0IHZhbHVlQ2hpbGQgPSBnZXRDaGlsZFdpdGhWYWx1ZShub2RlLCB2YWx1ZSk7XG4gICAgICAgIGlmICghdmFsdWVDaGlsZCkge1xuICAgICAgICAgIGxvZ2dlci5lcnJvcihgVW5hYmxlIHRvIHZhbHVlIGZvciBvYmplY3Qga2V5ICcke2tleX0nOiAke3ZhbHVlfWApO1xuICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHQub2JqZWN0UHJvcGVydHkoXG4gICAgICAgICAgdC5pZGVudGlmaWVyKGtleSksXG4gICAgICAgICAgY29udmVydFRGRXhwcmVzc2lvbkFzdFRvVHMoc2NvcGUsIHZhbHVlQ2hpbGQpLFxuICAgICAgICApO1xuICAgICAgfSlcbiAgICAgIC5maWx0ZXIoKHMpID0+IHMgIT09IG51bGwpIGFzIHQuT2JqZWN0UHJvcGVydHlbXSxcbiAgKTtcbn1cblxuZnVuY3Rpb24gY29udmVydEZ1bmN0aW9uQ2FsbEV4cHJlc3Npb25Ub1RzKFxuICBzY29wZTogUmVzb3VyY2VTY29wZSxcbiAgbm9kZTogdGV4LkZ1bmN0aW9uQ2FsbEV4cHJlc3Npb24sXG4pIHtcbiAgY29uc3QgZnVuY3Rpb25OYW1lID0gbm9kZS5tZXRhLm5hbWU7XG4gIGNvbnN0IG1hcHBpbmcgPSBmdW5jdGlvbnNNYXBbZnVuY3Rpb25OYW1lXTtcblxuICBpZiAoIW1hcHBpbmcpIHtcbiAgICBsb2dnZXIuZXJyb3IoXG4gICAgICBgVW5rbm93biBmdW5jdGlvbiAke2Z1bmN0aW9uTmFtZX0gZW5jb3VudGVyZWQuICR7bGVhdmVDb21tZW50VGV4dH1gLFxuICAgICk7XG4gICAgY29uc3QgYXJndW1lbnRFeHByZXNzaW9ucyA9IG5vZGUuY2hpbGRyZW4ubWFwKChjaGlsZCkgPT5cbiAgICAgIGNvbnZlcnRURkV4cHJlc3Npb25Bc3RUb1RzKHNjb3BlLCBjaGlsZCksXG4gICAgKTtcblxuICAgIHJldHVybiB0LmNhbGxFeHByZXNzaW9uKHQuaWRlbnRpZmllcihmdW5jdGlvbk5hbWUpLCBhcmd1bWVudEV4cHJlc3Npb25zKTtcbiAgfVxuXG4gIGxldCB0cmFuc2Zvcm1lZE5vZGU6IHRleC5GdW5jdGlvbkNhbGxFeHByZXNzaW9uID0gbWFwcGluZy50cmFuc2Zvcm1lclxuICAgID8gbWFwcGluZy50cmFuc2Zvcm1lcihub2RlKVxuICAgIDogbm9kZTtcblxuICBjb25zdCBhcmd1bWVudEV4cHJlc3Npb25zID0gdHJhbnNmb3JtZWROb2RlLmNoaWxkcmVuLm1hcCgoY2hpbGQpID0+XG4gICAgY29udmVydFRGRXhwcmVzc2lvbkFzdFRvVHMoc2NvcGUsIGNoaWxkKSxcbiAgKTtcblxuICBzY29wZS5pbXBvcnRhYmxlcy5wdXNoKHtcbiAgICBjb25zdHJ1Y3ROYW1lOiBcIkZuXCIsXG4gICAgcHJvdmlkZXI6IFwiY2RrdG5cIixcbiAgfSk7XG5cbiAgY29uc3QgY2FsbGVlID0gdC5tZW1iZXJFeHByZXNzaW9uKFxuICAgIHQuaWRlbnRpZmllcihcIkZuXCIpLFxuICAgIHQuaWRlbnRpZmllcihtYXBwaW5nLm5hbWUpLFxuICApO1xuXG4gIGlmIChcbiAgICBtYXBwaW5nLnBhcmFtZXRlcnMubGVuZ3RoID4gMCAmJlxuICAgIG1hcHBpbmcucGFyYW1ldGVyc1ttYXBwaW5nLnBhcmFtZXRlcnMubGVuZ3RoIC0gMV0udmFyaWFkaWNcbiAgKSB7XG4gICAgY29uc3QgbGFzdFBhcmFtZXRlclR5cGUgPVxuICAgICAgbWFwcGluZy5wYXJhbWV0ZXJzW21hcHBpbmcucGFyYW1ldGVycy5sZW5ndGggLSAxXS50eXBlO1xuICAgIGNvbnN0IG5vblZhcmlhZGljQXJndW1lbnRzID0gYXJndW1lbnRFeHByZXNzaW9ucy5zbGljZShcbiAgICAgIDAsXG4gICAgICBtYXBwaW5nLnBhcmFtZXRlcnMubGVuZ3RoIC0gMSxcbiAgICApO1xuXG4gICAgY29uc3QgZm5DYWxsQXJndW1lbnRzID0gW1xuICAgICAgLi4ubm9uVmFyaWFkaWNBcmd1bWVudHMubWFwKChhcmdFeHByLCBpbmRleCkgPT5cbiAgICAgICAgY29lcmNlVHlwZShcbiAgICAgICAgICBzY29wZSxcbiAgICAgICAgICBhcmdFeHByLFxuICAgICAgICAgIGZpbmRFeHByZXNzaW9uVHlwZShzY29wZSwgYXJnRXhwciksXG4gICAgICAgICAgbWFwcGluZy5wYXJhbWV0ZXJzW2luZGV4XS50eXBlLFxuICAgICAgICApLFxuICAgICAgKSxcblxuICAgICAgdC5hcnJheUV4cHJlc3Npb24oXG4gICAgICAgIGFyZ3VtZW50RXhwcmVzc2lvbnNcbiAgICAgICAgICAuc2xpY2UobWFwcGluZy5wYXJhbWV0ZXJzLmxlbmd0aCAtIDEpXG4gICAgICAgICAgLm1hcCgoYXJnRXhwcikgPT5cbiAgICAgICAgICAgIGNvZXJjZVR5cGUoXG4gICAgICAgICAgICAgIHNjb3BlLFxuICAgICAgICAgICAgICBhcmdFeHByLFxuICAgICAgICAgICAgICBmaW5kRXhwcmVzc2lvblR5cGUoc2NvcGUsIGFyZ0V4cHIpLFxuICAgICAgICAgICAgICBsYXN0UGFyYW1ldGVyVHlwZSxcbiAgICAgICAgICAgICksXG4gICAgICAgICAgKSxcbiAgICAgICksXG4gICAgXTtcblxuICAgIHJldHVybiB0LmNhbGxFeHByZXNzaW9uKGNhbGxlZSwgZm5DYWxsQXJndW1lbnRzKTtcbiAgfVxuXG4gIHJldHVybiB0LmNhbGxFeHByZXNzaW9uKFxuICAgIGNhbGxlZSxcbiAgICBhcmd1bWVudEV4cHJlc3Npb25zLm1hcCgoYXJnRXhwciwgaW5kZXgpID0+XG4gICAgICBjb2VyY2VUeXBlKFxuICAgICAgICBzY29wZSxcbiAgICAgICAgYXJnRXhwcixcbiAgICAgICAgZmluZEV4cHJlc3Npb25UeXBlKHNjb3BlLCBhcmdFeHByKSxcbiAgICAgICAgbWFwcGluZy5wYXJhbWV0ZXJzW2luZGV4XS50eXBlLFxuICAgICAgKSxcbiAgICApLFxuICApO1xufVxuXG5mdW5jdGlvbiBjb252ZXJ0SW5kZXhFeHByZXNzaW9uVG9UcyhcbiAgc2NvcGU6IFJlc291cmNlU2NvcGUsXG4gIG5vZGU6IHRleC5JbmRleEV4cHJlc3Npb24sXG4pIHtcbiAgY29uc3QgY29sbGVjdGlvbkV4cHJlc3Npb25DaGlsZCA9IHRleC5nZXRDaGlsZFdpdGhWYWx1ZShcbiAgICBub2RlLFxuICAgIG5vZGUubWV0YS5jb2xsZWN0aW9uRXhwcmVzc2lvbixcbiAgKTtcbiAgY29uc3Qga2V5RXhwcmVzc2lvbkNoaWxkID0gdGV4LmdldENoaWxkV2l0aFZhbHVlKFxuICAgIG5vZGUsXG4gICAgbm9kZS5tZXRhLmtleUV4cHJlc3Npb24sXG4gICk7XG5cbiAgY29uc3QgY29sbGVjdGlvbkV4cHJlc3Npb24gPSBjb252ZXJ0VEZFeHByZXNzaW9uQXN0VG9UcyhcbiAgICBzY29wZSxcbiAgICBjb2xsZWN0aW9uRXhwcmVzc2lvbkNoaWxkISxcbiAgKTtcbiAgY29uc3Qga2V5RXhwcmVzc2lvbiA9IGNvbnZlcnRURkV4cHJlc3Npb25Bc3RUb1RzKHNjb3BlLCBrZXlFeHByZXNzaW9uQ2hpbGQhKTtcblxuICBzY29wZS5pbXBvcnRhYmxlcy5wdXNoKHtcbiAgICBjb25zdHJ1Y3ROYW1lOiBcIkZuXCIsXG4gICAgcHJvdmlkZXI6IFwiY2RrdG5cIixcbiAgfSk7XG4gIGNvbnN0IGNhbGxlZSA9IHQubWVtYmVyRXhwcmVzc2lvbihcbiAgICB0LmlkZW50aWZpZXIoXCJGblwiKSxcbiAgICB0LmlkZW50aWZpZXIoXCJsb29rdXBOZXN0ZWRcIiksXG4gICk7XG4gIHJldHVybiB0LmNhbGxFeHByZXNzaW9uKGNhbGxlZSwgW1xuICAgIGNvbGxlY3Rpb25FeHByZXNzaW9uLFxuICAgIHQuYXJyYXlFeHByZXNzaW9uKFtrZXlFeHByZXNzaW9uXSksXG4gIF0pO1xufVxuXG5mdW5jdGlvbiBjb252ZXJ0U3BsYXRFeHByZXNzaW9uVG9UcyhcbiAgc2NvcGU6IFJlc291cmNlU2NvcGUsXG4gIG5vZGU6IHRleC5TcGxhdEV4cHJlc3Npb24sXG4pIHtcbiAgY29uc3Qgc291cmNlRXhwcmVzc2lvbkNoaWxkID0gdGV4LmdldENoaWxkV2l0aFZhbHVlKFxuICAgIG5vZGUsXG4gICAgbm9kZS5tZXRhLnNvdXJjZUV4cHJlc3Npb24sXG4gICkhO1xuICBsZXQgc291cmNlRXhwcmVzc2lvbiA9IGNvbnZlcnRURkV4cHJlc3Npb25Bc3RUb1RzKFxuICAgIHNjb3BlLFxuICAgIHNvdXJjZUV4cHJlc3Npb25DaGlsZCxcbiAgKTtcblxuICAvLyBXZSBkb24ndCBjb252ZXJ0IHRoZSByZWxhdGl2ZSBleHByZXNzaW9uIGJlY2F1c2UgZXZlcnl0aGluZyBhZnRlciB0aGUgc3BsYXQgaXMgZ29pbmcgdG8gYmVcbiAgLy8gYSBzdHJpbmdcbiAgbGV0IHJlbGF0aXZlRXhwcmVzc2lvbiA9IG5vZGUubWV0YS5lYWNoRXhwcmVzc2lvbi5zdGFydHNXaXRoKFxuICAgIG5vZGUubWV0YS5hbm9uU3ltYm9sRXhwcmVzc2lvbixcbiAgKVxuICAgID8gbm9kZS5tZXRhLmVhY2hFeHByZXNzaW9uLnNsaWNlKG5vZGUubWV0YS5hbm9uU3ltYm9sRXhwcmVzc2lvbi5sZW5ndGgpXG4gICAgOiBub2RlLm1ldGEuZWFjaEV4cHJlc3Npb247XG5cbiAgY29uc3Qgc2VnbWVudHMgPSByZWxhdGl2ZUV4cHJlc3Npb24uc3BsaXQoL1xcLnxcXFt8XFxdLykuZmlsdGVyKChzKSA9PiBzKTtcbiAgc2NvcGUuaW1wb3J0YWJsZXMucHVzaCh7XG4gICAgY29uc3RydWN0TmFtZTogXCJGblwiLFxuICAgIHByb3ZpZGVyOiBcImNka3RuXCIsXG4gIH0pO1xuICBjb25zdCBjYWxsZWUgPSB0Lm1lbWJlckV4cHJlc3Npb24oXG4gICAgdC5pZGVudGlmaWVyKFwiRm5cIiksXG4gICAgdC5pZGVudGlmaWVyKFwibG9va3VwTmVzdGVkXCIpLFxuICApO1xuXG4gIHJldHVybiB0LmNhbGxFeHByZXNzaW9uKGNhbGxlZSwgW1xuICAgIHNvdXJjZUV4cHJlc3Npb24sXG4gICAgdC5hcnJheUV4cHJlc3Npb24oW1xuICAgICAgLy8gd2UgZG9uJ3QgbmVlZCB0byB1c2UgdGhlIGFub25TeW1ib2xFeHByZXNzaW9uIGhlcmUgYmVjYXVzZVxuICAgICAgLy8gaXQgb25seSBjaGFuZ2VzIGJldHdlZW4gLiogYW5kIFsqXSB3aGljaCB3ZSBkb24ndCBjYXJlIGFib3V0XG4gICAgICB0LnN0cmluZ0xpdGVyYWwoXCIqXCIpLFxuICAgICAgLi4uc2VnbWVudHMubWFwKHQuc3RyaW5nTGl0ZXJhbCksXG4gICAgXSksXG4gIF0pO1xufVxuXG5mdW5jdGlvbiBjb252ZXJ0Q29uZGl0aW9uYWxFeHByZXNzaW9uVG9UcyhcbiAgc2NvcGU6IFJlc291cmNlU2NvcGUsXG4gIG5vZGU6IHRleC5Db25kaXRpb25hbEV4cHJlc3Npb24sXG4pIHtcbiAgY29uc3QgY29uZGl0aW9uQ2hpbGQgPSB0ZXguZ2V0Q2hpbGRXaXRoVmFsdWUoXG4gICAgbm9kZSxcbiAgICBub2RlLm1ldGEuY29uZGl0aW9uRXhwcmVzc2lvbixcbiAgKSE7XG4gIGxldCBjb25kaXRpb24gPSBjb252ZXJ0VEZFeHByZXNzaW9uQXN0VG9UcyhzY29wZSwgY29uZGl0aW9uQ2hpbGQpO1xuICBpZiAodC5pc0lkZW50aWZpZXIoY29uZGl0aW9uKSAmJiBjYW5Vc2VGcW4oY29uZGl0aW9uQ2hpbGQpKSB7XG4gICAgLy8gV2UgaGF2ZSBhIHJlc291cmNlIG9yIGRhdGEgc291cmNlIGhlcmUsIHdoaWNoIHdlIHdvdWxkIG5lZWQgdG9cbiAgICAvLyByZWZlcmVuY2UgdXNpbmcgZnFuXG4gICAgY29uZGl0aW9uID0gdC5tZW1iZXJFeHByZXNzaW9uKGNvbmRpdGlvbiwgdC5pZGVudGlmaWVyKFwiZnFuXCIpKTtcbiAgfVxuXG4gIGNvbnN0IHRydWVFeHByZXNzaW9uID0gY29udmVydFRGRXhwcmVzc2lvbkFzdFRvVHMoXG4gICAgc2NvcGUsXG4gICAgdGV4LmdldENoaWxkV2l0aFZhbHVlKG5vZGUsIG5vZGUubWV0YS50cnVlRXhwcmVzc2lvbikhLFxuICApO1xuXG4gIGNvbnN0IGZhbHNlRXhwcmVzc2lvbiA9IGNvbnZlcnRURkV4cHJlc3Npb25Bc3RUb1RzKFxuICAgIHNjb3BlLFxuICAgIHRleC5nZXRDaGlsZFdpdGhWYWx1ZShub2RlLCBub2RlLm1ldGEuZmFsc2VFeHByZXNzaW9uKSEsXG4gICk7XG5cbiAgc2NvcGUuaW1wb3J0YWJsZXMucHVzaCh7XG4gICAgY29uc3RydWN0TmFtZTogXCJjb25kaXRpb25hbFwiLFxuICAgIHByb3ZpZGVyOiBcImNka3RuXCIsXG4gIH0pO1xuXG4gIHJldHVybiB0LmNhbGxFeHByZXNzaW9uKHQuaWRlbnRpZmllcihcImNvbmRpdGlvbmFsXCIpLCBbXG4gICAgY29uZGl0aW9uLFxuICAgIHRydWVFeHByZXNzaW9uLFxuICAgIGZhbHNlRXhwcmVzc2lvbixcbiAgXSk7XG59XG5cbmZ1bmN0aW9uIGNvbnZlcnRUdXBsZUV4cHJlc3Npb25Ub1RzKFxuICBzY29wZTogUmVzb3VyY2VTY29wZSxcbiAgbm9kZTogdGV4LlR1cGxlRXhwcmVzc2lvbixcbikge1xuICBjb25zdCBleHByZXNzaW9ucyA9IG5vZGUuY2hpbGRyZW4ubWFwKChjaGlsZCkgPT5cbiAgICBjb252ZXJ0VEZFeHByZXNzaW9uQXN0VG9UcyhzY29wZSwgY2hpbGQpLFxuICApO1xuXG4gIHJldHVybiB0LmFycmF5RXhwcmVzc2lvbihleHByZXNzaW9ucyk7XG59XG5cbmZ1bmN0aW9uIGNvbnZlcnRSZWxhdGl2ZVRyYXZlcnNhbEV4cHJlc3Npb25Ub1RzKFxuICBzY29wZTogUmVzb3VyY2VTY29wZSxcbiAgbm9kZTogdGV4LlJlbGF0aXZlVHJhdmVyc2FsRXhwcmVzc2lvbixcbikge1xuICBjb25zdCBzZWdtZW50cyA9IG5vZGUubWV0YS50cmF2ZXJzYWw7XG5cbiAgLy8gVGhlIGxlZnQgaGFuZCBzaWRlIC8gc291cmNlIG9mIGEgcmVsYXRpdmUgdHJhdmVyc2FsIGlzIG5vdCBhIHByb3BlclxuICAvLyBvYmplY3QgLyByZXNvdXJjZSAvIGRhdGEgdGhpbmcgdGhhdCBpcyBiZWluZyByZWZlcmVuY2VkXG4gIGNvbnN0IHNvdXJjZSA9IGNvbnZlcnRURkV4cHJlc3Npb25Bc3RUb1RzKFxuICAgIHNjb3BlLFxuICAgIHRleC5nZXRDaGlsZFdpdGhWYWx1ZShub2RlLCBub2RlLm1ldGEuc291cmNlRXhwcmVzc2lvbikhLFxuICApO1xuXG4gIHNjb3BlLmltcG9ydGFibGVzLnB1c2goe1xuICAgIGNvbnN0cnVjdE5hbWU6IFwiRm5cIixcbiAgICBwcm92aWRlcjogXCJjZGt0blwiLFxuICB9KTtcbiAgY29uc3QgY2FsbGVlID0gdC5tZW1iZXJFeHByZXNzaW9uKFxuICAgIHQuaWRlbnRpZmllcihcIkZuXCIpLFxuICAgIHQuaWRlbnRpZmllcihcImxvb2t1cE5lc3RlZFwiKSxcbiAgKTtcblxuICByZXR1cm4gdC5jYWxsRXhwcmVzc2lvbihjYWxsZWUsIFtcbiAgICBzb3VyY2UsXG4gICAgdC5hcnJheUV4cHJlc3Npb24oc2VnbWVudHMubWFwKChzKSA9PiB0LnN0cmluZ0xpdGVyYWwocy5zZWdtZW50KSkpLFxuICBdKTtcbn1cblxuZnVuY3Rpb24gY29udmVydEZvckV4cHJlc3Npb25Ub1RzKFxuICBzY29wZTogUmVzb3VyY2VTY29wZSxcbiAgbm9kZTogdGV4LkZvckV4cHJlc3Npb24sXG4pIHtcbiAgY29uc3QgY29sbGVjdGlvbkNoaWxkID0gdGV4LmdldENoaWxkV2l0aFZhbHVlKFxuICAgIG5vZGUsXG4gICAgbm9kZS5tZXRhLmNvbGxlY3Rpb25FeHByZXNzaW9uLFxuICApITtcblxuICBsZXQgY29sbGVjdGlvbkV4cHJlc3Npb24gPSBjb252ZXJ0VEZFeHByZXNzaW9uQXN0VG9UcyhzY29wZSwgY29sbGVjdGlvbkNoaWxkKTtcblxuICBpZiAodC5pc0lkZW50aWZpZXIoY29sbGVjdGlvbkV4cHJlc3Npb24pICYmIGNhblVzZUZxbihjb2xsZWN0aW9uQ2hpbGQpKSB7XG4gICAgLy8gV2UgaGF2ZSBhIHJlc291cmNlIG9yIGRhdGEgc291cmNlIGhlcmUsIHdoaWNoIHdlIHdvdWxkIG5lZWQgdG9cbiAgICAvLyByZWZlcmVuY2UgdXNpbmcgZnFuXG4gICAgY29sbGVjdGlvbkV4cHJlc3Npb24gPSB0Lm1lbWJlckV4cHJlc3Npb24oXG4gICAgICBjb2xsZWN0aW9uRXhwcmVzc2lvbixcbiAgICAgIHQuaWRlbnRpZmllcihcImZxblwiKSxcbiAgICApO1xuICB9XG5cbiAgY29uc3QgY29sbGVjdGlvblJlcXVpcmVzV3JhcHBpbmcgPSAhdC5pc1N0cmluZ0xpdGVyYWwoY29sbGVjdGlvbkV4cHJlc3Npb24pO1xuICBjb25zdCBleHByZXNzaW9ucyA9IFtdO1xuICBjb25zdCBjb25kaXRpb25Cb2R5ID0gbm9kZS5tZXRhLmtleVZhclxuICAgID8gYCR7bm9kZS5tZXRhLmtleVZhcn0sICR7bm9kZS5tZXRhLnZhbFZhcn1gXG4gICAgOiBub2RlLm1ldGEudmFsVmFyO1xuXG4gIGNvbnN0IG9wZW5CcmFjZSA9IG5vZGUubWV0YS5vcGVuUmFuZ2VWYWx1ZTtcbiAgY29uc3QgY2xvc2VCcmFjZSA9IG5vZGUubWV0YS5jbG9zZVJhbmdlVmFsdWU7XG4gIGNvbnN0IGdyb3VwZWQgPSBub2RlLm1ldGEuZ3JvdXBlZFZhbHVlID8gXCIuLi5cIiA6IFwiXCI7XG4gIGNvbnN0IHZhbHVlRXhwcmVzc2lvbiA9IGAke25vZGUubWV0YS52YWx1ZUV4cHJlc3Npb259JHtncm91cGVkfWA7XG5cbiAgY29uc3QgcHJlZml4ID0gYFxcJHske29wZW5CcmFjZX0gZm9yICR7Y29uZGl0aW9uQm9keX0gaW4gYDtcbiAgY29uc3Qga2V5VmFsdWUgPSBub2RlLm1ldGEua2V5RXhwcmVzc2lvblxuICAgID8gYCA6ICR7bm9kZS5tZXRhLmtleUV4cHJlc3Npb259ID0+ICR7dmFsdWVFeHByZXNzaW9ufWBcbiAgICA6IGAgOiAke3ZhbHVlRXhwcmVzc2lvbn1gO1xuICBjb25zdCBjb25kaXRpb25hbCA9IG5vZGUubWV0YS5jb25kaXRpb25hbEV4cHJlc3Npb247XG4gIGNvbnN0IHN1ZmZpeCA9IGAke2tleVZhbHVlfSR7XG4gICAgY29uZGl0aW9uYWwgPyBgIGlmICR7Y29uZGl0aW9uYWx9YCA6IFwiXCJcbiAgfSR7Y2xvc2VCcmFjZX19YDtcblxuICBleHByZXNzaW9ucy5wdXNoKHQuc3RyaW5nTGl0ZXJhbChwcmVmaXgpKTtcbiAgaWYgKGNvbGxlY3Rpb25SZXF1aXJlc1dyYXBwaW5nKSB7XG4gICAgZXhwcmVzc2lvbnMucHVzaCh0LnN0cmluZ0xpdGVyYWwoXCIke1wiKSk7XG4gIH1cbiAgZXhwcmVzc2lvbnMucHVzaChjb2xsZWN0aW9uRXhwcmVzc2lvbik7XG4gIGlmIChjb2xsZWN0aW9uUmVxdWlyZXNXcmFwcGluZykge1xuICAgIGV4cHJlc3Npb25zLnB1c2godC5zdHJpbmdMaXRlcmFsKFwifVwiKSk7XG4gIH1cbiAgZXhwcmVzc2lvbnMucHVzaCh0LnN0cmluZ0xpdGVyYWwoc3VmZml4KSk7XG5cbiAgcmV0dXJuIGV4cHJlc3Npb25Gb3JTZXJpYWxTdHJpbmdDb25jYXRlbmF0aW9uKHNjb3BlLCBleHByZXNzaW9ucyk7XG59XG5cbmZ1bmN0aW9uIGNvbnZlcnRURkV4cHJlc3Npb25Bc3RUb1RzKFxuICBzY29wZTogUmVzb3VyY2VTY29wZSxcbiAgbm9kZTogdGV4LkV4cHJlc3Npb25UeXBlLFxuKTogdC5FeHByZXNzaW9uIHtcbiAgaWYgKHRleC5pc0xpdGVyYWxWYWx1ZUV4cHJlc3Npb24obm9kZSkpIHtcbiAgICByZXR1cm4gY29udmVydExpdGVyYWxWYWx1ZUV4cHJlc3Npb25Ub1RzKHNjb3BlLCBub2RlKTtcbiAgfVxuXG4gIGlmICh0ZXguaXNTY29wZVRyYXZlcnNhbEV4cHJlc3Npb24obm9kZSkpIHtcbiAgICByZXR1cm4gY29udmVydFNjb3BlVHJhdmVyc2FsRXhwcmVzc2lvblRvVHMoc2NvcGUsIG5vZGUpO1xuICB9XG5cbiAgaWYgKHRleC5pc1VuYXJ5T3BFeHByZXNzaW9uKG5vZGUpKSB7XG4gICAgcmV0dXJuIGNvbnZlcnRVbmFyeU9wRXhwcmVzc2lvblRvVHMoc2NvcGUsIG5vZGUpO1xuICB9XG5cbiAgaWYgKHRleC5pc0JpbmFyeU9wRXhwcmVzc2lvbihub2RlKSkge1xuICAgIHJldHVybiBjb252ZXJ0QmluYXJ5T3BFeHByZXNzaW9uVG9UcyhzY29wZSwgbm9kZSk7XG4gIH1cblxuICBpZiAodGV4LmlzVGVtcGxhdGVFeHByZXNzaW9uKG5vZGUpIHx8IHRleC5pc1RlbXBsYXRlV3JhcEV4cHJlc3Npb24obm9kZSkpIHtcbiAgICByZXR1cm4gY29udmVydFRlbXBsYXRlRXhwcmVzc2lvblRvVHMoc2NvcGUsIG5vZGUpO1xuICB9XG5cbiAgaWYgKHRleC5pc09iamVjdEV4cHJlc3Npb24obm9kZSkpIHtcbiAgICByZXR1cm4gY29udmVydE9iamVjdEV4cHJlc3Npb25Ub1RzKHNjb3BlLCBub2RlKTtcbiAgfVxuXG4gIGlmICh0ZXguaXNGdW5jdGlvbkNhbGxFeHByZXNzaW9uKG5vZGUpKSB7XG4gICAgcmV0dXJuIGNvbnZlcnRGdW5jdGlvbkNhbGxFeHByZXNzaW9uVG9UcyhzY29wZSwgbm9kZSk7XG4gIH1cblxuICBpZiAodGV4LmlzSW5kZXhFeHByZXNzaW9uKG5vZGUpKSB7XG4gICAgcmV0dXJuIGNvbnZlcnRJbmRleEV4cHJlc3Npb25Ub1RzKHNjb3BlLCBub2RlKTtcbiAgfVxuXG4gIGlmICh0ZXguaXNTcGxhdEV4cHJlc3Npb24obm9kZSkpIHtcbiAgICByZXR1cm4gY29udmVydFNwbGF0RXhwcmVzc2lvblRvVHMoc2NvcGUsIG5vZGUpO1xuICB9XG5cbiAgaWYgKHRleC5pc0NvbmRpdGlvbmFsRXhwcmVzc2lvbihub2RlKSkge1xuICAgIHJldHVybiBjb252ZXJ0Q29uZGl0aW9uYWxFeHByZXNzaW9uVG9UcyhzY29wZSwgbm9kZSk7XG4gIH1cblxuICBpZiAodGV4LmlzVHVwbGVFeHByZXNzaW9uKG5vZGUpKSB7XG4gICAgcmV0dXJuIGNvbnZlcnRUdXBsZUV4cHJlc3Npb25Ub1RzKHNjb3BlLCBub2RlKTtcbiAgfVxuXG4gIGlmICh0ZXguaXNSZWxhdGl2ZVRyYXZlcnNhbEV4cHJlc3Npb24obm9kZSkpIHtcbiAgICByZXR1cm4gY29udmVydFJlbGF0aXZlVHJhdmVyc2FsRXhwcmVzc2lvblRvVHMoc2NvcGUsIG5vZGUpO1xuICB9XG5cbiAgaWYgKHRleC5pc0ZvckV4cHJlc3Npb24obm9kZSkpIHtcbiAgICByZXR1cm4gY29udmVydEZvckV4cHJlc3Npb25Ub1RzKHNjb3BlLCBub2RlKTtcbiAgfVxuXG4gIHJldHVybiB0LnN0cmluZ0xpdGVyYWwoXCJcIik7XG59XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBleHByZXNzaW9uQXN0KFxuICBpbnB1dDogc3RyaW5nLFxuKTogUHJvbWlzZTx0ZXguRXhwcmVzc2lvblR5cGU+IHtcbiAgY29uc3QgeyB3cmFwLCB3cmFwT2Zmc2V0IH0gPSB3cmFwVGVycmFmb3JtRXhwcmVzc2lvbihpbnB1dCk7XG4gIGNvbnN0IGFzdCA9IGF3YWl0IGdldEV4cHJlc3Npb25Bc3QoXCJtYWluLnRmXCIsIHdyYXApO1xuXG4gIGlmICghYXN0KSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBVbmFibGUgdG8gcGFyc2UgdGVycmFmb3JtIGV4cHJlc3Npb246ICR7aW5wdXR9YCk7XG4gIH1cblxuICBpZiAod3JhcE9mZnNldCAhPSAwICYmIHRleC5pc1RlbXBsYXRlV3JhcEV4cHJlc3Npb24oYXN0KSkge1xuICAgIHJldHVybiBhc3QuY2hpbGRyZW5bMF07XG4gIH1cblxuICByZXR1cm4gYXN0O1xufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gY29udmVydFRlcnJhZm9ybUV4cHJlc3Npb25Ub1RzKFxuICBzY29wZTogUmVzb3VyY2VTY29wZSxcbiAgaW5wdXQ6IHN0cmluZyxcbiAgdGFyZ2V0VHlwZTogKCkgPT4gQXR0cmlidXRlVHlwZSxcbik6IFByb21pc2U8dC5FeHByZXNzaW9uPiB7XG4gIGxvZ2dlci5kZWJ1ZyhgY29udmVydFRlcnJhZm9ybUV4cHJlc3Npb25Ub1RzKCR7aW5wdXR9KWApO1xuICBjb25zdCB0c0V4cHJlc3Npb24gPSBjb252ZXJ0VEZFeHByZXNzaW9uQXN0VG9UcyhcbiAgICBzY29wZSxcbiAgICBhd2FpdCBleHByZXNzaW9uQXN0KGlucHV0KSxcbiAgKTtcblxuICByZXR1cm4gY29lcmNlVHlwZShcbiAgICBzY29wZSxcbiAgICB0c0V4cHJlc3Npb24sXG4gICAgZmluZEV4cHJlc3Npb25UeXBlKHNjb3BlLCB0c0V4cHJlc3Npb24pLFxuICAgIHRhcmdldFR5cGUoKSxcbiAgKTtcbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGV4dHJhY3RJdGVyYXRvclZhcmlhYmxlc0Zyb21FeHByZXNzaW9uKFxuICBpbnB1dDogc3RyaW5nLFxuKTogUHJvbWlzZTxJdGVyYXRvclZhcmlhYmxlUmVmZXJlbmNlW10+IHtcbiAgY29uc3QgcG9zc2libGVWYXJpYWJsZVNwb3RzID0gYXdhaXQgZ2V0UmVmZXJlbmNlc0luRXhwcmVzc2lvbihcbiAgICBcIm1haW4udGZcIixcbiAgICBpbnB1dCxcbiAgKTtcblxuICByZXR1cm4gcG9zc2libGVWYXJpYWJsZVNwb3RzXG4gICAgLmZpbHRlcigoc3BvdCkgPT4gc3BvdC52YWx1ZS5zdGFydHNXaXRoKFwiZWFjaC5cIikpXG4gICAgLm1hcCgoc3BvdCkgPT4gKHtcbiAgICAgIHN0YXJ0OiBzcG90LnN0YXJ0UG9zaXRpb24sXG4gICAgICBlbmQ6IHNwb3QuZW5kUG9zaXRpb24sXG4gICAgICB2YWx1ZTogc3BvdC52YWx1ZSxcbiAgICB9KSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBkeW5hbWljVmFyaWFibGVUb0FzdChcbiAgc2NvcGU6IFByb2dyYW1TY29wZSxcbiAgbm9kZTogdGV4LlNjb3BlVHJhdmVyc2FsRXhwcmVzc2lvbixcbiAgaXRlcmF0b3JOYW1lOiBzdHJpbmcsXG4gIGJsb2NrOiBzdHJpbmcgPSBcImVhY2hcIixcbik6IHQuRXhwcmVzc2lvbiB7XG4gIGlmIChpdGVyYXRvck5hbWUgPT09IFwiZHluYW1pYy1ibG9ja1wiKSB7XG4gICAgcmV0dXJuIGV4cHJlc3Npb25Gb3JTZXJpYWxTdHJpbmdDb25jYXRlbmF0aW9uKHNjb3BlLCBbXG4gICAgICB0LnN0cmluZ0xpdGVyYWwoXCIke1wiKSxcbiAgICAgIHQuc3RyaW5nTGl0ZXJhbChibG9jayksXG4gICAgICB0LnN0cmluZ0xpdGVyYWwoXCJ9XCIpLFxuICAgIF0pO1xuICB9XG4gIGlmIChub2RlLm1ldGEudmFsdWUgPT09IGAke2Jsb2NrfS5rZXlgKSB7XG4gICAgcmV0dXJuIHQubWVtYmVyRXhwcmVzc2lvbih0LmlkZW50aWZpZXIoaXRlcmF0b3JOYW1lKSwgdC5pZGVudGlmaWVyKFwia2V5XCIpKTtcbiAgfVxuICBpZiAobm9kZS5tZXRhLnZhbHVlID09PSBgJHtibG9ja30udmFsdWVgKSB7XG4gICAgcmV0dXJuIHQubWVtYmVyRXhwcmVzc2lvbihcbiAgICAgIHQuaWRlbnRpZmllcihpdGVyYXRvck5hbWUpLFxuICAgICAgdC5pZGVudGlmaWVyKFwidmFsdWVcIiksXG4gICAgKTtcbiAgfVxuXG4gIGlmIChibG9jayA9PT0gXCJjb3VudFwiICYmIG5vZGUubWV0YS52YWx1ZSA9PT0gYCR7YmxvY2t9LmluZGV4YCkge1xuICAgIHJldHVybiB0Lm1lbWJlckV4cHJlc3Npb24oXG4gICAgICB0LmlkZW50aWZpZXIoaXRlcmF0b3JOYW1lKSxcbiAgICAgIHQuaWRlbnRpZmllcihcImluZGV4XCIpLFxuICAgICk7XG4gIH1cblxuICBjb25zdCBzZWdtZW50cyA9IG5vZGUubWV0YS50cmF2ZXJzYWw7XG5cbiAgaWYgKFxuICAgIHNlZ21lbnRzLmxlbmd0aCA+IDIgJiZcbiAgICBzZWdtZW50c1swXS5zZWdtZW50ID09PSBibG9jayAmJlxuICAgIHNlZ21lbnRzWzFdLnNlZ21lbnQgPT09IFwidmFsdWVcIlxuICApIHtcbiAgICBjb25zdCBzZWdtZW50c0FmdGVyRWFjaFZhbHVlID0gc2VnbWVudHMuc2xpY2UoMik7XG4gICAgc2NvcGUuaW1wb3J0YWJsZXMucHVzaCh7XG4gICAgICBjb25zdHJ1Y3ROYW1lOiBcIkZuXCIsXG4gICAgICBwcm92aWRlcjogXCJjZGt0blwiLFxuICAgIH0pO1xuICAgIGNvbnN0IGNhbGxlZSA9IHQubWVtYmVyRXhwcmVzc2lvbihcbiAgICAgIHQuaWRlbnRpZmllcihcIkZuXCIpLFxuICAgICAgdC5pZGVudGlmaWVyKFwibG9va3VwTmVzdGVkXCIpLFxuICAgICk7XG4gICAgcmV0dXJuIHQuY2FsbEV4cHJlc3Npb24oY2FsbGVlLCBbXG4gICAgICB0Lm1lbWJlckV4cHJlc3Npb24odC5pZGVudGlmaWVyKGl0ZXJhdG9yTmFtZSksIHQuaWRlbnRpZmllcihcInZhbHVlXCIpKSxcbiAgICAgIHQuYXJyYXlFeHByZXNzaW9uKFxuICAgICAgICBzZWdtZW50c0FmdGVyRWFjaFZhbHVlLm1hcCgocGFydCkgPT4ge1xuICAgICAgICAgIGlmIChwYXJ0LnR5cGUgPT09IFwibmFtZVRyYXZlcnNhbFwiKSB7XG4gICAgICAgICAgICByZXR1cm4gdC5zdHJpbmdMaXRlcmFsKHBhcnQuc2VnbWVudCk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiB0LnN0cmluZ0xpdGVyYWwoYFske3BhcnQuc2VnbWVudH1dYCk7XG4gICAgICAgICAgfVxuICAgICAgICB9KSxcbiAgICAgICksXG4gICAgXSk7XG4gIH1cblxuICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgYENhbiBub3QgY3JlYXRlIEFTVCBmb3IgaXRlcmF0b3IgdmFyaWFibGUgb2YgJyR7bm9kZS5tZXRhLnZhbHVlfSdgLFxuICApO1xufVxuIl19