@mnaoumov/typescript-lib 0.0.0 → 1.0.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 (180) hide show
  1. package/@types/debug/package.json +4 -0
  2. package/LICENSE +21 -0
  3. package/README.md +7 -1
  4. package/dist/lib/cjs/@types/debug.d.cts +21 -0
  5. package/dist/lib/cjs/abort-controller.cjs +202 -0
  6. package/dist/lib/cjs/abort-controller.d.cts +135 -0
  7. package/dist/lib/cjs/aggregate-error.cjs +98 -0
  8. package/dist/lib/cjs/aggregate-error.d.cts +24 -0
  9. package/dist/lib/cjs/array-buffer.cjs +96 -0
  10. package/dist/lib/cjs/array-buffer.d.cts +16 -0
  11. package/dist/lib/cjs/array.cjs +134 -0
  12. package/dist/lib/cjs/array.d.cts +46 -0
  13. package/dist/lib/cjs/async-events.cjs +466 -0
  14. package/dist/lib/cjs/async-events.d.cts +456 -0
  15. package/dist/lib/cjs/async-operation-hook.cjs +113 -0
  16. package/dist/lib/cjs/async-operation-hook.d.cts +59 -0
  17. package/dist/lib/cjs/async.cjs +521 -0
  18. package/dist/lib/cjs/async.d.cts +414 -0
  19. package/dist/lib/cjs/beeper.cjs +126 -0
  20. package/dist/lib/cjs/beeper.d.cts +21 -0
  21. package/dist/lib/cjs/blob.cjs +160 -0
  22. package/dist/lib/cjs/blob.d.cts +59 -0
  23. package/dist/lib/cjs/bytes.cjs +114 -0
  24. package/dist/lib/cjs/bytes.d.cts +17 -0
  25. package/dist/lib/cjs/debug-controller.cjs +80 -0
  26. package/dist/lib/cjs/debug-controller.d.cts +87 -0
  27. package/dist/lib/cjs/debug.cjs +235 -0
  28. package/dist/lib/cjs/debug.d.cts +66 -0
  29. package/dist/lib/cjs/desktop-zip-extractor.cjs +215 -0
  30. package/dist/lib/cjs/desktop-zip-extractor.d.cts +95 -0
  31. package/dist/lib/cjs/disposable.cjs +414 -0
  32. package/dist/lib/cjs/disposable.d.cts +387 -0
  33. package/dist/lib/cjs/enum.cjs +100 -0
  34. package/dist/lib/cjs/enum.d.cts +24 -0
  35. package/dist/lib/cjs/error.cjs +297 -0
  36. package/dist/lib/cjs/error.d.cts +181 -0
  37. package/dist/lib/cjs/function.cjs +141 -0
  38. package/dist/lib/cjs/function.d.cts +128 -0
  39. package/dist/lib/cjs/html-element.cjs +341 -0
  40. package/dist/lib/cjs/html-element.d.cts +199 -0
  41. package/dist/lib/cjs/index.cjs +195 -0
  42. package/dist/lib/cjs/index.d.cts +33 -0
  43. package/dist/lib/cjs/jpeg-metadata.cjs +228 -0
  44. package/dist/lib/cjs/jpeg-metadata.d.cts +42 -0
  45. package/dist/lib/cjs/library.cjs +158 -0
  46. package/dist/lib/cjs/library.d.cts +96 -0
  47. package/dist/lib/cjs/object-utils.cjs +617 -0
  48. package/dist/lib/cjs/object-utils.d.cts +298 -0
  49. package/dist/lib/cjs/path.cjs +202 -0
  50. package/dist/lib/cjs/path.d.cts +154 -0
  51. package/dist/lib/cjs/reg-exp.cjs +254 -0
  52. package/dist/lib/cjs/reg-exp.d.cts +87 -0
  53. package/dist/lib/cjs/string.cjs +326 -0
  54. package/dist/lib/cjs/string.d.cts +361 -0
  55. package/dist/lib/cjs/transformers/date-transformer.cjs +129 -0
  56. package/dist/lib/cjs/transformers/date-transformer.d.cts +39 -0
  57. package/dist/lib/cjs/transformers/group-transformer.cjs +173 -0
  58. package/dist/lib/cjs/transformers/group-transformer.d.cts +70 -0
  59. package/dist/lib/cjs/transformers/index.cjs +123 -0
  60. package/dist/lib/cjs/transformers/index.d.cts +9 -0
  61. package/dist/lib/cjs/transformers/map-transformer.cjs +129 -0
  62. package/dist/lib/cjs/transformers/map-transformer.d.cts +41 -0
  63. package/dist/lib/cjs/transformers/set-transformer.cjs +129 -0
  64. package/dist/lib/cjs/transformers/set-transformer.d.cts +39 -0
  65. package/dist/lib/cjs/transformers/skip-private-property-transformer.cjs +127 -0
  66. package/dist/lib/cjs/transformers/skip-private-property-transformer.d.cts +36 -0
  67. package/dist/lib/cjs/transformers/transformer.cjs +170 -0
  68. package/dist/lib/cjs/transformers/transformer.d.cts +70 -0
  69. package/dist/lib/cjs/transformers/two-way-map-transformer.cjs +130 -0
  70. package/dist/lib/cjs/transformers/two-way-map-transformer.d.cts +42 -0
  71. package/dist/lib/cjs/transformers/typed-transformer.cjs +94 -0
  72. package/dist/lib/cjs/transformers/typed-transformer.d.cts +39 -0
  73. package/dist/lib/cjs/two-way-map.cjs +208 -0
  74. package/dist/lib/cjs/two-way-map.d.cts +101 -0
  75. package/dist/lib/cjs/type-guards.cjs +128 -0
  76. package/dist/lib/cjs/type-guards.d.cts +84 -0
  77. package/dist/lib/cjs/type.cjs +121 -0
  78. package/dist/lib/cjs/type.d.cts +122 -0
  79. package/dist/lib/cjs/typescript-lib-state.cjs +126 -0
  80. package/dist/lib/cjs/typescript-lib-state.d.cts +56 -0
  81. package/dist/lib/cjs/url.cjs +136 -0
  82. package/dist/lib/cjs/url.d.cts +74 -0
  83. package/dist/lib/cjs/value-provider.cjs +100 -0
  84. package/dist/lib/cjs/value-provider.d.cts +28 -0
  85. package/dist/lib/cjs/value-wrapper.cjs +144 -0
  86. package/dist/lib/cjs/value-wrapper.d.cts +47 -0
  87. package/dist/lib/esm/@types/debug.d.mts +21 -0
  88. package/dist/lib/esm/abort-controller.d.mts +135 -0
  89. package/dist/lib/esm/abort-controller.mjs +159 -0
  90. package/dist/lib/esm/aggregate-error.d.mts +24 -0
  91. package/dist/lib/esm/aggregate-error.mjs +60 -0
  92. package/dist/lib/esm/array-buffer.d.mts +16 -0
  93. package/dist/lib/esm/array-buffer.mjs +58 -0
  94. package/dist/lib/esm/array.d.mts +46 -0
  95. package/dist/lib/esm/array.mjs +93 -0
  96. package/dist/lib/esm/async-events.d.mts +456 -0
  97. package/dist/lib/esm/async-events.mjs +427 -0
  98. package/dist/lib/esm/async-operation-hook.d.mts +59 -0
  99. package/dist/lib/esm/async-operation-hook.mjs +71 -0
  100. package/dist/lib/esm/async.d.mts +414 -0
  101. package/dist/lib/esm/async.mjs +479 -0
  102. package/dist/lib/esm/beeper.d.mts +21 -0
  103. package/dist/lib/esm/beeper.mjs +88 -0
  104. package/dist/lib/esm/blob.d.mts +59 -0
  105. package/dist/lib/esm/blob.mjs +121 -0
  106. package/dist/lib/esm/bytes.d.mts +17 -0
  107. package/dist/lib/esm/bytes.mjs +76 -0
  108. package/dist/lib/esm/debug-controller.d.mts +87 -0
  109. package/dist/lib/esm/debug-controller.mjs +50 -0
  110. package/dist/lib/esm/debug.d.mts +66 -0
  111. package/dist/lib/esm/debug.mjs +185 -0
  112. package/dist/lib/esm/desktop-zip-extractor.d.mts +95 -0
  113. package/dist/lib/esm/desktop-zip-extractor.mjs +180 -0
  114. package/dist/lib/esm/disposable.d.mts +387 -0
  115. package/dist/lib/esm/disposable.mjs +360 -0
  116. package/dist/lib/esm/enum.d.mts +24 -0
  117. package/dist/lib/esm/enum.mjs +61 -0
  118. package/dist/lib/esm/error.d.mts +181 -0
  119. package/dist/lib/esm/error.mjs +248 -0
  120. package/dist/lib/esm/function.d.mts +128 -0
  121. package/dist/lib/esm/function.mjs +96 -0
  122. package/dist/lib/esm/html-element.d.mts +199 -0
  123. package/dist/lib/esm/html-element.mjs +291 -0
  124. package/dist/lib/esm/index.d.mts +33 -0
  125. package/dist/lib/esm/index.mjs +116 -0
  126. package/dist/lib/esm/jpeg-metadata.d.mts +42 -0
  127. package/dist/lib/esm/jpeg-metadata.mjs +189 -0
  128. package/dist/lib/esm/library.d.mts +96 -0
  129. package/dist/lib/esm/library.mjs +118 -0
  130. package/dist/lib/esm/object-utils.d.mts +298 -0
  131. package/dist/lib/esm/object-utils.mjs +567 -0
  132. package/dist/lib/esm/path.d.mts +154 -0
  133. package/dist/lib/esm/path.mjs +139 -0
  134. package/dist/lib/esm/reg-exp.d.mts +87 -0
  135. package/dist/lib/esm/reg-exp.mjs +213 -0
  136. package/dist/lib/esm/string.d.mts +361 -0
  137. package/dist/lib/esm/string.mjs +274 -0
  138. package/dist/lib/esm/transformers/date-transformer.d.mts +39 -0
  139. package/dist/lib/esm/transformers/date-transformer.mjs +91 -0
  140. package/dist/lib/esm/transformers/group-transformer.d.mts +70 -0
  141. package/dist/lib/esm/transformers/group-transformer.mjs +138 -0
  142. package/dist/lib/esm/transformers/index.d.mts +9 -0
  143. package/dist/lib/esm/transformers/index.mjs +68 -0
  144. package/dist/lib/esm/transformers/map-transformer.d.mts +41 -0
  145. package/dist/lib/esm/transformers/map-transformer.mjs +91 -0
  146. package/dist/lib/esm/transformers/set-transformer.d.mts +39 -0
  147. package/dist/lib/esm/transformers/set-transformer.mjs +91 -0
  148. package/dist/lib/esm/transformers/skip-private-property-transformer.d.mts +36 -0
  149. package/dist/lib/esm/transformers/skip-private-property-transformer.mjs +89 -0
  150. package/dist/lib/esm/transformers/transformer.d.mts +70 -0
  151. package/dist/lib/esm/transformers/transformer.mjs +132 -0
  152. package/dist/lib/esm/transformers/two-way-map-transformer.d.mts +42 -0
  153. package/dist/lib/esm/transformers/two-way-map-transformer.mjs +92 -0
  154. package/dist/lib/esm/transformers/typed-transformer.d.mts +39 -0
  155. package/dist/lib/esm/transformers/typed-transformer.mjs +56 -0
  156. package/dist/lib/esm/two-way-map.d.mts +101 -0
  157. package/dist/lib/esm/two-way-map.mjs +170 -0
  158. package/dist/lib/esm/type-guards.d.mts +84 -0
  159. package/dist/lib/esm/type-guards.mjs +85 -0
  160. package/dist/lib/esm/type.d.mts +122 -0
  161. package/dist/lib/esm/type.mjs +83 -0
  162. package/dist/lib/esm/typescript-lib-state.d.mts +56 -0
  163. package/dist/lib/esm/typescript-lib-state.mjs +84 -0
  164. package/dist/lib/esm/url.d.mts +74 -0
  165. package/dist/lib/esm/url.mjs +94 -0
  166. package/dist/lib/esm/value-provider.d.mts +28 -0
  167. package/dist/lib/esm/value-provider.mjs +62 -0
  168. package/dist/lib/esm/value-wrapper.d.mts +47 -0
  169. package/dist/lib/esm/value-wrapper.mjs +106 -0
  170. package/package.json +111 -13
  171. package/transformers/date-transformer/package.json +6 -0
  172. package/transformers/group-transformer/package.json +6 -0
  173. package/transformers/index/package.json +6 -0
  174. package/transformers/map-transformer/package.json +6 -0
  175. package/transformers/package.json +6 -0
  176. package/transformers/set-transformer/package.json +6 -0
  177. package/transformers/skip-private-property-transformer/package.json +6 -0
  178. package/transformers/transformer/package.json +6 -0
  179. package/transformers/two-way-map-transformer/package.json +6 -0
  180. package/transformers/typed-transformer/package.json +6 -0
