@ng-formworks/core 16.3.0 → 17.3.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 (113) hide show
  1. package/esm2022/lib/framework-library/framework-library.service.mjs +174 -174
  2. package/esm2022/lib/framework-library/framework.mjs +14 -14
  3. package/esm2022/lib/framework-library/no-framework.component.mjs +17 -17
  4. package/esm2022/lib/framework-library/no-framework.module.mjs +26 -26
  5. package/esm2022/lib/framework-library/no.framework.mjs +18 -18
  6. package/esm2022/lib/json-schema-form.component.mjs +765 -765
  7. package/esm2022/lib/json-schema-form.module.mjs +25 -25
  8. package/esm2022/lib/json-schema-form.service.mjs +675 -675
  9. package/esm2022/lib/locale/de-validation-messages.mjs +59 -59
  10. package/esm2022/lib/locale/en-validation-messages.mjs +59 -59
  11. package/esm2022/lib/locale/es-validation-messages.mjs +56 -56
  12. package/esm2022/lib/locale/fr-validation-messages.mjs +59 -59
  13. package/esm2022/lib/locale/index.mjs +7 -7
  14. package/esm2022/lib/locale/it-validation-messages.mjs +59 -59
  15. package/esm2022/lib/locale/pt-validation-messages.mjs +59 -59
  16. package/esm2022/lib/locale/zh-validation-messages.mjs +59 -59
  17. package/esm2022/lib/shared/convert-schema-to-draft6.function.mjs +299 -299
  18. package/esm2022/lib/shared/form-group.functions.mjs +441 -441
  19. package/esm2022/lib/shared/format-regex.constants.mjs +53 -53
  20. package/esm2022/lib/shared/index.mjs +11 -11
  21. package/esm2022/lib/shared/json-schema.functions.mjs +783 -783
  22. package/esm2022/lib/shared/json.validators.mjs +883 -883
  23. package/esm2022/lib/shared/jsonpointer.functions.mjs +1025 -1025
  24. package/esm2022/lib/shared/layout.functions.mjs +1153 -1153
  25. package/esm2022/lib/shared/merge-schemas.function.mjs +344 -344
  26. package/esm2022/lib/shared/utility.functions.mjs +379 -379
  27. package/esm2022/lib/shared/validator.functions.mjs +583 -583
  28. package/esm2022/lib/widget-library/add-reference.component.mjs +48 -48
  29. package/esm2022/lib/widget-library/button.component.mjs +41 -41
  30. package/esm2022/lib/widget-library/checkbox.component.mjs +46 -46
  31. package/esm2022/lib/widget-library/checkboxes.component.mjs +52 -52
  32. package/esm2022/lib/widget-library/file.component.mjs +35 -35
  33. package/esm2022/lib/widget-library/hidden.component.mjs +33 -33
  34. package/esm2022/lib/widget-library/index.mjs +54 -54
  35. package/esm2022/lib/widget-library/input.component.mjs +38 -38
  36. package/esm2022/lib/widget-library/message.component.mjs +33 -33
  37. package/esm2022/lib/widget-library/none.component.mjs +20 -20
  38. package/esm2022/lib/widget-library/number.component.mjs +44 -44
  39. package/esm2022/lib/widget-library/one-of.component.mjs +35 -35
  40. package/esm2022/lib/widget-library/orderable.directive.mjs +123 -123
  41. package/esm2022/lib/widget-library/radios.component.mjs +44 -44
  42. package/esm2022/lib/widget-library/root.component.mjs +44 -44
  43. package/esm2022/lib/widget-library/section.component.mjs +78 -78
  44. package/esm2022/lib/widget-library/select-framework.component.mjs +51 -51
  45. package/esm2022/lib/widget-library/select-widget.component.mjs +46 -46
  46. package/esm2022/lib/widget-library/select.component.mjs +41 -41
  47. package/esm2022/lib/widget-library/submit.component.mjs +55 -55
  48. package/esm2022/lib/widget-library/tab.component.mjs +30 -30
  49. package/esm2022/lib/widget-library/tabs.component.mjs +53 -53
  50. package/esm2022/lib/widget-library/template.component.mjs +46 -46
  51. package/esm2022/lib/widget-library/textarea.component.mjs +37 -37
  52. package/esm2022/lib/widget-library/widget-library.module.mjs +41 -41
  53. package/esm2022/lib/widget-library/widget-library.service.mjs +225 -225
  54. package/esm2022/ng-formworks-core.mjs +4 -4
  55. package/esm2022/public_api.mjs +12 -12
  56. package/fesm2022/ng-formworks-core.mjs +9103 -9103
  57. package/fesm2022/ng-formworks-core.mjs.map +1 -1
  58. package/index.d.ts +5 -5
  59. package/lib/framework-library/framework-library.service.d.ts +55 -55
  60. package/lib/framework-library/framework.d.ts +13 -13
  61. package/lib/framework-library/no-framework.component.d.ts +8 -8
  62. package/lib/framework-library/no-framework.module.d.ts +9 -9
  63. package/lib/framework-library/no.framework.d.ts +10 -10
  64. package/lib/json-schema-form.component.d.ts +218 -218
  65. package/lib/json-schema-form.module.d.ts +11 -11
  66. package/lib/json-schema-form.service.d.ts +115 -115
  67. package/lib/locale/de-validation-messages.d.ts +1 -1
  68. package/lib/locale/en-validation-messages.d.ts +1 -1
  69. package/lib/locale/es-validation-messages.d.ts +1 -1
  70. package/lib/locale/fr-validation-messages.d.ts +1 -1
  71. package/lib/locale/index.d.ts +7 -7
  72. package/lib/locale/it-validation-messages.d.ts +1 -1
  73. package/lib/locale/pt-validation-messages.d.ts +1 -1
  74. package/lib/locale/zh-validation-messages.d.ts +1 -1
  75. package/lib/shared/convert-schema-to-draft6.function.d.ts +21 -21
  76. package/lib/shared/form-group.functions.d.ts +100 -100
  77. package/lib/shared/format-regex.constants.d.ts +19 -19
  78. package/lib/shared/index.d.ts +9 -9
  79. package/lib/shared/json-schema.functions.d.ts +193 -193
  80. package/lib/shared/json.validators.d.ts +441 -441
  81. package/lib/shared/jsonpointer.functions.d.ts +416 -416
  82. package/lib/shared/layout.functions.d.ts +83 -83
  83. package/lib/shared/merge-schemas.function.d.ts +19 -19
  84. package/lib/shared/utility.functions.d.ts +165 -165
  85. package/lib/shared/validator.functions.d.ts +364 -364
  86. package/lib/widget-library/add-reference.component.d.ts +20 -20
  87. package/lib/widget-library/button.component.d.ts +21 -21
  88. package/lib/widget-library/checkbox.component.d.ts +24 -24
  89. package/lib/widget-library/checkboxes.component.d.ts +24 -24
  90. package/lib/widget-library/file.component.d.ts +21 -21
  91. package/lib/widget-library/hidden.component.d.ts +19 -19
  92. package/lib/widget-library/index.d.ts +47 -47
  93. package/lib/widget-library/input.component.d.ts +22 -22
  94. package/lib/widget-library/message.component.d.ts +15 -15
  95. package/lib/widget-library/none.component.d.ts +8 -8
  96. package/lib/widget-library/number.component.d.ts +25 -25
  97. package/lib/widget-library/one-of.component.d.ts +21 -21
  98. package/lib/widget-library/orderable.directive.d.ts +41 -41
  99. package/lib/widget-library/radios.component.d.ts +23 -23
  100. package/lib/widget-library/root.component.d.ts +17 -17
  101. package/lib/widget-library/section.component.d.ts +19 -19
  102. package/lib/widget-library/select-framework.component.d.ts +18 -18
  103. package/lib/widget-library/select-widget.component.d.ts +18 -18
  104. package/lib/widget-library/select.component.d.ts +24 -24
  105. package/lib/widget-library/submit.component.d.ts +24 -24
  106. package/lib/widget-library/tab.component.d.ts +14 -14
  107. package/lib/widget-library/tabs.component.d.ts +20 -20
  108. package/lib/widget-library/template.component.d.ts +18 -18
  109. package/lib/widget-library/textarea.component.d.ts +21 -21
  110. package/lib/widget-library/widget-library.module.d.ts +31 -31
  111. package/lib/widget-library/widget-library.service.d.ts +22 -22
  112. package/package.json +5 -5
  113. package/public_api.d.ts +9 -9
