@ng-formworks/core 18.5.1 → 19.5.1

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 (59) hide show
  1. package/README.md +2 -1
  2. package/fesm2022/ng-formworks-core.mjs +130 -110
  3. package/fesm2022/ng-formworks-core.mjs.map +1 -1
  4. package/package.json +3 -3
  5. package/esm2022/lib/framework-library/framework-library.service.mjs +0 -172
  6. package/esm2022/lib/framework-library/framework.mjs +0 -15
  7. package/esm2022/lib/framework-library/no-framework.component.mjs +0 -17
  8. package/esm2022/lib/framework-library/no-framework.module.mjs +0 -27
  9. package/esm2022/lib/framework-library/no.framework.mjs +0 -19
  10. package/esm2022/lib/json-schema-form.component.mjs +0 -759
  11. package/esm2022/lib/json-schema-form.module.mjs +0 -26
  12. package/esm2022/lib/json-schema-form.service.mjs +0 -695
  13. package/esm2022/lib/locale/de-validation-messages.mjs +0 -60
  14. package/esm2022/lib/locale/en-validation-messages.mjs +0 -60
  15. package/esm2022/lib/locale/es-validation-messages.mjs +0 -57
  16. package/esm2022/lib/locale/fr-validation-messages.mjs +0 -60
  17. package/esm2022/lib/locale/index.mjs +0 -8
  18. package/esm2022/lib/locale/it-validation-messages.mjs +0 -60
  19. package/esm2022/lib/locale/pt-validation-messages.mjs +0 -60
  20. package/esm2022/lib/locale/zh-validation-messages.mjs +0 -60
  21. package/esm2022/lib/shared/convert-schema-to-draft6.function.mjs +0 -300
  22. package/esm2022/lib/shared/form-group.functions.mjs +0 -444
  23. package/esm2022/lib/shared/format-regex.constants.mjs +0 -54
  24. package/esm2022/lib/shared/index.mjs +0 -12
  25. package/esm2022/lib/shared/json-schema.functions.mjs +0 -784
  26. package/esm2022/lib/shared/json.validators.mjs +0 -884
  27. package/esm2022/lib/shared/jsonpointer.functions.mjs +0 -1026
  28. package/esm2022/lib/shared/layout.functions.mjs +0 -1158
  29. package/esm2022/lib/shared/merge-schemas.function.mjs +0 -345
  30. package/esm2022/lib/shared/utility.functions.mjs +0 -380
  31. package/esm2022/lib/shared/validator.functions.mjs +0 -584
  32. package/esm2022/lib/widget-library/add-reference.component.mjs +0 -58
  33. package/esm2022/lib/widget-library/button.component.mjs +0 -69
  34. package/esm2022/lib/widget-library/checkbox.component.mjs +0 -102
  35. package/esm2022/lib/widget-library/checkboxes.component.mjs +0 -145
  36. package/esm2022/lib/widget-library/file.component.mjs +0 -32
  37. package/esm2022/lib/widget-library/hidden.component.mjs +0 -51
  38. package/esm2022/lib/widget-library/index.mjs +0 -55
  39. package/esm2022/lib/widget-library/input.component.mjs +0 -116
  40. package/esm2022/lib/widget-library/message.component.mjs +0 -35
  41. package/esm2022/lib/widget-library/none.component.mjs +0 -20
  42. package/esm2022/lib/widget-library/number.component.mjs +0 -120
  43. package/esm2022/lib/widget-library/one-of.component.mjs +0 -32
  44. package/esm2022/lib/widget-library/orderable.directive.mjs +0 -120
  45. package/esm2022/lib/widget-library/radios.component.mjs +0 -151
  46. package/esm2022/lib/widget-library/root.component.mjs +0 -73
  47. package/esm2022/lib/widget-library/section.component.mjs +0 -196
  48. package/esm2022/lib/widget-library/select-framework.component.mjs +0 -44
  49. package/esm2022/lib/widget-library/select-widget.component.mjs +0 -42
  50. package/esm2022/lib/widget-library/select.component.mjs +0 -147
  51. package/esm2022/lib/widget-library/submit.component.mjs +0 -79
  52. package/esm2022/lib/widget-library/tab.component.mjs +0 -38
  53. package/esm2022/lib/widget-library/tabs.component.mjs +0 -106
  54. package/esm2022/lib/widget-library/template.component.mjs +0 -43
  55. package/esm2022/lib/widget-library/textarea.component.mjs +0 -101
  56. package/esm2022/lib/widget-library/widget-library.module.mjs +0 -42
  57. package/esm2022/lib/widget-library/widget-library.service.mjs +0 -226
  58. package/esm2022/ng-formworks-core.mjs +0 -5
  59. package/esm2022/public_api.mjs +0 -13
