@ng-formworks/core 18.5.2 → 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 +146 -127
  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 -445
  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,884 +0,0 @@
1
- import isEqual from 'lodash/isEqual';
2
- import { _executeAsyncValidators, _executeValidators, _mergeErrors, _mergeObjects, getType, hasValue, isArray, isBoolean, isDefined, isEmpty, isNumber, isString, isType, toJavaScriptType, toObservable, xor } from './validator.functions';
3
- import { forEachCopy } from './utility.functions';
4
- import { forkJoin } from 'rxjs';
5
- import { jsonSchemaFormatTests } from './format-regex.constants';
6
- import { map } from 'rxjs/operators';
7
- /**
8
- * 'JsonValidators' class
9
- *
10
- * Provides an extended set of validators to be used by form controls,
11
- * compatible with standard JSON Schema validation options.
12
- * http://json-schema.org/latest/json-schema-validation.html
13
- *
14
- * Note: This library is designed as a drop-in replacement for the Angular
15
- * Validators library, and except for one small breaking change to the 'pattern'
16
- * validator (described below) it can even be imported as a substitute, like so:
17
- *
18
- * import { JsonValidators as Validators } from 'json-validators';
19
- *
20
- * and it should work with existing code as a complete replacement.
21
- *
22
- * The one exception is the 'pattern' validator, which has been changed to
23
- * matche partial values by default (the standard 'pattern' validator wrapped
24
- * all patterns in '^' and '$', forcing them to always match an entire value).
25
- * However, the old behavior can be restored by simply adding '^' and '$'
26
- * around your patterns, or by passing an optional second parameter of TRUE.
27
- * This change is to make the 'pattern' validator match the behavior of a
28
- * JSON Schema pattern, which allows partial matches, rather than the behavior
29
- * of an HTML input control pattern, which does not.
30
- *
31
- * This library replaces Angular's validators and combination functions
32
- * with the following validators and transformation functions:
33
- *
34
- * Validators:
35
- * For all formControls: required (*), type, enum, const
36
- * For text formControls: minLength (*), maxLength (*), pattern (*), format
37
- * For numeric formControls: maximum, exclusiveMaximum,
38
- * minimum, exclusiveMinimum, multipleOf
39
- * For formGroup objects: minProperties, maxProperties, dependencies
40
- * For formArray arrays: minItems, maxItems, uniqueItems, contains
41
- * Not used by JSON Schema: min (*), max (*), requiredTrue (*), email (*)
42
- * (Validators originally included with Angular are maked with (*).)
43
- *
44
- * NOTE / TODO: The dependencies validator is not complete.
45
- * NOTE / TODO: The contains validator is not complete.
46
- *
47
- * Validators not used by JSON Schema (but included for compatibility)
48
- * and their JSON Schema equivalents:
49
- *
50
- * Angular validator | JSON Schema equivalent
51
- * ------------------|-----------------------
52
- * min(number) | minimum(number)
53
- * max(number) | maximum(number)
54
- * requiredTrue() | const(true)
55
- * email() | format('email')
56
- *
57
- * Validator transformation functions:
58
- * composeAnyOf, composeOneOf, composeAllOf, composeNot
59
- * (Angular's original combination funciton, 'compose', is also included for
60
- * backward compatibility, though it is functionally equivalent to composeAllOf,
61
- * asside from its more generic error message.)
62
- *
63
- * All validators have also been extended to accept an optional second argument
64
- * which, if passed a TRUE value, causes the validator to perform the opposite
65
- * of its original finction. (This is used internally to enable 'not' and
66
- * 'composeOneOf' to function and return useful error messages.)
67
- *
68
- * The 'required' validator has also been overloaded so that if called with
69
- * a boolean parameter (or no parameters) it returns the original validator
70
- * function (rather than executing it). However, if it is called with an
71
- * AbstractControl parameter (as was previously required), it behaves
72
- * exactly as before.
73
- *
74
- * This enables all validators (including 'required') to be constructed in
75
- * exactly the same way, so they can be automatically applied using the
76
- * equivalent key names and values taken directly from a JSON Schema.
77
- *
78
- * This source code is partially derived from Angular,
79
- * which is Copyright (c) 2014-2017 Google, Inc.
80
- * Use of this source code is therefore governed by the same MIT-style license
81
- * that can be found in the LICENSE file at https://angular.io/license
82
- *
83
- * Original Angular Validators:
84
- * https://github.com/angular/angular/blob/master/packages/forms/src/validators.ts
85
- */
86
- export class JsonValidators {
87
- static required(input) {
88
- if (input === undefined) {
89
- input = true;
90
- }
91
- switch (input) {
92
- case true: // Return required function (do not execute it yet)
93
- return (control, invert = false) => {
94
- if (invert) {
95
- return null;
96
- } // if not required, always return valid
97
- return hasValue(control.value) ? null : { 'required': true };
98
- };
99
- case false: // Do nothing (if field is not required, it is always valid)
100
- return JsonValidators.nullValidator;
101
- default: // Execute required function
102
- return hasValue(input.value) ? null : { 'required': true };
103
- }
104
- }
105
- /**
106
- * 'type' validator
107
- *
108
- * Requires a control to only accept values of a specified type,
109
- * or one of an array of types.
110
- *
111
- * Note: SchemaPrimitiveType = 'string'|'number'|'integer'|'boolean'|'null'
112
- *
113
- * // {SchemaPrimitiveType|SchemaPrimitiveType[]} type - type(s) to accept
114
- * // {IValidatorFn}
115
- */
116
- static type(requiredType) {
117
- if (!hasValue(requiredType)) {
118
- return JsonValidators.nullValidator;
119
- }
120
- return (control, invert = false) => {
121
- if (isEmpty(control.value)) {
122
- return null;
123
- }
124
- const currentValue = control.value;
125
- const isValid = isArray(requiredType) ?
126
- requiredType.some(type => isType(currentValue, type)) :
127
- isType(currentValue, requiredType);
128
- return xor(isValid, invert) ?
129
- null : { 'type': { requiredType, currentValue } };
130
- };
131
- }
132
- /**
133
- * 'enum' validator
134
- *
135
- * Requires a control to have a value from an enumerated list of values.
136
- *
137
- * Converts types as needed to allow string inputs to still correctly
138
- * match number, boolean, and null enum values.
139
- *
140
- * // {any[]} allowedValues - array of acceptable values
141
- * // {IValidatorFn}
142
- */
143
- static enum(allowedValues) {
144
- if (!isArray(allowedValues)) {
145
- return JsonValidators.nullValidator;
146
- }
147
- return (control, invert = false) => {
148
- if (isEmpty(control.value)) {
149
- return null;
150
- }
151
- const currentValue = control.value;
152
- const isEqualVal = (enumValue, inputValue) => enumValue === inputValue ||
153
- (isNumber(enumValue) && +inputValue === +enumValue) ||
154
- (isBoolean(enumValue, 'strict') &&
155
- toJavaScriptType(inputValue, 'boolean') === enumValue) ||
156
- (enumValue === null && !hasValue(inputValue)) ||
157
- isEqual(enumValue, inputValue);
158
- const isValid = isArray(currentValue) ?
159
- currentValue.every(inputValue => allowedValues.some(enumValue => isEqualVal(enumValue, inputValue))) :
160
- allowedValues.some(enumValue => isEqualVal(enumValue, currentValue));
161
- return xor(isValid, invert) ?
162
- null : { 'enum': { allowedValues, currentValue } };
163
- };
164
- }
165
- /**
166
- * 'const' validator
167
- *
168
- * Requires a control to have a specific value.
169
- *
170
- * Converts types as needed to allow string inputs to still correctly
171
- * match number, boolean, and null values.
172
- *
173
- * TODO: modify to work with objects
174
- *
175
- * // {any[]} requiredValue - required value
176
- * // {IValidatorFn}
177
- */
178
- static const(requiredValue) {
179
- if (!hasValue(requiredValue)) {
180
- return JsonValidators.nullValidator;
181
- }
182
- return (control, invert = false) => {
183
- if (isEmpty(control.value)) {
184
- return null;
185
- }
186
- const currentValue = control.value;
187
- const isEqualVal = (constValue, inputValue) => constValue === inputValue ||
188
- isNumber(constValue) && +inputValue === +constValue ||
189
- isBoolean(constValue, 'strict') &&
190
- toJavaScriptType(inputValue, 'boolean') === constValue ||
191
- constValue === null && !hasValue(inputValue);
192
- const isValid = isEqualVal(requiredValue, currentValue);
193
- return xor(isValid, invert) ?
194
- null : { 'const': { requiredValue, currentValue } };
195
- };
196
- }
197
- /**
198
- * 'minLength' validator
199
- *
200
- * Requires a control's text value to be greater than a specified length.
201
- *
202
- * // {number} minimumLength - minimum allowed string length
203
- * // {boolean = false} invert - instead return error object only if valid
204
- * // {IValidatorFn}
205
- */
206
- static minLength(minimumLength) {
207
- if (!hasValue(minimumLength)) {
208
- return JsonValidators.nullValidator;
209
- }
210
- return (control, invert = false) => {
211
- if (isEmpty(control.value)) {
212
- return null;
213
- }
214
- const currentLength = isString(control.value) ? control.value.length : 0;
215
- const isValid = currentLength >= minimumLength;
216
- return xor(isValid, invert) ?
217
- null : { 'minLength': { minimumLength, currentLength } };
218
- };
219
- }
220
- /**
221
- * 'maxLength' validator
222
- *
223
- * Requires a control's text value to be less than a specified length.
224
- *
225
- * // {number} maximumLength - maximum allowed string length
226
- * // {boolean = false} invert - instead return error object only if valid
227
- * // {IValidatorFn}
228
- */
229
- static maxLength(maximumLength) {
230
- if (!hasValue(maximumLength)) {
231
- return JsonValidators.nullValidator;
232
- }
233
- return (control, invert = false) => {
234
- const currentLength = isString(control.value) ? control.value.length : 0;
235
- const isValid = currentLength <= maximumLength;
236
- return xor(isValid, invert) ?
237
- null : { 'maxLength': { maximumLength, currentLength } };
238
- };
239
- }
240
- /**
241
- * 'pattern' validator
242
- *
243
- * Note: NOT the same as Angular's default pattern validator.
244
- *
245
- * Requires a control's value to match a specified regular expression pattern.
246
- *
247
- * This validator changes the behavior of default pattern validator
248
- * by replacing RegExp(`^${pattern}$`) with RegExp(`${pattern}`),
249
- * which allows for partial matches.
250
- *
251
- * To return to the default funcitonality, and match the entire string,
252
- * pass TRUE as the optional second parameter.
253
- *
254
- * // {string} pattern - regular expression pattern
255
- * // {boolean = false} wholeString - match whole value string?
256
- * // {IValidatorFn}
257
- */
258
- static pattern(pattern, wholeString = false) {
259
- if (!hasValue(pattern)) {
260
- return JsonValidators.nullValidator;
261
- }
262
- return (control, invert = false) => {
263
- if (isEmpty(control.value)) {
264
- return null;
265
- }
266
- let regex;
267
- let requiredPattern;
268
- if (typeof pattern === 'string') {
269
- requiredPattern = (wholeString) ? `^${pattern}$` : pattern;
270
- regex = new RegExp(requiredPattern);
271
- }
272
- else {
273
- requiredPattern = pattern.toString();
274
- regex = pattern;
275
- }
276
- const currentValue = control.value;
277
- const isValid = isString(currentValue) ? regex.test(currentValue) : false;
278
- return xor(isValid, invert) ?
279
- null : { 'pattern': { requiredPattern, currentValue } };
280
- };
281
- }
282
- /**
283
- * 'format' validator
284
- *
285
- * Requires a control to have a value of a certain format.
286
- *
287
- * This validator currently checks the following formsts:
288
- * date, time, date-time, email, hostname, ipv4, ipv6,
289
- * uri, uri-reference, uri-template, url, uuid, color,
290
- * json-pointer, relative-json-pointer, regex
291
- *
292
- * Fast format regular expressions copied from AJV:
293
- * https://github.com/epoberezkin/ajv/blob/master/lib/compile/formats.js
294
- *
295
- * // {JsonSchemaFormatNames} requiredFormat - format to check
296
- * // {IValidatorFn}
297
- */
298
- static format(requiredFormat) {
299
- if (!hasValue(requiredFormat)) {
300
- return JsonValidators.nullValidator;
301
- }
302
- return (control, invert = false) => {
303
- if (isEmpty(control.value)) {
304
- return null;
305
- }
306
- let isValid;
307
- const currentValue = control.value;
308
- if (isString(currentValue)) {
309
- const formatTest = jsonSchemaFormatTests[requiredFormat];
310
- if (typeof formatTest === 'object') {
311
- isValid = formatTest.test(currentValue);
312
- }
313
- else if (typeof formatTest === 'function') {
314
- isValid = formatTest(currentValue);
315
- }
316
- else {
317
- console.error(`format validator error: "${requiredFormat}" is not a recognized format.`);
318
- isValid = true;
319
- }
320
- }
321
- else {
322
- // Allow JavaScript Date objects
323
- isValid = ['date', 'time', 'date-time'].includes(requiredFormat) &&
324
- Object.prototype.toString.call(currentValue) === '[object Date]';
325
- }
326
- return xor(isValid, invert) ?
327
- null : { 'format': { requiredFormat, currentValue } };
328
- };
329
- }
330
- /**
331
- * 'minimum' validator
332
- *
333
- * Requires a control's numeric value to be greater than or equal to
334
- * a minimum amount.
335
- *
336
- * Any non-numeric value is also valid (according to the HTML forms spec,
337
- * a non-numeric value doesn't have a minimum).
338
- * https://www.w3.org/TR/html5/forms.html#attr-input-max
339
- *
340
- * // {number} minimum - minimum allowed value
341
- * // {IValidatorFn}
342
- */
343
- static minimum(minimumValue) {
344
- if (!hasValue(minimumValue)) {
345
- return JsonValidators.nullValidator;
346
- }
347
- return (control, invert = false) => {
348
- if (isEmpty(control.value)) {
349
- return null;
350
- }
351
- const currentValue = control.value;
352
- const isValid = !isNumber(currentValue) || currentValue >= minimumValue;
353
- return xor(isValid, invert) ?
354
- null : { 'minimum': { minimumValue, currentValue } };
355
- };
356
- }
357
- /**
358
- * 'exclusiveMinimum' validator
359
- *
360
- * Requires a control's numeric value to be less than a maximum amount.
361
- *
362
- * Any non-numeric value is also valid (according to the HTML forms spec,
363
- * a non-numeric value doesn't have a maximum).
364
- * https://www.w3.org/TR/html5/forms.html#attr-input-max
365
- *
366
- * // {number} exclusiveMinimumValue - maximum allowed value
367
- * // {IValidatorFn}
368
- */
369
- static exclusiveMinimum(exclusiveMinimumValue) {
370
- if (!hasValue(exclusiveMinimumValue)) {
371
- return JsonValidators.nullValidator;
372
- }
373
- return (control, invert = false) => {
374
- if (isEmpty(control.value)) {
375
- return null;
376
- }
377
- const currentValue = control.value;
378
- const isValid = !isNumber(currentValue) || +currentValue < exclusiveMinimumValue;
379
- return xor(isValid, invert) ?
380
- null : { 'exclusiveMinimum': { exclusiveMinimumValue, currentValue } };
381
- };
382
- }
383
- /**
384
- * 'maximum' validator
385
- *
386
- * Requires a control's numeric value to be less than or equal to
387
- * a maximum amount.
388
- *
389
- * Any non-numeric value is also valid (according to the HTML forms spec,
390
- * a non-numeric value doesn't have a maximum).
391
- * https://www.w3.org/TR/html5/forms.html#attr-input-max
392
- *
393
- * // {number} maximumValue - maximum allowed value
394
- * // {IValidatorFn}
395
- */
396
- static maximum(maximumValue) {
397
- if (!hasValue(maximumValue)) {
398
- return JsonValidators.nullValidator;
399
- }
400
- return (control, invert = false) => {
401
- if (isEmpty(control.value)) {
402
- return null;
403
- }
404
- const currentValue = control.value;
405
- const isValid = !isNumber(currentValue) || +currentValue <= maximumValue;
406
- return xor(isValid, invert) ?
407
- null : { 'maximum': { maximumValue, currentValue } };
408
- };
409
- }
410
- /**
411
- * 'exclusiveMaximum' validator
412
- *
413
- * Requires a control's numeric value to be less than a maximum amount.
414
- *
415
- * Any non-numeric value is also valid (according to the HTML forms spec,
416
- * a non-numeric value doesn't have a maximum).
417
- * https://www.w3.org/TR/html5/forms.html#attr-input-max
418
- *
419
- * // {number} exclusiveMaximumValue - maximum allowed value
420
- * // {IValidatorFn}
421
- */
422
- static exclusiveMaximum(exclusiveMaximumValue) {
423
- if (!hasValue(exclusiveMaximumValue)) {
424
- return JsonValidators.nullValidator;
425
- }
426
- return (control, invert = false) => {
427
- if (isEmpty(control.value)) {
428
- return null;
429
- }
430
- const currentValue = control.value;
431
- const isValid = !isNumber(currentValue) || +currentValue < exclusiveMaximumValue;
432
- return xor(isValid, invert) ?
433
- null : { 'exclusiveMaximum': { exclusiveMaximumValue, currentValue } };
434
- };
435
- }
436
- /**
437
- * 'multipleOf' validator
438
- *
439
- * Requires a control to have a numeric value that is a multiple
440
- * of a specified number.
441
- *
442
- * // {number} multipleOfValue - number value must be a multiple of
443
- * // {IValidatorFn}
444
- */
445
- static multipleOf(multipleOfValue) {
446
- if (!hasValue(multipleOfValue)) {
447
- return JsonValidators.nullValidator;
448
- }
449
- return (control, invert = false) => {
450
- if (isEmpty(control.value)) {
451
- return null;
452
- }
453
- const currentValue = control.value;
454
- const isValid = isNumber(currentValue) &&
455
- currentValue % multipleOfValue === 0;
456
- return xor(isValid, invert) ?
457
- null : { 'multipleOf': { multipleOfValue, currentValue } };
458
- };
459
- }
460
- /**
461
- * 'minProperties' validator
462
- *
463
- * Requires a form group to have a minimum number of properties (i.e. have
464
- * values entered in a minimum number of controls within the group).
465
- *
466
- * // {number} minimumProperties - minimum number of properties allowed
467
- * // {IValidatorFn}
468
- */
469
- static minProperties(minimumProperties) {
470
- if (!hasValue(minimumProperties)) {
471
- return JsonValidators.nullValidator;
472
- }
473
- return (control, invert = false) => {
474
- if (isEmpty(control.value)) {
475
- return null;
476
- }
477
- const currentProperties = Object.keys(control.value).length || 0;
478
- const isValid = currentProperties >= minimumProperties;
479
- return xor(isValid, invert) ?
480
- null : { 'minProperties': { minimumProperties, currentProperties } };
481
- };
482
- }
483
- /**
484
- * 'maxProperties' validator
485
- *
486
- * Requires a form group to have a maximum number of properties (i.e. have
487
- * values entered in a maximum number of controls within the group).
488
- *
489
- * Note: Has no effect if the form group does not contain more than the
490
- * maximum number of controls.
491
- *
492
- * // {number} maximumProperties - maximum number of properties allowed
493
- * // {IValidatorFn}
494
- */
495
- static maxProperties(maximumProperties) {
496
- if (!hasValue(maximumProperties)) {
497
- return JsonValidators.nullValidator;
498
- }
499
- return (control, invert = false) => {
500
- const currentProperties = Object.keys(control.value).length || 0;
501
- const isValid = currentProperties <= maximumProperties;
502
- return xor(isValid, invert) ?
503
- null : { 'maxProperties': { maximumProperties, currentProperties } };
504
- };
505
- }
506
- /**
507
- * 'dependencies' validator
508
- *
509
- * Requires the controls in a form group to meet additional validation
510
- * criteria, depending on the values of other controls in the group.
511
- *
512
- * Examples:
513
- * https://spacetelescope.github.io/understanding-json-schema/reference/object.html#dependencies
514
- *
515
- * // {any} dependencies - required dependencies
516
- * // {IValidatorFn}
517
- */
518
- static dependencies(dependencies) {
519
- if (getType(dependencies) !== 'object' || isEmpty(dependencies)) {
520
- return JsonValidators.nullValidator;
521
- }
522
- return (control, invert = false) => {
523
- if (isEmpty(control.value)) {
524
- return null;
525
- }
526
- const allErrors = _mergeObjects(forEachCopy(dependencies, (value, requiringField) => {
527
- if (!hasValue(control.value[requiringField])) {
528
- return null;
529
- }
530
- let requiringFieldErrors = {};
531
- let requiredFields;
532
- let properties = {};
533
- if (getType(dependencies[requiringField]) === 'array') {
534
- requiredFields = dependencies[requiringField];
535
- }
536
- else if (getType(dependencies[requiringField]) === 'object') {
537
- requiredFields = dependencies[requiringField]['required'] || [];
538
- properties = dependencies[requiringField]['properties'] || {};
539
- }
540
- // Validate property dependencies
541
- for (const requiredField of requiredFields) {
542
- if (xor(!hasValue(control.value[requiredField]), invert)) {
543
- requiringFieldErrors[requiredField] = { 'required': true };
544
- }
545
- }
546
- // Validate schema dependencies
547
- requiringFieldErrors = _mergeObjects(requiringFieldErrors, forEachCopy(properties, (requirements, requiredField) => {
548
- const requiredFieldErrors = _mergeObjects(forEachCopy(requirements, (requirement, parameter) => {
549
- let validator = null;
550
- if (requirement === 'maximum' || requirement === 'minimum') {
551
- const exclusive = !!requirements['exclusiveM' + requirement.slice(1)];
552
- validator = JsonValidators[requirement](parameter, exclusive);
553
- }
554
- else if (typeof JsonValidators[requirement] === 'function') {
555
- validator = JsonValidators[requirement](parameter);
556
- }
557
- return !isDefined(validator) ?
558
- null : validator(control.value[requiredField]);
559
- }));
560
- return isEmpty(requiredFieldErrors) ?
561
- null : { [requiredField]: requiredFieldErrors };
562
- }));
563
- return isEmpty(requiringFieldErrors) ?
564
- null : { [requiringField]: requiringFieldErrors };
565
- }));
566
- return isEmpty(allErrors) ? null : allErrors;
567
- };
568
- }
569
- /**
570
- * 'minItems' validator
571
- *
572
- * Requires a form array to have a minimum number of values.
573
- *
574
- * // {number} minimumItems - minimum number of items allowed
575
- * // {IValidatorFn}
576
- */
577
- static minItems(minimumItems) {
578
- if (!hasValue(minimumItems)) {
579
- return JsonValidators.nullValidator;
580
- }
581
- return (control, invert = false) => {
582
- if (isEmpty(control.value)) {
583
- return null;
584
- }
585
- const currentItems = isArray(control.value) ? control.value.length : 0;
586
- const isValid = currentItems >= minimumItems;
587
- return xor(isValid, invert) ?
588
- null : { 'minItems': { minimumItems, currentItems } };
589
- };
590
- }
591
- /**
592
- * 'maxItems' validator
593
- *
594
- * Requires a form array to have a maximum number of values.
595
- *
596
- * // {number} maximumItems - maximum number of items allowed
597
- * // {IValidatorFn}
598
- */
599
- static maxItems(maximumItems) {
600
- if (!hasValue(maximumItems)) {
601
- return JsonValidators.nullValidator;
602
- }
603
- return (control, invert = false) => {
604
- const currentItems = isArray(control.value) ? control.value.length : 0;
605
- const isValid = currentItems <= maximumItems;
606
- return xor(isValid, invert) ?
607
- null : { 'maxItems': { maximumItems, currentItems } };
608
- };
609
- }
610
- /**
611
- * 'uniqueItems' validator
612
- *
613
- * Requires values in a form array to be unique.
614
- *
615
- * // {boolean = true} unique? - true to validate, false to disable
616
- * // {IValidatorFn}
617
- */
618
- static uniqueItems(unique = true) {
619
- if (!unique) {
620
- return JsonValidators.nullValidator;
621
- }
622
- return (control, invert = false) => {
623
- if (isEmpty(control.value)) {
624
- return null;
625
- }
626
- const sorted = control.value.slice().sort();
627
- const duplicateItems = [];
628
- for (let i = 1; i < sorted.length; i++) {
629
- if (sorted[i - 1] === sorted[i] && duplicateItems.includes(sorted[i])) {
630
- duplicateItems.push(sorted[i]);
631
- }
632
- }
633
- const isValid = !duplicateItems.length;
634
- return xor(isValid, invert) ?
635
- null : { 'uniqueItems': { duplicateItems } };
636
- };
637
- }
638
- /**
639
- * 'contains' validator
640
- *
641
- * TODO: Complete this validator
642
- *
643
- * Requires values in a form array to be unique.
644
- *
645
- * // {boolean = true} unique? - true to validate, false to disable
646
- * // {IValidatorFn}
647
- */
648
- static contains(requiredItem = true) {
649
- if (!requiredItem) {
650
- return JsonValidators.nullValidator;
651
- }
652
- return (control, invert = false) => {
653
- if (isEmpty(control.value) || !isArray(control.value)) {
654
- return null;
655
- }
656
- const currentItems = control.value;
657
- // const isValid = currentItems.some(item =>
658
- //
659
- // );
660
- const isValid = true;
661
- return xor(isValid, invert) ?
662
- null : { 'contains': { requiredItem, currentItems } };
663
- };
664
- }
665
- /**
666
- * No-op validator. Included for backward compatibility.
667
- */
668
- static nullValidator(control) {
669
- return null;
670
- }
671
- /**
672
- * Validator transformation functions:
673
- * composeAnyOf, composeOneOf, composeAllOf, composeNot,
674
- * compose, composeAsync
675
- *
676
- * TODO: Add composeAnyOfAsync, composeOneOfAsync,
677
- * composeAllOfAsync, composeNotAsync
678
- */
679
- /**
680
- * 'composeAnyOf' validator combination function
681
- *
682
- * Accepts an array of validators and returns a single validator that
683
- * evaluates to valid if any one or more of the submitted validators are
684
- * valid. If every validator is invalid, it returns combined errors from
685
- * all validators.
686
- *
687
- * // {IValidatorFn[]} validators - array of validators to combine
688
- * // {IValidatorFn} - single combined validator function
689
- */
690
- static composeAnyOf(validators) {
691
- if (!validators) {
692
- return null;
693
- }
694
- const presentValidators = validators.filter(isDefined);
695
- if (presentValidators.length === 0) {
696
- return null;
697
- }
698
- return (control, invert = false) => {
699
- const arrayOfErrors = _executeValidators(control, presentValidators, invert).filter(isDefined);
700
- const isValid = validators.length > arrayOfErrors.length;
701
- return xor(isValid, invert) ?
702
- null : _mergeObjects(...arrayOfErrors, { 'anyOf': !invert });
703
- };
704
- }
705
- /**
706
- * 'composeOneOf' validator combination function
707
- *
708
- * Accepts an array of validators and returns a single validator that
709
- * evaluates to valid only if exactly one of the submitted validators
710
- * is valid. Otherwise returns combined information from all validators,
711
- * both valid and invalid.
712
- *
713
- * // {IValidatorFn[]} validators - array of validators to combine
714
- * // {IValidatorFn} - single combined validator function
715
- */
716
- static composeOneOf(validators) {
717
- if (!validators) {
718
- return null;
719
- }
720
- const presentValidators = validators.filter(isDefined);
721
- if (presentValidators.length === 0) {
722
- return null;
723
- }
724
- return (control, invert = false) => {
725
- const arrayOfErrors = _executeValidators(control, presentValidators);
726
- const validControls = validators.length - arrayOfErrors.filter(isDefined).length;
727
- const isValid = validControls === 1;
728
- if (xor(isValid, invert)) {
729
- return null;
730
- }
731
- const arrayOfValids = _executeValidators(control, presentValidators, invert);
732
- return _mergeObjects(...arrayOfErrors, ...arrayOfValids, { 'oneOf': !invert });
733
- };
734
- }
735
- /**
736
- * 'composeAllOf' validator combination function
737
- *
738
- * Accepts an array of validators and returns a single validator that
739
- * evaluates to valid only if all the submitted validators are individually
740
- * valid. Otherwise it returns combined errors from all invalid validators.
741
- *
742
- * // {IValidatorFn[]} validators - array of validators to combine
743
- * // {IValidatorFn} - single combined validator function
744
- */
745
- static composeAllOf(validators) {
746
- if (!validators) {
747
- return null;
748
- }
749
- const presentValidators = validators.filter(isDefined);
750
- if (presentValidators.length === 0) {
751
- return null;
752
- }
753
- return (control, invert = false) => {
754
- const combinedErrors = _mergeErrors(_executeValidators(control, presentValidators, invert));
755
- const isValid = combinedErrors === null;
756
- return (xor(isValid, invert)) ?
757
- null : _mergeObjects(combinedErrors, { 'allOf': !invert });
758
- };
759
- }
760
- /**
761
- * 'composeNot' validator inversion function
762
- *
763
- * Accepts a single validator function and inverts its result.
764
- * Returns valid if the submitted validator is invalid, and
765
- * returns invalid if the submitted validator is valid.
766
- * (Note: this function can itself be inverted
767
- * - e.g. composeNot(composeNot(validator)) -
768
- * but this can be confusing and is therefore not recommended.)
769
- *
770
- * // {IValidatorFn[]} validators - validator(s) to invert
771
- * // {IValidatorFn} - new validator function that returns opposite result
772
- */
773
- static composeNot(validator) {
774
- if (!validator) {
775
- return null;
776
- }
777
- return (control, invert = false) => {
778
- if (isEmpty(control.value)) {
779
- return null;
780
- }
781
- const error = validator(control, !invert);
782
- const isValid = error === null;
783
- return (xor(isValid, invert)) ?
784
- null : _mergeObjects(error, { 'not': !invert });
785
- };
786
- }
787
- /**
788
- * 'compose' validator combination function
789
- *
790
- * // {IValidatorFn[]} validators - array of validators to combine
791
- * // {IValidatorFn} - single combined validator function
792
- */
793
- static compose(validators) {
794
- if (!validators) {
795
- return null;
796
- }
797
- const presentValidators = validators.filter(isDefined);
798
- if (presentValidators.length === 0) {
799
- return null;
800
- }
801
- return (control, invert = false) => _mergeErrors(_executeValidators(control, presentValidators, invert));
802
- }
803
- /**
804
- * 'composeAsync' async validator combination function
805
- *
806
- * // {AsyncIValidatorFn[]} async validators - array of async validators
807
- * // {AsyncIValidatorFn} - single combined async validator function
808
- */
809
- static composeAsync(validators) {
810
- if (!validators) {
811
- return null;
812
- }
813
- const presentValidators = validators.filter(isDefined);
814
- if (presentValidators.length === 0) {
815
- return null;
816
- }
817
- return (control) => {
818
- const observables = _executeAsyncValidators(control, presentValidators).map(toObservable);
819
- return map.call(forkJoin(observables), _mergeErrors);
820
- };
821
- }
822
- // Additional angular validators (not used by Angualr JSON Schema Form)
823
- // From https://github.com/angular/angular/blob/master/packages/forms/src/validators.ts
824
- /**
825
- * Validator that requires controls to have a value greater than a number.
826
- */
827
- static min(min) {
828
- if (!hasValue(min)) {
829
- return JsonValidators.nullValidator;
830
- }
831
- return (control) => {
832
- // don't validate empty values to allow optional controls
833
- if (isEmpty(control.value) || isEmpty(min)) {
834
- return null;
835
- }
836
- const value = parseFloat(control.value);
837
- const actual = control.value;
838
- // Controls with NaN values after parsing should be treated as not having a
839
- // minimum, per the HTML forms spec: https://www.w3.org/TR/html5/forms.html#attr-input-min
840
- return isNaN(value) || value >= min ? null : { 'min': { min, actual } };
841
- };
842
- }
843
- /**
844
- * Validator that requires controls to have a value less than a number.
845
- */
846
- static max(max) {
847
- if (!hasValue(max)) {
848
- return JsonValidators.nullValidator;
849
- }
850
- return (control) => {
851
- // don't validate empty values to allow optional controls
852
- if (isEmpty(control.value) || isEmpty(max)) {
853
- return null;
854
- }
855
- const value = parseFloat(control.value);
856
- const actual = control.value;
857
- // Controls with NaN values after parsing should be treated as not having a
858
- // maximum, per the HTML forms spec: https://www.w3.org/TR/html5/forms.html#attr-input-max
859
- return isNaN(value) || value <= max ? null : { 'max': { max, actual } };
860
- };
861
- }
862
- /**
863
- * Validator that requires control value to be true.
864
- */
865
- static requiredTrue(control) {
866
- if (!control) {
867
- return JsonValidators.nullValidator;
868
- }
869
- return control.value === true ? null : { 'required': true };
870
- }
871
- /**
872
- * Validator that performs email validation.
873
- */
874
- static email(control) {
875
- if (!control) {
876
- return JsonValidators.nullValidator;
877
- }
878
- const EMAIL_REGEXP =
879
- // tslint:disable-next-line:max-line-length
880
- /^(?=.{1,254}$)(?=.{1,64}@)[-!#$%&'*+/0-9=?A-Z^_`a-z{|}~]+(\.[-!#$%&'*+/0-9=?A-Z^_`a-z{|}~]+)*@[A-Za-z0-9]([A-Za-z0-9-]{0,61}[A-Za-z0-9])?(\.[A-Za-z0-9]([A-Za-z0-9-]{0,61}[A-Za-z0-9])?)*$/;
881
- return EMAIL_REGEXP.test(control.value) ? null : { 'email': true };
882
- }
883
- }
884
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoianNvbi52YWxpZGF0b3JzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvbmctZm9ybXdvcmtzLWNvcmUvc3JjL2xpYi9zaGFyZWQvanNvbi52YWxpZGF0b3JzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sT0FBTyxNQUFNLGdCQUFnQixDQUFDO0FBQ3JDLE9BQU8sRUFDTCx1QkFBdUIsRUFDdkIsa0JBQWtCLEVBQ2xCLFlBQVksRUFDWixhQUFhLEVBRWIsT0FBTyxFQUNQLFFBQVEsRUFDUixPQUFPLEVBQ1AsU0FBUyxFQUNULFNBQVMsRUFDVCxPQUFPLEVBQ1AsUUFBUSxFQUNSLFFBQVEsRUFDUixNQUFNLEVBR04sZ0JBQWdCLEVBQ2hCLFlBQVksRUFDWixHQUFHLEVBQ0YsTUFBTSx1QkFBdUIsQ0FBQztBQUVqQyxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDbEQsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUNoQyxPQUFPLEVBQXlCLHFCQUFxQixFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFDeEYsT0FBTyxFQUFFLEdBQUcsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBSXJDOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0E4RUc7QUFDSCxNQUFNLE9BQU8sY0FBYztJQXNDekIsTUFBTSxDQUFDLFFBQVEsQ0FBQyxLQUErQjtRQUM3QyxJQUFJLEtBQUssS0FBSyxTQUFTLEVBQUUsQ0FBQztZQUFDLEtBQUssR0FBRyxJQUFJLENBQUM7UUFBQyxDQUFDO1FBQzFDLFFBQVEsS0FBSyxFQUFFLENBQUM7WUFDZCxLQUFLLElBQUksRUFBRSxtREFBbUQ7Z0JBQzVELE9BQU8sQ0FBQyxPQUF3QixFQUFFLE1BQU0sR0FBRyxLQUFLLEVBQXlCLEVBQUU7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TSxNQUFNLEdBQUcsT0FBTyxDQUFDLEtBQUssQ0FBQztZQUM3QiwyRUFBMkU7WUFDM0UsMEZBQTBGO1lBQzFGLE9BQU8sS0FBSyxDQUFDLEtBQUssQ0FBQyxJQUFJLEtBQUssSUFBSSxHQUFHLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxLQUFLLEVBQUUsRUFBRSxHQUFHLEVBQUUsTUFBTSxFQUFFLEVBQUUsQ0FBQztRQUMxRSxDQUFDLENBQUM7SUFDSixDQUFDO0lBRUQ7O09BRUc7SUFDSCxNQUFNLENBQUMsWUFBWSxDQUFDLE9BQXdCO1FBQzFDLElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQztZQUFDLE9BQU8sY0FBYyxDQUFDLGFBQWEsQ0FBQztRQUFDLENBQUM7UUFDdEQsT0FBTyxPQUFPLENBQUMsS0FBSyxLQUFLLElBQUksQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFLFVBQVUsRUFBRSxJQUFJLEVBQUUsQ0FBQztJQUM5RCxDQUFDO0lBRUQ7O09BRUc7SUFDSCxNQUFNLENBQUMsS0FBSyxDQUFDLE9BQXdCO1FBQ25DLElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQztZQUFDLE9BQU8sY0FBYyxDQUFDLGFBQWEsQ0FBQztRQUFDLENBQUM7UUFDdEQsTUFBTSxZQUFZO1FBQ2hCLDJDQUEyQztRQUMzQyw0TEFBNEwsQ0FBQztRQUMvTCxPQUFPLFlBQVksQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsT0FBTyxFQUFFLElBQUksRUFBRSxDQUFDO0lBQ3JFLENBQUM7Q0FDRiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBpc0VxdWFsIGZyb20gJ2xvZGFzaC9pc0VxdWFsJztcclxuaW1wb3J0IHtcclxuICBfZXhlY3V0ZUFzeW5jVmFsaWRhdG9ycyxcclxuICBfZXhlY3V0ZVZhbGlkYXRvcnMsXHJcbiAgX21lcmdlRXJyb3JzLFxyXG4gIF9tZXJnZU9iamVjdHMsXHJcbiAgQXN5bmNJVmFsaWRhdG9yRm4sXHJcbiAgZ2V0VHlwZSxcclxuICBoYXNWYWx1ZSxcclxuICBpc0FycmF5LFxyXG4gIGlzQm9vbGVhbixcclxuICBpc0RlZmluZWQsXHJcbiAgaXNFbXB0eSxcclxuICBpc051bWJlcixcclxuICBpc1N0cmluZyxcclxuICBpc1R5cGUsXHJcbiAgSVZhbGlkYXRvckZuLFxyXG4gIFNjaGVtYVByaW1pdGl2ZVR5cGUsXHJcbiAgdG9KYXZhU2NyaXB0VHlwZSxcclxuICB0b09ic2VydmFibGUsXHJcbiAgeG9yXHJcbiAgfSBmcm9tICcuL3ZhbGlkYXRvci5mdW5jdGlvbnMnO1xyXG5pbXBvcnQgeyBBYnN0cmFjdENvbnRyb2wsIFZhbGlkYXRpb25FcnJvcnMsIFZhbGlkYXRvckZuIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xyXG5pbXBvcnQgeyBmb3JFYWNoQ29weSB9IGZyb20gJy4vdXRpbGl0eS5mdW5jdGlvbnMnO1xyXG5pbXBvcnQgeyBmb3JrSm9pbiB9IGZyb20gJ3J4anMnO1xyXG5pbXBvcnQgeyBKc29uU2NoZW1hRm9ybWF0TmFtZXMsIGpzb25TY2hlbWFGb3JtYXRUZXN0cyB9IGZyb20gJy4vZm9ybWF0LXJlZ2V4LmNvbnN0YW50cyc7XHJcbmltcG9ydCB7IG1hcCB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcclxuXHJcblxyXG5cclxuLyoqXHJcbiAqICdKc29uVmFsaWRhdG9ycycgY2xhc3NcclxuICpcclxuICogUHJvdmlkZXMgYW4gZXh0ZW5kZWQgc2V0IG9mIHZhbGlkYXRvcnMgdG8gYmUgdXNlZCBieSBmb3JtIGNvbnRyb2xzLFxyXG4gKiBjb21wYXRpYmxlIHdpdGggc3RhbmRhcmQgSlNPTiBTY2hlbWEgdmFsaWRhdGlvbiBvcHRpb25zLlxyXG4gKiBodHRwOi8vanNvbi1zY2hlbWEub3JnL2xhdGVzdC9qc29uLXNjaGVtYS12YWxpZGF0aW9uLmh0bWxcclxuICpcclxuICogTm90ZTogVGhpcyBsaWJyYXJ5IGlzIGRlc2lnbmVkIGFzIGEgZHJvcC1pbiByZXBsYWNlbWVudCBmb3IgdGhlIEFuZ3VsYXJcclxuICogVmFsaWRhdG9ycyBsaWJyYXJ5LCBhbmQgZXhjZXB0IGZvciBvbmUgc21hbGwgYnJlYWtpbmcgY2hhbmdlIHRvIHRoZSAncGF0dGVybidcclxuICogdmFsaWRhdG9yIChkZXNjcmliZWQgYmVsb3cpIGl0IGNhbiBldmVuIGJlIGltcG9ydGVkIGFzIGEgc3Vic3RpdHV0ZSwgbGlrZSBzbzpcclxuICpcclxuICogICBpbXBvcnQgeyBKc29uVmFsaWRhdG9ycyBhcyBWYWxpZGF0b3JzIH0gZnJvbSAnanNvbi12YWxpZGF0b3JzJztcclxuICpcclxuICogYW5kIGl0IHNob3VsZCB3b3JrIHdpdGggZXhpc3RpbmcgY29kZSBhcyBhIGNvbXBsZXRlIHJlcGxhY2VtZW50LlxyXG4gKlxyXG4gKiBUaGUgb25lIGV4Y2VwdGlvbiBpcyB0aGUgJ3BhdHRlcm4nIHZhbGlkYXRvciwgd2hpY2ggaGFzIGJlZW4gY2hhbmdlZCB0b1xyXG4gKiBtYXRjaGUgcGFydGlhbCB2YWx1ZXMgYnkgZGVmYXVsdCAodGhlIHN0YW5kYXJkICdwYXR0ZXJuJyB2YWxpZGF0b3Igd3JhcHBlZFxyXG4gKiBhbGwgcGF0dGVybnMgaW4gJ14nIGFuZCAnJCcsIGZvcmNpbmcgdGhlbSB0byBhbHdheXMgbWF0Y2ggYW4gZW50aXJlIHZhbHVlKS5cclxuICogSG93ZXZlciwgdGhlIG9sZCBiZWhhdmlvciBjYW4gYmUgcmVzdG9yZWQgYnkgc2ltcGx5IGFkZGluZyAnXicgYW5kICckJ1xyXG4gKiBhcm91bmQgeW91ciBwYXR0ZXJucywgb3IgYnkgcGFzc2luZyBhbiBvcHRpb25hbCBzZWNvbmQgcGFyYW1ldGVyIG9mIFRSVUUuXHJcbiAqIFRoaXMgY2hhbmdlIGlzIHRvIG1ha2UgdGhlICdwYXR0ZXJuJyB2YWxpZGF0b3IgbWF0Y2ggdGhlIGJlaGF2aW9yIG9mIGFcclxuICogSlNPTiBTY2hlbWEgcGF0dGVybiwgd2hpY2ggYWxsb3dzIHBhcnRpYWwgbWF0Y2hlcywgcmF0aGVyIHRoYW4gdGhlIGJlaGF2aW9yXHJcbiAqIG9mIGFuIEhUTUwgaW5wdXQgY29udHJvbCBwYXR0ZXJuLCB3aGljaCBkb2VzIG5vdC5cclxuICpcclxuICogVGhpcyBsaWJyYXJ5IHJlcGxhY2VzIEFuZ3VsYXIncyB2YWxpZGF0b3JzIGFuZCBjb21iaW5hdGlvbiBmdW5jdGlvbnNcclxuICogd2l0aCB0aGUgZm9sbG93aW5nIHZhbGlkYXRvcnMgYW5kIHRyYW5zZm9ybWF0aW9uIGZ1bmN0aW9uczpcclxuICpcclxuICogVmFsaWRhdG9yczpcclxuICogICBGb3IgYWxsIGZvcm1Db250cm9sczogICAgIHJlcXVpcmVkICgqKSwgdHlwZSwgZW51bSwgY29uc3RcclxuICogICBGb3IgdGV4dCBmb3JtQ29udHJvbHM6ICAgIG1pbkxlbmd0aCAoKiksIG1heExlbmd0aCAoKiksIHBhdHRlcm4gKCopLCBmb3JtYXRcclxuICogICBGb3IgbnVtZXJpYyBmb3JtQ29udHJvbHM6IG1heGltdW0sIGV4Y2x1c2l2ZU1heGltdW0sXHJcbiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtaW5pbXVtLCBleGNsdXNpdmVNaW5pbXVtLCBtdWx0aXBsZU9mXHJcbiAqICAgRm9yIGZvcm1Hcm91cCBvYmplY3RzOiAgICBtaW5Qcm9wZXJ0aWVzLCBtYXhQcm9wZXJ0aWVzLCBkZXBlbmRlbmNpZXNcclxuICogICBGb3IgZm9ybUFycmF5IGFycmF5czogICAgIG1pbkl0ZW1zLCBtYXhJdGVtcywgdW5pcXVlSXRlbXMsIGNvbnRhaW5zXHJcbiAqICAgTm90IHVzZWQgYnkgSlNPTiBTY2hlbWE6ICBtaW4gKCopLCBtYXggKCopLCByZXF1aXJlZFRydWUgKCopLCBlbWFpbCAoKilcclxuICogKFZhbGlkYXRvcnMgb3JpZ2luYWxseSBpbmNsdWRlZCB3aXRoIEFuZ3VsYXIgYXJlIG1ha2VkIHdpdGggKCopLilcclxuICpcclxuICogTk9URSAvIFRPRE86IFRoZSBkZXBlbmRlbmNpZXMgdmFsaWRhdG9yIGlzIG5vdCBjb21wbGV0ZS5cclxuICogTk9URSAvIFRPRE86IFRoZSBjb250YWlucyB2YWxpZGF0b3IgaXMgbm90IGNvbXBsZXRlLlxyXG4gKlxyXG4gKiBWYWxpZGF0b3JzIG5vdCB1c2VkIGJ5IEpTT04gU2NoZW1hIChidXQgaW5jbHVkZWQgZm9yIGNvbXBhdGliaWxpdHkpXHJcbiAqIGFuZCB0aGVpciBKU09OIFNjaGVtYSBlcXVpdmFsZW50czpcclxuICpcclxuICogICBBbmd1bGFyIHZhbGlkYXRvciB8IEpTT04gU2NoZW1hIGVxdWl2YWxlbnRcclxuICogICAtLS0tLS0tLS0tLS0tLS0tLS18LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuICogICAgIG1pbihudW1iZXIpICAgICB8ICAgbWluaW11bShudW1iZXIpXHJcbiAqICAgICBtYXgobnVtYmVyKSAgICAgfCAgIG1heGltdW0obnVtYmVyKVxyXG4gKiAgICAgcmVxdWlyZWRUcnVlKCkgIHwgICBjb25zdCh0cnVlKVxyXG4gKiAgICAgZW1haWwoKSAgICAgICAgIHwgICBmb3JtYXQoJ2VtYWlsJylcclxuICpcclxuICogVmFsaWRhdG9yIHRyYW5zZm9ybWF0aW9uIGZ1bmN0aW9uczpcclxuICogICBjb21wb3NlQW55T2YsIGNvbXBvc2VPbmVPZiwgY29tcG9zZUFsbE9mLCBjb21wb3NlTm90XHJcbiAqIChBbmd1bGFyJ3Mgb3JpZ2luYWwgY29tYmluYXRpb24gZnVuY2l0b24sICdjb21wb3NlJywgaXMgYWxzbyBpbmNsdWRlZCBmb3JcclxuICogYmFja3dhcmQgY29tcGF0aWJpbGl0eSwgdGhvdWdoIGl0IGlzIGZ1bmN0aW9uYWxseSBlcXVpdmFsZW50IHRvIGNvbXBvc2VBbGxPZixcclxuICogYXNzaWRlIGZyb20gaXRzIG1vcmUgZ2VuZXJpYyBlcnJvciBtZXNzYWdlLilcclxuICpcclxuICogQWxsIHZhbGlkYXRvcnMgaGF2ZSBhbHNvIGJlZW4gZXh0ZW5kZWQgdG8gYWNjZXB0IGFuIG9wdGlvbmFsIHNlY29uZCBhcmd1bWVudFxyXG4gKiB3aGljaCwgaWYgcGFzc2VkIGEgVFJVRSB2YWx1ZSwgY2F1c2VzIHRoZSB2YWxpZGF0b3IgdG8gcGVyZm9ybSB0aGUgb3Bwb3NpdGVcclxuICogb2YgaXRzIG9yaWdpbmFsIGZpbmN0aW9uLiAoVGhpcyBpcyB1c2VkIGludGVybmFsbHkgdG8gZW5hYmxlICdub3QnIGFuZFxyXG4gKiAnY29tcG9zZU9uZU9mJyB0byBmdW5jdGlvbiBhbmQgcmV0dXJuIHVzZWZ1bCBlcnJvciBtZXNzYWdlcy4pXHJcbiAqXHJcbiAqIFRoZSAncmVxdWlyZWQnIHZhbGlkYXRvciBoYXMgYWxzbyBiZWVuIG92ZXJsb2FkZWQgc28gdGhhdCBpZiBjYWxsZWQgd2l0aFxyXG4gKiBhIGJvb2xlYW4gcGFyYW1ldGVyIChvciBubyBwYXJhbWV0ZXJzKSBpdCByZXR1cm5zIHRoZSBvcmlnaW5hbCB2YWxpZGF0b3JcclxuICogZnVuY3Rpb24gKHJhdGhlciB0aGFuIGV4ZWN1dGluZyBpdCkuIEhvd2V2ZXIsIGlmIGl0IGlzIGNhbGxlZCB3aXRoIGFuXHJcbiAqIEFic3RyYWN0Q29udHJvbCBwYXJhbWV0ZXIgKGFzIHdhcyBwcmV2aW91c2x5IHJlcXVpcmVkKSwgaXQgYmVoYXZlc1xyXG4gKiBleGFjdGx5IGFzIGJlZm9yZS5cclxuICpcclxuICogVGhpcyBlbmFibGVzIGFsbCB2YWxpZGF0b3JzIChpbmNsdWRpbmcgJ3JlcXVpcmVkJykgdG8gYmUgY29uc3RydWN0ZWQgaW5cclxuICogZXhhY3RseSB0aGUgc2FtZSB3YXksIHNvIHRoZXkgY2FuIGJlIGF1dG9tYXRpY2FsbHkgYXBwbGllZCB1c2luZyB0aGVcclxuICogZXF1aXZhbGVudCBrZXkgbmFtZXMgYW5kIHZhbHVlcyB0YWtlbiBkaXJlY3RseSBmcm9tIGEgSlNPTiBTY2hlbWEuXHJcbiAqXHJcbiAqIFRoaXMgc291cmNlIGNvZGUgaXMgcGFydGlhbGx5IGRlcml2ZWQgZnJvbSBBbmd1bGFyLFxyXG4gKiB3aGljaCBpcyBDb3B5cmlnaHQgKGMpIDIwMTQtMjAxNyBHb29nbGUsIEluYy5cclxuICogVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgdGhlcmVmb3JlIGdvdmVybmVkIGJ5IHRoZSBzYW1lIE1JVC1zdHlsZSBsaWNlbnNlXHJcbiAqIHRoYXQgY2FuIGJlIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUgYXQgaHR0cHM6Ly9hbmd1bGFyLmlvL2xpY2Vuc2VcclxuICpcclxuICogT3JpZ2luYWwgQW5ndWxhciBWYWxpZGF0b3JzOlxyXG4gKiBodHRwczovL2dpdGh1Yi5jb20vYW5ndWxhci9hbmd1bGFyL2Jsb2IvbWFzdGVyL3BhY2thZ2VzL2Zvcm1zL3NyYy92YWxpZGF0b3JzLnRzXHJcbiAqL1xyXG5leHBvcnQgY2xhc3MgSnNvblZhbGlkYXRvcnMge1xyXG5cclxuICAvKipcclxuICAgKiBWYWxpZGF0b3IgZnVuY3Rpb25zOlxyXG4gICAqXHJcbiAgICogRm9yIGFsbCBmb3JtQ29udHJvbHM6ICAgICByZXF1aXJlZCwgdHlwZSwgZW51bSwgY29uc3RcclxuICAgKiBGb3IgdGV4dCBmb3JtQ29udHJvbHM6ICAgIG1pbkxlbmd0aCwgbWF4TGVuZ3RoLCBwYXR0ZXJuLCBmb3JtYXRcclxuICAgKiBGb3IgbnVtZXJpYyBmb3JtQ29udHJvbHM6IG1heGltdW0sIGV4Y2x1c2l2ZU1heGltdW0sXHJcbiAgICogICAgICAgICAgICAgICAgICAgICAgICAgICBtaW5pbXVtLCBleGNsdXNpdmVNaW5pbXVtLCBtdWx0aXBsZU9mXHJcbiAgICogRm9yIGZvcm1Hcm91cCBvYmplY3RzOiAgICBtaW5Qcm9wZXJ0aWVzLCBtYXhQcm9wZXJ0aWVzLCBkZXBlbmRlbmNpZXNcclxuICAgKiBGb3IgZm9ybUFycmF5IGFycmF5czogICAgIG1pbkl0ZW1zLCBtYXhJdGVtcywgdW5pcXVlSXRlbXMsIGNvbnRhaW5zXHJcbiAgICpcclxuICAgKiBUT0RPOiBmaW5pc2ggZGVwZW5kZW5jaWVzIHZhbGlkYXRvclxyXG4gICAqL1xyXG5cclxuICAvKipcclxuICAgKiAncmVxdWlyZWQnIHZhbGlkYXRvclxyXG4gICAqXHJcbiAgICogVGhpcyB2YWxpZGF0b3IgaXMgb3ZlcmxvYWRlZCwgY29tcGFyZWQgdG8gdGhlIGRlZmF1bHQgcmVxdWlyZWQgdmFsaWRhdG9yLlxyXG4gICAqIElmIGNhbGxlZCB3aXRoIG5vIHBhcmFtZXRlcnMsIG9yIFRSVUUsIHRoaXMgdmFsaWRhdG9yIHJldHVybnMgdGhlXHJcbiAgICogJ3JlcXVpcmVkJyB2YWxpZGF0b3IgZnVuY3Rpb24gKHJhdGhlciB0aGFuIGV4ZWN1dGluZyBpdCkuIFRoaXMgbWF0Y2hlc1xyXG4gICAqIHRoZSBiZWhhdmlvciBvZiBhbGwgb3RoZXIgdmFsaWRhdG9ycyBpbiB0aGlzIGxpYnJhcnkuXHJcbiAgICpcclxuICAgKiBJZiB0aGlzIHZhbGlkYXRvciBpcyBjYWxsZWQgd2l0aCBhbiBBYnN0cmFjdENvbnRyb2wgcGFyYW1ldGVyXHJcbiAgICogKGFzIHdhcyBwcmV2aW91c2x5IHJlcXVpcmVkKSBpdCBiZWhhdmVzIHRoZSBzYW1lIGFzIEFuZ3VsYXIncyBkZWZhdWx0XHJcbiAgICogcmVxdWlyZWQgdmFsaWRhdG9yLCBhbmQgcmV0dXJucyBhbiBlcnJvciBpZiB0aGUgY29udHJvbCBpcyBlbXB0eS5cclxuICAgKlxyXG4gICAqIE9sZCBiZWhhdmlvcjogKGlmIGlucHV0IHR5cGUgPSBBYnN0cmFjdENvbnRyb2wpXHJcbiAgICogLy8ge0Fic3RyYWN0Q29udHJvbH0gY29udHJvbCAtIHJlcXVpcmVkIGNvbnRyb2xcclxuICAgKiAvLyB7e1trZXk6IHN0cmluZ106IGJvb2xlYW59fSAtIHJldHVybnMgZXJyb3IgbWVzc2FnZSBpZiBubyBpbnB1dFxyXG4gICAqXHJcbiAgICogTmV3IGJlaGF2aW9yOiAoaWYgbm8gaW5wdXQsIG9yIGlucHV0IHR5cGUgPSBib29sZWFuKVxyXG4gICAqIC8vIHtib29sZWFuID0gdHJ1ZX0gcmVxdWlyZWQ/IC0gdHJ1ZSB0byB2YWxpZGF0ZSwgZmFsc2UgdG8gZGlzYWJsZVxyXG4gICAqIC8vIHtJVmFsaWRhdG9yRm59IC0gcmV0dXJucyB0aGUgJ3JlcXVpcmVkJyB2YWxpZGF0b3IgZnVuY3Rpb24gaXRzZWxmXHJcbiAgICovXHJcbiAgc3RhdGljIHJlcXVpcmVkKGlucHV0OiBBYnN0cmFjdENvbnRyb2wpOiBWYWxpZGF0aW9uRXJyb3JzfG51bGw7XHJcbiAgc3RhdGljIHJlcXVpcmVkKGlucHV0PzogYm9vbGVhbik6IElWYWxpZGF0b3JGbjtcclxuXHJcbiAgc3RhdGljIHJlcXVpcmVkKGlucHV0PzogQWJzdHJhY3RDb250cm9sfGJvb2xlYW4pOiBWYWxpZGF0aW9uRXJyb3JzfG51bGx8SVZhbGlkYXRvckZuIHtcclxuICAgIGlmIChpbnB1dCA9PT0gdW5kZWZpbmVkKSB7IGlucHV0ID0gdHJ1ZTsgfVxyXG4gICAgc3dpdGNoIChpbnB1dCkge1xyXG4gICAgICBjYXNlIHRydWU6IC8vIFJldHVybiByZXF1aXJlZCBmdW5jdGlvbiAoZG8gbm90IGV4ZWN1dGUgaXQgeWV0KVxyXG4gICAgICAgIHJldHVybiAoY29udHJvbDogQWJzdHJhY3RDb250cm9sLCBpbnZlcnQgPSBmYWxzZSk6IFZhbGlkYXRpb25FcnJvcnN8bnVsbCA9PiB7XHJcbiAgICAgICAgICBpZiAoaW52ZXJ0KSB7IHJldHVybiBudWxsOyB9IC8vIGlmIG5vdCByZXF1aXJlZCwgYWx3YXlzIHJldHVybiB2YWxpZFxyXG4gICAgICAgICAgcmV0dXJuIGhhc1ZhbHVlKGNvbnRyb2wudmFsdWUpID8gbnVsbCA6IHsgJ3JlcXVpcmVkJzogdHJ1ZSB9O1xyXG4gICAgICAgIH07XHJcbiAgICAgIGNhc2UgZmFsc2U6IC8vIERvIG5vdGhpbmcgKGlmIGZpZWxkIGlzIG5vdCByZXF1aXJlZCwgaXQgaXMgYWx3YXlzIHZhbGlkKVxyXG4gICAgICAgIHJldHVybiBKc29uVmFsaWRhdG9ycy5udWxsVmFsaWRhdG9yO1xyXG4gICAgICBkZWZhdWx0OiAvLyBFeGVjdXRlIHJlcXVpcmVkIGZ1bmN0aW9uXHJcbiAgICAgICAgcmV0dXJuIGhhc1ZhbHVlKCg8QWJzdHJhY3RDb250cm9sPmlucHV0KS52YWx1ZSkgPyBudWxsIDogeyAncmVxdWlyZWQnOiB0cnVlIH07XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiAndHlwZScgdmFsaWRhdG9yXHJcbiAgICpcclxuICAgKiBSZXF1aXJlcyBhIGNvbnRyb2wgdG8gb25seSBhY2NlcHQgdmFsdWVzIG9mIGEgc3BlY2lmaWVkIHR5cGUsXHJcbiAgICogb3Igb25lIG9mIGFuIGFycmF5IG9mIHR5cGVzLlxyXG4gICAqXHJcbiAgICogTm90ZTogU2NoZW1hUHJpbWl0aXZlVHlwZSA9ICdzdHJpbmcnfCdudW1iZXInfCdpbnRlZ2VyJ3wnYm9vbGVhbid8J251bGwnXHJcbiAgICpcclxuICAgKiAvLyB7U2NoZW1hUHJpbWl0aXZlVHlwZXxTY2hlbWFQcmltaXRpdmVUeXBlW119IHR5cGUgLSB0eXBlKHMpIHRvIGFjY2VwdFxyXG4gICAqIC8vIHtJVmFsaWRhdG9yRm59XHJcbiAgICovXHJcbiAgc3RhdGljIHR5cGUocmVxdWlyZWRUeXBlOiBTY2hlbWFQcmltaXRpdmVUeXBlfFNjaGVtYVByaW1pdGl2ZVR5cGVbXSk6IElWYWxpZGF0b3JGbiB7XHJcbiAgICBpZiAoIWhhc1ZhbHVlKHJlcXVpcmVkVHlwZSkpIHsgcmV0dXJuIEpzb25WYWxpZGF0b3JzLm51bGxWYWxpZGF0b3I7IH1cclxuICAgIHJldHVybiAoY29udHJvbDogQWJzdHJhY3RDb250cm9sLCBpbnZlcnQgPSBmYWxzZSk6IFZhbGlkYXRpb25FcnJvcnN8bnVsbCA9PiB7XHJcbiAgICAgIGlmIChpc0VtcHR5KGNvbnRyb2wudmFsdWUpKSB7IHJldHVybiBudWxsOyB9XHJcbiAgICAgIGNvbnN0IGN1cnJlbnRWYWx1ZTogYW55ID0gY29udHJvbC52YWx1ZTtcclxuICAgICAgY29uc3QgaXNWYWxpZCA9IGlzQXJyYXkocmVxdWlyZWRUeXBlKSA/XHJcbiAgICAgICAgKDxTY2hlbWFQcmltaXRpdmVUeXBlW10+cmVxdWlyZWRUeXBlKS5zb21lKHR5cGUgPT4gaXNUeXBlKGN1cnJlbnRWYWx1ZSwgdHlwZSkpIDpcclxuICAgICAgICBpc1R5cGUoY3VycmVudFZhbHVlLCA8U2NoZW1hUHJpbWl0aXZlVHlwZT5yZXF1aXJlZFR5cGUpO1xyXG4gICAgICByZXR1cm4geG9yKGlzVmFsaWQsIGludmVydCkgP1xyXG4gICAgICAgIG51bGwgOiB7ICd0eXBlJzogeyByZXF1aXJlZFR5cGUsIGN1cnJlbnRWYWx1ZSB9IH07XHJcbiAgICB9O1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogJ2VudW0nIHZhbGlkYXRvclxyXG4gICAqXHJcbiAgICogUmVxdWlyZXMgYSBjb250cm9sIHRvIGhhdmUgYSB2YWx1ZSBmcm9tIGFuIGVudW1lcmF0ZWQgbGlzdCBvZiB2YWx1ZXMuXHJcbiAgICpcclxuICAgKiBDb252ZXJ0cyB0eXBlcyBhcyBuZWVkZWQgdG8gYWxsb3cgc3RyaW5nIGlucHV0cyB0byBzdGlsbCBjb3JyZWN0bHlcclxuICAgKiBtYXRjaCBudW1iZXIsIGJvb2xlYW4sIGFuZCBudWxsIGVudW0gdmFsdWVzLlxyXG4gICAqXHJcbiAgICogLy8ge2FueVtdfSBhbGxvd2VkVmFsdWVzIC0gYXJyYXkgb2YgYWNjZXB0YWJsZSB2YWx1ZXNcclxuICAgKiAvLyB7SVZhbGlkYXRvckZufVxyXG4gICAqL1xyXG4gIHN0YXRpYyBlbnVtKGFsbG93ZWRWYWx1ZXM6IGFueVtdKTogSVZhbGlkYXRvckZuIHtcclxuICAgIGlmICghaXNBcnJheShhbGxvd2VkVmFsdWVzKSkgeyByZXR1cm4gSnNvblZhbGlkYXRvcnMubnVsbFZhbGlkYXRvcjsgfVxyXG4gICAgcmV0dXJuIChjb250cm9sOiBBYnN0cmFjdENvbnRyb2wsIGludmVydCA9IGZhbHNlKTogVmFsaWRhdGlvbkVycm9yc3xudWxsID0+IHtcclxuICAgICAgaWYgKGlzRW1wdHkoY29udHJvbC52YWx1ZSkpIHsgcmV0dXJuIG51bGw7IH1cclxuICAgICAgY29uc3QgY3VycmVudFZhbHVlOiBhbnkgPSBjb250cm9sLnZhbHVlO1xyXG4gICAgICBjb25zdCBpc0VxdWFsVmFsID0gKGVudW1WYWx1ZSwgaW5wdXRWYWx1ZSkgPT5cclxuICAgICAgICBlbnVtVmFsdWUgPT09IGlucHV0VmFsdWUgfHxcclxuICAgICAgICAoaXNOdW1iZXIoZW51bVZhbHVlKSAmJiAraW5wdXRWYWx1ZSA9PT0gK2VudW1WYWx1ZSkgfHxcclxuICAgICAgICAoaXNCb29sZWFuKGVudW1WYWx1ZSwgJ3N0cmljdCcpICYmXHJcbiAgICAgICAgICB0b0phdmFTY3JpcHRUeXBlKGlucHV0VmFsdWUsICdib29sZWFuJykgPT09IGVudW1WYWx1ZSkgfHxcclxuICAgICAgICAoZW51bVZhbHVlID09PSBudWxsICYmICFoYXNWYWx1ZShpbnB1dFZhbHVlKSkgfHxcclxuICAgICAgICBpc0VxdWFsKGVudW1WYWx1ZSwgaW5wdXRWYWx1ZSk7XHJcbiAgICAgIGNvbnN0IGlzVmFsaWQgPSBpc0FycmF5KGN1cnJlbnRWYWx1ZSkgP1xyXG4gICAgICAgIGN1cnJlbnRWYWx1ZS5ldmVyeShpbnB1dFZhbHVlID0+IGFsbG93ZWRWYWx1ZXMuc29tZShlbnVtVmFsdWUgPT5cclxuICAgICAgICAgIGlzRXF1YWxWYWwoZW51bVZhbHVlLCBpbnB1dFZhbHVlKVxyXG4gICAgICAgICkpIDpcclxuICAgICAgICBhbGxvd2VkVmFsdWVzLnNvbWUoZW51bVZhbHVlID0+IGlzRXF1YWxWYWwoZW51bVZhbHVlLCBjdXJyZW50VmFsdWUpKTtcclxuICAgICAgcmV0dXJuIHhvcihpc1ZhbGlkLCBpbnZlcnQpID9cclxuICAgICAgICBudWxsIDogeyAnZW51bSc6IHsgYWxsb3dlZFZhbHVlcywgY3VycmVudFZhbHVlIH0gfTtcclxuICAgIH07XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiAnY29uc3QnIHZhbGlkYXRvclxyXG4gICAqXHJcbiAgICogUmVxdWlyZXMgYSBjb250cm9sIHRvIGhhdmUgYSBzcGVjaWZpYyB2YWx1ZS5cclxuICAgKlxyXG4gICAqIENvbnZlcnRzIHR5cGVzIGFzIG5lZWRlZCB0byBhbGxvdyBzdHJpbmcgaW5wdXRzIHRvIHN0aWxsIGNvcnJlY3RseVxyXG4gICAqIG1hdGNoIG51bWJlciwgYm9vbGVhbiwgYW5kIG51bGwgdmFsdWVzLlxyXG4gICAqXHJcbiAgICogVE9ETzogbW9kaWZ5IHRvIHdvcmsgd2l0aCBvYmplY3RzXHJcbiAgICpcclxuICAgKiAvLyB7YW55W119IHJlcXVpcmVkVmFsdWUgLSByZXF1aXJlZCB2YWx1ZVxyXG4gICAqIC8vIHtJVmFsaWRhdG9yRm59XHJcbiAgICovXHJcbiAgc3RhdGljIGNvbnN0KHJlcXVpcmVkVmFsdWU6IGFueSk6IElWYWxpZGF0b3JGbiB7XHJcbiAgICBpZiAoIWhhc1ZhbHVlKHJlcXVpcmVkVmFsdWUpKSB7IHJldHVybiBKc29uVmFsaWRhdG9ycy5udWxsVmFsaWRhdG9yOyB9XHJcbiAgICByZXR1cm4gKGNvbnRyb2w6IEFic3RyYWN0Q29udHJvbCwgaW52ZXJ0ID0gZmFsc2UpOiBWYWxpZGF0aW9uRXJyb3JzfG51bGwgPT4ge1xyXG4gICAgICBpZiAoaXNFbXB0eShjb250cm9sLnZhbHVlKSkgeyByZXR1cm4gbnVsbDsgfVxyXG4gICAgICBjb25zdCBjdXJyZW50VmFsdWU6IGFueSA9IGNvbnRyb2wudmFsdWU7XHJcbiAgICAgIGNvbnN0IGlzRXF1YWxWYWwgPSAoY29uc3RWYWx1ZSwgaW5wdXRWYWx1ZSkgPT5cclxuICAgICAgICBjb25zdFZhbHVlID09PSBpbnB1dFZhbHVlIHx8XHJcbiAgICAgICAgaXNOdW1iZXIoY29uc3RWYWx1ZSkgJiYgK2lucHV0VmFsdWUgPT09ICtjb25zdFZhbHVlIHx8XHJcbiAgICAgICAgaXNCb29sZWFuKGNvbnN0VmFsdWUsICdzdHJpY3QnKSAmJlxyXG4gICAgICAgICAgdG9KYXZhU2NyaXB0VHlwZShpbnB1dFZhbHVlLCAnYm9vbGVhbicpID09PSBjb25zdFZhbHVlIHx8XHJcbiAgICAgICAgY29uc3RWYWx1ZSA9PT0gbnVsbCAmJiAhaGFzVmFsdWUoaW5wdXRWYWx1ZSk7XHJcbiAgICAgIGNvbnN0IGlzVmFsaWQgPSBpc0VxdWFsVmFsKHJlcXVpcmVkVmFsdWUsIGN1cnJlbnRWYWx1ZSk7XHJcbiAgICAgIHJldHVybiB4b3IoaXNWYWxpZCwgaW52ZXJ0KSA/XHJcbiAgICAgICAgbnVsbCA6IHsgJ2NvbnN0JzogeyByZXF1aXJlZFZhbHVlLCBjdXJyZW50VmFsdWUgfSB9O1xyXG4gICAgfTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqICdtaW5MZW5ndGgnIHZhbGlkYXRvclxyXG4gICAqXHJcbiAgICogUmVxdWlyZXMgYSBjb250cm9sJ3MgdGV4dCB2YWx1ZSB0byBiZSBncmVhdGVyIHRoYW4gYSBzcGVjaWZpZWQgbGVuZ3RoLlxyXG4gICAqXHJcbiAgICogLy8ge251bWJlcn0gbWluaW11bUxlbmd0aCAtIG1pbmltdW0gYWxsb3dlZCBzdHJpbmcgbGVuZ3RoXHJcbiAgICogLy8ge2Jvb2xlYW4gPSBmYWxzZX0gaW52ZXJ0IC0gaW5zdGVhZCByZXR1cm4gZXJyb3Igb2JqZWN0IG9ubHkgaWYgdmFsaWRcclxuICAgKiAvLyB7SVZhbGlkYXRvckZufVxyXG4gICAqL1xyXG4gIHN0YXRpYyBtaW5MZW5ndGgobWluaW11bUxlbmd0aDogbnVtYmVyKTogSVZhbGlkYXRvckZuIHtcclxuICAgIGlmICghaGFzVmFsdWUobWluaW11bUxlbmd0aCkpIHsgcmV0dXJuIEpzb25WYWxpZGF0b3JzLm51bGxWYWxpZGF0b3I7IH1cclxuICAgIHJldHVybiAoY29udHJvbDogQWJzdHJhY3RDb250cm9sLCBpbnZlcnQgPSBmYWxzZSk6IFZhbGlkYXRpb25FcnJvcnN8bnVsbCA9PiB7XHJcbiAgICAgIGlmIChpc0VtcHR5KGNvbnRyb2wudmFsdWUpKSB7IHJldHVybiBudWxsOyB9XHJcbiAgICAgIGNvbnN0IGN1cnJlbnRMZW5ndGggPSBpc1N0cmluZyhjb250cm9sLnZhbHVlKSA/IGNvbnRyb2wudmFsdWUubGVuZ3RoIDogMDtcclxuICAgICAgY29uc3QgaXNWYWxpZCA9IGN1cnJlbnRMZW5ndGggPj0gbWluaW11bUxlbmd0aDtcclxuICAgICAgcmV0dXJuIHhvcihpc1ZhbGlkLCBpbnZlcnQpID9cclxuICAgICAgICBudWxsIDogeyAnbWluTGVuZ3RoJzogeyBtaW5pbXVtTGVuZ3RoLCBjdXJyZW50TGVuZ3RoIH0gfTtcclxuICAgIH07XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiAnbWF4TGVuZ3RoJyB2YWxpZGF0b3JcclxuICAgKlxyXG4gICAqIFJlcXVpcmVzIGEgY29udHJvbCdzIHRleHQgdmFsdWUgdG8gYmUgbGVzcyB0aGFuIGEgc3BlY2lmaWVkIGxlbmd0aC5cclxuICAgKlxyXG4gICAqIC8vIHtudW1iZXJ9IG1heGltdW1MZW5ndGggLSBtYXhpbXVtIGFsbG93ZWQgc3RyaW5nIGxlbmd0aFxyXG4gICAqIC8vIHtib29sZWFuID0gZmFsc2V9IGludmVydCAtIGluc3RlYWQgcmV0dXJuIGVycm9yIG9iamVjdCBvbmx5IGlmIHZhbGlkXHJcbiAgICogLy8ge0lWYWxpZGF0b3JGbn1cclxuICAgKi9cclxuICBzdGF0aWMgbWF4TGVuZ3RoKG1heGltdW1MZW5ndGg6IG51bWJlcik6IElWYWxpZGF0b3JGbiB7XHJcbiAgICBpZiAoIWhhc1ZhbHVlKG1heGltdW1MZW5ndGgpKSB7IHJldHVybiBKc29uVmFsaWRhdG9ycy5udWxsVmFsaWRhdG9yOyB9XHJcbiAgICByZXR1cm4gKGNvbnRyb2w6IEFic3RyYWN0Q29udHJvbCwgaW52ZXJ0ID0gZmFsc2UpOiBWYWxpZGF0aW9uRXJyb3JzfG51bGwgPT4ge1xyXG4gICAgICBjb25zdCBjdXJyZW50TGVuZ3RoID0gaXNTdHJpbmcoY29udHJvbC52YWx1ZSkgPyBjb250cm9sLnZhbHVlLmxlbmd0aCA6IDA7XHJcbiAgICAgIGNvbnN0IGlzVmFsaWQgPSBjdXJyZW50TGVuZ3RoIDw9IG1heGltdW1MZW5ndGg7XHJcbiAgICAgIHJldHVybiB4b3IoaXNWYWxpZCwgaW52ZXJ0KSA/XHJcbiAgICAgICAgbnVsbCA6IHsgJ21heExlbmd0aCc6IHsgbWF4aW11bUxlbmd0aCwgY3VycmVudExlbmd0aCB9IH07XHJcbiAgICB9O1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogJ3BhdHRlcm4nIHZhbGlkYXRvclxyXG4gICAqXHJcbiAgICogTm90ZTogTk9UIHRoZSBzYW1lIGFzIEFuZ3VsYXIncyBkZWZhdWx0IHBhdHRlcm4gdmFsaWRhdG9yLlxyXG4gICAqXHJcbiAgICogUmVxdWlyZXMgYSBjb250cm9sJ3MgdmFsdWUgdG8gbWF0Y2ggYSBzcGVjaWZpZWQgcmVndWxhciBleHByZXNzaW9uIHBhdHRlcm4uXHJcbiAgICpcclxuICAgKiBUaGlzIHZhbGlkYXRvciBjaGFuZ2VzIHRoZSBiZWhhdmlvciBvZiBkZWZhdWx0IHBhdHRlcm4gdmFsaWRhdG9yXHJcbiAgICogYnkgcmVwbGFjaW5nIFJlZ0V4cChgXiR7cGF0dGVybn0kYCkgd2l0aCBSZWdFeHAoYCR7cGF0dGVybn1gKSxcclxuICAgKiB3aGljaCBhbGxvd3MgZm9yIHBhcnRpYWwgbWF0Y2hlcy5cclxuICAgKlxyXG4gICAqIFRvIHJldHVybiB0byB0aGUgZGVmYXVsdCBmdW5jaXRvbmFsaXR5LCBhbmQgbWF0Y2ggdGhlIGVudGlyZSBzdHJpbmcsXHJcbiAgICogcGFzcyBUUlVFIGFzIHRoZSBvcHRpb25hbCBzZWNvbmQgcGFyYW1ldGVyLlxyXG4gICAqXHJcbiAgICogLy8ge3N0cmluZ30gcGF0dGVybiAtIHJlZ3VsYXIgZXhwcmVzc2lvbiBwYXR0ZXJuXHJcbiAgICogLy8ge2Jvb2xlYW4gPSBmYWxzZX0gd2hvbGVTdHJpbmcgLSBtYXRjaCB3aG9sZSB2YWx1ZSBzdHJpbmc/XHJcbiAgICogLy8ge0lWYWxpZGF0b3JGbn1cclxuICAgKi9cclxuICBzdGF0aWMgcGF0dGVybihwYXR0ZXJuOiBzdHJpbmd8UmVnRXhwLCB3aG9sZVN0cmluZyA9IGZhbHNlKTogSVZhbGlkYXRvckZuIHtcclxuICAgIGlmICghaGFzVmFsdWUocGF0dGVybikpIHsgcmV0dXJuIEpzb25WYWxpZGF0b3JzLm51bGxWYWxpZGF0b3I7IH1cclxuICAgIHJldHVybiAoY29udHJvbDogQWJzdHJhY3RDb250cm9sLCBpbnZlcnQgPSBmYWxzZSk6IFZhbGlkYXRpb25FcnJvcnN8bnVsbCA9PiB7XHJcbiAgICAgIGlmIChpc0VtcHR5KGNvbnRyb2wudmFsdWUpKSB7IHJldHVybiBudWxsOyB9XHJcbiAgICAgIGxldCByZWdleDogUmVnRXhwO1xyXG4gICAgICBsZXQgcmVxdWlyZWRQYXR0ZXJuOiBzdHJpbmc7XHJcbiAgICAgIGlmICh0eXBlb2YgcGF0dGVybiA9PT0gJ3N0cmluZycpIHtcclxuICAgICAgICByZXF1aXJlZFBhdHRlcm4gPSAod2hvbGVTdHJpbmcpID8gYF4ke3BhdHRlcm59JGAgOiBwYXR0ZXJuO1xyXG4gICAgICAgIHJlZ2V4ID0gbmV3IFJlZ0V4cChyZXF1aXJlZFBhdHRlcm4pO1xyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIHJlcXVpcmVkUGF0dGVybiA9IHBhdHRlcm4udG9TdHJpbmcoKTtcclxuICAgICAgICByZWdleCA9IHBhdHRlcm47XHJcbiAgICAgIH1cclxuICAgICAgY29uc3QgY3VycmVudFZhbHVlOiBzdHJpbmcgPSBjb250cm9sLnZhbHVlO1xyXG4gICAgICBjb25zdCBpc1ZhbGlkID0gaXNTdHJpbmcoY3VycmVudFZhbHVlKSA/IHJlZ2V4LnRlc3QoY3VycmVudFZhbHVlKSA6IGZhbHNlO1xyXG4gICAgICByZXR1cm4geG9yKGlzVmFsaWQsIGludmVydCkgP1xyXG4gICAgICAgIG51bGwgOiB7ICdwYXR0ZXJuJzogeyByZXF1aXJlZFBhdHRlcm4sIGN1cnJlbnRWYWx1ZSB9IH07XHJcbiAgICB9O1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogJ2Zvcm1hdCcgdmFsaWRhdG9yXHJcbiAgICpcclxuICAgKiBSZXF1aXJlcyBhIGNvbnRyb2wgdG8gaGF2ZSBhIHZhbHVlIG9mIGEgY2VydGFpbiBmb3JtYXQuXHJcbiAgICpcclxuICAgKiBUaGlzIHZhbGlkYXRvciBjdXJyZW50bHkgY2hlY2tzIHRoZSBmb2xsb3dpbmcgZm9ybXN0czpcclxuICAgKiAgIGRhdGUsIHRpbWUsIGRhdGUtdGltZSwgZW1haWwsIGhvc3RuYW1lLCBpcHY0LCBpcHY2LFxyXG4gICAqICAgdXJpLCB1cmktcmVmZXJlbmNlLCB1cmktdGVtcGxhdGUsIHVybCwgdXVpZCwgY29sb3IsXHJcbiAgICogICBqc29uLXBvaW50ZXIsIHJlbGF0aXZlLWpzb24tcG9pbnRlciwgcmVnZXhcclxuICAgKlxyXG4gICAqIEZhc3QgZm9ybWF0IHJlZ3VsYXIgZXhwcmVzc2lvbnMgY29waWVkIGZyb20gQUpWOlxyXG4gICAqIGh0dHBzOi8vZ2l0aHViLmNvbS9lcG9iZXJlemtpbi9hanYvYmxvYi9tYXN0ZXIvbGliL2NvbXBpbGUvZm9ybWF0cy5qc1xyXG4gICAqXHJcbiAgICogLy8ge0pzb25TY2hlbWFGb3JtYXROYW1lc30gcmVxdWlyZWRGb3JtYXQgLSBmb3JtYXQgdG8gY2hlY2tcclxuICAgKiAvLyB7SVZhbGlkYXRvckZufVxyXG4gICAqL1xyXG4gIHN0YXRpYyBmb3JtYXQocmVxdWlyZWRGb3JtYXQ6IEpzb25TY2hlbWFGb3JtYXROYW1lcyk6IElWYWxpZGF0b3JGbiB7XHJcbiAgICBpZiAoIWhhc1ZhbHVlKHJlcXVpcmVkRm9ybWF0KSkgeyByZXR1cm4gSnNvblZhbGlkYXRvcnMubnVsbFZhbGlkYXRvcjsgfVxyXG4gICAgcmV0dXJuIChjb250cm9sOiBBYnN0cmFjdENvbnRyb2wsIGludmVydCA9IGZhbHNlKTogVmFsaWRhdGlvbkVycm9yc3xudWxsID0+IHtcclxuICAgICAgaWYgKGlzRW1wdHkoY29udHJvbC52YWx1ZSkpIHsgcmV0dXJuIG51bGw7IH1cclxuICAgICAgbGV0IGlzVmFsaWQ6IGJvb2xlYW47XHJcbiAgICAgIGNvbnN0IGN1cnJlbnRWYWx1ZTogc3RyaW5nfERhdGUgPSBjb250cm9sLnZhbHVlO1xyXG4gICAgICBpZiAoaXNTdHJpbmcoY3VycmVudFZhbHVlKSkge1xyXG4gICAgICAgIGNvbnN0IGZvcm1hdFRlc3Q6IEZ1bmN0aW9ufFJlZ0V4cCA9IGpzb25TY2hlbWFGb3JtYXRUZXN0c1tyZXF1aXJlZEZvcm1hdF07XHJcbiAgICAgICAgaWYgKHR5cGVvZiBmb3JtYXRUZXN0ID09PSAnb2JqZWN0Jykge1xyXG4gICAgICAgICAgaXNWYWxpZCA9ICg8UmVnRXhwPmZvcm1hdFRlc3QpLnRlc3QoPHN0cmluZz5jdXJyZW50VmFsdWUpO1xyXG4gICAgICAgIH0gZWxzZSBpZiAodHlwZW9mIGZvcm1hdFRlc3QgPT09ICdmdW5jdGlvbicpIHtcclxuICAgICAgICAgIGlzVmFsaWQgPSAoPEZ1bmN0aW9uPmZvcm1hdFRlc3QpKDxzdHJpbmc+Y3VycmVudFZhbHVlKTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgY29uc29sZS5lcnJvcihgZm9ybWF0IHZhbGlkYXRvciBlcnJvcjogXCIke3JlcXVpcmVkRm9ybWF0fVwiIGlzIG5vdCBhIHJlY29nbml6ZWQgZm9ybWF0LmApO1xyXG4gICAgICAgICAgaXNWYWxpZCA9IHRydWU7XHJcbiAgICAgICAgfVxyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIC8vIEFsbG93IEphdmFTY3JpcHQgRGF0ZSBvYmplY3RzXHJcbiAgICAgICAgaXNWYWxpZCA9IFsnZGF0ZScsICd0aW1lJywgJ2RhdGUtdGltZSddLmluY2x1ZGVzKHJlcXVpcmVkRm9ybWF0KSAmJlxyXG4gICAgICAgICAgT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKGN1cnJlbnRWYWx1ZSkgPT09ICdbb2JqZWN0IERhdGVdJztcclxuICAgICAgfVxyXG4gICAgICByZXR1cm4geG9yKGlzVmFsaWQsIGludmVydCkgP1xyXG4gICAgICAgIG51bGwgOiB7ICdmb3JtYXQnOiB7IHJlcXVpcmVkRm9ybWF0LCBjdXJyZW50VmFsdWUgfSB9O1xyXG4gICAgfTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqICdtaW5pbXVtJyB2YWxpZGF0b3JcclxuICAgKlxyXG4gICAqIFJlcXVpcmVzIGEgY29udHJvbCdzIG51bWVyaWMgdmFsdWUgdG8gYmUgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvXHJcbiAgICogYSBtaW5pbXVtIGFtb3VudC5cclxuICAgKlxyXG4gICAqIEFueSBub24tbnVtZXJpYyB2YWx1ZSBpcyBhbHNvIHZhbGlkIChhY2NvcmRpbmcgdG8gdGhlIEhUTUwgZm9ybXMgc3BlYyxcclxuICAgKiBhIG5vbi1udW1lcmljIHZhbHVlIGRvZXNuJ3QgaGF2ZSBhIG1pbmltdW0pLlxyXG4gICAqIGh0dHBzOi8vd3d3LnczLm9yZy9UUi9odG1sNS9mb3Jtcy5odG1sI2F0dHItaW5wdXQtbWF4XHJcbiAgICpcclxuICAgKiAvLyB7bnVtYmVyfSBtaW5pbXVtIC0gbWluaW11bSBhbGxvd2VkIHZhbHVlXHJcbiAgICogLy8ge0lWYWxpZGF0b3JGbn1cclxuICAgKi9cclxuICBzdGF0aWMgbWluaW11bShtaW5pbXVtVmFsdWU6IG51bWJlcik6IElWYWxpZGF0b3JGbiB7XHJcbiAgICBpZiAoIWhhc1ZhbHVlKG1pbmltdW1WYWx1ZSkpIHsgcmV0dXJuIEpzb25WYWxpZGF0b3JzLm51bGxWYWxpZGF0b3I7IH1cclxuICAgIHJldHVybiAoY29udHJvbDogQWJzdHJhY3RDb250cm9sLCBpbnZlcnQgPSBmYWxzZSk6IFZhbGlkYXRpb25FcnJvcnN8bnVsbCA9PiB7XHJcbiAgICAgIGlmIChpc0VtcHR5KGNvbnRyb2wudmFsdWUpKSB7IHJldHVybiBudWxsOyB9XHJcbiAgICAgIGNvbnN0IGN1cnJlbnRWYWx1ZSA9IGNvbnRyb2wudmFsdWU7XHJcbiAgICAgIGNvbnN0IGlzVmFsaWQgPSAhaXNOdW1iZXIoY3VycmVudFZhbHVlKSB8fCBjdXJyZW50VmFsdWUgPj0gbWluaW11bVZhbHVlO1xyXG4gICAgICByZXR1cm4geG9yKGlzVmFsaWQsIGludmVydCkgP1xyXG4gICAgICAgIG51bGwgOiB7ICdtaW5pbXVtJzogeyBtaW5pbXVtVmFsdWUsIGN1cnJlbnRWYWx1ZSB9IH07XHJcbiAgICB9O1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogJ2V4Y2x1c2l2ZU1pbmltdW0nIHZhbGlkYXRvclxyXG4gICAqXHJcbiAgICogUmVxdWlyZXMgYSBjb250cm9sJ3MgbnVtZXJpYyB2YWx1ZSB0byBiZSBsZXNzIHRoYW4gYSBtYXhpbXVtIGFtb3VudC5cclxuICAgKlxyXG4gICAqIEFueSBub24tbnVtZXJpYyB2YWx1ZSBpcyBhbHNvIHZhbGlkIChhY2NvcmRpbmcgdG8gdGhlIEhUTUwgZm9ybXMgc3BlYyxcclxuICAgKiBhIG5vbi1udW1lcmljIHZhbHVlIGRvZXNuJ3QgaGF2ZSBhIG1heGltdW0pLlxyXG4gICAqIGh0dHBzOi8vd3d3LnczLm9yZy9UUi9odG1sNS9mb3Jtcy5odG1sI2F0dHItaW5wdXQtbWF4XHJcbiAgICpcclxuICAgKiAvLyB7bnVtYmVyfSBleGNsdXNpdmVNaW5pbXVtVmFsdWUgLSBtYXhpbXVtIGFsbG93ZWQgdmFsdWVcclxuICAgKiAvLyB7SVZhbGlkYXRvckZufVxyXG4gICAqL1xyXG4gIHN0YXRpYyBleGNsdXNpdmVNaW5pbXVtKGV4Y2x1c2l2ZU1pbmltdW1WYWx1ZTogbnVtYmVyKTogSVZhbGlkYXRvckZuIHtcclxuICAgIGlmICghaGFzVmFsdWUoZXhjbHVzaXZlTWluaW11bVZhbHVlKSkgeyByZXR1cm4gSnNvblZhbGlkYXRvcnMubnVsbFZhbGlkYXRvcjsgfVxyXG4gICAgcmV0dXJuIChjb250cm9sOiBBYnN0cmFjdENvbnRyb2wsIGludmVydCA9IGZhbHNlKTogVmFsaWRhdGlvbkVycm9yc3xudWxsID0+IHtcclxuICAgICAgaWYgKGlzRW1wdHkoY29udHJvbC52YWx1ZSkpIHsgcmV0dXJuIG51bGw7IH1cclxuICAgICAgY29uc3QgY3VycmVudFZhbHVlID0gY29udHJvbC52YWx1ZTtcclxuICAgICAgY29uc3QgaXNWYWxpZCA9ICFpc051bWJlcihjdXJyZW50VmFsdWUpIHx8ICtjdXJyZW50VmFsdWUgPCBleGNsdXNpdmVNaW5pbXVtVmFsdWU7XHJcbiAgICAgIHJldHVybiB4b3IoaXNWYWxpZCwgaW52ZXJ0KSA/XHJcbiAgICAgICAgbnVsbCA6IHsgJ2V4Y2x1c2l2ZU1pbmltdW0nOiB7IGV4Y2x1c2l2ZU1pbmltdW1WYWx1ZSwgY3VycmVudFZhbHVlIH0gfTtcclxuICAgIH07XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiAnbWF4aW11bScgdmFsaWRhdG9yXHJcbiAgICpcclxuICAgKiBSZXF1aXJlcyBhIGNvbnRyb2wncyBudW1lcmljIHZhbHVlIHRvIGJlIGxlc3MgdGhhbiBvciBlcXVhbCB0b1xyXG4gICAqIGEgbWF4aW11bSBhbW91bnQuXHJcbiAgICpcclxuICAgKiBBbnkgbm9uLW51bWVyaWMgdmFsdWUgaXMgYWxzbyB2YWxpZCAoYWNjb3JkaW5nIHRvIHRoZSBIVE1MIGZvcm1zIHNwZWMsXHJcbiAgICogYSBub24tbnVtZXJpYyB2YWx1ZSBkb2Vzbid0IGhhdmUgYSBtYXhpbXVtKS5cclxuICAgKiBodHRwczovL3d3dy53My5vcmcvVFIvaHRtbDUvZm9ybXMuaHRtbCNhdHRyLWlucHV0LW1heFxyXG4gICAqXHJcbiAgICogLy8ge251bWJlcn0gbWF4aW11bVZhbHVlIC0gbWF4aW11bSBhbGxvd2VkIHZhbHVlXHJcbiAgICogLy8ge0lWYWxpZGF0b3JGbn1cclxuICAgKi9cclxuICBzdGF0aWMgbWF4aW11bShtYXhpbXVtVmFsdWU6IG51bWJlcik6IElWYWxpZGF0b3JGbiB7XHJcbiAgICBpZiAoIWhhc1ZhbHVlKG1heGltdW1WYWx1ZSkpIHsgcmV0dXJuIEpzb25WYWxpZGF0b3JzLm51bGxWYWxpZGF0b3I7IH1cclxuICAgIHJldHVybiAoY29udHJvbDogQWJzdHJhY3RDb250cm9sLCBpbnZlcnQgPSBmYWxzZSk6IFZhbGlkYXRpb25FcnJvcnN8bnVsbCA9PiB7XHJcbiAgICAgIGlmIChpc0VtcHR5KGNvbnRyb2wudmFsdWUpKSB7IHJldHVybiBudWxsOyB9XHJcbiAgICAgIGNvbnN0IGN1cnJlbnRWYWx1ZSA9IGNvbnRyb2wudmFsdWU7XHJcbiAgICAgIGNvbnN0IGlzVmFsaWQgPSAhaXNOdW1iZXIoY3VycmVudFZhbHVlKSB8fCArY3VycmVudFZhbHVlIDw9IG1heGltdW1WYWx1ZTtcclxuICAgICAgcmV0dXJuIHhvcihpc1ZhbGlkLCBpbnZlcnQpID9cclxuICAgICAgICBudWxsIDogeyAnbWF4aW11bSc6IHsgbWF4aW11bVZhbHVlLCBjdXJyZW50VmFsdWUgfSB9O1xyXG4gICAgfTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqICdleGNsdXNpdmVNYXhpbXVtJyB2YWxpZGF0b3JcclxuICAgKlxyXG4gICAqIFJlcXVpcmVzIGEgY29udHJvbCdzIG51bWVyaWMgdmFsdWUgdG8gYmUgbGVzcyB0aGFuIGEgbWF4aW11bSBhbW91bnQuXHJcbiAgICpcclxuICAgKiBBbnkgbm9uLW51bWVyaWMgdmFsdWUgaXMgYWxzbyB2YWxpZCAoYWNjb3JkaW5nIHRvIHRoZSBIVE1MIGZvcm1zIHNwZWMsXHJcbiAgICogYSBub24tbnVtZXJpYyB2YWx1ZSBkb2Vzbid0IGhhdmUgYSBtYXhpbXVtKS5cclxuICAgKiBodHRwczovL3d3dy53My5vcmcvVFIvaHRtbDUvZm9ybXMuaHRtbCNhdHRyLWlucHV0LW1heFxyXG4gICAqXHJcbiAgICogLy8ge251bWJlcn0gZXhjbHVzaXZlTWF4aW11bVZhbHVlIC0gbWF4aW11bSBhbGxvd2VkIHZhbHVlXHJcbiAgICogLy8ge0lWYWxpZGF0b3JGbn1cclxuICAgKi9cclxuICBzdGF0aWMgZXhjbHVzaXZlTWF4aW11bShleGNsdXNpdmVNYXhpbXVtVmFsdWU6IG51bWJlcik6IElWYWxpZGF0b3JGbiB7XHJcbiAgICBpZiAoIWhhc1ZhbHVlKGV4Y2x1c2l2ZU1heGltdW1WYWx1ZSkpIHsgcmV0dXJuIEpzb25WYWxpZGF0b3JzLm51bGxWYWxpZGF0b3I7IH1cclxuICAgIHJldHVybiAoY29udHJvbDogQWJzdHJhY3RDb250cm9sLCBpbnZlcnQgPSBmYWxzZSk6IFZhbGlkYXRpb25FcnJvcnN8bnVsbCA9PiB7XHJcbiAgICAgIGlmIChpc0VtcHR5KGNvbnRyb2wudmFsdWUpKSB7IHJldHVybiBudWxsOyB9XHJcbiAgICAgIGNvbnN0IGN1cnJlbnRWYWx1ZSA9IGNvbnRyb2wudmFsdWU7XHJcbiAgICAgIGNvbnN0IGlzVmFsaWQgPSAhaXNOdW1iZXIoY3VycmVudFZhbHVlKSB8fCArY3VycmVudFZhbHVlIDwgZXhjbHVzaXZlTWF4aW11bVZhbHVlO1xyXG4gICAgICByZXR1cm4geG9yKGlzVmFsaWQsIGludmVydCkgP1xyXG4gICAgICAgIG51bGwgOiB7ICdleGNsdXNpdmVNYXhpbXVtJzogeyBleGNsdXNpdmVNYXhpbXVtVmFsdWUsIGN1cnJlbnRWYWx1ZSB9IH07XHJcbiAgICB9O1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogJ211bHRpcGxlT2YnIHZhbGlkYXRvclxyXG4gICAqXHJcbiAgICogUmVxdWlyZXMgYSBjb250cm9sIHRvIGhhdmUgYSBudW1lcmljIHZhbHVlIHRoYXQgaXMgYSBtdWx0aXBsZVxyXG4gICAqIG9mIGEgc3BlY2lmaWVkIG51bWJlci5cclxuICAgKlxyXG4gICAqIC8vIHtudW1iZXJ9IG11bHRpcGxlT2ZWYWx1ZSAtIG51bWJlciB2YWx1ZSBtdXN0IGJlIGEgbXVsdGlwbGUgb2ZcclxuICAgKiAvLyB7SVZhbGlkYXRvckZufVxyXG4gICAqL1xyXG4gIHN0YXRpYyBtdWx0aXBsZU9mKG11bHRpcGxlT2ZWYWx1ZTogbnVtYmVyKTogSVZhbGlkYXRvckZuIHtcclxuICAgIGlmICghaGFzVmFsdWUobXVsdGlwbGVPZlZhbHVlKSkgeyByZXR1cm4gSnNvblZhbGlkYXRvcnMubnVsbFZhbGlkYXRvcjsgfVxyXG4gICAgcmV0dXJuIChjb250cm9sOiBBYnN0cmFjdENvbnRyb2wsIGludmVydCA9IGZhbHNlKTogVmFsaWRhdGlvbkVycm9yc3xudWxsID0+IHtcclxuICAgICAgaWYgKGlzRW1wdHkoY29udHJvbC52YWx1ZSkpIHsgcmV0dXJuIG51bGw7IH1cclxuICAgICAgY29uc3QgY3VycmVudFZhbHVlID0gY29udHJvbC52YWx1ZTtcclxuICAgICAgY29uc3QgaXNWYWxpZCA9IGlzTnVtYmVyKGN1cnJlbnRWYWx1ZSkgJiZcclxuICAgICAgICBjdXJyZW50VmFsdWUgJSBtdWx0aXBsZU9mVmFsdWUgPT09IDA7XHJcbiAgICAgIHJldHVybiB4b3IoaXNWYWxpZCwgaW52ZXJ0KSA/XHJcbiAgICAgICAgbnVsbCA6IHsgJ211bHRpcGxlT2YnOiB7IG11bHRpcGxlT2ZWYWx1ZSwgY3VycmVudFZhbHVlIH0gfTtcclxuICAgIH07XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiAnbWluUHJvcGVydGllcycgdmFsaWRhdG9yXHJcbiAgICpcclxuICAgKiBSZXF1aXJlcyBhIGZvcm0gZ3JvdXAgdG8gaGF2ZSBhIG1pbmltdW0gbnVtYmVyIG9mIHByb3BlcnRpZXMgKGkuZS4gaGF2ZVxyXG4gICAqIHZhbHVlcyBlbnRlcmVkIGluIGEgbWluaW11bSBudW1iZXIgb2YgY29udHJvbHMgd2l0aGluIHRoZSBncm91cCkuXHJcbiAgICpcclxuICAgKiAvLyB7bnVtYmVyfSBtaW5pbXVtUHJvcGVydGllcyAtIG1pbmltdW0gbnVtYmVyIG9mIHByb3BlcnRpZXMgYWxsb3dlZFxyXG4gICAqIC8vIHtJVmFsaWRhdG9yRm59XHJcbiAgICovXHJcbiAgc3RhdGljIG1pblByb3BlcnRpZXMobWluaW11bVByb3BlcnRpZXM6IG51bWJlcik6IElWYWxpZGF0b3JGbiB7XHJcbiAgICBpZiAoIWhhc1ZhbHVlKG1pbmltdW1Qcm9wZXJ0aWVzKSkgeyByZXR1cm4gSnNvblZhbGlkYXRvcnMubnVsbFZhbGlkYXRvcjsgfVxyXG4gICAgcmV0dXJuIChjb250cm9sOiBBYnN0cmFjdENvbnRyb2wsIGludmVydCA9IGZhbHNlKTogVmFsaWRhdGlvbkVycm9yc3xudWxsID0+IHtcclxuICAgICAgaWYgKGlzRW1wdHkoY29udHJvbC52YWx1ZSkpIHsgcmV0dXJuIG51bGw7IH1cclxuICAgICAgY29uc3QgY3VycmVudFByb3BlcnRpZXMgPSBPYmplY3Qua2V5cyhjb250cm9sLnZhbHVlKS5sZW5ndGggfHwgMDtcclxuICAgICAgY29uc3QgaXNWYWxpZCA9IGN1cnJlbnRQcm9wZXJ0aWVzID49IG1pbmltdW1Qcm9wZXJ0aWVzO1xyXG4gICAgICByZXR1cm4geG9yKGlzVmFsaWQsIGludmVydCkgP1xyXG4gICAgICAgIG51bGwgOiB7ICdtaW5Qcm9wZXJ0aWVzJzogeyBtaW5pbXVtUHJvcGVydGllcywgY3VycmVudFByb3BlcnRpZXMgfSB9O1xyXG4gICAgfTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqICdtYXhQcm9wZXJ0aWVzJyB2YWxpZGF0b3JcclxuICAgKlxyXG4gICAqIFJlcXVpcmVzIGEgZm9ybSBncm91cCB0byBoYXZlIGEgbWF4aW11bSBudW1iZXIgb2YgcHJvcGVydGllcyAoaS5lLiBoYXZlXHJcbiAgICogdmFsdWVzIGVudGVyZWQgaW4gYSBtYXhpbXVtIG51bWJlciBvZiBjb250cm9scyB3aXRoaW4gdGhlIGdyb3VwKS5cclxuICAgKlxyXG4gICAqIE5vdGU6IEhhcyBubyBlZmZlY3QgaWYgdGhlIGZvcm0gZ3JvdXAgZG9lcyBub3QgY29udGFpbiBtb3JlIHRoYW4gdGhlXHJcbiAgICogbWF4aW11bSBudW1iZXIgb2YgY29udHJvbHMuXHJcbiAgICpcclxuICAgKiAvLyB7bnVtYmVyfSBtYXhpbXVtUHJvcGVydGllcyAtIG1heGltdW0gbnVtYmVyIG9mIHByb3BlcnRpZXMgYWxsb3dlZFxyXG4gICAqIC8vIHtJVmFsaWRhdG9yRm59XHJcbiAgICovXHJcbiAgc3RhdGljIG1heFByb3BlcnRpZXMobWF4aW11bVByb3BlcnRpZXM6IG51bWJlcik6IElWYWxpZGF0b3JGbiB7XHJcbiAgICBpZiAoIWhhc1ZhbHVlKG1heGltdW1Qcm9wZXJ0aWVzKSkgeyByZXR1cm4gSnNvblZhbGlkYXRvcnMubnVsbFZhbGlkYXRvcjsgfVxyXG4gICAgcmV0dXJuIChjb250cm9sOiBBYnN0cmFjdENvbnRyb2wsIGludmVydCA9IGZhbHNlKTogVmFsaWRhdGlvbkVycm9yc3xudWxsID0+IHtcclxuICAgICAgY29uc3QgY3VycmVudFByb3BlcnRpZXMgPSBPYmplY3Qua2V5cyhjb250cm9sLnZhbHVlKS5sZW5ndGggfHwgMDtcclxuICAgICAgY29uc3QgaXNWYWxpZCA9IGN1cnJlbnRQcm9wZXJ0aWVzIDw9IG1heGltdW1Qcm9wZXJ0aWVzO1xyXG4gICAgICByZXR1cm4geG9yKGlzVmFsaWQsIGludmVydCkgP1xyXG4gICAgICAgIG51bGwgOiB7ICdtYXhQcm9wZXJ0aWVzJzogeyBtYXhpbXVtUHJvcGVydGllcywgY3VycmVudFByb3BlcnRpZXMgfSB9O1xyXG4gICAgfTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqICdkZXBlbmRlbmNpZXMnIHZhbGlkYXRvclxyXG4gICAqXHJcbiAgICogUmVxdWlyZXMgdGhlIGNvbnRyb2xzIGluIGEgZm9ybSBncm91cCB0byBtZWV0IGFkZGl0aW9uYWwgdmFsaWRhdGlvblxyXG4gICAqIGNyaXRlcmlhLCBkZXBlbmRpbmcgb24gdGhlIHZhbHVlcyBvZiBvdGhlciBjb250cm9scyBpbiB0aGUgZ3JvdXAuXHJcbiAgICpcclxuICAgKiBFeGFtcGxlczpcclxuICAgKiBodHRwczovL3NwYWNldGVsZXNjb3BlLmdpdGh1Yi5pby91bmRlcnN0YW5kaW5nLWpzb24tc2NoZW1hL3JlZmVyZW5jZS9vYmplY3QuaHRtbCNkZXBlbmRlbmNpZXNcclxuICAgKlxyXG4gICAqIC8vIHthbnl9IGRlcGVuZGVuY2llcyAtIHJlcXVpcmVkIGRlcGVuZGVuY2llc1xyXG4gICAqIC8vIHtJVmFsaWRhdG9yRm59XHJcbiAgICovXHJcbiAgc3RhdGljIGRlcGVuZGVuY2llcyhkZXBlbmRlbmNpZXM6IGFueSk6IElWYWxpZGF0b3JGbiB7XHJcbiAgICBpZiAoZ2V0VHlwZShkZXBlbmRlbmNpZXMpICE9PSAnb2JqZWN0JyB8fCBpc0VtcHR5KGRlcGVuZGVuY2llcykpIHtcclxuICAgICAgcmV0dXJuIEpzb25WYWxpZGF0b3JzLm51bGxWYWxpZGF0b3I7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gKGNvbnRyb2w6IEFic3RyYWN0Q29udHJvbCwgaW52ZXJ0ID0gZmFsc2UpOiBWYWxpZGF0aW9uRXJyb3JzfG51bGwgPT4ge1xyXG4gICAgICBpZiAoaXNFbXB0eShjb250cm9sLnZhbHVlKSkgeyByZXR1cm4gbnVsbDsgfVxyXG4gICAgICBjb25zdCBhbGxFcnJvcnMgPSBfbWVyZ2VPYmplY3RzKFxyXG4gICAgICAgIGZvckVhY2hDb3B5KGRlcGVuZGVuY2llcywgKHZhbHVlLCByZXF1aXJpbmdGaWVsZCkgPT4ge1xyXG4gICAgICAgICAgaWYgKCFoYXNWYWx1ZShjb250cm9sLnZhbHVlW3JlcXVpcmluZ0ZpZWxkXSkpIHsgcmV0dXJuIG51bGw7IH1cclxuICAgICAgICAgIGxldCByZXF1aXJpbmdGaWVsZEVycm9yczogVmFsaWRhdGlvbkVycm9ycyA9IHsgfTtcclxuICAgICAgICAgIGxldCByZXF1aXJlZEZpZWxkczogc3RyaW5nW107XHJcbiAgICAgICAgICBsZXQgcHJvcGVydGllczogVmFsaWRhdGlvbkVycm9ycyA9IHsgfTtcclxuICAgICAgICAgIGlmIChnZXRUeXBlKGRlcGVuZGVuY2llc1tyZXF1aXJpbmdGaWVsZF0pID09PSAnYXJyYXknKSB7XHJcbiAgICAgICAgICAgIHJlcXVpcmVkRmllbGRzID0gZGVwZW5kZW5jaWVzW3JlcXVpcmluZ0ZpZWxkXTtcclxuICAgICAgICAgIH0gZWxzZSBpZiAoZ2V0VHlwZShkZXBlbmRlbmNpZXNbcmVxdWlyaW5nRmllbGRdKSA9PT0gJ29iamVjdCcpIHtcclxuICAgICAgICAgICAgcmVxdWlyZWRGaWVsZHMgPSBkZXBlbmRlbmNpZXNbcmVxdWlyaW5nRmllbGRdWydyZXF1aXJlZCddIHx8IFtdO1xyXG4gICAgICAgICAgICBwcm9wZXJ0aWVzID0gZGVwZW5kZW5jaWVzW3JlcXVpcmluZ0ZpZWxkXVsncHJvcGVydGllcyddIHx8IHsgfTtcclxuICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAvLyBWYWxpZGF0ZSBwcm9wZXJ0eSBkZXBlbmRlbmNpZXNcclxuICAgICAgICAgIGZvciAoY29uc3QgcmVxdWlyZWRGaWVsZCBvZiByZXF1aXJlZEZpZWxkcykge1xyXG4gICAgICAgICAgICBpZiAoeG9yKCFoYXNWYWx1ZShjb250cm9sLnZhbHVlW3JlcXVpcmVkRmllbGRdKSwgaW52ZXJ0KSkge1xyXG4gICAgICAgICAgICAgIHJlcXVpcmluZ0ZpZWxkRXJyb3JzW3JlcXVpcmVkRmllbGRdID0geyAncmVxdWlyZWQnOiB0cnVlIH07XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAvLyBWYWxpZGF0ZSBzY2hlbWEgZGVwZW5kZW5jaWVzXHJcbiAgICAgICAgICByZXF1aXJpbmdGaWVsZEVycm9ycyA9IF9tZXJnZU9iamVjdHMocmVxdWlyaW5nRmllbGRFcnJvcnMsXHJcbiAgICAgICAgICAgIGZvckVhY2hDb3B5KHByb3BlcnRpZXMsIChyZXF1aXJlbWVudHMsIHJlcXVpcmVkRmllbGQpID0+IHtcclxuICAgICAgICAgICAgICBjb25zdCByZXF1aXJlZEZpZWxkRXJyb3JzID0gX21lcmdlT2JqZWN0cyhcclxuICAgICAgICAgICAgICAgIGZvckVhY2hDb3B5KHJlcXVpcmVtZW50cywgKHJlcXVpcmVtZW50LCBwYXJhbWV0ZXIpID0+IHtcclxuICAgICAgICAgICAgICAgICAgbGV0IHZhbGlkYXRvcjogSVZhbGlkYXRvckZuID0gbnVsbDtcclxuICAgICAgICAgICAgICAgICAgaWYgKHJlcXVpcmVtZW50ID09PSAnbWF4aW11bScgfHwgcmVxdWlyZW1lbnQgPT09ICdtaW5pbXVtJykge1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGV4Y2x1c2l2ZSA9ICEhcmVxdWlyZW1lbnRzWydleGNsdXNpdmVNJyArIHJlcXVpcmVtZW50LnNsaWNlKDEpXTtcclxuICAgICAgICAgICAgICAgICAgICB2YWxpZGF0b3IgPSBKc29uVmFsaWRhdG9yc1tyZXF1aXJlbWVudF0ocGFyYW1ldGVyLCBleGNsdXNpdmUpO1xyXG4gICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHR5cGVvZiBKc29uVmFsaWRhdG9yc1tyZXF1aXJlbWVudF0gPT09ICdmdW5jdGlvbicpIHtcclxuICAgICAgICAgICAgICAgICAgICB2YWxpZGF0b3IgPSBKc29uVmFsaWRhdG9yc1tyZXF1aXJlbWVudF0ocGFyYW1ldGVyKTtcclxuICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICByZXR1cm4gIWlzRGVmaW5lZCh2YWxpZGF0b3IpID9cclxuICAgICAgICAgICAgICAgICAgICBudWxsIDogdmFsaWRhdG9yKGNvbnRyb2wudmFsdWVbcmVxdWlyZWRGaWVsZF0pO1xyXG4gICAgICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgICApO1xyXG4gICAgICAgICAgICAgIHJldHVybiBpc0VtcHR5KHJlcXVpcmVkRmllbGRFcnJvcnMpID9cclxuICAgICAgICAgICAgICAgIG51bGwgOiB7IFtyZXF1aXJlZEZpZWxkXTogcmVxdWlyZWRGaWVsZEVycm9ycyB9O1xyXG4gICAgICAgICAgICB9KVxyXG4gICAgICAgICAgKTtcclxuICAgICAgICAgIHJldHVybiBpc0VtcHR5KHJlcXVpcmluZ0ZpZWxkRXJyb3JzKSA/XHJcbiAgICAgICAgICAgIG51bGwgOiB7IFtyZXF1aXJpbmdGaWVsZF06IHJlcXVpcmluZ0ZpZWxkRXJyb3JzIH07XHJcbiAgICAgICAgfSlcclxuICAgICAgKTtcclxuICAgICAgcmV0dXJuIGlzRW1wdHkoYWxsRXJyb3JzKSA/IG51bGwgOiBhbGxFcnJvcnM7XHJcbiAgICB9O1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogJ21pbkl0ZW1zJyB2YWxpZGF0b3JcclxuICAgKlxyXG4gICAqIFJlcXVpcmVzIGEgZm9ybSBhcnJheSB0byBoYXZlIGEgbWluaW11bSBudW1iZXIgb2YgdmFsdWVzLlxyXG4gICAqXHJcbiAgICogLy8ge251bWJlcn0gbWluaW11bUl0ZW1zIC0gbWluaW11bSBudW1iZXIgb2YgaXRlbXMgYWxsb3dlZFxyXG4gICAqIC8vIHtJVmFsaWRhdG9yRm59XHJcbiAgICovXHJcbiAgc3RhdGljIG1pbkl0ZW1zKG1pbmltdW1JdGVtczogbnVtYmVyKTogSVZhbGlkYXRvckZuIHtcclxuICAgIGlmICghaGFzVmFsdWUobWluaW11bUl0ZW1zKSkgeyByZXR1cm4gSnNvblZhbGlkYXRvcnMubnVsbFZhbGlkYXRvcjsgfVxyXG4gICAgcmV0dXJuIChjb250cm9sOiBBYnN0cmFjdENvbnRyb2wsIGludmVydCA9IGZhbHNlKTogVmFsaWRhdGlvbkVycm9yc3xudWxsID0+IHtcclxuICAgICAgaWYgKGlzRW1wdHkoY29udHJvbC52YWx1ZSkpIHsgcmV0dXJuIG51bGw7IH1cclxuICAgICAgY29uc3QgY3VycmVudEl0ZW1zID0gaXNBcnJheShjb250cm9sLnZhbHVlKSA/IGNvbnRyb2wudmFsdWUubGVuZ3RoIDogMDtcclxuICAgICAgY29uc3QgaXNWYWxpZCA9IGN1cnJlbnRJdGVtcyA+PSBtaW5pbXVtSXRlbXM7XHJcbiAgICAgIHJldHVybiB4b3IoaXNWYWxpZCwgaW52ZXJ0KSA/XHJcbiAgICAgICAgbnVsbCA6IHsgJ21pbkl0ZW1zJzogeyBtaW5pbXVtSXRlbXMsIGN1cnJlbnRJdGVtcyB9IH07XHJcbiAgICB9O1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogJ21heEl0ZW1zJyB2YWxpZGF0b3JcclxuICAgKlxyXG4gICAqIFJlcXVpcmVzIGEgZm9ybSBhcnJheSB0byBoYXZlIGEgbWF4aW11bSBudW1iZXIgb2YgdmFsdWVzLlxyXG4gICAqXHJcbiAgICogLy8ge251bWJlcn0gbWF4aW11bUl0ZW1zIC0gbWF4aW11bSBudW1iZXIgb2YgaXRlbXMgYWxsb3dlZFxyXG4gICAqIC8vIHtJVmFsaWRhdG9yRm59XHJcbiAgICovXHJcbiAgc3RhdGljIG1heEl0ZW1zKG1heGltdW1JdGVtczogbnVtYmVyKTogSVZhbGlkYXRvckZuIHtcclxuICAgIGlmICghaGFzVmFsdWUobWF4aW11bUl0ZW1zKSkgeyByZXR1cm4gSnNvblZhbGlkYXRvcnMubnVsbFZhbGlkYXRvcjsgfVxyXG4gICAgcmV0dXJuIChjb250cm9sOiBBYnN0cmFjdENvbnRyb2wsIGludmVydCA9IGZhbHNlKTogVmFsaWRhdGlvbkVycm9yc3xudWxsID0+IHtcclxuICAgICAgY29uc3QgY3VycmVudEl0ZW1zID0gaXNBcnJheShjb250cm9sLnZhbHVlKSA/IGNvbnRyb2wudmFsdWUubGVuZ3RoIDogMDtcclxuICAgICAgY29uc3QgaXNWYWxpZCA9IGN1cnJlbnRJdGVtcyA8PSBtYXhpbXVtSXRlbXM7XHJcbiAgICAgIHJldHVybiB4b3IoaXNWYWxpZCwgaW52ZXJ0KSA/XHJcbiAgICAgICAgbnVsbCA6IHsgJ21heEl0ZW1zJzogeyBtYXhpbXVtSXRlbXMsIGN1cnJlbnRJdGVtcyB9IH07XHJcbiAgICB9O1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogJ3VuaXF1ZUl0ZW1zJyB2YWxpZGF0b3JcclxuICAgKlxyXG4gICAqIFJlcXVpcmVzIHZhbHVlcyBpbiBhIGZvcm0gYXJyYXkgdG8gYmUgdW5pcXVlLlxyXG4gICAqXHJcbiAgICogLy8ge2Jvb2xlYW4gPSB0cnVlfSB1bmlxdWU/IC0gdHJ1ZSB0byB2YWxpZGF0ZSwgZmFsc2UgdG8gZGlzYWJsZVxyXG4gICAqIC8vIHtJVmFsaWRhdG9yRm59XHJcbiAgICovXHJcbiAgc3RhdGljIHVuaXF1ZUl0ZW1zKHVuaXF1ZSA9IHRydWUpOiBJVmFsaWRhdG9yRm4ge1xyXG4gICAgaWYgKCF1bmlxdWUpIHsgcmV0dXJuIEpzb25WYWxpZGF0b3JzLm51bGxWYWxpZGF0b3I7IH1cclxuICAgIHJldHVybiAoY29udHJvbDogQWJzdHJhY3RDb250cm9sLCBpbnZlcnQgPSBmYWxzZSk6IFZhbGlkYXRpb25FcnJvcnN8bnVsbCA9PiB7XHJcbiAgICAgIGlmIChpc0VtcHR5KGNvbnRyb2wudmFsdWUpKSB7IHJldHVybiBudWxsOyB9XHJcbiAgICAgIGNvbnN0IHNvcnRlZDogYW55W10gPSBjb250cm9sLnZhbHVlLnNsaWNlKCkuc29ydCgpO1xyXG4gICAgICBjb25zdCBkdXBsaWNhdGVJdGVtcyA9IFtdO1xyXG4gICAgICBmb3IgKGxldCBpID0gMTsgaSA8IHNvcnRlZC5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgIGlmIChzb3J0ZWRbaSAtIDFdID09PSBzb3J0ZWRbaV0gJiYgZHVwbGljYXRlSXRlbXMuaW5jbHVkZXMoc29ydGVkW2ldKSkge1xyXG4gICAgICAgICAgZHVwbGljYXRlSXRlbXMucHVzaChzb3J0ZWRbaV0pO1xyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG4gICAgICBjb25zdCBpc1ZhbGlkID0gIWR1cGxpY2F0ZUl0ZW1zLmxlbmd0aDtcclxuICAgICAgcmV0dXJuIHhvcihpc1ZhbGlkLCBpbnZlcnQpID9cclxuICAgICAgICBudWxsIDogeyAndW5pcXVlSXRlbXMnOiB7IGR1cGxpY2F0ZUl0ZW1zIH0gfTtcclxuICAgIH07XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiAnY29udGFpbnMnIHZhbGlkYXRvclxyXG4gICAqXHJcbiAgICogVE9ETzogQ29tcGxldGUgdGhpcyB2YWxpZGF0b3JcclxuICAgKlxyXG4gICAqIFJlcXVpcmVzIHZhbHVlcyBpbiBhIGZvcm0gYXJyYXkgdG8gYmUgdW5pcXVlLlxyXG4gICAqXHJcbiAgICogLy8ge2Jvb2xlYW4gPSB0cnVlfSB1bmlxdWU/IC0gdHJ1ZSB0byB2YWxpZGF0ZSwgZmFsc2UgdG8gZGlzYWJsZVxyXG4gICAqIC8vIHtJVmFsaWRhdG9yRm59XHJcbiAgICovXHJcbiAgc3RhdGljIGNvbnRhaW5zKHJlcXVpcmVkSXRlbSA9IHRydWUpOiBJVmFsaWRhdG9yRm4ge1xyXG4gICAgaWYgKCFyZXF1aXJlZEl0ZW0pIHsgcmV0dXJuIEpzb25WYWxpZGF0b3JzLm51bGxWYWxpZGF0b3I7IH1cclxuICAgIHJldHVybiAoY29udHJvbDogQWJzdHJhY3RDb250cm9sLCBpbnZlcnQgPSBmYWxzZSk6IFZhbGlkYXRpb25FcnJvcnN8bnVsbCA9PiB7XHJcbiAgICAgIGlmIChpc0VtcHR5KGNvbnRyb2wudmFsdWUpIHx8ICFpc0FycmF5KGNvbnRyb2wudmFsdWUpKSB7IHJldHVybiBudWxsOyB9XHJcbiAgICAgIGNvbnN0IGN1cnJlbnRJdGVtcyA9IGNvbnRyb2wudmFsdWU7XHJcbiAgICAgIC8vIGNvbnN0IGlzVmFsaWQgPSBjdXJyZW50SXRlbXMuc29tZShpdGVtID0+XHJcbiAgICAgIC8vXHJcbiAgICAgIC8vICk7XHJcbiAgICAgIGNvbnN0IGlzVmFsaWQgPSB0cnVlO1xyXG4gICAgICByZXR1cm4geG9yKGlzVmFsaWQsIGludmVydCkgP1xyXG4gICAgICAgIG51bGwgOiB7ICdjb250YWlucyc6IHsgcmVxdWlyZWRJdGVtLCBjdXJyZW50SXRlbXMgfSB9O1xyXG4gICAgfTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIE5vLW9wIHZhbGlkYXRvci4gSW5jbHVkZWQgZm9yIGJhY2t3YXJkIGNvbXBhdGliaWxpdHkuXHJcbiAgICovXHJcbiAgc3RhdGljIG51bGxWYWxpZGF0b3IoY29udHJvbDogQWJzdHJhY3RDb250cm9sKTogVmFsaWRhdGlvbkVycm9yc3xudWxsIHtcclxuICAgIHJldHVybiBudWxsO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogVmFsaWRhdG9yIHRyYW5zZm9ybWF0aW9uIGZ1bmN0aW9uczpcclxuICAgKiBjb21wb3NlQW55T2YsIGNvbXBvc2VPbmVPZiwgY29tcG9zZUFsbE9mLCBjb21wb3NlTm90LFxyXG4gICAqIGNvbXBvc2UsIGNvbXBvc2VBc3luY1xyXG4gICAqXHJcbiAgICogVE9ETzogQWRkIGNvbXBvc2VBbnlPZkFzeW5jLCBjb21wb3NlT25lT2ZBc3luYyxcclxuICAgKiAgICAgICAgICAgY29tcG9zZUFsbE9mQXN5bmMsIGNvbXBvc2VOb3RBc3luY1xyXG4gICAqL1xyXG5cclxuICAvKipcclxuICAgKiAnY29tcG9zZUFueU9mJyB2YWxpZGF0b3IgY29tYmluYXRpb24gZnVuY3Rpb25cclxuICAgKlxyXG4gICAqIEFjY2VwdHMgYW4gYXJyYXkgb2YgdmFsaWRhdG9ycyBhbmQgcmV0dXJucyBhIHNpbmdsZSB2YWxpZGF0b3IgdGhhdFxyXG4gICAqIGV2YWx1YXRlcyB0byB2YWxpZCBpZiBhbnkgb25lIG9yIG1vcmUgb2YgdGhlIHN1Ym1pdHRlZCB2YWxpZGF0b3JzIGFyZVxyXG4gICAqIHZhbGlkLiBJZiBldmVyeSB2YWxpZGF0b3IgaXMgaW52YWxpZCwgaXQgcmV0dXJucyBjb21iaW5lZCBlcnJvcnMgZnJvbVxyXG4gICAqIGFsbCB2YWxpZGF0b3JzLlxyXG4gICAqXHJcbiAgICogLy8ge0lWYWxpZGF0b3JGbltdfSB2YWxpZGF0b3JzIC0gYXJyYXkgb2YgdmFsaWRhdG9ycyB0byBjb21iaW5lXHJcbiAgICogLy8ge0lWYWxpZGF0b3JGbn0gLSBzaW5nbGUgY29tYmluZWQgdmFsaWRhdG9yIGZ1bmN0aW9uXHJcbiAgICovXHJcbiAgc3RhdGljIGNvbXBvc2VBbnlPZih2YWxpZGF0b3JzOiBJVmFsaWRhdG9yRm5bXSk6IElWYWxpZGF0b3JGbiB7XHJcbiAgICBpZiAoIXZhbGlkYXRvcnMpIHsgcmV0dXJuIG51bGw7IH1cclxuICAgIGNvbnN0IHByZXNlbnRWYWxpZGF0b3JzID0gdmFsaWRhdG9ycy5maWx0ZXIoaXNEZWZpbmVkKTtcclxuICAgIGlmIChwcmVzZW50VmFsaWRhdG9ycy5sZW5ndGggPT09IDApIHsgcmV0dXJuIG51bGw7IH1cclxuICAgIHJldHVybiAoY29udHJvbDogQWJzdHJhY3RDb250cm9sLCBpbnZlcnQgPSBmYWxzZSk6IFZhbGlkYXRpb25FcnJvcnN8bnVsbCA9PiB7XHJcbiAgICAgIGNvbnN0IGFycmF5T2ZFcnJvcnMgPVxyXG4gICAgICAgIF9leGVjdXRlVmFsaWRhdG9ycyhjb250cm9sLCBwcmVzZW50VmFsaWRhdG9ycywgaW52ZXJ0KS5maWx0ZXIoaXNEZWZpbmVkKTtcclxuICAgICAgY29uc3QgaXNWYWxpZCA9IHZhbGlkYXRvcnMubGVuZ3RoID4gYXJyYXlPZkVycm9ycy5sZW5ndGg7XHJcbiAgICAgIHJldHVybiB4b3IoaXNWYWxpZCwgaW52ZXJ0KSA/XHJcbiAgICAgICAgbnVsbCA6IF9tZXJnZU9iamVjdHMoLi4uYXJyYXlPZkVycm9ycywgeyAnYW55T2YnOiAhaW52ZXJ0IH0pO1xyXG4gICAgfTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqICdjb21wb3NlT25lT2YnIHZhbGlkYXRvciBjb21iaW5hdGlvbiBmdW5jdGlvblxyXG4gICAqXHJcbiAgICogQWNjZXB0cyBhbiBhcnJheSBvZiB2YWxpZGF0b3JzIGFuZCByZXR1cm5zIGEgc2luZ2xlIHZhbGlkYXRvciB0aGF0XHJcbiAgICogZXZhbHVhdGVzIHRvIHZhbGlkIG9ubHkgaWYgZXhhY3RseSBvbmUgb2YgdGhlIHN1Ym1pdHRlZCB2YWxpZGF0b3JzXHJcbiAgICogaXMgdmFsaWQuIE90aGVyd2lzZSByZXR1cm5zIGNvbWJpbmVkIGluZm9ybWF0aW9uIGZyb20gYWxsIHZhbGlkYXRvcnMsXHJcbiAgICogYm90aCB2YWxpZCBhbmQgaW52YWxpZC5cclxuICAgKlxyXG4gICAqIC8vIHtJVmFsaWRhdG9yRm5bXX0gdmFsaWRhdG9ycyAtIGFycmF5IG9mIHZhbGlkYXRvcnMgdG8gY29tYmluZVxyXG4gICAqIC8vIHtJVmFsaWRhdG9yRm59IC0gc2luZ2xlIGNvbWJpbmVkIHZhbGlkYXRvciBmdW5jdGlvblxyXG4gICAqL1xyXG4gIHN0YXRpYyBjb21wb3NlT25lT2YodmFsaWRhdG9yczogSVZhbGlkYXRvckZuW10pOiBJVmFsaWRhdG9yRm4ge1xyXG4gICAgaWYgKCF2YWxpZGF0b3JzKSB7IHJldHVybiBudWxsOyB9XHJcbiAgICBjb25zdCBwcmVzZW50VmFsaWRhdG9ycyA9IHZhbGlkYXRvcnMuZmlsdGVyKGlzRGVmaW5lZCk7XHJcbiAgICBpZiAocHJlc2VudFZhbGlkYXRvcnMubGVuZ3RoID09PSAwKSB7IHJldHVybiBudWxsOyB9XHJcbiAgICByZXR1cm4gKGNvbnRyb2w6IEFic3RyYWN0Q29udHJvbCwgaW52ZXJ0ID0gZmFsc2UpOiBWYWxpZGF0aW9uRXJyb3JzfG51bGwgPT4ge1xyXG4gICAgICBjb25zdCBhcnJheU9mRXJyb3JzID1cclxuICAgICAgICBfZXhlY3V0ZVZhbGlkYXRvcnMoY29udHJvbCwgcHJlc2VudFZhbGlkYXRvcnMpO1xyXG4gICAgICBjb25zdCB2YWxpZENvbnRyb2xzID1cclxuICAgICAgICB2YWxpZGF0b3JzLmxlbmd0aCAtIGFycmF5T2ZFcnJvcnMuZmlsdGVyKGlzRGVmaW5lZCkubGVuZ3RoO1xyXG4gICAgICBjb25zdCBpc1ZhbGlkID0gdmFsaWRDb250cm9scyA9PT0gMTtcclxuICAgICAgaWYgKHhvcihpc1ZhbGlkLCBpbnZlcnQpKSB7IHJldHVybiBudWxsOyB9XHJcbiAgICAgIGNvbnN0IGFycmF5T2ZWYWxpZHMgPVxyXG4gICAgICAgIF9leGVjdXRlVmFsaWRhdG9ycyhjb250cm9sLCBwcmVzZW50VmFsaWRhdG9ycywgaW52ZXJ0KTtcclxuICAgICAgcmV0dXJuIF9tZXJnZU9iamVjdHMoLi4uYXJyYXlPZkVycm9ycywgLi4uYXJyYXlPZlZhbGlkcywgeyAnb25lT2YnOiAhaW52ZXJ0IH0pO1xyXG4gICAgfTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqICdjb21wb3NlQWxsT2YnIHZhbGlkYXRvciBjb21iaW5hdGlvbiBmdW5jdGlvblxyXG4gICAqXHJcbiAgICogQWNjZXB0cyBhbiBhcnJheSBvZiB2YWxpZGF0b3JzIGFuZCByZXR1cm5zIGEgc2luZ2xlIHZhbGlkYXRvciB0aGF0XHJcbiAgICogZXZhbHVhdGVzIHRvIHZhbGlkIG9ubHkgaWYgYWxsIHRoZSBzdWJtaXR0ZWQgdmFsaWRhdG9ycyBhcmUgaW5kaXZpZHVhbGx5XHJcbiAgICogdmFsaWQuIE90aGVyd2lzZSBpdCByZXR1cm5zIGNvbWJpbmVkIGVycm9ycyBmcm9tIGFsbCBpbnZhbGlkIHZhbGlkYXRvcnMuXHJcbiAgICpcclxuICAgKiAvLyB7SVZhbGlkYXRvckZuW119IHZhbGlkYXRvcnMgLSBhcnJheSBvZiB2YWxpZGF0b3JzIHRvIGNvbWJpbmVcclxuICAgKiAvLyB7SVZhbGlkYXRvckZufSAtIHNpbmdsZSBjb21iaW5lZCB2YWxpZGF0b3IgZnVuY3Rpb25cclxuICAgKi9cclxuICBzdGF0aWMgY29tcG9zZUFsbE9mKHZhbGlkYXRvcnM6IElWYWxpZGF0b3JGbltdKTogSVZhbGlkYXRvckZuIHtcclxuICAgIGlmICghdmFsaWRhdG9ycykgeyByZXR1cm4gbnVsbDsgfVxyXG4gICAgY29uc3QgcHJlc2VudFZhbGlkYXRvcnMgPSB2YWxpZGF0b3JzLmZpbHRlcihpc0RlZmluZWQpO1xyXG4gICAgaWYgKHByZXNlbnRWYWxpZGF0b3JzLmxlbmd0aCA9PT0gMCkgeyByZXR1cm4gbnVsbDsgfVxyXG4gICAgcmV0dXJuIChjb250cm9sOiBBYnN0cmFjdENvbnRyb2wsIGludmVydCA9IGZhbHNlKTogVmFsaWRhdGlvbkVycm9yc3xudWxsID0+IHtcclxuICAgICAgY29uc3QgY29tYmluZWRFcnJvcnMgPSBfbWVyZ2VFcnJvcnMoXHJcbiAgICAgICAgX2V4ZWN1dGVWYWxpZGF0b3JzKGNvbnRyb2wsIHByZXNlbnRWYWxpZGF0b3JzLCBpbnZlcnQpXHJcbiAgICAgICk7XHJcbiAgICAgIGNvbnN0IGlzVmFsaWQgPSBjb21iaW5lZEVycm9ycyA9PT0gbnVsbDtcclxuICAgICAgcmV0dXJuICh4b3IoaXNWYWxpZCwgaW52ZXJ0KSkgP1xyXG4gICAgICAgIG51bGwgOiBfbWVyZ2VPYmplY3RzKGNvbWJpbmVkRXJyb3JzLCB7ICdhbGxPZic6ICFpbnZlcnQgfSk7XHJcbiAgICB9O1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogJ2NvbXBvc2VOb3QnIHZhbGlkYXRvciBpbnZlcnNpb24gZnVuY3Rpb25cclxuICAgKlxyXG4gICAqIEFjY2VwdHMgYSBzaW5nbGUgdmFsaWRhdG9yIGZ1bmN0aW9uIGFuZCBpbnZlcnRzIGl0cyByZXN1bHQuXHJcbiAgICogUmV0dXJucyB2YWxpZCBpZiB0aGUgc3VibWl0dGVkIHZhbGlkYXRvciBpcyBpbnZhbGlkLCBhbmRcclxuICAgKiByZXR1cm5zIGludmFsaWQgaWYgdGhlIHN1Ym1pdHRlZCB2YWxpZGF0b3IgaXMgdmFsaWQuXHJcbiAgICogKE5vdGU6IHRoaXMgZnVuY3Rpb24gY2FuIGl0c2VsZiBiZSBpbnZlcnRlZFxyXG4gICAqICAgLSBlLmcuIGNvbXBvc2VOb3QoY29tcG9zZU5vdCh2YWxpZGF0b3IpKSAtXHJcbiAgICogICBidXQgdGhpcyBjYW4gYmUgY29uZnVzaW5nIGFuZCBpcyB0aGVyZWZvcmUgbm90IHJlY29tbWVuZGVkLilcclxuICAgKlxyXG4gICAqIC8vIHtJVmFsaWRhdG9yRm5bXX0gdmFsaWRhdG9ycyAtIHZhbGlkYXRvcihzKSB0byBpbnZlcnRcclxuICAgKiAvLyB7SVZhbGlkYXRvckZufSAtIG5ldyB2YWxpZGF0b3IgZnVuY3Rpb24gdGhhdCByZXR1cm5zIG9wcG9zaXRlIHJlc3VsdFxyXG4gICAqL1xyXG4gIHN0YXRpYyBjb21wb3NlTm90KHZhbGlkYXRvcjogSVZhbGlkYXRvckZuKTogSVZhbGlkYXRvckZuIHtcclxuICAgIGlmICghdmFsaWRhdG9yKSB7IHJldHVybiBudWxsOyB9XHJcbiAgICByZXR1cm4gKGNvbnRyb2w6IEFic3RyYWN0Q29udHJvbCwgaW52ZXJ0ID0gZmFsc2UpOiBWYWxpZGF0aW9uRXJyb3JzfG51bGwgPT4ge1xyXG4gICAgICBpZiAoaXNFbXB0eShjb250cm9sLnZhbHVlKSkgeyByZXR1cm4gbnVsbDsgfVxyXG4gICAgICBjb25zdCBlcnJvciA9IHZhbGlkYXRvcihjb250cm9sLCAhaW52ZXJ0KTtcclxuICAgICAgY29uc3QgaXNWYWxpZCA9IGVycm9yID09PSBudWxsO1xyXG4gICAgICByZXR1cm4gKHhvcihpc1ZhbGlkLCBpbnZlcnQpKSA/XHJcbiAgICAgICAgbnVsbCA6IF9tZXJnZU9iamVjdHMoZXJyb3IsIHsgJ25vdCc6ICFpbnZlcnQgfSk7XHJcbiAgICB9O1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogJ2NvbXBvc2UnIHZhbGlkYXRvciBjb21iaW5hdGlvbiBmdW5jdGlvblxyXG4gICAqXHJcbiAgICogLy8ge0lWYWxpZGF0b3JGbltdfSB2YWxpZGF0b3JzIC0gYXJyYXkgb2YgdmFsaWRhdG9ycyB0byBjb21iaW5lXHJcbiAgICogLy8ge0lWYWxpZGF0b3JGbn0gLSBzaW5nbGUgY29tYmluZWQgdmFsaWRhdG9yIGZ1bmN0aW9uXHJcbiAgICovXHJcbiAgc3RhdGljIGNvbXBvc2UodmFsaWRhdG9yczogSVZhbGlkYXRvckZuW10pOiBJVmFsaWRhdG9yRm4ge1xyXG4gICAgaWYgKCF2YWxpZGF0b3JzKSB7IHJldHVybiBudWxsOyB9XHJcbiAgICBjb25zdCBwcmVzZW50VmFsaWRhdG9ycyA9IHZhbGlkYXRvcnMuZmlsdGVyKGlzRGVmaW5lZCk7XHJcbiAgICBpZiAocHJlc2VudFZhbGlkYXRvcnMubGVuZ3RoID09PSAwKSB7IHJldHVybiBudWxsOyB9XHJcbiAgICByZXR1cm4gKGNvbnRyb2w6IEFic3RyYWN0Q29udHJvbCwgaW52ZXJ0ID0gZmFsc2UpOiBWYWxpZGF0aW9uRXJyb3JzfG51bGwgPT5cclxuICAgICAgX21lcmdlRXJyb3JzKF9leGVjdXRlVmFsaWRhdG9ycyhjb250cm9sLCBwcmVzZW50VmFsaWRhdG9ycywgaW52ZXJ0KSk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiAnY29tcG9zZUFzeW5jJyBhc3luYyB2YWxpZGF0b3IgY29tYmluYXRpb24gZnVuY3Rpb25cclxuICAgKlxyXG4gICAqIC8vIHtBc3luY0lWYWxpZGF0b3JGbltdfSBhc3luYyB2YWxpZGF0b3JzIC0gYXJyYXkgb2YgYXN5bmMgdmFsaWRhdG9yc1xyXG4gICAqIC8vIHtBc3luY0lWYWxpZGF0b3JGbn0gLSBzaW5nbGUgY29tYmluZWQgYXN5bmMgdmFsaWRhdG9yIGZ1bmN0aW9uXHJcbiAgICovXHJcbiAgc3RhdGljIGNvbXBvc2VBc3luYyh2YWxpZGF0b3JzOiBBc3luY0lWYWxpZGF0b3JGbltdKTogQXN5bmNJVmFsaWRhdG9yRm4ge1xyXG4gICAgaWYgKCF2YWxpZGF0b3JzKSB7IHJldHVybiBudWxsOyB9XHJcbiAgICBjb25zdCBwcmVzZW50VmFsaWRhdG9ycyA9IHZhbGlkYXRvcnMuZmlsdGVyKGlzRGVmaW5lZCk7XHJcbiAgICBpZiAocHJlc2VudFZhbGlkYXRvcnMubGVuZ3RoID09PSAwKSB7IHJldHVybiBudWxsOyB9XHJcbiAgICByZXR1cm4gKGNvbnRyb2w6IEFic3RyYWN0Q29udHJvbCkgPT4ge1xyXG4gICAgICBjb25zdCBvYnNlcnZhYmxlcyA9XHJcbiAgICAgICAgX2V4ZWN1dGVBc3luY1ZhbGlkYXRvcnMoY29udHJvbCwgcHJlc2VudFZhbGlkYXRvcnMpLm1hcCh0b09ic2VydmFibGUpO1xyXG4gICAgICByZXR1cm4gbWFwLmNhbGwoZm9ya0pvaW4ob2JzZXJ2YWJsZXMpLCBfbWVyZ2VFcnJvcnMpO1xyXG4gICAgfTtcclxuICB9XHJcblxyXG4gIC8vIEFkZGl0aW9uYWwgYW5ndWxhciB2YWxpZGF0b3JzIChub3QgdXNlZCBieSBBbmd1YWxyIEpTT04gU2NoZW1hIEZvcm0pXHJcbiAgLy8gRnJvbSBodHRwczovL2dpdGh1Yi5jb20vYW5ndWxhci9hbmd1bGFyL2Jsb2IvbWFzdGVyL3BhY2thZ2VzL2Zvcm1zL3NyYy92YWxpZGF0b3JzLnRzXHJcblxyXG4gIC8qKlxyXG4gICAqIFZhbGlkYXRvciB0aGF0IHJlcXVpcmVzIGNvbnRyb2xzIHRvIGhhdmUgYSB2YWx1ZSBncmVhdGVyIHRoYW4gYSBudW1iZXIuXHJcbiAgICovXHJcbiAgc3RhdGljIG1pbihtaW46IG51bWJlcik6IFZhbGlkYXRvckZuIHtcclxuICAgIGlmICghaGFzVmFsdWUobWluKSkgeyByZXR1cm4gSnNvblZhbGlkYXRvcnMubnVsbFZhbGlkYXRvcjsgfVxyXG4gICAgcmV0dXJuIChjb250cm9sOiBBYnN0cmFjdENvbnRyb2wpOiBWYWxpZGF0aW9uRXJyb3JzfG51bGwgPT4ge1xyXG4gICAgICAvLyBkb24ndCB2YWxpZGF0ZSBlbXB0eSB2YWx1ZXMgdG8gYWxsb3cgb3B0aW9uYWwgY29udHJvbHNcclxuICAgICAgaWYgKGlzRW1wdHkoY29udHJvbC52YWx1ZSkgfHwgaXNFbXB0eShtaW4pKSB7IHJldHVybiBudWxsOyB9XHJcbiAgICAgIGNvbnN0IHZhbHVlID0gcGFyc2VGbG9hdChjb250cm9sLnZhbHVlKTtcclxuICAgICAgY29uc3QgYWN0dWFsID0gY29udHJvbC52YWx1ZTtcclxuICAgICAgLy8gQ29udHJvbHMgd2l0aCBOYU4gdmFsdWVzIGFmdGVyIHBhcnNpbmcgc2hvdWxkIGJlIHRyZWF0ZWQgYXMgbm90IGhhdmluZyBhXHJcbiAgICAgIC8vIG1pbmltdW0sIHBlciB0aGUgSFRNTCBmb3JtcyBzcGVjOiBodHRwczovL3d3dy53My5vcmcvVFIvaHRtbDUvZm9ybXMuaHRtbCNhdHRyLWlucHV0LW1pblxyXG4gICAgICByZXR1cm4gaXNOYU4odmFsdWUpIHx8IHZhbHVlID49IG1pbiA/IG51bGwgOiB7ICdtaW4nOiB7IG1pbiwgYWN0dWFsIH0gfTtcclxuICAgIH07XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBWYWxpZGF0b3IgdGhhdCByZXF1aXJlcyBjb250cm9scyB0byBoYXZlIGEgdmFsdWUgbGVzcyB0aGFuIGEgbnVtYmVyLlxyXG4gICAqL1xyXG4gIHN0YXRpYyBtYXgobWF4OiBudW1iZXIpOiBWYWxpZGF0b3JGbiB7XHJcbiAgICBpZiAoIWhhc1ZhbHVlKG1heCkpIHsgcmV0dXJuIEpzb25WYWxpZGF0b3JzLm51bGxWYWxpZGF0b3I7IH1cclxuICAgIHJldHVybiAoY29udHJvbDogQWJzdHJhY3RDb250cm9sKTogVmFsaWRhdGlvbkVycm9yc3xudWxsID0+IHtcclxuICAgICAgLy8gZG9uJ3QgdmFsaWRhdGUgZW1wdHkgdmFsdWVzIHRvIGFsbG93IG9wdGlvbmFsIGNvbnRyb2xzXHJcbiAgICAgIGlmIChpc0VtcHR5KGNvbnRyb2wudmFsdWUpIHx8IGlzRW1wdHkobWF4KSkgeyByZXR1cm4gbnVsbDsgfVxyXG4gICAgICBjb25zdCB2YWx1ZSA9IHBhcnNlRmxvYXQoY29udHJvbC52YWx1ZSk7XHJcbiAgICAgIGNvbnN0IGFjdHVhbCA9IGNvbnRyb2wudmFsdWU7XHJcbiAgICAgIC8vIENvbnRyb2xzIHdpdGggTmFOIHZhbHVlcyBhZnRlciBwYXJzaW5nIHNob3VsZCBiZSB0cmVhdGVkIGFzIG5vdCBoYXZpbmcgYVxyXG4gICAgICAvLyBtYXhpbXVtLCBwZXIgdGhlIEhUTUwgZm9ybXMgc3BlYzogaHR0cHM6Ly93d3cudzMub3JnL1RSL2h0bWw1L2Zvcm1zLmh0bWwjYXR0ci1pbnB1dC1tYXhcclxuICAgICAgcmV0dXJuIGlzTmFOKHZhbHVlKSB8fCB2YWx1ZSA8PSBtYXggPyBudWxsIDogeyAnbWF4JzogeyBtYXgsIGFjdHVhbCB9IH07XHJcbiAgICB9O1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogVmFsaWRhdG9yIHRoYXQgcmVxdWlyZXMgY29udHJvbCB2YWx1ZSB0byBiZSB0cnVlLlxyXG4gICAqL1xyXG4gIHN0YXRpYyByZXF1aXJlZFRydWUoY29udHJvbDogQWJzdHJhY3RDb250cm9sKTogVmFsaWRhdGlvbkVycm9yc3xudWxsIHtcclxuICAgIGlmICghY29udHJvbCkgeyByZXR1cm4gSnNvblZhbGlkYXRvcnMubnVsbFZhbGlkYXRvcjsgfVxyXG4gICAgcmV0dXJuIGNvbnRyb2wudmFsdWUgPT09IHRydWUgPyBudWxsIDogeyAncmVxdWlyZWQnOiB0cnVlIH07XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBWYWxpZGF0b3IgdGhhdCBwZXJmb3JtcyBlbWFpbCB2YWxpZGF0aW9uLlxyXG4gICAqL1xyXG4gIHN0YXRpYyBlbWFpbChjb250cm9sOiBBYnN0cmFjdENvbnRyb2wpOiBWYWxpZGF0aW9uRXJyb3JzfG51bGwge1xyXG4gICAgaWYgKCFjb250cm9sKSB7IHJldHVybiBKc29uVmFsaWRhdG9ycy5udWxsVmFsaWRhdG9yOyB9XHJcbiAgICBjb25zdCBFTUFJTF9SRUdFWFAgPVxyXG4gICAgICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6bWF4LWxpbmUtbGVuZ3RoXHJcbiAgICAgIC9eKD89LnsxLDI1NH0kKSg/PS57MSw2NH1AKVstISMkJSYnKisvMC05PT9BLVpeX2BhLXp7fH1+XSsoXFwuWy0hIyQlJicqKy8wLTk9P0EtWl5fYGEtent8fX5dKykqQFtBLVphLXowLTldKFtBLVphLXowLTktXXswLDYxfVtBLVphLXowLTldKT8oXFwuW0EtWmEtejAtOV0oW0EtWmEtejAtOS1dezAsNjF9W0EtWmEtejAtOV0pPykqJC87XHJcbiAgICByZXR1cm4gRU1BSUxfUkVHRVhQLnRlc3QoY29udHJvbC52YWx1ZSkgPyBudWxsIDogeyAnZW1haWwnOiB0cnVlIH07XHJcbiAgfVxyXG59XHJcbiJdfQ==