@sumaris-net/ngx-components 18.0.0-rc1 → 18.0.1-0.alpha1

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 (123) hide show
  1. package/doc/build.md +13 -11
  2. package/doc/changelog.md +42 -5
  3. package/esm2022/public_api.mjs +4 -2
  4. package/esm2022/src/app/admin/services/filter/person.filter.mjs +10 -3
  5. package/esm2022/src/app/admin/services/person.service.mjs +11 -5
  6. package/esm2022/src/app/admin/users/users.mjs +2 -2
  7. package/esm2022/src/app/core/about/about.modal.mjs +6 -4
  8. package/esm2022/src/app/core/about/about.module.mjs +5 -4
  9. package/esm2022/src/app/core/account/account.page.mjs +5 -6
  10. package/esm2022/src/app/core/account/token.table.mjs +10 -6
  11. package/esm2022/src/app/core/form/buttons/form-buttons-bar.component.mjs +5 -5
  12. package/esm2022/src/app/core/form/properties/properties.form.mjs +110 -57
  13. package/esm2022/src/app/core/form/properties/properties.utils.mjs +264 -32
  14. package/esm2022/src/app/core/form/properties/property.validator.mjs +36 -4
  15. package/esm2022/src/app/core/form/properties/testing/properties-form.test.mjs +26 -18
  16. package/esm2022/src/app/core/graphql/graphql.service.mjs +1 -1
  17. package/esm2022/src/app/core/home/home.module.mjs +2 -2
  18. package/esm2022/src/app/core/menu/menu.component.mjs +3 -3
  19. package/esm2022/src/app/core/menu/menu.module.mjs +2 -2
  20. package/esm2022/src/app/core/menu/menu.service.mjs +5 -4
  21. package/esm2022/src/app/core/register/register.form.mjs +1 -1
  22. package/esm2022/src/app/core/services/base-entity-service.class.mjs +1 -1
  23. package/esm2022/src/app/core/services/config/core.config.mjs +6 -1
  24. package/esm2022/src/app/core/services/local-settings.service.mjs +17 -8
  25. package/esm2022/src/app/core/services/model/config.model.mjs +1 -1
  26. package/esm2022/src/app/core/services/model/entity.model.mjs +2 -2
  27. package/esm2022/src/app/core/services/model/settings.model.mjs +1 -1
  28. package/esm2022/src/app/core/services/storage/entities-storage.service.mjs +1 -1
  29. package/esm2022/src/app/core/services/storage/entity-store.class.mjs +1 -1
  30. package/esm2022/src/app/core/services/validator/local-settings.validator.mjs +4 -24
  31. package/esm2022/src/app/core/settings/settings.page.mjs +51 -16
  32. package/esm2022/src/app/core/table/column/row-field.component.mjs +1 -1
  33. package/esm2022/src/app/core/table/testing/table.testing.mjs +1 -1
  34. package/esm2022/src/app/core/table/testing/table2.testing.mjs +1 -1
  35. package/esm2022/src/app/shared/debug/debug.component.mjs +10 -6
  36. package/esm2022/src/app/shared/form/field.component.mjs +39 -31
  37. package/esm2022/src/app/shared/form/field.model.mjs +59 -2
  38. package/esm2022/src/app/shared/functions.mjs +6 -3
  39. package/esm2022/src/app/shared/hotkeys/dialog/hotkeys-dialog.component.mjs +1 -1
  40. package/esm2022/src/app/shared/hotkeys/hotkeys.service.mjs +51 -17
  41. package/esm2022/src/app/shared/image/gallery/image-gallery.module.mjs +2 -2
  42. package/esm2022/src/app/shared/image/gallery/testing/gallery.testing.mjs +1 -1
  43. package/esm2022/src/app/shared/material/autocomplete/material.autocomplete.config.mjs +1 -1
  44. package/esm2022/src/app/shared/material/autocomplete/material.autocomplete.mjs +11 -4
  45. package/esm2022/src/app/shared/material/autocomplete/material.autocomplete.module.mjs +2 -2
  46. package/esm2022/src/app/shared/material/autocomplete/testing/autocomplete.test.mjs +18 -8
  47. package/esm2022/src/app/shared/material/chips/chips.module.mjs +2 -2
  48. package/esm2022/src/app/shared/material/chips/material.chips.mjs +4 -3
  49. package/esm2022/src/app/shared/material/latlong/material.latlong.mjs +33 -10
  50. package/esm2022/src/app/shared/named-filter/named-filter-selector.component.mjs +1 -1
  51. package/esm2022/src/app/shared/pipes/display-with.pipe.mjs +23 -0
  52. package/esm2022/src/app/shared/pipes/pipes.module.mjs +7 -3
  53. package/esm2022/src/app/shared/pipes/property.pipes.mjs +30 -31
  54. package/esm2022/src/app/shared/platforms.mjs +12 -4
  55. package/esm2022/src/app/shared/rx-state/rx-state.decorators.mjs +71 -0
  56. package/esm2022/src/app/shared/rx-state/rx-state.module.mjs +19 -0
  57. package/esm2022/src/app/shared/services/entity-service.class.mjs +1 -1
  58. package/esm2022/src/app/shared/services.mjs +34 -18
  59. package/esm2022/src/app/shared/shared.module.mjs +2 -2
  60. package/esm2022/src/app/shared/storage/storage-explorer.module.mjs +2 -2
  61. package/esm2022/src/app/shared/toolbar/modal-toolbar.mjs +2 -2
  62. package/esm2022/src/app/shared/toolbar/toolbar.module.mjs +2 -2
  63. package/esm2022/src/app/shared/types.mjs +1 -1
  64. package/esm2022/src/app/social/user-event/user-event.module.mjs +2 -2
  65. package/esm2022/src/environments/environment.mjs +3 -6
  66. package/fesm2022/sumaris-net.ngx-components.mjs +1429 -805
  67. package/fesm2022/sumaris-net.ngx-components.mjs.map +1 -1
  68. package/package.json +5 -2
  69. package/public_api.d.ts +3 -1
  70. package/src/app/admin/services/filter/person.filter.d.ts +1 -0
  71. package/src/app/admin/services/person.service.d.ts +8 -6
  72. package/src/app/core/about/about.modal.d.ts +1 -1
  73. package/src/app/core/about/about.module.d.ts +2 -1
  74. package/src/app/core/account/token.table.d.ts +1 -1
  75. package/src/app/core/form/properties/properties.form.d.ts +28 -11
  76. package/src/app/core/form/properties/properties.utils.d.ts +41 -13
  77. package/src/app/core/form/properties/property.validator.d.ts +8 -0
  78. package/src/app/core/form/properties/testing/properties-form.test.d.ts +6 -3
  79. package/src/app/core/graphql/graphql.service.d.ts +2 -2
  80. package/src/app/core/home/home.module.d.ts +1 -1
  81. package/src/app/core/menu/menu.module.d.ts +1 -1
  82. package/src/app/core/services/base-entity-service.class.d.ts +1 -1
  83. package/src/app/core/services/config/core.config.d.ts +1 -0
  84. package/src/app/core/services/local-settings.service.d.ts +3 -1
  85. package/src/app/core/services/model/config.model.d.ts +2 -2
  86. package/src/app/core/services/model/entity.model.d.ts +2 -2
  87. package/src/app/core/services/model/settings.model.d.ts +2 -2
  88. package/src/app/core/services/storage/entities-storage.service.d.ts +4 -4
  89. package/src/app/core/services/storage/entity-store.class.d.ts +4 -4
  90. package/src/app/core/services/validator/local-settings.validator.d.ts +3 -7
  91. package/src/app/core/settings/settings.page.d.ts +4 -1
  92. package/src/app/shared/debug/debug.component.d.ts +2 -1
  93. package/src/app/shared/form/field.component.d.ts +14 -5
  94. package/src/app/shared/form/field.model.d.ts +44 -1
  95. package/src/app/shared/functions.d.ts +1 -0
  96. package/src/app/shared/hotkeys/hotkeys.service.d.ts +10 -3
  97. package/src/app/shared/image/gallery/image-gallery.module.d.ts +1 -1
  98. package/src/app/shared/inputs.d.ts +1 -1
  99. package/src/app/shared/material/autocomplete/material.autocomplete.config.d.ts +2 -2
  100. package/src/app/shared/material/autocomplete/material.autocomplete.d.ts +4 -1
  101. package/src/app/shared/material/autocomplete/material.autocomplete.module.d.ts +1 -1
  102. package/src/app/shared/material/chips/chips.module.d.ts +1 -1
  103. package/src/app/shared/material/chips/material.chips.d.ts +1 -0
  104. package/src/app/shared/material/latlong/material.latlong.d.ts +3 -0
  105. package/src/app/shared/pipes/display-with.pipe.d.ts +8 -0
  106. package/src/app/shared/pipes/pipes.module.d.ts +5 -4
  107. package/src/app/shared/pipes/property.pipes.d.ts +3 -9
  108. package/src/app/shared/platforms.d.ts +3 -0
  109. package/src/app/shared/rx-state/rx-state.decorators.d.ts +7 -0
  110. package/src/app/shared/services/entity-service.class.d.ts +2 -0
  111. package/src/app/shared/services.d.ts +8 -1
  112. package/src/app/shared/shared.module.d.ts +1 -1
  113. package/src/app/shared/storage/storage-explorer.module.d.ts +1 -1
  114. package/src/app/shared/toolbar/toolbar.module.d.ts +1 -1
  115. package/src/app/shared/types.d.ts +11 -6
  116. package/src/app/social/user-event/user-event.module.d.ts +1 -1
  117. package/src/assets/i18n/en-US.json +14 -2
  118. package/src/assets/i18n/en.json +13 -1
  119. package/src/assets/i18n/fr.json +11 -1
  120. package/src/assets/manifest.json +1 -1
  121. package/src/theme/_ngx-components.scss +2 -4
  122. package/esm2022/src/app/shared/rx-state.module.mjs +0 -19
  123. /package/src/app/shared/{rx-state.module.d.ts → rx-state/rx-state.module.d.ts} +0 -0
