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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (179) hide show
  1. package/build/__tests__/edge-provider-schema/builder.js +106 -0
  2. package/build/__tests__/edge-provider-schema/cli.js +67 -0
  3. package/build/__tests__/edge-provider-schema/index.js +154 -0
  4. package/build/__tests__/edge-provider-schema.test.js +46 -0
  5. package/build/__tests__/provider.test.js +158 -0
  6. package/build/get/__tests__/constructs-maker.test.js +113 -0
  7. package/build/get/__tests__/generator/complex-computed-types.test.js +42 -0
  8. package/build/get/__tests__/generator/deep-nested-attributes.test.js +50 -0
  9. package/build/get/__tests__/generator/description-escaping.test.js +65 -0
  10. package/build/get/__tests__/generator/empty-provider-resources.test.js +40 -0
  11. package/build/get/__tests__/generator/export-sharding.test.js +82 -0
  12. package/build/get/__tests__/generator/module-generator.test.js +476 -0
  13. package/build/get/__tests__/generator/nested-types.test.js +51 -0
  14. package/build/get/__tests__/generator/provider.test.js +51 -0
  15. package/build/get/__tests__/generator/resource-types.test.js +78 -0
  16. package/build/get/__tests__/generator/skipped-attributes.test.js +55 -0
  17. package/build/get/__tests__/generator/types.test.js +289 -0
  18. package/build/get/__tests__/generator/versions-file.test.js +74 -0
  19. package/build/get/__tests__/util.js +59 -0
  20. package/{lib → build}/get/constructs-maker.d.ts +1 -1
  21. package/build/get/constructs-maker.js +530 -0
  22. package/build/get/generator/custom-defaults.js +403 -0
  23. package/build/get/generator/emitter/attributes-emitter.js +161 -0
  24. package/{lib → build}/get/generator/emitter/index.js +1 -1
  25. package/build/get/generator/emitter/resource-emitter.js +144 -0
  26. package/build/get/generator/emitter/struct-emitter.js +500 -0
  27. package/build/get/generator/loop-detection.js +56 -0
  28. package/build/get/generator/models/attribute-model.js +160 -0
  29. package/build/get/generator/models/attribute-type-model.js +376 -0
  30. package/{lib → build}/get/generator/models/index.js +1 -1
  31. package/build/get/generator/models/resource-model.js +106 -0
  32. package/build/get/generator/models/scope.js +36 -0
  33. package/build/get/generator/models/struct.js +90 -0
  34. package/build/get/generator/module-generator.js +184 -0
  35. package/build/get/generator/provider-generator.js +225 -0
  36. package/build/get/generator/resource-parser.js +497 -0
  37. package/build/get/generator/sanitized-comments.js +44 -0
  38. package/build/get/generator/skipped-attributes.js +29 -0
  39. package/{lib → build}/index.js +1 -1
  40. package/build/util.js +30 -0
  41. package/package.json +6 -6
  42. package/tsconfig.json +5 -3
  43. package/lib/__tests__/edge-provider-schema/builder.js +0 -106
  44. package/lib/__tests__/edge-provider-schema/cli.js +0 -67
  45. package/lib/__tests__/edge-provider-schema/index.js +0 -154
  46. package/lib/__tests__/edge-provider-schema.test.js +0 -46
  47. package/lib/__tests__/provider.test.js +0 -158
  48. package/lib/get/__tests__/constructs-maker.test.js +0 -113
  49. package/lib/get/__tests__/generator/complex-computed-types.test.js +0 -42
  50. package/lib/get/__tests__/generator/deep-nested-attributes.test.js +0 -50
  51. package/lib/get/__tests__/generator/description-escaping.test.js +0 -65
  52. package/lib/get/__tests__/generator/empty-provider-resources.test.js +0 -40
  53. package/lib/get/__tests__/generator/export-sharding.test.js +0 -82
  54. package/lib/get/__tests__/generator/module-generator.test.js +0 -476
  55. package/lib/get/__tests__/generator/nested-types.test.js +0 -51
  56. package/lib/get/__tests__/generator/provider.test.js +0 -51
  57. package/lib/get/__tests__/generator/resource-types.test.js +0 -78
  58. package/lib/get/__tests__/generator/skipped-attributes.test.js +0 -55
  59. package/lib/get/__tests__/generator/types.test.js +0 -289
  60. package/lib/get/__tests__/generator/versions-file.test.js +0 -74
  61. package/lib/get/__tests__/util.js +0 -59
  62. package/lib/get/constructs-maker.js +0 -530
  63. package/lib/get/generator/custom-defaults.js +0 -403
  64. package/lib/get/generator/emitter/attributes-emitter.js +0 -161
  65. package/lib/get/generator/emitter/resource-emitter.js +0 -144
  66. package/lib/get/generator/emitter/struct-emitter.js +0 -500
  67. package/lib/get/generator/loop-detection.js +0 -56
  68. package/lib/get/generator/models/attribute-model.js +0 -160
  69. package/lib/get/generator/models/attribute-type-model.js +0 -376
  70. package/lib/get/generator/models/resource-model.js +0 -106
  71. package/lib/get/generator/models/scope.js +0 -36
  72. package/lib/get/generator/models/struct.js +0 -90
  73. package/lib/get/generator/module-generator.js +0 -184
  74. package/lib/get/generator/provider-generator.js +0 -225
  75. package/lib/get/generator/resource-parser.js +0 -497
  76. package/lib/get/generator/sanitized-comments.js +0 -44
  77. package/lib/get/generator/skipped-attributes.js +0 -29
  78. package/lib/util.js +0 -30
  79. /package/{lib → build}/__tests__/edge-provider-schema/builder.d.ts +0 -0
  80. /package/{lib → build}/__tests__/edge-provider-schema/cli.d.ts +0 -0
  81. /package/{lib → build}/__tests__/edge-provider-schema/index.d.ts +0 -0
  82. /package/{lib → build}/__tests__/edge-provider-schema.test.d.ts +0 -0
  83. /package/{lib → build}/__tests__/provider.test.d.ts +0 -0
  84. /package/{lib → build}/get/__tests__/constructs-maker.test.d.ts +0 -0
  85. /package/{lib → build}/get/__tests__/generator/complex-computed-types.test.d.ts +0 -0
  86. /package/{lib → build}/get/__tests__/generator/deep-nested-attributes.test.d.ts +0 -0
  87. /package/{lib → build}/get/__tests__/generator/description-escaping.test.d.ts +0 -0
  88. /package/{lib → build}/get/__tests__/generator/empty-provider-resources.test.d.ts +0 -0
  89. /package/{lib → build}/get/__tests__/generator/export-sharding.test.d.ts +0 -0
  90. /package/{lib → build}/get/__tests__/generator/module-generator.test.d.ts +0 -0
  91. /package/{lib → build}/get/__tests__/generator/nested-types.test.d.ts +0 -0
  92. /package/{lib → build}/get/__tests__/generator/provider.test.d.ts +0 -0
  93. /package/{lib → build}/get/__tests__/generator/resource-types.test.d.ts +0 -0
  94. /package/{lib → build}/get/__tests__/generator/skipped-attributes.test.d.ts +0 -0
  95. /package/{lib → build}/get/__tests__/generator/types.test.d.ts +0 -0
  96. /package/{lib → build}/get/__tests__/generator/versions-file.test.d.ts +0 -0
  97. /package/{lib → build}/get/__tests__/util.d.ts +0 -0
  98. /package/{lib → build}/get/generator/custom-defaults.d.ts +0 -0
  99. /package/{lib → build}/get/generator/emitter/attributes-emitter.d.ts +0 -0
  100. /package/{lib → build}/get/generator/emitter/index.d.ts +0 -0
  101. /package/{lib → build}/get/generator/emitter/resource-emitter.d.ts +0 -0
  102. /package/{lib → build}/get/generator/emitter/struct-emitter.d.ts +0 -0
  103. /package/{lib → build}/get/generator/loop-detection.d.ts +0 -0
  104. /package/{lib → build}/get/generator/models/attribute-model.d.ts +0 -0
  105. /package/{lib → build}/get/generator/models/attribute-type-model.d.ts +0 -0
  106. /package/{lib → build}/get/generator/models/index.d.ts +0 -0
  107. /package/{lib → build}/get/generator/models/resource-model.d.ts +0 -0
  108. /package/{lib → build}/get/generator/models/scope.d.ts +0 -0
  109. /package/{lib → build}/get/generator/models/struct.d.ts +0 -0
  110. /package/{lib → build}/get/generator/module-generator.d.ts +0 -0
  111. /package/{lib → build}/get/generator/provider-generator.d.ts +0 -0
  112. /package/{lib → build}/get/generator/resource-parser.d.ts +0 -0
  113. /package/{lib → build}/get/generator/sanitized-comments.d.ts +0 -0
  114. /package/{lib → build}/get/generator/skipped-attributes.d.ts +0 -0
  115. /package/{lib → build}/index.d.ts +0 -0
  116. /package/{lib → build}/util.d.ts +0 -0
  117. /package/{lib → src}/__tests__/__snapshots__/edge-provider-schema.test.ts.snap +0 -0
  118. /package/{lib → src}/__tests__/__snapshots__/provider.test.ts.snap +0 -0
  119. /package/{lib → src}/get/__tests__/generator/__snapshots__/complex-computed-types.test.ts.snap +0 -0
  120. /package/{lib → src}/get/__tests__/generator/__snapshots__/description-escaping.test.ts.snap +0 -0
  121. /package/{lib → src}/get/__tests__/generator/__snapshots__/export-sharding.test.ts.snap +0 -0
  122. /package/{lib → src}/get/__tests__/generator/__snapshots__/module-generator.test.ts.snap +0 -0
  123. /package/{lib → src}/get/__tests__/generator/__snapshots__/nested-types.test.ts.snap +0 -0
  124. /package/{lib → src}/get/__tests__/generator/__snapshots__/provider.test.ts.snap +0 -0
  125. /package/{lib → src}/get/__tests__/generator/__snapshots__/resource-types.test.ts.snap +0 -0
  126. /package/{lib → src}/get/__tests__/generator/__snapshots__/skipped-attributes.test.ts.snap +0 -0
  127. /package/{lib → src}/get/__tests__/generator/__snapshots__/types.test.ts.snap +0 -0
  128. /package/{lib → src}/get/__tests__/generator/fixtures/aws-provider.test.fixture.json +0 -0
  129. /package/{lib → src}/get/__tests__/generator/fixtures/aws_acm_certificate.test.fixture.json +0 -0
  130. /package/{lib → src}/get/__tests__/generator/fixtures/aws_cloudfront_distribution.test.fixture.json +0 -0
  131. /package/{lib → src}/get/__tests__/generator/fixtures/aws_fms_admin_account.test.fixture.json +0 -0
  132. /package/{lib → src}/get/__tests__/generator/fixtures/aws_quicksight_template.test.fixture.json +0 -0
  133. /package/{lib → src}/get/__tests__/generator/fixtures/aws_s3_bucket.test.fixture.json +0 -0
  134. /package/{lib → src}/get/__tests__/generator/fixtures/aws_security_group.test.fixture.json +0 -0
  135. /package/{lib → src}/get/__tests__/generator/fixtures/aws_wafv2_web_acl.test.fixture.json +0 -0
  136. /package/{lib → src}/get/__tests__/generator/fixtures/block-type-nested-computed-list.test.fixture.json +0 -0
  137. /package/{lib → src}/get/__tests__/generator/fixtures/block-type-set-list.test.fixture.json +0 -0
  138. /package/{lib → src}/get/__tests__/generator/fixtures/boolean-list.test.fixture.json +0 -0
  139. /package/{lib → src}/get/__tests__/generator/fixtures/boolean-map.test.fixture.json +0 -0
  140. /package/{lib → src}/get/__tests__/generator/fixtures/comment-ending-sequence.test.fixture.json +0 -0
  141. /package/{lib → src}/get/__tests__/generator/fixtures/computed-complex-nested.test.fixture.json +0 -0
  142. /package/{lib → src}/get/__tests__/generator/fixtures/computed-complex.test.fixture.json +0 -0
  143. /package/{lib → src}/get/__tests__/generator/fixtures/computed-optional-complex.test.fixture.json +0 -0
  144. /package/{lib → src}/get/__tests__/generator/fixtures/data_aws_quicksight_analysis.fixture.json +0 -0
  145. /package/{lib → src}/get/__tests__/generator/fixtures/datadog_dashboard.test.fixture.json +0 -0
  146. /package/{lib → src}/get/__tests__/generator/fixtures/datadog_spans_metric.test.fixture.json +0 -0
  147. /package/{lib → src}/get/__tests__/generator/fixtures/deep-attributes.test.fixture.json +0 -0
  148. /package/{lib → src}/get/__tests__/generator/fixtures/deeply-nested-block-types.test.fixture.json +0 -0
  149. /package/{lib → src}/get/__tests__/generator/fixtures/description-escaping.test.fixture.json +0 -0
  150. /package/{lib → src}/get/__tests__/generator/fixtures/elasticstack-provider.test.fixture.json +0 -0
  151. /package/{lib → src}/get/__tests__/generator/fixtures/empty-provider-resources.test.fixture.json +0 -0
  152. /package/{lib → src}/get/__tests__/generator/fixtures/ignored-attributes.test.fixture.json +0 -0
  153. /package/{lib → src}/get/__tests__/generator/fixtures/incompatible-attribute-names.test.fixture.json +0 -0
  154. /package/{lib → src}/get/__tests__/generator/fixtures/incompatible-resource-names.test.fixture.json +0 -0
  155. /package/{lib → src}/get/__tests__/generator/fixtures/list-list-object.test.fixture.json +0 -0
  156. /package/{lib → src}/get/__tests__/generator/fixtures/list-list-string.test.fixture.json +0 -0
  157. /package/{lib → src}/get/__tests__/generator/fixtures/list-of-string-map.test.fixture.json +0 -0
  158. /package/{lib → src}/get/__tests__/generator/fixtures/map-of-map-of-string.test.fixture.json +0 -0
  159. /package/{lib → src}/get/__tests__/generator/fixtures/map-of-string-list.test.fixture.json +0 -0
  160. /package/{lib → src}/get/__tests__/generator/fixtures/markdown-description-with-code-blocks.test.fixture.json +0 -0
  161. /package/{lib → src}/get/__tests__/generator/fixtures/module-get-x.test.fixture.tf +0 -0
  162. /package/{lib → src}/get/__tests__/generator/fixtures/module-no-newline-1.test.fixture.tf +0 -0
  163. /package/{lib → src}/get/__tests__/generator/fixtures/module-no-newline-2.test.fixture.tf +0 -0
  164. /package/{lib → src}/get/__tests__/generator/fixtures/module-no-outputs.test.fixture.tf +0 -0
  165. /package/{lib → src}/get/__tests__/generator/fixtures/module-no-variable-type.test.fixture.tf +0 -0
  166. /package/{lib → src}/get/__tests__/generator/fixtures/module-with-star-default.test.fixture.tf +0 -0
  167. /package/{lib → src}/get/__tests__/generator/fixtures/name-conflict.test.fixture.json +0 -0
  168. /package/{lib → src}/get/__tests__/generator/fixtures/nested-type-without-attributes.test.fixture.json +0 -0
  169. /package/{lib → src}/get/__tests__/generator/fixtures/nested-types.test.fixture.json +0 -0
  170. /package/{lib → src}/get/__tests__/generator/fixtures/number-list.test.fixture.json +0 -0
  171. /package/{lib → src}/get/__tests__/generator/fixtures/number-map.test.fixture.json +0 -0
  172. /package/{lib → src}/get/__tests__/generator/fixtures/primitive-boolean.test.fixture.json +0 -0
  173. /package/{lib → src}/get/__tests__/generator/fixtures/primitive-dynamic.test.fixture.json +0 -0
  174. /package/{lib → src}/get/__tests__/generator/fixtures/primitive-number.test.fixture.json +0 -0
  175. /package/{lib → src}/get/__tests__/generator/fixtures/primitive-string.test.fixture.json +0 -0
  176. /package/{lib → src}/get/__tests__/generator/fixtures/single-block-type.test.fixture.json +0 -0
  177. /package/{lib → src}/get/__tests__/generator/fixtures/string-list.test.fixture.json +0 -0
  178. /package/{lib → src}/get/__tests__/generator/fixtures/string-map.test.fixture.json +0 -0
  179. /package/{lib → src}/get/__tests__/generator/fixtures/stripe-schema.test.fixture.json +0 -0