@@ -1,380 +0,0 @@
1
- import { hasValue, inArray, isArray, isDefined, isEmpty, isMap, isObject, isSet, isString } from './validator.functions';
2
- /**
3
- * Utility function library:
4
- *
5
- * addClasses, copy, forEach, forEachCopy, hasOwn, mergeFilteredObject,
6
- * uniqueItems, commonItems, fixTitle, toTitleCase
7
- */
8
- /**
9
- * 'addClasses' function
10
- *
11
- * Merges two space-delimited lists of CSS classes and removes duplicates.
12
- *
13
- * // {string | string[] | Set<string>} oldClasses
14
- * // {string | string[] | Set<string>} newClasses
15
- * // {string | string[] | Set<string>} - Combined classes
16
- */
17
- export function addClasses(oldClasses, newClasses) {
18
- const badType = i => !isSet(i) && !isArray(i) && !isString(i);
19
- if (badType(newClasses)) {
20
- return oldClasses;
21
- }
22
- if (badType(oldClasses)) {
23
- oldClasses = '';
24
- }
25
- const toSet = i => isSet(i) ? i : isArray(i) ? new Set(i) : new Set(i.split(' '));
26
- const combinedSet = toSet(oldClasses);
27
- const newSet = toSet(newClasses);
28
- newSet.forEach(c => combinedSet.add(c));
29
- if (isSet(oldClasses)) {
30
- return combinedSet;
31
- }
32
- if (isArray(oldClasses)) {
33
- return Array.from(combinedSet);
34
- }
35
- return Array.from(combinedSet).join(' ');
36
- }
37
- /**
38
- * 'copy' function
39
- *
40
- * Makes a shallow copy of a JavaScript object, array, Map, or Set.
41
- * If passed a JavaScript primitive value (string, number, boolean, or null),
42
- * it returns the value.
43
- *
44
- * // {Object|Array|string|number|boolean|null} object - The object to copy
45
- * // {boolean = false} errors - Show errors?
46
- * // {Object|Array|string|number|boolean|null} - The copied object
47
- */
48
- export function copy(object, errors = false) {
49
- if (typeof object !== 'object' || object === null) {
50
- return object;
51
- }
52
- if (isMap(object)) {
53
- return new Map(object);
54
- }
55
- if (isSet(object)) {
56
- return new Set(object);
57
- }
58
- if (isArray(object)) {
59
- return [...object];
60
- }
61
- if (isObject(object)) {
62
- return { ...object };
63
- }
64
- if (errors) {
65
- console.error('copy error: Object to copy must be a JavaScript object or value.');
66
- }
67
- return object;
68
- }
69
- /**
70
- * 'forEach' function
71
- *
72
- * Iterates over all items in the first level of an object or array
73
- * and calls an iterator funciton on each item.
74
- *
75
- * The iterator function is called with four values:
76
- * 1. The current item's value
77
- * 2. The current item's key
78
- * 3. The parent object, which contains the current item
79
- * 4. The root object
80
- *
81
- * Setting the optional third parameter to 'top-down' or 'bottom-up' will cause
82
- * it to also recursively iterate over items in sub-objects or sub-arrays in the
83
- * specified direction.
84
- *
85
- * // {Object|Array} object - The object or array to iterate over
86
- * // {function} fn - the iterator funciton to call on each item
87
- * // {boolean = false} errors - Show errors?
88
- * // {void}
89
- */
90
- export function forEach(object, fn, recurse = false, rootObject = object, errors = false) {
91
- if (isEmpty(object)) {
92
- return;
93
- }
94
- if ((isObject(object) || isArray(object)) && typeof fn === 'function') {
95
- for (const key of Object.keys(object)) {
96
- const value = object[key];
97
- if (recurse === 'bottom-up' && (isObject(value) || isArray(value))) {
98
- forEach(value, fn, recurse, rootObject);
99
- }
100
- fn(value, key, object, rootObject);
101
- if (recurse === 'top-down' && (isObject(value) || isArray(value))) {
102
- forEach(value, fn, recurse, rootObject);
103
- }
104
- }
105
- }
106
- if (errors) {
107
- if (typeof fn !== 'function') {
108
- console.error('forEach error: Iterator must be a function.');
109
- console.error('function', fn);
110
- }
111
- if (!isObject(object) && !isArray(object)) {
112
- console.error('forEach error: Input object must be an object or array.');
113
- console.error('object', object);
114
- }
115
- }
116
- }
117
- /**
118
- * 'forEachCopy' function
119
- *
120
- * Iterates over all items in the first level of an object or array
121
- * and calls an iterator function on each item. Returns a new object or array
122
- * with the same keys or indexes as the original, and values set to the results
123
- * of the iterator function.
124
- *
125
- * Does NOT recursively iterate over items in sub-objects or sub-arrays.
126
- *
127
- * // {Object | Array} object - The object or array to iterate over
128
- * // {function} fn - The iterator funciton to call on each item
129
- * // {boolean = false} errors - Show errors?
130
- * // {Object | Array} - The resulting object or array
131
- */
132
- export function forEachCopy(object, fn, errors = false) {
133
- if (!hasValue(object)) {
134
- return;
135
- }
136
- if ((isObject(object) || isArray(object)) && typeof object !== 'function') {
137
- const newObject = isArray(object) ? [] : {};
138
- for (const key of Object.keys(object)) {
139
- newObject[key] = fn(object[key], key, object);
140
- }
141
- return newObject;
142
- }
143
- if (errors) {
144
- if (typeof fn !== 'function') {
145
- console.error('forEachCopy error: Iterator must be a function.');
146
- console.error('function', fn);
147
- }
148
- if (!isObject(object) && !isArray(object)) {
149
- console.error('forEachCopy error: Input object must be an object or array.');
150
- console.error('object', object);
151
- }
152
- }
153
- }
154
- /**
155
- * 'hasOwn' utility function
156
- *
157
- * Checks whether an object or array has a particular property.
158
- *
159
- * // {any} object - the object to check
160
- * // {string} property - the property to look for
161
- * // {boolean} - true if object has property, false if not
162
- */
163
- export function hasOwn(object, property) {
164
- if (!object || !['number', 'string', 'symbol'].includes(typeof property) ||
165
- (!isObject(object) && !isArray(object) && !isMap(object) && !isSet(object))) {
166
- return false;
167
- }
168
- if (isMap(object) || isSet(object)) {
169
- return object.has(property);
170
- }
171
- if (typeof property === 'number') {
172
- if (isArray(object)) {
173
- return object[property];
174
- }
175
- property = property + '';
176
- }
177
- return object.hasOwnProperty(property);
178
- }
179
- /**
180
- * Types of possible expressions which the app is able to evaluate.
181
- */
182
- export var ExpressionType;
183
- (function (ExpressionType) {
184
- ExpressionType[ExpressionType["EQUALS"] = 0] = "EQUALS";
185
- ExpressionType[ExpressionType["NOT_EQUALS"] = 1] = "NOT_EQUALS";
186
- ExpressionType[ExpressionType["NOT_AN_EXPRESSION"] = 2] = "NOT_AN_EXPRESSION";
187
- })(ExpressionType || (ExpressionType = {}));
188
- /**
189
- * Detects the type of expression from the given candidate. `==` for equals,
190
- * `!=` for not equals. If none of these are contained in the candidate, the candidate
191
- * is not considered to be an expression at all and thus `NOT_AN_EXPRESSION` is returned.
192
- * // {expressionCandidate} expressionCandidate - potential expression
193
- */
194
- export function getExpressionType(expressionCandidate) {
195
- if (expressionCandidate.indexOf('==') !== -1) {
196
- return ExpressionType.EQUALS;
197
- }
198
- if (expressionCandidate.toString().indexOf('!=') !== -1) {
199
- return ExpressionType.NOT_EQUALS;
200
- }
201
- return ExpressionType.NOT_AN_EXPRESSION;
202
- }
203
- export function isEqual(expressionType) {
204
- return expressionType === ExpressionType.EQUALS;
205
- }
206
- export function isNotEqual(expressionType) {
207
- return expressionType === ExpressionType.NOT_EQUALS;
208
- }
209
- export function isNotExpression(expressionType) {
210
- return expressionType === ExpressionType.NOT_AN_EXPRESSION;
211
- }
212
- /**
213
- * Splits the expression key by the expressionType on a pair of values
214
- * before and after the equals or nor equals sign.
215
- * // {expressionType} enum of an expression type
216
- * // {key} the given key from a for loop iver all conditions
217
- */
218
- export function getKeyAndValueByExpressionType(expressionType, key) {
219
- if (isEqual(expressionType)) {
220
- return key.split('==', 2);
221
- }
222
- if (isNotEqual(expressionType)) {
223
- return key.split('!=', 2);
224
- }
225
- return null;
226
- }
227
- export function cleanValueOfQuotes(keyAndValue) {
228
- if (keyAndValue.charAt(0) === '\'' && keyAndValue.charAt(keyAndValue.length - 1) === '\'') {
229
- return keyAndValue.replace('\'', '').replace('\'', '');
230
- }
231
- return keyAndValue;
232
- }
233
- /**
234
- * 'mergeFilteredObject' utility function
235
- *
236
- * Shallowly merges two objects, setting key and values from source object
237
- * in target object, excluding specified keys.
238
- *
239
- * Optionally, it can also use functions to transform the key names and/or
240
- * the values of the merging object.
241
- *
242
- * // {PlainObject} targetObject - Target object to add keys and values to
243
- * // {PlainObject} sourceObject - Source object to copy keys and values from
244
- * // {string[]} excludeKeys - Array of keys to exclude
245
- * // {(string: string) => string = (k) => k} keyFn - Function to apply to keys
246
- * // {(any: any) => any = (v) => v} valueFn - Function to apply to values
247
- * // {PlainObject} - Returns targetObject
248
- */
249
- export function mergeFilteredObject(targetObject, sourceObject, excludeKeys = [], keyFn = (key) => key, valFn = (val) => val) {
250
- if (!isObject(sourceObject)) {
251
- return targetObject;
252
- }
253
- if (!isObject(targetObject)) {
254
- targetObject = {};
255
- }
256
- for (const key of Object.keys(sourceObject)) {
257
- if (!inArray(key, excludeKeys) && isDefined(sourceObject[key])) {
258
- targetObject[keyFn(key)] = valFn(sourceObject[key]);
259
- }
260
- }
261
- return targetObject;
262
- }
263
- /**
264
- * 'uniqueItems' function
265
- *
266
- * Accepts any number of string value inputs,
267
- * and returns an array of all input vaues, excluding duplicates.
268
- *
269
- * // {...string} ...items -
270
- * // {string[]} -
271
- */
272
- export function uniqueItems(...items) {
273
- const returnItems = [];
274
- for (const item of items) {
275
- if (!returnItems.includes(item)) {
276
- returnItems.push(item);
277
- }
278
- }
279
- return returnItems;
280
- }
281
- /**
282
- * 'commonItems' function
283
- *
284
- * Accepts any number of strings or arrays of string values,
285
- * and returns a single array containing only values present in all inputs.
286
- *
287
- * // {...string|string[]} ...arrays -
288
- * // {string[]} -
289
- */
290
- export function commonItems(...arrays) {
291
- let returnItems = null;
292
- for (let array of arrays) {
293
- if (isString(array)) {
294
- array = [array];
295
- }
296
- returnItems = returnItems === null ? [...array] :
297
- returnItems.filter(item => array.includes(item));
298
- if (!returnItems.length) {
299
- return [];
300
- }
301
- }
302
- return returnItems;
303
- }
304
- /**
305
- * 'fixTitle' function
306
- *
307
- *
308
- * // {string} input -
309
- * // {string} -
310
- */
311
- export function fixTitle(name) {
312
- return name && toTitleCase(name.replace(/([a-z])([A-Z])/g, '$1 $2').replace(/_/g, ' '));
313
- }
314
- /**
315
- * 'toTitleCase' function
316
- *
317
- * Intelligently converts an input string to Title Case.
318
- *
319
- * Accepts an optional second parameter with a list of additional
320
- * words and abbreviations to force into a particular case.
321
- *
322
- * This function is built on prior work by John Gruber and David Gouch:
323
- * http://daringfireball.net/2008/08/title_case_update
324
- * https://github.com/gouch/to-title-case
325
- *
326
- * // {string} input -
327
- * // {string|string[]} forceWords? -
328
- * // {string} -
329
- */
330
- export function toTitleCase(input, forceWords) {
331
- if (!isString(input)) {
332
- return input;
333
- }
334
- let forceArray = ['a', 'an', 'and', 'as', 'at', 'but', 'by', 'en',
335
- 'for', 'if', 'in', 'nor', 'of', 'on', 'or', 'per', 'the', 'to', 'v', 'v.',
336
- 'vs', 'vs.', 'via'];
337
- if (isString(forceWords)) {
338
- forceWords = forceWords.split('|');
339
- }
340
- if (isArray(forceWords)) {
341
- forceArray = forceArray.concat(forceWords);
342
- }
343
- const forceArrayLower = forceArray.map(w => w.toLowerCase());
344
- const noInitialCase = input === input.toUpperCase() || input === input.toLowerCase();
345
- let prevLastChar = '';
346
- input = input.trim();
347
- return input.replace(/[A-Za-z0-9\u00C0-\u00FF]+[^\s-]*/g, (word, idx) => {
348
- if (!noInitialCase && word.slice(1).search(/[A-Z]|\../) !== -1) {
349
- return word;
350
- }
351
- else {
352
- let newWord;
353
- const forceWord = forceArray[forceArrayLower.indexOf(word.toLowerCase())];
354
- if (!forceWord) {
355
- if (noInitialCase) {
356
- if (word.slice(1).search(/\../) !== -1) {
357
- newWord = word.toLowerCase();
358
- }
359
- else {
360
- newWord = word[0].toUpperCase() + word.slice(1).toLowerCase();
361
- }
362
- }
363
- else {
364
- newWord = word[0].toUpperCase() + word.slice(1);
365
- }
366
- }
367
- else if (forceWord === forceWord.toLowerCase() && (idx === 0 || idx + word.length === input.length ||
368
- prevLastChar === ':' || input[idx - 1].search(/[^\s-]/) !== -1 ||
369
- (input[idx - 1] !== '-' && input[idx + word.length] === '-'))) {
370
- newWord = forceWord[0].toUpperCase() + forceWord.slice(1);
371
- }
372
- else {
373
- newWord = forceWord;
374
- }
375
- prevLastChar = word.slice(-1);
376
- return newWord;
377
- }
378
- });
379
- }
380
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXRpbGl0eS5mdW5jdGlvbnMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9uZy1mb3Jtd29ya3MtY29yZS9zcmMvbGliL3NoYXJlZC91dGlsaXR5LmZ1bmN0aW9ucy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUMsUUFBUSxFQUFFLE9BQU8sRUFBRSxPQUFPLEVBQUUsU0FBUyxFQUFFLE9BQU8sRUFBRSxLQUFLLEVBQUUsUUFBUSxFQUFFLEtBQUssRUFBRSxRQUFRLEVBQWMsTUFBTSx1QkFBdUIsQ0FBQztBQUVwSTs7Ozs7RUFLRTtBQUVGOzs7Ozs7OztHQVFHO0FBQ0gsTUFBTSxVQUFVLFVBQVUsQ0FDeEIsVUFBMkMsRUFDM0MsVUFBMkM7SUFFM0MsTUFBTSxPQUFPLEdBQUcsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUM5RCxJQUFJLE9BQU8sQ0FBQyxVQUFVLENBQUMsRUFBRSxDQUFDO1FBQUMsT0FBTyxVQUFVLENBQUM7SUFBQyxDQUFDO0lBQy9DLElBQUksT0FBTyxDQUFDLFVBQVUsQ0FBQyxFQUFFLENBQUM7UUFBQyxVQUFVLEdBQUcsRUFBRSxDQUFDO0lBQUMsQ0FBQztJQUM3QyxNQUFNLEtBQUssR0FBRyxDQUFDLENBQUMsRUFBRSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLEdBQUcsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7SUFDbEYsTUFBTSxXQUFXLEdBQWEsS0FBSyxDQUFDLFVBQVUsQ0FBQyxDQUFDO0lBQ2hELE1BQU0sTUFBTSxHQUFhLEtBQUssQ0FBQyxVQUFVLENBQUMsQ0FBQztJQUMzQyxNQUFNLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsV0FBVyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ3hDLElBQUksS0FBSyxDQUFDLFVBQVUsQ0FBQyxFQUFFLENBQUM7UUFBQyxPQUFPLFdBQVcsQ0FBQztJQUFDLENBQUM7SUFDOUMsSUFBSSxPQUFPLENBQUMsVUFBVSxDQUFDLEVBQUUsQ0FBQztRQUFDLE9BQU8sS0FBSyxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQztJQUFDLENBQUM7SUFDNUQsT0FBTyxLQUFLLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUMzQyxDQUFDO0FBRUQ7Ozs7Ozs7Ozs7R0FVRztBQUNILE1BQU0sVUFBVSxJQUFJLENBQUMsTUFBVyxFQUFFLE1BQU0sR0FBRyxLQUFLO0lBQzlDLElBQUksT0FBTyxNQUFNLEtBQUssUUFBUSxJQUFJLE1BQU0sS0FBSyxJQUFJLEVBQUUsQ0FBQztRQUFDLE9BQU8sTUFBTSxDQUFDO0lBQUMsQ0FBQztJQUNyRSxJQUFJLEtBQUssQ0FBQyxNQUFNLENBQUMsRUFBSyxDQUFDO1FBQUMsT0FBTyxJQUFJLEdBQUcsQ0FBQyxNQUFNLENBQUMsQ0FBQztJQUFDLENBQUM7SUFDakQsSUFBSSxLQUFLLENBQUMsTUFBTSxDQUFDLEVBQUssQ0FBQztRQUFDLE9BQU8sSUFBSSxHQUFHLENBQUMsTUFBTSxDQUFDLENBQUM7SUFBQyxDQUFDO0lBQ2pELElBQUksT0FBTyxDQUFDLE1BQU0sQ0FBQyxFQUFHLENBQUM7UUFBQyxPQUFPLENBQUUsR0FBRyxNQUFNLENBQUUsQ0FBQztJQUFHLENBQUM7SUFDakQsSUFBSSxRQUFRLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQztRQUFDLE9BQU8sRUFBRSxHQUFHLE1BQU0sRUFBRSxDQUFDO0lBQUcsQ0FBQztJQUNqRCxJQUFJLE1BQU0sRUFBRSxDQUFDO1FBQ1gsT0FBTyxDQUFDLEtBQUssQ0FBQyxrRUFBa0UsQ0FBQyxDQUFDO0lBQ3BGLENBQUM7SUFDRCxPQUFPLE1BQU0sQ0FBQztBQUNoQixDQUFDO0FBRUQ7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBb0JHO0FBQ0gsTUFBTSxVQUFVLE9BQU8sQ0FDckIsTUFBVyxFQUFFLEVBQTJELEVBQ3hFLFVBQTRCLEtBQUssRUFBRSxhQUFrQixNQUFNLEVBQUUsTUFBTSxHQUFHLEtBQUs7SUFFM0UsSUFBSSxPQUFPLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQztRQUFDLE9BQU87SUFBQyxDQUFDO0lBQ2hDLElBQUksQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLElBQUksT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQUFDLElBQUksT0FBTyxFQUFFLEtBQUssVUFBVSxFQUFFLENBQUM7UUFDdEUsS0FBSyxNQUFNLEdBQUcsSUFBSSxNQUFNLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUM7WUFDdEMsTUFBTSxLQUFLLEdBQUcsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDO1lBQzFCLElBQUksT0FBTyxLQUFLLFdBQVcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsSUFBSSxPQUFPLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxDQUFDO2dCQUNuRSxPQUFPLENBQUMsS0FBSyxFQUFFLEVBQUUsRUFBRSxPQUFPLEVBQUUsVUFBVSxDQUFDLENBQUM7WUFDMUMsQ0FBQztZQUNELEVBQUUsQ0FBQyxLQUFLLEVBQUUsR0FBRyxFQUFFLE1BQU0sRUFBRSxVQUFVLENBQUMsQ0FBQztZQUNuQyxJQUFJLE9BQU8sS0FBSyxVQUFVLElBQUksQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLElBQUksT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsQ0FBQztnQkFDbEUsT0FBTyxDQUFDLEtBQUssRUFBRSxFQUFFLEVBQUUsT0FBTyxFQUFFLFVBQVUsQ0FBQyxDQUFDO1lBQzFDLENBQUM7UUFDSCxDQUFDO0lBQ0gsQ0FBQztJQUNELElBQUksTUFBTSxFQUFFLENBQUM7UUFDWCxJQUFJLE9BQU8sRUFBRSxLQUFLLFVBQVUsRUFBRSxDQUFDO1lBQzdCLE9BQU8sQ0FBQyxLQUFLLENBQUMsNkNBQTZDLENBQUMsQ0FBQztZQUM3RCxPQUFPLENBQUMsS0FBSyxDQUFDLFVBQVUsRUFBRSxFQUFFLENBQUMsQ0FBQztRQUNoQyxDQUFDO1FBQ0QsSUFBSSxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDO1lBQzFDLE9BQU8sQ0FBQyxLQUFLLENBQUMseURBQXlELENBQUMsQ0FBQztZQUN6RSxPQUFPLENBQUMsS0FBSyxDQUFDLFFBQVEsRUFBRSxNQUFNLENBQUMsQ0FBQztRQUNsQyxDQUFDO0lBQ0gsQ0FBQztBQUNILENBQUM7QUFFRDs7Ozs7Ozs7Ozs7Ozs7R0FjRztBQUNILE1BQU0sVUFBVSxXQUFXLENBQ3pCLE1BQVcsRUFBRSxFQUE2RCxFQUMxRSxNQUFNLEdBQUcsS0FBSztJQUVkLElBQUksQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQztRQUFDLE9BQU87SUFBQyxDQUFDO0lBQ2xDLElBQUksQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLElBQUksT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQUFDLElBQUksT0FBTyxNQUFNLEtBQUssVUFBVSxFQUFFLENBQUM7UUFDMUUsTUFBTSxTQUFTLEdBQVEsT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQztRQUNqRCxLQUFLLE1BQU0sR0FBRyxJQUFJLE1BQU0sQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQztZQUN0QyxTQUFTLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBRSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsRUFBRSxHQUFHLEVBQUUsTUFBTSxDQUFDLENBQUM7UUFDaEQsQ0FBQztRQUNELE9BQU8sU0FBUyxDQUFDO0lBQ25CLENBQUM7SUFDRCxJQUFJLE1BQU0sRUFBRSxDQUFDO1FBQ1gsSUFBSSxPQUFPLEVBQUUsS0FBSyxVQUFVLEVBQUUsQ0FBQztZQUM3QixPQUFPLENBQUMsS0FBSyxDQUFDLGlEQUFpRCxDQUFDLENBQUM7WUFDakUsT0FBTyxDQUFDLEtBQUssQ0FBQyxVQUFVLEVBQUUsRUFBRSxDQUFDLENBQUM7UUFDaEMsQ0FBQztRQUNELElBQUksQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQztZQUMxQyxPQUFPLENBQUMsS0FBSyxDQUFDLDZEQUE2RCxDQUFDLENBQUM7WUFDN0UsT0FBTyxDQUFDLEtBQUssQ0FBQyxRQUFRLEVBQUUsTUFBTSxDQUFDLENBQUM7UUFDbEMsQ0FBQztJQUNILENBQUM7QUFDSCxDQUFDO0FBRUQ7Ozs7Ozs7O0dBUUc7QUFDSCxNQUFNLFVBQVUsTUFBTSxDQUFDLE1BQVcsRUFBRSxRQUFnQjtJQUNsRCxJQUFJLENBQUMsTUFBTSxJQUFJLENBQUMsQ0FBQyxRQUFRLEVBQUUsUUFBUSxFQUFFLFFBQVEsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxPQUFPLFFBQVEsQ0FBQztRQUN0RSxDQUFDLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxDQUFDLEVBQzNFLENBQUM7UUFBQyxPQUFPLEtBQUssQ0FBQztJQUFDLENBQUM7SUFDbkIsSUFBSSxLQUFLLENBQUMsTUFBTSxDQUFDLElBQUksS0FBSyxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUM7UUFBQyxPQUFPLE1BQU0sQ0FBQyxHQUFHLENBQUMsUUFBUSxDQUFDLENBQUM7SUFBQyxDQUFDO0lBQ3BFLElBQUksT0FBTyxRQUFRLEtBQUssUUFBUSxFQUFFLENBQUM7UUFDakMsSUFBSSxPQUFPLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQztZQUFDLE9BQU8sTUFBTSxDQUFTLFFBQVEsQ0FBQyxDQUFDO1FBQUMsQ0FBQztRQUN6RCxRQUFRLEdBQUcsUUFBUSxHQUFHLEVBQUUsQ0FBQztJQUMzQixDQUFDO0lBQ0QsT0FBTyxNQUFNLENBQUMsY0FBYyxDQUFDLFFBQVEsQ0FBQyxDQUFDO0FBQ3pDLENBQUM7QUFFRDs7R0FFRztBQUNILE1BQU0sQ0FBTixJQUFZLGNBSVg7QUFKRCxXQUFZLGNBQWM7SUFDeEIsdURBQU0sQ0FBQTtJQUNOLCtEQUFVLENBQUE7SUFDViw2RUFBaUIsQ0FBQTtBQUNuQixDQUFDLEVBSlcsY0FBYyxLQUFkLGNBQWMsUUFJekI7QUFFRDs7Ozs7R0FLRztBQUNILE1BQU0sVUFBVSxpQkFBaUIsQ0FBQyxtQkFBMkI7SUFDM0QsSUFBSSxtQkFBbUIsQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsQ0FBQztRQUM3QyxPQUFPLGNBQWMsQ0FBQyxNQUFNLENBQUM7SUFDL0IsQ0FBQztJQUVELElBQUksbUJBQW1CLENBQUMsUUFBUSxFQUFFLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLENBQUM7UUFDeEQsT0FBTyxjQUFjLENBQUMsVUFBVSxDQUFDO0lBQ25DLENBQUM7SUFFRCxPQUFPLGNBQWMsQ0FBQyxpQkFBaUIsQ0FBQztBQUMxQyxDQUFDO0FBRUQsTUFBTSxVQUFVLE9BQU8sQ0FBQyxjQUFjO0lBQ3BDLE9BQU8sY0FBZ0MsS0FBSyxjQUFjLENBQUMsTUFBTSxDQUFDO0FBQ3BFLENBQUM7QUFFRCxNQUFNLFVBQVUsVUFBVSxDQUFDLGNBQWM7SUFDdkMsT0FBTyxjQUFnQyxLQUFLLGNBQWMsQ0FBQyxVQUFVLENBQUM7QUFDeEUsQ0FBQztBQUVELE1BQU0sVUFBVSxlQUFlLENBQUMsY0FBYztJQUM1QyxPQUFPLGNBQWdDLEtBQUssY0FBYyxDQUFDLGlCQUFpQixDQUFDO0FBQy9FLENBQUM7QUFFRDs7Ozs7R0FLRztBQUNILE1BQU0sVUFBVSw4QkFBOEIsQ0FBQyxjQUE4QixFQUFFLEdBQVc7SUFDeEYsSUFBSSxPQUFPLENBQUMsY0FBYyxDQUFDLEVBQUUsQ0FBQztRQUM1QixPQUFPLEdBQUcsQ0FBQyxLQUFLLENBQUMsSUFBSSxFQUFFLENBQUMsQ0FBQyxDQUFDO0lBQzVCLENBQUM7SUFFRCxJQUFJLFVBQVUsQ0FBQyxjQUFjLENBQUMsRUFBRSxDQUFDO1FBQy9CLE9BQU8sR0FBRyxDQUFDLEtBQUssQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFDNUIsQ0FBQztJQUVELE9BQU8sSUFBSSxDQUFDO0FBQ2QsQ0FBQztBQUVELE1BQU0sVUFBVSxrQkFBa0IsQ0FBQyxXQUFXO0lBQzVDLElBQUksV0FBVyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsS0FBSyxJQUFJLElBQUksV0FBVyxDQUFDLE1BQU0sQ0FBQyxXQUFXLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQyxLQUFLLElBQUksRUFBRSxDQUFDO1FBQzFGLE9BQU8sV0FBVyxDQUFDLE9BQU8sQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLENBQUMsT0FBTyxDQUFDLElBQUksRUFBRSxFQUFFLENBQUMsQ0FBQztJQUN6RCxDQUFDO0lBQ0QsT0FBTyxXQUFXLENBQUM7QUFDckIsQ0FBQztBQUVEOzs7Ozs7Ozs7Ozs7Ozs7R0FlRztBQUNILE1BQU0sVUFBVSxtQkFBbUIsQ0FDakMsWUFBeUIsRUFDekIsWUFBeUIsRUFDekIsY0FBd0IsRUFBRSxFQUMxQixRQUFRLENBQUMsR0FBVyxFQUFVLEVBQUUsQ0FBQyxHQUFHLEVBQ3BDLFFBQVEsQ0FBQyxHQUFRLEVBQU8sRUFBRSxDQUFDLEdBQUc7SUFFOUIsSUFBSSxDQUFDLFFBQVEsQ0FBQyxZQUFZLENBQUMsRUFBRSxDQUFDO1FBQUMsT0FBTyxZQUFZLENBQUM7SUFBQyxDQUFDO0lBQ3JELElBQUksQ0FBQyxRQUFRLENBQUMsWUFBWSxDQUFDLEVBQUUsQ0FBQztRQUFDLFlBQVksR0FBRyxFQUFFLENBQUM7SUFBQyxDQUFDO0lBQ25ELEtBQUssTUFBTSxHQUFHLElBQUksTUFBTSxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsRUFBRSxDQUFDO1FBQzVDLElBQUksQ0FBQyxPQUFPLENBQUMsR0FBRyxFQUFFLFdBQVcsQ0FBQyxJQUFJLFNBQVMsQ0FBQyxZQUFZLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxDQUFDO1lBQy9ELFlBQVksQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxLQUFLLENBQUMsWUFBWSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7UUFDdEQsQ0FBQztJQUNILENBQUM7SUFDRCxPQUFPLFlBQVksQ0FBQztBQUN0QixDQUFDO0FBRUQ7Ozs7Ozs7O0dBUUc7QUFDSCxNQUFNLFVBQVUsV0FBVyxDQUFDLEdBQUcsS0FBSztJQUNsQyxNQUFNLFdBQVcsR0FBRyxFQUFFLENBQUM7SUFDdkIsS0FBSyxNQUFNLElBQUksSUFBSSxLQUFLLEVBQUUsQ0FBQztRQUN6QixJQUFJLENBQUMsV0FBVyxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDO1lBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUFDLENBQUM7SUFDOUQsQ0FBQztJQUNELE9BQU8sV0FBVyxDQUFDO0FBQ3JCLENBQUM7QUFFRDs7Ozs7Ozs7R0FRRztBQUNILE1BQU0sVUFBVSxXQUFXLENBQUMsR0FBRyxNQUFNO0lBQ25DLElBQUksV0FBVyxHQUFHLElBQUksQ0FBQztJQUN2QixLQUFLLElBQUksS0FBSyxJQUFJLE1BQU0sRUFBRSxDQUFDO1FBQ3pCLElBQUksUUFBUSxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUM7WUFBQyxLQUFLLEdBQUcsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUFDLENBQUM7UUFDekMsV0FBVyxHQUFHLFdBQVcsS0FBSyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUUsR0FBRyxLQUFLLENBQUUsQ0FBQyxDQUFDO1lBQ2pELFdBQVcsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUM7UUFDbkQsSUFBSSxDQUFDLFdBQVcsQ0FBQyxNQUFNLEVBQUUsQ0FBQztZQUFDLE9BQU8sRUFBRSxDQUFDO1FBQUMsQ0FBQztJQUN6QyxDQUFDO0lBQ0QsT0FBTyxXQUFXLENBQUM7QUFDckIsQ0FBQztBQUVEOzs7Ozs7R0FNRztBQUNILE1BQU0sVUFBVSxRQUFRLENBQUMsSUFBWTtJQUNuQyxPQUFPLElBQUksSUFBSSxXQUFXLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxpQkFBaUIsRUFBRSxPQUFPLENBQUMsQ0FBQyxPQUFPLENBQUMsSUFBSSxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUM7QUFDMUYsQ0FBQztBQUVEOzs7Ozs7Ozs7Ozs7Ozs7R0FlRztBQUNILE1BQU0sVUFBVSxXQUFXLENBQUMsS0FBYSxFQUFFLFVBQTRCO0lBQ3JFLElBQUksQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQztRQUFDLE9BQU8sS0FBSyxDQUFDO0lBQUMsQ0FBQztJQUN2QyxJQUFJLFVBQVUsR0FBYSxDQUFDLEdBQUcsRUFBRSxJQUFJLEVBQUUsS0FBSyxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsS0FBSyxFQUFFLElBQUksRUFBRSxJQUFJO1FBQzFFLEtBQUssRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLEtBQUssRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLElBQUksRUFBRSxHQUFHLEVBQUUsSUFBSTtRQUN6RSxJQUFJLEVBQUUsS0FBSyxFQUFFLEtBQUssQ0FBQyxDQUFDO0lBQ3JCLElBQUksUUFBUSxDQUFDLFVBQVUsQ0FBQyxFQUFFLENBQUM7UUFBQyxVQUFVLEdBQVksVUFBVyxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUFDLENBQUM7SUFDM0UsSUFBSSxPQUFPLENBQUMsVUFBVSxDQUFDLEVBQUUsQ0FBQztRQUFDLFVBQVUsR0FBRyxVQUFVLENBQUMsTUFBTSxDQUFDLFVBQVUsQ0FBQyxDQUFDO0lBQUMsQ0FBQztJQUN4RSxNQUFNLGVBQWUsR0FBYSxVQUFVLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLFdBQVcsRUFBRSxDQUFDLENBQUM7SUFDdkUsTUFBTSxhQUFhLEdBQ2pCLEtBQUssS0FBSyxLQUFLLENBQUMsV0FBVyxFQUFFLElBQUksS0FBSyxLQUFLLEtBQUssQ0FBQyxXQUFXLEVBQUUsQ0FBQztJQUNqRSxJQUFJLFlBQVksR0FBRyxFQUFFLENBQUM7SUFDdEIsS0FBSyxHQUFHLEtBQUssQ0FBQyxJQUFJLEVBQUUsQ0FBQztJQUNyQixPQUFPLEtBQUssQ0FBQyxPQUFPLENBQUMsbUNBQW1DLEVBQUUsQ0FBQyxJQUFJLEVBQUUsR0FBRyxFQUFFLEVBQUU7UUFDdEUsSUFBSSxDQUFDLGFBQWEsSUFBSSxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxXQUFXLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxDQUFDO1lBQy9ELE9BQU8sSUFBSSxDQUFDO1FBQ2QsQ0FBQzthQUFNLENBQUM7WUFDTixJQUFJLE9BQWUsQ0FBQztZQUNwQixNQUFNLFNBQVMsR0FDYixVQUFVLENBQUMsZUFBZSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsV0FBVyxFQUFFLENBQUMsQ0FBQyxDQUFDO1lBQzFELElBQUksQ0FBQyxTQUFTLEVBQUUsQ0FBQztnQkFDZixJQUFJLGFBQWEsRUFBRSxDQUFDO29CQUNsQixJQUFJLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLENBQUM7d0JBQ3ZDLE9BQU8sR0FBRyxJQUFJLENBQUMsV0FBVyxFQUFFLENBQUM7b0JBQy9CLENBQUM7eUJBQU0sQ0FBQzt3QkFDTixPQUFPLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLFdBQVcsRUFBRSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsV0FBVyxFQUFFLENBQUM7b0JBQ2hFLENBQUM7Z0JBQ0gsQ0FBQztxQkFBTSxDQUFDO29CQUNOLE9BQU8sR0FBRyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsV0FBVyxFQUFFLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztnQkFDbEQsQ0FBQztZQUNILENBQUM7aUJBQU0sSUFDTCxTQUFTLEtBQUssU0FBUyxDQUFDLFdBQVcsRUFBRSxJQUFJLENBQ3ZDLEdBQUcsS0FBSyxDQUFDLElBQUksR0FBRyxHQUFHLElBQUksQ0FBQyxNQUFNLEtBQUssS0FBSyxDQUFDLE1BQU07Z0JBQy9DLFlBQVksS0FBSyxHQUFHLElBQUksS0FBSyxDQUFDLEdBQUcsR0FBRyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxDQUFDO2dCQUM5RCxDQUFDLEtBQUssQ0FBQyxHQUFHLEdBQUcsQ0FBQyxDQUFDLEtBQUssR0FBRyxJQUFJLEtBQUssQ0FBQyxHQUFHLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxLQUFLLEdBQUcsQ0FBQyxDQUM3RCxFQUNELENBQUM7Z0JBQ0QsT0FBTyxHQUFHLFNBQVMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxXQUFXLEVBQUUsR0FBRyxTQUFTLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQzVELENBQUM7aUJBQU0sQ0FBQztnQkFDTixPQUFPLEdBQUcsU0FBUyxDQUFDO1lBQ3RCLENBQUM7WUFDRCxZQUFZLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQzlCLE9BQU8sT0FBTyxDQUFDO1FBQ2pCLENBQUM7SUFDSCxDQUFDLENBQUMsQ0FBQztBQUNMLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge2hhc1ZhbHVlLCBpbkFycmF5LCBpc0FycmF5LCBpc0RlZmluZWQsIGlzRW1wdHksIGlzTWFwLCBpc09iamVjdCwgaXNTZXQsIGlzU3RyaW5nLCBQbGFpbk9iamVjdH0gZnJvbSAnLi92YWxpZGF0b3IuZnVuY3Rpb25zJztcclxuXHJcbi8qKlxyXG4gKiBVdGlsaXR5IGZ1bmN0aW9uIGxpYnJhcnk6XHJcbiAqXHJcbiAqIGFkZENsYXNzZXMsIGNvcHksIGZvckVhY2gsIGZvckVhY2hDb3B5LCBoYXNPd24sIG1lcmdlRmlsdGVyZWRPYmplY3QsXHJcbiAqIHVuaXF1ZUl0ZW1zLCBjb21tb25JdGVtcywgZml4VGl0bGUsIHRvVGl0bGVDYXNlXHJcbiovXHJcblxyXG4vKipcclxuICogJ2FkZENsYXNzZXMnIGZ1bmN0aW9uXHJcbiAqXHJcbiAqIE1lcmdlcyB0d28gc3BhY2UtZGVsaW1pdGVkIGxpc3RzIG9mIENTUyBjbGFzc2VzIGFuZCByZW1vdmVzIGR1cGxpY2F0ZXMuXHJcbiAqXHJcbiAqIC8vIHtzdHJpbmcgfCBzdHJpbmdbXSB8IFNldDxzdHJpbmc+fSBvbGRDbGFzc2VzXHJcbiAqIC8vIHtzdHJpbmcgfCBzdHJpbmdbXSB8IFNldDxzdHJpbmc+fSBuZXdDbGFzc2VzXHJcbiAqIC8vIHtzdHJpbmcgfCBzdHJpbmdbXSB8IFNldDxzdHJpbmc+fSAtIENvbWJpbmVkIGNsYXNzZXNcclxuICovXHJcbmV4cG9ydCBmdW5jdGlvbiBhZGRDbGFzc2VzKFxyXG4gIG9sZENsYXNzZXM6IHN0cmluZyB8IHN0cmluZ1tdIHwgU2V0PHN0cmluZz4sXHJcbiAgbmV3Q2xhc3Nlczogc3RyaW5nIHwgc3RyaW5nW10gfCBTZXQ8c3RyaW5nPlxyXG4pOiBzdHJpbmcgfCBzdHJpbmdbXSB8IFNldDxzdHJpbmc+IHtcclxuICBjb25zdCBiYWRUeXBlID0gaSA9PiAhaXNTZXQoaSkgJiYgIWlzQXJyYXkoaSkgJiYgIWlzU3RyaW5nKGkpO1xyXG4gIGlmIChiYWRUeXBlKG5ld0NsYXNzZXMpKSB7IHJldHVybiBvbGRDbGFzc2VzOyB9XHJcbiAgaWYgKGJhZFR5cGUob2xkQ2xhc3NlcykpIHsgb2xkQ2xhc3NlcyA9ICcnOyB9XHJcbiAgY29uc3QgdG9TZXQgPSBpID0+IGlzU2V0KGkpID8gaSA6IGlzQXJyYXkoaSkgPyBuZXcgU2V0KGkpIDogbmV3IFNldChpLnNwbGl0KCcgJykpO1xyXG4gIGNvbnN0IGNvbWJpbmVkU2V0OiBTZXQ8YW55PiA9IHRvU2V0KG9sZENsYXNzZXMpO1xyXG4gIGNvbnN0IG5ld1NldDogU2V0PGFueT4gPSB0b1NldChuZXdDbGFzc2VzKTtcclxuICBuZXdTZXQuZm9yRWFjaChjID0+IGNvbWJpbmVkU2V0LmFkZChjKSk7XHJcbiAgaWYgKGlzU2V0KG9sZENsYXNzZXMpKSB7IHJldHVybiBjb21iaW5lZFNldDsgfVxyXG4gIGlmIChpc0FycmF5KG9sZENsYXNzZXMpKSB7IHJldHVybiBBcnJheS5mcm9tKGNvbWJpbmVkU2V0KTsgfVxyXG4gIHJldHVybiBBcnJheS5mcm9tKGNvbWJpbmVkU2V0KS5qb2luKCcgJyk7XHJcbn1cclxuXHJcbi8qKlxyXG4gKiAnY29weScgZnVuY3Rpb25cclxuICpcclxuICogTWFrZXMgYSBzaGFsbG93IGNvcHkgb2YgYSBKYXZhU2NyaXB0IG9iamVjdCwgYXJyYXksIE1hcCwgb3IgU2V0LlxyXG4gKiBJZiBwYXNzZWQgYSBKYXZhU2NyaXB0IHByaW1pdGl2ZSB2YWx1ZSAoc3RyaW5nLCBudW1iZXIsIGJvb2xlYW4sIG9yIG51bGwpLFxyXG4gKiBpdCByZXR1cm5zIHRoZSB2YWx1ZS5cclxuICpcclxuICogLy8ge09iamVjdHxBcnJheXxzdHJpbmd8bnVtYmVyfGJvb2xlYW58bnVsbH0gb2JqZWN0IC0gVGhlIG9iamVjdCB0byBjb3B5XHJcbiAqIC8vIHtib29sZWFuID0gZmFsc2V9IGVycm9ycyAtIFNob3cgZXJyb3JzP1xyXG4gKiAvLyB7T2JqZWN0fEFycmF5fHN0cmluZ3xudW1iZXJ8Ym9vbGVhbnxudWxsfSAtIFRoZSBjb3BpZWQgb2JqZWN0XHJcbiAqL1xyXG5leHBvcnQgZnVuY3Rpb24gY29weShvYmplY3Q6IGFueSwgZXJyb3JzID0gZmFsc2UpOiBhbnkge1xyXG4gIGlmICh0eXBlb2Ygb2JqZWN0ICE9PSAnb2JqZWN0JyB8fCBvYmplY3QgPT09IG51bGwpIHsgcmV0dXJuIG9iamVjdDsgfVxyXG4gIGlmIChpc01hcChvYmplY3QpKSAgICB7IHJldHVybiBuZXcgTWFwKG9iamVjdCk7IH1cclxuICBpZiAoaXNTZXQob2JqZWN0KSkgICAgeyByZXR1cm4gbmV3IFNldChvYmplY3QpOyB9XHJcbiAgaWYgKGlzQXJyYXkob2JqZWN0KSkgIHsgcmV0dXJuIFsgLi4ub2JqZWN0IF07ICAgfVxyXG4gIGlmIChpc09iamVjdChvYmplY3QpKSB7IHJldHVybiB7IC4uLm9iamVjdCB9OyAgIH1cclxuICBpZiAoZXJyb3JzKSB7XHJcbiAgICBjb25zb2xlLmVycm9yKCdjb3B5IGVycm9yOiBPYmplY3QgdG8gY29weSBtdXN0IGJlIGEgSmF2YVNjcmlwdCBvYmplY3Qgb3IgdmFsdWUuJyk7XHJcbiAgfVxyXG4gIHJldHVybiBvYmplY3Q7XHJcbn1cclxuXHJcbi8qKlxyXG4gKiAnZm9yRWFjaCcgZnVuY3Rpb25cclxuICpcclxuICogSXRlcmF0ZXMgb3ZlciBhbGwgaXRlbXMgaW4gdGhlIGZpcnN0IGxldmVsIG9mIGFuIG9iamVjdCBvciBhcnJheVxyXG4gKiBhbmQgY2FsbHMgYW4gaXRlcmF0b3IgZnVuY2l0b24gb24gZWFjaCBpdGVtLlxyXG4gKlxyXG4gKiBUaGUgaXRlcmF0b3IgZnVuY3Rpb24gaXMgY2FsbGVkIHdpdGggZm91ciB2YWx1ZXM6XHJcbiAqIDEuIFRoZSBjdXJyZW50IGl0ZW0ncyB2YWx1ZVxyXG4gKiAyLiBUaGUgY3VycmVudCBpdGVtJ3Mga2V5XHJcbiAqIDMuIFRoZSBwYXJlbnQgb2JqZWN0LCB3aGljaCBjb250YWlucyB0aGUgY3VycmVudCBpdGVtXHJcbiAqIDQuIFRoZSByb290IG9iamVjdFxyXG4gKlxyXG4gKiBTZXR0aW5nIHRoZSBvcHRpb25hbCB0aGlyZCBwYXJhbWV0ZXIgdG8gJ3RvcC1kb3duJyBvciAnYm90dG9tLXVwJyB3aWxsIGNhdXNlXHJcbiAqIGl0IHRvIGFsc28gcmVjdXJzaXZlbHkgaXRlcmF0ZSBvdmVyIGl0ZW1zIGluIHN1Yi1vYmplY3RzIG9yIHN1Yi1hcnJheXMgaW4gdGhlXHJcbiAqIHNwZWNpZmllZCBkaXJlY3Rpb24uXHJcbiAqXHJcbiAqIC8vIHtPYmplY3R8QXJyYXl9IG9iamVjdCAtIFRoZSBvYmplY3Qgb3IgYXJyYXkgdG8gaXRlcmF0ZSBvdmVyXHJcbiAqIC8vIHtmdW5jdGlvbn0gZm4gLSB0aGUgaXRlcmF0b3IgZnVuY2l0b24gdG8gY2FsbCBvbiBlYWNoIGl0ZW1cclxuICogLy8ge2Jvb2xlYW4gPSBmYWxzZX0gZXJyb3JzIC0gU2hvdyBlcnJvcnM/XHJcbiAqIC8vIHt2b2lkfVxyXG4gKi9cclxuZXhwb3J0IGZ1bmN0aW9uIGZvckVhY2goXHJcbiAgb2JqZWN0OiBhbnksIGZuOiAodjogYW55LCBrPzogc3RyaW5nIHwgbnVtYmVyLCBjPzogYW55LCByYz86IGFueSkgPT4gYW55LFxyXG4gIHJlY3Vyc2U6IGJvb2xlYW4gfCBzdHJpbmcgPSBmYWxzZSwgcm9vdE9iamVjdDogYW55ID0gb2JqZWN0LCBlcnJvcnMgPSBmYWxzZVxyXG4pOiB2b2lkIHtcclxuICBpZiAoaXNFbXB0eShvYmplY3QpKSB7IHJldHVybjsgfVxyXG4gIGlmICgoaXNPYmplY3Qob2JqZWN0KSB8fCBpc0FycmF5KG9iamVjdCkpICYmIHR5cGVvZiBmbiA9PT0gJ2Z1bmN0aW9uJykge1xyXG4gICAgZm9yIChjb25zdCBrZXkgb2YgT2JqZWN0LmtleXMob2JqZWN0KSkge1xyXG4gICAgICBjb25zdCB2YWx1ZSA9IG9iamVjdFtrZXldO1xyXG4gICAgICBpZiAocmVjdXJzZSA9PT0gJ2JvdHRvbS11cCcgJiYgKGlzT2JqZWN0KHZhbHVlKSB8fCBpc0FycmF5KHZhbHVlKSkpIHtcclxuICAgICAgICBmb3JFYWNoKHZhbHVlLCBmbiwgcmVjdXJzZSwgcm9vdE9iamVjdCk7XHJcbiAgICAgIH1cclxuICAgICAgZm4odmFsdWUsIGtleSwgb2JqZWN0LCByb290T2JqZWN0KTtcclxuICAgICAgaWYgKHJlY3Vyc2UgPT09ICd0b3AtZG93bicgJiYgKGlzT2JqZWN0KHZhbHVlKSB8fCBpc0FycmF5KHZhbHVlKSkpIHtcclxuICAgICAgICBmb3JFYWNoKHZhbHVlLCBmbiwgcmVjdXJzZSwgcm9vdE9iamVjdCk7XHJcbiAgICAgIH1cclxuICAgIH1cclxuICB9XHJcbiAgaWYgKGVycm9ycykge1xyXG4gICAgaWYgKHR5cGVvZiBmbiAhPT0gJ2Z1bmN0aW9uJykge1xyXG4gICAgICBjb25zb2xlLmVycm9yKCdmb3JFYWNoIGVycm9yOiBJdGVyYXRvciBtdXN0IGJlIGEgZnVuY3Rpb24uJyk7XHJcbiAgICAgIGNvbnNvbGUuZXJyb3IoJ2Z1bmN0aW9uJywgZm4pO1xyXG4gICAgfVxyXG4gICAgaWYgKCFpc09iamVjdChvYmplY3QpICYmICFpc0FycmF5KG9iamVjdCkpIHtcclxuICAgICAgY29uc29sZS5lcnJvcignZm9yRWFjaCBlcnJvcjogSW5wdXQgb2JqZWN0IG11c3QgYmUgYW4gb2JqZWN0IG9yIGFycmF5LicpO1xyXG4gICAgICBjb25zb2xlLmVycm9yKCdvYmplY3QnLCBvYmplY3QpO1xyXG4gICAgfVxyXG4gIH1cclxufVxyXG5cclxuLyoqXHJcbiAqICdmb3JFYWNoQ29weScgZnVuY3Rpb25cclxuICpcclxuICogSXRlcmF0ZXMgb3ZlciBhbGwgaXRlbXMgaW4gdGhlIGZpcnN0IGxldmVsIG9mIGFuIG9iamVjdCBvciBhcnJheVxyXG4gKiBhbmQgY2FsbHMgYW4gaXRlcmF0b3IgZnVuY3Rpb24gb24gZWFjaCBpdGVtLiBSZXR1cm5zIGEgbmV3IG9iamVjdCBvciBhcnJheVxyXG4gKiB3aXRoIHRoZSBzYW1lIGtleXMgb3IgaW5kZXhlcyBhcyB0aGUgb3JpZ2luYWwsIGFuZCB2YWx1ZXMgc2V0IHRvIHRoZSByZXN1bHRzXHJcbiAqIG9mIHRoZSBpdGVyYXRvciBmdW5jdGlvbi5cclxuICpcclxuICogRG9lcyBOT1QgcmVjdXJzaXZlbHkgaXRlcmF0ZSBvdmVyIGl0ZW1zIGluIHN1Yi1vYmplY3RzIG9yIHN1Yi1hcnJheXMuXHJcbiAqXHJcbiAqIC8vIHtPYmplY3QgfCBBcnJheX0gb2JqZWN0IC0gVGhlIG9iamVjdCBvciBhcnJheSB0byBpdGVyYXRlIG92ZXJcclxuICogLy8ge2Z1bmN0aW9ufSBmbiAtIFRoZSBpdGVyYXRvciBmdW5jaXRvbiB0byBjYWxsIG9uIGVhY2ggaXRlbVxyXG4gKiAvLyB7Ym9vbGVhbiA9IGZhbHNlfSBlcnJvcnMgLSBTaG93IGVycm9ycz9cclxuICogLy8ge09iamVjdCB8IEFycmF5fSAtIFRoZSByZXN1bHRpbmcgb2JqZWN0IG9yIGFycmF5XHJcbiAqL1xyXG5leHBvcnQgZnVuY3Rpb24gZm9yRWFjaENvcHkoXHJcbiAgb2JqZWN0OiBhbnksIGZuOiAodjogYW55LCBrPzogc3RyaW5nIHwgbnVtYmVyLCBvPzogYW55LCBwPzogc3RyaW5nKSA9PiBhbnksXHJcbiAgZXJyb3JzID0gZmFsc2VcclxuKTogYW55IHtcclxuICBpZiAoIWhhc1ZhbHVlKG9iamVjdCkpIHsgcmV0dXJuOyB9XHJcbiAgaWYgKChpc09iamVjdChvYmplY3QpIHx8IGlzQXJyYXkob2JqZWN0KSkgJiYgdHlwZW9mIG9iamVjdCAhPT0gJ2Z1bmN0aW9uJykge1xyXG4gICAgY29uc3QgbmV3T2JqZWN0OiBhbnkgPSBpc0FycmF5KG9iamVjdCkgPyBbXSA6IHt9O1xyXG4gICAgZm9yIChjb25zdCBrZXkgb2YgT2JqZWN0LmtleXMob2JqZWN0KSkge1xyXG4gICAgICBuZXdPYmplY3Rba2V5XSA9IGZuKG9iamVjdFtrZXldLCBrZXksIG9iamVjdCk7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gbmV3T2JqZWN0O1xyXG4gIH1cclxuICBpZiAoZXJyb3JzKSB7XHJcbiAgICBpZiAodHlwZW9mIGZuICE9PSAnZnVuY3Rpb24nKSB7XHJcbiAgICAgIGNvbnNvbGUuZXJyb3IoJ2ZvckVhY2hDb3B5IGVycm9yOiBJdGVyYXRvciBtdXN0IGJlIGEgZnVuY3Rpb24uJyk7XHJcbiAgICAgIGNvbnNvbGUuZXJyb3IoJ2Z1bmN0aW9uJywgZm4pO1xyXG4gICAgfVxyXG4gICAgaWYgKCFpc09iamVjdChvYmplY3QpICYmICFpc0FycmF5KG9iamVjdCkpIHtcclxuICAgICAgY29uc29sZS5lcnJvcignZm9yRWFjaENvcHkgZXJyb3I6IElucHV0IG9iamVjdCBtdXN0IGJlIGFuIG9iamVjdCBvciBhcnJheS4nKTtcclxuICAgICAgY29uc29sZS5lcnJvcignb2JqZWN0Jywgb2JqZWN0KTtcclxuICAgIH1cclxuICB9XHJcbn1cclxuXHJcbi8qKlxyXG4gKiAnaGFzT3duJyB1dGlsaXR5IGZ1bmN0aW9uXHJcbiAqXHJcbiAqIENoZWNrcyB3aGV0aGVyIGFuIG9iamVjdCBvciBhcnJheSBoYXMgYSBwYXJ0aWN1bGFyIHByb3BlcnR5LlxyXG4gKlxyXG4gKiAvLyB7YW55fSBvYmplY3QgLSB0aGUgb2JqZWN0IHRvIGNoZWNrXHJcbiAqIC8vIHtzdHJpbmd9IHByb3BlcnR5IC0gdGhlIHByb3BlcnR5IHRvIGxvb2sgZm9yXHJcbiAqIC8vIHtib29sZWFufSAtIHRydWUgaWYgb2JqZWN0IGhhcyBwcm9wZXJ0eSwgZmFsc2UgaWYgbm90XHJcbiAqL1xyXG5leHBvcnQgZnVuY3Rpb24gaGFzT3duKG9iamVjdDogYW55LCBwcm9wZXJ0eTogc3RyaW5nKTogYm9vbGVhbiB7XHJcbiAgaWYgKCFvYmplY3QgfHwgIVsnbnVtYmVyJywgJ3N0cmluZycsICdzeW1ib2wnXS5pbmNsdWRlcyh0eXBlb2YgcHJvcGVydHkpIHx8XHJcbiAgICAoIWlzT2JqZWN0KG9iamVjdCkgJiYgIWlzQXJyYXkob2JqZWN0KSAmJiAhaXNNYXAob2JqZWN0KSAmJiAhaXNTZXQob2JqZWN0KSlcclxuICApIHsgcmV0dXJuIGZhbHNlOyB9XHJcbiAgaWYgKGlzTWFwKG9iamVjdCkgfHwgaXNTZXQob2JqZWN0KSkgeyByZXR1cm4gb2JqZWN0Lmhhcyhwcm9wZXJ0eSk7IH1cclxuICBpZiAodHlwZW9mIHByb3BlcnR5ID09PSAnbnVtYmVyJykge1xyXG4gICAgaWYgKGlzQXJyYXkob2JqZWN0KSkgeyByZXR1cm4gb2JqZWN0WzxudW1iZXI+cHJvcGVydHldOyB9XHJcbiAgICBwcm9wZXJ0eSA9IHByb3BlcnR5ICsgJyc7XHJcbiAgfVxyXG4gIHJldHVybiBvYmplY3QuaGFzT3duUHJvcGVydHkocHJvcGVydHkpO1xyXG59XHJcblxyXG4vKipcclxuICogVHlwZXMgb2YgcG9zc2libGUgZXhwcmVzc2lvbnMgd2hpY2ggdGhlIGFwcCBpcyBhYmxlIHRvIGV2YWx1YXRlLlxyXG4gKi9cclxuZXhwb3J0IGVudW0gRXhwcmVzc2lvblR5cGUge1xyXG4gIEVRVUFMUyxcclxuICBOT1RfRVFVQUxTLFxyXG4gIE5PVF9BTl9FWFBSRVNTSU9OXHJcbn1cclxuXHJcbi8qKlxyXG4gKiBEZXRlY3RzIHRoZSB0eXBlIG9mIGV4cHJlc3Npb24gZnJvbSB0aGUgZ2l2ZW4gY2FuZGlkYXRlLiBgPT1gIGZvciBlcXVhbHMsXHJcbiAqIGAhPWAgZm9yIG5vdCBlcXVhbHMuIElmIG5vbmUgb2YgdGhlc2UgYXJlIGNvbnRhaW5lZCBpbiB0aGUgY2FuZGlkYXRlLCB0aGUgY2FuZGlkYXRlXHJcbiAqIGlzIG5vdCBjb25zaWRlcmVkIHRvIGJlIGFuIGV4cHJlc3Npb24gYXQgYWxsIGFuZCB0aHVzIGBOT1RfQU5fRVhQUkVTU0lPTmAgaXMgcmV0dXJuZWQuXHJcbiAqIC8vIHtleHByZXNzaW9uQ2FuZGlkYXRlfSBleHByZXNzaW9uQ2FuZGlkYXRlIC0gcG90ZW50aWFsIGV4cHJlc3Npb25cclxuICovXHJcbmV4cG9ydCBmdW5jdGlvbiBnZXRFeHByZXNzaW9uVHlwZShleHByZXNzaW9uQ2FuZGlkYXRlOiBzdHJpbmcpOiBFeHByZXNzaW9uVHlwZSB7XHJcbiAgaWYgKGV4cHJlc3Npb25DYW5kaWRhdGUuaW5kZXhPZignPT0nKSAhPT0gLTEpIHtcclxuICAgIHJldHVybiBFeHByZXNzaW9uVHlwZS5FUVVBTFM7XHJcbiAgfVxyXG5cclxuICBpZiAoZXhwcmVzc2lvbkNhbmRpZGF0ZS50b1N0cmluZygpLmluZGV4T2YoJyE9JykgIT09IC0xKSB7XHJcbiAgICByZXR1cm4gRXhwcmVzc2lvblR5cGUuTk9UX0VRVUFMUztcclxuICB9XHJcblxyXG4gIHJldHVybiBFeHByZXNzaW9uVHlwZS5OT1RfQU5fRVhQUkVTU0lPTjtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIGlzRXF1YWwoZXhwcmVzc2lvblR5cGUpIHtcclxuICByZXR1cm4gZXhwcmVzc2lvblR5cGUgYXMgRXhwcmVzc2lvblR5cGUgPT09IEV4cHJlc3Npb25UeXBlLkVRVUFMUztcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIGlzTm90RXF1YWwoZXhwcmVzc2lvblR5cGUpIHtcclxuICByZXR1cm4gZXhwcmVzc2lvblR5cGUgYXMgRXhwcmVzc2lvblR5cGUgPT09IEV4cHJlc3Npb25UeXBlLk5PVF9FUVVBTFM7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBpc05vdEV4cHJlc3Npb24oZXhwcmVzc2lvblR5cGUpIHtcclxuICByZXR1cm4gZXhwcmVzc2lvblR5cGUgYXMgRXhwcmVzc2lvblR5cGUgPT09IEV4cHJlc3Npb25UeXBlLk5PVF9BTl9FWFBSRVNTSU9OO1xyXG59XHJcblxyXG4vKipcclxuICogU3BsaXRzIHRoZSBleHByZXNzaW9uIGtleSBieSB0aGUgZXhwcmVzc2lvblR5cGUgb24gYSBwYWlyIG9mIHZhbHVlc1xyXG4gKiBiZWZvcmUgYW5kIGFmdGVyIHRoZSBlcXVhbHMgb3Igbm9yIGVxdWFscyBzaWduLlxyXG4gKiAvLyB7ZXhwcmVzc2lvblR5cGV9IGVudW0gb2YgYW4gZXhwcmVzc2lvbiB0eXBlXHJcbiAqIC8vIHtrZXl9IHRoZSBnaXZlbiBrZXkgZnJvbSBhIGZvciBsb29wIGl2ZXIgYWxsIGNvbmRpdGlvbnNcclxuICovXHJcbmV4cG9ydCBmdW5jdGlvbiBnZXRLZXlBbmRWYWx1ZUJ5RXhwcmVzc2lvblR5cGUoZXhwcmVzc2lvblR5cGU6IEV4cHJlc3Npb25UeXBlLCBrZXk6IHN0cmluZykge1xyXG4gIGlmIChpc0VxdWFsKGV4cHJlc3Npb25UeXBlKSkge1xyXG4gICAgcmV0dXJuIGtleS5zcGxpdCgnPT0nLCAyKTtcclxuICB9XHJcblxyXG4gIGlmIChpc05vdEVxdWFsKGV4cHJlc3Npb25UeXBlKSkge1xyXG4gICAgcmV0dXJuIGtleS5zcGxpdCgnIT0nLCAyKTtcclxuICB9XHJcblxyXG4gIHJldHVybiBudWxsO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gY2xlYW5WYWx1ZU9mUXVvdGVzKGtleUFuZFZhbHVlKTogU3RyaW5nIHtcclxuICBpZiAoa2V5QW5kVmFsdWUuY2hhckF0KDApID09PSAnXFwnJyAmJiBrZXlBbmRWYWx1ZS5jaGFyQXQoa2V5QW5kVmFsdWUubGVuZ3RoIC0gMSkgPT09ICdcXCcnKSB7XHJcbiAgICByZXR1cm4ga2V5QW5kVmFsdWUucmVwbGFjZSgnXFwnJywgJycpLnJlcGxhY2UoJ1xcJycsICcnKTtcclxuICB9XHJcbiAgcmV0dXJuIGtleUFuZFZhbHVlO1xyXG59XHJcblxyXG4vKipcclxuICogJ21lcmdlRmlsdGVyZWRPYmplY3QnIHV0aWxpdHkgZnVuY3Rpb25cclxuICpcclxuICogU2hhbGxvd2x5IG1lcmdlcyB0d28gb2JqZWN0cywgc2V0dGluZyBrZXkgYW5kIHZhbHVlcyBmcm9tIHNvdXJjZSBvYmplY3RcclxuICogaW4gdGFyZ2V0IG9iamVjdCwgZXhjbHVkaW5nIHNwZWNpZmllZCBrZXlzLlxyXG4gKlxyXG4gKiBPcHRpb25hbGx5LCBpdCBjYW4gYWxzbyB1c2UgZnVuY3Rpb25zIHRvIHRyYW5zZm9ybSB0aGUga2V5IG5hbWVzIGFuZC9vclxyXG4gKiB0aGUgdmFsdWVzIG9mIHRoZSBtZXJnaW5nIG9iamVjdC5cclxuICpcclxuICogLy8ge1BsYWluT2JqZWN0fSB0YXJnZXRPYmplY3QgLSBUYXJnZXQgb2JqZWN0IHRvIGFkZCBrZXlzIGFuZCB2YWx1ZXMgdG9cclxuICogLy8ge1BsYWluT2JqZWN0fSBzb3VyY2VPYmplY3QgLSBTb3VyY2Ugb2JqZWN0IHRvIGNvcHkga2V5cyBhbmQgdmFsdWVzIGZyb21cclxuICogLy8ge3N0cmluZ1tdfSBleGNsdWRlS2V5cyAtIEFycmF5IG9mIGtleXMgdG8gZXhjbHVkZVxyXG4gKiAvLyB7KHN0cmluZzogc3RyaW5nKSA9PiBzdHJpbmcgPSAoaykgPT4ga30ga2V5Rm4gLSBGdW5jdGlvbiB0byBhcHBseSB0byBrZXlzXHJcbiAqIC8vIHsoYW55OiBhbnkpID0+IGFueSA9ICh2KSA9PiB2fSB2YWx1ZUZuIC0gRnVuY3Rpb24gdG8gYXBwbHkgdG8gdmFsdWVzXHJcbiAqIC8vIHtQbGFpbk9iamVjdH0gLSBSZXR1cm5zIHRhcmdldE9iamVjdFxyXG4gKi9cclxuZXhwb3J0IGZ1bmN0aW9uIG1lcmdlRmlsdGVyZWRPYmplY3QoXHJcbiAgdGFyZ2V0T2JqZWN0OiBQbGFpbk9iamVjdCxcclxuICBzb3VyY2VPYmplY3Q6IFBsYWluT2JqZWN0LFxyXG4gIGV4Y2x1ZGVLZXlzID0gPHN0cmluZ1tdPltdLFxyXG4gIGtleUZuID0gKGtleTogc3RyaW5nKTogc3RyaW5nID0+IGtleSxcclxuICB2YWxGbiA9ICh2YWw6IGFueSk6IGFueSA9PiB2YWxcclxuKTogUGxhaW5PYmplY3Qge1xyXG4gIGlmICghaXNPYmplY3Qoc291cmNlT2JqZWN0KSkgeyByZXR1cm4gdGFyZ2V0T2JqZWN0OyB9XHJcbiAgaWYgKCFpc09iamVjdCh0YXJnZXRPYmplY3QpKSB7IHRhcmdldE9iamVjdCA9IHt9OyB9XHJcbiAgZm9yIChjb25zdCBrZXkgb2YgT2JqZWN0LmtleXMoc291cmNlT2JqZWN0KSkge1xyXG4gICAgaWYgKCFpbkFycmF5KGtleSwgZXhjbHVkZUtleXMpICYmIGlzRGVmaW5lZChzb3VyY2VPYmplY3Rba2V5XSkpIHtcclxuICAgICAgdGFyZ2V0T2JqZWN0W2tleUZuKGtleSldID0gdmFsRm4oc291cmNlT2JqZWN0W2tleV0pO1xyXG4gICAgfVxyXG4gIH1cclxuICByZXR1cm4gdGFyZ2V0T2JqZWN0O1xyXG59XHJcblxyXG4vKipcclxuICogJ3VuaXF1ZUl0ZW1zJyBmdW5jdGlvblxyXG4gKlxyXG4gKiBBY2NlcHRzIGFueSBudW1iZXIgb2Ygc3RyaW5nIHZhbHVlIGlucHV0cyxcclxuICogYW5kIHJldHVybnMgYW4gYXJyYXkgb2YgYWxsIGlucHV0IHZhdWVzLCBleGNsdWRpbmcgZHVwbGljYXRlcy5cclxuICpcclxuICogLy8gey4uLnN0cmluZ30gLi4uaXRlbXMgLVxyXG4gKiAvLyB7c3RyaW5nW119IC1cclxuICovXHJcbmV4cG9ydCBmdW5jdGlvbiB1bmlxdWVJdGVtcyguLi5pdGVtcyk6IHN0cmluZ1tdIHtcclxuICBjb25zdCByZXR1cm5JdGVtcyA9IFtdO1xyXG4gIGZvciAoY29uc3QgaXRlbSBvZiBpdGVtcykge1xyXG4gICAgaWYgKCFyZXR1cm5JdGVtcy5pbmNsdWRlcyhpdGVtKSkgeyByZXR1cm5JdGVtcy5wdXNoKGl0ZW0pOyB9XHJcbiAgfVxyXG4gIHJldHVybiByZXR1cm5JdGVtcztcclxufVxyXG5cclxuLyoqXHJcbiAqICdjb21tb25JdGVtcycgZnVuY3Rpb25cclxuICpcclxuICogQWNjZXB0cyBhbnkgbnVtYmVyIG9mIHN0cmluZ3Mgb3IgYXJyYXlzIG9mIHN0cmluZyB2YWx1ZXMsXHJcbiAqIGFuZCByZXR1cm5zIGEgc2luZ2xlIGFycmF5IGNvbnRhaW5pbmcgb25seSB2YWx1ZXMgcHJlc2VudCBpbiBhbGwgaW5wdXRzLlxyXG4gKlxyXG4gKiAvLyB7Li4uc3RyaW5nfHN0cmluZ1tdfSAuLi5hcnJheXMgLVxyXG4gKiAvLyB7c3RyaW5nW119IC1cclxuICovXHJcbmV4cG9ydCBmdW5jdGlvbiBjb21tb25JdGVtcyguLi5hcnJheXMpOiBzdHJpbmdbXSB7XHJcbiAgbGV0IHJldHVybkl0ZW1zID0gbnVsbDtcclxuICBmb3IgKGxldCBhcnJheSBvZiBhcnJheXMpIHtcclxuICAgIGlmIChpc1N0cmluZyhhcnJheSkpIHsgYXJyYXkgPSBbYXJyYXldOyB9XHJcbiAgICByZXR1cm5JdGVtcyA9IHJldHVybkl0ZW1zID09PSBudWxsID8gWyAuLi5hcnJheSBdIDpcclxuICAgICAgcmV0dXJuSXRlbXMuZmlsdGVyKGl0ZW0gPT4gYXJyYXkuaW5jbHVkZXMoaXRlbSkpO1xyXG4gICAgaWYgKCFyZXR1cm5JdGVtcy5sZW5ndGgpIHsgcmV0dXJuIFtdOyB9XHJcbiAgfVxyXG4gIHJldHVybiByZXR1cm5JdGVtcztcclxufVxyXG5cclxuLyoqXHJcbiAqICdmaXhUaXRsZScgZnVuY3Rpb25cclxuICpcclxuICpcclxuICogLy8ge3N0cmluZ30gaW5wdXQgLVxyXG4gKiAvLyB7c3RyaW5nfSAtXHJcbiAqL1xyXG5leHBvcnQgZnVuY3Rpb24gZml4VGl0bGUobmFtZTogc3RyaW5nKTogc3RyaW5nIHtcclxuICByZXR1cm4gbmFtZSAmJiB0b1RpdGxlQ2FzZShuYW1lLnJlcGxhY2UoLyhbYS16XSkoW0EtWl0pL2csICckMSAkMicpLnJlcGxhY2UoL18vZywgJyAnKSk7XHJcbn1cclxuXHJcbi8qKlxyXG4gKiAndG9UaXRsZUNhc2UnIGZ1bmN0aW9uXHJcbiAqXHJcbiAqIEludGVsbGlnZW50bHkgY29udmVydHMgYW4gaW5wdXQgc3RyaW5nIHRvIFRpdGxlIENhc2UuXHJcbiAqXHJcbiAqIEFjY2VwdHMgYW4gb3B0aW9uYWwgc2Vjb25kIHBhcmFtZXRlciB3aXRoIGEgbGlzdCBvZiBhZGRpdGlvbmFsXHJcbiAqIHdvcmRzIGFuZCBhYmJyZXZpYXRpb25zIHRvIGZvcmNlIGludG8gYSBwYXJ0aWN1bGFyIGNhc2UuXHJcbiAqXHJcbiAqIFRoaXMgZnVuY3Rpb24gaXMgYnVpbHQgb24gcHJpb3Igd29yayBieSBKb2huIEdydWJlciBhbmQgRGF2aWQgR291Y2g6XHJcbiAqIGh0dHA6Ly9kYXJpbmdmaXJlYmFsbC5uZXQvMjAwOC8wOC90aXRsZV9jYXNlX3VwZGF0ZVxyXG4gKiBodHRwczovL2dpdGh1Yi5jb20vZ291Y2gvdG8tdGl0bGUtY2FzZVxyXG4gKlxyXG4gKiAvLyB7c3RyaW5nfSBpbnB1dCAtXHJcbiAqIC8vIHtzdHJpbmd8c3RyaW5nW119IGZvcmNlV29yZHM/IC1cclxuICogLy8ge3N0cmluZ30gLVxyXG4gKi9cclxuZXhwb3J0IGZ1bmN0aW9uIHRvVGl0bGVDYXNlKGlucHV0OiBzdHJpbmcsIGZvcmNlV29yZHM/OiBzdHJpbmd8c3RyaW5nW10pOiBzdHJpbmcge1xyXG4gIGlmICghaXNTdHJpbmcoaW5wdXQpKSB7IHJldHVybiBpbnB1dDsgfVxyXG4gIGxldCBmb3JjZUFycmF5OiBzdHJpbmdbXSA9IFsnYScsICdhbicsICdhbmQnLCAnYXMnLCAnYXQnLCAnYnV0JywgJ2J5JywgJ2VuJyxcclxuICAgJ2ZvcicsICdpZicsICdpbicsICdub3InLCAnb2YnLCAnb24nLCAnb3InLCAncGVyJywgJ3RoZScsICd0bycsICd2JywgJ3YuJyxcclxuICAgJ3ZzJywgJ3ZzLicsICd2aWEnXTtcclxuICBpZiAoaXNTdHJpbmcoZm9yY2VXb3JkcykpIHsgZm9yY2VXb3JkcyA9ICg8c3RyaW5nPmZvcmNlV29yZHMpLnNwbGl0KCd8Jyk7IH1cclxuICBpZiAoaXNBcnJheShmb3JjZVdvcmRzKSkgeyBmb3JjZUFycmF5ID0gZm9yY2VBcnJheS5jb25jYXQoZm9yY2VXb3Jkcyk7IH1cclxuICBjb25zdCBmb3JjZUFycmF5TG93ZXI6IHN0cmluZ1tdID0gZm9yY2VBcnJheS5tYXAodyA9PiB3LnRvTG93ZXJDYXNlKCkpO1xyXG4gIGNvbnN0IG5vSW5pdGlhbENhc2U6IGJvb2xlYW4gPVxyXG4gICAgaW5wdXQgPT09IGlucHV0LnRvVXBwZXJDYXNlKCkgfHwgaW5wdXQgPT09IGlucHV0LnRvTG93ZXJDYXNlKCk7XHJcbiAgbGV0IHByZXZMYXN0Q2hhciA9ICcnO1xyXG4gIGlucHV0ID0gaW5wdXQudHJpbSgpO1xyXG4gIHJldHVybiBpbnB1dC5yZXBsYWNlKC9bQS1aYS16MC05XFx1MDBDMC1cXHUwMEZGXStbXlxccy1dKi9nLCAod29yZCwgaWR4KSA9PiB7XHJcbiAgICBpZiAoIW5vSW5pdGlhbENhc2UgJiYgd29yZC5zbGljZSgxKS5zZWFyY2goL1tBLVpdfFxcLi4vKSAhPT0gLTEpIHtcclxuICAgICAgcmV0dXJuIHdvcmQ7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICBsZXQgbmV3V29yZDogc3RyaW5nO1xyXG4gICAgICBjb25zdCBmb3JjZVdvcmQ6IHN0cmluZyA9XHJcbiAgICAgICAgZm9yY2VBcnJheVtmb3JjZUFycmF5TG93ZXIuaW5kZXhPZih3b3JkLnRvTG93ZXJDYXNlKCkpXTtcclxuICAgICAgaWYgKCFmb3JjZVdvcmQpIHtcclxuICAgICAgICBpZiAobm9Jbml0aWFsQ2FzZSkge1xyXG4gICAgICAgICAgaWYgKHdvcmQuc2xpY2UoMSkuc2VhcmNoKC9cXC4uLykgIT09IC0xKSB7XHJcbiAgICAgICAgICAgIG5ld1dvcmQgPSB3b3JkLnRvTG93ZXJDYXNlKCk7XHJcbiAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICBuZXdXb3JkID0gd29yZFswXS50b1VwcGVyQ2FzZSgpICsgd29yZC5zbGljZSgxKS50b0xvd2VyQ2FzZSgpO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICBuZXdXb3JkID0gd29yZFswXS50b1VwcGVyQ2FzZSgpICsgd29yZC5zbGljZSgxKTtcclxuICAgICAgICB9XHJcbiAgICAgIH0gZWxzZSBpZiAoXHJcbiAgICAgICAgZm9yY2VXb3JkID09PSBmb3JjZVdvcmQudG9Mb3dlckNhc2UoKSAmJiAoXHJcbiAgICAgICAgICBpZHggPT09IDAgfHwgaWR4ICsgd29yZC5sZW5ndGggPT09IGlucHV0Lmxlbmd0aCB8fFxyXG4gICAgICAgICAgcHJldkxhc3RDaGFyID09PSAnOicgfHwgaW5wdXRbaWR4IC0gMV0uc2VhcmNoKC9bXlxccy1dLykgIT09IC0xIHx8XHJcbiAgICAgICAgICAoaW5wdXRbaWR4IC0gMV0gIT09ICctJyAmJiBpbnB1dFtpZHggKyB3b3JkLmxlbmd0aF0gPT09ICctJylcclxuICAgICAgICApXHJcbiAgICAgICkge1xyXG4gICAgICAgIG5ld1dvcmQgPSBmb3JjZVdvcmRbMF0udG9VcHBlckNhc2UoKSArIGZvcmNlV29yZC5zbGljZSgxKTtcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICBuZXdXb3JkID0gZm9yY2VXb3JkO1xyXG4gICAgICB9XHJcbiAgICAgIHByZXZMYXN0Q2hhciA9IHdvcmQuc2xpY2UoLTEpO1xyXG4gICAgICByZXR1cm4gbmV3V29yZDtcclxuICAgIH1cclxuICB9KTtcclxufVxyXG4iXX0=