@@ -0,0 +1,567 @@
1
+ /*
2
+ THIS IS A GENERATED/BUNDLED FILE BY ESBUILD
3
+ if you want to view the source, please visit the github repository of this plugin
4
+ */
5
+
6
+ (function () {
7
+ function ensureDisposeSymbols(symbolConstructor = Symbol) {
8
+ symbolConstructor.asyncDispose ??= symbolConstructor.for('Symbol.asyncDispose');
9
+ symbolConstructor.dispose ??= symbolConstructor.for('Symbol.dispose');
10
+ }
11
+
12
+ function ensureBrowserProcess() {
13
+ const browserProcess = {
14
+ browser: true,
15
+ cwd() {
16
+ return '/';
17
+ },
18
+ env: {},
19
+ platform: 'android'
20
+ };
21
+
22
+ // eslint-disable-next-line obsidianmd/no-global-this, unicorn/no-unnecessary-global-this -- Must stay `globalThis`-qualified: in the emitted banner a bare `process` is a free identifier, so reading it where the host has none throws a ReferenceError instead of yielding `undefined`. That is the very case this function exists to handle.
23
+ const existingProcess = globalThis.process;
24
+
25
+ if (!existingProcess) {
26
+ // eslint-disable-next-line obsidianmd/no-global-this -- Actively use globalThis.
27
+ globalThis.process = browserProcess;
28
+ return;
29
+ }
30
+
31
+ if (existingProcess.versions?.node) {
32
+ return;
33
+ }
34
+
35
+ const existingProcessRecord = existingProcess;
36
+
37
+ for (const [key, value] of Object.entries(browserProcess)) {
38
+ existingProcessRecord[key] ??= value;
39
+ }
40
+
41
+ existingProcessRecord['browser'] = true;
42
+ }
43
+
44
+ (function initEsm() {
45
+ ensureDisposeSymbols();
46
+ ensureBrowserProcess();
47
+ })();
48
+ })();
49
+
50
+ import { errorToString } from "./error.mjs";
51
+ import { getFunctionExpressionString } from "./function.mjs";
52
+ import { escapeRegExp } from "./reg-exp.mjs";
53
+ import { replaceAll } from "./string.mjs";
54
+ import {
55
+ assertNever,
56
+ ensureGenericObject,
57
+ ensureNonNullable
58
+ } from "./type-guards.mjs";
59
+ var FunctionHandlingMode = /* @__PURE__ */ ((FunctionHandlingMode2) => {
60
+ FunctionHandlingMode2["Exclude"] = "exclude";
61
+ FunctionHandlingMode2["Full"] = "full";
62
+ FunctionHandlingMode2["NameOnly"] = "nameOnly";
63
+ return FunctionHandlingMode2;
64
+ })(FunctionHandlingMode || {});
65
+ const KEY_SEPARATOR = ".";
66
+ const PLACEHOLDER_KEY_PREFIX = "toJson:";
67
+ const equalityComparerEntries = [
68
+ createEqualityComparerEntry(ArrayBuffer, isDeepEqualArrayBuffer),
69
+ createEqualityComparerEntry(Date, isDeepEqualDate),
70
+ createEqualityComparerEntry(RegExp, isDeepEqualRegExp),
71
+ createEqualityComparerEntry(Map, isDeepEqualMap),
72
+ createEqualityComparerEntry(Set, isDeepEqualSet)
73
+ ];
74
+ class ToJsonConverter {
75
+ fullOptions;
76
+ functionTexts = [];
77
+ usedObjects = /* @__PURE__ */ new WeakSet();
78
+ /**
79
+ * Creates a new converter, resolving the provided options against the defaults.
80
+ *
81
+ * @param options - The options for the JSON conversion.
82
+ */
83
+ constructor(options) {
84
+ const DEFAULT_OPTIONS = {
85
+ functionHandlingMode: "exclude" /* Exclude */,
86
+ maxDepth: -1,
87
+ shouldCatchToJSONErrors: false,
88
+ shouldHandleCircularReferences: false,
89
+ shouldHandleErrors: false,
90
+ shouldHandleUndefined: false,
91
+ shouldSortKeys: false,
92
+ // eslint-disable-next-line no-magic-numbers -- Extracting magic number as a constant would be repetitive, as the value is used only once and its name would be the same as the property.
93
+ space: 2,
94
+ tokenSubstitutions: {
95
+ circularReference: makeObjectTokenSubstitution("CircularReference" /* CircularReference */),
96
+ maxDepthLimitReached: makeObjectTokenSubstitution("MaxDepthLimitReached" /* MaxDepthLimitReached */),
97
+ toJSONFailed: makeObjectTokenSubstitution("ToJSONFailed" /* ToJSONFailed */)
98
+ }
99
+ };
100
+ const fullOptions = {
101
+ ...DEFAULT_OPTIONS,
102
+ ...options,
103
+ tokenSubstitutions: {
104
+ ...DEFAULT_OPTIONS.tokenSubstitutions,
105
+ ...options.tokenSubstitutions
106
+ }
107
+ };
108
+ if (fullOptions.maxDepth === -1) {
109
+ fullOptions.maxDepth = Infinity;
110
+ }
111
+ this.fullOptions = fullOptions;
112
+ }
113
+ /**
114
+ * Converts the given value to a JSON string, applying the configured token substitutions.
115
+ *
116
+ * @param value - The value to convert.
117
+ * @returns The JSON string representation of the value.
118
+ */
119
+ convert(value) {
120
+ const plainObject = this.toPlainObject({
121
+ canUseToJSON: true,
122
+ depth: 0,
123
+ key: "",
124
+ value
125
+ });
126
+ let json = ensureNonNullable(JSON.stringify(plainObject, null, this.fullOptions.space));
127
+ const placeholderRegExp = new RegExp(String.raw`"\[\[${escapeRegExp(PLACEHOLDER_KEY_PREFIX)}(?<Key>[A-Za-z]+)(?<Index>\d*)\]\]"`, "g");
128
+ json = replaceAll({
129
+ $string: json,
130
+ replacer: ({ capturedGroupArguments: [key = "", indexString = ""] }) => applySubstitutions({
131
+ functionTexts: this.functionTexts,
132
+ index: indexString ? parseInt(indexString, 10) : 0,
133
+ key: castTo(key),
134
+ substitutions: this.fullOptions.tokenSubstitutions
135
+ }),
136
+ searchValue: placeholderRegExp
137
+ });
138
+ return json;
139
+ }
140
+ handleArray(params) {
141
+ const {
142
+ canUseToJSON,
143
+ depth,
144
+ value
145
+ } = params;
146
+ return depth > this.fullOptions.maxDepth ? makePlaceholder("MaxDepthLimitReachedArray" /* MaxDepthLimitReachedArray */, value.length) : value.map(
147
+ (item, index) => this.toPlainObject({
148
+ canUseToJSON,
149
+ depth: depth + 1,
150
+ key: String(index),
151
+ value: item
152
+ })
153
+ );
154
+ }
155
+ handleCircularReference(value, key) {
156
+ if (this.fullOptions.shouldHandleCircularReferences) {
157
+ return makePlaceholder("CircularReference" /* CircularReference */);
158
+ }
159
+ const valueConstructorName = value.constructor.name || "Object";
160
+ throw new TypeError(`Converting circular structure to JSON
161
+ --> starting at object with constructor '${valueConstructorName}'
162
+ --- property '${key}' closes the circle`);
163
+ }
164
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type -- We need to use `Function` type to handle them separately.
165
+ handleFunction(value) {
166
+ if (this.fullOptions.functionHandlingMode === "exclude" /* Exclude */) {
167
+ return void 0;
168
+ }
169
+ const index = this.functionTexts.length;
170
+ const functionText = this.fullOptions.functionHandlingMode === "full" /* Full */ ? getFunctionExpressionString(value) : `function ${value.name || "anonymous"}() { /* ... */ }`;
171
+ this.functionTexts.push(functionText);
172
+ return makePlaceholder("Function" /* Function */, index);
173
+ }
174
+ handleObject(params) {
175
+ const {
176
+ canUseToJSON,
177
+ depth,
178
+ key,
179
+ value
180
+ } = params;
181
+ if (this.usedObjects.has(value)) {
182
+ return this.handleCircularReference(value, key);
183
+ }
184
+ this.usedObjects.add(value);
185
+ if (canUseToJSON) {
186
+ const toJSONResult = this.tryHandleToJSON({
187
+ depth,
188
+ key,
189
+ value
190
+ });
191
+ if (toJSONResult !== void 0) {
192
+ return toJSONResult;
193
+ }
194
+ }
195
+ if (Array.isArray(value)) {
196
+ return this.handleArray({
197
+ canUseToJSON,
198
+ depth,
199
+ value
200
+ });
201
+ }
202
+ if (depth > this.fullOptions.maxDepth) {
203
+ return makePlaceholder("MaxDepthLimitReached" /* MaxDepthLimitReached */);
204
+ }
205
+ return value instanceof Error && this.fullOptions.shouldHandleErrors ? errorToString(value) : this.handlePlainObject({
206
+ canUseToJSON,
207
+ depth,
208
+ value
209
+ });
210
+ }
211
+ handlePlainObject(params) {
212
+ const {
213
+ canUseToJSON,
214
+ depth,
215
+ value
216
+ } = params;
217
+ const entries = Object.entries(value);
218
+ if (this.fullOptions.shouldSortKeys) {
219
+ entries.sort(([key1], [key2]) => key1.localeCompare(key2));
220
+ }
221
+ return Object.fromEntries(
222
+ entries.map(([key2, value2]) => [
223
+ key2,
224
+ this.toPlainObject({
225
+ canUseToJSON,
226
+ depth: depth + 1,
227
+ key: key2,
228
+ value: value2
229
+ })
230
+ ])
231
+ );
232
+ }
233
+ toPlainObject(params) {
234
+ const {
235
+ canUseToJSON,
236
+ depth,
237
+ key,
238
+ value
239
+ } = params;
240
+ if (value === void 0) {
241
+ return depth === 0 || this.fullOptions.shouldHandleUndefined ? makePlaceholder("Undefined" /* Undefined */) : void 0;
242
+ }
243
+ if (typeof value === "function") {
244
+ return this.handleFunction(value);
245
+ }
246
+ return typeof value !== "object" || value === null ? value : this.handleObject({
247
+ canUseToJSON,
248
+ depth,
249
+ key,
250
+ value
251
+ });
252
+ }
253
+ tryHandleToJSON(params) {
254
+ const {
255
+ depth,
256
+ key,
257
+ value
258
+ } = params;
259
+ const toJSON = value.toJSON;
260
+ if (typeof toJSON === "function") {
261
+ try {
262
+ const newValue = toJSON.call(value, key);
263
+ return this.toPlainObject({
264
+ canUseToJSON: false,
265
+ depth,
266
+ key,
267
+ value: newValue
268
+ });
269
+ } catch (error) {
270
+ if (this.fullOptions.shouldCatchToJSONErrors) {
271
+ return makePlaceholder("ToJSONFailed" /* ToJSONFailed */);
272
+ }
273
+ throw error;
274
+ }
275
+ }
276
+ return void 0;
277
+ }
278
+ }
279
+ function assignWithNonEnumerableProperties(target, ...sources) {
280
+ return assignWithNonEnumerablePropertiesImpl(target, ...sources);
281
+ }
282
+ function castTo(value) {
283
+ return value;
284
+ }
285
+ function cloneWithNonEnumerableProperties($object) {
286
+ return Object.create(getPrototypeOf($object), Object.getOwnPropertyDescriptors($object));
287
+ }
288
+ function deleteProperties($object, propertyNames) {
289
+ let hasDeletedAny = false;
290
+ for (const propertyName of propertyNames) {
291
+ hasDeletedAny = deleteProperty($object, propertyName) || hasDeletedAny;
292
+ }
293
+ return hasDeletedAny;
294
+ }
295
+ function deleteProperty($object, propertyName) {
296
+ if (!Object.hasOwn($object, propertyName)) {
297
+ return false;
298
+ }
299
+ delete $object[propertyName];
300
+ return true;
301
+ }
302
+ function extractDefaultExportInterop(module) {
303
+ if (typeof module !== "object" || module === null) {
304
+ return module;
305
+ }
306
+ return "default" in module ? module.default : module;
307
+ }
308
+ function getAllEntries($object) {
309
+ return getAllKeys($object).map((key) => [key, $object[key]]);
310
+ }
311
+ function getAllKeys($object) {
312
+ const keys = [];
313
+ let current = $object;
314
+ while (current) {
315
+ const descriptors = Object.getOwnPropertyDescriptors(current);
316
+ for (const [key, descriptor] of Object.entries(descriptors)) {
317
+ if (key === "__proto__" || typeof descriptor.value === "function") {
318
+ continue;
319
+ }
320
+ const hasGetter = typeof descriptor.get === "function";
321
+ const hasSetter = typeof descriptor.set === "function";
322
+ if (hasGetter || hasSetter) {
323
+ if (hasGetter && hasSetter) {
324
+ keys.push(key);
325
+ }
326
+ continue;
327
+ }
328
+ if (descriptor.enumerable && descriptor.writable) {
329
+ keys.push(key);
330
+ }
331
+ }
332
+ current = Object.getPrototypeOf(current);
333
+ }
334
+ return keys.sort();
335
+ }
336
+ function getNestedPropertyValue($object, path) {
337
+ let node = $object;
338
+ const keys = path.split(KEY_SEPARATOR);
339
+ for (const key of keys) {
340
+ if (node === void 0) {
341
+ return void 0;
342
+ }
343
+ node = node[key];
344
+ }
345
+ return node;
346
+ }
347
+ function getPrototypeOf(instance) {
348
+ return instance === void 0 || instance === null ? instance : Object.getPrototypeOf(instance);
349
+ }
350
+ function isDeepEqual(a, b) {
351
+ if (a === b) {
352
+ return true;
353
+ }
354
+ if (typeof a !== "object" || typeof b !== "object" || a === null || b === null) {
355
+ return false;
356
+ }
357
+ const aConstructor = a.constructor;
358
+ const bConstructor = b.constructor;
359
+ if (aConstructor !== bConstructor) {
360
+ return false;
361
+ }
362
+ if (aConstructor !== Object) {
363
+ const result = deepEqualTyped(a, b);
364
+ if (result !== void 0) {
365
+ return result;
366
+ }
367
+ }
368
+ const keysA = getAllKeys(a);
369
+ const keysB = getAllKeys(b);
370
+ if (keysA.length !== keysB.length) {
371
+ return false;
372
+ }
373
+ const aRecord = ensureGenericObject(a);
374
+ const bRecord = ensureGenericObject(b);
375
+ for (const key of keysA) {
376
+ if (!keysB.includes(key) || !isDeepEqual(aRecord[key], bRecord[key])) {
377
+ return false;
378
+ }
379
+ }
380
+ return true;
381
+ }
382
+ function nameof(name) {
383
+ return name;
384
+ }
385
+ function normalizeOptionalProperties($object) {
386
+ return $object;
387
+ }
388
+ function removeUndefinedProperties($object, keysToKeep) {
389
+ for (const [key, value] of Object.entries($object)) {
390
+ if (value === void 0 && !keysToKeep?.includes(key)) {
391
+ delete $object[key];
392
+ }
393
+ }
394
+ return $object;
395
+ }
396
+ function setNestedPropertyValue(params) {
397
+ const {
398
+ $object,
399
+ path,
400
+ value
401
+ } = params;
402
+ const error = new Error(`Property path ${path} not found`);
403
+ let node = $object;
404
+ const keys = path.split(KEY_SEPARATOR);
405
+ for (const key of keys.slice(0, -1)) {
406
+ if (node === void 0) {
407
+ throw error;
408
+ }
409
+ node = node[key];
410
+ }
411
+ const lastKey = ensureNonNullable(keys.at(-1));
412
+ if (node === void 0) {
413
+ throw error;
414
+ }
415
+ node[lastKey] = value;
416
+ }
417
+ function toJson(value, options = {}) {
418
+ return new ToJsonConverter(options).convert(value);
419
+ }
420
+ function applySubstitutions(params) {
421
+ switch (params.key) {
422
+ case "CircularReference" /* CircularReference */: {
423
+ return params.substitutions.circularReference;
424
+ }
425
+ case "Function" /* Function */: {
426
+ return ensureNonNullable(params.functionTexts[params.index], `Function with index ${String(params.index)} not found`);
427
+ }
428
+ case "MaxDepthLimitReached" /* MaxDepthLimitReached */: {
429
+ return params.substitutions.maxDepthLimitReached;
430
+ }
431
+ case "MaxDepthLimitReachedArray" /* MaxDepthLimitReachedArray */: {
432
+ return `Array(${String(params.index)})`;
433
+ }
434
+ case "ToJSONFailed" /* ToJSONFailed */: {
435
+ return params.substitutions.toJSONFailed;
436
+ }
437
+ case "Undefined" /* Undefined */: {
438
+ return "undefined";
439
+ }
440
+ /* v8 ignore start -- Exhaustive switch guard; default branch is unreachable. */
441
+ default: {
442
+ assertNever(params.key);
443
+ }
444
+ }
445
+ }
446
+ function assignWithNonEnumerablePropertiesImpl(target, ...sources) {
447
+ for (const source of sources) {
448
+ const descriptors = Object.getOwnPropertyDescriptors(source);
449
+ for (const [key, descriptor] of Object.entries(descriptors)) {
450
+ try {
451
+ if (key === "prototype" || Object.getOwnPropertyDescriptor(target, key)?.writable === false && !Object.getOwnPropertyDescriptor(target, key)?.configurable) {
452
+ continue;
453
+ }
454
+ Object.defineProperty(target, key, descriptor);
455
+ } catch {
456
+ }
457
+ }
458
+ }
459
+ const sourcePrototypes = sources.map((source) => getPrototypeOf(source)).filter((prototype) => !!prototype);
460
+ if (sourcePrototypes.length > 0) {
461
+ const targetPrototype = assignWithNonEnumerablePropertiesImpl({}, getPrototypeOf(target), ...sourcePrototypes);
462
+ try {
463
+ Object.setPrototypeOf(target, targetPrototype);
464
+ } catch {
465
+ }
466
+ }
467
+ return target;
468
+ }
469
+ function createEqualityComparerEntry(constructor, checkIsEqual) {
470
+ return {
471
+ constructor,
472
+ equalityComparer: (a, b) => checkIsEqual(a, b)
473
+ };
474
+ }
475
+ function deepEqualTyped(a, b) {
476
+ for (const entry of equalityComparerEntries) {
477
+ const result = tryEntryEquality({
478
+ a,
479
+ b,
480
+ entry
481
+ });
482
+ if (result !== void 0) {
483
+ return result;
484
+ }
485
+ }
486
+ return void 0;
487
+ }
488
+ function isDeepEqualArrayBuffer(a, b) {
489
+ if (a.byteLength !== b.byteLength) {
490
+ return false;
491
+ }
492
+ const viewA = new Uint8Array(a);
493
+ const viewB = new Uint8Array(b);
494
+ return isDeepEqual(viewA, viewB);
495
+ }
496
+ function isDeepEqualDate(a, b) {
497
+ return a.getTime() === b.getTime();
498
+ }
499
+ function isDeepEqualMap(a, b) {
500
+ if (a.size !== b.size) {
501
+ return false;
502
+ }
503
+ for (const [key, value] of a) {
504
+ if (!b.has(key) || !isDeepEqual(value, b.get(key))) {
505
+ return false;
506
+ }
507
+ }
508
+ return true;
509
+ }
510
+ function isDeepEqualRegExp(a, b) {
511
+ return a.source === b.source && a.flags === b.flags;
512
+ }
513
+ function isDeepEqualSet(a, b) {
514
+ if (a.size !== b.size) {
515
+ return false;
516
+ }
517
+ for (const valueA of a) {
518
+ if (b.has(valueA)) {
519
+ continue;
520
+ }
521
+ let hasMatch = false;
522
+ for (const valueB of b) {
523
+ if (isDeepEqual(valueA, valueB)) {
524
+ hasMatch = true;
525
+ break;
526
+ }
527
+ }
528
+ if (!hasMatch) {
529
+ return false;
530
+ }
531
+ }
532
+ return true;
533
+ }
534
+ function makeObjectTokenSubstitution(key) {
535
+ return `{ "[[${key}]]": null }`;
536
+ }
537
+ function makePlaceholder(key, index) {
538
+ return `[[${PLACEHOLDER_KEY_PREFIX}${key}${index ? String(index) : ""}]]`;
539
+ }
540
+ function tryEntryEquality(params) {
541
+ const {
542
+ a,
543
+ b,
544
+ entry
545
+ } = params;
546
+ return a instanceof entry.constructor && b instanceof entry.constructor ? entry.equalityComparer(a, b) : void 0;
547
+ }
548
+ export {
549
+ FunctionHandlingMode,
550
+ assignWithNonEnumerableProperties,
551
+ castTo,
552
+ cloneWithNonEnumerableProperties,
553
+ deleteProperties,
554
+ deleteProperty,
555
+ extractDefaultExportInterop,
556
+ getAllEntries,
557
+ getAllKeys,
558
+ getNestedPropertyValue,
559
+ getPrototypeOf,
560
+ isDeepEqual,
561
+ nameof,
562
+ normalizeOptionalProperties,
563
+ removeUndefinedProperties,
564
+ setNestedPropertyValue,
565
+ toJson
566
+ };
567
+ //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vc3JjL29iamVjdC11dGlscy50cyJdLAogICJzb3VyY2VzQ29udGVudCI6IFsiLyoqXG4gKiBAZmlsZVxuICpcbiAqIENvbnRhaW5zIHV0aWxpdHkgZnVuY3Rpb25zIGZvciBPYmplY3RzLlxuICovXG5cbmltcG9ydCB0eXBlIHtcbiAgQ29uc3RydWN0b3IsXG4gIFJlcXVpcmVkS2V5c09mLFxuICBVbmRlZmluZWRPblBhcnRpYWxEZWVwXG59IGZyb20gJ3R5cGUtZmVzdCc7XG5cbmltcG9ydCB0eXBlIHsgR2VuZXJpY09iamVjdCB9IGZyb20gJy4vdHlwZS1ndWFyZHMudHMnO1xuaW1wb3J0IHR5cGUge1xuICBFeGFjdE1lbWJlcnMsXG4gIE1heWJlUmV0dXJuLFxuICBTdHJpbmdLZXlzXG59IGZyb20gJy4vdHlwZS50cyc7XG5cbmltcG9ydCB7IGVycm9yVG9TdHJpbmcgfSBmcm9tICcuL2Vycm9yLnRzJztcbmltcG9ydCB7IGdldEZ1bmN0aW9uRXhwcmVzc2lvblN0cmluZyB9IGZyb20gJy4vZnVuY3Rpb24udHMnO1xuaW1wb3J0IHsgZXNjYXBlUmVnRXhwIH0gZnJvbSAnLi9yZWctZXhwLnRzJztcbmltcG9ydCB7IHJlcGxhY2VBbGwgfSBmcm9tICcuL3N0cmluZy50cyc7XG5pbXBvcnQge1xuICBhc3NlcnROZXZlcixcbiAgZW5zdXJlR2VuZXJpY09iamVjdCxcbiAgZW5zdXJlTm9uTnVsbGFibGVcbn0gZnJvbSAnLi90eXBlLWd1YXJkcy50cyc7XG5cbi8qKlxuICogU3BlY2lmaWVzIGhvdyBmdW5jdGlvbnMgc2hvdWxkIGJlIGhhbmRsZWQgaW4gdGhlIEpTT04gb3V0cHV0LlxuICovXG5leHBvcnQgZW51bSBGdW5jdGlvbkhhbmRsaW5nTW9kZSB7XG4gIC8qKlxuICAgKiBFeGNsdWRlcyBmdW5jdGlvbnMgZnJvbSB0aGUgSlNPTiBvdXRwdXQuXG4gICAqL1xuICBFeGNsdWRlID0gJ2V4Y2x1ZGUnLFxuICAvKipcbiAgICogSW5jbHVkZXMgdGhlIGZ1bGwgZnVuY3Rpb24gZGVmaW5pdGlvbiBpbiB0aGUgSlNPTiBvdXRwdXQuXG4gICAqL1xuICBGdWxsID0gJ2Z1bGwnLFxuICAvKipcbiAgICogSW5jbHVkZXMgb25seSB0aGUgZnVuY3Rpb24gbmFtZSBpbiB0aGUgSlNPTiBvdXRwdXQuXG4gICAqL1xuICBOYW1lT25seSA9ICduYW1lT25seSdcbn1cblxuZW51bSBUb2tlblN1YnN0aXR1dGlvbktleSB7XG4gIENpcmN1bGFyUmVmZXJlbmNlID0gJ0NpcmN1bGFyUmVmZXJlbmNlJyxcbiAgRnVuY3Rpb24gPSAnRnVuY3Rpb24nLFxuICBNYXhEZXB0aExpbWl0UmVhY2hlZCA9ICdNYXhEZXB0aExpbWl0UmVhY2hlZCcsXG4gIE1heERlcHRoTGltaXRSZWFjaGVkQXJyYXkgPSAnTWF4RGVwdGhMaW1pdFJlYWNoZWRBcnJheScsXG4gIFRvSlNPTkZhaWxlZCA9ICdUb0pTT05GYWlsZWQnLFxuICBVbmRlZmluZWQgPSAnVW5kZWZpbmVkJ1xufVxuXG4vKipcbiAqIE9wdGlvbnMgZm9yIHtAbGluayB0b0pzb259LlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFRvSnNvbk9wdGlvbnMge1xuICAvKipcbiAgICogU3BlY2lmaWVzIGhvdyBmdW5jdGlvbnMgc2hvdWxkIGJlIGhhbmRsZWQgaW4gdGhlIEpTT04gb3V0cHV0LlxuICAgKlxuICAgKiBAZGVmYXVsdCB7QGxpbmsgRnVuY3Rpb25IYW5kbGluZ01vZGUuRXhjbHVkZX1cbiAgICovXG4gIHJlYWRvbmx5IGZ1bmN0aW9uSGFuZGxpbmdNb2RlOiBGdW5jdGlvbkhhbmRsaW5nTW9kZTtcblxuICAvKipcbiAgICogU3BlY2lmaWVzIHRoZSBtYXhpbXVtIGRlcHRoIG9mIG5lc3RlZCBvYmplY3RzIHRvIGluY2x1ZGUgaW4gdGhlIEpTT04gb3V0cHV0LlxuICAgKiBVc2UgYC0xYCBmb3Igbm8gbGltaXQuXG4gICAqXG4gICAqIEBkZWZhdWx0IGAtMWBcbiAgICovXG4gIHJlYWRvbmx5IG1heERlcHRoOiBudW1iZXI7XG5cbiAgLyoqXG4gICAqIFNwZWNpZmllcyB3aGV0aGVyIHRvIGNhdGNoIGVycm9ycyBpbiBgdG9KU09OKClgIGFuZCByZXBsYWNlIHRoZW0gd2l0aCBhIHBsYWNlaG9sZGVyLlxuICAgKlxuICAgKiBAZGVmYXVsdCBgZmFsc2VgXG4gICAqL1xuICByZWFkb25seSBzaG91bGRDYXRjaFRvSlNPTkVycm9yczogYm9vbGVhbjtcblxuICAvKipcbiAgICogU3BlY2lmaWVzIHdoZXRoZXIgdG8gaGFuZGxlIGNpcmN1bGFyIHJlZmVyZW5jZXMgaW4gdGhlIEpTT04gb3V0cHV0LlxuICAgKlxuICAgKiBAZGVmYXVsdCBgZmFsc2VgXG4gICAqL1xuICByZWFkb25seSBzaG91bGRIYW5kbGVDaXJjdWxhclJlZmVyZW5jZXM6IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIFNwZWNpZmllcyB3aGV0aGVyIHRvIGhhbmRsZSBlcnJvcnMgaW4gdGhlIEpTT04gb3V0cHV0LlxuICAgKlxuICAgKiBAZGVmYXVsdCBgZmFsc2VgXG4gICAqL1xuICByZWFkb25seSBzaG91bGRIYW5kbGVFcnJvcnM6IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIFNwZWNpZmllcyB3aGV0aGVyIHRvIGhhbmRsZSBgdW5kZWZpbmVkYCB2YWx1ZXMgaW4gdGhlIEpTT04gb3V0cHV0LlxuICAgKlxuICAgKiBAZGVmYXVsdCBgZmFsc2VgXG4gICAqL1xuICByZWFkb25seSBzaG91bGRIYW5kbGVVbmRlZmluZWQ6IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIFNwZWNpZmllcyB3aGV0aGVyIHRvIHNvcnQgdGhlIGtleXMgb2YgdGhlIEpTT04gb3V0cHV0LlxuICAgKlxuICAgKiBAZGVmYXVsdCBgZmFsc2VgXG4gICAqL1xuICByZWFkb25seSBzaG91bGRTb3J0S2V5czogYm9vbGVhbjtcblxuICAvKipcbiAgICogU3BlY2lmaWVzIHRoZSBpbmRlbnRhdGlvbiBvZiB0aGUgSlNPTiBvdXRwdXQuIFRoaXMgY2FuIGJlIGEgbnVtYmVyIG9mIHNwYWNlcyBvciBhIHN0cmluZy5cbiAgICpcbiAgICogQGRlZmF1bHQgYDJgXG4gICAqL1xuICByZWFkb25seSBzcGFjZTogbnVtYmVyIHwgc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBTcGVjaWZpZXMgdGhlIHN1YnN0aXR1dGlvbnMgdG8gdXNlIGluIHRoZSBKU09OIG91dHB1dC5cbiAgICovXG4gIHJlYWRvbmx5IHRva2VuU3Vic3RpdHV0aW9uczogUGFydGlhbDxUb2tlblN1YnN0aXR1dGlvbnM+O1xufVxuXG5pbnRlcmZhY2UgQXBwbHlTdWJzdGl0dXRpb25zUGFyYW1zIHtcbiAgcmVhZG9ubHkgZnVuY3Rpb25UZXh0czogcmVhZG9ubHkgc3RyaW5nW107XG4gIHJlYWRvbmx5IGluZGV4OiBudW1iZXI7XG4gIHJlYWRvbmx5IGtleTogVG9rZW5TdWJzdGl0dXRpb25LZXk7XG4gIHJlYWRvbmx5IHN1YnN0aXR1dGlvbnM6IFRva2VuU3Vic3RpdHV0aW9ucztcbn1cblxuaW50ZXJmYWNlIEVxdWFsaXR5Q29tcGFyZXJFbnRyeTxUPiB7XG4gIGNvbnN0cnVjdG9yOiBDb25zdHJ1Y3RvcjxUPjtcbiAgZXF1YWxpdHlDb21wYXJlcjogKGE6IFQsIGI6IFQpID0+IGJvb2xlYW47XG59XG5cbmludGVyZmFjZSBKU09OU2VyaWFsaXphYmxlIHtcbiAgdG9KU09OOiAoLi4uJGFyZ3VtZW50czogdW5rbm93bltdKSA9PiB1bmtub3duO1xufVxuXG5pbnRlcmZhY2UgTW9kdWxlV2l0aERlZmF1bHRFeHBvcnQ8VD4ge1xuICBkZWZhdWx0OiBUO1xufVxuXG5pbnRlcmZhY2UgUmVzb2x2ZWRUb0pzb25PcHRpb25zIGV4dGVuZHMgVG9Kc29uT3B0aW9ucyB7XG4gIHJlYWRvbmx5IHRva2VuU3Vic3RpdHV0aW9uczogVG9rZW5TdWJzdGl0dXRpb25zO1xufVxuXG5pbnRlcmZhY2UgVG9rZW5TdWJzdGl0dXRpb25zIHtcbiAgY2lyY3VsYXJSZWZlcmVuY2U6IHN0cmluZztcbiAgbWF4RGVwdGhMaW1pdFJlYWNoZWQ6IHN0cmluZztcbiAgdG9KU09ORmFpbGVkOiBzdHJpbmc7XG59XG5cbmNvbnN0IEtFWV9TRVBBUkFUT1IgPSAnLic7XG5jb25zdCBQTEFDRUhPTERFUl9LRVlfUFJFRklYID0gJ3RvSnNvbjonO1xuY29uc3QgZXF1YWxpdHlDb21wYXJlckVudHJpZXM6IHJlYWRvbmx5IEVxdWFsaXR5Q29tcGFyZXJFbnRyeTx1bmtub3duPltdID0gW1xuICBjcmVhdGVFcXVhbGl0eUNvbXBhcmVyRW50cnkoQXJyYXlCdWZmZXIsIGlzRGVlcEVxdWFsQXJyYXlCdWZmZXIpLFxuICBjcmVhdGVFcXVhbGl0eUNvbXBhcmVyRW50cnkoRGF0ZSwgaXNEZWVwRXF1YWxEYXRlKSxcbiAgY3JlYXRlRXF1YWxpdHlDb21wYXJlckVudHJ5KFJlZ0V4cCwgaXNEZWVwRXF1YWxSZWdFeHApLFxuICBjcmVhdGVFcXVhbGl0eUNvbXBhcmVyRW50cnk8TWFwPHVua25vd24sIHVua25vd24+PihNYXAsIGlzRGVlcEVxdWFsTWFwKSxcbiAgY3JlYXRlRXF1YWxpdHlDb21wYXJlckVudHJ5PFNldDx1bmtub3duPj4oU2V0LCBpc0RlZXBFcXVhbFNldClcbl07XG5cbi8qKlxuICogUGFyYW1ldGVycyBmb3Ige0BsaW5rIHNldE5lc3RlZFByb3BlcnR5VmFsdWV9LlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFNldE5lc3RlZFByb3BlcnR5VmFsdWVQYXJhbXMge1xuICAvKipcbiAgICogVGhlIG9iamVjdCB0byBzZXQgdGhlIG5lc3RlZCBwcm9wZXJ0eSB2YWx1ZSBpbi5cbiAgICovXG4gIHJlYWRvbmx5ICRvYmplY3Q6IEdlbmVyaWNPYmplY3Q7XG5cbiAgLyoqXG4gICAqIFRoZSBwYXRoIHRvIHRoZSBuZXN0ZWQgcHJvcGVydHkuXG4gICAqL1xuICByZWFkb25seSBwYXRoOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFRoZSB2YWx1ZSB0byBzZXQuXG4gICAqL1xuICByZWFkb25seSB2YWx1ZTogdW5rbm93bjtcbn1cblxuaW50ZXJmYWNlIEhhbmRsZUFycmF5UGFyYW1zIHtcbiAgLyoqXG4gICAqIFdoZXRoZXIgYHRvSlNPTigpYCBtYXkgYmUgdXNlZCBkdXJpbmcgY29udmVyc2lvbi5cbiAgICovXG4gIHJlYWRvbmx5IGNhblVzZVRvSlNPTjogYm9vbGVhbjtcblxuICAvKipcbiAgICogVGhlIGN1cnJlbnQgcmVjdXJzaW9uIGRlcHRoLlxuICAgKi9cbiAgcmVhZG9ubHkgZGVwdGg6IG51bWJlcjtcblxuICAvKipcbiAgICogVGhlIGFycmF5IHZhbHVlIHRvIGNvbnZlcnQuXG4gICAqL1xuICByZWFkb25seSB2YWx1ZTogdW5rbm93bltdO1xufVxuXG5pbnRlcmZhY2UgSGFuZGxlT2JqZWN0UGFyYW1zIHtcbiAgLyoqXG4gICAqIFdoZXRoZXIgYHRvSlNPTigpYCBtYXkgYmUgdXNlZCBkdXJpbmcgY29udmVyc2lvbi5cbiAgICovXG4gIHJlYWRvbmx5IGNhblVzZVRvSlNPTjogYm9vbGVhbjtcblxuICAvKipcbiAgICogVGhlIGN1cnJlbnQgcmVjdXJzaW9uIGRlcHRoLlxuICAgKi9cbiAgcmVhZG9ubHkgZGVwdGg6IG51bWJlcjtcblxuICAvKipcbiAgICogVGhlIGtleSB1bmRlciB3aGljaCB0aGUgdmFsdWUgaXMgc3RvcmVkIGluIGl0cyBwYXJlbnQuXG4gICAqL1xuICByZWFkb25seSBrZXk6IHN0cmluZztcblxuICAvKipcbiAgICogVGhlIG9iamVjdCB2YWx1ZSB0byBjb252ZXJ0LlxuICAgKi9cbiAgcmVhZG9ubHkgdmFsdWU6IG9iamVjdDtcbn1cblxuaW50ZXJmYWNlIEhhbmRsZVBsYWluT2JqZWN0UGFyYW1zIHtcbiAgLyoqXG4gICAqIFdoZXRoZXIgYHRvSlNPTigpYCBtYXkgYmUgdXNlZCBkdXJpbmcgY29udmVyc2lvbi5cbiAgICovXG4gIHJlYWRvbmx5IGNhblVzZVRvSlNPTjogYm9vbGVhbjtcblxuICAvKipcbiAgICogVGhlIGN1cnJlbnQgcmVjdXJzaW9uIGRlcHRoLlxuICAgKi9cbiAgcmVhZG9ubHkgZGVwdGg6IG51bWJlcjtcblxuICAvKipcbiAgICogVGhlIHBsYWluIG9iamVjdCB2YWx1ZSB0byBjb252ZXJ0LlxuICAgKi9cbiAgcmVhZG9ubHkgdmFsdWU6IG9iamVjdDtcbn1cblxudHlwZSBLZXlzV2l0aFVuZGVmaW5lZDxUPiA9IEtleXNXaXRoVW5kZWZpbmVkTWFwPFQ+W2tleW9mIFRdO1xuXG50eXBlIEtleXNXaXRoVW5kZWZpbmVkTWFwPFQ+ID0ge1xuICBbSyBpbiBrZXlvZiBUXS0/OiB1bmRlZmluZWQgZXh0ZW5kcyBUW0tdID8gSyA6IG5ldmVyO1xufTtcbnR5cGUgTWFuZGF0b3J5S2V5c1dpdGhVbmRlZmluZWQ8VCBleHRlbmRzIG9iamVjdD4gPSBFeHRyYWN0PFJlcXVpcmVkS2V5c09mPFQ+ICYgU3RyaW5nS2V5czxUPiwgS2V5c1dpdGhVbmRlZmluZWQ8VD4+O1xudHlwZSBSZW1vdmVVbmRlZmluZWRPdmVybG9hZDxUIGV4dGVuZHMgb2JqZWN0PiA9IE1hbmRhdG9yeUtleXNXaXRoVW5kZWZpbmVkPFQ+IGV4dGVuZHMgbmV2ZXIgPyBbb2JqOiBUXVxuICA6IG5ldmVyO1xuXG50eXBlIFJlbW92ZVVuZGVmaW5lZFdpdGhLZXlzT3ZlcmxvYWQ8VCBleHRlbmRzIG9iamVjdCwgSyBleHRlbmRzIHJlYWRvbmx5IHN0cmluZ1tdPiA9IFtvYmo6IFQsIGtleXNUb0tlZXA6IEV4YWN0TWVtYmVyczxNYW5kYXRvcnlLZXlzV2l0aFVuZGVmaW5lZDxUPiwgSz5dO1xuXG5pbnRlcmZhY2UgVG9QbGFpbk9iamVjdFBhcmFtcyB7XG4gIC8qKlxuICAgKiBXaGV0aGVyIGB0b0pTT04oKWAgbWF5IGJlIHVzZWQgZHVyaW5nIGNvbnZlcnNpb24uXG4gICAqL1xuICByZWFkb25seSBjYW5Vc2VUb0pTT046IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIFRoZSBjdXJyZW50IHJlY3Vyc2lvbiBkZXB0aC5cbiAgICovXG4gIHJlYWRvbmx5IGRlcHRoOiBudW1iZXI7XG5cbiAgLyoqXG4gICAqIFRoZSBrZXkgdW5kZXIgd2hpY2ggdGhlIHZhbHVlIGlzIHN0b3JlZCBpbiBpdHMgcGFyZW50LlxuICAgKi9cbiAgcmVhZG9ubHkga2V5OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFRoZSB2YWx1ZSB0byBjb252ZXJ0LlxuICAgKi9cbiAgcmVhZG9ubHkgdmFsdWU6IHVua25vd247XG59XG5cbi8qKlxuICogUGFyYW1ldGVycyBmb3Ige0BsaW5rIHRyeUVudHJ5RXF1YWxpdHl9LlxuICovXG5pbnRlcmZhY2UgVHJ5RW50cnlFcXVhbGl0eVBhcmFtcyB7XG4gIC8qKlxuICAgKiBUaGUgZmlyc3QgdmFsdWUgdG8gY29tcGFyZS5cbiAgICovXG4gIHJlYWRvbmx5IGE6IHVua25vd247XG5cbiAgLyoqXG4gICAqIFRoZSBzZWNvbmQgdmFsdWUgdG8gY29tcGFyZS5cbiAgICovXG4gIHJlYWRvbmx5IGI6IHVua25vd247XG5cbiAgLyoqXG4gICAqIFRoZSBlcXVhbGl0eSBjb21wYXJlciBlbnRyeSB0byB1c2UuXG4gICAqL1xuICByZWFkb25seSBlbnRyeTogRXF1YWxpdHlDb21wYXJlckVudHJ5PHVua25vd24+O1xufVxuXG5pbnRlcmZhY2UgVHJ5SGFuZGxlVG9KU09OUGFyYW1zIHtcbiAgLyoqXG4gICAqIFRoZSBjdXJyZW50IHJlY3Vyc2lvbiBkZXB0aC5cbiAgICovXG4gIHJlYWRvbmx5IGRlcHRoOiBudW1iZXI7XG5cbiAgLyoqXG4gICAqIFRoZSBrZXkgdW5kZXIgd2hpY2ggdGhlIHZhbHVlIGlzIHN0b3JlZCBpbiBpdHMgcGFyZW50LlxuICAgKi9cbiAgcmVhZG9ubHkga2V5OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFRoZSBvYmplY3QgdmFsdWUgdG8gY29udmVydC5cbiAgICovXG4gIHJlYWRvbmx5IHZhbHVlOiBvYmplY3Q7XG59XG5cbi8qKlxuICogQ29udmVydHMgYSB2YWx1ZSB0byBhIEpTT04tc2VyaWFsaXphYmxlIHBsYWluIG9iamVjdCBhbmQgcmVuZGVycyBpdCBhcyBhIEpTT04gc3RyaW5nLlxuICpcbiAqIEEgZnJlc2ggaW5zdGFuY2UgaXMgY3JlYXRlZCBwZXIge0BsaW5rIHRvSnNvbn0gY2FsbCBzbyB0aGF0IHRoZSBhY2N1bXVsYXRlZCBgZnVuY3Rpb25UZXh0c2BcbiAqIGFuZCB0aGUgYHVzZWRPYmplY3RzYCBjaXJjdWxhci1yZWZlcmVuY2Ugc2V0IG5ldmVyIGxlYWsgYmV0d2VlbiBjb252ZXJzaW9ucy5cbiAqL1xuY2xhc3MgVG9Kc29uQ29udmVydGVyIHtcbiAgcHJpdmF0ZSByZWFkb25seSBmdWxsT3B0aW9uczogUmVzb2x2ZWRUb0pzb25PcHRpb25zO1xuICBwcml2YXRlIHJlYWRvbmx5IGZ1bmN0aW9uVGV4dHM6IHN0cmluZ1tdID0gW107XG4gIHByaXZhdGUgcmVhZG9ubHkgdXNlZE9iamVjdHMgPSBuZXcgV2Vha1NldCgpO1xuXG4gIC8qKlxuICAgKiBDcmVhdGVzIGEgbmV3IGNvbnZlcnRlciwgcmVzb2x2aW5nIHRoZSBwcm92aWRlZCBvcHRpb25zIGFnYWluc3QgdGhlIGRlZmF1bHRzLlxuICAgKlxuICAgKiBAcGFyYW0gb3B0aW9ucyAtIFRoZSBvcHRpb25zIGZvciB0aGUgSlNPTiBjb252ZXJzaW9uLlxuICAgKi9cbiAgcHVibGljIGNvbnN0cnVjdG9yKG9wdGlvbnM6IFBhcnRpYWw8VG9Kc29uT3B0aW9ucz4pIHtcbiAgICBjb25zdCBERUZBVUxUX09QVElPTlM6IFJlc29sdmVkVG9Kc29uT3B0aW9ucyA9IHtcbiAgICAgIGZ1bmN0aW9uSGFuZGxpbmdNb2RlOiBGdW5jdGlvbkhhbmRsaW5nTW9kZS5FeGNsdWRlLFxuICAgICAgbWF4RGVwdGg6IC0xLFxuICAgICAgc2hvdWxkQ2F0Y2hUb0pTT05FcnJvcnM6IGZhbHNlLFxuICAgICAgc2hvdWxkSGFuZGxlQ2lyY3VsYXJSZWZlcmVuY2VzOiBmYWxzZSxcbiAgICAgIHNob3VsZEhhbmRsZUVycm9yczogZmFsc2UsXG4gICAgICBzaG91bGRIYW5kbGVVbmRlZmluZWQ6IGZhbHNlLFxuICAgICAgc2hvdWxkU29ydEtleXM6IGZhbHNlLFxuICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLW1hZ2ljLW51bWJlcnMgLS0gRXh0cmFjdGluZyBtYWdpYyBudW1iZXIgYXMgYSBjb25zdGFudCB3b3VsZCBiZSByZXBldGl0aXZlLCBhcyB0aGUgdmFsdWUgaXMgdXNlZCBvbmx5IG9uY2UgYW5kIGl0cyBuYW1lIHdvdWxkIGJlIHRoZSBzYW1lIGFzIHRoZSBwcm9wZXJ0eS5cbiAgICAgIHNwYWNlOiAyLFxuICAgICAgdG9rZW5TdWJzdGl0dXRpb25zOiB7XG4gICAgICAgIGNpcmN1bGFyUmVmZXJlbmNlOiBtYWtlT2JqZWN0VG9rZW5TdWJzdGl0dXRpb24oVG9rZW5TdWJzdGl0dXRpb25LZXkuQ2lyY3VsYXJSZWZlcmVuY2UpLFxuICAgICAgICBtYXhEZXB0aExpbWl0UmVhY2hlZDogbWFrZU9iamVjdFRva2VuU3Vic3RpdHV0aW9uKFRva2VuU3Vic3RpdHV0aW9uS2V5Lk1heERlcHRoTGltaXRSZWFjaGVkKSxcbiAgICAgICAgdG9KU09ORmFpbGVkOiBtYWtlT2JqZWN0VG9rZW5TdWJzdGl0dXRpb24oVG9rZW5TdWJzdGl0dXRpb25LZXkuVG9KU09ORmFpbGVkKVxuICAgICAgfVxuICAgIH07XG5cbiAgICBjb25zdCBmdWxsT3B0aW9ucyA9IHtcbiAgICAgIC4uLkRFRkFVTFRfT1BUSU9OUyxcbiAgICAgIC4uLm9wdGlvbnMsXG4gICAgICB0b2tlblN1YnN0aXR1dGlvbnM6IHtcbiAgICAgICAgLi4uREVGQVVMVF9PUFRJT05TLnRva2VuU3Vic3RpdHV0aW9ucyxcbiAgICAgICAgLi4ub3B0aW9ucy50b2tlblN1YnN0aXR1dGlvbnNcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgaWYgKGZ1bGxPcHRpb25zLm1heERlcHRoID09PSAtMSkge1xuICAgICAgZnVsbE9wdGlvbnMubWF4RGVwdGggPSBJbmZpbml0eTtcbiAgICB9XG5cbiAgICB0aGlzLmZ1bGxPcHRpb25zID0gZnVsbE9wdGlvbnM7XG4gIH1cblxuICAvKipcbiAgICogQ29udmVydHMgdGhlIGdpdmVuIHZhbHVlIHRvIGEgSlNPTiBzdHJpbmcsIGFwcGx5aW5nIHRoZSBjb25maWd1cmVkIHRva2VuIHN1YnN0aXR1dGlvbnMuXG4gICAqXG4gICAqIEBwYXJhbSB2YWx1ZSAtIFRoZSB2YWx1ZSB0byBjb252ZXJ0LlxuICAgKiBAcmV0dXJucyBUaGUgSlNPTiBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhlIHZhbHVlLlxuICAgKi9cbiAgcHVibGljIGNvbnZlcnQodmFsdWU6IHVua25vd24pOiBzdHJpbmcge1xuICAgIGNvbnN0IHBsYWluT2JqZWN0ID0gdGhpcy50b1BsYWluT2JqZWN0KHtcbiAgICAgIGNhblVzZVRvSlNPTjogdHJ1ZSxcbiAgICAgIGRlcHRoOiAwLFxuICAgICAga2V5OiAnJyxcbiAgICAgIHZhbHVlXG4gICAgfSk7XG4gICAgbGV0IGpzb24gPSBlbnN1cmVOb25OdWxsYWJsZShKU09OLnN0cmluZ2lmeShwbGFpbk9iamVjdCwgbnVsbCwgdGhpcy5mdWxsT3B0aW9ucy5zcGFjZSkpO1xuICAgIGNvbnN0IHBsYWNlaG9sZGVyUmVnRXhwID0gbmV3IFJlZ0V4cChTdHJpbmcucmF3YFwiXFxbXFxbJHtlc2NhcGVSZWdFeHAoUExBQ0VIT0xERVJfS0VZX1BSRUZJWCl9KD88S2V5PltBLVphLXpdKykoPzxJbmRleD5cXGQqKVxcXVxcXVwiYCwgJ2cnKTtcbiAgICBqc29uID0gcmVwbGFjZUFsbCh7XG4gICAgICAkc3RyaW5nOiBqc29uLFxuICAgICAgcmVwbGFjZXI6ICh7IGNhcHR1cmVkR3JvdXBBcmd1bWVudHM6IFtrZXkgPSAnJywgaW5kZXhTdHJpbmcgPSAnJ10gfSkgPT5cbiAgICAgICAgYXBwbHlTdWJzdGl0dXRpb25zKHtcbiAgICAgICAgICBmdW5jdGlvblRleHRzOiB0aGlzLmZ1bmN0aW9uVGV4dHMsXG4gICAgICAgICAgaW5kZXg6IGluZGV4U3RyaW5nID8gcGFyc2VJbnQoaW5kZXhTdHJpbmcsIDEwKSA6IDAsXG4gICAgICAgICAga2V5OiBjYXN0VG88VG9rZW5TdWJzdGl0dXRpb25LZXk+KGtleSksXG4gICAgICAgICAgc3Vic3RpdHV0aW9uczogdGhpcy5mdWxsT3B0aW9ucy50b2tlblN1YnN0aXR1dGlvbnNcbiAgICAgICAgfSksXG4gICAgICBzZWFyY2hWYWx1ZTogcGxhY2Vob2xkZXJSZWdFeHBcbiAgICB9KTtcbiAgICByZXR1cm4ganNvbjtcbiAgfVxuXG4gIHByaXZhdGUgaGFuZGxlQXJyYXkocGFyYW1zOiBIYW5kbGVBcnJheVBhcmFtcyk6IHVua25vd24ge1xuICAgIGNvbnN0IHtcbiAgICAgIGNhblVzZVRvSlNPTixcbiAgICAgIGRlcHRoLFxuICAgICAgdmFsdWVcbiAgICB9ID0gcGFyYW1zO1xuICAgIHJldHVybiBkZXB0aCA+IHRoaXMuZnVsbE9wdGlvbnMubWF4RGVwdGhcbiAgICAgID8gbWFrZVBsYWNlaG9sZGVyKFRva2VuU3Vic3RpdHV0aW9uS2V5Lk1heERlcHRoTGltaXRSZWFjaGVkQXJyYXksIHZhbHVlLmxlbmd0aClcbiAgICAgIDogdmFsdWUubWFwKChpdGVtLCBpbmRleCkgPT5cbiAgICAgICAgdGhpcy50b1BsYWluT2JqZWN0KHtcbiAgICAgICAgICBjYW5Vc2VUb0pTT04sXG4gICAgICAgICAgZGVwdGg6IGRlcHRoICsgMSxcbiAgICAgICAgICBrZXk6IFN0cmluZyhpbmRleCksXG4gICAgICAgICAgdmFsdWU6IGl0ZW1cbiAgICAgICAgfSlcbiAgICAgICk7XG4gIH1cblxuICBwcml2YXRlIGhhbmRsZUNpcmN1bGFyUmVmZXJlbmNlKHZhbHVlOiBvYmplY3QsIGtleTogc3RyaW5nKTogdW5rbm93biB7XG4gICAgaWYgKHRoaXMuZnVsbE9wdGlvbnMuc2hvdWxkSGFuZGxlQ2lyY3VsYXJSZWZlcmVuY2VzKSB7XG4gICAgICByZXR1cm4gbWFrZVBsYWNlaG9sZGVyKFRva2VuU3Vic3RpdHV0aW9uS2V5LkNpcmN1bGFyUmVmZXJlbmNlKTtcbiAgICB9XG4gICAgY29uc3QgdmFsdWVDb25zdHJ1Y3Rvck5hbWUgPSB2YWx1ZS5jb25zdHJ1Y3Rvci5uYW1lIHx8ICdPYmplY3QnO1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoYENvbnZlcnRpbmcgY2lyY3VsYXIgc3RydWN0dXJlIHRvIEpTT05cbi0tPiBzdGFydGluZyBhdCBvYmplY3Qgd2l0aCBjb25zdHJ1Y3RvciAnJHt2YWx1ZUNvbnN0cnVjdG9yTmFtZX0nXG4tLS0gcHJvcGVydHkgJyR7a2V5fScgY2xvc2VzIHRoZSBjaXJjbGVgKTtcbiAgfVxuXG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW5zYWZlLWZ1bmN0aW9uLXR5cGUgLS0gV2UgbmVlZCB0byB1c2UgYEZ1bmN0aW9uYCB0eXBlIHRvIGhhbmRsZSB0aGVtIHNlcGFyYXRlbHkuXG4gIHByaXZhdGUgaGFuZGxlRnVuY3Rpb24odmFsdWU6IEZ1bmN0aW9uKTogdW5rbm93biB7XG4gICAgaWYgKHRoaXMuZnVsbE9wdGlvbnMuZnVuY3Rpb25IYW5kbGluZ01vZGUgPT09IEZ1bmN0aW9uSGFuZGxpbmdNb2RlLkV4Y2x1ZGUpIHtcbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuICAgIGNvbnN0IGluZGV4ID0gdGhpcy5mdW5jdGlvblRleHRzLmxlbmd0aDtcbiAgICBjb25zdCBmdW5jdGlvblRleHQgPSB0aGlzLmZ1bGxPcHRpb25zLmZ1bmN0aW9uSGFuZGxpbmdNb2RlID09PSBGdW5jdGlvbkhhbmRsaW5nTW9kZS5GdWxsXG4gICAgICA/IGdldEZ1bmN0aW9uRXhwcmVzc2lvblN0cmluZyh2YWx1ZSlcbiAgICAgIDogYGZ1bmN0aW9uICR7dmFsdWUubmFtZSB8fCAnYW5vbnltb3VzJ30oKSB7IC8qIC4uLiAqLyB9YDtcbiAgICB0aGlzLmZ1bmN0aW9uVGV4dHMucHVzaChmdW5jdGlvblRleHQpO1xuICAgIHJldHVybiBtYWtlUGxhY2Vob2xkZXIoVG9rZW5TdWJzdGl0dXRpb25LZXkuRnVuY3Rpb24sIGluZGV4KTtcbiAgfVxuXG4gIHByaXZhdGUgaGFuZGxlT2JqZWN0KHBhcmFtczogSGFuZGxlT2JqZWN0UGFyYW1zKTogdW5rbm93biB7XG4gICAgY29uc3Qge1xuICAgICAgY2FuVXNlVG9KU09OLFxuICAgICAgZGVwdGgsXG4gICAgICBrZXksXG4gICAgICB2YWx1ZVxuICAgIH0gPSBwYXJhbXM7XG4gICAgaWYgKHRoaXMudXNlZE9iamVjdHMuaGFzKHZhbHVlKSkge1xuICAgICAgcmV0dXJuIHRoaXMuaGFuZGxlQ2lyY3VsYXJSZWZlcmVuY2UodmFsdWUsIGtleSk7XG4gICAgfVxuXG4gICAgdGhpcy51c2VkT2JqZWN0cy5hZGQodmFsdWUpO1xuXG4gICAgaWYgKGNhblVzZVRvSlNPTikge1xuICAgICAgY29uc3QgdG9KU09OUmVzdWx0ID0gdGhpcy50cnlIYW5kbGVUb0pTT04oe1xuICAgICAgICBkZXB0aCxcbiAgICAgICAga2V5LFxuICAgICAgICB2YWx1ZVxuICAgICAgfSk7XG4gICAgICBpZiAodG9KU09OUmVzdWx0ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgcmV0dXJuIHRvSlNPTlJlc3VsdDtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoQXJyYXkuaXNBcnJheSh2YWx1ZSkpIHtcbiAgICAgIHJldHVybiB0aGlzLmhhbmRsZUFycmF5KHtcbiAgICAgICAgY2FuVXNlVG9KU09OLFxuICAgICAgICBkZXB0aCxcbiAgICAgICAgdmFsdWVcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIGlmIChkZXB0aCA+IHRoaXMuZnVsbE9wdGlvbnMubWF4RGVwdGgpIHtcbiAgICAgIHJldHVybiBtYWtlUGxhY2Vob2xkZXIoVG9rZW5TdWJzdGl0dXRpb25LZXkuTWF4RGVwdGhMaW1pdFJlYWNoZWQpO1xuICAgIH1cblxuICAgIHJldHVybiB2YWx1ZSBpbnN0YW5jZW9mIEVycm9yICYmIHRoaXMuZnVsbE9wdGlvbnMuc2hvdWxkSGFuZGxlRXJyb3JzXG4gICAgICA/IGVycm9yVG9TdHJpbmcodmFsdWUpXG4gICAgICA6IHRoaXMuaGFuZGxlUGxhaW5PYmplY3Qoe1xuICAgICAgICBjYW5Vc2VUb0pTT04sXG4gICAgICAgIGRlcHRoLFxuICAgICAgICB2YWx1ZVxuICAgICAgfSk7XG4gIH1cblxuICBwcml2YXRlIGhhbmRsZVBsYWluT2JqZWN0KHBhcmFtczogSGFuZGxlUGxhaW5PYmplY3RQYXJhbXMpOiB1bmtub3duIHtcbiAgICBjb25zdCB7XG4gICAgICBjYW5Vc2VUb0pTT04sXG4gICAgICBkZXB0aCxcbiAgICAgIHZhbHVlXG4gICAgfSA9IHBhcmFtcztcbiAgICBjb25zdCBlbnRyaWVzID0gT2JqZWN0LmVudHJpZXModmFsdWUpO1xuICAgIGlmICh0aGlzLmZ1bGxPcHRpb25zLnNob3VsZFNvcnRLZXlzKSB7XG4gICAgICBlbnRyaWVzLnNvcnQoKFtrZXkxXSwgW2tleTJdKSA9PiBrZXkxLmxvY2FsZUNvbXBhcmUoa2V5MikpO1xuICAgIH1cblxuICAgIHJldHVybiBPYmplY3QuZnJvbUVudHJpZXMoXG4gICAgICBlbnRyaWVzLm1hcCgoW2tleTIsIHZhbHVlMl0pID0+IFtcbiAgICAgICAga2V5MixcbiAgICAgICAgdGhpcy50b1BsYWluT2JqZWN0KHtcbiAgICAgICAgICBjYW5Vc2VUb0pTT04sXG4gICAgICAgICAgZGVwdGg6IGRlcHRoICsgMSxcbiAgICAgICAgICBrZXk6IGtleTIsXG4gICAgICAgICAgdmFsdWU6IHZhbHVlMlxuICAgICAgICB9KVxuICAgICAgXSlcbiAgICApO1xuICB9XG5cbiAgcHJpdmF0ZSB0b1BsYWluT2JqZWN0KHBhcmFtczogVG9QbGFpbk9iamVjdFBhcmFtcyk6IHVua25vd24ge1xuICAgIGNvbnN0IHtcbiAgICAgIGNhblVzZVRvSlNPTixcbiAgICAgIGRlcHRoLFxuICAgICAga2V5LFxuICAgICAgdmFsdWVcbiAgICB9ID0gcGFyYW1zO1xuICAgIGlmICh2YWx1ZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICByZXR1cm4gKGRlcHRoID09PSAwIHx8IHRoaXMuZnVsbE9wdGlvbnMuc2hvdWxkSGFuZGxlVW5kZWZpbmVkKVxuICAgICAgICA/IG1ha2VQbGFjZWhvbGRlcihUb2tlblN1YnN0aXR1dGlvbktleS5VbmRlZmluZWQpXG4gICAgICAgIDogdW5kZWZpbmVkO1xuICAgIH1cblxuICAgIGlmICh0eXBlb2YgdmFsdWUgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIHJldHVybiB0aGlzLmhhbmRsZUZ1bmN0aW9uKHZhbHVlKTtcbiAgICB9XG5cbiAgICByZXR1cm4gdHlwZW9mIHZhbHVlICE9PSAnb2JqZWN0JyB8fCB2YWx1ZSA9PT0gbnVsbFxuICAgICAgPyB2YWx1ZVxuICAgICAgOiB0aGlzLmhhbmRsZU9iamVjdCh7XG4gICAgICAgIGNhblVzZVRvSlNPTixcbiAgICAgICAgZGVwdGgsXG4gICAgICAgIGtleSxcbiAgICAgICAgdmFsdWVcbiAgICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSB0cnlIYW5kbGVUb0pTT04ocGFyYW1zOiBUcnlIYW5kbGVUb0pTT05QYXJhbXMpOiB1bmtub3duIHtcbiAgICBjb25zdCB7XG4gICAgICBkZXB0aCxcbiAgICAgIGtleSxcbiAgICAgIHZhbHVlXG4gICAgfSA9IHBhcmFtcztcbiAgICBjb25zdCB0b0pTT04gPSAodmFsdWUgYXMgUGFydGlhbDxKU09OU2VyaWFsaXphYmxlPikudG9KU09OO1xuICAgIGlmICh0eXBlb2YgdG9KU09OID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICB0cnkge1xuICAgICAgICBjb25zdCBuZXdWYWx1ZSA9IHRvSlNPTi5jYWxsKHZhbHVlLCBrZXkpO1xuICAgICAgICByZXR1cm4gdGhpcy50b1BsYWluT2JqZWN0KHtcbiAgICAgICAgICBjYW5Vc2VUb0pTT046IGZhbHNlLFxuICAgICAgICAgIGRlcHRoLFxuICAgICAgICAgIGtleSxcbiAgICAgICAgICB2YWx1ZTogbmV3VmFsdWVcbiAgICAgICAgfSk7XG4gICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICBpZiAodGhpcy5mdWxsT3B0aW9ucy5zaG91bGRDYXRjaFRvSlNPTkVycm9ycykge1xuICAgICAgICAgIHJldHVybiBtYWtlUGxhY2Vob2xkZXIoVG9rZW5TdWJzdGl0dXRpb25LZXkuVG9KU09ORmFpbGVkKTtcbiAgICAgICAgfVxuICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxufVxuLyoqXG4gKiBBc3NpZ25zIHByb3BlcnRpZXMgZnJvbSBvbmUgb3IgbW9yZSBzb3VyY2Ugb2JqZWN0cyB0byBhIHRhcmdldCBvYmplY3QsIGluY2x1ZGluZyBub24tZW51bWVyYWJsZSBwcm9wZXJ0aWVzLlxuICpcbiAqIEB0eXBlUGFyYW0gVCAtIFRoZSB0YXJnZXQgb2JqZWN0IHR5cGUuXG4gKiBAdHlwZVBhcmFtIFUgLSBUaGUgc291cmNlIG9iamVjdCB0eXBlLlxuICogQHBhcmFtIHRhcmdldCAtIFRoZSB0YXJnZXQgb2JqZWN0IHRvIGFzc2lnbiBwcm9wZXJ0aWVzIHRvLlxuICogQHBhcmFtIHNvdXJjZSAtIFRoZSBzb3VyY2Ugb2JqZWN0IHRvIGFzc2lnbiBwcm9wZXJ0aWVzIGZyb20uXG4gKiBAcmV0dXJucyBUaGUgdGFyZ2V0IG9iamVjdCB3aXRoIHRoZSBhc3NpZ25lZCBwcm9wZXJ0aWVzLlxuICovXG5leHBvcnQgZnVuY3Rpb24gYXNzaWduV2l0aE5vbkVudW1lcmFibGVQcm9wZXJ0aWVzPFQgZXh0ZW5kcyBvYmplY3QsIFU+KHRhcmdldDogVCwgc291cmNlOiBVKTogVCAmIFU7XG4vKipcbiAqIEFzc2lnbnMgcHJvcGVydGllcyBmcm9tIG9uZSBvciBtb3JlIHNvdXJjZSBvYmplY3RzIHRvIGEgdGFyZ2V0IG9iamVjdCwgaW5jbHVkaW5nIG5vbi1lbnVtZXJhYmxlIHByb3BlcnRpZXMuXG4gKlxuICogQHR5cGVQYXJhbSBUIC0gVGhlIHRhcmdldCBvYmplY3QgdHlwZS5cbiAqIEB0eXBlUGFyYW0gVSAtIFRoZSBmaXJzdCBzb3VyY2Ugb2JqZWN0IHR5cGUuXG4gKiBAdHlwZVBhcmFtIFYgLSBUaGUgc2Vjb25kIHNvdXJjZSBvYmplY3QgdHlwZS5cbiAqIEBwYXJhbSB0YXJnZXQgLSBUaGUgdGFyZ2V0IG9iamVjdCB0byBhc3NpZ24gcHJvcGVydGllcyB0by5cbiAqIEBwYXJhbSBzb3VyY2UxIC0gVGhlIGZpcnN0IHNvdXJjZSBvYmplY3QgdG8gYXNzaWduIHByb3BlcnRpZXMgZnJvbS5cbiAqIEBwYXJhbSBzb3VyY2UyIC0gVGhlIHNlY29uZCBzb3VyY2Ugb2JqZWN0IHRvIGFzc2lnbiBwcm9wZXJ0aWVzIGZyb20uXG4gKiBAcmV0dXJucyBUaGUgdGFyZ2V0IG9iamVjdCB3aXRoIHRoZSBhc3NpZ25lZCBwcm9wZXJ0aWVzLlxuICovXG5leHBvcnQgZnVuY3Rpb24gYXNzaWduV2l0aE5vbkVudW1lcmFibGVQcm9wZXJ0aWVzPFQgZXh0ZW5kcyBvYmplY3QsIFUsIFY+KHRhcmdldDogVCwgc291cmNlMTogVSwgc291cmNlMjogVik6IFQgJiBVICYgVjtcbi8qKlxuICogQXNzaWducyBwcm9wZXJ0aWVzIGZyb20gb25lIG9yIG1vcmUgc291cmNlIG9iamVjdHMgdG8gYSB0YXJnZXQgb2JqZWN0LCBpbmNsdWRpbmcgbm9uLWVudW1lcmFibGUgcHJvcGVydGllcy5cbiAqXG4gKiBAdHlwZVBhcmFtIFQgLSBUaGUgdGFyZ2V0IG9iamVjdCB0eXBlLlxuICogQHR5cGVQYXJhbSBVIC0gVGhlIGZpcnN0IHNvdXJjZSBvYmplY3QgdHlwZS5cbiAqIEB0eXBlUGFyYW0gViAtIFRoZSBzZWNvbmQgc291cmNlIG9iamVjdCB0eXBlLlxuICogQHR5cGVQYXJhbSBXIC0gVGhlIHRoaXJkIHNvdXJjZSBvYmplY3QgdHlwZS5cbiAqIEBwYXJhbSB0YXJnZXQgLSBUaGUgdGFyZ2V0IG9iamVjdCB0byBhc3NpZ24gcHJvcGVydGllcyB0by5cbiAqIEBwYXJhbSBzb3VyY2UxIC0gVGhlIGZpcnN0IHNvdXJjZSBvYmplY3QgdG8gYXNzaWduIHByb3BlcnRpZXMgZnJvbS5cbiAqIEBwYXJhbSBzb3VyY2UyIC0gVGhlIHNlY29uZCBzb3VyY2Ugb2JqZWN0IHRvIGFzc2lnbiBwcm9wZXJ0aWVzIGZyb20uXG4gKiBAcGFyYW0gc291cmNlMyAtIFRoZSB0aGlyZCBzb3VyY2Ugb2JqZWN0IHRvIGFzc2lnbiBwcm9wZXJ0aWVzIGZyb20uXG4gKiBAcmV0dXJucyBUaGUgdGFyZ2V0IG9iamVjdCB3aXRoIHRoZSBhc3NpZ25lZCBwcm9wZXJ0aWVzLlxuICovXG5leHBvcnQgZnVuY3Rpb24gYXNzaWduV2l0aE5vbkVudW1lcmFibGVQcm9wZXJ0aWVzPFQgZXh0ZW5kcyBvYmplY3QsIFUsIFYsIFc+KHRhcmdldDogVCwgc291cmNlMTogVSwgc291cmNlMjogViwgc291cmNlMzogVyk6IFQgJiBVICYgViAmIFc7XG4vKipcbiAqIEFzc2lnbnMgcHJvcGVydGllcyBmcm9tIG9uZSBvciBtb3JlIHNvdXJjZSBvYmplY3RzIHRvIGEgdGFyZ2V0IG9iamVjdCwgaW5jbHVkaW5nIG5vbi1lbnVtZXJhYmxlIHByb3BlcnRpZXMuXG4gKlxuICogQHBhcmFtIHRhcmdldCAtIFRoZSB0YXJnZXQgb2JqZWN0IHRvIGFzc2lnbiBwcm9wZXJ0aWVzIHRvLlxuICogQHBhcmFtIHNvdXJjZXMgLSBUaGUgc291cmNlIG9iamVjdHMgdG8gYXNzaWduIHByb3BlcnRpZXMgZnJvbS5cbiAqIEByZXR1cm5zIFRoZSB0YXJnZXQgb2JqZWN0IHdpdGggdGhlIGFzc2lnbmVkIHByb3BlcnRpZXMuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBhc3NpZ25XaXRoTm9uRW51bWVyYWJsZVByb3BlcnRpZXModGFyZ2V0OiBvYmplY3QsIC4uLnNvdXJjZXM6IG9iamVjdFtdKTogb2JqZWN0IHtcbiAgcmV0dXJuIGFzc2lnbldpdGhOb25FbnVtZXJhYmxlUHJvcGVydGllc0ltcGwodGFyZ2V0LCAuLi5zb3VyY2VzKTtcbn1cblxuLyoqXG4gKiBDYXN0cyBhIHZhbHVlIHRvIGEgc3BlY2lmaWMgdHlwZS5cbiAqXG4gKiBAdHlwZVBhcmFtIFQgLSBUaGUgdGFyZ2V0IHR5cGUgdG8gY2FzdCB0by5cbiAqIEBwYXJhbSB2YWx1ZSAtIFRoZSB2YWx1ZSB0byBjYXN0LlxuICogQHJldHVybnMgVGhlIHZhbHVlIGFzIHRoZSBzcGVjaWZpZWQgdHlwZS5cbiAqL1xuLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby11bm5lY2Vzc2FyeS10eXBlLXBhcmFtZXRlcnMgLS0gV2UgbmVlZCB0byBjYXN0LlxuZXhwb3J0IGZ1bmN0aW9uIGNhc3RUbzxUPih2YWx1ZTogdW5rbm93bik6IFQge1xuICByZXR1cm4gdmFsdWUgYXMgVDtcbn1cblxuLyoqXG4gKiBDbG9uZXMgYW4gb2JqZWN0LCBpbmNsdWRpbmcgbm9uLWVudW1lcmFibGUgcHJvcGVydGllcy5cbiAqXG4gKiBAdHlwZVBhcmFtIFQgLSBUaGUgdHlwZSBvZiB0aGUgb2JqZWN0LlxuICogQHBhcmFtICRvYmplY3QgLSBUaGUgb2JqZWN0IHRvIGNsb25lLlxuICogQHJldHVybnMgQSBuZXcgb2JqZWN0IHdpdGggdGhlIHNhbWUgcHJvcGVydGllcyBhcyB0aGUgb3JpZ2luYWwgb2JqZWN0LCBpbmNsdWRpbmcgbm9uLWVudW1lcmFibGUgcHJvcGVydGllcy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNsb25lV2l0aE5vbkVudW1lcmFibGVQcm9wZXJ0aWVzPFQgZXh0ZW5kcyBvYmplY3Q+KCRvYmplY3Q6IFQpOiBUIHtcbiAgcmV0dXJuIE9iamVjdC5jcmVhdGUoZ2V0UHJvdG90eXBlT2YoJG9iamVjdCksIE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3JzKCRvYmplY3QpKSBhcyBUO1xufVxuXG4vKipcbiAqIERlbGV0ZXMgbXVsdGlwbGUgcHJvcGVydGllcyBmcm9tIGFuIG9iamVjdC5cbiAqXG4gKiBAdHlwZVBhcmFtIFQgLSBUaGUgdHlwZSBvZiB0aGUgb2JqZWN0LlxuICogQHBhcmFtICRvYmplY3QgLSBUaGUgb2JqZWN0IHRvIGRlbGV0ZSB0aGUgcHJvcGVydGllcyBmcm9tLlxuICogQHBhcmFtIHByb3BlcnR5TmFtZXMgLSBUaGUgbmFtZXMgb2YgdGhlIHByb3BlcnRpZXMgdG8gZGVsZXRlLlxuICogQHJldHVybnMgYHRydWVgIGlmIGFueSBvZiB0aGUgcHJvcGVydGllcyB3ZXJlIHByZXNlbnQsIG90aGVyd2lzZSBgZmFsc2VgLlxuICovXG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgdW5pY29ybi9jb25zaXN0ZW50LWJvb2xlYW4tbmFtZSAtLSBUaGUgbmFtZSBzdGF0ZXMgdGhlIGFjdGlvbjsgdGhlIGJvb2xlYW4gb25seSByZXBvcnRzIHdoZXRoZXIgYW55dGhpbmcgd2FzIGRlbGV0ZWQuXG5leHBvcnQgZnVuY3Rpb24gZGVsZXRlUHJvcGVydGllczxUIGV4dGVuZHMgb2JqZWN0Pigkb2JqZWN0OiBULCBwcm9wZXJ0eU5hbWVzOiAoa2V5b2YgVClbXSk6IGJvb2xlYW4ge1xuICBsZXQgaGFzRGVsZXRlZEFueSA9IGZhbHNlO1xuXG4gIGZvciAoY29uc3QgcHJvcGVydHlOYW1lIG9mIHByb3BlcnR5TmFtZXMpIHtcbiAgICBoYXNEZWxldGVkQW55ID0gZGVsZXRlUHJvcGVydHkoJG9iamVjdCwgcHJvcGVydHlOYW1lKSB8fCBoYXNEZWxldGVkQW55O1xuICB9XG5cbiAgcmV0dXJuIGhhc0RlbGV0ZWRBbnk7XG59XG5cbi8qKlxuICogRGVsZXRlcyBhIHByb3BlcnR5IGZyb20gYW4gb2JqZWN0LlxuICpcbiAqIEB0eXBlUGFyYW0gVCAtIFRoZSB0eXBlIG9mIHRoZSBvYmplY3QuXG4gKiBAcGFyYW0gJG9iamVjdCAtIFRoZSBvYmplY3QgdG8gZGVsZXRlIHRoZSBwcm9wZXJ0eSBmcm9tLlxuICogQHBhcmFtIHByb3BlcnR5TmFtZSAtIFRoZSBuYW1lIG9mIHRoZSBwcm9wZXJ0eSB0byBkZWxldGUuXG4gKiBAcmV0dXJucyBgdHJ1ZWAgaWYgdGhlIHByb3BlcnR5IHdhcyBwcmVzZW50LCBvdGhlcndpc2UgYGZhbHNlYC5cbiAqL1xuLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIHVuaWNvcm4vY29uc2lzdGVudC1ib29sZWFuLW5hbWUgLS0gVGhlIG5hbWUgc3RhdGVzIHRoZSBhY3Rpb247IHRoZSBib29sZWFuIG9ubHkgcmVwb3J0cyB3aGV0aGVyIHRoZSBwcm9wZXJ0eSB3YXMgZGVsZXRlZC5cbmV4cG9ydCBmdW5jdGlvbiBkZWxldGVQcm9wZXJ0eTxUIGV4dGVuZHMgb2JqZWN0Pigkb2JqZWN0OiBULCBwcm9wZXJ0eU5hbWU6IGtleW9mIFQpOiBib29sZWFuIHtcbiAgaWYgKCFPYmplY3QuaGFzT3duKCRvYmplY3QsIHByb3BlcnR5TmFtZSkpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1keW5hbWljLWRlbGV0ZSAtLSBXZSBoYXZlIG5vIG90aGVyIHdheSB0byBkZWxldGUgdGhlIHByb3BlcnR5LlxuICBkZWxldGUgJG9iamVjdFtwcm9wZXJ0eU5hbWVdO1xuICByZXR1cm4gdHJ1ZTtcbn1cblxuLyoqXG4gKiBFeHRyYWN0cyB0aGUgZGVmYXVsdCBleHBvcnQgZnJvbSBhIG1vZHVsZS5cbiAqXG4gKiBVc2VmdWwgdG8gaGFuZGxlIGluY29ycmVjdCBkZWZhdWx0IGV4cG9ydCBpbnRlcm9wIGJldHdlZW4gRVNNIGFuZCBDSlMuXG4gKlxuICogQHR5cGVQYXJhbSBUIC0gVGhlIHR5cGUgb2YgdGhlIGRlZmF1bHQgZXhwb3J0LlxuICogQHBhcmFtIG1vZHVsZSAtIFRoZSBtb2R1bGUgdG8gZXh0cmFjdCB0aGUgZGVmYXVsdCBleHBvcnQgZnJvbS5cbiAqIEByZXR1cm5zIFRoZSBkZWZhdWx0IGV4cG9ydC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGV4dHJhY3REZWZhdWx0RXhwb3J0SW50ZXJvcDxUPihtb2R1bGU6IE1vZHVsZVdpdGhEZWZhdWx0RXhwb3J0PFQ+IHwgVCk6IFQge1xuICBpZiAodHlwZW9mIG1vZHVsZSAhPT0gJ29iamVjdCcgfHwgbW9kdWxlID09PSBudWxsKSB7XG4gICAgcmV0dXJuIG1vZHVsZTtcbiAgfVxuXG4gIHJldHVybiAnZGVmYXVsdCcgaW4gbW9kdWxlID8gbW9kdWxlLmRlZmF1bHQgOiBtb2R1bGU7XG59XG5cbi8qKlxuICogR2V0cyBhbGwgZW50cmllcyBvZiBhbiBvYmplY3QuXG4gKlxuICogQHR5cGVQYXJhbSBUIC0gVGhlIHR5cGUgb2YgdGhlIG9iamVjdC5cbiAqIEBwYXJhbSAkb2JqZWN0IC0gVGhlIG9iamVjdCB0byBnZXQgdGhlIGVudHJpZXMgb2YuXG4gKiBAcmV0dXJucyBBbiBhcnJheSBvZiBhbGwgZW50cmllcyBvZiB0aGUgb2JqZWN0LlxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0QWxsRW50cmllczxUIGV4dGVuZHMgb2JqZWN0Pigkb2JqZWN0OiBUKTogW1N0cmluZ0tleXM8VD4sIFRbU3RyaW5nS2V5czxUPl1dW10ge1xuICByZXR1cm4gZ2V0QWxsS2V5cygkb2JqZWN0KS5tYXAoKGtleSkgPT4gW2tleSwgJG9iamVjdFtrZXldXSk7XG59XG5cbi8qKlxuICogR2V0cyBhbGwga2V5cyBvZiBhbiBvYmplY3QuXG4gKiBJbmNsdWRlcyBmaWVsZHMgYW5kIHByb3BlcnRpZXMuXG4gKlxuICogQHR5cGVQYXJhbSBUIC0gVGhlIHR5cGUgb2YgdGhlIG9iamVjdC5cbiAqIEBwYXJhbSAkb2JqZWN0IC0gVGhlIG9iamVjdCB0byBnZXQgdGhlIGtleXMgb2YuXG4gKiBAcmV0dXJucyBBbiBhcnJheSBvZiBhbGwga2V5cyBvZiB0aGUgb2JqZWN0LlxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0QWxsS2V5czxUIGV4dGVuZHMgb2JqZWN0Pigkb2JqZWN0OiBUKTogU3RyaW5nS2V5czxUPltdIHtcbiAgY29uc3Qga2V5czogU3RyaW5nS2V5czxUPltdID0gW107XG4gIGxldCBjdXJyZW50OiBudWxsIHwgb2JqZWN0ID0gJG9iamVjdDtcbiAgd2hpbGUgKGN1cnJlbnQpIHtcbiAgICBjb25zdCBkZXNjcmlwdG9ycyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3JzKGN1cnJlbnQpO1xuICAgIGZvciAoY29uc3QgW2tleSwgZGVzY3JpcHRvcl0gb2YgT2JqZWN0LmVudHJpZXMoZGVzY3JpcHRvcnMpKSB7XG4gICAgICBpZiAoKGtleSA9PT0gJ19fcHJvdG9fXycpIHx8ICh0eXBlb2YgZGVzY3JpcHRvci52YWx1ZSA9PT0gJ2Z1bmN0aW9uJykpIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGhhc0dldHRlciA9IHR5cGVvZiBkZXNjcmlwdG9yLmdldCA9PT0gJ2Z1bmN0aW9uJztcbiAgICAgIGNvbnN0IGhhc1NldHRlciA9IHR5cGVvZiBkZXNjcmlwdG9yLnNldCA9PT0gJ2Z1bmN0aW9uJztcbiAgICAgIGlmIChoYXNHZXR0ZXIgfHwgaGFzU2V0dGVyKSB7XG4gICAgICAgIGlmIChoYXNHZXR0ZXIgJiYgaGFzU2V0dGVyKSB7XG4gICAgICAgICAga2V5cy5wdXNoKGtleSBhcyBTdHJpbmdLZXlzPFQ+KTtcbiAgICAgICAgfVxuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgaWYgKGRlc2NyaXB0b3IuZW51bWVyYWJsZSAmJiBkZXNjcmlwdG9yLndyaXRhYmxlKSB7XG4gICAgICAgIGtleXMucHVzaChrZXkgYXMgU3RyaW5nS2V5czxUPik7XG4gICAgICB9XG4gICAgfVxuXG4gICAgY3VycmVudCA9IE9iamVjdC5nZXRQcm90b3R5cGVPZihjdXJyZW50KSBhcyBudWxsIHwgb2JqZWN0O1xuICB9XG4gIHJldHVybiBrZXlzLnNvcnQoKTtcbn1cblxuLyoqXG4gKiBHZXRzIHRoZSB2YWx1ZSBvZiBhIG5lc3RlZCBwcm9wZXJ0eSBmcm9tIGFuIG9iamVjdC5cbiAqXG4gKiBAcGFyYW0gJG9iamVjdCAtIFRoZSBvYmplY3QgdG8gZ2V0IHRoZSBuZXN0ZWQgcHJvcGVydHkgdmFsdWUgZnJvbS5cbiAqIEBwYXJhbSBwYXRoIC0gVGhlIHBhdGggdG8gdGhlIG5lc3RlZCBwcm9wZXJ0eS5cbiAqIEByZXR1cm5zIFRoZSB2YWx1ZSBvZiB0aGUgbmVzdGVkIHByb3BlcnR5LlxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0TmVzdGVkUHJvcGVydHlWYWx1ZSgkb2JqZWN0OiBHZW5lcmljT2JqZWN0LCBwYXRoOiBzdHJpbmcpOiB1bmtub3duIHtcbiAgbGV0IG5vZGU6IEdlbmVyaWNPYmplY3QgfCB1bmRlZmluZWQgPSAkb2JqZWN0O1xuICBjb25zdCBrZXlzID0gcGF0aC5zcGxpdChLRVlfU0VQQVJBVE9SKTtcbiAgZm9yIChjb25zdCBrZXkgb2Yga2V5cykge1xuICAgIGlmIChub2RlID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuICAgIG5vZGUgPSBub2RlW2tleV0gYXMgR2VuZXJpY09iamVjdCB8IHVuZGVmaW5lZDtcbiAgfVxuXG4gIHJldHVybiBub2RlO1xufVxuXG4vKipcbiAqIEdldHMgdGhlIHByb3RvdHlwZSBvZiB0aGUgc3BlY2lmaWVkIG9iamVjdC5cbiAqXG4gKiBAdHlwZVBhcmFtIFQgLSBUaGUgdHlwZSBvZiB0aGUgb2JqZWN0LlxuICogQHBhcmFtIGluc3RhbmNlIC0gVGhlIG9iamVjdCBpbnN0YW5jZSB0byByZXRyaWV2ZSB0aGUgcHJvdG90eXBlIG9mLlxuICogQHJldHVybnMgVGhlIHByb3RvdHlwZSBvZiB0aGUgb2JqZWN0LlxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0UHJvdG90eXBlT2Y8VD4oaW5zdGFuY2U6IFQpOiBUIHtcbiAgcmV0dXJuIGluc3RhbmNlID09PSB1bmRlZmluZWQgfHwgaW5zdGFuY2UgPT09IG51bGwgPyBpbnN0YW5jZSA6IChPYmplY3QuZ2V0UHJvdG90eXBlT2YoaW5zdGFuY2UpIGFzIFQpO1xufVxuXG4vKipcbiAqIENvbXBhcmVzIHR3byB2YWx1ZXMgdG8gZGV0ZXJtaW5lIGlmIHRoZXkgYXJlIGRlZXBseSBlcXVhbC5cbiAqXG4gKiBAcGFyYW0gYSAtIFRoZSBmaXJzdCB2YWx1ZSB0byBjb21wYXJlLlxuICogQHBhcmFtIGIgLSBUaGUgc2Vjb25kIHZhbHVlIHRvIGNvbXBhcmUuXG4gKiBAcmV0dXJucyBgdHJ1ZWAgaWYgdGhlIHZhbHVlcyBhcmUgZGVlcGx5IGVxdWFsLCBvdGhlcndpc2UgYGZhbHNlYC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzRGVlcEVxdWFsKGE6IHVua25vd24sIGI6IHVua25vd24pOiBib29sZWFuIHtcbiAgaWYgKGEgPT09IGIpIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIGlmICh0eXBlb2YgYSAhPT0gJ29iamVjdCcgfHwgdHlwZW9mIGIgIT09ICdvYmplY3QnIHx8IGEgPT09IG51bGwgfHwgYiA9PT0gbnVsbCkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIGNvbnN0IGFDb25zdHJ1Y3RvciA9IGEuY29uc3RydWN0b3I7XG4gIGNvbnN0IGJDb25zdHJ1Y3RvciA9IGIuY29uc3RydWN0b3I7XG5cbiAgaWYgKGFDb25zdHJ1Y3RvciAhPT0gYkNvbnN0cnVjdG9yKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgaWYgKGFDb25zdHJ1Y3RvciAhPT0gT2JqZWN0KSB7XG4gICAgY29uc3QgcmVzdWx0ID0gZGVlcEVxdWFsVHlwZWQoYSwgYik7XG4gICAgaWYgKHJlc3VsdCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cbiAgfVxuXG4gIGNvbnN0IGtleXNBID0gZ2V0QWxsS2V5cyhhKTtcbiAgY29uc3Qga2V5c0IgPSBnZXRBbGxLZXlzKGIpO1xuXG4gIGlmIChrZXlzQS5sZW5ndGggIT09IGtleXNCLmxlbmd0aCkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIGNvbnN0IGFSZWNvcmQgPSBlbnN1cmVHZW5lcmljT2JqZWN0KGEpO1xuICBjb25zdCBiUmVjb3JkID0gZW5zdXJlR2VuZXJpY09iamVjdChiKTtcblxuICBmb3IgKGNvbnN0IGtleSBvZiBrZXlzQSkge1xuICAgIGlmICgha2V5c0IuaW5jbHVkZXMoa2V5KSB8fCAhaXNEZWVwRXF1YWwoYVJlY29yZFtrZXldLCBiUmVjb3JkW2tleV0pKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHRydWU7XG59XG4vKipcbiAqIFJldHJpZXZlcyB0aGUgbmFtZSBvZiBhIHByb3BlcnR5IG9mIGEgZ2l2ZW4gdHlwZSBgVGAuXG4gKlxuICogQHR5cGVQYXJhbSBUIC0gVGhlIHR5cGUgb2YgdGhlIG9iamVjdCBjb250YWluaW5nIHRoZSBwcm9wZXJ0eS5cbiAqIEBwYXJhbSBuYW1lIC0gVGhlIG5hbWUgb2YgdGhlIHByb3BlcnR5IGFzIGEgc3RyaW5nLlxuICogQHJldHVybnMgVGhlIG5hbWUgb2YgdGhlIHByb3BlcnR5LlxuICovXG5leHBvcnQgZnVuY3Rpb24gbmFtZW9mPFQgZXh0ZW5kcyBvYmplY3Q+KG5hbWU6IFN0cmluZ0tleXM8VD4pOiBTdHJpbmdLZXlzPFQ+IHtcbiAgcmV0dXJuIG5hbWU7XG59XG4vKipcbiAqIE5vcm1hbGl6ZXMgb3B0aW9uYWwgcHJvcGVydGllcyB0byBhbGxvdyBgdW5kZWZpbmVkYCBhc3NpZ25tZW50IGluIHN0cmljdCBtb2RlLlxuICpcbiAqIFRoaXMgdXRpbGl0eSBwcm92aWRlcyBhIHdvcmthcm91bmQgZm9yIHRoZSBgZXhhY3RPcHRpb25hbFByb3BlcnR5VHlwZXNgIFR5cGVTY3JpcHQgZmxhZyxcbiAqIHdoaWNoIHByb2hpYml0cyBkaXJlY3RseSBhc3NpZ25pbmcgYHVuZGVmaW5lZGAgdG8gb3B0aW9uYWwgcHJvcGVydGllcyB3aGVuIHRoZSB0eXBlXG4gKiBleHBsaWNpdGx5IG9taXRzIGB1bmRlZmluZWRgLlxuICpcbiAqIEV4YW1wbGU6XG4gKiBgYGB0eXBlc2NyaXB0XG4gKiAvLyBXaXRoIGBleGFjdE9wdGlvbmFsUHJvcGVydHlUeXBlczogdHJ1ZWBcbiAqIGNvbnN0IHg6IHsgcHJvcD86IHN0cmluZyB9ID0geyBwcm9wOiB1bmRlZmluZWQgfTsgLy8gQ29tcGlsZXIgZXJyb3JcbiAqXG4gKiAvLyBVc2luZyB0aGlzIHV0aWxpdHk6XG4gKiBjb25zdCB5OiB7IHByb3A/OiBzdHJpbmcgfSA9IG5vcm1hbGl6ZU9wdGlvbmFsUHJvcGVydGllczx7IHByb3A/OiBzdHJpbmcgfT4oeyBwcm9wOiB1bmRlZmluZWQgfSk7IC8vIFdvcmtzXG4gKiBgYGBcbiAqXG4gKiBAdHlwZVBhcmFtIFQgLSBUaGUgdGFyZ2V0IHR5cGUgd2l0aCBvcHRpb25hbCBwcm9wZXJ0aWVzIHRvIG5vcm1hbGl6ZS5cbiAqIEBwYXJhbSAkb2JqZWN0IC0gVGhlIG9iamVjdCB0byBub3JtYWxpemUsIGFsbG93aW5nIGV4cGxpY2l0IGB1bmRlZmluZWRgIGZvciBvcHRpb25hbCBwcm9wZXJ0aWVzLlxuICogQHJldHVybnMgVGhlIG5vcm1hbGl6ZWQgb2JqZWN0LCBjb21wYXRpYmxlIHdpdGggYGV4YWN0T3B0aW9uYWxQcm9wZXJ0eVR5cGVzYC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG5vcm1hbGl6ZU9wdGlvbmFsUHJvcGVydGllczxUPigkb2JqZWN0OiBVbmRlZmluZWRPblBhcnRpYWxEZWVwPFQ+KTogVCB7XG4gIHJldHVybiAkb2JqZWN0IGFzIFQ7XG59XG4vKipcbiAqIFJlbW92ZXMgYWxsIGB1bmRlZmluZWRgIHByb3BlcnRpZXMgZnJvbSBhbiBvYmplY3Qgd2hlbiB0aGVyZSBhcmUgbm8gbWFuZGF0b3J5IGtleXMgd2l0aCBgdW5kZWZpbmVkYCB2YWx1ZXMuXG4gKlxuICogQHR5cGVQYXJhbSBUeXBlIC0gVGhlIHR5cGUgb2YgdGhlIG9iamVjdC5cbiAqIEBwYXJhbSAkYXJndW1lbnRzIC0gVGhlIGFyZ3VtZW50cyB0byB0aGUgZnVuY3Rpb24uXG4gKiBAcmV0dXJucyBUaGUgb2JqZWN0IHdpdGggYWxsIGB1bmRlZmluZWRgIHByb3BlcnRpZXMgcmVtb3ZlZC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlbW92ZVVuZGVmaW5lZFByb3BlcnRpZXM8VHlwZSBleHRlbmRzIG9iamVjdD4oXG4gIC4uLiRhcmd1bWVudHM6IFJlbW92ZVVuZGVmaW5lZE92ZXJsb2FkPFR5cGU+XG4pOiBUeXBlO1xuLyoqXG4gKiBSZW1vdmVzIGFsbCBgdW5kZWZpbmVkYCBwcm9wZXJ0aWVzIGZyb20gYW4gb2JqZWN0IHdoZW4gdGhlcmUgYXJlIG1hbmRhdG9yeSBrZXlzIHdpdGggYHVuZGVmaW5lZGAgdmFsdWVzLlxuICpcbiAqIEB0eXBlUGFyYW0gVHlwZSAtIFRoZSB0eXBlIG9mIHRoZSBvYmplY3QuXG4gKiBAdHlwZVBhcmFtIEtleXNUb0tlZXAgLSBUaGUga2V5cyB0byBrZWVwLlxuICogQHBhcmFtICRhcmd1bWVudHMgLSBUaGUgYXJndW1lbnRzIHRvIHRoZSBmdW5jdGlvbi5cbiAqIEByZXR1cm5zIFRoZSBvYmplY3Qgd2l0aCBhbGwgYHVuZGVmaW5lZGAgcHJvcGVydGllcyByZW1vdmVkLlxuICovXG5leHBvcnQgZnVuY3Rpb24gcmVtb3ZlVW5kZWZpbmVkUHJvcGVydGllczxUeXBlIGV4dGVuZHMgb2JqZWN0LCBjb25zdCBLZXlzVG9LZWVwIGV4dGVuZHMgcmVhZG9ubHkgc3RyaW5nW10+KFxuICAuLi4kYXJndW1lbnRzOiBSZW1vdmVVbmRlZmluZWRXaXRoS2V5c092ZXJsb2FkPFR5cGUsIEtleXNUb0tlZXA+XG4pOiBUeXBlO1xuLyoqXG4gKiBSZW1vdmVzIGFsbCBgdW5kZWZpbmVkYCBwcm9wZXJ0aWVzIGZyb20gYW4gb2JqZWN0LlxuICpcbiAqIEB0eXBlUGFyYW0gVHlwZSAtIFRoZSB0eXBlIG9mIHRoZSBvYmplY3QuXG4gKiBAcGFyYW0gJG9iamVjdCAtIFRoZSBvYmplY3QgdG8gcmVtb3ZlIGB1bmRlZmluZWRgIHByb3BlcnRpZXMgZnJvbS5cbiAqIEBwYXJhbSBrZXlzVG9LZWVwIC0gVGhlIGtleXMgdG8ga2VlcC5cbiAqIEByZXR1cm5zIFRoZSBvYmplY3Qgd2l0aCBhbGwgYHVuZGVmaW5lZGAgcHJvcGVydGllcyByZW1vdmVkLlxuICovXG5leHBvcnQgZnVuY3Rpb24gcmVtb3ZlVW5kZWZpbmVkUHJvcGVydGllczxUeXBlIGV4dGVuZHMgb2JqZWN0Pigkb2JqZWN0OiBUeXBlLCBrZXlzVG9LZWVwPzogcmVhZG9ubHkgc3RyaW5nW10pOiBUeXBlIHtcbiAgZm9yIChjb25zdCBba2V5LCB2YWx1ZV0gb2YgT2JqZWN0LmVudHJpZXMoJG9iamVjdCkgYXMgW1N0cmluZ0tleXM8VHlwZT4sIHVua25vd25dW10pIHtcbiAgICBpZiAodmFsdWUgPT09IHVuZGVmaW5lZCAmJiAha2V5c1RvS2VlcD8uaW5jbHVkZXMoa2V5KSkge1xuICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1keW5hbWljLWRlbGV0ZSAtLSBXZSBoYXZlIG5vIG90aGVyIHdheSB0byBkZWxldGUgdGhlIHByb3BlcnR5LlxuICAgICAgZGVsZXRlICRvYmplY3Rba2V5XTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuICRvYmplY3Q7XG59XG5cbi8qKlxuICogU2V0cyB0aGUgdmFsdWUgb2YgYSBuZXN0ZWQgcHJvcGVydHkgaW4gYW4gb2JqZWN0LlxuICpcbiAqIEBwYXJhbSBwYXJhbXMgLSBUaGUgcGFyYW1ldGVycyBmb3Igc2V0dGluZyB0aGUgbmVzdGVkIHByb3BlcnR5IHZhbHVlLlxuICovXG5leHBvcnQgZnVuY3Rpb24gc2V0TmVzdGVkUHJvcGVydHlWYWx1ZShwYXJhbXM6IFNldE5lc3RlZFByb3BlcnR5VmFsdWVQYXJhbXMpOiB2b2lkIHtcbiAgY29uc3Qge1xuICAgICRvYmplY3QsXG4gICAgcGF0aCxcbiAgICB2YWx1ZVxuICB9ID0gcGFyYW1zO1xuICBjb25zdCBlcnJvciA9IG5ldyBFcnJvcihgUHJvcGVydHkgcGF0aCAke3BhdGh9IG5vdCBmb3VuZGApO1xuICBsZXQgbm9kZTogR2VuZXJpY09iamVjdCB8IHVuZGVmaW5lZCA9ICRvYmplY3Q7XG4gIGNvbnN0IGtleXMgPSBwYXRoLnNwbGl0KEtFWV9TRVBBUkFUT1IpO1xuICBmb3IgKGNvbnN0IGtleSBvZiBrZXlzLnNsaWNlKDAsIC0xKSkge1xuICAgIGlmIChub2RlID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHRocm93IGVycm9yO1xuICAgIH1cbiAgICBub2RlID0gbm9kZVtrZXldIGFzIEdlbmVyaWNPYmplY3QgfCB1bmRlZmluZWQ7XG4gIH1cblxuICBjb25zdCBsYXN0S2V5ID0gZW5zdXJlTm9uTnVsbGFibGUoa2V5cy5hdCgtMSkpO1xuICBpZiAobm9kZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgdGhyb3cgZXJyb3I7XG4gIH1cblxuICBub2RlW2xhc3RLZXldID0gdmFsdWU7XG59XG5cbi8qKlxuICogQ29udmVydHMgYSBnaXZlbiB2YWx1ZSB0byBhIEpTT04gc3RyaW5nLlxuICpcbiAqIEBwYXJhbSB2YWx1ZSAtIFRoZSB2YWx1ZSB0byBiZSBjb252ZXJ0ZWQgdG8gSlNPTi4gVGhpcyBjYW4gYmUgb2YgYW55IHR5cGUuXG4gKiBAcGFyYW0gb3B0aW9ucyAtIE9wdGlvbnMgZm9yIGN1c3RvbWl6aW5nIHRoZSBKU09OIGNvbnZlcnNpb24gcHJvY2Vzcy5cbiAqIEByZXR1cm5zIFRoZSBKU09OIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGUgaW5wdXQgdmFsdWUuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB0b0pzb24odmFsdWU6IHVua25vd24sIG9wdGlvbnM6IFBhcnRpYWw8VG9Kc29uT3B0aW9ucz4gPSB7fSk6IHN0cmluZyB7XG4gIHJldHVybiBuZXcgVG9Kc29uQ29udmVydGVyKG9wdGlvbnMpLmNvbnZlcnQodmFsdWUpO1xufVxuXG5mdW5jdGlvbiBhcHBseVN1YnN0aXR1dGlvbnMocGFyYW1zOiBBcHBseVN1YnN0aXR1dGlvbnNQYXJhbXMpOiBNYXliZVJldHVybjxzdHJpbmc+IHtcbiAgc3dpdGNoIChwYXJhbXMua2V5KSB7XG4gICAgY2FzZSBUb2tlblN1YnN0aXR1dGlvbktleS5DaXJjdWxhclJlZmVyZW5jZToge1xuICAgICAgcmV0dXJuIHBhcmFtcy5zdWJzdGl0dXRpb25zLmNpcmN1bGFyUmVmZXJlbmNlO1xuICAgIH1cbiAgICBjYXNlIFRva2VuU3Vic3RpdHV0aW9uS2V5LkZ1bmN0aW9uOiB7XG4gICAgICByZXR1cm4gZW5zdXJlTm9uTnVsbGFibGUocGFyYW1zLmZ1bmN0aW9uVGV4dHNbcGFyYW1zLmluZGV4XSwgYEZ1bmN0aW9uIHdpdGggaW5kZXggJHtTdHJpbmcocGFyYW1zLmluZGV4KX0gbm90IGZvdW5kYCk7XG4gICAgfVxuICAgIGNhc2UgVG9rZW5TdWJzdGl0dXRpb25LZXkuTWF4RGVwdGhMaW1pdFJlYWNoZWQ6IHtcbiAgICAgIHJldHVybiBwYXJhbXMuc3Vic3RpdHV0aW9ucy5tYXhEZXB0aExpbWl0UmVhY2hlZDtcbiAgICB9XG4gICAgY2FzZSBUb2tlblN1YnN0aXR1dGlvbktleS5NYXhEZXB0aExpbWl0UmVhY2hlZEFycmF5OiB7XG4gICAgICByZXR1cm4gYEFycmF5KCR7U3RyaW5nKHBhcmFtcy5pbmRleCl9KWA7XG4gICAgfVxuICAgIGNhc2UgVG9rZW5TdWJzdGl0dXRpb25LZXkuVG9KU09ORmFpbGVkOiB7XG4gICAgICByZXR1cm4gcGFyYW1zLnN1YnN0aXR1dGlvbnMudG9KU09ORmFpbGVkO1xuICAgIH1cbiAgICBjYXNlIFRva2VuU3Vic3RpdHV0aW9uS2V5LlVuZGVmaW5lZDoge1xuICAgICAgcmV0dXJuICd1bmRlZmluZWQnO1xuICAgIH1cbiAgICAvKiB2OCBpZ25vcmUgc3RhcnQgLS0gRXhoYXVzdGl2ZSBzd2l0Y2ggZ3VhcmQ7IGRlZmF1bHQgYnJhbmNoIGlzIHVucmVhY2hhYmxlLiAqL1xuICAgIGRlZmF1bHQ6IHtcbiAgICAgIGFzc2VydE5ldmVyKHBhcmFtcy5rZXkpO1xuICAgIH1cbiAgICAgIC8qIHY4IGlnbm9yZSBzdG9wICovXG4gIH1cbn1cblxuZnVuY3Rpb24gYXNzaWduV2l0aE5vbkVudW1lcmFibGVQcm9wZXJ0aWVzSW1wbCh0YXJnZXQ6IG9iamVjdCwgLi4uc291cmNlczogb2JqZWN0W10pOiBvYmplY3Qge1xuICBmb3IgKGNvbnN0IHNvdXJjZSBvZiBzb3VyY2VzKSB7XG4gICAgY29uc3QgZGVzY3JpcHRvcnMgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9ycyhzb3VyY2UpO1xuXG4gICAgZm9yIChjb25zdCBba2V5LCBkZXNjcmlwdG9yXSBvZiBPYmplY3QuZW50cmllcyhkZXNjcmlwdG9ycykpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIC8vIEF2b2lkIHJlZGVmaW5pbmcgcmVhZC1vbmx5IHByb3BlcnRpZXMgKGVzcGVjaWFsbHkgYHByb3RvdHlwZWApXG4gICAgICAgIGlmIChcbiAgICAgICAgICBrZXkgPT09ICdwcm90b3R5cGUnXG4gICAgICAgICAgfHwgKE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IodGFyZ2V0LCBrZXkpPy53cml0YWJsZSA9PT0gZmFsc2VcbiAgICAgICAgICAgICYmICFPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKHRhcmdldCwga2V5KT8uY29uZmlndXJhYmxlKVxuICAgICAgICApIHtcbiAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0YXJnZXQsIGtleSwgZGVzY3JpcHRvcik7XG4gICAgICB9IGNhdGNoIHtcbiAgICAgICAgLy8gU2lsZW50bHkgaWdub3JlIGlmIGRlZmluZVByb3BlcnR5IGZhaWxzXG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgY29uc3Qgc291cmNlUHJvdG90eXBlcyA9IHNvdXJjZXNcbiAgICAubWFwKChzb3VyY2UpID0+IGdldFByb3RvdHlwZU9mPG9iamVjdCB8IHVuZGVmaW5lZD4oc291cmNlKSlcbiAgICAuZmlsdGVyKChwcm90b3R5cGUpOiBwcm90b3R5cGUgaXMgb2JqZWN0ID0+ICEhcHJvdG90eXBlKTtcblxuICBpZiAoc291cmNlUHJvdG90eXBlcy5sZW5ndGggPiAwKSB7XG4gICAgY29uc3QgdGFyZ2V0UHJvdG90eXBlID0gYXNzaWduV2l0aE5vbkVudW1lcmFibGVQcm9wZXJ0aWVzSW1wbCh7fSwgZ2V0UHJvdG90eXBlT2YodGFyZ2V0KSwgLi4uc291cmNlUHJvdG90eXBlcyk7XG5cbiAgICB0cnkge1xuICAgICAgT2JqZWN0LnNldFByb3RvdHlwZU9mKHRhcmdldCwgdGFyZ2V0UHJvdG90eXBlKTtcbiAgICB9IGNhdGNoIHtcbiAgICAgIC8vIFNpbGVudGx5IGlnbm9yZSBpZiBzZXRQcm90b3R5cGVPZiBmYWlsc1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiB0YXJnZXQ7XG59XG5cbi8qXG4gKiBUaGUgb25lIHBsYWNlIHdoZXJlIHRoZSBsaXN0J3MgaGV0ZXJvZ2VuZWl0eSBpcyBicmlkZ2VkLCBhbmQgaXQgbmVlZHMgYSBjYXN0IGJlY2F1c2UgdGhlIGNvcnJlbGF0aW9uIHRoYXQgbWFrZXMgaXRcbiAqIHNhZmUgaXMgYSBydW50aW1lIG9uZTogYHRyeUVudHJ5RXF1YWxpdHlgIGNhbGxzIHRoZSBjb21wYXJlciBvbmx5IGFmdGVyIGBhIGluc3RhbmNlb2YgZW50cnkuY29uc3RydWN0b3JgIGhhcyBoZWxkIGZvclxuICogYm90aCBvcGVyYW5kcywgYW5kIG5vIHR5cGUgY2FuIHRpZSB0aGF0IGBpbnN0YW5jZW9mYCB0byB0aGlzIGVudHJ5J3MgYFRgLiBDb25maW5pbmcgdGhlIGNhc3QgaGVyZSBidXlzIHRoZSBjaGVjayB0aGVcbiAqIGxpc3QgdXNlZCB0byBsYWNrIC0gdGhlIGNvbnN0cnVjdG9yIGFuZCB0aGUgY29tcGFyZXIgYXJlIGluZmVycmVkIGZyb20gT05FIGBUYCwgc28gYSBtaXNtYXRjaGVkIHBhaXIgaXMgYSBjb21waWxlXG4gKiBlcnJvciBhdCB0aGUgY2FsbCBzaXRlIGluc3RlYWQgb2YgYmVpbmcgd2F2ZWQgdGhyb3VnaCBieSBhbiBgYW55YC10eXBlZCBlbnRyeSBhcnJheS5cbiAqL1xuZnVuY3Rpb24gY3JlYXRlRXF1YWxpdHlDb21wYXJlckVudHJ5PFQ+KGNvbnN0cnVjdG9yOiBDb25zdHJ1Y3RvcjxUPiwgY2hlY2tJc0VxdWFsOiAoYTogVCwgYjogVCkgPT4gYm9vbGVhbik6IEVxdWFsaXR5Q29tcGFyZXJFbnRyeTx1bmtub3duPiB7XG4gIHJldHVybiB7XG4gICAgY29uc3RydWN0b3IsXG4gICAgZXF1YWxpdHlDb21wYXJlcjogKGEsIGIpID0+IGNoZWNrSXNFcXVhbChhIGFzIFQsIGIgYXMgVClcbiAgfTtcbn1cblxuZnVuY3Rpb24gZGVlcEVxdWFsVHlwZWQoYTogdW5rbm93biwgYjogdW5rbm93bik6IGJvb2xlYW4gfCB1bmRlZmluZWQge1xuICBmb3IgKGNvbnN0IGVudHJ5IG9mIGVxdWFsaXR5Q29tcGFyZXJFbnRyaWVzKSB7XG4gICAgY29uc3QgcmVzdWx0ID0gdHJ5RW50cnlFcXVhbGl0eSh7XG4gICAgICBhLFxuICAgICAgYixcbiAgICAgIGVudHJ5XG4gICAgfSk7XG4gICAgaWYgKHJlc3VsdCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cbiAgfVxuICByZXR1cm4gdW5kZWZpbmVkO1xufVxuXG5mdW5jdGlvbiBpc0RlZXBFcXVhbEFycmF5QnVmZmVyKGE6IEFycmF5QnVmZmVyLCBiOiBBcnJheUJ1ZmZlcik6IGJvb2xlYW4ge1xuICBpZiAoYS5ieXRlTGVuZ3RoICE9PSBiLmJ5dGVMZW5ndGgpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICBjb25zdCB2aWV3QSA9IG5ldyBVaW50OEFycmF5KGEpO1xuICBjb25zdCB2aWV3QiA9IG5ldyBVaW50OEFycmF5KGIpO1xuICByZXR1cm4gaXNEZWVwRXF1YWwodmlld0EsIHZpZXdCKTtcbn1cblxuZnVuY3Rpb24gaXNEZWVwRXF1YWxEYXRlKGE6IERhdGUsIGI6IERhdGUpOiBib29sZWFuIHtcbiAgcmV0dXJuIGEuZ2V0VGltZSgpID09PSBiLmdldFRpbWUoKTtcbn1cblxuZnVuY3Rpb24gaXNEZWVwRXF1YWxNYXAoYTogTWFwPHVua25vd24sIHVua25vd24+LCBiOiBNYXA8dW5rbm93biwgdW5rbm93bj4pOiBib29sZWFuIHtcbiAgaWYgKGEuc2l6ZSAhPT0gYi5zaXplKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgZm9yIChjb25zdCBba2V5LCB2YWx1ZV0gb2YgYSkge1xuICAgIGlmICghYi5oYXMoa2V5KSB8fCAhaXNEZWVwRXF1YWwodmFsdWUsIGIuZ2V0KGtleSkpKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHRydWU7XG59XG5cbmZ1bmN0aW9uIGlzRGVlcEVxdWFsUmVnRXhwKGE6IFJlZ0V4cCwgYjogUmVnRXhwKTogYm9vbGVhbiB7XG4gIHJldHVybiBhLnNvdXJjZSA9PT0gYi5zb3VyY2UgJiYgYS5mbGFncyA9PT0gYi5mbGFncztcbn1cblxuZnVuY3Rpb24gaXNEZWVwRXF1YWxTZXQoYTogU2V0PHVua25vd24+LCBiOiBTZXQ8dW5rbm93bj4pOiBib29sZWFuIHtcbiAgaWYgKGEuc2l6ZSAhPT0gYi5zaXplKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgZm9yIChjb25zdCB2YWx1ZUEgb2YgYSkge1xuICAgIGlmIChiLmhhcyh2YWx1ZUEpKSB7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG4gICAgbGV0IGhhc01hdGNoID0gZmFsc2U7XG4gICAgZm9yIChjb25zdCB2YWx1ZUIgb2YgYikge1xuICAgICAgaWYgKGlzRGVlcEVxdWFsKHZhbHVlQSwgdmFsdWVCKSkge1xuICAgICAgICBoYXNNYXRjaCA9IHRydWU7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH1cbiAgICBpZiAoIWhhc01hdGNoKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHRydWU7XG59XG5cbmZ1bmN0aW9uIG1ha2VPYmplY3RUb2tlblN1YnN0aXR1dGlvbihrZXk6IFRva2VuU3Vic3RpdHV0aW9uS2V5KTogc3RyaW5nIHtcbiAgcmV0dXJuIGB7IFwiW1ske2tleX1dXVwiOiBudWxsIH1gO1xufVxuXG5mdW5jdGlvbiBtYWtlUGxhY2Vob2xkZXIoa2V5OiBUb2tlblN1YnN0aXR1dGlvbktleSwgaW5kZXg/OiBudW1iZXIpOiBzdHJpbmcge1xuICByZXR1cm4gYFtbJHtQTEFDRUhPTERFUl9LRVlfUFJFRklYfSR7a2V5fSR7aW5kZXggPyBTdHJpbmcoaW5kZXgpIDogJyd9XV1gO1xufVxuXG5mdW5jdGlvbiB0cnlFbnRyeUVxdWFsaXR5KHBhcmFtczogVHJ5RW50cnlFcXVhbGl0eVBhcmFtcyk6IGJvb2xlYW4gfCB1bmRlZmluZWQge1xuICBjb25zdCB7XG4gICAgYSxcbiAgICBiLFxuICAgIGVudHJ5XG4gIH0gPSBwYXJhbXM7XG4gIHJldHVybiBhIGluc3RhbmNlb2YgZW50cnkuY29uc3RydWN0b3IgJiYgYiBpbnN0YW5jZW9mIGVudHJ5LmNvbnN0cnVjdG9yID8gZW50cnkuZXF1YWxpdHlDb21wYXJlcihhLCBiKSA6IHVuZGVmaW5lZDtcbn1cbiJdLAogICJtYXBwaW5ncyI6ICI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFtQkEsU0FBUyxxQkFBcUI7QUFDOUIsU0FBUyxtQ0FBbUM7QUFDNUMsU0FBUyxvQkFBb0I7QUFDN0IsU0FBUyxrQkFBa0I7QUFDM0I7QUFBQSxFQUNFO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxPQUNLO0FBS0EsSUFBSyx1QkFBTCxrQkFBS0EsMEJBQUw7QUFJTCxFQUFBQSxzQkFBQSxhQUFVO0FBSVYsRUFBQUEsc0JBQUEsVUFBTztBQUlQLEVBQUFBLHNCQUFBLGNBQVc7QUFaRCxTQUFBQTtBQUFBLEdBQUE7QUF5SFosTUFBTSxnQkFBZ0I7QUFDdEIsTUFBTSx5QkFBeUI7QUFDL0IsTUFBTSwwQkFBcUU7QUFBQSxFQUN6RSw0QkFBNEIsYUFBYSxzQkFBc0I7QUFBQSxFQUMvRCw0QkFBNEIsTUFBTSxlQUFlO0FBQUEsRUFDakQsNEJBQTRCLFFBQVEsaUJBQWlCO0FBQUEsRUFDckQsNEJBQW1ELEtBQUssY0FBYztBQUFBLEVBQ3RFLDRCQUEwQyxLQUFLLGNBQWM7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