@@ -0,0 +1,500 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ Object.defineProperty(exports, "__esModule", { value: true });
26
+ exports.StructEmitter = void 0;
27
+ const models_1 = require("../models");
28
+ const attributes_emitter_1 = require("./attributes-emitter");
29
+ const util_1 = require("../../../util");
30
+ const path = __importStar(require("path"));
31
+ const resource_model_1 = require("../models/resource-model");
32
+ const sanitized_comments_1 = require("../sanitized-comments");
33
+ class StructEmitter {
34
+ constructor(code) {
35
+ this.code = code;
36
+ this.attributesEmitter = new attributes_emitter_1.AttributesEmitter(this.code);
37
+ }
38
+ emit(resource) {
39
+ if (resource.structsRequireSharding) {
40
+ this.emitNamespacedStructs(resource);
41
+ }
42
+ else {
43
+ this.emitStructs(resource);
44
+ }
45
+ }
46
+ // Due to https://github.com/hashicorp/terraform-plugin-sdk/commit/2387eb85e32c064b4a62718c9f5c80bf00dc7fb9 all
47
+ // resources from providers using the old SDK have the id field by default
48
+ // We have no way to distinguish them through the provider schema, so a word of warning for our users
49
+ warnAboutIdField(att) {
50
+ if (att.name === "id") {
51
+ this.code.line(`*`);
52
+ this.code.line(`* Please be aware that the id field is automatically added to all resources in Terraform providers using a Terraform provider SDK version below 2.`);
53
+ this.code.line(`* If you experience problems setting this value it might not be settable. Please take a look at the provider documentation to ensure it should be settable.`);
54
+ }
55
+ }
56
+ emitInterface(resource, struct, name = struct.name) {
57
+ if (resource.isProvider) {
58
+ this.code.openBlock(`export interface ${name}`);
59
+ }
60
+ else {
61
+ this.code.openBlock(`export interface ${name}${struct.extends}`);
62
+ }
63
+ for (const att of struct.assignableAttributes) {
64
+ const comment = (0, sanitized_comments_1.sanitizedComment)(this.code);
65
+ if (att.description) {
66
+ comment.line(att.description);
67
+ comment.line(``);
68
+ comment.line(`Docs at Terraform Registry: {@link ${resource.linkToDocs}#${att.terraformName} ${resource.className}#${att.terraformName}}`);
69
+ this.warnAboutIdField(att);
70
+ comment.end();
71
+ }
72
+ else {
73
+ comment.line(`Docs at Terraform Registry: {@link ${resource.linkToDocs}#${att.terraformName} ${resource.className}#${att.terraformName}}`);
74
+ this.warnAboutIdField(att);
75
+ comment.end();
76
+ }
77
+ this.code.line(`readonly ${att.typeDefinition};`);
78
+ }
79
+ this.code.closeBlock();
80
+ if (!(struct instanceof models_1.ConfigStruct)) {
81
+ this.emitToTerraformFunction(struct);
82
+ this.emitToHclTerraformFunction(struct);
83
+ }
84
+ }
85
+ emitStructs(resource) {
86
+ resource.structs.forEach((struct) => {
87
+ if (struct instanceof models_1.ConfigStruct) {
88
+ this.emitInterface(resource, struct);
89
+ }
90
+ else {
91
+ // We use the interface here for the configuration / inputs of a resource / nested block
92
+ this.emitInterface(resource, struct);
93
+ // And we use the class for the attributes / outputs of a resource / nested block
94
+ if (!struct.isProvider) {
95
+ this.emitClass(struct);
96
+ }
97
+ }
98
+ });
99
+ }
100
+ emitNamespacedStructs(resource) {
101
+ // iterate over all structs in batches of 400 to avoid too many exports (> 1200)
102
+ const structImports = {};
103
+ // drop configStruct from resource.structs to avoid double import
104
+ const structsWithoutConfigStruct = resource.structs.slice(1);
105
+ const structSplits = [[]];
106
+ const splitCounts = [0];
107
+ structsWithoutConfigStruct.forEach((struct) => {
108
+ if (splitCounts[splitCounts.length - 1] + struct.exportCount <=
109
+ resource_model_1.STRUCT_SHARDING_THRESHOLD) {
110
+ structSplits[structSplits.length - 1].push(struct);
111
+ splitCounts[splitCounts.length - 1] += struct.exportCount;
112
+ }
113
+ else {
114
+ structSplits.push([struct]);
115
+ splitCounts.push(struct.exportCount);
116
+ }
117
+ });
118
+ // fill the struct imports mapping before code generation so that imports can
119
+ // point to not yet generated struct files
120
+ for (let i = 0; i < structSplits.length; i++) {
121
+ const structFilename = `structs${i * resource_model_1.STRUCT_SHARDING_THRESHOLD}.ts`;
122
+ const structs = structSplits[i];
123
+ // associate current structs batch with the file it will be written to
124
+ // to find it in subsequent files for importing
125
+ structs.forEach((struct) => (structImports[struct.name] = structFilename));
126
+ }
127
+ const structPaths = [];
128
+ for (let i = 0; i < structSplits.length; i++) {
129
+ const structsToImport = {};
130
+ const structs = structSplits[i];
131
+ const structFilename = `structs${i * resource_model_1.STRUCT_SHARDING_THRESHOLD}.ts`;
132
+ structPaths.push(structFilename);
133
+ // find all structs that need to be imported in this file
134
+ structs.forEach((struct) => {
135
+ struct.attributes.forEach((att) => {
136
+ var _a, _b;
137
+ const structTypeName = (_a = att.type.struct) === null || _a === void 0 ? void 0 : _a.name;
138
+ const fileToImport = structImports[structTypeName !== null && structTypeName !== void 0 ? structTypeName : ""];
139
+ if (fileToImport && fileToImport !== structFilename) {
140
+ const attTypeStruct = att.type.struct;
141
+ if (!attTypeStruct)
142
+ throw new Error(`${structTypeName} is not a struct`);
143
+ (_b = structsToImport[fileToImport]) !== null && _b !== void 0 ? _b : (structsToImport[fileToImport] = []);
144
+ const attReferences = att.getReferencedTypes(struct instanceof models_1.ConfigStruct);
145
+ if (attReferences) {
146
+ structsToImport[fileToImport].push(...attReferences);
147
+ }
148
+ }
149
+ });
150
+ });
151
+ const namespacedFilePath = path.join(resource.structsFolderPath, structFilename);
152
+ this.code.openFile(namespacedFilePath);
153
+ // the structs only makes use of cdktn not constructs
154
+ this.code.line(`import * as cdktn from 'cdktn';`);
155
+ Object.entries(structsToImport).forEach(([fileToImport, structs]) => {
156
+ this.code.line(`import { ${[...new Set(structs)].join(",\n")} } from './${path.basename(fileToImport, ".ts")}'`);
157
+ });
158
+ structs.forEach((struct) => {
159
+ if (struct instanceof models_1.ConfigStruct) {
160
+ this.emitInterface(resource, struct);
161
+ }
162
+ else {
163
+ // We use the interface here for the configuration / inputs of a resource / nested block
164
+ this.emitInterface(resource, struct);
165
+ // And we use the class for the attributes / outputs of a resource / nested block
166
+ if (!struct.isProvider) {
167
+ this.emitClass(struct);
168
+ }
169
+ }
170
+ });
171
+ this.code.closeFile(namespacedFilePath);
172
+ }
173
+ // emit the index file that exports all the struct files we've just generated
174
+ const indexFilePath = path.join(resource.structsFolderPath, "index.ts");
175
+ this.code.openFile(indexFilePath);
176
+ structPaths.forEach((structPath) => {
177
+ this.code.line(`export * from './${path.basename(structPath, ".ts")}'`);
178
+ });
179
+ this.code.closeFile(indexFilePath);
180
+ }
181
+ emitClass(struct) {
182
+ this.code.openBlock(`export class ${struct.outputReferenceName} extends cdktn.ComplexObject`);
183
+ this.code.line("private isEmptyObject = false;");
184
+ if (!struct.isClass) {
185
+ this.code.line("private resolvableValue?: cdktn.IResolvable;");
186
+ }
187
+ this.code.line();
188
+ const comment = (0, sanitized_comments_1.sanitizedComment)(this.code);
189
+ comment.line(`@param terraformResource The parent resource`);
190
+ comment.line(`@param terraformAttribute The attribute on the parent resource this class is referencing`);
191
+ if (struct.isSingleItem) {
192
+ comment.end();
193
+ this.code.openBlock(`public constructor(terraformResource: cdktn.IInterpolatingParent, terraformAttribute: string)`);
194
+ this.code.line(`super(terraformResource, terraformAttribute, false, 0);`);
195
+ this.code.closeBlock();
196
+ }
197
+ else if (struct.nestingMode === "single" ||
198
+ struct.nestingMode === "object") {
199
+ comment.end();
200
+ this.code.openBlock(`public constructor(terraformResource: cdktn.IInterpolatingParent, terraformAttribute: string)`);
201
+ this.code.line(`super(terraformResource, terraformAttribute, false);`);
202
+ this.code.closeBlock();
203
+ }
204
+ else if (struct.nestingMode.startsWith("map")) {
205
+ this.code.line(`* @param complexObjectKey the key of this item in the map`);
206
+ comment.end();
207
+ this.code.openBlock(`public constructor(terraformResource: cdktn.IInterpolatingParent, terraformAttribute: string, complexObjectKey: string)`);
208
+ this.code.line(`super(terraformResource, terraformAttribute, false, complexObjectKey);`);
209
+ this.code.closeBlock();
210
+ }
211
+ else {
212
+ comment.line(`@param complexObjectIndex the index of this item in the list`);
213
+ comment.line(`@param complexObjectIsFromSet whether the list is wrapping a set (will add tolist() to be able to access an item via an index)`);
214
+ comment.end();
215
+ this.code.openBlock(`public constructor(terraformResource: cdktn.IInterpolatingParent, terraformAttribute: string, complexObjectIndex: number, complexObjectIsFromSet: boolean)`);
216
+ this.code.line(`super(terraformResource, terraformAttribute, complexObjectIsFromSet, complexObjectIndex);`);
217
+ this.code.closeBlock();
218
+ }
219
+ this.code.line();
220
+ this.emitInternalValueGetter(struct);
221
+ this.code.line();
222
+ this.emitInternalValueSetter(struct);
223
+ for (const att of struct.attributes) {
224
+ this.attributesEmitter.emit(att, this.attributesEmitter.needsResetEscape(att, struct.attributes), this.attributesEmitter.needsInputEscape(att, struct.attributes));
225
+ }
226
+ this.code.closeBlock();
227
+ if (!struct.isSingleItem &&
228
+ (struct.nestingMode === "list" || struct.nestingMode === "set")) {
229
+ this.emitComplexListClass(struct);
230
+ }
231
+ else if (struct.nestingMode === "map") {
232
+ this.emitComplexMapClass(struct);
233
+ }
234
+ else if (struct.nestingMode === "maplist") {
235
+ this.emitComplexMapListClasses(struct);
236
+ }
237
+ else if (struct.nestingMode === "mapset") {
238
+ this.emitComplexMapListClasses(struct);
239
+ }
240
+ else if (struct.nestingMode === "listmap") {
241
+ this.emitComplexListMapClasses(struct, false);
242
+ }
243
+ else if (struct.nestingMode === "setmap") {
244
+ this.emitComplexListMapClasses(struct, true);
245
+ }
246
+ else if (struct.nestingMode === "listlist" ||
247
+ struct.nestingMode === "listset" ||
248
+ struct.nestingMode === "setlist" ||
249
+ struct.nestingMode === "setset") {
250
+ this.emitComplexListListClasses(struct);
251
+ }
252
+ // other types of nested collections aren't supported
253
+ }
254
+ emitComplexListClass(struct) {
255
+ this.code.line();
256
+ this.code.openBlock(`export class ${struct.listName} extends cdktn.ComplexList`);
257
+ if (struct.assignable) {
258
+ this.code.line(`public internalValue? : ${struct.name}[] | cdktn.IResolvable`);
259
+ }
260
+ this.code.line();
261
+ const constructorComment = (0, sanitized_comments_1.sanitizedComment)(this.code);
262
+ constructorComment.line(`@param terraformResource The parent resource`);
263
+ constructorComment.line(`@param terraformAttribute The attribute on the parent resource this class is referencing`);
264
+ constructorComment.line(`@param wrapsSet whether the list is wrapping a set (will add tolist() to be able to access an item via an index)`);
265
+ constructorComment.end();
266
+ this.code.openBlock(`constructor(terraformResource: cdktn.IInterpolatingParent, terraformAttribute: string, wrapsSet: boolean)`);
267
+ this.code.line(`super(terraformResource, terraformAttribute, wrapsSet)`);
268
+ this.code.closeBlock();
269
+ this.code.line();
270
+ const getterComment = (0, sanitized_comments_1.sanitizedComment)(this.code);
271
+ getterComment.line(`@param index the index of the item to return`);
272
+ getterComment.end();
273
+ this.code.openBlock(`public get(index: number): ${struct.outputReferenceName}`);
274
+ this.code.line(`return new ${struct.outputReferenceName}(this.terraformResource, this.terraformAttribute, index, this.wrapsSet);`);
275
+ this.code.closeBlock();
276
+ this.code.closeBlock();
277
+ }
278
+ emitComplexMapClass(struct) {
279
+ this.code.line();
280
+ this.code.openBlock(`export class ${struct.mapName} extends cdktn.ComplexMap`);
281
+ if (struct.assignable) {
282
+ this.code.line(`public internalValue? : { [key: string]: ${struct.name} } | cdktn.IResolvable`);
283
+ }
284
+ this.code.line();
285
+ const constructorComment = (0, sanitized_comments_1.sanitizedComment)(this.code);
286
+ constructorComment.line(`@param terraformResource The parent resource`);
287
+ constructorComment.line(`@param terraformAttribute The attribute on the parent resource this class is referencing`);
288
+ constructorComment.end();
289
+ this.code.openBlock(`constructor(terraformResource: cdktn.IInterpolatingParent, terraformAttribute: string)`);
290
+ this.code.line(`super(terraformResource, terraformAttribute)`);
291
+ this.code.closeBlock();
292
+ this.code.line();
293
+ const getterComment = (0, sanitized_comments_1.sanitizedComment)(this.code);
294
+ getterComment.line(`@param key the key of the item to return`);
295
+ getterComment.end();
296
+ this.code.openBlock(`public get(key: string): ${struct.outputReferenceName}`);
297
+ this.code.line(`return new ${struct.outputReferenceName}(this.terraformResource, this.terraformAttribute, key);`);
298
+ this.code.closeBlock();
299
+ this.code.closeBlock();
300
+ }
301
+ emitComplexMapListClasses(struct) {
302
+ this.emitComplexMapListClass(struct);
303
+ this.emitComplexMapClass(struct);
304
+ }
305
+ emitComplexMapListClass(struct) {
306
+ this.code.line();
307
+ this.code.openBlock(`export class ${struct.mapListName} extends cdktn.MapList`);
308
+ if (struct.assignable) {
309
+ this.code.line(`public internalValue? : ${struct.mapName}[] | cdktn.IResolvable`);
310
+ }
311
+ this.code.line();
312
+ const constructorComment = (0, sanitized_comments_1.sanitizedComment)(this.code);
313
+ constructorComment.line(`@param terraformResource The parent resource`);
314
+ constructorComment.line(`@param terraformAttribute The attribute on the parent resource this class is referencing`);
315
+ constructorComment.line(`@param wrapsSet whether the list is wrapping a set (will add tolist() to be able to access an item via an index)`);
316
+ constructorComment.end();
317
+ this.code.openBlock(`constructor(terraformResource: cdktn.IInterpolatingParent, terraformAttribute: string, wrapsSet: boolean)`);
318
+ this.code.line(`super(terraformResource, terraformAttribute, wrapsSet)`);
319
+ this.code.closeBlock();
320
+ this.code.line();
321
+ const getterComment = (0, sanitized_comments_1.sanitizedComment)(this.code);
322
+ getterComment.line(`@param index the index of the item to return`);
323
+ getterComment.end();
324
+ this.code.openBlock(`public get(index: number): ${struct.mapName}`);
325
+ this.code.line(`return new ${struct.mapName}(this, \`[\${index}]\`);`);
326
+ this.code.closeBlock();
327
+ this.code.closeBlock();
328
+ }
329
+ emitComplexListMapClasses(struct, isSet) {
330
+ this.emitComplexListMapClass(struct, isSet);
331
+ this.emitComplexListClass(struct);
332
+ }
333
+ emitComplexListMapClass(struct, isSet) {
334
+ this.code.line();
335
+ this.code.openBlock(`export class ${struct.listMapName} extends cdktn.ComplexMap`);
336
+ if (struct.assignable) {
337
+ this.code.line(`public internalValue? : { [key: string]: ${struct.name}[] } | cdktn.IResolvable`);
338
+ }
339
+ this.code.line();
340
+ const constructorComment = (0, sanitized_comments_1.sanitizedComment)(this.code);
341
+ constructorComment.line(`@param terraformResource The parent resource`);
342
+ constructorComment.line(`@param terraformAttribute The attribute on the parent resource this class is referencing`);
343
+ constructorComment.end();
344
+ this.code.openBlock(`constructor(terraformResource: cdktn.IInterpolatingParent, terraformAttribute: string)`);
345
+ this.code.line(`super(terraformResource, terraformAttribute)`);
346
+ this.code.closeBlock();
347
+ this.code.line();
348
+ const getterComment = (0, sanitized_comments_1.sanitizedComment)(this.code);
349
+ getterComment.line(`@param key the key of the item to return`);
350
+ getterComment.end();
351
+ this.code.openBlock(`public get(key: string): ${struct.listName}`);
352
+ this.code.line(`return new ${struct.listName}(this, \`[\${key}]\`, ${isSet});`);
353
+ this.code.closeBlock();
354
+ this.code.closeBlock();
355
+ }
356
+ emitComplexListListClasses(struct) {
357
+ this.emitComplexListListClass(struct);
358
+ this.emitComplexListClass(struct);
359
+ }
360
+ emitComplexListListClass(struct) {
361
+ this.code.line();
362
+ this.code.openBlock(`export class ${struct.listListName} extends cdktn.MapList`);
363
+ if (struct.assignable) {
364
+ this.code.line(`public internalValue? : ${struct.name}[][] | cdktn.IResolvable`);
365
+ }
366
+ this.code.line();
367
+ const constructorComment = (0, sanitized_comments_1.sanitizedComment)(this.code);
368
+ constructorComment.line(`@param terraformResource The parent resource`);
369
+ constructorComment.line(`@param terraformAttribute The attribute on the parent resource this class is referencing`);
370
+ constructorComment.line(`@param wrapsSet whether the list is wrapping a set (will add tolist() to be able to access an item via an index)`);
371
+ constructorComment.end();
372
+ this.code.openBlock(`constructor(terraformResource: cdktn.IInterpolatingParent, terraformAttribute: string, wrapsSet: boolean)`);
373
+ this.code.line(`super(terraformResource, terraformAttribute, wrapsSet)`);
374
+ this.code.closeBlock();
375
+ this.code.line();
376
+ const getterComment = (0, sanitized_comments_1.sanitizedComment)(this.code);
377
+ getterComment.line(`@param index the index of the item to return`);
378
+ getterComment.end();
379
+ this.code.openBlock(`public get(index: number): ${struct.listName}`);
380
+ this.code.line(`return new ${struct.listName}(this, \`[\${index}]\`, ${struct.nestingMode === "setlist" || struct.nestingMode === "setset"});`);
381
+ this.code.closeBlock();
382
+ this.code.closeBlock();
383
+ }
384
+ emitInternalValueGetter(struct) {
385
+ this.code.openBlock(`public get internalValue(): ${struct.name}${!struct.isClass ? " | cdktn.IResolvable" : ""} | undefined`);
386
+ if (!struct.isClass) {
387
+ this.code.openBlock("if (this.resolvableValue)");
388
+ this.code.line("return this.resolvableValue;");
389
+ this.code.closeBlock();
390
+ }
391
+ this.code.line("let hasAnyValues = this.isEmptyObject;");
392
+ this.code.line("const internalValueResult: any = {};");
393
+ for (const att of struct.attributes) {
394
+ if (att.isStored) {
395
+ if (att.getterType._type === "stored_class") {
396
+ this.code.openBlock(`if (this.${att.storageName}?.internalValue !== undefined)`);
397
+ }
398
+ else {
399
+ this.code.openBlock(`if (this.${att.storageName} !== undefined)`);
400
+ }
401
+ this.code.line("hasAnyValues = true;");
402
+ if (att.getterType._type === "stored_class") {
403
+ this.code.line(`internalValueResult.${att.name} = this.${att.storageName}?.internalValue;`);
404
+ }
405
+ else {
406
+ this.code.line(`internalValueResult.${att.name} = this.${att.storageName};`);
407
+ }
408
+ this.code.closeBlock();
409
+ }
410
+ }
411
+ this.code.line("return hasAnyValues ? internalValueResult : undefined;");
412
+ this.code.closeBlock();
413
+ }
414
+ emitInternalValueSetter(struct) {
415
+ this.code.openBlock(`public set internalValue(value: ${struct.name}${!struct.isClass ? " | cdktn.IResolvable" : ""} | undefined)`);
416
+ this.code.openBlock("if (value === undefined)");
417
+ this.code.line("this.isEmptyObject = false;");
418
+ if (!struct.isClass) {
419
+ this.code.line("this.resolvableValue = undefined;");
420
+ }
421
+ for (const att of struct.attributes) {
422
+ if (att.isStored) {
423
+ if (att.setterType._type === "stored_class") {
424
+ this.code.line(`this.${att.storageName}.internalValue = undefined;`);
425
+ }
426
+ else if (att.setterType._type !== "none") {
427
+ this.code.line(`this.${att.storageName} = undefined;`);
428
+ }
429
+ }
430
+ }
431
+ this.code.closeBlock();
432
+ if (!struct.isClass) {
433
+ this.code.openBlock("else if (cdktn.Tokenization.isResolvable(value))");
434
+ this.code.line("this.isEmptyObject = false;");
435
+ this.code.line("this.resolvableValue = value;");
436
+ this.code.closeBlock();
437
+ }
438
+ this.code.openBlock("else");
439
+ this.code.line("this.isEmptyObject = Object.keys(value).length === 0;");
440
+ if (!struct.isClass) {
441
+ this.code.line("this.resolvableValue = undefined;");
442
+ }
443
+ for (const att of struct.attributes) {
444
+ if (att.isStored) {
445
+ if (att.setterType._type === "stored_class") {
446
+ this.code.line(`this.${att.storageName}.internalValue = value.${att.name};`);
447
+ }
448
+ else if (att.setterType._type !== "none") {
449
+ this.code.line(`this.${att.storageName} = value.${att.name};`);
450
+ }
451
+ }
452
+ }
453
+ this.code.closeBlock();
454
+ this.code.closeBlock();
455
+ }
456
+ emitToHclTerraformFunction(struct) {
457
+ this.code.line();
458
+ this.code.openBlock(`export function ${(0, util_1.downcaseFirst)(struct.name)}ToHclTerraform(struct?: ${struct.isSingleItem && !struct.isProvider
459
+ ? `${struct.name}OutputReference | `
460
+ : ""}${struct.name}${!struct.isClass ? " | cdktn.IResolvable" : ""}): any`);
461
+ this.code.line(`if (!cdktn.canInspect(struct) || cdktn.Tokenization.isResolvable(struct)) { return struct; }`);
462
+ this.code.openBlock(`if (cdktn.isComplexElement(struct))`);
463
+ this.code.line(`throw new Error("A complex element was used as configuration, this is not supported: https://cdk.tf/complex-object-as-configuration");`);
464
+ this.code.closeBlock();
465
+ this.code.open(`const attrs = {`);
466
+ for (const att of struct.assignableAttributes) {
467
+ this.attributesEmitter.emitToHclTerraform(att, true);
468
+ }
469
+ this.code.close(`};`);
470
+ if (struct.assignableAttributes.length > 0) {
471
+ this.code.line();
472
+ this.code.line(`// remove undefined attributes`);
473
+ this.code.line(`return Object.fromEntries(Object.entries(attrs).filter(([_, value]) => value !== undefined && value.value !== undefined));`);
474
+ }
475
+ else {
476
+ this.code.line(`return attrs;`);
477
+ }
478
+ this.code.closeBlock();
479
+ this.code.line();
480
+ }
481
+ emitToTerraformFunction(struct) {
482
+ this.code.line();
483
+ this.code.openBlock(`export function ${(0, util_1.downcaseFirst)(struct.name)}ToTerraform(struct?: ${struct.isSingleItem && !struct.isProvider
484
+ ? `${struct.name}OutputReference | `
485
+ : ""}${struct.name}${!struct.isClass ? " | cdktn.IResolvable" : ""}): any`);
486
+ this.code.line(`if (!cdktn.canInspect(struct) || cdktn.Tokenization.isResolvable(struct)) { return struct; }`);
487
+ this.code.openBlock(`if (cdktn.isComplexElement(struct))`);
488
+ this.code.line(`throw new Error("A complex element was used as configuration, this is not supported: https://cdk.tf/complex-object-as-configuration");`);
489
+ this.code.closeBlock();
490
+ this.code.openBlock("return");
491
+ for (const att of struct.assignableAttributes) {
492
+ this.attributesEmitter.emitToTerraform(att, true);
493
+ }
494
+ this.code.closeBlock(";");
495
+ this.code.closeBlock();
496
+ this.code.line();
497
+ }
498
+ }
499
+ exports.StructEmitter = StructEmitter;
500
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RydWN0LWVtaXR0ZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvZ2V0L2dlbmVyYXRvci9lbWl0dGVyL3N0cnVjdC1lbWl0dGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBR0Esc0NBQWdFO0FBQ2hFLDZEQUF5RDtBQUN6RCx3Q0FBOEM7QUFDOUMsMkNBQTZCO0FBQzdCLDZEQUFxRTtBQUVyRSw4REFBeUQ7QUFDekQsTUFBYSxhQUFhO0lBR3hCLFlBQTZCLElBQWU7UUFBZixTQUFJLEdBQUosSUFBSSxDQUFXO1FBQzFDLElBQUksQ0FBQyxpQkFBaUIsR0FBRyxJQUFJLHNDQUFpQixDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUM1RCxDQUFDO0lBRU0sSUFBSSxDQUFDLFFBQXVCO1FBQ2pDLElBQUksUUFBUSxDQUFDLHNCQUFzQixFQUFFLENBQUM7WUFDcEMsSUFBSSxDQUFDLHFCQUFxQixDQUFDLFFBQVEsQ0FBQyxDQUFDO1FBQ3ZDLENBQUM7YUFBTSxDQUFDO1lBQ04sSUFBSSxDQUFDLFdBQVcsQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUM3QixDQUFDO0lBQ0gsQ0FBQztJQUVELCtHQUErRztJQUMvRywwRUFBMEU7SUFDMUUscUdBQXFHO0lBQzdGLGdCQUFnQixDQUFDLEdBQW1CO1FBQzFDLElBQUksR0FBRyxDQUFDLElBQUksS0FBSyxJQUFJLEVBQUUsQ0FBQztZQUN0QixJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQztZQUNwQixJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FDWixvSkFBb0osQ0FDckosQ0FBQztZQUNGLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUNaLDZKQUE2SixDQUM5SixDQUFDO1FBQ0osQ0FBQztJQUNILENBQUM7SUFFTSxhQUFhLENBQ2xCLFFBQXVCLEVBQ3ZCLE1BQWMsRUFDZCxJ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U1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IE1QTC0yLjBcbmltcG9ydCB7IENvZGVNYWtlciB9IGZyb20gXCJjb2RlbWFrZXJcIjtcbmltcG9ydCB7IFJlc291cmNlTW9kZWwsIFN0cnVjdCwgQ29uZmlnU3RydWN0IH0gZnJvbSBcIi4uL21vZGVsc1wiO1xuaW1wb3J0IHsgQXR0cmlidXRlc0VtaXR0ZXIgfSBmcm9tIFwiLi9hdHRyaWJ1dGVzLWVtaXR0ZXJcIjtcbmltcG9ydCB7IGRvd25jYXNlRmlyc3QgfSBmcm9tIFwiLi4vLi4vLi4vdXRpbFwiO1xuaW1wb3J0ICogYXMgcGF0aCBmcm9tIFwicGF0aFwiO1xuaW1wb3J0IHsgU1RSVUNUX1NIQVJESU5HX1RIUkVTSE9MRCB9IGZyb20gXCIuLi9tb2RlbHMvcmVzb3VyY2UtbW9kZWxcIjtcbmltcG9ydCB7IEF0dHJpYnV0ZU1vZGVsIH0gZnJvbSBcIi4uL21vZGVscy9hdHRyaWJ1dGUtbW9kZWxcIjtcbmltcG9ydCB7IHNhbml0aXplZENvbW1lbnQgfSBmcm9tIFwiLi4vc2FuaXRpemVkLWNvbW1lbnRzXCI7XG5leHBvcnQgY2xhc3MgU3RydWN0RW1pdHRlciB7XG4gIGF0dHJpYnV0ZXNFbWl0dGVyOiBBdHRyaWJ1dGVzRW1pdHRlcjtcblxuICBjb25zdHJ1Y3Rvcihwcml2YXRlIHJlYWRvbmx5IGNvZGU6IENvZGVNYWtlcikge1xuICAgIHRoaXMuYXR0cmlidXRlc0VtaXR0ZXIgPSBuZXcgQXR0cmlidXRlc0VtaXR0ZXIodGhpcy5jb2RlKTtcbiAgfVxuXG4gIHB1YmxpYyBlbWl0KHJlc291cmNlOiBSZXNvdXJjZU1vZGVsKSB7XG4gICAgaWYgKHJlc291cmNlLnN0cnVjdHNSZXF1aXJlU2hhcmRpbmcpIHtcbiAgICAgIHRoaXMuZW1pdE5hbWVzcGFjZWRTdHJ1Y3RzKHJlc291cmNlKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5lbWl0U3RydWN0cyhyZXNvdXJjZSk7XG4gICAgfVxuICB9XG5cbiAgLy8gRHVlIHRvIGh0dHBzOi8vZ2l0aHViLmNvbS9oYXNoaWNvcnAvdGVycmFmb3JtLXBsdWdpbi1zZGsvY29tbWl0LzIzODdlYjg1ZTMyYzA2NGI0YTYyNzE4YzlmNWM4MGJmMDBkYzdmYjkgYWxsXG4gIC8vIHJlc291cmNlcyBmcm9tIHByb3ZpZGVycyB1c2luZyB0aGUgb2xkIFNESyBoYXZlIHRoZSBpZCBmaWVsZCBieSBkZWZhdWx0XG4gIC8vIFdlIGhhdmUgbm8gd2F5IHRvIGRpc3Rpbmd1aXNoIHRoZW0gdGhyb3VnaCB0aGUgcHJvdmlkZXIgc2NoZW1hLCBzbyBhIHdvcmQgb2Ygd2FybmluZyBmb3Igb3VyIHVzZXJzXG4gIHByaXZhdGUgd2FybkFib3V0SWRGaWVsZChhdHQ6IEF0dHJpYnV0ZU1vZGVsKSB7XG4gICAgaWYgKGF0dC5uYW1lID09PSBcImlkXCIpIHtcbiAgICAgIHRoaXMuY29kZS5saW5lKGAqYCk7XG4gICAgICB0aGlzLmNvZGUubGluZShcbiAgICAgICAgYCogUGxlYXNlIGJlIGF3YXJlIHRoYXQgdGhlIGlkIGZpZWxkIGlzIGF1dG9tYXRpY2FsbHkgYWRkZWQgdG8gYWxsIHJlc291cmNlcyBpbiBUZXJyYWZvcm0gcHJvdmlkZXJzIHVzaW5nIGEgVGVycmFmb3JtIHByb3ZpZGVyIFNESyB2ZXJzaW9uIGJlbG93IDIuYCxcbiAgICAgICk7XG4gICAgICB0aGlzLmNvZGUubGluZShcbiAgICAgICAgYCogSWYgeW91IGV4cGVyaWVuY2UgcHJvYmxlbXMgc2V0dGluZyB0aGlzIHZhbHVlIGl0IG1pZ2h0IG5vdCBiZSBzZXR0YWJsZS4gUGxlYXNlIHRha2UgYSBsb29rIGF0IHRoZSBwcm92aWRlciBkb2N1bWVudGF0aW9uIHRvIGVuc3VyZSBpdCBzaG91bGQgYmUgc2V0dGFibGUuYCxcbiAgICAgICk7XG4gICAgfVxuICB9XG5cbiAgcHVibGljIGVtaXRJbnRlcmZhY2UoXG4gICAgcmVzb3VyY2U6IFJlc291cmNlTW9kZWwsXG4gICAgc3RydWN0OiBTdHJ1Y3QsXG4gICAgbmFtZSA9IHN0cnVjdC5uYW1lLFxuICApIHtcbiAgICBpZiAocmVzb3VyY2UuaXNQcm92aWRlcikge1xuICAgICAgdGhpcy5jb2RlLm9wZW5CbG9jayhgZXhwb3J0IGludGVyZmFjZSAke25hbWV9YCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuY29kZS5vcGVuQmxvY2soYGV4cG9ydCBpbnRlcmZhY2UgJHtuYW1lfSR7c3RydWN0LmV4dGVuZHN9YCk7XG4gICAgfVxuXG4gICAgZm9yIChjb25zdCBhdHQgb2Ygc3RydWN0LmFzc2lnbmFibGVBdHRyaWJ1dGVzKSB7XG4gICAgICBjb25zdCBjb21tZW50ID0gc2FuaXRpemVkQ29tbWVudCh0aGlzLmNvZGUpO1xuICAgICAgaWYgKGF0dC5kZXNjcmlwdGlvbikge1xuICAgICAgICBjb21tZW50LmxpbmUoYXR0LmRlc2NyaXB0aW9uKTtcbiAgICAgICAgY29tbWVudC5saW5lKGBgKTtcbiAgICAgICAgY29tbWVudC5saW5lKFxuICAgICAgICAgIGBEb2NzIGF0IFRlcnJhZm9ybSBSZWdpc3RyeToge0BsaW5rICR7cmVzb3VyY2UubGlua1RvRG9jc30jJHthdHQudGVycmFmb3JtTmFtZX0gJHtyZXNvdXJjZS5jbGFzc05hbWV9IyR7YXR0LnRlcnJhZm9ybU5hbWV9fWAsXG4gICAgICAgICk7XG4gICAgICAgIHRoaXMud2FybkFib3V0SWRGaWVsZChhdHQpO1xuICAgICAgICBjb21tZW50LmVuZCgpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29tbWVudC5saW5lKFxuICAgICAgICAgIGBEb2NzIGF0IFRlcnJhZm9ybSBSZWdpc3RyeToge0BsaW5rICR7cmVzb3VyY2UubGlua1RvRG9jc30jJHthdHQudGVycmFmb3JtTmFtZX0gJHtyZXNvdXJjZS5jbGFzc05hbWV9IyR7YXR0LnRlcnJhZm9ybU5hbWV9fWAsXG4gICAgICAgICk7XG4gICAgICAgIHRoaXMud2FybkFib3V0SWRGaWVsZChhdHQpO1xuICAgICAgICBjb21tZW50LmVuZCgpO1xuICAgICAgfVxuXG4gICAgICB0aGlzLmNvZGUubGluZShgcmVhZG9ubHkgJHthdHQudHlwZURlZmluaXRpb259O2ApO1xuICAgIH1cbiAgICB0aGlzLmNvZGUuY2xvc2VCbG9jaygpO1xuXG4gICAgaWYgKCEoc3RydWN0IGluc3RhbmNlb2YgQ29uZmlnU3RydWN0KSkge1xuICAgICAgdGhpcy5lbWl0VG9UZXJyYWZvcm1GdW5jdGlvbihzdHJ1Y3QpO1xuICAgICAgdGhpcy5lbWl0VG9IY2xUZXJyYWZvcm1GdW5jdGlvbihzdHJ1Y3QpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgZW1pdFN0cnVjdHMocmVzb3VyY2U6IFJlc291cmNlTW9kZWwpIHtcbiAgICByZXNvdXJjZS5zdHJ1Y3RzLmZvckVhY2goKHN0cnVjdCkgPT4ge1xuICAgICAgaWYgKHN0cnVjdCBpbnN0YW5jZW9mIENvbmZpZ1N0cnVjdCkge1xuICAgICAgICB0aGlzLmVtaXRJbnRlcmZhY2UocmVzb3VyY2UsIHN0cnVjdCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBXZSB1c2UgdGhlIGludGVyZmFjZSBoZXJlIGZvciB0aGUgY29uZmlndXJhdGlvbiAvIGlucHV0cyBvZiBhIHJlc291cmNlIC8gbmVzdGVkIGJsb2NrXG4gICAgICAgIHRoaXMuZW1pdEludGVyZmFjZShyZXNvdXJjZSwgc3RydWN0KTtcbiAgICAgICAgLy8gQW5kIHdlIHVzZSB0aGUgY2xhc3MgZm9yIHRoZSBhdHRyaWJ1dGVzIC8gb3V0cHV0cyBvZiBhIHJlc291cmNlIC8gbmVzdGVkIGJsb2NrXG4gICAgICAgIGlmICghc3RydWN0LmlzUHJvdmlkZXIpIHtcbiAgICAgICAgICB0aGlzLmVtaXRDbGFzcyhzdHJ1Y3QpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIGVtaXROYW1lc3BhY2VkU3RydWN0cyhyZXNvdXJjZTogUmVzb3VyY2VNb2RlbCkge1xuICAgIC8vIGl0ZXJhdGUgb3ZlciBhbGwgc3RydWN0cyBpbiBiYXRjaGVzIG9mIDQwMCB0byBhdm9pZCB0b28gbWFueSBleHBvcnRzICg+IDEyMDApXG4gICAgY29uc3Qgc3RydWN0SW1wb3J0czogUmVjb3JkPHN0cmluZywgc3RyaW5nPiA9IHt9O1xuXG4gICAgLy8gZHJvcCBjb25maWdTdHJ1Y3QgZnJvbSByZXNvdXJjZS5zdHJ1Y3RzIHRvIGF2b2lkIGRvdWJsZSBpbXBvcnRcbiAgICBjb25zdCBzdHJ1Y3RzV2l0aG91dENvbmZpZ1N0cnVjdCA9IHJlc291cmNlLnN0cnVjdHMuc2xpY2UoMSk7XG5cbiAgICBjb25zdCBzdHJ1Y3RTcGxpdHM6IFN0cnVjdFtdW10gPSBbW11dO1xuICAgIGNvbnN0IHNwbGl0Q291bnRzOiBudW1iZXJbXSA9IFswXTtcbiAgICBzdHJ1Y3RzV2l0aG91dENvbmZpZ1N0cnVjdC5mb3JFYWNoKChzdHJ1Y3QpID0+IHtcbiAgICAgIGlmIChcbiAgICAgICAgc3BsaXRDb3VudHNbc3BsaXRDb3VudHMubGVuZ3RoIC0gMV0gKyBzdHJ1Y3QuZXhwb3J0Q291bnQgPD1cbiAgICAgICAgU1RSVUNUX1NIQVJESU5HX1RIUkVTSE9MRFxuICAgICAgKSB7XG4gICAgICAgIHN0cnVjdFNwbGl0c1tzdHJ1Y3RTcGxpdHMubGVuZ3RoIC0gMV0ucHVzaChzdHJ1Y3QpO1xuICAgICAgICBzcGxpdENvdW50c1tzcGxpdENvdW50cy5sZW5ndGggLSAxXSArPSBzdHJ1Y3QuZXhwb3J0Q291bnQ7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBzdHJ1Y3RTcGxpdHMucHVzaChbc3RydWN0XSk7XG4gICAgICAgIHNwbGl0Q291bnRzLnB1c2goc3RydWN0LmV4cG9ydENvdW50KTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIC8vIGZpbGwgdGhlIHN0cnVjdCBpbXBvcnRzIG1hcHBpbmcgYmVmb3JlIGNvZGUgZ2VuZXJhdGlvbiBzbyB0aGF0IGltcG9ydHMgY2FuXG4gICAgLy8gcG9pbnQgdG8gbm90IHlldCBnZW5lcmF0ZWQgc3RydWN0IGZpbGVzXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBzdHJ1Y3RTcGxpdHMubGVuZ3RoOyBpKyspIHtcbiAgICAgIGNvbnN0IHN0cnVjdEZpbGVuYW1lID0gYHN0cnVjdHMke2kgKiBTVFJVQ1RfU0hBUkRJTkdfVEhSRVNIT0xEfS50c2A7XG4gICAgICBjb25zdCBzdHJ1Y3RzID0gc3RydWN0U3BsaXRzW2ldO1xuXG4gICAgICAvLyBhc3NvY2lhdGUgY3VycmVudCBzdHJ1Y3RzIGJhdGNoIHdpdGggdGhlIGZpbGUgaXQgd2lsbCBiZSB3cml0dGVuIHRvXG4gICAgICAvLyB0byBmaW5kIGl0IGluIHN1YnNlcXVlbnQgZmlsZXMgZm9yIGltcG9ydGluZ1xuICAgICAgc3RydWN0cy5mb3JFYWNoKFxuICAgICAgICAoc3RydWN0KSA9PiAoc3RydWN0SW1wb3J0c1tzdHJ1Y3QubmFtZV0gPSBzdHJ1Y3RGaWxlbmFtZSksXG4gICAgICApO1xuICAgIH1cblxuICAgIGNvbnN0IHN0cnVjdFBhdGhzID0gW107XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBzdHJ1Y3RTcGxpdHMubGVuZ3RoOyBpKyspIHtcbiAgICAgIGNvbnN0IHN0cnVjdHNUb0ltcG9ydDogUmVjb3JkPHN0cmluZywgc3RyaW5nW10+ID0ge307XG4gICAgICBjb25zdCBzdHJ1Y3RzID0gc3RydWN0U3BsaXRzW2ldO1xuICAgICAgY29uc3Qgc3RydWN0RmlsZW5hbWUgPSBgc3RydWN0cyR7aSAqIFNUUlVDVF9TSEFSRElOR19USFJFU0hPTER9LnRzYDtcbiAgICAgIHN0cnVjdFBhdGhzLnB1c2goc3RydWN0RmlsZW5hbWUpO1xuXG4gICAgICAvLyBmaW5kIGFsbCBzdHJ1Y3RzIHRoYXQgbmVlZCB0byBiZSBpbXBvcnRlZCBpbiB0aGlzIGZpbGVcbiAgICAgIHN0cnVjdHMuZm9yRWFjaCgoc3RydWN0KSA9PiB7XG4gICAgICAgIHN0cnVjdC5hdHRyaWJ1dGVzLmZvckVhY2goKGF0dCkgPT4ge1xuICAgICAgICAgIGNvbnN0IHN0cnVjdFR5cGVOYW1lID0gYXR0LnR5cGUuc3RydWN0Py5uYW1lO1xuICAgICAgICAgIGNvbnN0IGZpbGVUb0ltcG9ydCA9IHN0cnVjdEltcG9ydHNbc3RydWN0VHlwZU5hbWUgPz8gXCJcIl07XG5cbiAgICAgICAgICBpZiAoZmlsZVRvSW1wb3J0ICYmIGZpbGVUb0ltcG9ydCAhPT0gc3RydWN0RmlsZW5hbWUpIHtcbiAgICAgICAgICAgIGNvbnN0IGF0dFR5cGVTdHJ1Y3QgPSBhdHQudHlwZS5zdHJ1Y3Q7XG4gICAgICAgICAgICBpZiAoIWF0dFR5cGVTdHJ1Y3QpXG4gICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgJHtzdHJ1Y3RUeXBlTmFtZX0gaXMgbm90IGEgc3RydWN0YCk7XG5cbiAgICAgICAgICAgIHN0cnVjdHNUb0ltcG9ydFtmaWxlVG9JbXBvcnRdID8/XG4gICAgICAgICAgICAgIChzdHJ1Y3RzVG9JbXBvcnRbZmlsZVRvSW1wb3J0XSA9IFtdKTtcblxuICAgICAgICAgICAgY29uc3QgYXR0UmVmZXJlbmNlcyA9IGF0dC5nZXRSZWZlcmVuY2VkVHlwZXMoXG4gICAgICAgICAgICAgIHN0cnVjdCBpbnN0YW5jZW9mIENvbmZpZ1N0cnVjdCxcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICBpZiAoYXR0UmVmZXJlbmNlcykge1xuICAgICAgICAgICAgICBzdHJ1Y3RzVG9JbXBvcnRbZmlsZVRvSW1wb3J0XS5wdXNoKC4uLmF0dFJlZmVyZW5jZXMpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICB9KTtcblxuICAgICAgY29uc3QgbmFtZXNwYWNlZEZpbGVQYXRoID0gcGF0aC5qb2luKFxuICAgICAgICByZXNvdXJjZS5zdHJ1Y3RzRm9sZGVyUGF0aCxcbiAgICAgICAgc3RydWN0RmlsZW5hbWUsXG4gICAgICApO1xuXG4gICAgICB0aGlzLmNvZGUub3BlbkZpbGUobmFtZXNwYWNlZEZpbGVQYXRoKTtcbiAgICAgIC8vIHRoZSBzdHJ1Y3RzIG9ubHkgbWFrZXMgdXNlIG9mIGNka3RuIG5vdCBjb25zdHJ1Y3RzXG4gICAgICB0aGlzLmNvZGUubGluZShgaW1wb3J0ICogYXMgY2RrdG4gZnJvbSAnY2RrdG4nO2ApO1xuICAgICAgT2JqZWN0LmVudHJpZXMoc3RydWN0c1RvSW1wb3J0KS5mb3JFYWNoKChbZmlsZVRvSW1wb3J0LCBzdHJ1Y3RzXSkgPT4ge1xuICAgICAgICB0aGlzLmNvZGUubGluZShcbiAgICAgICAgICBgaW1wb3J0IHsgJHtbLi4ubmV3IFNldChzdHJ1Y3RzKV0uam9pbihcbiAgICAgICAgICAgIFwiLFxcblwiLFxuICAgICAgICAgICl9IH0gZnJvbSAnLi8ke3BhdGguYmFzZW5hbWUoZmlsZVRvSW1wb3J0LCBcIi50c1wiKX0nYCxcbiAgICAgICAgKTtcbiAgICAgIH0pO1xuXG4gICAgICBzdHJ1Y3RzLmZvckVhY2goKHN0cnVjdCkgPT4ge1xuICAgICAgICBpZiAoc3RydWN0IGluc3RhbmNlb2YgQ29uZmlnU3RydWN0KSB7XG4gICAgICAgICAgdGhpcy5lbWl0SW50ZXJmYWNlKHJlc291cmNlLCBzdHJ1Y3QpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIC8vIFdlIHVzZSB0aGUgaW50ZXJmYWNlIGhlcmUgZm9yIHRoZSBjb25maWd1cmF0aW9uIC8gaW5wdXRzIG9mIGEgcmVzb3VyY2UgLyBuZXN0ZWQgYmxvY2tcbiAgICAgICAgICB0aGlzLmVtaXRJbnRlcmZhY2UocmVzb3VyY2UsIHN0cnVjdCk7XG4gICAgICAgICAgLy8gQW5kIHdlIHVzZSB0aGUgY2xhc3MgZm9yIHRoZSBhdHRyaWJ1dGVzIC8gb3V0cHV0cyBvZiBhIHJlc291cmNlIC8gbmVzdGVkIGJsb2NrXG4gICAgICAgICAgaWYgKCFzdHJ1Y3QuaXNQcm92aWRlcikge1xuICAgICAgICAgICAgdGhpcy5lbWl0Q2xhc3Moc3RydWN0KTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgICAgdGhpcy5jb2RlLmNsb3NlRmlsZShuYW1lc3BhY2VkRmlsZVBhdGgpO1xuICAgIH1cblxuICAgIC8vIGVtaXQgdGhlIGluZGV4IGZpbGUgdGhhdCBleHBvcnRzIGFsbCB0aGUgc3RydWN0IGZpbGVzIHdlJ3ZlIGp1c3QgZ2VuZXJhdGVkXG4gICAgY29uc3QgaW5kZXhGaWxlUGF0aCA9IHBhdGguam9pbihyZXNvdXJjZS5zdHJ1Y3RzRm9sZGVyUGF0aCwgXCJpbmRleC50c1wiKTtcblxuICAgIHRoaXMuY29kZS5vcGVuRmlsZShpbmRleEZpbGVQYXRoKTtcbiAgICBzdHJ1Y3RQYXRocy5mb3JFYWNoKChzdHJ1Y3RQYXRoKSA9PiB7XG4gICAgICB0aGlzLmNvZGUubGluZShgZXhwb3J0ICogZnJvbSAnLi8ke3BhdGguYmFzZW5hbWUoc3RydWN0UGF0aCwgXCIudHNcIil9J2ApO1xuICAgIH0pO1xuICAgIHRoaXMuY29kZS5jbG9zZUZpbGUoaW5kZXhGaWxlUGF0aCk7XG4gIH1cblxuICBwcml2YXRlIGVtaXRDbGFzcyhzdHJ1Y3Q6IFN0cnVjdCkge1xuICAgIHRoaXMuY29kZS5vcGVuQmxvY2soXG4gICAgICBgZXhwb3J0IGNsYXNzICR7c3RydWN0Lm91dHB1dFJlZmVyZW5jZU5hbWV9IGV4dGVuZHMgY2RrdG4uQ29tcGxleE9iamVjdGAsXG4gICAgKTtcblxuICAgIHRoaXMuY29kZS5saW5lKFwicHJpdmF0ZSBpc0VtcHR5T2JqZWN0ID0gZmFsc2U7XCIpO1xuICAgIGlmICghc3RydWN0LmlzQ2xhc3MpIHtcbiAgICAgIHRoaXMuY29kZS5saW5lKFwicHJpdmF0ZSByZXNvbHZhYmxlVmFsdWU/OiBjZGt0bi5JUmVzb2x2YWJsZTtcIik7XG4gICAgfVxuICAgIHRoaXMuY29kZS5saW5lKCk7XG5cbiAgICBjb25zdCBjb21tZW50ID0gc2FuaXRpemVkQ29tbWVudCh0aGlzLmNvZGUpO1xuICAgIGNvbW1lbnQubGluZShgQHBhcmFtIHRlcnJhZm9ybVJlc291cmNlIFRoZSBwYXJlbnQgcmVzb3VyY2VgKTtcbiAgICBjb21tZW50LmxpbmUoXG4gICAgICBgQHBhcmFtIHRlcnJhZm9ybUF0dHJpYnV0ZSBUaGUgYXR0cmlidXRlIG9uIHRoZSBwYXJlbnQgcmVzb3VyY2UgdGhpcyBjbGFzcyBpcyByZWZlcmVuY2luZ2AsXG4gICAgKTtcbiAgICBpZiAoc3RydWN0LmlzU2luZ2xlSXRlbSkge1xuICAgICAgY29tbWVudC5lbmQoKTtcbiAgICAgIHRoaXMuY29kZS5vcGVuQmxvY2soXG4gICAgICAgIGBwdWJsaWMgY29uc3RydWN0b3IodGVycmFmb3JtUmVzb3VyY2U6IGNka3RuLklJbnRlcnBvbGF0aW5nUGFyZW50LCB0ZXJyYWZvcm1BdHRyaWJ1dGU6IHN0cmluZylgLFxuICAgICAgKTtcbiAgICAgIHRoaXMuY29kZS5saW5lKGBzdXBlcih0ZXJyYWZvcm1SZXNvdXJjZSwgdGVycmFmb3JtQXR0cmlidXRlLCBmYWxzZSwgMCk7YCk7XG4gICAgICB0aGlzLmNvZGUuY2xvc2VCbG9jaygpO1xuICAgIH0gZWxzZSBpZiAoXG4gICAgICBzdHJ1Y3QubmVzdGluZ01vZGUgPT09IFwic2luZ2xlXCIgfHxcbiAgICAgIHN0cnVjdC5uZXN0aW5nTW9kZSA9PT0gXCJvYmplY3RcIlxuICAgICkge1xuICAgICAgY29tbWVudC5lbmQoKTtcbiAgICAgIHRoaXMuY29kZS5vcGVuQmxvY2soXG4gICAgICAgIGBwdWJsaWMgY29uc3RydWN0b3IodGVycmFmb3JtUmVzb3VyY2U6IGNka3RuLklJbnRlcnBvbGF0aW5nUGFyZW50LCB0ZXJyYWZvcm1BdHRyaWJ1dGU6IHN0cmluZylgLFxuICAgICAgKTtcbiAgICAgIHRoaXMuY29kZS5saW5lKGBzdXBlcih0ZXJyYWZvcm1SZXNvdXJjZSwgdGVycmFmb3JtQXR0cmlidXRlLCBmYWxzZSk7YCk7XG4gICAgICB0aGlzLmNvZGUuY2xvc2VCbG9jaygpO1xuICAgIH0gZWxzZSBpZiAoc3RydWN0Lm5lc3RpbmdNb2RlLnN0YXJ0c1dpdGgoXCJtYXBcIikpIHtcbiAgICAgIHRoaXMuY29kZS5saW5lKFxuICAgICAgICBgKiBAcGFyYW0gY29tcGxleE9iamVjdEtleSB0aGUga2V5IG9mIHRoaXMgaXRlbSBpbiB0aGUgbWFwYCxcbiAgICAgICk7XG4gICAgICBjb21tZW50LmVuZCgpO1xuICAgICAgdGhpcy5jb2RlLm9wZW5CbG9jayhcbiAgICAgICAgYHB1YmxpYyBjb25zdHJ1Y3Rvcih0ZXJyYWZvcm1SZXNvdXJjZTogY2RrdG4uSUludGVycG9sYXRpbmdQYXJlbnQsIHRlcnJhZm9ybUF0dHJpYnV0ZTogc3RyaW5nLCBjb21wbGV4T2JqZWN0S2V5OiBzdHJpbmcpYCxcbiAgICAgICk7XG4gICAgICB0aGlzLmNvZGUubGluZShcbiAgICAgICAgYHN1cGVyKHRlcnJhZm9ybVJlc291cmNlLCB0ZXJyYWZvcm1BdHRyaWJ1dGUsIGZhbHNlLCBjb21wbGV4T2JqZWN0S2V5KTtgLFxuICAgICAgKTtcbiAgICAgIHRoaXMuY29kZS5jbG9zZUJsb2NrKCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbW1lbnQubGluZShcbiAgICAgICAgYEBwYXJhbSBjb21wbGV4T2JqZWN0SW5kZXggdGhlIGluZGV4IG9mIHRoaXMgaXRlbSBpbiB0aGUgbGlzdGAsXG4gICAgICApO1xuICAgICAgY29tbWVudC5saW5lKFxuICAgICAgICBgQHBhcmFtIGNvbXBsZXhPYmplY3RJc0Zyb21TZXQgd2hldGhlciB0aGUgbGlzdCBpcyB3cmFwcGluZyBhIHNldCAod2lsbCBhZGQgdG9saXN0KCkgdG8gYmUgYWJsZSB0byBhY2Nlc3MgYW4gaXRlbSB2aWEgYW4gaW5kZXgpYCxcbiAgICAgICk7XG4gICAgICBjb21tZW50LmVuZCgpO1xuICAgICAgdGhpcy5jb2RlLm9wZW5CbG9jayhcbiAgICAgICAgYHB1YmxpYyBjb25zdHJ1Y3Rvcih0ZXJyYWZvcm1SZXNvdXJjZTogY2RrdG4uSUludGVycG9sYXRpbmdQYXJlbnQsIHRlcnJhZm9ybUF0dHJpYnV0ZTogc3RyaW5nLCBjb21wbGV4T2JqZWN0SW5kZXg6IG51bWJlciwgY29tcGxleE9iamVjdElzRnJvbVNldDogYm9vbGVhbilgLFxuICAgICAgKTtcbiAgICAgIHRoaXMuY29kZS5saW5lKFxuICAgICAgICBgc3VwZXIodGVycmFmb3JtUmVzb3VyY2UsIHRlcnJhZm9ybUF0dHJpYnV0ZSwgY29tcGxleE9iamVjdElzRnJvbVNldCwgY29tcGxleE9iamVjdEluZGV4KTtgLFxuICAgICAgKTtcbiAgICAgIHRoaXMuY29kZS5jbG9zZUJsb2NrKCk7XG4gICAgfVxuXG4gICAgdGhpcy5jb2RlLmxpbmUoKTtcbiAgICB0aGlzLmVtaXRJbnRlcm5hbFZhbHVlR2V0dGVyKHN0cnVjdCk7XG4gICAgdGhpcy5jb2RlLmxpbmUoKTtcbiAgICB0aGlzLmVtaXRJbnRlcm5hbFZhbHVlU2V0dGVyKHN0cnVjdCk7XG5cbiAgICBmb3IgKGNvbnN0IGF0dCBvZiBzdHJ1Y3QuYXR0cmlidXRlcykge1xuICAgICAgdGhpcy5hdHRyaWJ1dGVzRW1pdHRlci5lbWl0KFxuICAgICAgICBhdHQsXG4gICAgICAgIHRoaXMuYXR0cmlidXRlc0VtaXR0ZXIubmVlZHNSZXNldEVzY2FwZShhdHQsIHN0cnVjdC5hdHRyaWJ1dGVzKSxcbiAgICAgICAgdGhpcy5hdHRyaWJ1dGVzRW1pdHRlci5uZWVkc0lucHV0RXNjYXBlKGF0dCwgc3RydWN0LmF0dHJpYnV0ZXMpLFxuICAgICAgKTtcbiAgICB9XG5cbiAgICB0aGlzLmNvZGUuY2xvc2VCbG9jaygpO1xuXG4gICAgaWYgKFxuICAgICAgIXN0cnVjdC5pc1NpbmdsZUl0ZW0gJiZcbiAgICAgIChzdHJ1Y3QubmVzdGluZ01vZGUgPT09IFwibGlzdFwiIHx8IHN0cnVjdC5uZXN0aW5nTW9kZSA9PT0gXCJzZXRcIilcbiAgICApIHtcbiAgICAgIHRoaXMuZW1pdENvbXBsZXhMaXN0Q2xhc3Moc3RydWN0KTtcbiAgICB9IGVsc2UgaWYgKHN0cnVjdC5uZXN0aW5nTW9kZSA9PT0gXCJtYXBcIikge1xuICAgICAgdGhpcy5lbWl0Q29tcGxleE1hcENsYXNzKHN0cnVjdCk7XG4gICAgfSBlbHNlIGlmIChzdHJ1Y3QubmVzdGluZ01vZGUgPT09IFwibWFwbGlzdFwiKSB7XG4gICAgICB0aGlzLmVtaXRDb21wbGV4TWFwTGlzdENsYXNzZXMoc3RydWN0KTtcbiAgICB9IGVsc2UgaWYgKHN0cnVjdC5uZXN0aW5nTW9kZSA9PT0gXCJtYXBzZXRcIikge1xuICAgICAgdGhpcy5lbWl0Q29tcGxleE1hcExpc3RDbGFzc2VzKHN0cnVjdCk7XG4gICAgfSBlbHNlIGlmIChzdHJ1Y3QubmVzdGluZ01vZGUgPT09IFwibGlzdG1hcFwiKSB7XG4gICAgICB0aGlzLmVtaXRDb21wbGV4TGlzdE1hcENsYXNzZXMoc3RydWN0LCBmYWxzZSk7XG4gICAgfSBlbHNlIGlmIChzdHJ1Y3QubmVzdGluZ01vZGUgPT09IFwic2V0bWFwXCIpIHtcbiAgICAgIHRoaXMuZW1pdENvbXBsZXhMaXN0TWFwQ2xhc3NlcyhzdHJ1Y3QsIHRydWUpO1xuICAgIH0gZWxzZSBpZiAoXG4gICAgICBzdHJ1Y3QubmVzdGluZ01vZGUgPT09IFwibGlzdGxpc3RcIiB8fFxuICAgICAgc3RydWN0Lm5lc3RpbmdNb2RlID09PSBcImxpc3RzZXRcIiB8fFxuICAgICAgc3RydWN0Lm5lc3RpbmdNb2RlID09PSBcInNldGxpc3RcIiB8fFxuICAgICAgc3RydWN0Lm5lc3RpbmdNb2RlID09PSBcInNldHNldFwiXG4gICAgKSB7XG4gICAgICB0aGlzLmVtaXRDb21wbGV4TGlzdExpc3RDbGFzc2VzKHN0cnVjdCk7XG4gICAgfVxuICAgIC8vIG90aGVyIHR5cGVzIG9mIG5lc3RlZCBjb2xsZWN0aW9ucyBhcmVuJ3Qgc3VwcG9ydGVkXG4gIH1cblxuICBwcml2YXRlIGVtaXRDb21wbGV4TGlzdENsYXNzKHN0cnVjdDogU3RydWN0KSB7XG4gICAgdGhpcy5jb2RlLmxpbmUoKTtcbiAgICB0aGlzLmNvZGUub3BlbkJsb2NrKFxuICAgICAgYGV4cG9ydCBjbGFzcyAke3N0cnVjdC5saXN0TmFtZX0gZXh0ZW5kcyBjZGt0bi5Db21wbGV4TGlzdGAsXG4gICAgKTtcblxuICAgIGlmIChzdHJ1Y3QuYXNzaWduYWJsZSkge1xuICAgICAgdGhpcy5jb2RlLmxpbmUoXG4gICAgICAgIGBwdWJsaWMgaW50ZXJuYWxWYWx1ZT8gOiAke3N0cnVjdC5uYW1lfVtdIHwgY2RrdG4uSVJlc29sdmFibGVgLFxuICAgICAgKTtcbiAgICB9XG5cbiAgICB0aGlzLmNvZGUubGluZSgpO1xuICAgIGNvbnN0IGNvbnN0cnVjdG9yQ29tbWVudCA9IHNhbml0aXplZENvbW1lbnQodGhpcy5jb2RlKTtcbiAgICBjb25zdHJ1Y3RvckNvbW1lbnQubGluZShgQHBhcmFtIHRlcnJhZm9ybVJlc291cmNlIFRoZSBwYXJlbnQgcmVzb3VyY2VgKTtcbiAgICBjb25zdHJ1Y3RvckNvbW1lbnQubGluZShcbiAgICAgIGBAcGFyYW0gdGVycmFmb3JtQXR0cmlidXRlIFRoZSBhdHRyaWJ1dGUgb24gdGhlIHBhcmVudCByZXNvdXJjZSB0aGlzIGNsYXNzIGlzIHJlZmVyZW5jaW5nYCxcbiAgICApO1xuICAgIGNvbnN0cnVjdG9yQ29tbWVudC5saW5lKFxuICAgICAgYEBwYXJhbSB3cmFwc1NldCB3aGV0aGVyIHRoZSBsaXN0IGlzIHdyYXBwaW5nIGEgc2V0ICh3aWxsIGFkZCB0b2xpc3QoKSB0byBiZSBhYmxlIHRvIGFjY2VzcyBhbiBpdGVtIHZpYSBhbiBpbmRleClgLFxuICAgICk7XG4gICAgY29uc3RydWN0b3JDb21tZW50LmVuZCgpO1xuICAgIHRoaXMuY29kZS5vcGVuQmxvY2soXG4gICAgICBgY29uc3RydWN0b3IodGVycmFmb3JtUmVzb3VyY2U6IGNka3RuLklJbnRlcnBvbGF0aW5nUGFyZW50LCB0ZXJyYWZvcm1BdHRyaWJ1dGU6IHN0cmluZywgd3JhcHNTZXQ6IGJvb2xlYW4pYCxcbiAgICApO1xuICAgIHRoaXMuY29kZS5saW5lKGBzdXBlcih0ZXJyYWZvcm1SZXNvdXJjZSwgdGVycmFmb3JtQXR0cmlidXRlLCB3cmFwc1NldClgKTtcbiAgICB0aGlzLmNvZGUuY2xvc2VCbG9jaygpO1xuXG4gICAgdGhpcy5jb2RlLmxpbmUoKTtcbiAgICBjb25zdCBnZXR0ZXJDb21tZW50ID0gc2FuaXRpemVkQ29tbWVudCh0aGlzLmNvZGUpO1xuICAgIGdldHRlckNvbW1lbnQubGluZShgQHBhcmFtIGluZGV4IHRoZSBpbmRleCBvZiB0aGUgaXRlbSB0byByZXR1cm5gKTtcbiAgICBnZXR0ZXJDb21tZW50LmVuZCgpO1xuICAgIHRoaXMuY29kZS5vcGVuQmxvY2soXG4gICAgICBgcHVibGljIGdldChpbmRleDogbnVtYmVyKTogJHtzdHJ1Y3Qub3V0cHV0UmVmZXJlbmNlTmFtZX1gLFxuICAgICk7XG4gICAgdGhpcy5jb2RlLmxpbmUoXG4gICAgICBgcmV0dXJuIG5ldyAke3N0cnVjdC5vdXRwdXRSZWZlcmVuY2VOYW1lfSh0aGlzLnRlcnJhZm9ybVJlc291cmNlLCB0aGlzLnRlcnJhZm9ybUF0dHJpYnV0ZSwgaW5kZXgsIHRoaXMud3JhcHNTZXQpO2AsXG4gICAgKTtcbiAgICB0aGlzLmNvZGUuY2xvc2VCbG9jaygpO1xuXG4gICAgdGhpcy5jb2RlLmNsb3NlQmxvY2soKTtcbiAgfVxuXG4gIHByaXZhdGUgZW1pdENvbXBsZXhNYXBDbGFzcyhzdHJ1Y3Q6IFN0cnVjdCkge1xuICAgIHRoaXMuY29kZS5saW5lKCk7XG4gICAgdGhpcy5jb2RlLm9wZW5CbG9jayhcbiAgICAgIGBleHBvcnQgY2xhc3MgJHtzdHJ1Y3QubWFwTmFtZX0gZXh0ZW5kcyBjZGt0bi5Db21wbGV4TWFwYCxcbiAgICApO1xuXG4gICAgaWYgKHN0cnVjdC5hc3NpZ25hYmxlKSB7XG4gICAgICB0aGlzLmNvZGUubGluZShcbiAgICAgICAgYHB1YmxpYyBpbnRlcm5hbFZhbHVlPyA6IHsgW2tleTogc3RyaW5nXTogJHtzdHJ1Y3QubmFtZX0gfSB8IGNka3RuLklSZXNvbHZhYmxlYCxcbiAgICAgICk7XG4gICAgfVxuXG4gICAgdGhpcy5jb2RlLmxpbmUoKTtcbiAgICBjb25zdCBjb25zdHJ1Y3RvckNvbW1lbnQgPSBzYW5pdGl6ZWRDb21tZW50KHRoaXMuY29kZSk7XG4gICAgY29uc3RydWN0b3JDb21tZW50LmxpbmUoYEBwYXJhbSB0ZXJyYWZvcm1SZXNvdXJjZSBUaGUgcGFyZW50IHJlc291cmNlYCk7XG4gICAgY29uc3RydWN0b3JDb21tZW50LmxpbmUoXG4gICAgICBgQHBhcmFtIHRlcnJhZm9ybUF0dHJpYnV0ZSBUaGUgYXR0cmlidXRlIG9uIHRoZSBwYXJlbnQgcmVzb3VyY2UgdGhpcyBjbGFzcyBpcyByZWZlcmVuY2luZ2AsXG4gICAgKTtcbiAgICBjb25zdHJ1Y3RvckNvbW1lbnQuZW5kKCk7XG4gICAgdGhpcy5jb2RlLm9wZW5CbG9jayhcbiAgICAgIGBjb25zdHJ1Y3Rvcih0ZXJyYWZvcm1SZXNvdXJjZTogY2RrdG4uSUludGVycG9sYXRpbmdQYXJlbnQsIHRlcnJhZm9ybUF0dHJpYnV0ZTogc3RyaW5nKWAsXG4gICAgKTtcbiAgICB0aGlzLmNvZGUubGluZShgc3VwZXIodGVycmFmb3JtUmVzb3VyY2UsIHRlcnJhZm9ybUF0dHJpYnV0ZSlgKTtcbiAgICB0aGlzLmNvZGUuY2xvc2VCbG9jaygpO1xuXG4gICAgdGhpcy5jb2RlLmxpbmUoKTtcbiAgICBjb25zdCBnZXR0ZXJDb21tZW50ID0gc2FuaXRpemVkQ29tbWVudCh0aGlzLmNvZGUpO1xuICAgIGdldHRlckNvbW1lbnQubGluZShgQHBhcmFtIGtleSB0aGUga2V5IG9mIHRoZSBpdGVtIHRvIHJldHVybmApO1xuICAgIGdldHRlckNvbW1lbnQuZW5kKCk7XG4gICAgdGhpcy5jb2RlLm9wZW5CbG9jayhcbiAgICAgIGBwdWJsaWMgZ2V0KGtleTogc3RyaW5nKTogJHtzdHJ1Y3Qub3V0cHV0UmVmZXJlbmNlTmFtZX1gLFxuICAgICk7XG4gICAgdGhpcy5jb2RlLmxpbmUoXG4gICAgICBgcmV0dXJuIG5ldyAke3N0cnVjdC5vdXRwdXRSZWZlcmVuY2VOYW1lfSh0aGlzLnRlcnJhZm9ybVJlc291cmNlLCB0aGlzLnRlcnJhZm9ybUF0dHJpYnV0ZSwga2V5KTtgLFxuICAgICk7XG4gICAgdGhpcy5jb2RlLmNsb3NlQmxvY2soKTtcblxuICAgIHRoaXMuY29kZS5jbG9zZUJsb2NrKCk7XG4gIH1cblxuICBwcml2YXRlIGVtaXRDb21wbGV4TWFwTGlzdENsYXNzZXMoc3RydWN0OiBTdHJ1Y3QpIHtcbiAgICB0aGlzLmVtaXRDb21wbGV4TWFwTGlzdENsYXNzKHN0cnVjdCk7XG4gICAgdGhpcy5lbWl0Q29tcGxleE1hcENsYXNzKHN0cnVjdCk7XG4gIH1cblxuICBwcml2YXRlIGVtaXRDb21wbGV4TWFwTGlzdENsYXNzKHN0cnVjdDogU3RydWN0KSB7XG4gICAgdGhpcy5jb2RlLmxpbmUoKTtcbiAgICB0aGlzLmNvZGUub3BlbkJsb2NrKFxuICAgICAgYGV4cG9ydCBjbGFzcyAke3N0cnVjdC5tYXBMaXN0TmFtZX0gZXh0ZW5kcyBjZGt0bi5NYXBMaXN0YCxcbiAgICApO1xuXG4gICAgaWYgKHN0cnVjdC5hc3NpZ25hYmxlKSB7XG4gICAgICB0aGlzLmNvZGUubGluZShcbiAgICAgICAgYHB1YmxpYyBpbnRlcm5hbFZhbHVlPyA6ICR7c3RydWN0Lm1hcE5hbWV9W10gfCBjZGt0bi5JUmVzb2x2YWJsZWAsXG4gICAgICApO1xuICAgIH1cblxuICAgIHRoaXMuY29kZS5saW5lKCk7XG4gICAgY29uc3QgY29uc3RydWN0b3JDb21tZW50ID0gc2FuaXRpemVkQ29tbWVudCh0aGlzLmNvZGUpO1xuICAgIGNvbnN0cnVjdG9yQ29tbWVudC5saW5lKGBAcGFyYW0gdGVycmFmb3JtUmVzb3VyY2UgVGhlIHBhcmVudCByZXNvdXJjZWApO1xuICAgIGNvbnN0cnVjdG9yQ29tbWVudC5saW5lKFxuICAgICAgYEBwYXJhbSB0ZXJyYWZvcm1BdHRyaWJ1dGUgVGhlIGF0dHJpYnV0ZSBvbiB0aGUgcGFyZW50IHJlc291cmNlIHRoaXMgY2xhc3MgaXMgcmVmZXJlbmNpbmdgLFxuICAgICk7XG4gICAgY29uc3RydWN0b3JDb21tZW50LmxpbmUoXG4gICAgICBgQHBhcmFtIHdyYXBzU2V0IHdoZXRoZXIgdGhlIGxpc3QgaXMgd3JhcHBpbmcgYSBzZXQgKHdpbGwgYWRkIHRvbGlzdCgpIHRvIGJlIGFibGUgdG8gYWNjZXNzIGFuIGl0ZW0gdmlhIGFuIGluZGV4KWAsXG4gICAgKTtcbiAgICBjb25zdHJ1Y3RvckNvbW1lbnQuZW5kKCk7XG4gICAgdGhpcy5jb2RlLm9wZW5CbG9jayhcbiAgICAgIGBjb25zdHJ1Y3Rvcih0ZXJyYWZvcm1SZXNvdXJjZTogY2RrdG4uSUludGVycG9sYXRpbmdQYXJlbnQsIHRlcnJhZm9ybUF0dHJpYnV0ZTogc3RyaW5nLCB3cmFwc1NldDogYm9vbGVhbilgLFxuICAgICk7XG4gICAgdGhpcy5jb2RlLmxpbmUoYHN1cGVyKHRlcnJhZm9ybVJlc291cmNlLCB0ZXJyYWZvcm1BdHRyaWJ1dGUsIHdyYXBzU2V0KWApO1xuICAgIHRoaXMuY29kZS5jbG9zZUJsb2NrKCk7XG5cbiAgICB0aGlzLmNvZGUubGluZSgpO1xuICAgIGNvbnN0IGdldHRlckNvbW1lbnQgPSBzYW5pdGl6ZWRDb21tZW50KHRoaXMuY29kZSk7XG4gICAgZ2V0dGVyQ29tbWVudC5saW5lKGBAcGFyYW0gaW5kZXggdGhlIGluZGV4IG9mIHRoZSBpdGVtIHRvIHJldHVybmApO1xuICAgIGdldHRlckNvbW1lbnQuZW5kKCk7XG4gICAgdGhpcy5jb2RlLm9wZW5CbG9jayhgcHVibGljIGdldChpbmRleDogbnVtYmVyKTogJHtzdHJ1Y3QubWFwTmFtZX1gKTtcbiAgICB0aGlzLmNvZGUubGluZShgcmV0dXJuIG5ldyAke3N0cnVjdC5tYXBOYW1lfSh0aGlzLCBcXGBbXFwke2luZGV4fV1cXGApO2ApO1xuICAgIHRoaXMuY29kZS5jbG9zZUJsb2NrKCk7XG5cbiAgICB0aGlzLmNvZGUuY2xvc2VCbG9jaygpO1xuICB9XG5cbiAgcHJpdmF0ZSBlbWl0Q29tcGxleExpc3RNYXBDbGFzc2VzKHN0cnVjdDogU3RydWN0LCBpc1NldDogYm9vbGVhbikge1xuICAgIHRoaXMuZW1pdENvbXBsZXhMaXN0TWFwQ2xhc3Moc3RydWN0LCBpc1NldCk7XG4gICAgdGhpcy5lbWl0Q29tcGxleExpc3RDbGFzcyhzdHJ1Y3QpO1xuICB9XG5cbiAgcHJpdmF0ZSBlbWl0Q29tcGxleExpc3RNYXBDbGFzcyhzdHJ1Y3Q6IFN0cnVjdCwgaXNTZXQ6IGJvb2xlYW4pIHtcbiAgICB0aGlzLmNvZGUubGluZSgpO1xuICAgIHRoaXMuY29kZS5vcGVuQmxvY2soXG4gICAgICBgZXhwb3J0IGNsYXNzICR7c3RydWN0Lmxpc3RNYXBOYW1lfSBleHRlbmRzIGNka3RuLkNvbXBsZXhNYXBgLFxuICAgICk7XG5cbiAgICBpZiAoc3RydWN0LmFzc2lnbmFibGUpIHtcbiAgICAgIHRoaXMuY29kZS5saW5lKFxuICAgICAgICBgcHVibGljIGludGVybmFsVmFsdWU/IDogeyBba2V5OiBzdHJpbmddOiAke3N0cnVjdC5uYW1lfVtdIH0gfCBjZGt0bi5JUmVzb2x2YWJsZWAsXG4gICAgICApO1xuICAgIH1cblxuICAgIHRoaXMuY29kZS5saW5lKCk7XG4gICAgY29uc3QgY29uc3RydWN0b3JDb21tZW50ID0gc2FuaXRpemVkQ29tbWVudCh0aGlzLmNvZGUpO1xuICAgIGNvbnN0cnVjdG9yQ29tbWVudC5saW5lKGBAcGFyYW0gdGVycmFmb3JtUmVzb3VyY2UgVGhlIHBhcmVudCByZXNvdXJjZWApO1xuICAgIGNvbnN0cnVjdG9yQ29tbWVudC5saW5lKFxuICAgICAgYEBwYXJhbSB0ZXJyYWZvcm1BdHRyaWJ1dGUgVGhlIGF0dHJpYnV0ZSBvbiB0aGUgcGFyZW50IHJlc291cmNlIHRoaXMgY2xhc3MgaXMgcmVmZXJlbmNpbmdgLFxuICAgICk7XG4gICAgY29uc3RydWN0b3JDb21tZW50LmVuZCgpO1xuICAgIHRoaXMuY29kZS5vcGVuQmxvY2soXG4gICAgICBgY29uc3RydWN0b3IodGVycmFmb3JtUmVzb3VyY2U6IGNka3RuLklJbnRlcnBvbGF0aW5nUGFyZW50LCB0ZXJyYWZvcm1BdHRyaWJ1dGU6IHN0cmluZylgLFxuICAgICk7XG4gICAgdGhpcy5jb2RlLmxpbmUoYHN1cGVyKHRlcnJhZm9ybVJlc291cmNlLCB0ZXJyYWZvcm1BdHRyaWJ1dGUpYCk7XG4gICAgdGhpcy5jb2RlLmNsb3NlQmxvY2soKTtcblxuICAgIHRoaXMuY29kZS5saW5lKCk7XG4gICAgY29uc3QgZ2V0dGVyQ29tbWVudCA9IHNhbml0aXplZENvbW1lbnQodGhpcy5jb2RlKTtcbiAgICBnZXR0ZXJDb21tZW50LmxpbmUoYEBwYXJhbSBrZXkgdGhlIGtleSBvZiB0aGUgaXRlbSB0byByZXR1cm5gKTtcbiAgICBnZXR0ZXJDb21tZW50LmVuZCgpO1xuICAgIHRoaXMuY29kZS5vcGVuQmxvY2soYHB1YmxpYyBnZXQoa2V5OiBzdHJpbmcpOiAke3N0cnVjdC5saXN0TmFtZX1gKTtcbiAgICB0aGlzLmNvZGUubGluZShcbiAgICAgIGByZXR1cm4gbmV3ICR7c3RydWN0Lmxpc3ROYW1lfSh0aGlzLCBcXGBbXFwke2tleX1dXFxgLCAke2lzU2V0fSk7YCxcbiAgICApO1xuICAgIHRoaXMuY29kZS5jbG9zZUJsb2NrKCk7XG5cbiAgICB0aGlzLmNvZGUuY2xvc2VCbG9jaygpO1xuICB9XG5cbiAgcHJpdmF0ZSBlbWl0Q29tcGxleExpc3RMaXN0Q2xhc3NlcyhzdHJ1Y3Q6IFN0cnVjdCkge1xuICAgIHRoaXMuZW1pdENvbXBsZXhMaXN0TGlzdENsYXNzKHN0cnVjdCk7XG4gICAgdGhpcy5lbWl0Q29tcGxleExpc3RDbGFzcyhzdHJ1Y3QpO1xuICB9XG5cbiAgcHJpdmF0ZSBlbWl0Q29tcGxleExpc3RMaXN0Q2xhc3Moc3RydWN0OiBTdHJ1Y3QpIHtcbiAgICB0aGlzLmNvZGUubGluZSgpO1xuICAgIHRoaXMuY29kZS5vcGVuQmxvY2soXG4gICAgICBgZXhwb3J0IGNsYXNzICR7c3RydWN0Lmxpc3RMaXN0TmFtZX0gZXh0ZW5kcyBjZGt0bi5NYXBMaXN0YCwgLy8gZGVzcGl0ZSBuYW1lLCBuZWVkIHRoZSBzYW1lIGJlaGF2aW9yXG4gICAgKTtcblxuICAgIGlmIChzdHJ1Y3QuYXNzaWduYWJsZSkge1xuICAgICAgdGhpcy5jb2RlLmxpbmUoXG4gICAgICAgIGBwdWJsaWMgaW50ZXJuYWxWYWx1ZT8gOiAke3N0cnVjdC5uYW1lfVtdW10gfCBjZGt0bi5JUmVzb2x2YWJsZWAsXG4gICAgICApO1xuICAgIH1cblxuICAgIHRoaXMuY29kZS5saW5lKCk7XG4gICAgY29uc3QgY29uc3RydWN0b3JDb21tZW50ID0gc2FuaXRpemVkQ29tbWVudCh0aGlzLmNvZGUpO1xuICAgIGNvbnN0cnVjdG9yQ29tbWVudC5saW5lKGBAcGFyYW0gdGVycmFmb3JtUmVzb3VyY2UgVGhlIHBhcmVudCByZXNvdXJjZWApO1xuICAgIGNvbnN0cnVjdG9yQ29tbWVudC5saW5lKFxuICAgICAgYEBwYXJhbSB0ZXJyYWZvcm1BdHRyaWJ1dGUgVGhlIGF0dHJpYnV0ZSBvbiB0aGUgcGFyZW50IHJlc291cmNlIHRoaXMgY2xhc3MgaXMgcmVmZXJlbmNpbmdgLFxuICAgICk7XG4gICAgY29uc3RydWN0b3JDb21tZW50LmxpbmUoXG4gICAgICBgQHBhcmFtIHdyYXBzU2V0IHdoZXRoZXIgdGhlIGxpc3QgaXMgd3JhcHBpbmcgYSBzZXQgKHdpbGwgYWRkIHRvbGlzdCgpIHRvIGJlIGFibGUgdG8gYWNjZXNzIGFuIGl0ZW0gdmlhIGFuIGluZGV4KWAsXG4gICAgKTtcbiAgICBjb25zdHJ1Y3RvckNvbW1lbnQuZW5kKCk7XG4gICAgdGhpcy5jb2RlLm9wZW5CbG9jayhcbiAgICAgIGBjb25zdHJ1Y3Rvcih0ZXJyYWZvcm1SZXNvdXJjZTogY2RrdG4uSUludGVycG9sYXRpbmdQYXJlbnQsIHRlcnJhZm9ybUF0dHJpYnV0ZTogc3RyaW5nLCB3cmFwc1NldDogYm9vbGVhbilgLFxuICAgICk7XG4gICAgdGhpcy5jb2RlLmxpbmUoYHN1cGVyKHRlcnJhZm9ybVJlc291cmNlLCB0ZXJyYWZvcm1BdHRyaWJ1dGUsIHdyYXBzU2V0KWApO1xuICAgIHRoaXMuY29kZS5jbG9zZUJsb2NrKCk7XG5cbiAgICB0aGlzLmNvZGUubGluZSgpO1xuICAgIGNvbnN0IGdldHRlckNvbW1lbnQgPSBzYW5pdGl6ZWRDb21tZW50KHRoaXMuY29kZSk7XG4gICAgZ2V0dGVyQ29tbWVudC5saW5lKGBAcGFyYW0gaW5kZXggdGhlIGluZGV4IG9mIHRoZSBpdGVtIHRvIHJldHVybmApO1xuICAgIGdldHRlckNvbW1lbnQuZW5kKCk7XG4gICAgdGhpcy5jb2RlLm9wZW5CbG9jayhgcHVibGljIGdldChpbmRleDogbnVtYmVyKTogJHtzdHJ1Y3QubGlzdE5hbWV9YCk7XG4gICAgdGhpcy5jb2RlLmxpbmUoXG4gICAgICBgcmV0dXJuIG5ldyAke3N0cnVjdC5saXN0TmFtZX0odGhpcywgXFxgW1xcJHtpbmRleH1dXFxgLCAke1xuICAgICAgICBzdHJ1Y3QubmVzdGluZ01vZGUgPT09IFwic2V0bGlzdFwiIHx8IHN0cnVjdC5uZXN0aW5nTW9kZSA9PT0gXCJzZXRzZXRcIlxuICAgICAgfSk7YCxcbiAgICApO1xuICAgIHRoaXMuY29kZS5jbG9zZUJsb2NrKCk7XG5cbiAgICB0aGlzLmNvZGUuY2xvc2VCbG9jaygpO1xuICB9XG5cbiAgcHJpdmF0ZSBlbWl0SW50ZXJuYWxWYWx1ZUdldHRlcihzdHJ1Y3Q6IFN0cnVjdCkge1xuICAgIHRoaXMuY29kZS5vcGVuQmxvY2soXG4gICAgICBgcHVibGljIGdldCBpbnRlcm5hbFZhbHVlKCk6ICR7c3RydWN0Lm5hbWV9JHtcbiAgICAgICAgIXN0cnVjdC5pc0NsYXNzID8gXCIgfCBjZGt0bi5JUmVzb2x2YWJsZVwiIDogXCJcIlxuICAgICAgfSB8IHVuZGVmaW5lZGAsXG4gICAgKTtcblxuICAgIGlmICghc3RydWN0LmlzQ2xhc3MpIHtcbiAgICAgIHRoaXMuY29kZS5vcGVuQmxvY2soXCJpZiAodGhpcy5yZXNvbHZhYmxlVmFsdWUpXCIpO1xuICAgICAgdGhpcy5jb2RlLmxpbmUoXCJyZXR1cm4gdGhpcy5yZXNvbHZhYmxlVmFsdWU7XCIpO1xuICAgICAgdGhpcy5jb2RlLmNsb3NlQmxvY2soKTtcbiAgICB9XG5cbiAgICB0aGlzLmNvZGUubGluZShcImxldCBoYXNBbnlWYWx1ZXMgPSB0aGlzLmlzRW1wdHlPYmplY3Q7XCIpO1xuICAgIHRoaXMuY29kZS5saW5lKFwiY29uc3QgaW50ZXJuYWxWYWx1ZVJlc3VsdDogYW55ID0ge307XCIpO1xuICAgIGZvciAoY29uc3QgYXR0IG9mIHN0cnVjdC5hdHRyaWJ1dGVzKSB7XG4gICAgICBpZiAoYXR0LmlzU3RvcmVkKSB7XG4gICAgICAgIGlmIChhdHQuZ2V0dGVyVHlwZS5fdHlwZSA9PT0gXCJzdG9yZWRfY2xhc3NcIikge1xuICAgICAgICAgIHRoaXMuY29kZS5vcGVuQmxvY2soXG4gICAgICAgICAgICBgaWYgKHRoaXMuJHthdHQuc3RvcmFnZU5hbWV9Py5pbnRlcm5hbFZhbHVlICE9PSB1bmRlZmluZWQpYCxcbiAgICAgICAgICApO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRoaXMuY29kZS5vcGVuQmxvY2soYGlmICh0aGlzLiR7YXR0LnN0b3JhZ2VOYW1lfSAhPT0gdW5kZWZpbmVkKWApO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuY29kZS5saW5lKFwiaGFzQW55VmFsdWVzID0gdHJ1ZTtcIik7XG4gICAgICAgIGlmIChhdHQuZ2V0dGVyVHlwZS5fdHlwZSA9PT0gXCJzdG9yZWRfY2xhc3NcIikge1xuICAgICAgICAgIHRoaXMuY29kZS5saW5lKFxuICAgICAgICAgICAgYGludGVybmFsVmFsdWVSZXN1bHQuJHthdHQubmFtZX0gPSB0aGlzLiR7YXR0LnN0b3JhZ2VOYW1lfT8uaW50ZXJuYWxWYWx1ZTtgLFxuICAgICAgICAgICk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdGhpcy5jb2RlLmxpbmUoXG4gICAgICAgICAgICBgaW50ZXJuYWxWYWx1ZVJlc3VsdC4ke2F0dC5uYW1lfSA9IHRoaXMuJHthdHQuc3RvcmFnZU5hbWV9O2AsXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmNvZGUuY2xvc2VCbG9jaygpO1xuICAgICAgfVxuICAgIH1cbiAgICB0aGlzLmNvZGUubGluZShcInJldHVybiBoYXNBbnlWYWx1ZXMgPyBpbnRlcm5hbFZhbHVlUmVzdWx0IDogdW5kZWZpbmVkO1wiKTtcbiAgICB0aGlzLmNvZGUuY2xvc2VCbG9jaygpO1xuICB9XG5cbiAgcHJpdmF0ZSBlbWl0SW50ZXJuYWxWYWx1ZVNldHRlcihzdHJ1Y3Q6IFN0cnVjdCkge1xuICAgIHRoaXMuY29kZS5vcGVuQmxvY2soXG4gICAgICBgcHVibGljIHNldCBpbnRlcm5hbFZhbHVlKHZhbHVlOiAke3N0cnVjdC5uYW1lfSR7XG4gICAgICAgICFzdHJ1Y3QuaXNDbGFzcyA/IFwiIHwgY2RrdG4uSVJlc29sdmFibGVcIiA6IFwiXCJcbiAgICAgIH0gfCB1bmRlZmluZWQpYCxcbiAgICApO1xuXG4gICAgdGhpcy5jb2RlLm9wZW5CbG9jayhcImlmICh2YWx1ZSA9PT0gdW5kZWZpbmVkKVwiKTtcbiAgICB0aGlzLmNvZGUubGluZShcInRoaXMuaXNFbXB0eU9iamVjdCA9IGZhbHNlO1wiKTtcbiAgICBpZiAoIXN0cnVjdC5pc0NsYXNzKSB7XG4gICAgICB0aGlzLmNvZGUubGluZShcInRoaXMucmVzb2x2YWJsZVZhbHVlID0gdW5kZWZpbmVkO1wiKTtcbiAgICB9XG4gICAgZm9yIChjb25zdCBhdHQgb2Ygc3RydWN0LmF0dHJpYnV0ZXMpIHtcbiAgICAgIGlmIChhdHQuaXNTdG9yZWQpIHtcbiAgICAgICAgaWYgKGF0dC5zZXR0ZXJUeXBlLl90eXBlID09PSBcInN0b3JlZF9jbGFzc1wiKSB7XG4gICAgICAgICAgdGhpcy5jb2RlLmxpbmUoYHRoaXMuJHthdHQuc3RvcmFnZU5hbWV9LmludGVybmFsVmFsdWUgPSB1bmRlZmluZWQ7YCk7XG4gICAgICAgIH0gZWxzZSBpZiAoYXR0LnNldHRlclR5cGUuX3R5cGUgIT09IFwibm9uZVwiKSB7XG4gICAgICAgICAgdGhpcy5jb2RlLmxpbmUoYHRoaXMuJHthdHQuc3RvcmFnZU5hbWV9ID0gdW5kZWZpbmVkO2ApO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICAgIHRoaXMuY29kZS5jbG9zZUJsb2NrKCk7XG4gICAgaWYgKCFzdHJ1Y3QuaXNDbGFzcykge1xuICAgICAgdGhpcy5jb2RlLm9wZW5CbG9jayhcImVsc2UgaWYgKGNka3RuLlRva2VuaXphdGlvbi5pc1Jlc29sdmFibGUodmFsdWUpKVwiKTtcbiAgICAgIHRoaXMuY29kZS5saW5lKFwidGhpcy5pc0VtcHR5T2JqZWN0ID0gZmFsc2U7XCIpO1xuICAgICAgdGhpcy5jb2RlLmxpbmUoXCJ0aGlzLnJlc29sdmFibGVWYWx1ZSA9IHZhbHVlO1wiKTtcbiAgICAgIHRoaXMuY29kZS5jbG9zZUJsb2NrKCk7XG4gICAgfVxuICAgIHRoaXMuY29kZS5vcGVuQmxvY2soXCJlbHNlXCIpO1xuICAgIHRoaXMuY29kZS5saW5lKFwidGhpcy5pc0VtcHR5T2JqZWN0ID0gT2JqZWN0LmtleXModmFsdWUpLmxlbmd0aCA9PT0gMDtcIik7XG4gICAgaWYgKCFzdHJ1Y3QuaXNDbGFzcykge1xuICAgICAgdGhpcy5jb2RlLmxpbmUoXCJ0aGlzLnJlc29sdmFibGVWYWx1ZSA9IHVuZGVmaW5lZDtcIik7XG4gICAgfVxuICAgIGZvciAoY29uc3QgYXR0IG9mIHN0cnVjdC5hdHRyaWJ1dGVzKSB7XG4gICAgICBpZiAoYXR0LmlzU3RvcmVkKSB7XG4gICAgICAgIGlmIChhdHQuc2V0dGVyVHlwZS5fdHlwZSA9PT0gXCJzdG9yZWRfY2xhc3NcIikge1xuICAgICAgICAgIHRoaXMuY29kZS5saW5lKFxuICAgICAgICAgICAgYHRoaXMuJHthdHQuc3RvcmFnZU5hbWV9LmludGVybmFsVmFsdWUgPSB2YWx1ZS4ke2F0dC5uYW1lfTtgLFxuICAgICAgICAgICk7XG4gICAgICAgIH0gZWxzZSBpZiAoYXR0LnNldHRlclR5cGUuX3R5cGUgIT09IFwibm9uZVwiKSB7XG4gICAgICAgICAgdGhpcy5jb2RlLmxpbmUoYHRoaXMuJHthdHQuc3RvcmFnZU5hbWV9ID0gdmFsdWUuJHthdHQubmFtZX07YCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgdGhpcy5jb2RlLmNsb3NlQmxvY2soKTtcbiAgICB0aGlzLmNvZGUuY2xvc2VCbG9jaygpO1xuICB9XG5cbiAgcHJpdmF0ZSBlbWl0VG9IY2xUZXJyYWZvcm1GdW5jdGlvbihzdHJ1Y3Q6IFN0cnVjdCkge1xuICAgIHRoaXMuY29kZS5saW5lKCk7XG4gICAgdGhpcy5jb2RlLm9wZW5CbG9jayhcbiAgICAgIGBleHBvcnQgZnVuY3Rpb24gJHtkb3duY2FzZUZpcnN0KHN0cnVjdC5uYW1lKX1Ub0hjbFRlcnJhZm9ybShzdHJ1Y3Q/OiAke1xuICAgICAgICBzdHJ1Y3QuaXNTaW5nbGVJdGVtICYmICFzdHJ1Y3QuaXNQcm92aWRlclxuICAgICAgICAgID8gYCR7c3RydWN0Lm5hbWV9T3V0cHV0UmVmZXJlbmNlIHwgYFxuICAgICAgICAgIDogXCJcIlxuICAgICAgfSR7c3RydWN0Lm5hbWV9JHshc3RydWN0LmlzQ2xhc3MgPyBcIiB8IGNka3RuLklSZXNvbHZhYmxlXCIgOiBcIlwifSk6IGFueWAsXG4gICAgKTtcbiAgICB0aGlzLmNvZGUubGluZShcbiAgICAgIGBpZiAoIWNka3RuLmNhbkluc3BlY3Qoc3RydWN0KSB8fCBjZGt0bi5Ub2tlbml6YXRpb24uaXNSZXNvbHZhYmxlKHN0cnVjdCkpIHsgcmV0dXJuIHN0cnVjdDsgfWAsXG4gICAgKTtcbiAgICB0aGlzLmNvZGUub3BlbkJsb2NrKGBpZiAoY2RrdG4uaXNDb21wbGV4RWxlbWVudChzdHJ1Y3QpKWApO1xuICAgIHRoaXMuY29kZS5saW5lKFxuICAgICAgYHRocm93IG5ldyBFcnJvcihcIkEgY29tcGxleCBlbGVtZW50IHdhcyB1c2VkIGFzIGNvbmZpZ3VyYXRpb24sIHRoaXMgaXMgbm90IHN1cHBvcnRlZDogaHR0cHM6Ly9jZGsudGYvY29tcGxleC1vYmplY3QtYXMtY29uZmlndXJhdGlvblwiKTtgLFxuICAgICk7XG4gICAgdGhpcy5jb2RlLmNsb3NlQmxvY2soKTtcblxuICAgIHRoaXMuY29kZS5vcGVuKGBjb25zdCBhdHRycyA9IHtgKTtcblxuICAgIGZvciAoY29uc3QgYXR0IG9mIHN0cnVjdC5hc3NpZ25hYmxlQXR0cmlidXRlcykge1xuICAgICAgdGhpcy5hdHRyaWJ1dGVzRW1pdHRlci5lbWl0VG9IY2xUZXJyYWZvcm0oYXR0LCB0cnVlKTtcbiAgICB9XG5cbiAgICB0aGlzLmNvZGUuY2xvc2UoYH07YCk7XG5cbiAgICBpZiAoc3RydWN0LmFzc2lnbmFibGVBdHRyaWJ1dGVzLmxlbmd0aCA+IDApIHtcbiAgICAgIHRoaXMuY29kZS5saW5lKCk7XG4gICAgICB0aGlzLmNvZGUubGluZShgLy8gcmVtb3ZlIHVuZGVmaW5lZCBhdHRyaWJ1dGVzYCk7XG4gICAgICB0aGlzLmNvZGUubGluZShcbiAgICAgICAgYHJldHVybiBPYmplY3QuZnJvbUVudHJpZXMoT2JqZWN0LmVudHJpZXMoYXR0cnMpLmZpbHRlcigoW18sIHZhbHVlXSkgPT4gdmFsdWUgIT09IHVuZGVmaW5lZCAmJiB2YWx1ZS52YWx1ZSAhPT0gdW5kZWZpbmVkKSk7YCxcbiAgICAgICk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuY29kZS5saW5lKGByZXR1cm4gYXR0cnM7YCk7XG4gICAgfVxuXG4gICAgdGhpcy5jb2RlLmNsb3NlQmxvY2soKTtcbiAgICB0aGlzLmNvZGUubGluZSgpO1xuICB9XG5cbiAgcHJpdmF0ZSBlbWl0VG9UZXJyYWZvcm1GdW5jdGlvbihzdHJ1Y3Q6IFN0cnVjdCkge1xuICAgIHRoaXMuY29kZS5saW5lKCk7XG4gICAgdGhpcy5jb2RlLm9wZW5CbG9jayhcbiAgICAgIGBleHBvcnQgZnVuY3Rpb24gJHtkb3duY2FzZUZpcnN0KHN0cnVjdC5uYW1lKX1Ub1RlcnJhZm9ybShzdHJ1Y3Q/OiAke1xuICAgICAgICBzdHJ1Y3QuaXNTaW5nbGVJdGVtICYmICFzdHJ1Y3QuaXNQcm92aWRlclxuICAgICAgICAgID8gYCR7c3RydWN0Lm5hbWV9T3V0cHV0UmVmZXJlbmNlIHwgYFxuICAgICAgICAgIDogXCJcIlxuICAgICAgfSR7c3RydWN0Lm5hbWV9JHshc3RydWN0LmlzQ2xhc3MgPyBcIiB8IGNka3RuLklSZXNvbHZhYmxlXCIgOiBcIlwifSk6IGFueWAsXG4gICAgKTtcbiAgICB0aGlzLmNvZGUubGluZShcbiAgICAgIGBpZiAoIWNka3RuLmNhbkluc3BlY3Qoc3RydWN0KSB8fCBjZGt0bi5Ub2tlbml6YXRpb24uaXNSZXNvbHZhYmxlKHN0cnVjdCkpIHsgcmV0dXJuIHN0cnVjdDsgfWAsXG4gICAgKTtcbiAgICB0aGlzLmNvZGUub3BlbkJsb2NrKGBpZiAoY2RrdG4uaXNDb21wbGV4RWxlbWVudChzdHJ1Y3QpKWApO1xuICAgIHRoaXMuY29kZS5saW5lKFxuICAgICAgYHRocm93IG5ldyBFcnJvcihcIkEgY29tcGxleCBlbGVtZW50IHdhcyB1c2VkIGFzIGNvbmZpZ3VyYXRpb24sIHRoaXMgaXMgbm90IHN1cHBvcnRlZDogaHR0cHM6Ly9jZGsudGYvY29tcGxleC1vYmplY3QtYXMtY29uZmlndXJhdGlvblwiKTtgLFxuICAgICk7XG4gICAgdGhpcy5jb2RlLmNsb3NlQmxvY2soKTtcblxuICAgIHRoaXMuY29kZS5vcGVuQmxvY2soXCJyZXR1cm5cIik7XG4gICAgZm9yIChjb25zdCBhdHQgb2Ygc3RydWN0LmFzc2lnbmFibGVBdHRyaWJ1dGVzKSB7XG4gICAgICB0aGlzLmF0dHJpYnV0ZXNFbWl0dGVyLmVtaXRUb1RlcnJhZm9ybShhdHQsIHRydWUpO1xuICAgIH1cbiAgICB0aGlzLmNvZGUuY2xvc2VCbG9jayhcIjtcIik7XG4gICAgdGhpcy5jb2RlLmNsb3NlQmxvY2soKTtcbiAgICB0aGlzLmNvZGUubGluZSgpO1xuICB9XG59XG4iXX0=