@@ -1,60 +1,292 @@
1
- import { isNilOrBlank, isNotNil } from '../../../shared/functions';
1
+ import { getPropertyByPath, isNil, isNilOrBlank, isNotNil, isNotNilOrBlank, isPromise, toBoolean, toNumber } from '../../../shared/functions';
2
2
  export class AppPropertiesUtils {
3
3
  /**
4
- * Converts an array of Property objects to an object map.
4
+ * Converts an array of `Property` objects into a `PropertiesMap` object.
5
5
  *
6
- * @param {Property[]} [sources] - The array of Property objects to convert.
7
- * @param {Object} [opts] - Options for the conversion.
8
- * @param {boolean} [opts.omitNilOrBlank] - If set to true, properties with nil or blank values will be omitted from the resulting object.
9
- * @return {PropertiesMap} The resulting object map where keys are property keys and values are property values.
6
+ * @param {Property[]} [sources] - An optional array of properties to be converted.
7
+ * @param {FormFieldDefinition[]} [definitions] - An optional array of form field definitions to help with the conversion.
8
+ * @param {Object} [opts] - Optional configurations.
9
+ * @param {boolean} [opts.omitNilOrBlank] - If true, properties with nil or blank values will be omitted. Defaults to true.
10
+ * @return {PropertyMap} - The resulting `PropertiesMap` object.
10
11
  */
11
- static arrayAsObject(sources, opts) {
12
+ static arrayAsObject(sources, definitions, opts) {
12
13
  return ((sources || [])
13
14
  // Serialize each item
14
- .map(AppPropertyUtils.asObject)
15
+ .map((source) => {
16
+ if (!source)
17
+ return undefined;
18
+ const key = AppPropertyUtils.getPropertyKey(source);
19
+ if (!key)
20
+ return undefined;
21
+ const def = definitions?.find((d) => d.key === key);
22
+ return AppPropertyUtils.asObject(source, def);
23
+ })
15
24
  // Fill a JSON object
16
25
  .reduce((res, item) => {
17
- if (isNilOrBlank(item.key))
26
+ if (isNilOrBlank(item?.key))
18
27
  return res;
19
- if (isNilOrBlank(item.value) && opts?.omitNilOrBlank !== false)
28
+ // Skip if nil or blank value
29
+ if (opts?.omitNilOrBlank !== false && isNilOrBlank(item.value))
20
30
  return res;
21
31
  res[item.key] = item.value;
22
32
  return res;
23
33
  }, {}));
24
34
  }
25
35
  /**
26
- * Converts an object into an array of properties.
36
+ * Generates an array of properties from the given object, optionally applying definitions to the properties.
27
37
  *
28
- * @param {PropertiesMap} [source] - The source object containing properties to convert.
29
- * @return {Property[]} An array of properties derived from the source object.
38
+ * @param {PropertyMap} [sources] - The source object from which properties are to be extracted.
39
+ * @param {FormFieldDefinition[]} [definitions] - An optional array of definitions to be applied to the extracted properties.
40
+ * @param opts
41
+ * @return {Property[] | Promise<Property[]>} An array of properties generated from the source object, or a promise resolving to that array.
30
42
  */
31
- static arrayFromObject(source) {
32
- if (Array.isArray(source))
33
- return source; // Already an array
34
- return Object.getOwnPropertyNames(source || {}).map((key) => ({
35
- key,
36
- value: source[key],
37
- }));
43
+ static arrayFromObject(sources, definitions, opts) {
44
+ // DEBUG
45
+ //console.debug(`[properties-utils] Convert property map into array of Property...`);
46
+ let targets = Array.isArray(sources)
47
+ ? sources.slice()
48
+ : Object.getOwnPropertyNames(sources || {}).map((key) => ({
49
+ key,
50
+ value: sources[key],
51
+ }));
52
+ const jobs = [];
53
+ if (!!definitions) {
54
+ targets = targets
55
+ .map((target) => {
56
+ // Find definition
57
+ const def = definitions.find((def) => def.key === target.key);
58
+ // Exclude no definition (if expected by user options)
59
+ if (!def && opts?.keepOrphan === false)
60
+ return null;
61
+ // Deserialize from string
62
+ let propertyOrPromise = AppPropertyUtils.fromObject(target, def);
63
+ if (isPromise(propertyOrPromise)) {
64
+ jobs.push(propertyOrPromise.then((property) => (target.value = property.value)));
65
+ }
66
+ else {
67
+ // Update the target value
68
+ target.value = propertyOrPromise.value;
69
+ }
70
+ return target;
71
+ })
72
+ // Clean orphan
73
+ .filter(isNotNil);
74
+ // Return as promise, when need
75
+ if (jobs.length)
76
+ return Promise.all(jobs).then(() => targets);
77
+ }
78
+ return targets;
38
79
  }
39
80
  }
40
81
  export class AppPropertyUtils {
41
- static asObject(source) {
82
+ static key(key) {
83
+ return key?.key ?? key;
84
+ }
85
+ static getPropertyKey(source) {
86
+ if (!source)
87
+ return undefined;
88
+ return source.key?.key ?? source.key;
89
+ }
90
+ /**
91
+ * Converts the given source to an object that contains a key-value pair.
92
+ *
93
+ * @param {Property<any> | any} source - The source property or any value to be converted.
94
+ * @param {FormFieldDefinition} [def] - The form field definition used for serialization.
95
+ * @param {Object} [opts] - Additional options for serialization.
96
+ * @param {string} [opts.defaultSerializeAttribute='id'] - The attribute to be used for default serialization.
97
+ * @return {{ key: string, value: string } | undefined} An object containing the serialized key-value pair, or undefined if the source is not provided.
98
+ */
99
+ static asObject(source, def, opts) {
42
100
  if (!source)
43
101
  return undefined;
44
102
  // Serialize key (WARNING: can be an object, when using autocomplete field to edit a key - see AppPropertiesForm)
45
- const key = source.key?.key ?? source.key;
46
- // Serialize the value
47
- let value = source.value;
48
- if (Array.isArray(value)) {
49
- value = value
50
- .map((v) => v?.id ?? v)
51
- .filter(isNotNil)
52
- .join(',');
103
+ const key = AppPropertyUtils.getPropertyKey(source);
104
+ // Prepare a deserialize function
105
+ let serializeFn = def?.serialize;
106
+ if (!serializeFn) {
107
+ switch (def?.type || 'other') {
108
+ case 'enum':
109
+ case 'enums':
110
+ serializeFn = AppPropertyUtils.key;
111
+ break;
112
+ case 'entity':
113
+ case 'entities':
114
+ const serializeAttribute = def?.serializeAttribute ?? opts?.defaultSerializeAttribute ?? 'id';
115
+ serializeFn =
116
+ def?.serialize ||
117
+ ((value) => {
118
+ const serializeValue = getPropertyByPath(value, serializeAttribute, value /*default value*/);
119
+ if (isNil(serializeValue))
120
+ return serializeValue;
121
+ return serializeValue.toString();
122
+ });
123
+ break;
124
+ default:
125
+ serializeFn = AppPropertyUtils.toString;
126
+ }
127
+ }
128
+ let valueStr;
129
+ // Value is an array
130
+ if (Array.isArray(source.value)) {
131
+ valueStr = source.value.map(serializeFn).filter(isNotNilOrBlank).join(',');
132
+ }
133
+ // Any other case
134
+ else {
135
+ valueStr = serializeFn(source.value);
136
+ }
137
+ return { key, value: valueStr };
138
+ }
139
+ static fromObject(source, def, opts) {
140
+ if (!source?.key || isNil(source.value) || !def)
141
+ return source; // Skip if no key
142
+ // Clone the source
143
+ const target = { key: source.key, value: source.value };
144
+ const jobs = [];
145
+ // Resolve value
146
+ switch (def.type) {
147
+ case 'boolean':
148
+ target.value = toBoolean(source.value, toBoolean(def.defaultValue));
149
+ break;
150
+ case 'integer':
151
+ case 'double':
152
+ target.value = toNumber(source.value, toNumber(def.defaultValue));
153
+ break;
154
+ case 'enum':
155
+ const valueKey = AppPropertyUtils.key(target.value);
156
+ if (isNotNilOrBlank(valueKey)) {
157
+ const enumValue = def.values?.find((defValue) => defValue && valueKey === (defValue['key'] || defValue)) ?? null;
158
+ target.value = enumValue?.['key'] ?? enumValue ?? null;
159
+ }
160
+ else {
161
+ target.value = null;
162
+ }
163
+ break;
164
+ case 'enums':
165
+ const valueKeys = Array.isArray(source.value)
166
+ ? source.value.map(AppPropertyUtils.key) // Copy
167
+ : typeof source.value === 'string'
168
+ ? source.value.trim().split(/,+/)
169
+ : [AppPropertyUtils.key(source.value)];
170
+ target.value = valueKeys
171
+ .filter(isNotNil)
172
+ .map((key) => def.values?.find((defValue) => defValue && key === (defValue['key'] || defValue)) || { key, value: '?' });
173
+ break;
174
+ case 'entity':
175
+ // Deserialize entity (e.g. load entity from the id)
176
+ const valueOrPromise = AppPropertyUtils.resolveEntity(target.value, def, opts);
177
+ if (isPromise(valueOrPromise)) {
178
+ jobs.push(valueOrPromise.then((value) => {
179
+ target.value = value;
180
+ }));
181
+ }
182
+ else {
183
+ target.value = valueOrPromise;
184
+ }
185
+ break;
186
+ case 'entities':
187
+ // Convert value to array
188
+ target.value = Array.isArray(source.value)
189
+ ? source.value.slice() // Copy
190
+ : typeof source.value === 'string'
191
+ ? source.value
192
+ .split(',')
193
+ .map((v) => v.trim())
194
+ .filter(isNotNilOrBlank)
195
+ : [];
196
+ // Deserialize each sub-value
197
+ let index = 0;
198
+ for (let subValue of target.value) {
199
+ // Deserialize sub-value
200
+ const subValueOrPromise = AppPropertyUtils.resolveEntity(subValue, def, opts);
201
+ // Add promise to jobs
202
+ if (isPromise(subValueOrPromise)) {
203
+ const finalIndex = index;
204
+ jobs.push(subValueOrPromise.then((value) => {
205
+ // Update sub value
206
+ target.value[finalIndex] = value;
207
+ }));
208
+ }
209
+ else {
210
+ // Update sub value
211
+ target.value[index] = subValueOrPromise;
212
+ }
213
+ index++;
214
+ }
215
+ }
216
+ // /!\ Return as promise only if need (let function sync when possible)
217
+ if (jobs.length)
218
+ return Promise.all(jobs).then(() => target);
219
+ return target;
220
+ }
221
+ static resolveEntity(value, def, opts) {
222
+ // Use deserialize function, if any
223
+ if (def.deserialize) {
224
+ return def.deserialize(value);
225
+ }
226
+ // Or try using suggest function
227
+ return this.resolveEntityBySuggest(value, def, opts);
228
+ }
229
+ static async resolveEntityBySuggest(value, def, opts) {
230
+ const serializeAttribute = def.serializeAttribute ?? opts?.defaultSerializeAttribute ?? 'id';
231
+ if (typeof value === 'object' && isNotNil(value[serializeAttribute])) {
232
+ return value; // Already resolve
233
+ }
234
+ const suggestFn = def.autocomplete?.suggestFn || opts?.defaultSuggestFn;
235
+ if (!suggestFn) {
236
+ console.warn(`Missing 'deserialize' or 'autocomplete.suggestFn' in the field definition '${def.key}'. Cannot deserialize value: ${JSON.stringify(value)}`);
237
+ return value; // Skip
238
+ }
239
+ let searchValue = value;
240
+ const filter = { ...def.autocomplete?.filter }; // Cope filter
241
+ if (serializeAttribute === 'id' || serializeAttribute === 'label') {
242
+ filter[serializeAttribute] = serializeAttribute === 'id' ? +value : value;
243
+ searchValue = '*';
244
+ // DEBUG
245
+ //console.debug(`[properties-utils] Resolving entity where id=${value}...`);
53
246
  }
54
247
  else {
55
- value = value?.id ?? value;
248
+ filter.searchAttribute = serializeAttribute;
249
+ // DEBUG
250
+ //console.debug(`[properties-utils] Resolving entity where ${serializeAttribute}=${searchValue}...`);
251
+ }
252
+ try {
253
+ // Fetch entity, using the suggest function
254
+ const res = await suggestFn(searchValue, filter, serializeAttribute, 'asc', {
255
+ withTotal: false,
256
+ offset: 0,
257
+ size: 1,
258
+ ...opts?.defaultSuggestOptions,
259
+ });
260
+ // Get result array
261
+ const data = Array.isArray(res) ? res : res.data;
262
+ if (data?.length > 0) {
263
+ if (data?.length > 1) {
264
+ console.warn(`[properties-utils] More than one entity found, for option ${def.key}=${value}! Please check option's definition and the 'autocomplete.suggestFn' function`, data);
265
+ }
266
+ // DEBUG
267
+ //console.debug(`[properties-utils] ${data.length} entities found: `, data);
268
+ // Ok, we find it => stop here
269
+ return data[0];
270
+ }
271
+ // Warn, but continue
272
+ console.warn(`[properties-utils] Unable to resolve entity for option: ${def.key}=${value}. Please check option's definition and the 'autocomplete.suggestFn' function`);
56
273
  }
57
- return { key, value };
274
+ catch (err) {
275
+ console.error(`[properties-utils] Cannot resolve entity for option: ${def.key}=${value}`, err);
276
+ // Continue
277
+ }
278
+ // Create the missing result
279
+ const unresolvedEntity = {
280
+ [serializeAttribute]: value,
281
+ };
282
+ // Fill attributes with '??'
283
+ def.autocomplete?.attributes?.forEach((key) => {
284
+ unresolvedEntity[key] = unresolvedEntity[key] ?? '';
285
+ });
286
+ return unresolvedEntity;
287
+ }
288
+ static toString(value) {
289
+ return value?.toString();
58
290
  }
59
291
  }
60
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJvcGVydGllcy51dGlscy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3NyYy9hcHAvY29yZS9mb3JtL3Byb3BlcnRpZXMvcHJvcGVydGllcy51dGlscy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFDQSxPQUFPLEVBQUUsWUFBWSxFQUFFLFFBQVEsRUFBRSxNQUFNLDJCQUEyQixDQUFDO0FBRW5FLE1BQU0sT0FBTyxrQkFBa0I7SUFDN0I7Ozs7Ozs7T0FPRztJQUNILE1BQU0sQ0FBQyxhQUFhLENBQUMsT0FBb0IsRUFBRSxJQUFrQztRQUMzRSxPQUFPLENBQ0wsQ0FBQyxPQUFPLElBQUksRUFBRSxDQUFDO1lBQ2Isc0JBQXNCO2FBQ3JCLEdBQUcsQ0FBQyxnQkFBZ0IsQ0FBQyxRQUFRLENBQUM7WUFDL0IscUJBQXFCO2FBQ3BCLE1BQU0sQ0FDTCxDQUFDLEdBQUcsRUFBRSxJQUFJLEVBQUUsRUFBRTtZQUNaLElBQUksWUFBWSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUM7Z0JBQUUsT0FBTyxHQUFHLENBQUM7WUFDdkMsSUFBSSxZQUFZLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLElBQUksRUFBRSxjQUFjLEtBQUssS0FBSztnQkFBRSxPQUFPLEdBQUcsQ0FBQztZQUMzRSxHQUFHLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUM7WUFDM0IsT0FBTyxHQUFHLENBQUM7UUFDYixDQUFDLEVBQ2MsRUFBRSxDQUNsQixDQUNKLENBQUM7SUFDSixDQUFDO0lBRUQ7Ozs7O09BS0c7SUFDSCxNQUFNLENBQUMsZUFBZSxDQUFVLE1BQXNCO1FBQ3BELElBQUksS0FBSyxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUM7WUFBRSxPQUFPLE1BQU0sQ0FBQyxDQUFDLG1CQUFtQjtRQUM3RCxPQUFPLE1BQU0sQ0FBQyxtQkFBbUIsQ0FBQyxNQUFNLElBQUksRUFBRSxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxFQUFFLEVBQUUsQ0FBQyxDQUFDO1lBQzVELEdBQUc7WUFDSCxLQUFLLEVBQUUsTUFBTSxDQUFDLEdBQUcsQ0FBQztTQUNuQixDQUFDLENBQUMsQ0FBQztJQUNOLENBQUM7Q0FDRjtBQUVELE1BQU0sT0FBTyxnQkFBZ0I7SUFDM0IsTUFBTSxDQUFDLFFBQVEsQ0FBQyxNQUFzQjtRQUNwQyxJQUFJLENBQUMsTUFBTTtZQUFFLE9BQU8sU0FBUyxDQUFDO1FBQzlCLGlIQUFpSDtRQUNqSCxNQUFNLEdBQUcsR0FBSSxNQUFNLENBQUMsR0FBVyxFQUFFLEdBQUcsSUFBSSxNQUFNLENBQUMsR0FBRyxDQUFDO1FBRW5ELHNCQUFzQjtRQUN0QixJQUFJLEtBQUssR0FBRyxNQUFNLENBQUMsS0FBSyxDQUFDO1FBQ3pCLElBQUksS0FBSyxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDO1lBQ3pCLEtBQUssR0FBRyxLQUFLO2lCQUNWLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxFQUFFLEVBQUUsSUFBSSxDQUFDLENBQUM7aUJBQ3RCLE1BQU0sQ0FBQyxRQUFRLENBQUM7aUJBQ2hCLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUNmLENBQUM7YUFBTSxDQUFDO1lBQ04sS0FBSyxHQUFJLEtBQWEsRUFBRSxFQUFFLElBQUksS0FBSyxDQUFDO1FBQ3RDLENBQUM7UUFDRCxPQUFPLEVBQUUsR0FBRyxFQUFFLEtBQUssRUFBRSxDQUFDO0lBQ3hCLENBQUM7Q0FDRiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IFByb3BlcnRpZXNNYXAsIFByb3BlcnR5IH0gZnJvbSAnLi4vLi4vLi4vc2hhcmVkL3R5cGVzJztcbmltcG9ydCB7IGlzTmlsT3JCbGFuaywgaXNOb3ROaWwgfSBmcm9tICcuLi8uLi8uLi9zaGFyZWQvZnVuY3Rpb25zJztcblxuZXhwb3J0IGNsYXNzIEFwcFByb3BlcnRpZXNVdGlscyB7XG4gIC8qKlxuICAgKiBDb252ZXJ0cyBhbiBhcnJheSBvZiBQcm9wZXJ0eSBvYmplY3RzIHRvIGFuIG9iamVjdCBtYXAuXG4gICAqXG4gICAqIEBwYXJhbSB7UHJvcGVydHlbXX0gW3NvdXJjZXNdIC0gVGhlIGFycmF5IG9mIFByb3BlcnR5IG9iamVjdHMgdG8gY29udmVydC5cbiAgICogQHBhcmFtIHtPYmplY3R9IFtvcHRzXSAtIE9wdGlvbnMgZm9yIHRoZSBjb252ZXJzaW9uLlxuICAgKiBAcGFyYW0ge2Jvb2xlYW59IFtvcHRzLm9taXROaWxPckJsYW5rXSAtIElmIHNldCB0byB0cnVlLCBwcm9wZXJ0aWVzIHdpdGggbmlsIG9yIGJsYW5rIHZhbHVlcyB3aWxsIGJlIG9taXR0ZWQgZnJvbSB0aGUgcmVzdWx0aW5nIG9iamVjdC5cbiAgICogQHJldHVybiB7UHJvcGVydGllc01hcH0gVGhlIHJlc3VsdGluZyBvYmplY3QgbWFwIHdoZXJlIGtleXMgYXJlIHByb3BlcnR5IGtleXMgYW5kIHZhbHVlcyBhcmUgcHJvcGVydHkgdmFsdWVzLlxuICAgKi9cbiAgc3RhdGljIGFycmF5QXNPYmplY3Qoc291cmNlcz86IFByb3BlcnR5W10sIG9wdHM/OiB7IG9taXROaWxPckJsYW5rOiBib29sZWFuIH0pOiBQcm9wZXJ0aWVzTWFwIHtcbiAgICByZXR1cm4gKFxuICAgICAgKHNvdXJjZXMgfHwgW10pXG4gICAgICAgIC8vIFNlcmlhbGl6ZSBlYWNoIGl0ZW1cbiAgICAgICAgLm1hcChBcHBQcm9wZXJ0eVV0aWxzLmFzT2JqZWN0KVxuICAgICAgICAvLyBGaWxsIGEgSlNPTiBvYmplY3RcbiAgICAgICAgLnJlZHVjZShcbiAgICAgICAgICAocmVzLCBpdGVtKSA9PiB7XG4gICAgICAgICAgICBpZiAoaXNOaWxPckJsYW5rKGl0ZW0ua2V5KSkgcmV0dXJuIHJlcztcbiAgICAgICAgICAgIGlmIChpc05pbE9yQmxhbmsoaXRlbS52YWx1ZSkgJiYgb3B0cz8ub21pdE5pbE9yQmxhbmsgIT09IGZhbHNlKSByZXR1cm4gcmVzO1xuICAgICAgICAgICAgcmVzW2l0ZW0ua2V5XSA9IGl0ZW0udmFsdWU7XG4gICAgICAgICAgICByZXR1cm4gcmVzO1xuICAgICAgICAgIH0sXG4gICAgICAgICAgPFByb3BlcnRpZXNNYXA+e31cbiAgICAgICAgKVxuICAgICk7XG4gIH1cblxuICAvKipcbiAgICogQ29udmVydHMgYW4gb2JqZWN0IGludG8gYW4gYXJyYXkgb2YgcHJvcGVydGllcy5cbiAgICpcbiAgICogQHBhcmFtIHtQcm9wZXJ0aWVzTWFwfSBbc291cmNlXSAtIFRoZSBzb3VyY2Ugb2JqZWN0IGNvbnRhaW5pbmcgcHJvcGVydGllcyB0byBjb252ZXJ0LlxuICAgKiBAcmV0dXJuIHtQcm9wZXJ0eVtdfSBBbiBhcnJheSBvZiBwcm9wZXJ0aWVzIGRlcml2ZWQgZnJvbSB0aGUgc291cmNlIG9iamVjdC5cbiAgICovXG4gIHN0YXRpYyBhcnJheUZyb21PYmplY3Q8VCA9IGFueT4oc291cmNlPzogUHJvcGVydGllc01hcCk6IFByb3BlcnR5W10ge1xuICAgIGlmIChBcnJheS5pc0FycmF5KHNvdXJjZSkpIHJldHVybiBzb3VyY2U7IC8vIEFscmVhZHkgYW4gYXJyYXlcbiAgICByZXR1cm4gT2JqZWN0LmdldE93blByb3BlcnR5TmFtZXMoc291cmNlIHx8IHt9KS5tYXAoKGtleSkgPT4gKHtcbiAgICAgIGtleSxcbiAgICAgIHZhbHVlOiBzb3VyY2Vba2V5XSxcbiAgICB9KSk7XG4gIH1cbn1cblxuZXhwb3J0IGNsYXNzIEFwcFByb3BlcnR5VXRpbHMge1xuICBzdGF0aWMgYXNPYmplY3Qoc291cmNlOiBQcm9wZXJ0eSB8IGFueSk6IHsga2V5OiBzdHJpbmc7IHZhbHVlOiBzdHJpbmcgfSB8IHVuZGVmaW5lZCB7XG4gICAgaWYgKCFzb3VyY2UpIHJldHVybiB1bmRlZmluZWQ7XG4gICAgLy8gU2VyaWFsaXplIGtleSAoV0FSTklORzogY2FuIGJlIGFuIG9iamVjdCwgd2hlbiB1c2luZyBhdXRvY29tcGxldGUgZmllbGQgdG8gZWRpdCBhIGtleSAtIHNlZSBBcHBQcm9wZXJ0aWVzRm9ybSlcbiAgICBjb25zdCBrZXkgPSAoc291cmNlLmtleSBhcyBhbnkpPy5rZXkgPz8gc291cmNlLmtleTtcblxuICAgIC8vIFNlcmlhbGl6ZSB0aGUgdmFsdWVcbiAgICBsZXQgdmFsdWUgPSBzb3VyY2UudmFsdWU7XG4gICAgaWYgKEFycmF5LmlzQXJyYXkodmFsdWUpKSB7XG4gICAgICB2YWx1ZSA9IHZhbHVlXG4gICAgICAgIC5tYXAoKHYpID0+IHY/LmlkID8/IHYpXG4gICAgICAgIC5maWx0ZXIoaXNOb3ROaWwpXG4gICAgICAgIC5qb2luKCcsJyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHZhbHVlID0gKHZhbHVlIGFzIGFueSk/LmlkID8/IHZhbHVlO1xuICAgIH1cbiAgICByZXR1cm4geyBrZXksIHZhbHVlIH07XG4gIH1cbn1cbiJdfQ==
292
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJvcGVydGllcy51dGlscy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3NyYy9hcHAvY29yZS9mb3JtL3Byb3BlcnRpZXMvcHJvcGVydGllcy51dGlscy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFDQSxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsS0FBSyxFQUFFLFlBQVksRUFBRSxRQUFRLEVBQUUsZUFBZSxFQUFFLFNBQVMsRUFBRSxTQUFTLEVBQUUsUUFBUSxFQUFFLE1BQU0sMkJBQTJCLENBQUM7QUFJOUksTUFBTSxPQUFPLGtCQUFrQjtJQUM3Qjs7Ozs7Ozs7T0FRRztJQUNILE1BQU0sQ0FBQyxhQUFhLENBQVUsT0FBdUIsRUFBRSxXQUFtQyxFQUFFLElBQWtDO1FBQzVILE9BQU8sQ0FDTCxDQUFDLE9BQU8sSUFBSSxFQUFFLENBQUM7WUFDYixzQkFBc0I7YUFDckIsR0FBRyxDQUFDLENBQUMsTUFBTSxFQUFFLEVBQUU7WUFDZCxJQUFJLENBQUMsTUFBTTtnQkFBRSxPQUFPLFNBQVMsQ0FBQztZQUM5QixNQUFNLEdBQUcsR0FBRyxnQkFBZ0IsQ0FBQyxjQUFjLENBQUMsTUFBTSxDQUFDLENBQUM7WUFDcEQsSUFBSSxDQUFDLEdBQUc7Z0JBQUUsT0FBTyxTQUFTLENBQUM7WUFDM0IsTUFBTSxHQUFHLEdBQUcsV0FBVyxFQUFFLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLEdBQUcsS0FBSyxHQUFHLENBQUMsQ0FBQztZQUNwRCxPQUFPLGdCQUFnQixDQUFDLFFBQVEsQ0FBQyxNQUFNLEVBQUUsR0FBRyxDQUFDLENBQUM7UUFDaEQsQ0FBQyxDQUFDO1lBQ0YscUJBQXFCO2FBQ3BCLE1BQU0sQ0FDTCxDQUFDLEdBQUcsRUFBRSxJQUFJLEVBQUUsRUFBRTtZQUNaLElBQUksWUFBWSxDQUFDLElBQUksRUFBRSxHQUFHLENBQUM7Z0JBQUUsT0FBTyxHQUFHLENBQUM7WUFD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LHdEQUF3RCxHQUFHLENBQUMsR0FBRyxJQUFJLEtBQUssRUFBRSxFQUFFLEdBQUcsQ0FBQyxDQUFDO1lBQy9GLFdBQVc7UUFDYixDQUFDO1FBRUQsNEJBQTRCO1FBQzVCLE1BQU0sZ0JBQWdCLEdBQVE7WUFDNUIsQ0FBQyxrQkFBa0IsQ0FBQyxFQUFFLEtBQUs7U0FDNUIsQ0FBQztRQUVGLDRCQUE0QjtRQUM1QixHQUFHLENBQUMsWUFBWSxFQUFFLFVBQVUsRUFBRSxPQUFPLENBQUMsQ0FBQyxHQUFHLEVBQUUsRUFBRTtZQUM1QyxnQkFBZ0IsQ0FBQyxHQUFHLENBQUMsR0FBRyxnQkFBZ0IsQ0FBQyxHQUFHLENBQUMsSUFBSSxFQUFFLENBQUM7UUFDdEQsQ0FBQyxDQUFDLENBQUM7UUFFSCxPQUFPLGdCQUFnQixDQUFDO0lBQzFCLENBQUM7SUFFTyxNQUFNLENBQUMsUUFBUSxDQUFDLEtBQVc7UUFDakMsT0FBTyxLQUFLLEVBQUUsUUFBUSxFQUFFLENBQUM7SUFDM0IsQ0FBQztDQUNGIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgUHJvcGVydHksIFByb3BlcnR5TWFwIH0gZnJvbSAnLi4vLi4vLi4vc2hhcmVkL3R5cGVzJztcbmltcG9ydCB7IGdldFByb3BlcnR5QnlQYXRoLCBpc05pbCwgaXNOaWxPckJsYW5rLCBpc05vdE5pbCwgaXNOb3ROaWxPckJsYW5rLCBpc1Byb21pc2UsIHRvQm9vbGVhbiwgdG9OdW1iZXIgfSBmcm9tICcuLi8uLi8uLi9zaGFyZWQvZnVuY3Rpb25zJztcbmltcG9ydCB7IEZvcm1GaWVsZERlZmluaXRpb24gfSBmcm9tICcuLi8uLi8uLi9zaGFyZWQvZm9ybS9maWVsZC5tb2RlbCc7XG5pbXBvcnQgeyBFbnRpdGllc1NlcnZpY2VMb2FkT3B0aW9ucywgU3VnZ2VzdEZuIH0gZnJvbSAnLi4vLi4vLi4vc2hhcmVkL3NlcnZpY2VzL2VudGl0eS1zZXJ2aWNlLmNsYXNzJztcblxuZXhwb3J0IGNsYXNzIEFwcFByb3BlcnRpZXNVdGlscyB7XG4gIC8qKlxuICAgKiBDb252ZXJ0cyBhbiBhcnJheSBvZiBgUHJvcGVydHlgIG9iamVjdHMgaW50byBhIGBQcm9wZXJ0aWVzTWFwYCBvYmplY3QuXG4gICAqXG4gICAqIEBwYXJhbSB7UHJvcGVydHlbXX0gW3NvdXJjZXNdIC0gQW4gb3B0aW9uYWwgYXJyYXkgb2YgcHJvcGVydGllcyB0byBiZSBjb252ZXJ0ZWQuXG4gICAqIEBwYXJhbSB7Rm9ybUZpZWxkRGVmaW5pdGlvbltdfSBbZGVmaW5pdGlvbnNdIC0gQW4gb3B0aW9uYWwgYXJyYXkgb2YgZm9ybSBmaWVsZCBkZWZpbml0aW9ucyB0byBoZWxwIHdpdGggdGhlIGNvbnZlcnNpb24uXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBbb3B0c10gLSBPcHRpb25hbCBjb25maWd1cmF0aW9ucy5cbiAgICogQHBhcmFtIHtib29sZWFufSBbb3B0cy5vbWl0TmlsT3JCbGFua10gLSBJZiB0cnVlLCBwcm9wZXJ0aWVzIHdpdGggbmlsIG9yIGJsYW5rIHZhbHVlcyB3aWxsIGJlIG9taXR0ZWQuIERlZmF1bHRzIHRvIHRydWUuXG4gICAqIEByZXR1cm4ge1Byb3BlcnR5TWFwfSAtIFRoZSByZXN1bHRpbmcgYFByb3BlcnRpZXNNYXBgIG9iamVjdC5cbiAgICovXG4gIHN0YXRpYyBhcnJheUFzT2JqZWN0PFQgPSBhbnk+KHNvdXJjZXM/OiBQcm9wZXJ0eTxUPltdLCBkZWZpbml0aW9ucz86IEZvcm1GaWVsZERlZmluaXRpb25bXSwgb3B0cz86IHsgb21pdE5pbE9yQmxhbms6IGJvb2xlYW4gfSk6IFByb3BlcnR5TWFwIHtcbiAgICByZXR1cm4gKFxuICAgICAgKHNvdXJjZXMgfHwgW10pXG4gICAgICAgIC8vIFNlcmlhbGl6ZSBlYWNoIGl0ZW1cbiAgICAgICAgLm1hcCgoc291cmNlKSA9PiB7XG4gICAgICAgICAgaWYgKCFzb3VyY2UpIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICAgICAgY29uc3Qga2V5ID0gQXBwUHJvcGVydHlVdGlscy5nZXRQcm9wZXJ0eUtleShzb3VyY2UpO1xuICAgICAgICAgIGlmICgha2V5KSByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgICAgIGNvbnN0IGRlZiA9IGRlZmluaXRpb25zPy5maW5kKChkKSA9PiBkLmtleSA9PT0ga2V5KTtcbiAgICAgICAgICByZXR1cm4gQXBwUHJvcGVydHlVdGlscy5hc09iamVjdChzb3VyY2UsIGRlZik7XG4gICAgICAgIH0pXG4gICAgICAgIC8vIEZpbGwgYSBKU09OIG9iamVjdFxuICAgICAgICAucmVkdWNlKFxuICAgICAgICAgIChyZXMsIGl0ZW0pID0+IHtcbiAgICAgICAgICAgIGlmIChpc05pbE9yQmxhbmsoaXRlbT8ua2V5KSkgcmV0dXJuIHJlcztcbiAgICAgICAgICAgIC8vIFNraXAgaWYgbmlsIG9yIGJsYW5rIHZhbHVlXG4gICAgICAgICAgICBpZiAob3B0cz8ub21pdE5pbE9yQmxhbmsgIT09IGZhbHNlICYmIGlzTmlsT3JCbGFuayhpdGVtLnZhbHVlKSkgcmV0dXJuIHJlcztcbiAgICAgICAgICAgIHJlc1tpdGVtLmtleV0gPSBpdGVtLnZhbHVlO1xuICAgICAgICAgICAgcmV0dXJuIHJlcztcbiAgICAgICAgICB9LFxuICAgICAgICAgIDxQcm9wZXJ0eU1hcD57fVxuICAgICAgICApXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZW5lcmF0ZXMgYW4gYXJyYXkgb2YgcHJvcGVydGllcyBmcm9tIHRoZSBnaXZlbiBvYmplY3QsIG9wdGlvbmFsbHkgYXBwbHlpbmcgZGVmaW5pdGlvbnMgdG8gdGhlIHByb3BlcnRpZXMuXG4gICAqXG4gICAqIEBwYXJhbSB7UHJvcGVydHlNYXB9IFtzb3VyY2VzXSAtIFRoZSBzb3VyY2Ugb2JqZWN0IGZyb20gd2hpY2ggcHJvcGVydGllcyBhcmUgdG8gYmUgZXh0cmFjdGVkLlxuICAgKiBAcGFyYW0ge0Zvcm1GaWVsZERlZmluaXRpb25bXX0gW2RlZmluaXRpb25zXSAtIEFuIG9wdGlvbmFsIGFycmF5IG9mIGRlZmluaXRpb25zIHRvIGJlIGFwcGxpZWQgdG8gdGhlIGV4dHJhY3RlZCBwcm9wZXJ0aWVzLlxuICAgKiBAcGFyYW0gb3B0c1xuICAgKiBAcmV0dXJuIHtQcm9wZXJ0eVtdIHwgUHJvbWlzZTxQcm9wZXJ0eVtdPn0gQW4gYXJyYXkgb2YgcHJvcGVydGllcyBnZW5lcmF0ZWQgZnJvbSB0aGUgc291cmNlIG9iamVjdCwgb3IgYSBwcm9taXNlIHJlc29sdmluZyB0byB0aGF0IGFycmF5LlxuICAgKi9cbiAgc3RhdGljIGFycmF5RnJvbU9iamVjdDxUPihcbiAgICBzb3VyY2VzPzogUHJvcGVydHlNYXAgfCBQcm9wZXJ0eTxUPltdLFxuICAgIGRlZmluaXRpb25zPzogRm9ybUZpZWxkRGVmaW5pdGlvbltdLFxuICAgIG9wdHM/OiB7XG4gICAgICBrZWVwT3JwaGFuPzogYm9vbGVhbjsgLy8gdHJ1ZSBieSBkZWZhdWx0XG4gICAgfVxuICApOiBQcm9wZXJ0eTxUPltdIHwgUHJvbWlzZTxQcm9wZXJ0eTxUPltdPiB7XG4gICAgLy8gREVCVUdcbiAgICAvL2NvbnNvbGUuZGVidWcoYFtwcm9wZXJ0aWVzLXV0aWxzXSBDb252ZXJ0IHByb3BlcnR5IG1hcCBpbnRvIGFycmF5IG9mIFByb3BlcnR5Li4uYCk7XG5cbiAgICBsZXQgdGFyZ2V0cyA9IEFycmF5LmlzQXJyYXkoc291cmNlcylcbiAgICAgID8gc291cmNlcy5zbGljZSgpXG4gICAgICA6IE9iamVjdC5nZXRPd25Qcm9wZXJ0eU5hbWVzKHNvdXJjZXMgfHwge30pLm1hcChcbiAgICAgICAgICAoa2V5KSA9PlxuICAgICAgICAgICAgPFByb3BlcnR5PGFueT4+e1xuICAgICAgICAgICAgICBrZXksXG4gICAgICAgICAgICAgIHZhbHVlOiBzb3VyY2VzW2tleV0sXG4gICAgICAgICAgICB9XG4gICAgICAgICk7XG4gICAgY29uc3Qgam9icyA9IFtdO1xuXG4gICAgaWYgKCEhZGVmaW5pdGlvbnMpIHtcbiAgICAgIHRhcmdldHMgPSB0YXJnZXRzXG4gICAgICAgIC5tYXAoKHRhcmdldDogUHJvcGVydHk8YW55PikgPT4ge1xuICAgICAgICAgIC8vIEZpbmQgZGVmaW5pdGlvblxuICAgICAgICAgIGNvbnN0IGRlZiA9IGRlZmluaXRpb25zLmZpbmQoKGRlZikgPT4gZGVmLmtleSA9PT0gdGFyZ2V0LmtleSk7XG5cbiAgICAgICAgICAvLyBFeGNsdWRlIG5vIGRlZmluaXRpb24gKGlmIGV4cGVjdGVkIGJ5IHVzZXIgb3B0aW9ucylcbiAgICAgICAgICBpZiAoIWRlZiAmJiBvcHRzPy5rZWVwT3JwaGFuID09PSBmYWxzZSkgcmV0dXJuIG51bGw7XG5cbiAgICAgICAgICAvLyBEZXNlcmlhbGl6ZSBmcm9tIHN0cmluZ1xuICAgICAgICAgIGxldCBwcm9wZXJ0eU9yUHJvbWlzZSA9IEFwcFByb3BlcnR5VXRpbHMuZnJvbU9iamVjdCh0YXJnZXQsIGRlZik7XG4gICAgICAgICAgaWYgKGlzUHJvbWlzZShwcm9wZXJ0eU9yUHJvbWlzZSkpIHtcbiAgICAgICAgICAgIGpvYnMucHVzaChwcm9wZXJ0eU9yUHJvbWlzZS50aGVuKChwcm9wZXJ0eSkgPT4gKHRhcmdldC52YWx1ZSA9IHByb3BlcnR5LnZhbHVlKSkpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAvLyBVcGRhdGUgdGhlIHRhcmdldCB2YWx1ZVxuICAgICAgICAgICAgdGFyZ2V0LnZhbHVlID0gcHJvcGVydHlPclByb21pc2UudmFsdWU7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgcmV0dXJuIHRhcmdldDtcbiAgICAgICAgfSlcbiAgICAgICAgLy8gQ2xlYW4gb3JwaGFuXG4gICAgICAgIC5maWx0ZXIoaXNOb3ROaWwpO1xuXG4gICAgICAvLyBSZXR1cm4gYXMgcHJvbWlzZSwgd2hlbiBuZWVkXG4gICAgICBpZiAoam9icy5sZW5ndGgpIHJldHVybiBQcm9taXNlLmFsbChqb2JzKS50aGVuKCgpID0+IHRhcmdldHMgYXMgUHJvcGVydHk8VD5bXSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRhcmdldHMgYXMgUHJvcGVydHk8VD5bXTtcbiAgfVxufVxuXG5leHBvcnQgY2xhc3MgQXBwUHJvcGVydHlVdGlscyB7XG4gIHN0YXRpYyBrZXkoa2V5OiBhbnkpOiBzdHJpbmcge1xuICAgIHJldHVybiBrZXk/LmtleSA/PyBrZXk7XG4gIH1cblxuICBzdGF0aWMgZ2V0UHJvcGVydHlLZXkoc291cmNlOiBQcm9wZXJ0eSB8IGFueSk6IHN0cmluZyB7XG4gICAgaWYgKCFzb3VyY2UpIHJldHVybiB1bmRlZmluZWQ7XG4gICAgcmV0dXJuIChzb3VyY2Uua2V5IGFzIGFueSk/LmtleSA/PyBzb3VyY2Uua2V5O1xuICB9XG5cbiAgLyoqXG4gICAqIENvbnZlcnRzIHRoZSBnaXZlbiBzb3VyY2UgdG8gYW4gb2JqZWN0IHRoYXQgY29udGFpbnMgYSBrZXktdmFsdWUgcGFpci5cbiAgICpcbiAgICogQHBhcmFtIHtQcm9wZXJ0eTxhbnk+IHwgYW55fSBzb3VyY2UgLSBUaGUgc291cmNlIHByb3BlcnR5IG9yIGFueSB2YWx1ZSB0byBiZSBjb252ZXJ0ZWQuXG4gICAqIEBwYXJhbSB7Rm9ybUZpZWxkRGVmaW5pdGlvbn0gW2RlZl0gLSBUaGUgZm9ybSBmaWVsZCBkZWZpbml0aW9uIHVzZWQgZm9yIHNlcmlhbGl6YXRpb24uXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBbb3B0c10gLSBBZGRpdGlvbmFsIG9wdGlvbnMgZm9yIHNlcmlhbGl6YXRpb24uXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBbb3B0cy5kZWZhdWx0U2VyaWFsaXplQXR0cmlidXRlPSdpZCddIC0gVGhlIGF0dHJpYnV0ZSB0byBiZSB1c2VkIGZvciBkZWZhdWx0IHNlcmlhbGl6YXRpb24uXG4gICAqIEByZXR1cm4ge3sga2V5OiBzdHJpbmcsIHZhbHVlOiBzdHJpbmcgfSB8IHVuZGVmaW5lZH0gQW4gb2JqZWN0IGNvbnRhaW5pbmcgdGhlIHNlcmlhbGl6ZWQga2V5LXZhbHVlIHBhaXIsIG9yIHVuZGVmaW5lZCBpZiB0aGUgc291cmNlIGlzIG5vdCBwcm92aWRlZC5cbiAgICovXG4gIHN0YXRpYyBhc09iamVjdChcbiAgICBzb3VyY2U6IFByb3BlcnR5PGFueT4gfCBhbnksXG4gICAgZGVmPzogRm9ybUZpZWxkRGVmaW5pdGlvbixcbiAgICBvcHRzPzoge1xuICAgICAgZGVmYXVsdFNlcmlhbGl6ZUF0dHJpYnV0ZT86IHN0cmluZztcbiAgICB9XG4gICk6IHsga2V5OiBzdHJpbmc7IHZhbHVlOiBzdHJpbmcgfSB8IHVuZGVmaW5lZCB7XG4gICAgaWYgKCFzb3VyY2UpIHJldHVybiB1bmRlZmluZWQ7XG4gICAgLy8gU2VyaWFsaXplIGtleSAoV0FSTklORzogY2FuIGJlIGFuIG9iamVjdCwgd2hlbiB1c2luZyBhdXRvY29tcGxldGUgZmllbGQgdG8gZWRpdCBhIGtleSAtIHNlZSBBcHBQcm9wZXJ0aWVzRm9ybSlcbiAgICBjb25zdCBrZXkgPSBBcHBQcm9wZXJ0eVV0aWxzLmdldFByb3BlcnR5S2V5KHNvdXJjZSk7XG5cbiAgICAvLyBQcmVwYXJlIGEgZGVzZXJpYWxpemUgZnVuY3Rpb25cbiAgICBsZXQgc2VyaWFsaXplRm4gPSBkZWY/LnNlcmlhbGl6ZTtcbiAgICBpZiAoIXNlcmlhbGl6ZUZuKSB7XG4gICAgICBzd2l0Y2ggKGRlZj8udHlwZSB8fCAnb3RoZXInKSB7XG4gICAgICAgIGNhc2UgJ2VudW0nOlxuICAgICAgICBjYXNlICdlbnVtcyc6XG4gICAgICAgICAgc2VyaWFsaXplRm4gPSBBcHBQcm9wZXJ0eVV0aWxzLmtleTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSAnZW50aXR5JzpcbiAgICAgICAgY2FzZSAnZW50aXRpZXMnOlxuICAgICAgICAgIGNvbnN0IHNlcmlhbGl6ZUF0dHJpYnV0ZSA9IGRlZj8uc2VyaWFsaXplQXR0cmlidXRlID8/IG9wdHM/LmRlZmF1bHRTZXJpYWxpemVBdHRyaWJ1dGUgPz8gJ2lkJztcbiAgICAgICAgICBzZXJpYWxpemVGbiA9XG4gICAgICAgICAgICBkZWY/LnNlcmlhbGl6ZSB8fFxuICAgICAgICAgICAgKCh2YWx1ZSkgPT4ge1xuICAgICAgICAgICAgICBjb25zdCBzZXJpYWxpemVWYWx1ZSA9IGdldFByb3BlcnR5QnlQYXRoKHZhbHVlLCBzZXJpYWxpemVBdHRyaWJ1dGUsIHZhbHVlIC8qZGVmYXVsdCB2YWx1ZSovKTtcbiAgICAgICAgICAgICAgaWYgKGlzTmlsKHNlcmlhbGl6ZVZhbHVlKSkgcmV0dXJuIHNlcmlhbGl6ZVZhbHVlO1xuICAgICAgICAgICAgICByZXR1cm4gc2VyaWFsaXplVmFsdWUudG9TdHJpbmcoKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgIHNlcmlhbGl6ZUZuID0gQXBwUHJvcGVydHlVdGlscy50b1N0cmluZztcbiAgICAgIH1cbiAgICB9XG5cbiAgICBsZXQgdmFsdWVTdHI6IHN0cmluZztcblxuICAgIC8vIFZhbHVlIGlzIGFuIGFycmF5XG4gICAgaWYgKEFycmF5LmlzQXJyYXkoc291cmNlLnZhbHVlKSkge1xuICAgICAgdmFsdWVTdHIgPSBzb3VyY2UudmFsdWUubWFwKHNlcmlhbGl6ZUZuKS5maWx0ZXIoaXNOb3ROaWxPckJsYW5rKS5qb2luKCcsJyk7XG4gICAgfVxuICAgIC8vIEFueSBvdGhlciBjYXNlXG4gICAgZWxzZSB7XG4gICAgICB2YWx1ZVN0ciA9IHNlcmlhbGl6ZUZuKHNvdXJjZS52YWx1ZSk7XG4gICAgfVxuICAgIHJldHVybiB7IGtleSwgdmFsdWU6IHZhbHVlU3RyIH07XG4gIH1cblxuICBzdGF0aWMgZnJvbU9iamVjdDxUID0gc3RyaW5nPihcbiAgICBzb3VyY2U6IFByb3BlcnR5IHwgUHJvcGVydHk8VD4sXG4gICAgZGVmOiBGb3JtRmllbGREZWZpbml0aW9uLFxuICAgIG9wdHM/OiB7XG4gICAgICBkZWZhdWx0U3VnZ2VzdEZuOiBTdWdnZXN0Rm48YW55LCBhbnk+O1xuICAgICAgZGVmYXVsdFN1Z2dlc3RPcHRpb25zPzogRW50aXRpZXNTZXJ2aWNlTG9hZE9wdGlvbnM7XG4gICAgICBkZWZhdWx0U2VyaWFsaXplQXR0cmlidXRlPzogc3RyaW5nO1xuICAgIH1cbiAgKTogUHJvcGVydHk8VD4gfCBQcm9taXNlPFByb3BlcnR5PFQ+PiB7XG4gICAgaWYgKCFzb3VyY2U/LmtleSB8fCBpc05pbChzb3VyY2UudmFsdWUpIHx8ICFkZWYpIHJldHVybiBzb3VyY2UgYXMgUHJvcGVydHk8VD47IC8vIFNraXAgaWYgbm8ga2V5XG5cbiAgICAvLyBDbG9uZSB0aGUgc291cmNlXG4gICAgY29uc3QgdGFyZ2V0OiBQcm9wZXJ0eTxhbnk+ID0geyBrZXk6IHNvdXJjZS5rZXksIHZhbHVlOiBzb3VyY2UudmFsdWUgfTtcblxuICAgIGNvbnN0IGpvYnM6IFByb21pc2U8YW55PltdID0gW107XG4gICAgLy8gUmVzb2x2ZSB2YWx1ZVxuICAgIHN3aXRjaCAoZGVmLnR5cGUpIHtcbiAgICAgIGNhc2UgJ2Jvb2xlYW4nOlxuICAgICAgICB0YXJnZXQudmFsdWUgPSB0b0Jvb2xlYW4oc291cmNlLnZhbHVlIGFzIGFueSwgdG9Cb29sZWFuKGRlZi5kZWZhdWx0VmFsdWUpKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICdpbnRlZ2VyJzpcbiAgICAgIGNhc2UgJ2RvdWJsZSc6XG4gICAgICAgIHRhcmdldC52YWx1ZSA9IHRvTnVtYmVyKHNvdXJjZS52YWx1ZSBhcyBhbnksIHRvTnVtYmVyKGRlZi5kZWZhdWx0VmFsdWUpKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICdlbnVtJzpcbiAgICAgICAgY29uc3QgdmFsdWVLZXkgPSBBcHBQcm9wZXJ0eVV0aWxzLmtleSh0YXJnZXQudmFsdWUpO1xuICAgICAgICBpZiAoaXNOb3ROaWxPckJsYW5rKHZhbHVlS2V5KSkge1xuICAgICAgICAgIGNvbnN0IGVudW1WYWx1ZSA9IChkZWYudmFsdWVzIGFzIChzdHJpbmcgfCBQcm9wZXJ0eSlbXSk/LmZpbmQoKGRlZlZhbHVlKSA9PiBkZWZWYWx1ZSAmJiB2YWx1ZUtleSA9PT0gKGRlZlZhbHVlWydrZXknXSB8fCBkZWZWYWx1ZSkpID8/IG51bGw7XG4gICAgICAgICAgdGFyZ2V0LnZhbHVlID0gZW51bVZhbHVlPy5bJ2tleSddID8/IGVudW1WYWx1ZSA/PyBudWxsO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRhcmdldC52YWx1ZSA9IG51bGw7XG4gICAgICAgIH1cbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICdlbnVtcyc6XG4gICAgICAgIGNvbnN0IHZhbHVlS2V5cyA9IEFycmF5LmlzQXJyYXkoc291cmNlLnZhbHVlKVxuICAgICAgICAgID8gc291cmNlLnZhbHVlLm1hcChBcHBQcm9wZXJ0eVV0aWxzLmtleSkgLy8gQ29weVxuICAgICAgICAgIDogdHlwZW9mIHNvdXJjZS52YWx1ZSA9PT0gJ3N0cmluZydcbiAgICAgICAgICAgID8gc291cmNlLnZhbHVlLnRyaW0oKS5zcGxpdCgvLCsvKVxuICAgICAgICAgICAgOiBbQXBwUHJvcGVydHlVdGlscy5rZXkoc291cmNlLnZhbHVlKV07XG4gICAgICAgIHRhcmdldC52YWx1ZSA9IHZhbHVlS2V5c1xuICAgICAgICAgIC5maWx0ZXIoaXNOb3ROaWwpXG4gICAgICAgICAgLm1hcChcbiAgICAgICAgICAgIChrZXk6IHN0cmluZykgPT5cbiAgICAgICAgICAgICAgKGRlZi52YWx1ZXMgYXMgKHN0cmluZyB8IFByb3BlcnR5KVtdKT8uZmluZCgoZGVmVmFsdWUpID0+IGRlZlZhbHVlICYmIGtleSA9PT0gKGRlZlZhbHVlWydrZXknXSB8fCBkZWZWYWx1ZSkpIHx8IHsga2V5LCB2YWx1ZTogJz8nIH1cbiAgICAgICAgICApO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ2VudGl0eSc6XG4gICAgICAgIC8vIERlc2VyaWFsaXplIGVudGl0eSAoZS5nLiBsb2FkIGVudGl0eSBmcm9tIHRoZSBpZClcbiAgICAgICAgY29uc3QgdmFsdWVPclByb21pc2UgPSBBcHBQcm9wZXJ0eVV0aWxzLnJlc29sdmVFbnRpdHkodGFyZ2V0LnZhbHVlLCBkZWYsIG9wdHMpO1xuICAgICAgICBpZiAoaXNQcm9taXNlKHZhbHVlT3JQcm9taXNlKSkge1xuICAgICAgICAgIGpvYnMucHVzaChcbiAgICAgICAgICAgIHZhbHVlT3JQcm9taXNlLnRoZW4oKHZhbHVlKSA9PiB7XG4gICAgICAgICAgICAgIHRhcmdldC52YWx1ZSA9IHZhbHVlO1xuICAgICAgICAgICAgfSlcbiAgICAgICAgICApO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRhcmdldC52YWx1ZSA9IHZhbHVlT3JQcm9taXNlIGFzIGFueTtcbiAgICAgICAgfVxuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ2VudGl0aWVzJzpcbiAgICAgICAgLy8gQ29udmVydCB2YWx1ZSB0byBhcnJheVxuICAgICAgICB0YXJnZXQudmFsdWUgPSBBcnJheS5pc0FycmF5KHNvdXJjZS52YWx1ZSlcbiAgICAgICAgICA/IHNvdXJjZS52YWx1ZS5zbGljZSgpIC8vIENvcHlcbiAgICAgICAgICA6IHR5cGVvZiBzb3VyY2UudmFsdWUgPT09ICdzdHJpbmcnXG4gICAgICAgICAgICA/IHNvdXJjZS52YWx1ZVxuICAgICAgICAgICAgICAgIC5zcGxpdCgnLCcpXG4gICAgICAgICAgICAgICAgLm1hcCgodikgPT4gdi50cmltKCkpXG4gICAgICAgICAgICAgICAgLmZpbHRlcihpc05vdE5pbE9yQmxhbmspXG4gICAgICAgICAgICA6IFtdO1xuXG4gICAgICAgIC8vIERlc2VyaWFsaXplIGVhY2ggc3ViLXZhbHVlXG4gICAgICAgIGxldCBpbmRleCA9IDA7XG4gICAgICAgIGZvciAobGV0IHN1YlZhbHVlIG9mIHRhcmdldC52YWx1ZSkge1xuICAgICAgICAgIC8vIERlc2VyaWFsaXplIHN1Yi12YWx1ZVxuICAgICAgICAgIGNvbnN0IHN1YlZhbHVlT3JQcm9taXNlID0gQXBwUHJvcGVydHlVdGlscy5yZXNvbHZlRW50aXR5KHN1YlZhbHVlLCBkZWYsIG9wdHMpO1xuXG4gICAgICAgICAgLy8gQWRkIHByb21pc2UgdG8gam9ic1xuICAgICAgICAgIGlmIChpc1Byb21pc2Uoc3ViVmFsdWVPclByb21pc2UpKSB7XG4gICAgICAgICAgICBjb25zdCBmaW5hbEluZGV4ID0gaW5kZXg7XG4gICAgICAgICAgICBqb2JzLnB1c2goXG4gICAgICAgICAgICAgIHN1YlZhbHVlT3JQcm9taXNlLnRoZW4oKHZhbHVlKSA9PiB7XG4gICAgICAgICAgICAgICAgLy8gVXBkYXRlIHN1YiB2YWx1ZVxuICAgICAgICAgICAgICAgIHRhcmdldC52YWx1ZVtmaW5hbEluZGV4XSA9IHZhbHVlO1xuICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgLy8gVXBkYXRlIHN1YiB2YWx1ZVxuICAgICAgICAgICAgdGFyZ2V0LnZhbHVlW2luZGV4XSA9IHN1YlZhbHVlT3JQcm9taXNlIGFzIGFueTtcbiAgICAgICAgICB9XG4gICAgICAgICAgaW5kZXgrKztcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8vIC8hXFwgUmV0dXJuIGFzIHByb21pc2Ugb25seSBpZiBuZWVkIChsZXQgZnVuY3Rpb24gc3luYyB3aGVuIHBvc3NpYmxlKVxuICAgIGlmIChqb2JzLmxlbmd0aCkgcmV0dXJuIFByb21pc2UuYWxsKGpvYnMpLnRoZW4oKCkgPT4gdGFyZ2V0KTtcblxuICAgIHJldHVybiB0YXJnZXQ7XG4gIH1cblxuICBwcml2YXRlIHN0YXRpYyByZXNvbHZlRW50aXR5KFxuICAgIHZhbHVlOiBhbnksXG4gICAgZGVmOiBGb3JtRmllbGREZWZpbml0aW9uLFxuICAgIG9wdHM/OiB7XG4gICAgICBkZWZhdWx0U3VnZ2VzdEZuOiBTdWdnZXN0Rm48YW55LCBhbnk+O1xuICAgICAgZGVmYXVsdFN1Z2dlc3RPcHRpb25zPzogRW50aXRpZXNTZXJ2aWNlTG9hZE9wdGlvbnM7XG4gICAgICBkZWZhdWx0U2VyaWFsaXplQXR0cmlidXRlPzogc3RyaW5nO1xuICAgIH1cbiAgKTogYW55IHwgUHJvbWlzZTxhbnk+IHtcbiAgICAvLyBVc2UgZGVzZXJpYWxpemUgZnVuY3Rpb24sIGlmIGFueVxuICAgIGlmIChkZWYuZGVzZXJpYWxpemUpIHtcbiAgICAgIHJldHVybiBkZWYuZGVzZXJpYWxpemUodmFsdWUpO1xuICAgIH1cblxuICAgIC8vIE9yIHRyeSB1c2luZyBzdWdnZXN0IGZ1bmN0aW9uXG4gICAgcmV0dXJuIHRoaXMucmVzb2x2ZUVudGl0eUJ5U3VnZ2VzdCh2YWx1ZSwgZGVmLCBvcHRzKTtcbiAgfVxuXG4gIHByaXZhdGUgc3RhdGljIGFzeW5jIHJlc29sdmVFbnRpdHlCeVN1Z2dlc3QoXG4gICAgdmFsdWU6IGFueSxcbiAgICBkZWY6IEZvcm1GaWVsZERlZmluaXRpb24sXG4gICAgb3B0cz86IHtcbiAgICAgIGRlZmF1bHRTdWdnZXN0Rm46IFN1Z2dlc3RGbjxhbnksIGFueT47XG4gICAgICBkZWZhdWx0U3VnZ2VzdE9wdGlvbnM/OiBFbnRpdGllc1NlcnZpY2VMb2FkT3B0aW9ucztcbiAgICAgIGRlZmF1bHRTZXJpYWxpemVBdHRyaWJ1dGU/OiBzdHJpbmc7XG4gICAgfVxuICApOiBQcm9taXNlPGFueT4ge1xuICAgIGNvbnN0IHNlcmlhbGl6ZUF0dHJpYnV0ZSA9IGRlZi5zZXJpYWxpemVBdHRyaWJ1dGUgPz8gb3B0cz8uZGVmYXVsdFNlcmlhbGl6ZUF0dHJpYnV0ZSA/PyAnaWQnO1xuICAgIGlmICh0eXBlb2YgdmFsdWUgPT09ICdvYmplY3QnICYmIGlzTm90TmlsKHZhbHVlW3NlcmlhbGl6ZUF0dHJpYnV0ZV0pKSB7XG4gICAgICByZXR1cm4gdmFsdWU7IC8vIEFscmVhZHkgcmVzb2x2ZVxuICAgIH1cblxuICAgIGNvbnN0IHN1Z2dlc3RGbjogU3VnZ2VzdEZuPGFueSwgYW55PiA9IGRlZi5hdXRvY29tcGxldGU/LnN1Z2dlc3RGbiB8fCBvcHRzPy5kZWZhdWx0U3VnZ2VzdEZuO1xuICAgIGlmICghc3VnZ2VzdEZuKSB7XG4gICAgICBjb25zb2xlLndhcm4oXG4gICAgICAgIGBNaXNzaW5nICdkZXNlcmlhbGl6ZScgb3IgJ2F1dG9jb21wbGV0ZS5zdWdnZXN0Rm4nIGluIHRoZSBmaWVsZCBkZWZpbml0aW9uICcke2RlZi5rZXl9Jy4gQ2Fubm90IGRlc2VyaWFsaXplIHZhbHVlOiAke0pTT04uc3RyaW5naWZ5KHZhbHVlKX1gXG4gICAgICApO1xuICAgICAgcmV0dXJuIHZhbHVlOyAvLyBTa2lwXG4gICAgfVxuICAgIGxldCBzZWFyY2hWYWx1ZSA9IHZhbHVlO1xuICAgIGNvbnN0IGZpbHRlciA9IHsgLi4uZGVmLmF1dG9jb21wbGV0ZT8uZmlsdGVyIH07IC8vIENvcGUgZmlsdGVyXG4gICAgaWYgKHNlcmlhbGl6ZUF0dHJpYnV0ZSA9PT0gJ2lkJyB8fCBzZXJpYWxpemVBdHRyaWJ1dGUgPT09ICdsYWJlbCcpIHtcbiAgICAgIGZpbHRlcltzZXJpYWxpemVBdHRyaWJ1dGVdID0gc2VyaWFsaXplQXR0cmlidXRlID09PSAnaWQnID8gK3ZhbHVlIDogdmFsdWU7XG4gICAgICBzZWFyY2hWYWx1ZSA9ICcqJztcbiAgICAgIC8vIERFQlVHXG4gICAgICAvL2NvbnNvbGUuZGVidWcoYFtwcm9wZXJ0aWVzLXV0aWxzXSBSZXNvbHZpbmcgZW50aXR5IHdoZXJlIGlkPSR7dmFsdWV9Li4uYCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGZpbHRlci5zZWFyY2hBdHRyaWJ1dGUgPSBzZXJpYWxpemVBdHRyaWJ1dGU7XG4gICAgICAvLyBERUJVR1xuICAgICAgLy9jb25zb2xlLmRlYnVnKGBbcHJvcGVydGllcy11dGlsc10gUmVzb2x2aW5nIGVudGl0eSB3aGVyZSAke3NlcmlhbGl6ZUF0dHJpYnV0ZX09JHtzZWFyY2hWYWx1ZX0uLi5gKTtcbiAgICB9XG5cbiAgICB0cnkge1xuICAgICAgLy8gRmV0Y2ggZW50aXR5LCB1c2luZyB0aGUgc3VnZ2VzdCBmdW5jdGlvblxuICAgICAgY29uc3QgcmVzID0gYXdhaXQgc3VnZ2VzdEZuKHNlYXJjaFZhbHVlLCBmaWx0ZXIsIHNlcmlhbGl6ZUF0dHJpYnV0ZSwgJ2FzYycsIHtcbiAgICAgICAgd2l0aFRvdGFsOiBmYWxzZSxcbiAgICAgICAgb2Zmc2V0OiAwLFxuICAgICAgICBzaXplOiAxLFxuICAgICAgICAuLi5vcHRzPy5kZWZhdWx0U3VnZ2VzdE9wdGlvbnMsXG4gICAgICB9KTtcblxuICAgICAgLy8gR2V0IHJlc3VsdCBhcnJheVxuICAgICAgY29uc3QgZGF0YSA9IEFycmF5LmlzQXJyYXkocmVzKSA/IHJlcyA6IHJlcy5kYXRhO1xuXG4gICAgICBpZiAoZGF0YT8ubGVuZ3RoID4gMCkge1xuICAgICAgICBpZiAoZGF0YT8ubGVuZ3RoID4gMSkge1xuICAgICAgICAgIGNvbnNvbGUud2FybihcbiAgICAgICAgICAgIGBbcHJvcGVydGllcy11dGlsc10gTW9yZSB0aGFuIG9uZSBlbnRpdHkgZm91bmQsIGZvciBvcHRpb24gJHtkZWYua2V5fT0ke3ZhbHVlfSEgUGxlYXNlIGNoZWNrIG9wdGlvbidzIGRlZmluaXRpb24gYW5kIHRoZSAnYXV0b2NvbXBsZXRlLnN1Z2dlc3RGbicgZnVuY3Rpb25gLFxuICAgICAgICAgICAgZGF0YVxuICAgICAgICAgICk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBERUJVR1xuICAgICAgICAvL2NvbnNvbGUuZGVidWcoYFtwcm9wZXJ0aWVzLXV0aWxzXSAke2RhdGEubGVuZ3RofSBlbnRpdGllcyBmb3VuZDogYCwgZGF0YSk7XG5cbiAgICAgICAgLy8gT2ssIHdlIGZpbmQgaXQgPT4gc3RvcCBoZXJlXG4gICAgICAgIHJldHVybiBkYXRhWzBdO1xuICAgICAgfVxuXG4gICAgICAvLyBXYXJuLCBidXQgY29udGludWVcbiAgICAgIGNvbnNvbGUud2FybihcbiAgICAgICAgYFtwcm9wZXJ0aWVzLXV0aWxzXSBVbmFibGUgdG8gcmVzb2x2ZSBlbnRpdHkgZm9yIG9wdGlvbjogJHtkZWYua2V5fT0ke3ZhbHVlfS4gUGxlYXNlIGNoZWNrIG9wdGlvbidzIGRlZmluaXRpb24gYW5kIHRoZSAnYXV0b2NvbXBsZXRlLnN1Z2dlc3RGbicgZnVuY3Rpb25gXG4gICAgICApO1xuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgY29uc29sZS5lcnJvcihgW3Byb3BlcnRpZXMtdXRpbHNdIENhbm5vdCByZXNvbHZlIGVudGl0eSBmb3Igb3B0aW9uOiAke2RlZi5rZXl9PSR7dmFsdWV9YCwgZXJyKTtcbiAgICAgIC8vIENvbnRpbnVlXG4gICAgfVxuXG4gICAgLy8gQ3JlYXRlIHRoZSBtaXNzaW5nIHJlc3VsdFxuICAgIGNvbnN0IHVucmVzb2x2ZWRFbnRpdHkgPSA8YW55PntcbiAgICAgIFtzZXJpYWxpemVBdHRyaWJ1dGVdOiB2YWx1ZSxcbiAgICB9O1xuXG4gICAgLy8gRmlsbCBhdHRyaWJ1dGVzIHdpdGggJz8/J1xuICAgIGRlZi5hdXRvY29tcGxldGU/LmF0dHJpYnV0ZXM/LmZvckVhY2goKGtleSkgPT4ge1xuICAgICAgdW5yZXNvbHZlZEVudGl0eVtrZXldID0gdW5yZXNvbHZlZEVudGl0eVtrZXldID8/ICcnO1xuICAgIH0pO1xuXG4gICAgcmV0dXJuIHVucmVzb2x2ZWRFbnRpdHk7XG4gIH1cblxuICBwcml2YXRlIHN0YXRpYyB0b1N0cmluZyh2YWx1ZT86IGFueSk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHZhbHVlPy50b1N0cmluZygpO1xuICB9XG59XG4iXX0=
@@ -1,7 +1,9 @@
1
1
  import { Injectable } from '@angular/core';
2
2
  import { Validators } from '@angular/forms';
3
3
  import { AppValidatorService } from '../../services/validator/base.validator.class';
4
- import { isNil } from '../../../shared/functions';
4
+ import { isNil, isNotEmptyArray } from '../../../shared/functions';
5
+ import { AppFormArray } from '../array/form-array';
6
+ import { AppPropertiesUtils } from './properties.utils';
5
7
  import * as i0 from "@angular/core";
6
8
  import * as i1 from "@angular/forms";
7
9
  export class PropertyValidator extends AppValidatorService {
@@ -10,14 +12,44 @@ export class PropertyValidator extends AppValidatorService {
10
12
  super(formBuilder, null);
11
13
  this.formBuilder = formBuilder;
12
14
  }
15
+ getFormArray(data, opts) {
16
+ const fromArray = new AppFormArray((value) => this.getFormGroup(value, { valueMaxLength: 2000 }), (v1, v2) => this.equals(v1, v2), (value) => this.isEmpty(value), {
17
+ allowReuseControls: false,
18
+ allowEmptyArray: true,
19
+ });
20
+ // Set data, if any
21
+ if (data) {
22
+ const dataArrayOrPromise = AppPropertiesUtils.arrayFromObject(data, opts?.definitions);
23
+ if (Array.isArray(dataArrayOrPromise)) {
24
+ if (isNotEmptyArray(dataArrayOrPromise))
25
+ fromArray.patchValue(dataArrayOrPromise);
26
+ }
27
+ else {
28
+ // If promise: wait and set after
29
+ dataArrayOrPromise
30
+ .catch((err) => {
31
+ console.error('[property-validator] Error during conversion from map to array conversion: ' + (err?.message || err), data, err);
32
+ return null;
33
+ })
34
+ .then((values) => {
35
+ if (isNotEmptyArray(values))
36
+ fromArray.patchValue(values);
37
+ fromArray.updateValueAndValidity();
38
+ });
39
+ // Wait value to be set
40
+ fromArray.markAsPending();
41
+ }
42
+ }
43
+ return fromArray;
44
+ }
13
45
  getFormGroup(data, opts) {
14
46
  return this.formBuilder.group(this.getFormGroupConfig(data, opts));
15
47
  }
16
48
  getFormGroupConfig(data, opts) {
17
49
  return {
18
- key: [(data && data.key) || null, Validators.compose([Validators.required, Validators.max(50)])],
50
+ key: [data?.key ?? null, Validators.compose([Validators.required, Validators.max(50)])],
19
51
  value: [
20
- (data && data.value) || null,
52
+ data?.value ?? null,
21
53
  opts?.valueMaxLength > 0 ? Validators.compose([Validators.required, Validators.max(opts.valueMaxLength)]) : Validators.required,
22
54
  ],
23
55
  };
@@ -35,4 +67,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.8", ngImpor
35
67
  type: Injectable,
36
68
  args: [{ providedIn: 'root' }]
37
69
  }], ctorParameters: () => [{ type: i1.UntypedFormBuilder }] });
38
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJvcGVydHkudmFsaWRhdG9yLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vc3JjL2FwcC9jb3JlL2Zvcm0vcHJvcGVydGllcy9wcm9wZXJ0eS52YWxpZGF0b3IudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUMzQyxPQUFPLEVBQXdDLFVBQVUsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBRWxGLE9BQU8sRUFBRSxtQkFBbUIsRUFBRSxNQUFNLCtDQUErQyxDQUFDO0FBQ3BGLE9BQU8sRUFBRSxLQUFLLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQzs7O0FBT2xELE1BQU0sT0FBTyxpQkFBa0IsU0FBUSxtQkFBNkI7SUFDNUM7SUFBdEIsWUFBc0IsV0FBK0I7UUFDbkQsS0FBSyxDQUFDLFdBQVcsRUFBRSxJQUFJLENBQUMsQ0FBQztRQURMLGdCQUFXLEdBQVgsV0FBVyxDQUFvQjtJQUVyRCxDQUFDO0lBRUQsWUFBWSxDQUFDLElBQWUsRUFBRSxJQUErQjtRQUMzRCxPQUFPLElBQUksQ0FBQyxXQUFXLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLENBQUMsQ0FBQztJQUNyRSxDQUFDO0lBRUQsa0JBQWtCLENBQUMsSUFBZSxFQUFFLElBQStCO1FBQ2pFLE9BQU87WUFDTCxHQUFHLEVBQUUsQ0FBQyxDQUFDLElBQUksSUFBSSxJQUFJLENBQUMsR0FBRyxDQUFDLElBQUksSUFBSSxFQUFFLFVBQVUsQ0FBQyxPQUFPLENBQUMsQ0FBQyxVQUFVLENBQUMsUUFBUSxFQUFFLFVBQVUsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQ2hHLEtBQUssRUFBRTtnQkFDTCxDQUFDLElBQUksSUFBSSxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksSUFBSTtnQkFDNUIsSUFBSSxFQUFFLGNBQWMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxPQUFPLENBQUMsQ0FBQyxVQUFVLENBQUMsUUFBUSxFQUFFLFVBQVUsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLGNBQWMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsVUFBVSxDQUFDLFFBQVE7YUFDaEk7U0FDRixDQUFDO0lBQ0osQ0FBQztJQUVELE1BQU0sQ0FBQyxFQUFZLEVBQUUsRUFBWTtRQUMvQixPQUFPLENBQUMsQ0FBQyxFQUFFLElBQUksQ0FBQyxFQUFFLENBQUMsSUFBSSxFQUFFLENBQUMsR0FBRyxLQUFLLEVBQUUsQ0FBQyxHQUFHLENBQUM7SUFDM0MsQ0FBQztJQUVELE9BQU8sQ0FBQyxHQUFhO1FBQ25CLE9BQU8sS0FBSyxDQUFDLEdBQUcsRUFBRSxHQUFHLENBQUMsSUFBSSxLQUFLLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQzdDLENBQUM7dUdBekJVLGlCQUFpQjsyR0FBakIsaUJBQWlCLGNBREosTUFBTTs7MkZBQ25CLGlCQUFpQjtrQkFEN0IsVUFBVTttQkFBQyxFQUFFLFVBQVUsRUFBRSxNQUFNLEVBQUUiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBJbmplY3RhYmxlIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBVbnR5cGVkRm9ybUJ1aWxkZXIsIFVudHlwZWRGb3JtR3JvdXAsIFZhbGlkYXRvcnMgfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XG5pbXBvcnQgeyBQcm9wZXJ0eSB9IGZyb20gJy4uLy4uLy4uL3NoYXJlZC90eXBlcyc7XG5pbXBvcnQgeyBBcHBWYWxpZGF0b3JTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vc2VydmljZXMvdmFsaWRhdG9yL2Jhc2UudmFsaWRhdG9yLmNsYXNzJztcbmltcG9ydCB7IGlzTmlsIH0gZnJvbSAnLi4vLi4vLi4vc2hhcmVkL2Z1bmN0aW9ucyc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgUHJvcGVydHlWYWxpZGF0b3JPcHRpb25zIHtcbiAgdmFsdWVNYXhMZW5ndGg/OiBudW1iZXI7XG59XG5cbkBJbmplY3RhYmxlKHsgcHJvdmlkZWRJbjogJ3Jvb3QnIH0pXG5leHBvcnQgY2xhc3MgUHJvcGVydHlWYWxpZGF0b3IgZXh0ZW5kcyBBcHBWYWxpZGF0b3JTZXJ2aWNlPFByb3BlcnR5PiB7XG4gIGNvbnN0cnVjdG9yKHByb3RlY3RlZCBmb3JtQnVpbGRlcjogVW50eXBlZEZvcm1CdWlsZGVyKSB7XG4gICAgc3VwZXIoZm9ybUJ1aWxkZXIsIG51bGwpO1xuICB9XG5cbiAgZ2V0Rm9ybUdyb3VwKGRhdGE/OiBQcm9wZXJ0eSwgb3B0cz86IFByb3BlcnR5VmFsaWRhdG9yT3B0aW9ucyk6IFVudHlwZWRGb3JtR3JvdXAge1xuICAgIHJldHVybiB0aGlzLmZvcm1CdWlsZGVyLmdyb3VwKHRoaXMuZ2V0Rm9ybUdyb3VwQ29uZmlnKGRhdGEsIG9wdHMpKTtcbiAgfVxuXG4gIGdldEZvcm1Hcm91cENvbmZpZyhkYXRhPzogUHJvcGVydHksIG9wdHM/OiBQcm9wZXJ0eVZhbGlkYXRvck9wdGlvbnMpOiB7IFtwOiBzdHJpbmddOiBhbnkgfSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIGtleTogWyhkYXRhICYmIGRhdGEua2V5KSB8fCBudWxsLCBWYWxpZGF0b3JzLmNvbXBvc2UoW1ZhbGlkYXRvcnMucmVxdWlyZWQsIFZhbGlkYXRvcnMubWF4KDUwKV0pXSxcbiAgICAgIHZhbHVlOiBbXG4gICAgICAgIChkYXRhICYmIGRhdGEudmFsdWUpIHx8IG51bGwsXG4gICAgICAgIG9wdHM/LnZhbHVlTWF4TGVuZ3RoID4gMCA/IFZhbGlkYXRvcnMuY29tcG9zZShbVmFsaWRhdG9ycy5yZXF1aXJlZCwgVmFsaWRhdG9ycy5tYXgob3B0cy52YWx1ZU1heExlbmd0aCldKSA6IFZhbGlkYXRvcnMucmVxdWlyZWQsXG4gICAgICBdLFxuICAgIH07XG4gIH1cblxuICBlcXVhbHModjE6IFByb3BlcnR5LCB2MjogUHJvcGVydHkpOiBib29sZWFuIHtcbiAgICByZXR1cm4gKCF2MSAmJiAhdjIpIHx8IHYxLmtleSA9PT0gdjIua2V5O1xuICB9XG5cbiAgaXNFbXB0eShvYmo6IFByb3BlcnR5KTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIGlzTmlsKG9iaj8ua2V5KSB8fCBpc05pbChvYmoudmFsdWUpO1xuICB9XG59XG4iXX0=
70
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJvcGVydHkudmFsaWRhdG9yLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vc3JjL2FwcC9jb3JlL2Zvcm0vcHJvcGVydGllcy9wcm9wZXJ0eS52YWxpZGF0b3IudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUMzQyxPQUFPLEVBQXdDLFVBQVUsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBRWxGLE9BQU8sRUFBRSxtQkFBbUIsRUFBRSxNQUFNLCtDQUErQyxDQUFDO0FBQ3BGLE9BQU8sRUFBRSxLQUFLLEVBQUUsZUFBZSxFQUFFLE1BQU0sMkJBQTJCLENBQUM7QUFFbkUsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBQ25ELE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLG9CQUFvQixDQUFDOzs7QUFheEQsTUFBTSxPQUFPLGlCQUFrQixTQUFRLG1CQUE2QjtJQUM1QztJQUF0QixZQUFzQixXQUErQjtRQUNuRCxLQUFLLENBQUMsV0FBVyxFQUFFLElBQUksQ0FBQyxDQUFDO1FBREwsZ0JBQVcsR0FBWCxXQUFXLENBQW9CO0lBRXJELENBQUM7SUFFRCxZQUFZLENBQUMsSUFBVSxFQUFFLElBQWlDO1FBQ3hELE1BQU0sU0FBUyxHQUFHLElBQUksWUFBWSxDQUNoQyxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxLQUFLLEVBQUUsRUFBRSxjQUFjLEVBQUUsSUFBSSxFQUFFLENBQUMsRUFDN0QsQ0FBQyxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLEVBQUUsRUFBRSxFQUFFLENBQUMsRUFDL0IsQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLEVBQzlCO1lBQ0Usa0JBQWtCLEVBQUUsS0FBSztZQUN6QixlQUFlLEVBQUUsSUFBSTtTQUN0QixDQUNGLENBQUM7UUFFRixtQkFBbUI7UUFDbkIsSUFBSSxJQUFJLEVBQUUsQ0FBQztZQUNULE1BQU0sa0JBQWtCLEdBQUcsa0JBQWtCLENBQUMsZUFBZSxDQUFDLElBQUksRUFBRSxJQUFJLEVBQUUsV0FBVyxDQUFDLENBQUM7WUFDdkYsSUFBSSxLQUFLLENBQUMsT0FBTyxDQUFDLGtCQUFrQixDQUFDLEVBQUUsQ0FBQztnQkFDdEMsSUFBSSxlQUFlLENBQUMsa0JBQWtCLENBQUM7b0JBQUUsU0FBUyxDQUFDLFVBQVUsQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDO1lBQ3BGLENBQUM7aUJBQU0sQ0FBQztnQkFDTixpQ0FBaUM7Z0JBQ2pDLGtCQUFrQjtxQkFDZixLQUFLLENBQUMsQ0FBQyxHQUFHLEVBQUUsRUFBRTtvQkFDYixPQUFPLENBQUMsS0FBSyxDQUFDLDZFQUE2RSxHQUFHLENBQUMsR0FBRyxFQUFFLE9BQU8sSUFBSSxHQUFHLENBQUMsRUFBRSxJQUFJLEVBQUUsR0FBRyxDQUFDLENBQUM7b0JBQ2hJLE9BQU8sSUFBSSxDQUFDO2dCQUNkLENBQUMsQ0FBQztxQkFDRCxJQUFJLENBQUMsQ0FBQyxNQUFNLEVBQUUsRUFBRTtvQkFDZixJQUFJLGVBQWUsQ0FBQyxNQUFNLENBQUM7d0JBQUUsU0FBUyxDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUMsQ0FBQztvQkFDMUQsU0FBUyxDQUFDLHNCQUFzQixFQUFFLENBQUM7Z0JBQ3JDLENBQUMsQ0FBQyxDQUFDO2dCQUVMLHVCQUF1QjtnQkFDdkIsU0FBUyxDQUFDLGFBQWEsRUFBRSxDQUFDO1lBQzVCLENBQUM7UUFDSCxDQUFDO1FBQ0QsT0FBTyxTQUFTLENBQUM7SUFDbkIsQ0FBQztJQUVELFlBQVksQ0FBQyxJQUFlLEVBQUUsSUFBK0I7UUFDM0QsT0FBTyxJQUFJLENBQUMsV0FBVyxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsa0JBQWtCLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxDQUFDLENBQUM7SUFDckUsQ0FBQztJQUVELGtCQUFrQixDQUFDLElBQWUsRUFBRSxJQUErQjtRQUNqRSxPQUFPO1lBQ0wsR0FBRyxFQUFFLENBQUMsSUFBSSxFQUFFLEdBQUcsSUFBSSxJQUFJLEVBQUUsVUFBVSxDQUFDLE9BQU8sQ0FBQyxDQUFDLFVBQVUsQ0FBQyxRQUFRLEVBQUUsVUFBVSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDdkYsS0FBSyxFQUFFO2dCQUNMLElBQUksRUFBRSxLQUFLLElBQUksSUFBSTtnQkFDbkIsSUFBSSxFQUFFLGNBQWMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxPQUFPLENBQUMsQ0FBQyxVQUFVLENBQUMsUUFBUSxFQUFFLFVBQVUsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLGNBQWMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsVUFBVSxDQUFDLFFBQVE7YUFDaEk7U0FDRixDQUFDO0lBQ0osQ0FBQztJQUVELE1BQU0sQ0FBQyxFQUFZLEVBQUUsRUFBWTtRQUMvQixPQUFPLENBQUMsQ0FBQyxFQUFFLElBQUksQ0FBQyxFQUFFLENBQUMsSUFBSSxFQUFFLENBQUMsR0FBRyxLQUFLLEVBQUUsQ0FBQyxHQUFHLENBQUM7SUFDM0MsQ0FBQztJQUVELE9BQU8sQ0FBQyxHQUFhO1FBQ25CLE9BQU8sS0FBSyxDQUFDLEdBQUcsRUFBRSxHQUFHLENBQUMsSUFBSSxLQUFLLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQzdDLENBQUM7dUdBNURVLGlCQUFpQjsyR0FBakIsaUJBQWlCLGNBREosTUFBTTs7MkZBQ25CLGlCQUFpQjtrQkFEN0IsVUFBVTttQkFBQyxFQUFFLFVBQVUsRUFBRSxNQUFNLEVBQUUiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBJbmplY3RhYmxlIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBVbnR5cGVkRm9ybUJ1aWxkZXIsIFVudHlwZWRGb3JtR3JvdXAsIFZhbGlkYXRvcnMgfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XG5pbXBvcnQgeyBQcm9wZXJ0eSB9IGZyb20gJy4uLy4uLy4uL3NoYXJlZC90eXBlcyc7XG5pbXBvcnQgeyBBcHBWYWxpZGF0b3JTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vc2VydmljZXMvdmFsaWRhdG9yL2Jhc2UudmFsaWRhdG9yLmNsYXNzJztcbmltcG9ydCB7IGlzTmlsLCBpc05vdEVtcHR5QXJyYXkgfSBmcm9tICcuLi8uLi8uLi9zaGFyZWQvZnVuY3Rpb25zJztcbmltcG9ydCB7IEZvcm1GaWVsZERlZmluaXRpb24gfSBmcm9tICcuLi8uLi8uLi9zaGFyZWQvZm9ybS9maWVsZC5tb2RlbCc7XG5pbXBvcnQgeyBBcHBGb3JtQXJyYXkgfSBmcm9tICcuLi9hcnJheS9mb3JtLWFycmF5JztcbmltcG9ydCB7IEFwcFByb3BlcnRpZXNVdGlscyB9IGZyb20gJy4vcHJvcGVydGllcy51dGlscyc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgUHJvcGVydHlWYWxpZGF0b3JPcHRpb25zIHtcbiAgZGVmaW5pdGlvbj86IEZvcm1GaWVsZERlZmluaXRpb247XG4gIHZhbHVlTWF4TGVuZ3RoPzogbnVtYmVyO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFByb3BlcnRpZXNWYWxpZGF0b3JPcHRpb25zIHtcbiAgZGVmaW5pdGlvbnM/OiBGb3JtRmllbGREZWZpbml0aW9uW107XG4gIHZhbHVlTWF4TGVuZ3RoPzogbnVtYmVyO1xufVxuXG5ASW5qZWN0YWJsZSh7IHByb3ZpZGVkSW46ICdyb290JyB9KVxuZXhwb3J0IGNsYXNzIFByb3BlcnR5VmFsaWRhdG9yIGV4dGVuZHMgQXBwVmFsaWRhdG9yU2VydmljZTxQcm9wZXJ0eT4ge1xuICBjb25zdHJ1Y3Rvcihwcm90ZWN0ZWQgZm9ybUJ1aWxkZXI6IFVudHlwZWRGb3JtQnVpbGRlcikge1xuICAgIHN1cGVyKGZvcm1CdWlsZGVyLCBudWxsKTtcbiAgfVxuXG4gIGdldEZvcm1BcnJheShkYXRhPzogYW55LCBvcHRzPzogUHJvcGVydGllc1ZhbGlkYXRvck9wdGlvbnMpIHtcbiAgICBjb25zdCBmcm9tQXJyYXkgPSBuZXcgQXBwRm9ybUFycmF5PFByb3BlcnR5LCBVbnR5cGVkRm9ybUdyb3VwPihcbiAgICAgICh2YWx1ZSkgPT4gdGhpcy5nZXRGb3JtR3JvdXAodmFsdWUsIHsgdmFsdWVNYXhMZW5ndGg6IDIwMDAgfSksXG4gICAgICAodjEsIHYyKSA9PiB0aGlzLmVxdWFscyh2MSwgdjIpLFxuICAgICAgKHZhbHVlKSA9PiB0aGlzLmlzRW1wdHkodmFsdWUpLFxuICAgICAge1xuICAgICAgICBhbGxvd1JldXNlQ29udHJvbHM6IGZhbHNlLFxuICAgICAgICBhbGxvd0VtcHR5QXJyYXk6IHRydWUsXG4gICAgICB9XG4gICAgKTtcblxuICAgIC8vIFNldCBkYXRhLCBpZiBhbnlcbiAgICBpZiAoZGF0YSkge1xuICAgICAgY29uc3QgZGF0YUFycmF5T3JQcm9taXNlID0gQXBwUHJvcGVydGllc1V0aWxzLmFycmF5RnJvbU9iamVjdChkYXRhLCBvcHRzPy5kZWZpbml0aW9ucyk7XG4gICAgICBpZiAoQXJyYXkuaXNBcnJheShkYXRhQXJyYXlPclByb21pc2UpKSB7XG4gICAgICAgIGlmIChpc05vdEVtcHR5QXJyYXkoZGF0YUFycmF5T3JQcm9taXNlKSkgZnJvbUFycmF5LnBhdGNoVmFsdWUoZGF0YUFycmF5T3JQcm9taXNlKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIElmIHByb21pc2U6IHdhaXQgYW5kIHNldCBhZnRlclxuICAgICAgICBkYXRhQXJyYXlPclByb21pc2VcbiAgICAgICAgICAuY2F0Y2goKGVycikgPT4ge1xuICAgICAgICAgICAgY29uc29sZS5lcnJvcignW3Byb3BlcnR5LXZhbGlkYXRvcl0gRXJyb3IgZHVyaW5nIGNvbnZlcnNpb24gZnJvbSBtYXAgdG8gYXJyYXkgY29udmVyc2lvbjogJyArIChlcnI/Lm1lc3NhZ2UgfHwgZXJyKSwgZGF0YSwgZXJyKTtcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICAgIH0pXG4gICAgICAgICAgLnRoZW4oKHZhbHVlcykgPT4ge1xuICAgICAgICAgICAgaWYgKGlzTm90RW1wdHlBcnJheSh2YWx1ZXMpKSBmcm9tQXJyYXkucGF0Y2hWYWx1ZSh2YWx1ZXMpO1xuICAgICAgICAgICAgZnJvbUFycmF5LnVwZGF0ZVZhbHVlQW5kVmFsaWRpdHkoKTtcbiAgICAgICAgICB9KTtcblxuICAgICAgICAvLyBXYWl0IHZhbHVlIHRvIGJlIHNldFxuICAgICAgICBmcm9tQXJyYXkubWFya0FzUGVuZGluZygpO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gZnJvbUFycmF5O1xuICB9XG5cbiAgZ2V0Rm9ybUdyb3VwKGRhdGE/OiBQcm9wZXJ0eSwgb3B0cz86IFByb3BlcnR5VmFsaWRhdG9yT3B0aW9ucyk6IFVudHlwZWRGb3JtR3JvdXAge1xuICAgIHJldHVybiB0aGlzLmZvcm1CdWlsZGVyLmdyb3VwKHRoaXMuZ2V0Rm9ybUdyb3VwQ29uZmlnKGRhdGEsIG9wdHMpKTtcbiAgfVxuXG4gIGdldEZvcm1Hcm91cENvbmZpZyhkYXRhPzogUHJvcGVydHksIG9wdHM/OiBQcm9wZXJ0eVZhbGlkYXRvck9wdGlvbnMpOiB7IFtwOiBzdHJpbmddOiBhbnkgfSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIGtleTogW2RhdGE/LmtleSA/PyBudWxsLCBWYWxpZGF0b3JzLmNvbXBvc2UoW1ZhbGlkYXRvcnMucmVxdWlyZWQsIFZhbGlkYXRvcnMubWF4KDUwKV0pXSxcbiAgICAgIHZhbHVlOiBbXG4gICAgICAgIGRhdGE/LnZhbHVlID8/IG51bGwsXG4gICAgICAgIG9wdHM/LnZhbHVlTWF4TGVuZ3RoID4gMCA/IFZhbGlkYXRvcnMuY29tcG9zZShbVmFsaWRhdG9ycy5yZXF1aXJlZCwgVmFsaWRhdG9ycy5tYXgob3B0cy52YWx1ZU1heExlbmd0aCldKSA6IFZhbGlkYXRvcnMucmVxdWlyZWQsXG4gICAgICBdLFxuICAgIH07XG4gIH1cblxuICBlcXVhbHModjE6IFByb3BlcnR5LCB2MjogUHJvcGVydHkpOiBib29sZWFuIHtcbiAgICByZXR1cm4gKCF2MSAmJiAhdjIpIHx8IHYxLmtleSA9PT0gdjIua2V5O1xuICB9XG5cbiAgaXNFbXB0eShvYmo6IFByb3BlcnR5KTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIGlzTmlsKG9iaj8ua2V5KSB8fCBpc05pbChvYmoudmFsdWUpO1xuICB9XG59XG4iXX0=