@@ -1,345 +1,345 @@
1
- import isEqual from 'lodash/isEqual';
2
- import { isArray, isEmpty, isNumber, isObject, isString } from './validator.functions';
3
- import { hasOwn, uniqueItems, commonItems } from './utility.functions';
4
- /**
5
- * 'mergeSchemas' function
6
- *
7
- * Merges multiple JSON schemas into a single schema with combined rules.
8
- *
9
- * If able to logically merge properties from all schemas,
10
- * returns a single schema object containing all merged properties.
11
- *
12
- * Example: ({ a: b, max: 1 }, { c: d, max: 2 }) => { a: b, c: d, max: 1 }
13
- *
14
- * If unable to logically merge, returns an allOf schema object containing
15
- * an array of the original schemas;
16
- *
17
- * Example: ({ a: b }, { a: d }) => { allOf: [ { a: b }, { a: d } ] }
18
- *
19
- * // schemas - one or more input schemas
20
- * // - merged schema
21
- */
22
- export function mergeSchemas(...schemas) {
23
- schemas = schemas.filter(schema => !isEmpty(schema));
24
- if (schemas.some(schema => !isObject(schema))) {
25
- return null;
26
- }
27
- const combinedSchema = {};
28
- for (const schema of schemas) {
29
- for (const key of Object.keys(schema)) {
30
- const combinedValue = combinedSchema[key];
31
- const schemaValue = schema[key];
32
- if (!hasOwn(combinedSchema, key) || isEqual(combinedValue, schemaValue)) {
33
- combinedSchema[key] = schemaValue;
34
- }
35
- else {
36
- switch (key) {
37
- case 'allOf':
38
- // Combine all items from both arrays
39
- if (isArray(combinedValue) && isArray(schemaValue)) {
40
- combinedSchema.allOf = mergeSchemas(...combinedValue, ...schemaValue);
41
- }
42
- else {
43
- return { allOf: [...schemas] };
44
- }
45
- break;
46
- case 'additionalItems':
47
- case 'additionalProperties':
48
- case 'contains':
49
- case 'propertyNames':
50
- // Merge schema objects
51
- if (isObject(combinedValue) && isObject(schemaValue)) {
52
- combinedSchema[key] = mergeSchemas(combinedValue, schemaValue);
53
- // additionalProperties == false in any schema overrides all other values
54
- }
55
- else if (key === 'additionalProperties' &&
56
- (combinedValue === false || schemaValue === false)) {
57
- combinedSchema.combinedSchema = false;
58
- }
59
- else {
60
- return { allOf: [...schemas] };
61
- }
62
- break;
63
- case 'anyOf':
64
- case 'oneOf':
65
- case 'enum':
66
- // Keep only items that appear in both arrays
67
- if (isArray(combinedValue) && isArray(schemaValue)) {
68
- combinedSchema[key] = combinedValue.filter(item1 => schemaValue.findIndex(item2 => isEqual(item1, item2)) > -1);
69
- if (!combinedSchema[key].length) {
70
- return { allOf: [...schemas] };
71
- }
72
- }
73
- else {
74
- return { allOf: [...schemas] };
75
- }
76
- break;
77
- case 'definitions':
78
- // Combine keys from both objects
79
- if (isObject(combinedValue) && isObject(schemaValue)) {
80
- const combinedObject = { ...combinedValue };
81
- for (const subKey of Object.keys(schemaValue)) {
82
- if (!hasOwn(combinedObject, subKey) ||
83
- isEqual(combinedObject[subKey], schemaValue[subKey])) {
84
- combinedObject[subKey] = schemaValue[subKey];
85
- // Don't combine matching keys with different values
86
- }
87
- else {
88
- return { allOf: [...schemas] };
89
- }
90
- }
91
- combinedSchema.definitions = combinedObject;
92
- }
93
- else {
94
- return { allOf: [...schemas] };
95
- }
96
- break;
97
- case 'dependencies':
98
- // Combine all keys from both objects
99
- // and merge schemas on matching keys,
100
- // converting from arrays to objects if necessary
101
- if (isObject(combinedValue) && isObject(schemaValue)) {
102
- const combinedObject = { ...combinedValue };
103
- for (const subKey of Object.keys(schemaValue)) {
104
- if (!hasOwn(combinedObject, subKey) ||
105
- isEqual(combinedObject[subKey], schemaValue[subKey])) {
106
- combinedObject[subKey] = schemaValue[subKey];
107
- // If both keys are arrays, include all items from both arrays,
108
- // excluding duplicates
109
- }
110
- else if (isArray(schemaValue[subKey]) && isArray(combinedObject[subKey])) {
111
- combinedObject[subKey] =
112
- uniqueItems(...combinedObject[subKey], ...schemaValue[subKey]);
113
- // If either key is an object, merge the schemas
114
- }
115
- else if ((isArray(schemaValue[subKey]) || isObject(schemaValue[subKey])) &&
116
- (isArray(combinedObject[subKey]) || isObject(combinedObject[subKey]))) {
117
- // If either key is an array, convert it to an object first
118
- const required = isArray(combinedSchema.required) ?
119
- combinedSchema.required : [];
120
- const combinedDependency = isArray(combinedObject[subKey]) ?
121
- { required: uniqueItems(...required, combinedObject[subKey]) } :
122
- combinedObject[subKey];
123
- const schemaDependency = isArray(schemaValue[subKey]) ?
124
- { required: uniqueItems(...required, schemaValue[subKey]) } :
125
- schemaValue[subKey];
126
- combinedObject[subKey] =
127
- mergeSchemas(combinedDependency, schemaDependency);
128
- }
129
- else {
130
- return { allOf: [...schemas] };
131
- }
132
- }
133
- combinedSchema.dependencies = combinedObject;
134
- }
135
- else {
136
- return { allOf: [...schemas] };
137
- }
138
- break;
139
- case 'items':
140
- // If arrays, keep only items that appear in both arrays
141
- if (isArray(combinedValue) && isArray(schemaValue)) {
142
- combinedSchema.items = combinedValue.filter(item1 => schemaValue.findIndex(item2 => isEqual(item1, item2)) > -1);
143
- if (!combinedSchema.items.length) {
144
- return { allOf: [...schemas] };
145
- }
146
- // If both keys are objects, merge them
147
- }
148
- else if (isObject(combinedValue) && isObject(schemaValue)) {
149
- combinedSchema.items = mergeSchemas(combinedValue, schemaValue);
150
- // If object + array, combine object with each array item
151
- }
152
- else if (isArray(combinedValue) && isObject(schemaValue)) {
153
- combinedSchema.items =
154
- combinedValue.map(item => mergeSchemas(item, schemaValue));
155
- }
156
- else if (isObject(combinedValue) && isArray(schemaValue)) {
157
- combinedSchema.items =
158
- schemaValue.map(item => mergeSchemas(item, combinedValue));
159
- }
160
- else {
161
- return { allOf: [...schemas] };
162
- }
163
- break;
164
- case 'multipleOf':
165
- // TODO: Adjust to correctly handle decimal values
166
- // If numbers, set to least common multiple
167
- if (isNumber(combinedValue) && isNumber(schemaValue)) {
168
- const gcd = (x, y) => !y ? x : gcd(y, x % y);
169
- const lcm = (x, y) => (x * y) / gcd(x, y);
170
- combinedSchema.multipleOf = lcm(combinedValue, schemaValue);
171
- }
172
- else {
173
- return { allOf: [...schemas] };
174
- }
175
- break;
176
- case 'maximum':
177
- case 'exclusiveMaximum':
178
- case 'maxLength':
179
- case 'maxItems':
180
- case 'maxProperties':
181
- // If numbers, set to lowest value
182
- if (isNumber(combinedValue) && isNumber(schemaValue)) {
183
- combinedSchema[key] = Math.min(combinedValue, schemaValue);
184
- }
185
- else {
186
- return { allOf: [...schemas] };
187
- }
188
- break;
189
- case 'minimum':
190
- case 'exclusiveMinimum':
191
- case 'minLength':
192
- case 'minItems':
193
- case 'minProperties':
194
- // If numbers, set to highest value
195
- if (isNumber(combinedValue) && isNumber(schemaValue)) {
196
- combinedSchema[key] = Math.max(combinedValue, schemaValue);
197
- }
198
- else {
199
- return { allOf: [...schemas] };
200
- }
201
- break;
202
- case 'not':
203
- // Combine not values into anyOf array
204
- if (isObject(combinedValue) && isObject(schemaValue)) {
205
- const notAnyOf = [combinedValue, schemaValue]
206
- .reduce((notAnyOfArray, notSchema) => isArray(notSchema.anyOf) &&
207
- Object.keys(notSchema).length === 1 ?
208
- [...notAnyOfArray, ...notSchema.anyOf] :
209
- [...notAnyOfArray, notSchema], []);
210
- // TODO: Remove duplicate items from array
211
- combinedSchema.not = { anyOf: notAnyOf };
212
- }
213
- else {
214
- return { allOf: [...schemas] };
215
- }
216
- break;
217
- case 'patternProperties':
218
- // Combine all keys from both objects
219
- // and merge schemas on matching keys
220
- if (isObject(combinedValue) && isObject(schemaValue)) {
221
- const combinedObject = { ...combinedValue };
222
- for (const subKey of Object.keys(schemaValue)) {
223
- if (!hasOwn(combinedObject, subKey) ||
224
- isEqual(combinedObject[subKey], schemaValue[subKey])) {
225
- combinedObject[subKey] = schemaValue[subKey];
226
- // If both keys are objects, merge them
227
- }
228
- else if (isObject(schemaValue[subKey]) && isObject(combinedObject[subKey])) {
229
- combinedObject[subKey] =
230
- mergeSchemas(combinedObject[subKey], schemaValue[subKey]);
231
- }
232
- else {
233
- return { allOf: [...schemas] };
234
- }
235
- }
236
- combinedSchema.patternProperties = combinedObject;
237
- }
238
- else {
239
- return { allOf: [...schemas] };
240
- }
241
- break;
242
- case 'properties':
243
- // Combine all keys from both objects
244
- // unless additionalProperties === false
245
- // and merge schemas on matching keys
246
- if (isObject(combinedValue) && isObject(schemaValue)) {
247
- const combinedObject = { ...combinedValue };
248
- // If new schema has additionalProperties,
249
- // merge or remove non-matching property keys in combined schema
250
- if (hasOwn(schemaValue, 'additionalProperties')) {
251
- Object.keys(combinedValue)
252
- .filter(combinedKey => !Object.keys(schemaValue).includes(combinedKey))
253
- .forEach(nonMatchingKey => {
254
- if (schemaValue.additionalProperties === false) {
255
- delete combinedObject[nonMatchingKey];
256
- }
257
- else if (isObject(schemaValue.additionalProperties)) {
258
- combinedObject[nonMatchingKey] = mergeSchemas(combinedObject[nonMatchingKey], schemaValue.additionalProperties);
259
- }
260
- });
261
- }
262
- for (const subKey of Object.keys(schemaValue)) {
263
- if (isEqual(combinedObject[subKey], schemaValue[subKey]) || (!hasOwn(combinedObject, subKey) &&
264
- !hasOwn(combinedObject, 'additionalProperties'))) {
265
- combinedObject[subKey] = schemaValue[subKey];
266
- // If combined schema has additionalProperties,
267
- // merge or ignore non-matching property keys in new schema
268
- }
269
- else if (!hasOwn(combinedObject, subKey) &&
270
- hasOwn(combinedObject, 'additionalProperties')) {
271
- // If combinedObject.additionalProperties === false,
272
- // do nothing (don't set key)
273
- // If additionalProperties is object, merge with new key
274
- if (isObject(combinedObject.additionalProperties)) {
275
- combinedObject[subKey] = mergeSchemas(combinedObject.additionalProperties, schemaValue[subKey]);
276
- }
277
- // If both keys are objects, merge them
278
- }
279
- else if (isObject(schemaValue[subKey]) &&
280
- isObject(combinedObject[subKey])) {
281
- combinedObject[subKey] =
282
- mergeSchemas(combinedObject[subKey], schemaValue[subKey]);
283
- }
284
- else {
285
- return { allOf: [...schemas] };
286
- }
287
- }
288
- combinedSchema.properties = combinedObject;
289
- }
290
- else {
291
- return { allOf: [...schemas] };
292
- }
293
- break;
294
- case 'required':
295
- // If arrays, include all items from both arrays, excluding duplicates
296
- if (isArray(combinedValue) && isArray(schemaValue)) {
297
- combinedSchema.required = uniqueItems(...combinedValue, ...schemaValue);
298
- // If booleans, aet true if either true
299
- }
300
- else if (typeof schemaValue === 'boolean' &&
301
- typeof combinedValue === 'boolean') {
302
- combinedSchema.required = !!combinedValue || !!schemaValue;
303
- }
304
- else {
305
- return { allOf: [...schemas] };
306
- }
307
- break;
308
- case '$schema':
309
- case '$id':
310
- case 'id':
311
- // Don't combine these keys
312
- break;
313
- case 'title':
314
- case 'description':
315
- case '$comment':
316
- // Return the last value, overwriting any previous one
317
- // These properties are not used for validation, so conflicts don't matter
318
- combinedSchema[key] = schemaValue;
319
- break;
320
- case 'type':
321
- if ((isArray(schemaValue) || isString(schemaValue)) &&
322
- (isArray(combinedValue) || isString(combinedValue))) {
323
- const combinedTypes = commonItems(combinedValue, schemaValue);
324
- if (!combinedTypes.length) {
325
- return { allOf: [...schemas] };
326
- }
327
- combinedSchema.type = combinedTypes.length > 1 ? combinedTypes : combinedTypes[0];
328
- }
329
- else {
330
- return { allOf: [...schemas] };
331
- }
332
- break;
333
- case 'uniqueItems':
334
- // Set true if either true
335
- combinedSchema.uniqueItems = !!combinedValue || !!schemaValue;
336
- break;
337
- default:
338
- return { allOf: [...schemas] };
339
- }
340
- }
341
- }
342
- }
343
- return combinedSchema;
344
- }
1
+ import isEqual from 'lodash/isEqual';
2
+ import { isArray, isEmpty, isNumber, isObject, isString } from './validator.functions';
3
+ import { hasOwn, uniqueItems, commonItems } from './utility.functions';
4
+ /**
5
+ * 'mergeSchemas' function
6
+ *
7
+ * Merges multiple JSON schemas into a single schema with combined rules.
8
+ *
9
+ * If able to logically merge properties from all schemas,
10
+ * returns a single schema object containing all merged properties.
11
+ *
12
+ * Example: ({ a: b, max: 1 }, { c: d, max: 2 }) => { a: b, c: d, max: 1 }
13
+ *
14
+ * If unable to logically merge, returns an allOf schema object containing
15
+ * an array of the original schemas;
16
+ *
17
+ * Example: ({ a: b }, { a: d }) => { allOf: [ { a: b }, { a: d } ] }
18
+ *
19
+ * // schemas - one or more input schemas
20
+ * // - merged schema
21
+ */
22
+ export function mergeSchemas(...schemas) {
23
+ schemas = schemas.filter(schema => !isEmpty(schema));
24
+ if (schemas.some(schema => !isObject(schema))) {
25
+ return null;
26
+ }
27
+ const combinedSchema = {};
28
+ for (const schema of schemas) {
29
+ for (const key of Object.keys(schema)) {
30
+ const combinedValue = combinedSchema[key];
31
+ const schemaValue = schema[key];
32
+ if (!hasOwn(combinedSchema, key) || isEqual(combinedValue, schemaValue)) {
33
+ combinedSchema[key] = schemaValue;
34
+ }
35
+ else {
36
+ switch (key) {
37
+ case 'allOf':
38
+ // Combine all items from both arrays
39
+ if (isArray(combinedValue) && isArray(schemaValue)) {
40
+ combinedSchema.allOf = mergeSchemas(...combinedValue, ...schemaValue);
41
+ }
42
+ else {
43
+ return { allOf: [...schemas] };
44
+ }
45
+ break;
46
+ case 'additionalItems':
47
+ case 'additionalProperties':
48
+ case 'contains':
49
+ case 'propertyNames':
50
+ // Merge schema objects
51
+ if (isObject(combinedValue) && isObject(schemaValue)) {
52
+ combinedSchema[key] = mergeSchemas(combinedValue, schemaValue);
53
+ // additionalProperties == false in any schema overrides all other values
54
+ }
55
+ else if (key === 'additionalProperties' &&
56
+ (combinedValue === false || schemaValue === false)) {
57
+ combinedSchema.combinedSchema = false;
58
+ }
59
+ else {
60
+ return { allOf: [...schemas] };
61
+ }
62
+ break;
63
+ case 'anyOf':
64
+ case 'oneOf':
65
+ case 'enum':
66
+ // Keep only items that appear in both arrays
67
+ if (isArray(combinedValue) && isArray(schemaValue)) {
68
+ combinedSchema[key] = combinedValue.filter(item1 => schemaValue.findIndex(item2 => isEqual(item1, item2)) > -1);
69
+ if (!combinedSchema[key].length) {
70
+ return { allOf: [...schemas] };
71
+ }
72
+ }
73
+ else {
74
+ return { allOf: [...schemas] };
75
+ }
76
+ break;
77
+ case 'definitions':
78
+ // Combine keys from both objects
79
+ if (isObject(combinedValue) && isObject(schemaValue)) {
80
+ const combinedObject = { ...combinedValue };
81
+ for (const subKey of Object.keys(schemaValue)) {
82
+ if (!hasOwn(combinedObject, subKey) ||
83
+ isEqual(combinedObject[subKey], schemaValue[subKey])) {
84
+ combinedObject[subKey] = schemaValue[subKey];
85
+ // Don't combine matching keys with different values
86
+ }
87
+ else {
88
+ return { allOf: [...schemas] };
89
+ }
90
+ }
91
+ combinedSchema.definitions = combinedObject;
92
+ }
93
+ else {
94
+ return { allOf: [...schemas] };
95
+ }
96
+ break;
97
+ case 'dependencies':
98
+ // Combine all keys from both objects
99
+ // and merge schemas on matching keys,
100
+ // converting from arrays to objects if necessary
101
+ if (isObject(combinedValue) && isObject(schemaValue)) {
102
+ const combinedObject = { ...combinedValue };
103
+ for (const subKey of Object.keys(schemaValue)) {
104
+ if (!hasOwn(combinedObject, subKey) ||
105
+ isEqual(combinedObject[subKey], schemaValue[subKey])) {
106
+ combinedObject[subKey] = schemaValue[subKey];
107
+ // If both keys are arrays, include all items from both arrays,
108
+ // excluding duplicates
109
+ }
110
+ else if (isArray(schemaValue[subKey]) && isArray(combinedObject[subKey])) {
111
+ combinedObject[subKey] =
112
+ uniqueItems(...combinedObject[subKey], ...schemaValue[subKey]);
113
+ // If either key is an object, merge the schemas
114
+ }
115
+ else if ((isArray(schemaValue[subKey]) || isObject(schemaValue[subKey])) &&
116
+ (isArray(combinedObject[subKey]) || isObject(combinedObject[subKey]))) {
117
+ // If either key is an array, convert it to an object first
118
+ const required = isArray(combinedSchema.required) ?
119
+ combinedSchema.required : [];
120
+ const combinedDependency = isArray(combinedObject[subKey]) ?
121
+ { required: uniqueItems(...required, combinedObject[subKey]) } :
122
+ combinedObject[subKey];
123
+ const schemaDependency = isArray(schemaValue[subKey]) ?
124
+ { required: uniqueItems(...required, schemaValue[subKey]) } :
125
+ schemaValue[subKey];
126
+ combinedObject[subKey] =
127
+ mergeSchemas(combinedDependency, schemaDependency);
128
+ }
129
+ else {
130
+ return { allOf: [...schemas] };
131
+ }
132
+ }
133
+ combinedSchema.dependencies = combinedObject;
134
+ }
135
+ else {
136
+ return { allOf: [...schemas] };
137
+ }
138
+ break;
139
+ case 'items':
140
+ // If arrays, keep only items that appear in both arrays
141
+ if (isArray(combinedValue) && isArray(schemaValue)) {
142
+ combinedSchema.items = combinedValue.filter(item1 => schemaValue.findIndex(item2 => isEqual(item1, item2)) > -1);
143
+ if (!combinedSchema.items.length) {
144
+ return { allOf: [...schemas] };
145
+ }
146
+ // If both keys are objects, merge them
147
+ }
148
+ else if (isObject(combinedValue) && isObject(schemaValue)) {
149
+ combinedSchema.items = mergeSchemas(combinedValue, schemaValue);
150
+ // If object + array, combine object with each array item
151
+ }
152
+ else if (isArray(combinedValue) && isObject(schemaValue)) {
153
+ combinedSchema.items =
154
+ combinedValue.map(item => mergeSchemas(item, schemaValue));
155
+ }
156
+ else if (isObject(combinedValue) && isArray(schemaValue)) {
157
+ combinedSchema.items =
158
+ schemaValue.map(item => mergeSchemas(item, combinedValue));
159
+ }
160
+ else {
161
+ return { allOf: [...schemas] };
162
+ }
163
+ break;
164
+ case 'multipleOf':
165
+ // TODO: Adjust to correctly handle decimal values
166
+ // If numbers, set to least common multiple
167
+ if (isNumber(combinedValue) && isNumber(schemaValue)) {
168
+ const gcd = (x, y) => !y ? x : gcd(y, x % y);
169
+ const lcm = (x, y) => (x * y) / gcd(x, y);
170
+ combinedSchema.multipleOf = lcm(combinedValue, schemaValue);
171
+ }
172
+ else {
173
+ return { allOf: [...schemas] };
174
+ }
175
+ break;
176
+ case 'maximum':
177
+ case 'exclusiveMaximum':
178
+ case 'maxLength':
179
+ case 'maxItems':
180
+ case 'maxProperties':
181
+ // If numbers, set to lowest value
182
+ if (isNumber(combinedValue) && isNumber(schemaValue)) {
183
+ combinedSchema[key] = Math.min(combinedValue, schemaValue);
184
+ }
185
+ else {
186
+ return { allOf: [...schemas] };
187
+ }
188
+ break;
189
+ case 'minimum':
190
+ case 'exclusiveMinimum':
191
+ case 'minLength':
192
+ case 'minItems':
193
+ case 'minProperties':
194
+ // If numbers, set to highest value
195
+ if (isNumber(combinedValue) && isNumber(schemaValue)) {
196
+ combinedSchema[key] = Math.max(combinedValue, schemaValue);
197
+ }
198
+ else {
199
+ return { allOf: [...schemas] };
200
+ }
201
+ break;
202
+ case 'not':
203
+ // Combine not values into anyOf array
204
+ if (isObject(combinedValue) && isObject(schemaValue)) {
205
+ const notAnyOf = [combinedValue, schemaValue]
206
+ .reduce((notAnyOfArray, notSchema) => isArray(notSchema.anyOf) &&
207
+ Object.keys(notSchema).length === 1 ?
208
+ [...notAnyOfArray, ...notSchema.anyOf] :
209
+ [...notAnyOfArray, notSchema], []);
210
+ // TODO: Remove duplicate items from array
211
+ combinedSchema.not = { anyOf: notAnyOf };
212
+ }
213
+ else {
214
+ return { allOf: [...schemas] };
215
+ }
216
+ break;
217
+ case 'patternProperties':
218
+ // Combine all keys from both objects
219
+ // and merge schemas on matching keys
220
+ if (isObject(combinedValue) && isObject(schemaValue)) {
221
+ const combinedObject = { ...combinedValue };
222
+ for (const subKey of Object.keys(schemaValue)) {
223
+ if (!hasOwn(combinedObject, subKey) ||
224
+ isEqual(combinedObject[subKey], schemaValue[subKey])) {
225
+ combinedObject[subKey] = schemaValue[subKey];
226
+ // If both keys are objects, merge them
227
+ }
228
+ else if (isObject(schemaValue[subKey]) && isObject(combinedObject[subKey])) {
229
+ combinedObject[subKey] =
230
+ mergeSchemas(combinedObject[subKey], schemaValue[subKey]);
231
+ }
232
+ else {
233
+ return { allOf: [...schemas] };
234
+ }
235
+ }
236
+ combinedSchema.patternProperties = combinedObject;
237
+ }
238
+ else {
239
+ return { allOf: [...schemas] };
240
+ }
241
+ break;
242
+ case 'properties':
243
+ // Combine all keys from both objects
244
+ // unless additionalProperties === false
245
+ // and merge schemas on matching keys
246
+ if (isObject(combinedValue) && isObject(schemaValue)) {
247
+ const combinedObject = { ...combinedValue };
248
+ // If new schema has additionalProperties,
249
+ // merge or remove non-matching property keys in combined schema
250
+ if (hasOwn(schemaValue, 'additionalProperties')) {
251
+ Object.keys(combinedValue)
252
+ .filter(combinedKey => !Object.keys(schemaValue).includes(combinedKey))
253
+ .forEach(nonMatchingKey => {
254
+ if (schemaValue.additionalProperties === false) {
255
+ delete combinedObject[nonMatchingKey];
256
+ }
257
+ else if (isObject(schemaValue.additionalProperties)) {
258
+ combinedObject[nonMatchingKey] = mergeSchemas(combinedObject[nonMatchingKey], schemaValue.additionalProperties);
259
+ }
260
+ });
261
+ }
262
+ for (const subKey of Object.keys(schemaValue)) {
263
+ if (isEqual(combinedObject[subKey], schemaValue[subKey]) || (!hasOwn(combinedObject, subKey) &&
264
+ !hasOwn(combinedObject, 'additionalProperties'))) {
265
+ combinedObject[subKey] = schemaValue[subKey];
266
+ // If combined schema has additionalProperties,
267
+ // merge or ignore non-matching property keys in new schema
268
+ }
269
+ else if (!hasOwn(combinedObject, subKey) &&
270
+ hasOwn(combinedObject, 'additionalProperties')) {
271
+ // If combinedObject.additionalProperties === false,
272
+ // do nothing (don't set key)
273
+ // If additionalProperties is object, merge with new key
274
+ if (isObject(combinedObject.additionalProperties)) {
275
+ combinedObject[subKey] = mergeSchemas(combinedObject.additionalProperties, schemaValue[subKey]);
276
+ }
277
+ // If both keys are objects, merge them
278
+ }
279
+ else if (isObject(schemaValue[subKey]) &&
280
+ isObject(combinedObject[subKey])) {
281
+ combinedObject[subKey] =
282
+ mergeSchemas(combinedObject[subKey], schemaValue[subKey]);
283
+ }
284
+ else {
285
+ return { allOf: [...schemas] };
286
+ }
287
+ }
288
+ combinedSchema.properties = combinedObject;
289
+ }
290
+ else {
291
+ return { allOf: [...schemas] };
292
+ }
293
+ break;
294
+ case 'required':
295
+ // If arrays, include all items from both arrays, excluding duplicates
296
+ if (isArray(combinedValue) && isArray(schemaValue)) {
297
+ combinedSchema.required = uniqueItems(...combinedValue, ...schemaValue);
298
+ // If booleans, aet true if either true
299
+ }
300
+ else if (typeof schemaValue === 'boolean' &&
301
+ typeof combinedValue === 'boolean') {
302
+ combinedSchema.required = !!combinedValue || !!schemaValue;
303
+ }
304
+ else {
305
+ return { allOf: [...schemas] };
306
+ }
307
+ break;
308
+ case '$schema':
309
+ case '$id':
310
+ case 'id':
311
+ // Don't combine these keys
312
+ break;
313
+ case 'title':
314
+ case 'description':
315
+ case '$comment':
316
+ // Return the last value, overwriting any previous one
317
+ // These properties are not used for validation, so conflicts don't matter
318
+ combinedSchema[key] = schemaValue;
319
+ break;
320
+ case 'type':
321
+ if ((isArray(schemaValue) || isString(schemaValue)) &&
322
+ (isArray(combinedValue) || isString(combinedValue))) {
323
+ const combinedTypes = commonItems(combinedValue, schemaValue);
324
+ if (!combinedTypes.length) {
325
+ return { allOf: [...schemas] };
326
+ }
327
+ combinedSchema.type = combinedTypes.length > 1 ? combinedTypes : combinedTypes[0];
328
+ }
329
+ else {
330
+ return { allOf: [...schemas] };
331
+ }
332
+ break;
333
+ case 'uniqueItems':
334
+ // Set true if either true
335
+ combinedSchema.uniqueItems = !!combinedValue || !!schemaValue;
336
+ break;
337
+ default:
338
+ return { allOf: [...schemas] };
339
+ }
340
+ }
341
+ }
342
+ }
343
+ return combinedSchema;
344
+ }
345
345
  //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWVyZ2Utc2NoZW1hcy5mdW5jdGlvbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL25nLWZvcm13b3Jrcy1jb3JlL3NyYy9saWIvc2hhcmVkL21lcmdlLXNjaGVtYXMuZnVuY3Rpb24udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxPQUFPLE1BQU0sZ0JBQWdCLENBQUM7QUFFckMsT0FBTyxFQUNMLE9BQU8sRUFBRSxPQUFPLEVBQUUsUUFBUSxFQUFFLFFBQVEsRUFBRSxRQUFRLEVBQy9DLE1BQU0sdUJBQXVCLENBQUM7QUFDL0IsT0FBTyxFQUFFLE1BQU0sRUFBRSxXQUFXLEVBQUUsV0FBVyxFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFHdkU7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBaUJHO0FBQ0gsTUFBTSxVQUFVLFlBQVksQ0FBQyxHQUFHLE9BQU87SUFDckMsT0FBTyxHQUFHLE9BQU8sQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDO0lBQ3JELElBQUksT0FBTyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxDQUFDLEVBQUU7UUFBRSxPQUFPLElBQUksQ0FBQztLQUFFO0lBQy9ELE1BQU0sY0FBYyxHQUFRLEVBQUUsQ0FBQztJQUMvQixLQUFLLE1BQU0sTUFBTSxJQUFJLE9BQU8sRUFBRTtRQUM1QixLQUFLLE1BQU0sR0FBRyxJQUFJLE1BQU0sQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLEVBQUU7WUFDckMsTUFBTSxhQUFhLEdBQUcsY0FBYyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1lBQzFDLE1BQU0sV0FBVyxHQUFHLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQztZQUNoQyxJQUFJLENBQUMsTUFBTSxDQUFDLGNBQWMsRUFBRSxHQUFHLENBQUMsSUFB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RyxPQUFPLENBQUUsRUFBRSxDQUFDO3lCQUNsQzt3QkFDSCxNQUFNO29CQUNOLEtBQUssYUFBYTt3QkFDaEIsMEJBQTBCO3dCQUMxQixjQUFjLENBQUMsV0FBVyxHQUFHLENBQUMsQ0FBQyxhQUFhLElBQUksQ0FBQyxDQUFDLFdBQVcsQ0FBQzt3QkFDaEUsTUFBTTtvQkFDTjt3QkFDRSxPQUFPLEVBQUUsS0FBSyxFQUFFLENBQUUsR0FBRyxPQUFPLENBQUUsRUFBRSxDQUFDO2lCQUNwQzthQUNGO1NBQ0Y7S0FDRjtJQUNELE9BQU8sY0FBYyxDQUFDO0FBQ3hCLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgaXNFcXVhbCBmcm9tICdsb2Rhc2gvaXNFcXVhbCc7XHJcblxyXG5pbXBvcnQge1xyXG4gIGlzQXJyYXksIGlzRW1wdHksIGlzTnVtYmVyLCBpc09iamVjdCwgaXNTdHJpbmdcclxufSBmcm9tICcuL3ZhbGlkYXRvci5mdW5jdGlvbnMnO1xyXG5pbXBvcnQgeyBoYXNPd24sIHVuaXF1ZUl0ZW1zLCBjb21tb25JdGVtcyB9IGZyb20gJy4vdXRpbGl0eS5mdW5jdGlvbnMnO1xyXG5pbXBvcnQgeyBKc29uUG9pbnRlciwgUG9pbnRlciB9IGZyb20gJy4vanNvbnBvaW50ZXIuZnVuY3Rpb25zJztcclxuXHJcbi8qKlxyXG4gKiAnbWVyZ2VTY2hlbWFzJyBmdW5jdGlvblxyXG4gKlxyXG4gKiBNZXJnZXMgbXVsdGlwbGUgSlNPTiBzY2hlbWFzIGludG8gYSBzaW5nbGUgc2NoZW1hIHdpdGggY29tYmluZWQgcnVsZXMuXHJcbiAqXHJcbiAqIElmIGFibGUgdG8gbG9naWNhbGx5IG1lcmdlIHByb3BlcnRpZXMgZnJvbSBhbGwgc2NoZW1hcyxcclxuICogcmV0dXJucyBhIHNpbmdsZSBzY2hlbWEgb2JqZWN0IGNvbnRhaW5pbmcgYWxsIG1lcmdlZCBwcm9wZXJ0aWVzLlxyXG4gKlxyXG4gKiBFeGFtcGxlOiAoeyBhOiBiLCBtYXg6IDEgfSwgeyBjOiBkLCBtYXg6IDIgfSkgPT4geyBhOiBiLCBjOiBkLCBtYXg6IDEgfVxyXG4gKlxyXG4gKiBJZiB1bmFibGUgdG8gbG9naWNhbGx5IG1lcmdlLCByZXR1cm5zIGFuIGFsbE9mIHNjaGVtYSBvYmplY3QgY29udGFpbmluZ1xyXG4gKiBhbiBhcnJheSBvZiB0aGUgb3JpZ2luYWwgc2NoZW1hcztcclxuICpcclxuICogRXhhbXBsZTogKHsgYTogYiB9LCB7IGE6IGQgfSkgPT4geyBhbGxPZjogWyB7IGE6IGIgfSwgeyBhOiBkIH0gXSB9XHJcbiAqXHJcbiAqIC8vICAgc2NoZW1hcyAtIG9uZSBvciBtb3JlIGlucHV0IHNjaGVtYXNcclxuICogLy8gIC0gbWVyZ2VkIHNjaGVtYVxyXG4gKi9cclxuZXhwb3J0IGZ1bmN0aW9uIG1lcmdlU2NoZW1hcyguLi5zY2hlbWFzKSB7XHJcbiAgc2NoZW1hcyA9IHNjaGVtYXMuZmlsdGVyKHNjaGVtYSA9PiAhaXNFbXB0eShzY2hlbWEpKTtcclxuICBpZiAoc2NoZW1hcy5zb21lKHNjaGVtYSA9PiAhaXNPYmplY3Qoc2NoZW1hKSkpIHsgcmV0dXJuIG51bGw7IH1cclxuICBjb25zdCBjb21iaW5lZFNjaGVtYTogYW55ID0ge307XHJcbiAgZm9yIChjb25zdCBzY2hlbWEgb2Ygc2NoZW1hcykge1xyXG4gICAgZm9yIChjb25zdCBrZXkgb2YgT2JqZWN0LmtleXMoc2NoZW1hKSkge1xyXG4gICAgICBjb25zdCBjb21iaW5lZFZhbHVlID0gY29tYmluZWRTY2hlbWFba2V5XTtcclxuICAgICAgY29uc3Qgc2NoZW1hVmFsdWUgPSBzY2hlbWFba2V5XTtcclxuICAgICAgaWYgKCFoYXNPd24oY29tYmluZWRTY2hlbWEsIGtleSkgfHwgaXNFcXVhbChjb21iaW5lZFZhbHVlLCBzY2hlbWFWYWx1ZSkpIHtcclxuICAgICAgICBjb21iaW5lZFNjaGVtYVtrZXldID0gc2NoZW1hVmFsdWU7XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgc3dpdGNoIChrZXkpIHtcclxuICAgICAgICAgIGNhc2UgJ2FsbE9mJzpcclxuICAgICAgICAgICAgLy8gQ29tYmluZSBhbGwgaXRlbXMgZnJvbSBib3RoIGFycmF5c1xyXG4gICAgICAgICAgICBpZiAoaXNBcnJheShjb21iaW5lZFZhbHVlKSAmJiBpc0FycmF5KHNjaGVtYVZhbHVlKSkge1xyXG4gICAgICAgICAgICAgIGNvbWJpbmVkU2NoZW1hLmFsbE9mID0gbWVyZ2VTY2hlbWFzKC4uLmNvbWJpbmVkVmFsdWUsIC4uLnNjaGVtYVZhbHVlKTtcclxuICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICByZXR1cm4geyBhbGxPZjogWyAuLi5zY2hlbWFzIF0gfTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICBjYXNlICdhZGRpdGlvbmFsSXRlbXMnOiBjYXNlICdhZGRpdGlvbmFsUHJvcGVydGllcyc6XHJcbiAgICAgICAgICBjYXNlICdjb250YWlucyc6IGNhc2UgJ3Byb3BlcnR5TmFtZXMnOlxyXG4gICAgICAgICAgICAvLyBNZXJnZSBzY2hlbWEgb2JqZWN0c1xyXG4gICAgICAgICAgICBpZiAoaXNPYmplY3QoY29tYmluZWRWYWx1ZSkgJiYgaXNPYmplY3Qoc2NoZW1hVmFsdWUpKSB7XHJcbiAgICAgICAgICAgICAgY29tYmluZWRTY2hlbWFba2V5XSA9IG1lcmdlU2NoZW1hcyhjb21iaW5lZFZhbHVlLCBzY2hlbWFWYWx1ZSk7XHJcbiAgICAgICAgICAgIC8vIGFkZGl0aW9uYWxQcm9wZXJ0aWVzID09IGZhbHNlIGluIGFueSBzY2hlbWEgb3ZlcnJpZGVzIGFsbCBvdGhlciB2YWx1ZXNcclxuICAgICAgICAgICAgfSBlbHNlIGlmIChcclxuICAgICAgICAgICAgICBrZXkgPT09ICdhZGRpdGlvbmFsUHJvcGVydGllcycgJiZcclxuICAgICAgICAgICAgICAoY29tYmluZWRWYWx1ZSA9PT0gZmFsc2UgfHwgc2NoZW1hVmFsdWUgPT09IGZhbHNlKVxyXG4gICAgICAgICAgICApIHtcclxuICAgICAgICAgICAgICBjb21iaW5lZFNjaGVtYS5jb21iaW5lZFNjaGVtYSA9IGZhbHNlO1xyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgIHJldHVybiB7IGFsbE9mOiBbIC4uLnNjaGVtYXMgXSB9O1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICBicmVhaztcclxuICAgICAgICAgIGNhc2UgJ2FueU9mJzogY2FzZSAnb25lT2YnOiBjYXNlICdlbnVtJzpcclxuICAgICAgICAgICAgLy8gS2VlcCBvbmx5IGl0ZW1zIHRoYXQgYXBwZWFyIGluIGJvdGggYXJyYXlzXHJcbiAgICAgICAgICAgIGlmIChpc0FycmF5KGNvbWJpbmVkVmFsdWUpICYmIGlzQXJyYXkoc2NoZW1hVmFsdWUpKSB7XHJcbiAgICAgICAgICAgICAgY29tYmluZWRTY2hlbWFba2V5XSA9IGNvbWJpbmVkVmFsdWUuZmlsdGVyKGl0ZW0xID0+XHJcbiAgICAgICAgICAgICAgICBzY2hlbWFWYWx1ZS5maW5kSW5kZXgoaXRlbTIgPT4gaXNFcXVhbChpdGVtMSwgaXRlbTIpKSA+IC0xXHJcbiAgICAgICAgICAgICAgKTtcclxuICAgICAgICAgICAgICBpZiAoIWNvbWJpbmVkU2NoZW1hW2tleV0ubGVuZ3RoKSB7IHJldHVybiB7IGFsbE9mOiBbIC4uLnNjaGVtYXMgXSB9OyB9XHJcbiAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgcmV0dXJuIHsgYWxsT2Y6IFsgLi4uc2NoZW1hcyBdIH07XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgY2FzZSAnZGVmaW5pdGlvbnMnOlxyXG4gICAgICAgICAgICAvLyBDb21iaW5lIGtleXMgZnJvbSBib3RoIG9iamVjdHNcclxuICAgICAgICAgICAgaWYgKGlzT2JqZWN0KGNvbWJpbmVkVmFsdWUpICYmIGlzT2JqZWN0KHNjaGVtYVZhbHVlKSkge1xyXG4gICAgICAgICAgICAgIGNvbnN0IGNvbWJpbmVkT2JqZWN0ID0geyAuLi5jb21iaW5lZFZhbHVlIH07XHJcbiAgICAgICAgICAgICAgZm9yIChjb25zdCBzdWJLZXkgb2YgT2JqZWN0LmtleXMoc2NoZW1hVmFsdWUpKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoIWhhc093bihjb21iaW5lZE9iamVjdCwgc3ViS2V5KSB8fFxyXG4gICAgICAgICAgICAgICAgICBpc0VxdWFsKGNvbWJpbmVkT2JqZWN0W3N1YktleV0sIHNjaGVtYVZhbHVlW3N1YktleV0pXHJcbiAgICAgICAgICAgICAgICApIHtcclxuICAgICAgICAgICAgICAgICAgY29tYmluZWRPYmplY3Rbc3ViS2V5XSA9IHNjaGVtYVZhbHVlW3N1YktleV07XHJcbiAgICAgICAgICAgICAgICAvLyBEb24ndCBjb21iaW5lIG1hdGNoaW5nIGtleXMgd2l0aCBkaWZmZXJlbnQgdmFsdWVzXHJcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICByZXR1cm4geyBhbGxPZjogWyAuLi5zY2hlbWFzIF0gfTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgY29tYmluZWRTY2hlbWEuZGVmaW5pdGlvbnMgPSBjb21iaW5lZE9iamVjdDtcclxuICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICByZXR1cm4geyBhbGxPZjogWyAuLi5zY2hlbWFzIF0gfTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICBjYXNlICdkZXBlbmRlbmNpZXMnOlxyXG4gICAgICAgICAgICAvLyBDb21iaW5lIGFsbCBrZXlzIGZyb20gYm90aCBvYmplY3RzXHJcbiAgICAgICAgICAgIC8vIGFuZCBtZXJnZSBzY2hlbWFzIG9uIG1hdGNoaW5nIGtleXMsXHJcbiAgICAgICAgICAgIC8vIGNvbnZlcnRpbmcgZnJvbSBhcnJheXMgdG8gb2JqZWN0cyBpZiBuZWNlc3NhcnlcclxuICAgICAgICAgICAgaWYgKGlzT2JqZWN0KGNvbWJpbmVkVmFsdWUpICYmIGlzT2JqZWN0KHNjaGVtYVZhbHVlKSkge1xyXG4gICAgICAgICAgICAgIGNvbnN0IGNvbWJpbmVkT2JqZWN0ID0geyAuLi5jb21iaW5lZFZhbHVlIH07XHJcbiAgICAgICAgICAgICAgZm9yIChjb25zdCBzdWJLZXkgb2YgT2JqZWN0LmtleXMoc2NoZW1hVmFsdWUpKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoIWhhc093bihjb21iaW5lZE9iamVjdCwgc3ViS2V5KSB8fFxyXG4gICAgICAgICAgICAgICAgICBpc0VxdWFsKGNvbWJpbmVkT2JqZWN0W3N1YktleV0sIHNjaGVtYVZhbHVlW3N1YktleV0pXHJcbiAgICAgICAgICAgICAgICApIHtcclxuICAgICAgICAgICAgICAgICAgY29tYmluZWRPYmplY3Rbc3ViS2V5XSA9IHNjaGVtYVZhbHVlW3N1YktleV07XHJcbiAgICAgICAgICAgICAgICAvLyBJZiBib3RoIGtleXMgYXJlIGFycmF5cywgaW5jbHVkZSBhbGwgaXRlbXMgZnJvbSBib3RoIGFycmF5cyxcclxuICAgICAgICAgICAgICAgIC8vIGV4Y2x1ZGluZyBkdXBsaWNhdGVzXHJcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKFxyXG4gICAgICAgICAgICAgICAgICBpc0FycmF5KHNjaGVtYVZhbHVlW3N1YktleV0pICYmIGlzQXJyYXkoY29tYmluZWRPYmplY3Rbc3ViS2V5XSlcclxuICAgICAgICAgICAgICAgICkge1xyXG4gICAgICAgICAgICAgICAgICBjb21iaW5lZE9iamVjdFtzdWJLZXldID1cclxuICAgICAgICAgICAgICAgICAgICB1bmlxdWVJdGVtcyguLi5jb21iaW5lZE9iamVjdFtzdWJLZXldLCAuLi5zY2hlbWFWYWx1ZVtzdWJLZXldKTtcclxuICAgICAgICAgICAgICAgIC8vIElmIGVpdGhlciBrZXkgaXMgYW4gb2JqZWN0LCBtZXJnZSB0aGUgc2NoZW1hc1xyXG4gICAgICAgICAgICAgICAgfSBlbHNlIGlmIChcclxuICAgICAgICAgICAgICAgICAgKGlzQXJyYXkoc2NoZW1hVmFsdWVbc3ViS2V5XSkgfHwgaXNPYmplY3Qoc2NoZW1hVmFsdWVbc3ViS2V5XSkpICYmXHJcbiAgICAgICAgICAgICAgICAgIChpc0FycmF5KGNvbWJpbmVkT2JqZWN0W3N1YktleV0pIHx8IGlzT2JqZWN0KGNvbWJpbmVkT2JqZWN0W3N1YktleV0pKVxyXG4gICAgICAgICAgICAgICAgKSB7XHJcbiAgICAgICAgICAgICAgICAgIC8vIElmIGVpdGhlciBrZXkgaXMgYW4gYXJyYXksIGNvbnZlcnQgaXQgdG8gYW4gb2JqZWN0IGZpcnN0XHJcbiAgICAgICAgICAgICAgICAgIGNvbnN0IHJlcXVpcmVkID0gaXNBcnJheShjb21iaW5lZFNjaGVtYS5yZXF1aXJlZCkgP1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbWJpbmVkU2NoZW1hLnJlcXVpcmVkIDogW107XHJcbiAgICAgICAgICAgICAgICAgIGNvbnN0IGNvbWJpbmVkRGVwZW5kZW5jeSA9IGlzQXJyYXkoY29tYmluZWRPYmplY3Rbc3ViS2V5XSkgP1xyXG4gICAgICAgICAgICAgICAgICAgIHsgcmVxdWlyZWQ6IHVuaXF1ZUl0ZW1zKC4uLnJlcXVpcmVkLCBjb21iaW5lZE9iamVjdFtzdWJLZXldKSB9IDpcclxuICAgICAgICAgICAgICAgICAgICBjb21iaW5lZE9iamVjdFtzdWJLZXldO1xyXG4gICAgICAgICAgICAgICAgICBjb25zdCBzY2hlbWFEZXBlbmRlbmN5ID0gaXNBcnJheShzY2hlbWFWYWx1ZVtzdWJLZXldKSA/XHJcbiAgICAgICAgICAgICAgICAgICAgeyByZXF1aXJlZDogdW5pcXVlSXRlbXMoLi4ucmVxdWlyZWQsIHNjaGVtYVZhbHVlW3N1YktleV0pIH0gOlxyXG4gICAgICAgICAgICAgICAgICAgIHNjaGVtYVZhbHVlW3N1YktleV07XHJcbiAgICAgICAgICAgICAgICAgIGNvbWJpbmVkT2JqZWN0W3N1YktleV0gPVxyXG4gICAgICAgICAgICAgICAgICAgIG1lcmdlU2NoZW1hcyhjb21iaW5lZERlcGVuZGVuY3ksIHNjaGVtYURlcGVuZGVuY3kpO1xyXG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgcmV0dXJuIHsgYWxsT2Y6IFsgLi4uc2NoZW1hcyBdIH07XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgIGNvbWJpbmVkU2NoZW1hLmRlcGVuZGVuY2llcyA9IGNvbWJpbmVkT2JqZWN0O1xyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgIHJldHVybiB7IGFsbE9mOiBbIC4uLnNjaGVtYXMgXSB9O1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICBicmVhaztcclxuICAgICAgICAgIGNhc2UgJ2l0ZW1zJzpcclxuICAgICAgICAgICAgLy8gSWYgYXJyYXlzLCBrZWVwIG9ubHkgaXRlbXMgdGhhdCBhcHBlYXIgaW4gYm90aCBhcnJheXNcclxuICAgICAgICAgICAgaWYgKGlzQXJyYXkoY29tYmluZWRWYWx1ZSkgJiYgaXNBcnJheShzY2hlbWFWYWx1ZSkpIHtcclxuICAgICAgICAgICAgICBjb21iaW5lZFNjaGVtYS5pdGVtcyA9IGNvbWJpbmVkVmFsdWUuZmlsdGVyKGl0ZW0xID0+XHJcbiAgICAgICAgICAgICAgICBzY2hlbWFWYWx1ZS5maW5kSW5kZXgoaXRlbTIgPT4gaXNFcXVhbChpdGVtMSwgaXRlbTIpKSA+IC0xXHJcbiAgICAgICAgICAgICAgKTtcclxuICAgICAgICAgICAgICBpZiAoIWNvbWJpbmVkU2NoZW1hLml0ZW1zLmxlbmd0aCkgeyByZXR1cm4geyBhbGxPZjogWyAuLi5zY2hlbWFzIF0gfTsgfVxyXG4gICAgICAgICAgICAvLyBJZiBib3RoIGtleXMgYXJlIG9iamVjdHMsIG1lcmdlIHRoZW1cclxuICAgICAgICAgICAgfSBlbHNlIGlmIChpc09iamVjdChjb21iaW5lZFZhbHVlKSAmJiBpc09iamVjdChzY2hlbWFWYWx1ZSkpIHtcclxuICAgICAgICAgICAgICBjb21iaW5lZFNjaGVtYS5pdGVtcyA9IG1lcmdlU2NoZW1hcyhjb21iaW5lZFZhbHVlLCBzY2hlbWFWYWx1ZSk7XHJcbiAgICAgICAgICAgIC8vIElmIG9iamVjdCArIGFycmF5LCBjb21iaW5lIG9iamVjdCB3aXRoIGVhY2ggYXJyYXkgaXRlbVxyXG4gICAgICAgICAgICB9IGVsc2UgaWYgKGlzQXJyYXkoY29tYmluZWRWYWx1ZSkgJiYgaXNPYmplY3Qoc2NoZW1hVmFsdWUpKSB7XHJcbiAgICAgICAgICAgICAgY29tYmluZWRTY2hlbWEuaXRlbXMgPVxyXG4gICAgICAgICAgICAgICAgY29tYmluZWRWYWx1ZS5tYXAoaXRlbSA9PiBtZXJnZVNjaGVtYXMoaXRlbSwgc2NoZW1hVmFsdWUpKTtcclxuICAgICAgICAgICAgfSBlbHNlIGlmIChpc09iamVjdChjb21iaW5lZFZhbHVlKSAmJiBpc0FycmF5KHNjaGVtYVZhbHVlKSkge1xyXG4gICAgICAgICAgICAgIGNvbWJpbmVkU2NoZW1hLml0ZW1zID1cclxuICAgICAgICAgICAgICAgIHNjaGVtYVZhbHVlLm1hcChpdGVtID0+IG1lcmdlU2NoZW1hcyhpdGVtLCBjb21iaW5lZFZhbHVlKSk7XHJcbiAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgcmV0dXJuIHsgYWxsT2Y6IFsgLi4uc2NoZW1hcyBdIH07XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgY2FzZSAnbXVsdGlwbGVPZic6XHJcbiAgICAgICAgICAgIC8vIFRPRE86IEFkanVzdCB0byBjb3JyZWN0bHkgaGFuZGxlIGRlY2ltYWwgdmFsdWVzXHJcbiAgICAgICAgICAgIC8vIElmIG51bWJlcnMsIHNldCB0byBsZWFzdCBjb21tb24gbXVsdGlwbGVcclxuICAgICAgICAgICAgaWYgKGlzTnVtYmVyKGNvbWJpbmVkVmFsdWUpICYmIGlzTnVtYmVyKHNjaGVtYVZhbHVlKSkge1xyXG4gICAgICAgICAgICAgIGNvbnN0IGdjZCA9ICh4LCB5KSA9PiAheSA/IHggOiBnY2QoeSwgeCAlIHkpO1xyXG4gICAgICAgICAgICAgIGNvbnN0IGxjbSA9ICh4LCB5KSA9PiAoeCAqIHkpIC8gZ2NkKHgsIHkpO1xyXG4gICAgICAgICAgICAgIGNvbWJpbmVkU2NoZW1hLm11bHRpcGxlT2YgPSBsY20oY29tYmluZWRWYWx1ZSwgc2NoZW1hVmFsdWUpO1xyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgIHJldHVybiB7IGFsbE9mOiBbIC4uLnNjaGVtYXMgXSB9O1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICBicmVhaztcclxuICAgICAgICAgIGNhc2UgJ21heGltdW0nOiBjYXNlICdleGNsdXNpdmVNYXhpbXVtJzogY2FzZSAnbWF4TGVuZ3RoJzpcclxuICAgICAgICAgIGNhc2UgJ21heEl0ZW1zJzogY2FzZSAnbWF4UHJvcGVydGllcyc6XHJcbiAgICAgICAgICAgIC8vIElmIG51bWJlcnMsIHNldCB0byBsb3dlc3QgdmFsdWVcclxuICAgICAgICAgICAgaWYgKGlzTnVtYmVyKGNvbWJpbmVkVmFsdWUpICYmIGlzTnVtYmVyKHNjaGVtYVZhbHVlKSkge1xyXG4gICAgICAgICAgICAgIGNvbWJpbmVkU2NoZW1hW2tleV0gPSBNYXRoLm1pbihjb21iaW5lZFZhbHVlLCBzY2hlbWFWYWx1ZSk7XHJcbiAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgcmV0dXJuIHsgYWxsT2Y6IFsgLi4uc2NoZW1hcyBdIH07XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgY2FzZSAnbWluaW11bSc6IGNhc2UgJ2V4Y2x1c2l2ZU1pbmltdW0nOiBjYXNlICdtaW5MZW5ndGgnOlxyXG4gICAgICAgICAgY2FzZSAnbWluSXRlbXMnOiBjYXNlICdtaW5Qcm9wZXJ0aWVzJzpcclxuICAgICAgICAgICAgLy8gSWYgbnVtYmVycywgc2V0IHRvIGhpZ2hlc3QgdmFsdWVcclxuICAgICAgICAgICAgaWYgKGlzTnVtYmVyKGNvbWJpbmVkVmFsdWUpICYmIGlzTnVtYmVyKHNjaGVtYVZhbHVlKSkge1xyXG4gICAgICAgICAgICAgIGNvbWJpbmVkU2NoZW1hW2tleV0gPSBNYXRoLm1heChjb21iaW5lZFZhbHVlLCBzY2hlbWFWYWx1ZSk7XHJcbiAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgcmV0dXJuIHsgYWxsT2Y6IFsgLi4uc2NoZW1hcyBdIH07XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgY2FzZSAnbm90JzpcclxuICAgICAgICAgICAgLy8gQ29tYmluZSBub3QgdmFsdWVzIGludG8gYW55T2YgYXJyYXlcclxuICAgICAgICAgICAgaWYgKGlzT2JqZWN0KGNvbWJpbmVkVmFsdWUpICYmIGlzT2JqZWN0KHNjaGVtYVZhbHVlKSkge1xyXG4gICAgICAgICAgICAgIGNvbnN0IG5vdEFueU9mID0gW2NvbWJpbmVkVmFsdWUsIHNjaGVtYVZhbHVlXVxyXG4gICAgICAgICAgICAgICAgLnJlZHVjZSgobm90QW55T2ZBcnJheSwgbm90U2NoZW1hKSA9PlxyXG4gICAgICAgICAgICAgICAgICBpc0FycmF5KG5vdFNjaGVtYS5hbnlPZikgJiZcclxuICAgICAgICAgICAgICAgICAgT2JqZWN0LmtleXMobm90U2NoZW1hKS5sZW5ndGggPT09IDEgP1xyXG4gICAgICAgICAgICAgICAgICAgIFsgLi4ubm90QW55T2ZBcnJheSwgLi4ubm90U2NoZW1hLmFueU9mIF0gOlxyXG4gICAgICAgICAgICAgICAgICAgIFsgLi4ubm90QW55T2ZBcnJheSwgbm90U2NoZW1hIF1cclxuICAgICAgICAgICAgICAgICwgW10pO1xyXG4gICAgICAgICAgICAgIC8vIFRPRE86IFJlbW92ZSBkdXBsaWNhdGUgaXRlbXMgZnJvbSBhcnJheVxyXG4gICAgICAgICAgICAgIGNvbWJpbmVkU2NoZW1hLm5vdCA9IHsgYW55T2Y6IG5vdEFueU9mIH07XHJcbiAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgcmV0dXJuIHsgYWxsT2Y6IFsgLi4uc2NoZW1hcyBdIH07XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgY2FzZSAncGF0dGVyblByb3BlcnRpZXMnOlxyXG4gICAgICAgICAgICAvLyBDb21iaW5lIGFsbCBrZXlzIGZyb20gYm90aCBvYmplY3RzXHJcbiAgICAgICAgICAgIC8vIGFuZCBtZXJnZSBzY2hlbWFzIG9uIG1hdGNoaW5nIGtleXNcclxuICAgICAgICAgICAgaWYgKGlzT2JqZWN0KGNvbWJpbmVkVmFsdWUpICYmIGlzT2JqZWN0KHNjaGVtYVZhbHVlKSkge1xyXG4gICAgICAgICAgICAgIGNvbnN0IGNvbWJpbmVkT2JqZWN0ID0geyAuLi5jb21iaW5lZFZhbHVlIH07XHJcbiAgICAgICAgICAgICAgZm9yIChjb25zdCBzdWJLZXkgb2YgT2JqZWN0LmtleXMoc2NoZW1hVmFsdWUpKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoIWhhc093bihjb21iaW5lZE9iamVjdCwgc3ViS2V5KSB8fFxyXG4gICAgICAgICAgICAgICAgICBpc0VxdWFsKGNvbWJpbmVkT2JqZWN0W3N1YktleV0sIHNjaGVtYVZhbHVlW3N1YktleV0pXHJcbiAgICAgICAgICAgICAgICApIHtcclxuICAgICAgICAgICAgICAgICAgY29tYmluZWRPYmplY3Rbc3ViS2V5XSA9IHNjaGVtYVZhbHVlW3N1YktleV07XHJcbiAgICAgICAgICAgICAgICAvLyBJZiBib3RoIGtleXMgYXJlIG9iamVjdHMsIG1lcmdlIHRoZW1cclxuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoXHJcbiAgICAgICAgICAgICAgICAgIGlzT2JqZWN0KHNjaGVtYVZhbHVlW3N1YktleV0pICYmIGlzT2JqZWN0KGNvbWJpbmVkT2JqZWN0W3N1YktleV0pXHJcbiAgICAgICAgICAgICAgICApIHtcclxuICAgICAgICAgICAgICAgICAgY29tYmluZWRPYmplY3Rbc3ViS2V5XSA9XHJcbiAgICAgICAgICAgICAgICAgICAgbWVyZ2VTY2hlbWFzKGNvbWJpbmVkT2JqZWN0W3N1YktleV0sIHNjaGVtYVZhbHVlW3N1YktleV0pO1xyXG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgcmV0dXJuIHsgYWxsT2Y6IFsgLi4uc2NoZW1hcyBdIH07XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgIGNvbWJpbmVkU2NoZW1hLnBhdHRlcm5Qcm9wZXJ0aWVzID0gY29tYmluZWRPYmplY3Q7XHJcbiAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgcmV0dXJuIHsgYWxsT2Y6IFsgLi4uc2NoZW1hcyBdIH07XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgY2FzZSAncHJvcGVydGllcyc6XHJcbiAgICAgICAgICAgIC8vIENvbWJpbmUgYWxsIGtleXMgZnJvbSBib3RoIG9iamVjdHNcclxuICAgICAgICAgICAgLy8gdW5sZXNzIGFkZGl0aW9uYWxQcm9wZXJ0aWVzID09PSBmYWxzZVxyXG4gICAgICAgICAgICAvLyBhbmQgbWVyZ2Ugc2NoZW1hcyBvbiBtYXRjaGluZyBrZXlzXHJcbiAgICAgICAgICAgIGlmIChpc09iamVjdChjb21iaW5lZFZhbHVlKSAmJiBpc09iamVjdChzY2hlbWFWYWx1ZSkpIHtcclxuICAgICAgICAgICAgICBjb25zdCBjb21iaW5lZE9iamVjdCA9IHsgLi4uY29tYmluZWRWYWx1ZSB9O1xyXG4gICAgICAgICAgICAgIC8vIElmIG5ldyBzY2hlbWEgaGFzIGFkZGl0aW9uYWxQcm9wZXJ0aWVzLFxyXG4gICAgICAgICAgICAgIC8vIG1lcmdlIG9yIHJlbW92ZSBub24tbWF0Y2hpbmcgcHJvcGVydHkga2V5cyBpbiBjb21iaW5lZCBzY2hlbWFcclxuICAgICAgICAgICAgICBpZiAoaGFzT3duKHNjaGVtYVZhbHVlLCAnYWRkaXRpb25hbFByb3BlcnRpZXMnKSkge1xyXG4gICAgICAgICAgICAgICAgT2JqZWN0LmtleXMoY29tYmluZWRWYWx1ZSlcclxuICAgICAgICAgICAgICAgICAgLmZpbHRlcihjb21iaW5lZEtleSA9PiAhT2JqZWN0LmtleXMoc2NoZW1hVmFsdWUpLmluY2x1ZGVzKGNvbWJpbmVkS2V5KSlcclxuICAgICAgICAgICAgICAgICAgLmZvckVhY2gobm9uTWF0Y2hpbmdLZXkgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChzY2hlbWFWYWx1ZS5hZGRpdGlvbmFsUHJvcGVydGllcyA9PT0gZmFsc2UpIHtcclxuICAgICAgICAgICAgICAgICAgICAgIGRlbGV0ZSBjb21iaW5lZE9iamVjdFtub25NYXRjaGluZ0tleV07XHJcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChpc09iamVjdChzY2hlbWFWYWx1ZS5hZGRpdGlvbmFsUHJvcGVydGllcykpIHtcclxuICAgICAgICAgICAgICAgICAgICAgIGNvbWJpbmVkT2JqZWN0W25vbk1hdGNoaW5nS2V5XSA9IG1lcmdlU2NoZW1hcyhcclxuICAgICAgICAgICAgICAgICAgICAgICAgY29tYmluZWRPYmplY3Rbbm9uTWF0Y2hpbmdLZXldLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBzY2hlbWFWYWx1ZS5hZGRpdGlvbmFsUHJvcGVydGllc1xyXG4gICAgICAgICAgICAgICAgICAgICAgKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICBmb3IgKGNvbnN0IHN1YktleSBvZiBPYmplY3Qua2V5cyhzY2hlbWFWYWx1ZSkpIHtcclxuICAgICAgICAgICAgICAgIGlmIChpc0VxdWFsKGNvbWJpbmVkT2JqZWN0W3N1YktleV0sIHNjaGVtYVZhbHVlW3N1YktleV0pIHx8IChcclxuICAgICAgICAgICAgICAgICAgIWhhc093bihjb21iaW5lZE9iamVjdCwgc3ViS2V5KSAmJlxyXG4gICAgICAgICAgICAgICAgICAhaGFzT3duKGNvbWJpbmVkT2JqZWN0LCAnYWRkaXRpb25hbFByb3BlcnRpZXMnKVxyXG4gICAgICAgICAgICAgICAgKSkge1xyXG4gICAgICAgICAgICAgICAgICBjb21iaW5lZE9iamVjdFtzdWJLZXldID0gc2NoZW1hVmFsdWVbc3ViS2V5XTtcclxuICAgICAgICAgICAgICAgIC8vIElmIGNvbWJpbmVkIHNjaGVtYSBoYXMgYWRkaXRpb25hbFByb3BlcnRpZXMsXHJcbiAgICAgICAgICAgICAgICAvLyBtZXJnZSBvciBpZ25vcmUgbm9uLW1hdGNoaW5nIHByb3BlcnR5IGtleXMgaW4gbmV3IHNjaGVtYVxyXG4gICAgICAgICAgICAgICAgfSBlbHNlIGlmIChcclxuICAgICAgICAgICAgICAgICAgIWhhc093bihjb21iaW5lZE9iamVjdCwgc3ViS2V5KSAmJlxyXG4gICAgICAgICAgICAgICAgICBoYXNPd24oY29tYmluZWRPYmplY3QsICdhZGRpdGlvbmFsUHJvcGVydGllcycpXHJcbiAgICAgICAgICAgICAgICApIHtcclxuICAgICAgICAgICAgICAgICAgLy8gSWYgY29tYmluZWRPYmplY3QuYWRkaXRpb25hbFByb3BlcnRpZXMgPT09IGZhbHNlLFxyXG4gICAgICAgICAgICAgICAgICAvLyBkbyBub3RoaW5nIChkb24ndCBzZXQga2V5KVxyXG4gICAgICAgICAgICAgICAgICAvLyBJZiBhZGRpdGlvbmFsUHJvcGVydGllcyBpcyBvYmplY3QsIG1lcmdlIHdpdGggbmV3IGtleVxyXG4gICAgICAgICAgICAgICAgICBpZiAoaXNPYmplY3QoY29tYmluZWRPYmplY3QuYWRkaXRpb25hbFByb3BlcnRpZXMpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgY29tYmluZWRPYmplY3Rbc3ViS2V5XSA9IG1lcmdlU2NoZW1hcyhcclxuICAgICAgICAgICAgICAgICAgICAgIGNvbWJpbmVkT2JqZWN0LmFkZGl0aW9uYWxQcm9wZXJ0aWVzLCBzY2hlbWFWYWx1ZVtzdWJLZXldXHJcbiAgICAgICAgICAgICAgICAgICAgKTtcclxuICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgLy8gSWYgYm90aCBrZXlzIGFyZSBvYmplY3RzLCBtZXJnZSB0aGVtXHJcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKFxyXG4gICAgICAgICAgICAgICAgICBpc09iamVjdChzY2hlbWFWYWx1ZVtzdWJLZXldKSAmJlxyXG4gICAgICAgICAgICAgICAgICBpc09iamVjdChjb21iaW5lZE9iamVjdFtzdWJLZXldKVxyXG4gICAgICAgICAgICAgICAgKSB7XHJcbiAgICAgICAgICAgICAgICAgIGNvbWJpbmVkT2JqZWN0W3N1YktleV0gPVxyXG4gICAgICAgICAgICAgICAgICAgIG1lcmdlU2NoZW1hcyhjb21iaW5lZE9iamVjdFtzdWJLZXldLCBzY2hlbWFWYWx1ZVtzdWJLZXldKTtcclxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgIHJldHVybiB7IGFsbE9mOiBbIC4uLnNjaGVtYXMgXSB9O1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICBjb21iaW5lZFNjaGVtYS5wcm9wZXJ0aWVzID0gY29tYmluZWRPYmplY3Q7XHJcbiAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgcmV0dXJuIHsgYWxsT2Y6IFsgLi4uc2NoZW1hcyBdIH07XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgY2FzZSAncmVxdWlyZWQnOlxyXG4gICAgICAgICAgICAvLyBJZiBhcnJheXMsIGluY2x1ZGUgYWxsIGl0ZW1zIGZyb20gYm90aCBhcnJheXMsIGV4Y2x1ZGluZyBkdXBsaWNhdGVzXHJcbiAgICAgICAgICAgIGlmIChpc0FycmF5KGNvbWJpbmVkVmFsdWUpICYmIGlzQXJyYXkoc2NoZW1hVmFsdWUpKSB7XHJcbiAgICAgICAgICAgICAgY29tYmluZWRTY2hlbWEucmVxdWlyZWQgPSB1bmlxdWVJdGVtcyguLi5jb21iaW5lZFZhbHVlLCAuLi5zY2hlbWFWYWx1ZSk7XHJcbiAgICAgICAgICAgIC8vIElmIGJvb2xlYW5zLCBhZXQgdHJ1ZSBpZiBlaXRoZXIgdHJ1ZVxyXG4gICAgICAgICAgICB9IGVsc2UgaWYgKFxyXG4gICAgICAgICAgICAgIHR5cGVvZiBzY2hlbWFWYWx1ZSA9PT0gJ2Jvb2xlYW4nICYmXHJcbiAgICAgICAgICAgICAgdHlwZW9mIGNvbWJpbmVkVmFsdWUgPT09ICdib29sZWFuJ1xyXG4gICAgICAgICAgICApIHtcclxuICAgICAgICAgICAgICBjb21iaW5lZFNjaGVtYS5yZXF1aXJlZCA9ICEhY29tYmluZWRWYWx1ZSB8fCAhIXNjaGVtYVZhbHVlO1xyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgIHJldHVybiB7IGFsbE9mOiBbIC4uLnNjaGVtYXMgXSB9O1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICBicmVhaztcclxuICAgICAgICAgIGNhc2UgJyRzY2hlbWEnOiBjYXNlICckaWQnOiBjYXNlICdpZCc6XHJcbiAgICAgICAgICAgIC8vIERvbid0IGNvbWJpbmUgdGhlc2Uga2V5c1xyXG4gICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICBjYXNlICd0aXRsZSc6IGNhc2UgJ2Rlc2NyaXB0aW9uJzogY2FzZSAnJGNvbW1lbnQnOlxyXG4gICAgICAgICAgICAvLyBSZXR1cm4gdGhlIGxhc3QgdmFsdWUsIG92ZXJ3cml0aW5nIGFueSBwcmV2aW91cyBvbmVcclxuICAgICAgICAgICAgLy8gVGhlc2UgcHJvcGVydGllcyBhcmUgbm90IHVzZWQgZm9yIHZhbGlkYXRpb24sIHNvIGNvbmZsaWN0cyBkb24ndCBtYXR0ZXJcclxuICAgICAgICAgICAgY29tYmluZWRTY2hlbWFba2V5XSA9IHNjaGVtYVZhbHVlO1xyXG4gICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICBjYXNlICd0eXBlJzpcclxuICAgICAgICAgICAgaWYgKFxyXG4gICAgICAgICAgICAgIChpc0FycmF5KHNjaGVtYVZhbHVlKSB8fCBpc1N0cmluZyhzY2hlbWFWYWx1ZSkpICYmXHJcbiAgICAgICAgICAgICAgKGlzQXJyYXkoY29tYmluZWRWYWx1ZSkgfHwgaXNTdHJpbmcoY29tYmluZWRWYWx1ZSkpXHJcbiAgICAgICAgICAgICkge1xyXG4gICAgICAgICAgICAgIGNvbnN0IGNvbWJpbmVkVHlwZXMgPSBjb21tb25JdGVtcyhjb21iaW5lZFZhbHVlLCBzY2hlbWFWYWx1ZSk7XHJcbiAgICAgICAgICAgICAgaWYgKCFjb21iaW5lZFR5cGVzLmxlbmd0aCkgeyByZXR1cm4geyBhbGxPZjogWyAuLi5zY2hlbWFzIF0gfTsgfVxyXG4gICAgICAgICAgICAgIGNvbWJpbmVkU2NoZW1hLnR5cGUgPSBjb21iaW5lZFR5cGVzLmxlbmd0aCA+IDEgPyBjb21iaW5lZFR5cGVzIDogY29tYmluZWRUeXBlc1swXTtcclxuICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICByZXR1cm4geyBhbGxPZjogWyAuLi5zY2hlbWFzIF0gfTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICBjYXNlICd1bmlxdWVJdGVtcyc6XHJcbiAgICAgICAgICAgIC8vIFNldCB0cnVlIGlmIGVpdGhlciB0cnVlXHJcbiAgICAgICAgICAgIGNvbWJpbmVkU2NoZW1hLnVuaXF1ZUl0ZW1zID0gISFjb21iaW5lZFZhbHVlIHx8ICEhc2NoZW1hVmFsdWU7XHJcbiAgICAgICAgICBicmVhaztcclxuICAgICAgICAgIGRlZmF1bHQ6XHJcbiAgICAgICAgICAgIHJldHVybiB7IGFsbE9mOiBbIC4uLnNjaGVtYXMgXSB9O1xyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG4gICAgfVxyXG4gIH1cclxuICByZXR1cm4gY29tYmluZWRTY2hlbWE7XHJcbn1cclxuIl19