@decaf-ts/for-angular 0.0.22 → 0.0.24

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 (46) hide show
  1. package/components/component-renderer/component-renderer.component.d.ts +3 -2
  2. package/components/crud-field/crud-field.component.d.ts +4 -2
  3. package/components/fieldset/fieldset.component.d.ts +10 -1
  4. package/components/for-angular-components.module.d.ts +3 -2
  5. package/components/index.d.ts +1 -1
  6. package/components/layout/layout.component.d.ts +1 -24
  7. package/components/list/list.component.d.ts +1 -2
  8. package/components/model-renderer/model-renderer.component.d.ts +6 -1
  9. package/components/steped-form/steped-form.component.d.ts +243 -0
  10. package/engine/NgxBaseComponent.d.ts +3 -3
  11. package/engine/NgxCrudFormField.d.ts +1 -0
  12. package/engine/NgxFormService.d.ts +381 -48
  13. package/engine/NgxRenderingEngine.d.ts +4 -2
  14. package/engine/constants.d.ts +12 -0
  15. package/engine/interfaces.d.ts +1 -1
  16. package/engine/types.d.ts +17 -3
  17. package/esm2022/components/component-renderer/component-renderer.component.mjs +10 -4
  18. package/esm2022/components/crud-field/crud-field.component.mjs +14 -3
  19. package/esm2022/components/crud-form/crud-form.component.mjs +3 -3
  20. package/esm2022/components/empty-state/empty-state.component.mjs +2 -2
  21. package/esm2022/components/fieldset/fieldset.component.mjs +6 -4
  22. package/esm2022/components/for-angular-components.module.mjs +10 -5
  23. package/esm2022/components/index.mjs +2 -2
  24. package/esm2022/components/layout/layout.component.mjs +4 -29
  25. package/esm2022/components/list/list.component.mjs +5 -4
  26. package/esm2022/components/model-renderer/model-renderer.component.mjs +10 -3
  27. package/esm2022/components/steped-form/steped-form.component.mjs +291 -0
  28. package/esm2022/engine/NgxBaseComponent.mjs +12 -12
  29. package/esm2022/engine/NgxCrudFormField.mjs +19 -17
  30. package/esm2022/engine/NgxFormService.mjs +438 -57
  31. package/esm2022/engine/NgxRenderingEngine.mjs +21 -10
  32. package/esm2022/engine/ValidatorFactory.mjs +4 -4
  33. package/esm2022/engine/constants.mjs +6 -1
  34. package/esm2022/engine/interfaces.mjs +1 -1
  35. package/esm2022/engine/types.mjs +1 -1
  36. package/esm2022/for-angular-common.module.mjs +4 -2
  37. package/esm2022/i18n/Loader.mjs +4 -4
  38. package/fesm2022/decaf-ts-for-angular.mjs +830 -153
  39. package/fesm2022/decaf-ts-for-angular.mjs.map +1 -1
  40. package/for-angular-common.module.d.ts +8 -2
  41. package/i18n/Loader.d.ts +2 -7
  42. package/package.json +9 -9
  43. package/assets/i18n/en.json +0 -80
  44. package/assets/i18n/pt.json +0 -80
  45. package/components/list/constants.d.ts +0 -25
  46. package/esm2022/components/list/constants.mjs +0 -6
@@ -66,12 +66,61 @@ export class NgxFormService {
66
66
  * @memberOf NgxFormService
67
67
  */
68
68
  static { this.formRegistry = new Map(); }
69
+ static { this.pageMapper = {}; }
70
+ /**
71
+ * @description Creates a new form group or form array with the specified identifier.
72
+ * @summary Generates a FormGroup or FormArray based on the provided properties. If pages are specified
73
+ * and greater than 1, creates a FormArray; otherwise creates a FormGroup. The form can optionally
74
+ * be registered in the global form registry for later access throughout the application.
75
+ *
76
+ * @param {string} id - Unique identifier for the form
77
+ * @param {Partial<IComponentInput>} [props={}] - Configuration properties for the form
78
+ * @param {boolean} [registry=true] - Whether to register the form in the global registry
79
+ * @return {FormGroup | FormArray} The created form instance
80
+ *
81
+ * @mermaid
82
+ * sequenceDiagram
83
+ * participant C as Component
84
+ * participant NFS as NgxFormService
85
+ * participant FR as Form Registry
86
+ * participant AF as Angular Forms
87
+ *
88
+ * C->>NFS: createForm(id, props, registry)
89
+ * NFS->>FR: Check if form exists
90
+ * alt Form doesn't exist
91
+ * alt props.pages > 1
92
+ * NFS->>AF: new FormArray([])
93
+ * else
94
+ * NFS->>AF: new FormGroup({})
95
+ * end
96
+ * alt registry is true
97
+ * NFS->>FR: addRegistry(id, form)
98
+ * end
99
+ * end
100
+ * NFS-->>C: Return FormGroup | FormArray
101
+ *
102
+ * @static
103
+ * @memberOf NgxFormService
104
+ */
105
+ static createForm(id, props = {}, registry = true) {
106
+ const form = this.formRegistry.get(id) ?? (props?.pages && props?.pages > 1 ? new FormArray([]) : new FormGroup({}));
107
+ if (!this.formRegistry.has(id) && registry)
108
+ this.addRegistry(id, form);
109
+ return form;
110
+ }
69
111
  /**
70
112
  * @description Adds a form to the registry.
71
- * @summary Registers a FormGroup with a unique identifier. Throws an error if the identifier is already in use.
72
- * @param {string} formId - The unique identifier for the form.
73
- * @param {FormGroup} formGroup - The FormGroup to be registered.
74
- * @throws {Error} If a FormGroup with the given id is already registered.
113
+ * @summary Registers a FormGroup or FormArray with a unique identifier for global access throughout
114
+ * the application. This allows forms to be retrieved and managed centrally. Throws an error if
115
+ * the identifier is already in use to prevent conflicts.
116
+ *
117
+ * @param {string} formId - The unique identifier for the form
118
+ * @param {FormParent} formGroup - The FormGroup or FormArray to be registered
119
+ * @return {void}
120
+ * @throws {Error} If a FormGroup with the given id is already registered
121
+ *
122
+ * @static
123
+ * @memberOf NgxFormService
75
124
  */
76
125
  static addRegistry(formId, formGroup) {
77
126
  if (this.formRegistry.has(formId))
@@ -80,8 +129,15 @@ export class NgxFormService {
80
129
  }
81
130
  /**
82
131
  * @description Removes a form from the registry.
83
- * @summary Deletes a FormGroup from the registry using its unique identifier.
84
- * @param {string} formId - The unique identifier of the form to be removed.
132
+ * @summary Deletes a FormGroup or FormArray from the registry using its unique identifier.
133
+ * This cleans up the registry and allows the identifier to be reused. The form itself
134
+ * is not destroyed, only removed from the central registry.
135
+ *
136
+ * @param {string} formId - The unique identifier of the form to be removed
137
+ * @return {void}
138
+ *
139
+ * @static
140
+ * @memberOf NgxFormService
85
141
  */
86
142
  static removeRegistry(formId) {
87
143
  this.formRegistry.delete(formId);
@@ -89,9 +145,38 @@ export class NgxFormService {
89
145
  /**
90
146
  * @description Resolves the parent group and control name from a path.
91
147
  * @summary Traverses the form group structure to find the parent group and control name for a given path.
92
- * @param {FormGroup} formGroup - The root FormGroup.
93
- * @param {string} path - The path to the control.
94
- * @return {FormParentGroup} A tuple containing the parent FormGroup and the control name.
148
+ * Handles complex nested structures including arrays and sub-groups. Creates missing intermediate
149
+ * groups as needed and properly configures FormArray controls for multiple value scenarios.
150
+ *
151
+ * @param {FormGroup} formGroup - The root FormGroup to traverse
152
+ * @param {string} path - The dot-separated path to the control (e.g., 'user.address.street')
153
+ * @param {IComponentInput} componentProps - Properties defining the component configuration
154
+ * @param {KeyValue} parentProps - Properties from the parent component for context
155
+ * @return {FormParentGroup} A tuple containing the parent FormGroup and the control name
156
+ *
157
+ * @private
158
+ * @mermaid
159
+ * sequenceDiagram
160
+ * participant NFS as NgxFormService
161
+ * participant FG as FormGroup
162
+ * participant FA as FormArray
163
+ *
164
+ * NFS->>NFS: Split path into parts
165
+ * loop For each path part
166
+ * alt Control doesn't exist
167
+ * alt isMultiple and part is childOf
168
+ * NFS->>FA: new FormArray([new FormGroup({})])
169
+ * else
170
+ * NFS->>FG: new FormGroup({})
171
+ * end
172
+ * NFS->>FG: addControl(part, newControl)
173
+ * end
174
+ * NFS->>NFS: Navigate to next level
175
+ * end
176
+ * NFS-->>NFS: Return [parentGroup, controlName]
177
+ *
178
+ * @static
179
+ * @memberOf NgxFormService
95
180
  */
96
181
  static resolveParentGroup(formGroup, path, componentProps, parentProps) {
97
182
  const isMultiple = parentProps?.['multiple'] || parentProps?.['type'] === 'Array' || false;
@@ -270,19 +355,62 @@ export class NgxFormService {
270
355
  if (!parentGroup.get(controlName)) {
271
356
  const control = NgxFormService.fromProps(componentProps, componentProps.updateMode || 'change');
272
357
  NgxFormService.register(control, componentProps);
273
- parentGroup.addControl(controlName, control);
358
+ if (parentGroup instanceof FormGroup) {
359
+ parentGroup.addControl(controlName, control);
360
+ }
361
+ if (parentGroup instanceof FormArray) {
362
+ const root = parentGroup.controls[componentProps?.['page'] - 1];
363
+ if (root) {
364
+ root.addControl(controlName, control);
365
+ }
366
+ else {
367
+ parentGroup.push({ [controlName]: control });
368
+ }
369
+ }
274
370
  }
275
- componentProps['formGroup'] = parentGroup;
371
+ const root = parentGroup instanceof FormArray ? parentGroup.controls[componentProps?.['page'] - 1] : parentGroup;
372
+ componentProps['formGroup'] = root;
276
373
  componentProps['formControl'] = parentGroup.get(controlName);
277
374
  componentProps['multiple'] = isMultiple;
278
375
  }
279
376
  /**
280
377
  * @description Retrieves a control from a registered form.
281
378
  * @summary Finds and returns an AbstractControl from a registered form using the form id and optional path.
282
- * @param {string} formId - The unique identifier of the form.
283
- * @param {string} [path] - The path to the control within the form.
284
- * @return {AbstractControl} The requested AbstractControl.
285
- * @throws {Error} If the form is not found in the registry or the control is not found in the form.
379
+ * This method provides centralized access to form controls across the application by leveraging
380
+ * the form registry system.
381
+ *
382
+ * @param {string} formId - The unique identifier of the form in the registry
383
+ * @param {string} [path] - The optional dot-separated path to a specific control within the form
384
+ * @return {AbstractControl} The requested AbstractControl (FormGroup, FormArray, or FormControl)
385
+ * @throws {Error} If the form is not found in the registry or the control is not found in the form
386
+ *
387
+ * @mermaid
388
+ * sequenceDiagram
389
+ * participant C as Component
390
+ * participant NFS as NgxFormService
391
+ * participant FR as Form Registry
392
+ *
393
+ * C->>NFS: getControlFromForm(formId, path?)
394
+ * NFS->>FR: Get form by formId
395
+ * alt Form not found
396
+ * FR-->>NFS: null
397
+ * NFS-->>C: Throw Error
398
+ * else Form found
399
+ * FR-->>NFS: Return form
400
+ * alt path provided
401
+ * NFS->>NFS: form.get(path)
402
+ * alt Control not found
403
+ * NFS-->>C: Throw Error
404
+ * else
405
+ * NFS-->>C: Return control
406
+ * end
407
+ * else
408
+ * NFS-->>C: Return form
409
+ * end
410
+ * end
411
+ *
412
+ * @static
413
+ * @memberOf NgxFormService
286
414
  */
287
415
  static getControlFromForm(formId, path) {
288
416
  const form = this.formRegistry.get(formId);
@@ -295,13 +423,77 @@ export class NgxFormService {
295
423
  throw new Error(`Control with path '${path}' not found in form '${formId}'.`);
296
424
  return control;
297
425
  }
426
+ /**
427
+ * @description Creates a form from UI model metadata children.
428
+ * @summary Generates a FormGroup from an array of UIModelMetadata objects, extracting component
429
+ * properties and creating appropriate form controls. This method is specifically designed to work
430
+ * with the UI decorator system and provides automatic form generation from metadata.
431
+ *
432
+ * @param {string} id - Unique identifier for the form
433
+ * @param {boolean} [registry=false] - Whether to register the created form in the global registry
434
+ * @param {UIModelMetadata[]} [children] - Array of UI model metadata objects to create controls from
435
+ * @return {FormGroup} The created FormGroup with controls for each child metadata
436
+ *
437
+ * @mermaid
438
+ * sequenceDiagram
439
+ * participant C as Component
440
+ * participant NFS as NgxFormService
441
+ * participant AF as Angular Forms
442
+ *
443
+ * C->>NFS: createFormFromChildren(id, registry, children)
444
+ * NFS->>AF: new FormGroup({})
445
+ * loop For each child metadata
446
+ * NFS->>NFS: addFormControl(form, child.props)
447
+ * NFS->>AF: Create and add FormControl
448
+ * end
449
+ * alt registry is true
450
+ * NFS->>NFS: addRegistry(id, form)
451
+ * end
452
+ * NFS-->>C: Return FormGroup
453
+ *
454
+ * @static
455
+ * @memberOf NgxFormService
456
+ */
457
+ static createFormFromChildren(id, registry = false, children) {
458
+ const form = new FormGroup({});
459
+ if (children?.length)
460
+ children.forEach(child => {
461
+ this.addFormControl(form, child.props);
462
+ });
463
+ if (registry)
464
+ this.addRegistry(id, form);
465
+ return form;
466
+ }
298
467
  /**
299
468
  * @description Creates a form from component configurations.
300
469
  * @summary Generates a FormGroup based on an array of component configurations and optionally registers it.
301
- * @param {string} id - The unique identifier for the form.
302
- * @param {IComponentConfig[]} components - An array of component configurations.
303
- * @param {boolean} [registry=false] - Whether to register the created form.
304
- * @return {FormGroup} The created FormGroup.
470
+ * This method processes component input configurations to create appropriate form controls with
471
+ * validation and initial values.
472
+ *
473
+ * @param {string} id - The unique identifier for the form
474
+ * @param {IComponentConfig[]} components - An array of component configurations defining the form structure
475
+ * @param {boolean} [registry=false] - Whether to register the created form in the global registry
476
+ * @return {FormGroup} The created FormGroup with controls for each component configuration
477
+ *
478
+ * @mermaid
479
+ * sequenceDiagram
480
+ * participant C as Component
481
+ * participant NFS as NgxFormService
482
+ * participant AF as Angular Forms
483
+ *
484
+ * C->>NFS: createFormFromComponents(id, components, registry)
485
+ * NFS->>AF: new FormGroup({})
486
+ * loop For each component config
487
+ * NFS->>NFS: addFormControl(form, component.inputs)
488
+ * NFS->>AF: Create and add FormControl
489
+ * end
490
+ * alt registry is true
491
+ * NFS->>NFS: addRegistry(id, form)
492
+ * end
493
+ * NFS-->>C: Return FormGroup
494
+ *
495
+ * @static
496
+ * @memberOf NgxFormService
305
497
  */
306
498
  static createFormFromComponents(id, components, registry = false) {
307
499
  const form = new FormGroup({});
@@ -315,14 +507,61 @@ export class NgxFormService {
315
507
  /**
316
508
  * @description Adds a control to a form based on component properties.
317
509
  * @summary Creates and adds a form control to a form (existing or new) based on the provided component properties.
318
- * @param {string} id - The unique identifier of the form.
319
- * @param {FieldProperties} componentProperties - The properties of the component to create the control from.
320
- * @return {AbstractControl} The form or created control.
510
+ * Handles multi-page forms by managing FormArray structures and proper indexing. This method supports
511
+ * complex form scenarios including nested controls and page-based form organization.
512
+ *
513
+ * @param {string} id - The unique identifier of the form
514
+ * @param {FieldProperties} componentProperties - The properties of the component to create the control from
515
+ * @param {FieldProperties} [parentProps] - Optional parent properties for context and configuration
516
+ * @return {AbstractControl} The form or created control
517
+ *
518
+ * @mermaid
519
+ * sequenceDiagram
520
+ * participant C as Component
521
+ * participant NFS as NgxFormService
522
+ * participant F as Form
523
+ *
524
+ * C->>NFS: addControlFromProps(id, componentProps, parentProps?)
525
+ * NFS->>NFS: createForm(id, parentProps, true)
526
+ * alt Multi-page form (parentProps.pages > 1)
527
+ * NFS->>NFS: Calculate page index
528
+ * NFS->>F: Get or create FormGroup at index
529
+ * NFS->>NFS: Set form to page FormGroup
530
+ * end
531
+ * alt componentProperties has path
532
+ * NFS->>NFS: addFormControl(form, componentProperties, parentProps)
533
+ * end
534
+ * NFS-->>C: Return form/control
535
+ *
536
+ * @static
537
+ * @memberOf NgxFormService
321
538
  */
322
539
  static addControlFromProps(id, componentProperties, parentProps) {
323
- const form = this.formRegistry.get(id) ?? new FormGroup({});
324
- if (!this.formRegistry.has(id))
325
- this.addRegistry(id, form);
540
+ let form = this.createForm(id, parentProps, true);
541
+ const formLength = form.length;
542
+ if (parentProps?.pages && parentProps?.pages > 1) {
543
+ let index = componentProperties.page || parentProps.page;
544
+ if (!(typeof index === 'number') || index === 0)
545
+ throw Error(`Property 'page' is required and greather than 0 on ${componentProperties.name}`);
546
+ if (index > formLength) {
547
+ if (form?.['lastIndex'] && index === form['lastIndex']['page']) {
548
+ index = form['lastIndex']['index'];
549
+ }
550
+ else {
551
+ form['lastIndex'] = {
552
+ page: index,
553
+ index: formLength + 1
554
+ };
555
+ index = formLength + 1;
556
+ }
557
+ }
558
+ let group = form.controls[index - 1];
559
+ if (!group) {
560
+ group = new FormGroup({});
561
+ form.insert(index, group);
562
+ }
563
+ form = group;
564
+ }
326
565
  if (componentProperties.path)
327
566
  this.addFormControl(form, componentProperties, parentProps);
328
567
  return form;
@@ -330,8 +569,45 @@ export class NgxFormService {
330
569
  /**
331
570
  * @description Retrieves form data from a FormGroup.
332
571
  * @summary Extracts and processes the data from a FormGroup, handling different input types and nested form groups.
333
- * @param {FormGroup} formGroup - The FormGroup to extract data from.
334
- * @return {Record<string, unknown>} An object containing the form data.
572
+ * Performs type conversion for various HTML5 input types, validates nested controls, and manages
573
+ * multiple control scenarios. Automatically enables all group controls after data extraction.
574
+ *
575
+ * @param {FormGroup} formGroup - The FormGroup to extract data from
576
+ * @return {Record<string, unknown>} An object containing the processed form data with proper type conversions
577
+ *
578
+ * @mermaid
579
+ * sequenceDiagram
580
+ * participant C as Component
581
+ * participant NFS as NgxFormService
582
+ * participant FG as FormGroup
583
+ * participant FC as FormControl
584
+ *
585
+ * C->>NFS: getFormData(formGroup)
586
+ * loop For each control in formGroup
587
+ * alt Control is not FormControl
588
+ * NFS->>NFS: Recursive getFormData(control)
589
+ * alt parentProps.multiple and !isValid
590
+ * NFS->>NFS: reset(control)
591
+ * end
592
+ * else Control is FormControl
593
+ * NFS->>FC: Get control value
594
+ * NFS->>NFS: Apply type conversion based on props.type
595
+ * alt HTML5CheckTypes
596
+ * NFS->>NFS: Keep boolean value
597
+ * else NUMBER type
598
+ * NFS->>NFS: parseToNumber(value)
599
+ * else DATE/DATETIME types
600
+ * NFS->>NFS: new Date(value)
601
+ * else Other types
602
+ * NFS->>NFS: escapeHtml(value)
603
+ * end
604
+ * end
605
+ * end
606
+ * NFS->>NFS: enableAllGroupControls(formGroup)
607
+ * NFS-->>C: Return processed data object
608
+ *
609
+ * @static
610
+ * @memberOf NgxFormService
335
611
  */
336
612
  static getFormData(formGroup) {
337
613
  const data = {};
@@ -376,10 +652,51 @@ export class NgxFormService {
376
652
  /**
377
653
  * @description Validates fields in a form control or form group.
378
654
  * @summary Recursively validates all fields in a form control or form group, marking them as touched and dirty.
379
- * @param {AbstractControl} control - The control or form group to validate.
380
- * @param {string} [path] - The path to the control within the form.
381
- * @return {boolean} True if all fields are valid, false otherwise.
382
- * @throws {Error} If no control is found at the specified path or if the control type is unknown.
655
+ * Performs comprehensive validation including uniqueness checks for primary keys in FormArray scenarios.
656
+ * This method ensures all validation rules are applied and form state is properly updated.
657
+ *
658
+ * @param {AbstractControl} control - The control or form group to validate
659
+ * @param {string} [pk] - Optional primary key field name for uniqueness validation
660
+ * @param {string} [path] - The path to the control within the form for error reporting
661
+ * @return {boolean} True if all fields are valid, false otherwise
662
+ * @throws {Error} If no control is found at the specified path or if the control type is unknown
663
+ *
664
+ * @mermaid
665
+ * sequenceDiagram
666
+ * participant C as Component
667
+ * participant NFS as NgxFormService
668
+ * participant FC as FormControl
669
+ * participant FG as FormGroup
670
+ * participant FA as FormArray
671
+ *
672
+ * C->>NFS: validateFields(control, pk?, path?)
673
+ * alt Control is FormControl
674
+ * NFS->>FC: markAsTouched()
675
+ * NFS->>FC: markAsDirty()
676
+ * NFS->>FC: updateValueAndValidity()
677
+ * alt Is in FormArray group
678
+ * NFS->>NFS: Check uniqueness in group
679
+ * alt Not unique
680
+ * NFS->>FC: setErrors({notUnique: true})
681
+ * end
682
+ * end
683
+ * NFS-->>C: Return control.valid
684
+ * else Control is FormGroup
685
+ * loop For each child control
686
+ * NFS->>NFS: Recursive validateFields(child)
687
+ * end
688
+ * NFS-->>C: Return allValid
689
+ * else Control is FormArray
690
+ * loop For each array control
691
+ * NFS->>NFS: Recursive validateFields(child)
692
+ * end
693
+ * NFS-->>C: Return allValid
694
+ * else Unknown control type
695
+ * NFS-->>C: Throw Error
696
+ * end
697
+ *
698
+ * @static
699
+ * @memberOf NgxFormService
383
700
  */
384
701
  static validateFields(control, pk, path) {
385
702
  control = path ? control.get(path) : control;
@@ -419,13 +736,13 @@ export class NgxFormService {
419
736
  });
420
737
  }
421
738
  }
422
- function getControlName(control) {
423
- const group = control.parent;
424
- if (!group)
425
- return null;
426
- return Object.keys(group.controls).find(name => control === group.get(name)) || null;
427
- }
428
- return !getControlName(control) ? true : control.valid;
739
+ // function getControlName(control: AbstractControl): string | null {
740
+ // const group = control.parent as FormGroup;
741
+ // if (!group)
742
+ // return null;
743
+ // return Object.keys(group.controls).find(name => control === group.get(name)) || null;
744
+ // }
745
+ return control.valid;
429
746
  }
430
747
  /**
431
748
  * @description Generates validators from component properties.
@@ -443,10 +760,38 @@ export class NgxFormService {
443
760
  }
444
761
  /**
445
762
  * @description Creates a FormControl from component properties.
446
- * @summary Generates a FormControl with validators based on the provided component properties.
447
- * @param {FieldProperties} props - The component properties.
448
- * @param {FieldUpdateMode} [updateMode='change'] - The update mode for the control.
449
- * @return {FormControl} The created FormControl.
763
+ * @summary Generates a FormControl with validators and initial configuration based on the provided
764
+ * component properties. Handles different input types, sets initial values, and configures
765
+ * validation rules and update modes.
766
+ *
767
+ * @param {FieldProperties} props - The component properties defining the control configuration
768
+ * @param {FieldUpdateMode} [updateMode='change'] - The update mode for the control ('change', 'blur', 'submit')
769
+ * @return {FormControl} The created FormControl with proper configuration and validators
770
+ *
771
+ * @mermaid
772
+ * sequenceDiagram
773
+ * participant C as Component
774
+ * participant NFS as NgxFormService
775
+ * participant VF as ValidatorFactory
776
+ * participant AF as Angular Forms
777
+ *
778
+ * C->>NFS: fromProps(props, updateMode?)
779
+ * NFS->>NFS: validatorsFromProps(props)
780
+ * NFS->>VF: Create validators from props
781
+ * VF-->>NFS: Return validator array
782
+ * NFS->>NFS: Compose validators
783
+ * alt props.value exists and not checkbox
784
+ * alt props.type is DATE
785
+ * NFS->>NFS: Validate date format
786
+ * end
787
+ * NFS->>NFS: Set initial value
788
+ * end
789
+ * NFS->>AF: new FormControl(config)
790
+ * AF-->>NFS: Return FormControl
791
+ * NFS-->>C: Return configured FormControl
792
+ *
793
+ * @static
794
+ * @memberOf NgxFormService
450
795
  */
451
796
  static fromProps(props, updateMode = 'change') {
452
797
  const validators = this.validatorsFromProps(props);
@@ -464,21 +809,50 @@ export class NgxFormService {
464
809
  });
465
810
  }
466
811
  /**
467
- * @description Retrieves properties from a FormControl.
468
- * @summary Gets the FieldProperties associated with a FormControl from the internal WeakMap.
469
- * @param {FormControl} control - The FormControl to get properties for.
470
- * @return {FieldProperties} The properties associated with the control.
812
+ * @description Retrieves properties from a FormControl, FormArray, or FormGroup.
813
+ * @summary Gets the FieldProperties associated with a form control from the internal WeakMap.
814
+ * This method provides access to the original component properties that were used to create
815
+ * the control, enabling validation, rendering, and behavior configuration.
816
+ *
817
+ * @param {FormControl | FormArray | FormGroup} control - The form control to get properties for
818
+ * @return {FieldProperties} The properties associated with the control, or empty object if not found
819
+ *
820
+ * @static
821
+ * @memberOf NgxFormService
471
822
  */
472
823
  static getPropsFromControl(control) {
473
824
  return this.controls.get(control) || {};
474
825
  }
475
826
  /**
476
- * @description Finds a parent element with a specific tag.
477
- * @summary Traverses up the DOM tree to find the nearest parent element with the specified tag.
478
- * @param {HTMLElement} el - The starting element.
479
- * @param {string} tag - The tag name to search for.
480
- * @return {HTMLElement} The found parent element.
481
- * @throws {Error} If no parent with the specified tag is found.
827
+ * @description Finds a parent element with a specific tag in the DOM tree.
828
+ * @summary Traverses up the DOM tree to find the nearest parent element with the specified tag name.
829
+ * This is useful for finding container elements or specific parent components in the DOM hierarchy.
830
+ * The search is case-insensitive for tag name matching.
831
+ *
832
+ * @param {HTMLElement} el - The starting element to traverse from
833
+ * @param {string} tag - The tag name to search for (case-insensitive)
834
+ * @return {HTMLElement} The found parent element with the specified tag
835
+ * @throws {Error} If no parent with the specified tag is found in the DOM tree
836
+ *
837
+ * @mermaid
838
+ * sequenceDiagram
839
+ * participant C as Component
840
+ * participant NFS as NgxFormService
841
+ * participant DOM as DOM Tree
842
+ *
843
+ * C->>NFS: getParentEl(element, tagName)
844
+ * loop Traverse up DOM tree
845
+ * NFS->>DOM: Get parentElement
846
+ * DOM-->>NFS: Return parent or null
847
+ * alt Parent exists and tag matches
848
+ * NFS-->>C: Return parent element
849
+ * else Parent is null
850
+ * NFS-->>C: Throw Error
851
+ * end
852
+ * end
853
+ *
854
+ * @static
855
+ * @memberOf NgxFormService
482
856
  */
483
857
  static getParentEl(el, tag) {
484
858
  let parent;
@@ -491,10 +865,17 @@ export class NgxFormService {
491
865
  throw new Error(`No parent with the tag ${tag} was found for provided element`);
492
866
  }
493
867
  /**
494
- * @description Registers a control with its properties.
495
- * @summary Associates a control with its properties in the internal WeakMap.
496
- * @param {AbstractControl} control - The control to register.
497
- * @param {FieldProperties} props - The properties to associate with the control.
868
+ * @description Registers a control with its properties in the internal WeakMap.
869
+ * @summary Associates a form control with its component properties for later retrieval.
870
+ * This enables the service to maintain metadata about controls without creating memory leaks,
871
+ * as WeakMap automatically cleans up references when controls are garbage collected.
872
+ *
873
+ * @param {AbstractControl} control - The control to register (FormControl, FormGroup, or FormArray)
874
+ * @param {FieldProperties} props - The properties to associate with the control
875
+ * @return {void}
876
+ *
877
+ * @static
878
+ * @memberOf NgxFormService
498
879
  */
499
880
  static register(control, props) {
500
881
  this.controls.set(control, props);
@@ -533,4 +914,4 @@ export class NgxFormService {
533
914
  }
534
915
  }
535
916
  }
536
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiTmd4Rm9ybVNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvbGliL2VuZ2luZS9OZ3hGb3JtU2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsVUFBVSxFQUFtQixlQUFlLEVBQUUsZUFBZSxFQUFFLGFBQWEsRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBR3ZILE9BQU8sRUFBRSxlQUFlLEVBQUUsU0FBUyxFQUFFLFdBQVcsRUFBRSxTQUFTLEVBQWUsVUFBVSxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDN0csT0FBTyxFQUFFLFdBQVcsRUFBRSxTQUFTLEVBQUUsU0FBUyxFQUFFLFVBQVUsRUFBRSxVQUFVLEVBQUUsTUFBTSxnQ0FBZ0MsQ0FBQztBQUMzRyxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUN0RCxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sWUFBWSxDQUFDO0FBQ3pDLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUN4RCxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUc1RTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQXFDRztBQUNILE1BQU0sT0FBTyxjQUFjO0lBQ3pCOzs7Ozs7Ozs7T0FTRzthQUNZLGFBQVEsR0FBRyxJQUFJLE9BQU8sRUFBb0MsQ0FBQztJQUUxRTs7Ozs7Ozs7O09BU0c7YUFDWSxpQkFBWSxHQUFHLElBQUksR0FBRyxFQUFxQixDQUFDO0lBQzNEOzs7Ozs7T0FNRztJQUNILE1BQU0sQ0FBQyxXQUFXLENBQUMsTUFBYyxFQUFFLFNBQW9CO1FBQ3JELElBQUksSUFBSSxDQUFDLFlBQVksQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDO1lBQy9CLE1BQU0sSUFBSSxLQUFLLENBQUMsd0JBQXdCLE1BQU0sMEJBQTBCLENBQUMs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OztPQUtHO0lBQ0gsTUFBTSxDQUFDLFVBQVUsQ0FBQyxPQUF3QjtRQUN4QyxPQUFPLElBQUksQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxDQUFDO0lBQ3ZDLENBQUM7SUFFRDs7OztPQUlHO0lBQ0gsTUFBTSxDQUFDLEtBQUssQ0FBQyxTQUFrQztRQUM3QyxJQUFHLFNBQVMsWUFBWSxXQUFXLEVBQUUsQ0FBQztZQUNwQyxNQUFNLE9BQU8sR0FBRyxTQUF3QixDQUFDO1lBQ3pDLE1BQU0sRUFBRSxJQUFJLEVBQUUsR0FBRyxjQUFjLENBQUMsbUJBQW1CLENBQUMsT0FBTyxDQUFDLENBQUM7WUFDN0QsSUFBSSxDQUFDLGVBQWUsQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDO2dCQUNqQyxPQUFPLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQyxDQUFDO1lBQ3ZCLE9BQU8sQ0FBQyxjQUFjLEVBQUUsQ0FBQztZQUN6QixPQUFPLENBQUMsZUFBZSxFQUFFLENBQUM7WUFDMUIsT0FBTyxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUN4QixPQUFPLENBQUMsc0JBQXNCLEVBQUUsQ0FBQztRQUNuQyxDQUFDO2FBQU0sQ0FBQztZQUNOLEtBQUssTUFBTSxHQUFHLElBQUksU0FBUyxDQUFDLFFBQVEsRUFBRSxDQUFDO2dCQUNyQyxNQUFNLE9BQU8sR0FBRyxTQUFTLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxDQUFDO2dCQUN4QyxjQUFjLENBQUMsS0FBSyxDQUFDLE9BQXNCLENBQUMsQ0FBQztnQkFDN0MsU0FBUztZQUNYLENBQUM7UUFDSCxDQUFDO0lBQ0gsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IGVzY2FwZUh0bWwsIEZpZWxkUHJvcGVydGllcywgSFRNTDVDaGVja1R5cGVzLCBIVE1MNUlucHV0VHlwZXMsIHBhcnNlVG9OdW1iZXIgfSBmcm9tICdAZGVjYWYtdHMvdWktZGVjb3JhdG9ycyc7XG5pbXBvcnQgeyBGaWVsZFVwZGF0ZU1vZGUsIEZvcm1QYXJlbnRHcm91cCwgS2V5VmFsdWUgfSBmcm9tICcuL3R5cGVzJztcbmltcG9ydCB7IElDb21wb25lbnRDb25maWcsIElDb21wb25lbnRJbnB1dCB9IGZyb20gJy4vaW50ZXJmYWNlcyc7XG5pbXBvcnQgeyBBYnN0cmFjdENvbnRyb2wsIEZvcm1BcnJheSwgRm9ybUNvbnRyb2wsIEZvcm1Hcm91cCwgVmFsaWRhdG9yRm4sIFZhbGlkYXRvcnMgfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XG5pbXBvcnQgeyBpc1ZhbGlkRGF0ZSwgTW9kZWxLZXlzLCBwYXJzZURhdGUsIFByaW1pdGl2ZXMsIFZhbGlkYXRpb24gfSBmcm9tICdAZGVjYWYtdHMvZGVjb3JhdG9yLXZhbGlkYXRpb24nO1xuaW1wb3J0IHsgVmFsaWRhdG9yRmFjdG9yeSB9IGZyb20gJy4vVmFsaWRhdG9yRmFjdG9yeSc7XG5pbXBvcnQgeyBjbGVhblNwYWNlcyB9IGZyb20gJy4uL2hlbHBlcnMnO1xuaW1wb3J0IHsgT3BlcmF0aW9uS2V5cyB9IGZyb20gJ0BkZWNhZi10cy9kYi1kZWNvcmF0b3JzJztcbmltcG9ydCB7IEFuZ3VsYXJFbmdpbmVLZXlzLCBCYXNlQ29tcG9uZW50UHJvcHMgfSBmcm9tICcuLi9lbmdpbmUvY29uc3RhbnRzJztcblxuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBTZXJ2aWNlIGZvciBtYW5hZ2luZyBBbmd1bGFyIGZvcm1zIGFuZCBmb3JtIGNvbnRyb2xzLlxuICogQHN1bW1hcnkgVGhlIE5neEZvcm1TZXJ2aWNlIHByb3ZpZGVzIHV0aWxpdHkgbWV0aG9kcyBmb3IgY3JlYXRpbmcsIG1hbmFnaW5nLCBhbmQgdmFsaWRhdGluZyBBbmd1bGFyIGZvcm1zIGFuZCBmb3JtIGNvbnRyb2xzLiBJdCBpbmNsdWRlcyBmdW5jdGlvbmFsaXR5IGZvciByZWdpc3RlcmluZyBmb3JtcywgYWRkaW5nIGNvbnRyb2xzLCB2YWxpZGF0aW5nIGZpZWxkcywgYW5kIGhhbmRsaW5nIGZvcm0gZGF0YS5cbiAqXG4gKiBAY2xhc3NcbiAqIEBwYXJhbSB7V2Vha01hcDxBYnN0cmFjdENvbnRyb2wsIEZpZWxkUHJvcGVydGllcz59IGNvbnRyb2xzIC0gQSBXZWFrTWFwIHRvIHN0b3JlIGNvbnRyb2wgcHJvcGVydGllcy5cbiAqIEBwYXJhbSB7TWFwPHN0cmluZywgRm9ybUdyb3VwPn0gZm9ybVJlZ2lzdHJ5IC0gQSBNYXAgdG8gc3RvcmUgcmVnaXN0ZXJlZCBmb3Jtcy5cbiAqXG4gKiBAZXhhbXBsZVxuICogLy8gQ3JlYXRpbmcgYSBmb3JtIGZyb20gY29tcG9uZW50c1xuICogY29uc3QgY29tcG9uZW50cyA9IFtcbiAqICAgeyBpbnB1dHM6IHsgbmFtZTogJ3VzZXJuYW1lJywgdHlwZTogJ3RleHQnLCByZXF1aXJlZDogdHJ1ZSB9IH0sXG4gKiAgIHsgaW5wdXRzOiB7IG5hbWU6ICdwYXNzd29yZCcsIHR5cGU6ICdwYXNzd29yZCcsIG1pbkxlbmd0aDogOCB9IH1cbiAqIF07XG4gKiBjb25zdCBmb3JtID0gTmd4Rm9ybVNlcnZpY2UuY3JlYXRlRm9ybUZyb21Db21wb25lbnRzKCdsb2dpbkZvcm0nLCBjb21wb25lbnRzLCB0cnVlKTtcbiAqXG4gKiAvLyBWYWxpZGF0aW5nIGZpZWxkc1xuICogTmd4Rm9ybVNlcnZpY2UudmFsaWRhdGVGaWVsZHMoZm9ybSk7XG4gKlxuICogLy8gR2V0dGluZyBmb3JtIGRhdGFcbiAqIGNvbnN0IGZvcm1EYXRhID0gTmd4Rm9ybVNlcnZpY2UuZ2V0Rm9ybURhdGEoZm9ybSk7XG4gKlxuICogQG1lcm1haWRcbiAqIHNlcXVlbmNlRGlhZ3JhbVxuICogICBwYXJ0aWNpcGFudCBDIGFzIENvbXBvbmVudFxuICogICBwYXJ0aWNpcGFudCBORlMgYXMgTmd4Rm9ybVNlcnZpY2VcbiAqICAgcGFydGljaXBhbnQgQUYgYXMgQW5ndWxhciBGb3Jtc1xuICogICBDLT4+TkZTOiBjcmVhdGVGb3JtRnJvbUNvbXBvbmVudHMoKVxuICogICBORlMtPj5BRjogbmV3IEZvcm1Hcm91cCgpXG4gKiAgIE5GUy0+Pk5GUzogYWRkRm9ybUNvbnRyb2woKVxuICogICBORlMtPj5BRjogYWRkQ29udHJvbCgpXG4gKiAgIE5GUy0tPj5DOiBSZXR1cm4gRm9ybUdyb3VwXG4gKiAgIEMtPj5ORlM6IHZhbGlkYXRlRmllbGRzKClcbiAqICAgTkZTLT4+QUY6IG1hcmtBc1RvdWNoZWQoKSwgbWFya0FzRGlydHkoKSwgdXBkYXRlVmFsdWVBbmRWYWxpZGl0eSgpXG4gKiAgIEMtPj5ORlM6IGdldEZvcm1EYXRhKClcbiAqICAgTkZTLT4+QUY6IEdldCBjb250cm9sIHZhbHVlc1xuICogICBORlMtLT4+QzogUmV0dXJuIGZvcm0gZGF0YVxuICovXG5leHBvcnQgY2xhc3MgTmd4Rm9ybVNlcnZpY2Uge1xuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFdlYWtNYXAgdGhhdCBzdG9yZXMgY29udHJvbCBwcm9wZXJ0aWVzIGZvciBmb3JtIGNvbnRyb2xzLlxuICAgKiBAc3VtbWFyeSBBIFdlYWtNYXAgdGhhdCBhc3NvY2lhdGVzIEFic3RyYWN0Q29udHJvbCBpbnN0YW5jZXMgd2l0aCB0aGVpciBjb3JyZXNwb25kaW5nIEZpZWxkUHJvcGVydGllcy5cbiAgICogVGhpcyBhbGxvd3MgdGhlIHNlcnZpY2UgdG8gdHJhY2sgbWV0YWRhdGEgZm9yIGZvcm0gY29udHJvbHMgd2l0aG91dCBjcmVhdGluZyBtZW1vcnkgbGVha3MuXG4gICAqXG4gICAqIEB0eXBlIHtXZWFrTWFwPEFic3RyYWN0Q29udHJvbCwgRmllbGRQcm9wZXJ0aWVzPn1cbiAgICogQHByaXZhdGVcbiAgICogQHN0YXRpY1xuICAgKiBAbWVtYmVyT2YgTmd4Rm9ybVNlcnZpY2VcbiAgICovXG4gIHByaXZhdGUgc3RhdGljIGNvbnRyb2xzID0gbmV3IFdlYWtNYXA8QWJzdHJhY3RDb250cm9sLCBGaWVsZFByb3BlcnRpZXM+KCk7XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBSZWdpc3RyeSBvZiBmb3JtIGdyb3VwcyBpbmRleGVkIGJ5IHRoZWlyIHVuaXF1ZSBpZGVudGlmaWVycy5cbiAgICogQHN1bW1hcnkgQSBNYXAgdGhhdCBzdG9yZXMgRm9ybUdyb3VwIGluc3RhbmNlcyB3aXRoIHRoZWlyIHVuaXF1ZSBzdHJpbmcgaWRlbnRpZmllcnMuXG4gICAqIFRoaXMgYWxsb3dzIGdsb2JhbCBhY2Nlc3MgdG8gcmVnaXN0ZXJlZCBmb3JtcyB0aHJvdWdob3V0IHRoZSBhcHBsaWNhdGlvbi5cbiAgICpcbiAgICogQHR5cGUge01hcDxzdHJpbmcsIEZvcm1Hcm91cD59XG4gICAqIEBwcml2YXRlXG4gICAqIEBzdGF0aWNcbiAgICogQG1lbWJlck9mIE5neEZvcm1TZXJ2aWNlXG4gICAqL1xuICBwcml2YXRlIHN0YXRpYyBmb3JtUmVnaXN0cnkgPSBuZXcgTWFwPHN0cmluZywgRm9ybUdyb3VwPigpO1xuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIEFkZHMgYSBmb3JtIHRvIHRoZSByZWdpc3RyeS5cbiAgICogQHN1bW1hcnkgUmVnaXN0ZXJzIGEgRm9ybUdyb3VwIHdpdGggYSB1bmlxdWUgaWRlbnRpZmllci4gVGhyb3dzIGFuIGVycm9yIGlmIHRoZSBpZGVudGlmaWVyIGlzIGFscmVhZHkgaW4gdXNlLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gZm9ybUlkIC0gVGhlIHVuaXF1ZSBpZGVudGlmaWVyIGZvciB0aGUgZm9ybS5cbiAgICogQHBhcmFtIHtGb3JtR3JvdXB9IGZvcm1Hcm91cCAtIFRoZSBGb3JtR3JvdXAgdG8gYmUgcmVnaXN0ZXJlZC5cbiAgICogQHRocm93cyB7RXJyb3J9IElmIGEgRm9ybUdyb3VwIHdpdGggdGhlIGdpdmVuIGlkIGlzIGFscmVhZHkgcmVnaXN0ZXJlZC5cbiAgICovXG4gIHN0YXRpYyBhZGRSZWdpc3RyeShmb3JtSWQ6IHN0cmluZywgZm9ybUdyb3VwOiBGb3JtR3JvdXApOiB2b2lkIHtcbiAgICBpZiAodGhpcy5mb3JtUmVnaXN0cnkuaGFzKGZvcm1JZCkpXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYEEgRm9ybUdyb3VwIHdpdGggaWQgJyR7Zm9ybUlkfScgaXMgYWxyZWFkeSByZWdpc3RlcmVkLmApO1xuICAgIHRoaXMuZm9ybVJlZ2lzdHJ5LnNldChmb3JtSWQsIGZvcm1Hcm91cCk7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFJlbW92ZXMgYSBmb3JtIGZyb20gdGhlIHJlZ2lzdHJ5LlxuICAgKiBAc3VtbWFyeSBEZWxldGVzIGEgRm9ybUdyb3VwIGZyb20gdGhlIHJlZ2lzdHJ5IHVzaW5nIGl0cyB1bmlxdWUgaWRlbnRpZmllci5cbiAgICogQHBhcmFtIHtzdHJpbmd9IGZvcm1JZCAtIFRoZSB1bmlxdWUgaWRlbnRpZmllciBvZiB0aGUgZm9ybSB0byBiZSByZW1vdmVkLlxuICAgKi9cbiAgc3RhdGljIHJlbW92ZVJlZ2lzdHJ5KGZvcm1JZDogc3RyaW5nKTogdm9pZCB7XG4gICAgdGhpcy5mb3JtUmVnaXN0cnkuZGVsZXRlKGZvcm1JZCk7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFJlc29sdmVzIHRoZSBwYXJlbnQgZ3JvdXAgYW5kIGNvbnRyb2wgbmFtZSBmcm9tIGEgcGF0aC5cbiAgICogQHN1bW1hcnkgVHJhdmVyc2VzIHRoZSBmb3JtIGdyb3VwIHN0cnVjdHVyZSB0byBmaW5kIHRoZSBwYXJlbnQgZ3JvdXAgYW5kIGNvbnRyb2wgbmFtZSBmb3IgYSBnaXZlbiBwYXRoLlxuICAgKiBAcGFyYW0ge0Zvcm1Hcm91cH0gZm9ybUdyb3VwIC0gVGhlIHJvb3QgRm9ybUdyb3VwLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gcGF0aCAtIFRoZSBwYXRoIHRvIHRoZSBjb250cm9sLlxuICAgKiBAcmV0dXJuIHtGb3JtUGFyZW50R3JvdXB9IEEgdHVwbGUgY29udGFpbmluZyB0aGUgcGFyZW50IEZvcm1Hcm91cCBhbmQgdGhlIGNvbnRyb2wgbmFtZS5cbiAgICovXG4gIHByaXZhdGUgc3RhdGljIHJlc29sdmVQYXJlbnRHcm91cChmb3JtR3JvdXA6IEZvcm1Hcm91cCwgcGF0aDogc3RyaW5nLCBjb21wb25lbnRQcm9wczogSUNvbXBvbmVudElucHV0LCBwYXJlbnRQcm9wczogS2V5VmFsdWUpOiBGb3JtUGFyZW50R3JvdXAge1xuICAgIGNvbnN0IGlzTXVsdGlwbGUgPSBwYXJlbnRQcm9wcz8uWydtdWx0aXBsZSddIHx8IHBhcmVudFByb3BzPy5bJ3R5cGUnXSA9PT0gJ0FycmF5JyB8fCBmYWxzZTtcbiAgICBjb25zdCBwYXJ0cyA9IHBhdGguc3BsaXQoJy4nKTtcbiAgICBjb25zdCBjb250cm9sTmFtZSA9IHBhcnRzLnBvcCgpIGFzIHN0cmluZztcbiAgICBjb25zdCB7Y2hpbGRPZn0gPSBjb21wb25lbnRQcm9wc1xuICAgIGxldCBjdXJyZW50R3JvdXAgPSBmb3JtR3JvdXA7XG5cbiAgICBmdW5jdGlvbiBzZXRBcnJheUNvbXBvbmVudFByb3BzKGZvcm1Hcm91cEFycmF5OiBGb3JtQXJyYXkpIHtcbiAgICAgIGNvbnN0IHByb3BzID0gKGZvcm1Hcm91cEFycmF5IGFzIEtleVZhbHVlKVtBbmd1bGFyRW5naW5lS2V5cy5GT1JNX0dST1VQX0NPTVBPTkVOVF9QUk9QU10gfHwge307XG4gICAgICAgIGlmKCFwcm9wc1tNb2RlbEtleXMuTU9ERUxdW2NvbnRyb2xOYW1lXSlcbiAgICAgICAgICBwcm9wc1tNb2RlbEtleXMuTU9ERUxdID0gT2JqZWN0LmFzc2lnbih7fSwgcHJvcHNbTW9kZWxLZXlzLk1PREVMXSwge1tjb250cm9sTmFtZV06IHsuLi5jb21wb25lbnRQcm9wc319KTtcbiAgICB9XG5cbiAgICBmb3IgKGNvbnN0IHBhcnQgb2YgcGFydHMpIHtcbiAgICAgIGlmICghY3VycmVudEdyb3VwLmdldChwYXJ0KSkge1xuICAgICAgICBjb25zdCBwYXJ0Rm9ybUdyb3VwID0gKGlzTXVsdGlwbGUgJiYgcGFydCA9PT0gY2hpbGRPZikgPyBuZXcgRm9ybUFycmF5KFtuZXcgRm9ybUdyb3VwKHt9KV0pIDogbmV3IEZvcm1Hcm91cCh7fSk7XG4gICAgICAgIChwYXJ0Rm9ybUdyb3VwIGFzIEtleVZhbHVlKVtBbmd1bGFyRW5naW5lS2V5cy5GT1JNX0dST1VQX0NPTVBPTkVOVF9QUk9QU10gPSB7XG4gICAgICAgICAgY2hpbGRPZjogY2hpbGRPZiB8fCAnJyxcbiAgICAgICAgICBpc011bHRpcGxlOiBpc011bHRpcGxlLFxuICAgICAgICAgIG5hbWU6IHBhcnQsXG4gICAgICAgICAgcGs6IGNvbXBvbmVudFByb3BzPy5bJ3BrJ10gfHwgcGFyZW50UHJvcHM/LlsncGsnXSB8fCAnJyxcbiAgICAgICAgICBbTW9kZWxLZXlzLk1PREVMXToge30sXG4gICAgICAgIH0gYXMgUGFydGlhbDxGaWVsZFByb3BlcnRpZXM+ICYge21vZGVsOiBLZXlWYWx1ZX07XG5cbiAgICAgICAgaWYoY3VycmVudEdyb3VwIGluc3RhbmNlb2YgRm9ybUFycmF5KSB7XG4gICAgICAgICAgKGN1cnJlbnRHcm91cCBhcyBGb3JtQXJyYXkpLnB1c2gocGFydEZvcm1Hcm91cCk7XG4gICAgICAgIH0gZWxzZSB7XG5cbiAgICAgICAgICBmb3IoY29uc3QgY29udHJvbCBvZiBPYmplY3QudmFsdWVzKHBhcnRGb3JtR3JvdXAuY29udHJvbHMpKSB7XG4gICAgICAgICAgICBpZihjb250cm9sIGluc3RhbmNlb2YgRm9ybUNvbnRyb2wpXG4gICAgICAgICAgICAgIHRoaXMucmVnaXN0ZXIoY29udHJvbCBhcyBBYnN0cmFjdENvbnRyb2wsIGNvbXBvbmVudFByb3BzKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZihwYXJ0Rm9ybUdyb3VwIGluc3RhbmNlb2YgQWJzdHJhY3RDb250cm9sKVxuICAgICAgICAgICAgdGhpcy5yZWdpc3RlcihwYXJ0Rm9ybUdyb3VwIGFzIEFic3RyYWN0Q29udHJvbCwgY29tcG9uZW50UHJvcHMpO1xuXG4gICAgICAgICAgY3VycmVudEdyb3VwLmFkZENvbnRyb2wocGFydCwgcGFydEZvcm1Hcm91cCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmKGNoaWxkT2YgJiYgY3VycmVudEdyb3VwIGluc3RhbmNlb2YgRm9ybUFycmF5KVxuICAgICAgICBzZXRBcnJheUNvbXBvbmVudFByb3BzKGN1cnJlbnRHcm91cCk7XG5cbiAgICAgIGN1cnJlbnRHcm91cCA9IGN1cnJlbnRHcm91cC5nZXQocGFydCkgYXMgRm9ybUdyb3VwO1xuICAgIH1cbiAgICByZXR1cm4gW2N1cnJlbnRHcm91cCwgY29udHJvbE5hbWVdO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBSZXRyaWV2ZXMgY29tcG9uZW50IHByb3BlcnRpZXMgZnJvbSBhIEZvcm1Hcm91cCBvciBGb3JtQXJyYXkuXG4gICAqIEBzdW1tYXJ5IEV4dHJhY3RzIGNvbXBvbmVudCBwcm9wZXJ0aWVzIHN0b3JlZCBpbiB0aGUgZm9ybSBncm91cCBtZXRhZGF0YS4gSWYgYSBGb3JtR3JvdXAgaXMgcHJvdmlkZWRcbiAgICogYW5kIGdyb3VwQXJyYXlOYW1lIGlzIHNwZWNpZmllZCwgaXQgd2lsbCBsb29rIGZvciB0aGUgRm9ybUFycmF5IHdpdGhpbiB0aGUgZm9ybSBzdHJ1Y3R1cmUuXG4gICAqXG4gICAqIEBwYXJhbSB7Rm9ybUdyb3VwIHwgRm9ybUFycmF5fSBmb3JtR3JvdXAgLSBUaGUgZm9ybSBncm91cCBvciBmb3JtIGFycmF5IHRvIGV4dHJhY3QgcHJvcGVydGllcyBmcm9tXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBba2V5XSAtIE9wdGlvbmFsIGtleSB0byByZXRyaWV2ZSBhIHNwZWNpZmljIHByb3BlcnR5XG4gICAqIEBwYXJhbSB7c3RyaW5nfSBbZ3JvdXBBcnJheU5hbWVdIC0gT3B0aW9uYWwgbmFtZSBvZiB0aGUgZ3JvdXAgYXJyYXkgaWYgZm9ybUdyb3VwIGlzIG5vdCBhIEZvcm1BcnJheVxuICAgKiBAcmV0dXJuIHtQYXJ0aWFsPEZpZWxkUHJvcGVydGllcz59IFRoZSBjb21wb25lbnQgcHJvcGVydGllcyBvciBhIHNwZWNpZmljIHByb3BlcnR5IGlmIGtleSBpcyBwcm92aWRlZFxuICAgKlxuICAgKiBAc3RhdGljXG4gICAqIEBtZW1iZXJPZiBOZ3hGb3JtU2VydmljZVxuICAgKi9cbiAgc3RhdGljIGdldENvbXBvbmVudFByb3BzRnJvbUdyb3VwQXJyYXkoZm9ybUdyb3VwOiBGb3JtR3JvdXAgfCBGb3JtQXJyYXksIGtleT86IHN0cmluZywgZ3JvdXBBcnJheU5hbWU/OiBzdHJpbmcgfCB1bmRlZmluZWQpOiBQYXJ0aWFsPEZpZWxkUHJvcGVydGllcz4ge1xuICAgIGlmKCEoZm9ybUdyb3VwIGluc3RhbmNlb2YgRm9ybUFycmF5KSAmJiB0eXBlb2YgZ3JvdXBBcnJheU5hbWUgPT09IFByaW1pdGl2ZXMuU1RSSU5HKVxuICAgICAgZm9ybUdyb3VwID0gZm9ybUdyb3VwLnJvb3QuZ2V0KGdyb3VwQXJyYXlOYW1lIGFzIHN0cmluZykgYXMgRm9ybUFycmF5IHx8IHt9O1xuICAgIGNvbnN0IHByb3BzID0gKGZvcm1Hcm91cCBhcyBLZXlWYWx1ZSk/LltBbmd1bGFyRW5naW5lS2V5cy5GT1JNX0dST1VQX0NPTVBPTkVOVF9QUk9QU10gfHwge307XG4gICAgcmV0dXJuICgha2V5ID8gcHJvcHMgOiBwcm9wcz8uW2tleV0pIHx8IHt9O1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBBZGRzIGEgbmV3IGdyb3VwIHRvIGEgcGFyZW50IEZvcm1BcnJheS5cbiAgICogQHN1bW1hcnkgQ3JlYXRlcyBhbmQgYWRkcyBhIG5ldyBGb3JtR3JvdXAgdG8gdGhlIHNwZWNpZmllZCBwYXJlbnQgRm9ybUFycmF5IGJhc2VkIG9uIHRoZVxuICAgKiBjb21wb25lbnQgcHJvcGVydGllcyBzdG9yZWQgaW4gdGhlIHBhcmVudCdzIG1ldGFkYXRhLiBUaGlzIGlzIHVzZWQgZm9yIGR5bmFtaWMgZm9ybSBhcnJheXNcbiAgICogd2hlcmUgbmV3IGdyb3VwcyBuZWVkIHRvIGJlIGFkZGVkIGF0IHJ1bnRpbWUuXG4gICAqXG4gICAqIEBwYXJhbSB7Rm9ybUdyb3VwfSBmb3JtR3JvdXAgLSBUaGUgcm9vdCBmb3JtIGdyb3VwIGNvbnRhaW5pbmcgdGhlIHBhcmVudCBGb3JtQXJyYXlcbiAgICogQHBhcmFtIHtzdHJpbmd9IHBhcmVudE5hbWUgLSBUaGUgbmFtZSBvZiB0aGUgcGFyZW50IEZvcm1BcnJheSB0byBhZGQgdGhlIGdyb3VwIHRvXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBbaW5kZXg9MV0gLSBUaGUgaW5kZXggcG9zaXRpb24gd2hlcmUgdGhlIG5ldyBncm91cCBzaG91bGQgYmUgYWRkZWRcbiAgICogQHJldHVybiB7Rm9ybUdyb3VwfSBUaGUgbmV3bHkgY3JlYXRlZCBhbmQgYWRkZWQgRm9ybUdyb3VwXG4gICAqXG4gICAqIEBzdGF0aWNcbiAgICogQG1lbWJlck9mIE5neEZvcm1TZXJ2aWNlXG4gICAqL1xuICBzdGF0aWMgYWRkR3JvdXBUb1BhcmVudChmb3JtR3JvdXA6IEZvcm1Hcm91cCwgcGFyZW50TmFtZTogc3RyaW5nLCBpbmRleDogbnVtYmVyID0gMSk6IEZvcm1Hcm91cCB7XG4gICAgY29uc3QgY29tcG9uZW50UHJvcHMgPSB0aGlzLmdldENvbXBvbmVudFByb3BzRnJvbUdyb3VwQXJyYXkoZm9ybUdyb3VwLCBNb2RlbEtleXMuTU9ERUwsIHBhcmVudE5hbWUpO1xuICAgIE9iamVjdC5lbnRyaWVzKGNvbXBvbmVudFByb3BzIGFzIEtleVZhbHVlKS5mb3JFYWNoKChbLCB2YWx1ZV0pID0+IHtcbiAgICAgIHJldHVybiB0aGlzLmFkZEZvcm1Db250cm9sKGZvcm1Hcm91cCwgdmFsdWUsIHttdWx0aXBsZTogdHJ1ZX0sIGluZGV4KTtcbiAgICB9KTtcblxuICAgIHJldHVybiB0aGlzLmdldEdyb3VwRnJvbVBhcmVudChmb3JtR3JvdXAsIHBhcmVudE5hbWUsIGluZGV4KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gUmV0cmlldmVzIGEgRm9ybUdyb3VwIGZyb20gYSBwYXJlbnQgRm9ybUFycmF5IGF0IHRoZSBzcGVjaWZpZWQgaW5kZXguXG4gICAqIEBzdW1tYXJ5IEdldHMgYSBGb3JtR3JvdXAgZnJvbSB0aGUgc3BlY2lmaWVkIHBhcmVudCBGb3JtQXJyYXkuIElmIHRoZSBncm91cCBkb2Vzbid0IGV4aXN0XG4gICAqIGF0IHRoZSBnaXZlbiBpbmRleCwgaXQgd2lsbCBjcmVhdGUgYSBuZXcgb25lIHVzaW5nIGFkZEdyb3VwVG9QYXJlbnQuXG4gICAqXG4gICAqIEBwYXJhbSB7Rm9ybUdyb3VwfSBmb3JtR3JvdXAgLSBUaGUgcm9vdCBmb3JtIGdyb3VwIGNvbnRhaW5pbmcgdGhlIHBhcmVudCBGb3JtQXJyYXlcbiAgICogQHBhcmFtIHtzdHJpbmd9IHBhcmVudE5hbWUgLSBUaGUgbmFtZSBvZiB0aGUgcGFyZW50IEZvcm1BcnJheSB0byByZXRyaWV2ZSB0aGUgZ3JvdXAgZnJvbVxuICAgKiBAcGFyYW0ge251bWJlcn0gW2luZGV4PTFdIC0gVGhlIGluZGV4IG9mIHRoZSBncm91cCB0byByZXRyaWV2ZVxuICAgKiBAcmV0dXJuIHtGb3JtR3JvdXB9IFRoZSBGb3JtR3JvdXAgYXQgdGhlIHNwZWNpZmllZCBpbmRleFxuICAgKlxuICAgKiBAc3RhdGljXG4gICAqIEBtZW1iZXJPZiBOZ3hGb3JtU2VydmljZVxuICAgKi9cbiAgc3RhdGljIGdldEdyb3VwRnJvbVBhcmVudChmb3JtR3JvdXA6IEZvcm1Hcm91cCwgcGFyZW50TmFtZTogc3RyaW5nLCBpbmRleDogbnVtYmVyID0gMSk6IEZvcm1Hcm91cCB7XG4gICAgY29uc3QgY2hpbGRHcm91cCA9ICgoZm9ybUdyb3VwLmdldChwYXJlbnROYW1lKSB8fCBmb3JtR3JvdXApIGFzIEZvcm1BcnJheSkuYXQoaW5kZXgpO1xuICAgIGlmKGNoaWxkR3JvdXAgaW5zdGFuY2VvZiBGb3JtR3JvdXApXG4gICAgICByZXR1cm4gY2hpbGRHcm91cDtcbiAgICByZXR1cm4gdGhpcy5hZGRHcm91cFRvUGFyZW50KGZvcm1Hcm91cCwgcGFyZW50TmFtZSwgaW5kZXgpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBDaGVja3MgaWYgYSB2YWx1ZSBpcyB1bmlxdWUgd2l0aGluIGEgRm9ybUFycmF5IGdyb3VwLlxuICAgKiBAc3VtbWFyeSBWYWxpZGF0ZXMgdGhhdCB0aGUgcHJpbWFyeSBrZXkgdmFsdWUgaW4gYSBGb3JtR3JvdXAgaXMgdW5pcXVlIGFtb25nIGFsbCBncm91cHNcbiAgICogaW4gdGhlIHBhcmVudCBGb3JtQXJyYXkuIFRoZSB1bmlxdWVuZXNzIGNoZWNrIGJlaGF2aW9yIGRpZmZlcnMgYmFzZWQgb24gdGhlIG9wZXJhdGlvbiB0eXBlLlxuICAgKlxuICAgKiBAcGFyYW0ge0Zvcm1Hcm91cH0gZm9ybUdyb3VwIC0gVGhlIEZvcm1Hcm91cCB0byBjaGVjayBmb3IgdW5pcXVlbmVzc1xuICAgKiBAcGFyYW0ge251bWJlcn0gaW5kZXggLSBUaGUgaW5kZXggb2YgdGhlIGN1cnJlbnQgZ3JvdXAgd2l0aGluIHRoZSBGb3JtQXJyYXlcbiAgICogQHBhcmFtIHtPcGVyYXRpb25LZXlzfSBbb3BlcmF0aW9uPU9wZXJhdGlvbktleXMuQ1JFQVRFXSAtIFRoZSB0eXBlIG9mIG9wZXJhdGlvbiBiZWluZyBwZXJmb3JtZWRcbiAgICogQHJldHVybiB7Ym9vbGVhbn0gVHJ1ZSBpZiB0aGUgdmFsdWUgaXMgdW5pcXVlLCBmYWxzZSBvdGhlcndpc2VcbiAgICpcbiAgICogQHN0YXRpY1xuICAgKiBAbWVtYmVyT2YgTmd4Rm9ybVNlcnZpY2VcbiAgICovXG4gIHN0YXRpYyBpc1VuaXF1ZU9uR3JvdXAoZm9ybUdyb3VwOiBGb3JtR3JvdXAsIGluZGV4OiBudW1iZXIsIG9wZXJhdGlvbjogT3BlcmF0aW9uS2V5cyA9IE9wZXJhdGlvbktleXMuQ1JFQVRFKTogYm9vbGVhbiB7XG4gICAgY29uc3QgZm9ybUdyb3VwQXJyYXkgPSBmb3JtR3JvdXAucGFyZW50IGFzIEZvcm1BcnJheTtcbiAgICBjb25zdCBwayA9IHRoaXMuZ2V0Q29tcG9uZW50UHJvcHNGcm9tR3JvdXBBcnJheShmb3JtR3JvdXBBcnJheSwgQmFzZUNvbXBvbmVudFByb3BzLlBLIGFzIHN0cmluZykgYXMgc3RyaW5nO1xuICAgIGNvbnN0IGNvbnRyb2xOYW1lID0gT2JqZWN0LmtleXMoZm9ybUdyb3VwLmNvbnRyb2xzKVswXTtcblxuICAgIC8vIG9ubHkgY2hlY2sgZm9yIHVuaXF1ZSBpZiBpcyB0aGUgcGsgY29udHJvbFxuICAgIGlmKGNvbnRyb2xOYW1lICE9PSBwaylcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIGNvbnN0IGNvbnRyb2xWYWx1ZSA9IGNsZWFuU3BhY2VzKGAke2Zvcm1Hcm91cC5nZXQocGspPy52YWx1ZX1gLCB0cnVlKTtcbiAgICBpZihvcGVyYXRpb24gPT09IE9wZXJhdGlvbktleXMuQ1JFQVRFKVxuICAgICAgcmV0dXJuICFmb3JtR3JvdXBBcnJheS5jb250cm9scy5zb21lKChncm91cCwgaSkgPT4gaSAhPT0gaW5kZXggJiYgY2xlYW5TcGFjZXMoYCR7Z3JvdXAuZ2V0KHBrKT8udmFsdWV9YCwgdHJ1ZSkgPT09IGNvbnRyb2xWYWx1ZSk7XG5cbiAgICByZXR1cm4gIWZvcm1Hcm91cEFycmF5LmNvbnRyb2xzLnNvbWUoKGdyb3VwLCBpKSA9PiB7XG4gICAgICBjb25zdCB2YWx1ZSA9IGNsZWFuU3BhY2VzKGAke2dyb3VwLmdldChwayk/LnZhbHVlfWAsIHRydWUpO1xuICAgICAgcmV0dXJuIGkgIT09IGluZGV4ICYmIGNvbnRyb2xWYWx1ZSA9PT0gdmFsdWU7XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIEVuYWJsZXMgYWxsIGNvbnRyb2xzIHdpdGhpbiBhIEZvcm1Hcm91cCBvciBGb3JtQXJyYXkuXG4gICAqIEBzdW1tYXJ5IFJlY3Vyc2l2ZWx5IGVuYWJsZXMgYWxsIGZvcm0gY29udHJvbHMgd2l0aGluIHRoZSBwcm92aWRlZCBGb3JtR3JvdXAgb3IgRm9ybUFycmF5LlxuICAgKiBUaGlzIGlzIHVzZWZ1bCBmb3IgbWFraW5nIGFsbCBjb250cm9scyBpbnRlcmFjdGl2ZSBhZnRlciB0aGV5IGhhdmUgYmVlbiBkaXNhYmxlZC5cbiAgICpcbiAgICogQHBhcmFtIHtGb3JtQXJyYXkgfCBGb3JtR3JvdXB9IGZvcm1Hcm91cCAtIFRoZSBGb3JtR3JvdXAgb3IgRm9ybUFycmF5IHRvIGVuYWJsZSBhbGwgY29udHJvbHMgZm9yXG4gICAqIEByZXR1cm4ge3ZvaWR9XG4gICAqXG4gICAqIEBzdGF0aWNcbiAgICogQG1lbWJlck9mIE5neEZvcm1TZXJ2aWNlXG4gICAqL1xuICBzdGF0aWMgZW5hYmxlQWxsR3JvdXBDb250cm9scyhmb3JtR3JvdXA6IEZvcm1BcnJheSB8IEZvcm1Hcm91cCk6IHZvaWQge1xuICAgIE9iamVjdC5rZXlzKGZvcm1Hcm91cC5jb250cm9scykuZm9yRWFjaChrZXkgPT4ge1xuICAgICAgY29uc3QgY29udHJvbCA9IGZvcm1Hcm91cC5nZXQoa2V5KTtcbiAgICAgIGlmIChjb250cm9sIGluc3RhbmNlb2YgRm9ybUFycmF5KSB7XG4gICAgICAgIGNvbnRyb2wuY29udHJvbHMuZm9yRWFjaChjaGlsZCA9PiB7XG4gICAgICAgICAgaWYgKGNoaWxkIGluc3RhbmNlb2YgRm9ybUdyb3VwKSB7XG4gICAgICAgICAgICBjaGlsZC5lbmFibGUoeyBlbWl0RXZlbnQ6IGZhbHNlIH0pO1xuICAgICAgICAgICAgY2hpbGQudXBkYXRlVmFsdWVBbmRWYWxpZGl0eSh7IGVtaXRFdmVudDogdHJ1ZSB9KTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBBZGRzIGEgZm9ybSBjb250cm9sIHRvIGEgZm9ybSBncm91cCBiYXNlZCBvbiBjb21wb25lbnQgcHJvcGVydGllcy5cbiAgICogQHN1bW1hcnkgQ3JlYXRlcyBhbmQgY29uZmlndXJlcyBhIEZvcm1Db250cm9sIHdpdGhpbiB0aGUgc3BlY2lmaWVkIEZvcm1Hcm91cCB1c2luZyB0aGUgcHJvdmlkZWRcbiAgICogY29tcG9uZW50IHByb3BlcnRpZXMuIEhhbmRsZXMgbmVzdGVkIHBhdGhzLCBtdWx0aXBsZSBjb250cm9scyAoRm9ybUFycmF5cyksIGFuZCBjb250cm9sIHJlZ2lzdHJhdGlvbi5cbiAgICogVGhpcyBtZXRob2Qgc3VwcG9ydHMgY29tcGxleCBmb3JtIHN0cnVjdHVyZXMgd2l0aCBuZXN0ZWQgZ3JvdXBzIGFuZCBhcnJheXMuXG4gICAqXG4gICAqIEBwYXJhbSB7Rm9ybUdyb3VwfSBmb3JtR3JvdXAgLSBUaGUgZm9ybSBncm91cCB0byBhZGQgdGhlIGNvbnRyb2wgdG9cbiAgICogQHBhcmFtIHtJQ29tcG9uZW50SW5wdXR9IGNvbXBvbmVudFByb3BzIC0gVGhlIGNvbXBvbmVudCBwcm9wZXJ0aWVzIGRlZmluaW5nIHRoZSBjb250cm9sIGNvbmZpZ3VyYXRpb25cbiAgICogQHBhcmFtIHtLZXlWYWx1ZX0gW3BhcmVudFByb3BzPXt9XSAtIFByb3BlcnRpZXMgZnJvbSB0aGUgcGFyZW50IGNvbXBvbmVudCBmb3IgY29udGV4dFxuICAgKiBAcGFyYW0ge251bWJlcn0gW2luZGV4PTBdIC0gVGhlIGluZGV4IGZvciBtdWx0aXBsZSBjb250cm9scyBpbiBGb3JtQXJyYXlzXG4gICAqIEByZXR1cm4ge3ZvaWR9XG4gICAqXG4gICAqIEBwcml2YXRlXG4gICAqIEBzdGF0aWNcbiAgICogQG1lbWJlck9mIE5neEZvcm1TZXJ2aWNlXG4gICAqL1xuICBwcml2YXRlIHN0YXRpYyBhZGRGb3JtQ29udHJvbChmb3JtR3JvdXA6IEZvcm1Hcm91cCwgY29tcG9uZW50UHJvcHM6IElDb21wb25lbnRJbnB1dCwgcGFyZW50UHJvcHM6IEtleVZhbHVlID0ge30sIGluZGV4OiBudW1iZXIgPSAwKTogdm9pZCB7XG5cbiAgICBjb25zdCBpc011bHRpcGxlID0gcGFyZW50UHJvcHM/LlsnbXVsdGlwbGUnXSB8fCBwYXJlbnRQcm9wcz8uWyd0eXBlJ10gPT09ICdBcnJheScgfHwgZmFsc2U7XG4gICAgY29uc3QgeyBuYW1lLCBjaGlsZE9mLCB9ID0gY29tcG9uZW50UHJvcHM7XG4gICAgaWYoaXNNdWx0aXBsZSlcbiAgICAgIGNvbXBvbmVudFByb3BzWydwayddID0gY29tcG9uZW50UHJvcHNbJ3BrJ10gfHwgcGFyZW50UHJvcHM/LlsncGsnXSB8fCAnJztcbiAgICBjb25zdCBmdWxsUGF0aCA9IGNoaWxkT2YgPyBpc011bHRpcGxlID8gYCR7Y2hpbGRPZn0uJHtpbmRleH0uJHtuYW1lfWAgOiBgJHtjaGlsZE9mfS4ke25hbWV9YCA6IG5hbWU7XG4gICAgY29uc3QgW3BhcmVudEdyb3VwLCBjb250cm9sTmFtZV0gPSB0aGlzLnJlc29sdmVQYXJlbnRHcm91cChmb3JtR3JvdXAsIGZ1bGxQYXRoLCBjb21wb25lbnRQcm9wcywgcGFyZW50UHJvcHMpO1xuXG4gICAgaWYgKCFwYXJlbnRHcm91cC5nZXQoY29udHJvbE5hbWUpKSB7XG4gICAgICBjb25zdCBjb250cm9sID0gTmd4Rm9ybVNlcnZpY2UuZnJvbVByb3BzKFxuICAgICAgICBjb21wb25lbnRQcm9wcyxcbiAgICAgICAgY29tcG9uZW50UHJvcHMudXBkYXRlTW9kZSB8fCAnY2hhbmdlJyxcbiAgICAgICk7XG4gICAgICBOZ3hGb3JtU2VydmljZS5yZWdpc3Rlcihjb250cm9sLCBjb21wb25lbnRQcm9wcyk7XG4gICAgICBwYXJlbnRHcm91cC5hZGRDb250cm9sKGNvbnRyb2xOYW1lLCBjb250cm9sKTtcbiAgICB9XG5cbiAgICBjb21wb25lbnRQcm9wc1snZm9ybUdyb3VwJ10gPSBwYXJlbnRHcm91cDtcbiAgICBjb21wb25lbnRQcm9wc1snZm9ybUNvbnRyb2wnXSA9IHBhcmVudEdyb3VwLmdldChjb250cm9sTmFtZSkgYXMgRm9ybUNvbnRyb2w7XG4gICAgY29tcG9uZW50UHJvcHNbJ211bHRpcGxlJ10gPSBpc011bHRpcGxlXG5cbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gUmV0cmlldmVzIGEgY29udHJvbCBmcm9tIGEgcmVnaXN0ZXJlZCBmb3JtLlxuICAgKiBAc3VtbWFyeSBGaW5kcyBhbmQgcmV0dXJucyBhbiBBYnN0cmFjdENvbnRyb2wgZnJvbSBhIHJlZ2lzdGVyZWQgZm9ybSB1c2luZyB0aGUgZm9ybSBpZCBhbmQgb3B0aW9uYWwgcGF0aC5cbiAgICogQHBhcmFtIHtzdHJpbmd9IGZvcm1JZCAtIFRoZSB1bmlxdWUgaWRlbnRpZmllciBvZiB0aGUgZm9ybS5cbiAgICogQHBhcmFtIHtzdHJpbmd9IFtwYXRoXSAtIFRoZSBwYXRoIHRvIHRoZSBjb250cm9sIHdpdGhpbiB0aGUgZm9ybS5cbiAgICogQHJldHVybiB7QWJzdHJhY3RDb250cm9sfSBUaGUgcmVxdWVzdGVkIEFic3RyYWN0Q29udHJvbC5cbiAgICogQHRocm93cyB7RXJyb3J9IElmIHRoZSBmb3JtIGlzIG5vdCBmb3VuZCBpbiB0aGUgcmVnaXN0cnkgb3IgdGhlIGNvbnRyb2wgaXMgbm90IGZvdW5kIGluIHRoZSBmb3JtLlxuICAgKi9cbiAgc3RhdGljIGdldENvbnRyb2xGcm9tRm9ybShmb3JtSWQ6IHN0cmluZywgcGF0aD86IHN0cmluZyk6IEFic3RyYWN0Q29udHJvbCB7XG4gICAgY29uc3QgZm9ybSA9IHRoaXMuZm9ybVJlZ2lzdHJ5LmdldChmb3JtSWQpO1xuICAgIGlmICghZm9ybSlcbiAgICAgIHRocm93IG5ldyBFcnJvcihgRm9ybSB3aXRoIGlkICcke2Zvcm1JZH0nIG5vdCBmb3VuZCBpbiB0aGUgcmVnaXN0cnkuYCk7XG5cbiAgICBpZiAoIXBhdGgpXG4gICAgICByZXR1cm4gZm9ybTtcblxuICAgIGNvbnN0IGNvbnRyb2wgPSBmb3JtLmdldChwYXRoKTtcbiAgICBpZiAoIWNvbnRyb2wpXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYENvbnRyb2wgd2l0aCBwYXRoICcke3BhdGh9JyBub3QgZm91bmQgaW4gZm9ybSAnJHtmb3JtSWR9Jy5gKTtcbiAgICByZXR1cm4gY29udHJvbDtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gQ3JlYXRlcyBhIGZvcm0gZnJvbSBjb21wb25lbnQgY29uZmlndXJhdGlvbnMuXG4gICAqIEBzdW1tYXJ5IEdlbmVyYXRlcyBhIEZvcm1Hcm91cCBiYXNlZCBvbiBhbiBhcnJheSBvZiBjb21wb25lbnQgY29uZmlndXJhdGlvbnMgYW5kIG9wdGlvbmFsbHkgcmVnaXN0ZXJzIGl0LlxuICAgKiBAcGFyYW0ge3N0cmluZ30gaWQgLSBUaGUgdW5pcXVlIGlkZW50aWZpZXIgZm9yIHRoZSBmb3JtLlxuICAgKiBAcGFyYW0ge0lDb21wb25lbnRDb25maWdbXX0gY29tcG9uZW50cyAtIEFuIGFycmF5IG9mIGNvbXBvbmVudCBjb25maWd1cmF0aW9ucy5cbiAgICogQHBhcmFtIHtib29sZWFufSBbcmVnaXN0cnk9ZmFsc2VdIC0gV2hldGhlciB0byByZWdpc3RlciB0aGUgY3JlYXRlZCBmb3JtLlxuICAgKiBAcmV0dXJuIHtGb3JtR3JvdXB9IFRoZSBjcmVhdGVkIEZvcm1Hcm91cC5cbiAgICovXG4gIHN0YXRpYyBjcmVhdGVGb3JtRnJvbUNvbXBvbmVudHMoaWQ6IHN0cmluZywgY29tcG9uZW50czogSUNvbXBvbmVudENvbmZpZ1tdLCByZWdpc3RyeTogYm9vbGVhbiA9IGZhbHNlKTogRm9ybUdyb3VwIHtcbiAgICBjb25zdCBmb3JtID0gbmV3IEZvcm1Hcm91cCh7fSk7XG4gICAgY29tcG9uZW50cy5mb3JFYWNoKGNvbXBvbmVudCA9PiB7XG4gICAgICB0aGlzLmFkZEZvcm1Db250cm9sKGZvcm0sIGNvbXBvbmVudC5pbnB1dHMpO1xuICAgIH0pO1xuXG4gICAgaWYgKHJlZ2lzdHJ5KVxuICAgICAgdGhpcy5hZGRSZWdpc3RyeShpZCwgZm9ybSk7XG5cbiAgICByZXR1cm4gZm9ybTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gQWRkcyBhIGNvbnRyb2wgdG8gYSBmb3JtIGJhc2VkIG9uIGNvbXBvbmVudCBwcm9wZXJ0aWVzLlxuICAgKiBAc3VtbWFyeSBDcmVhdGVzIGFuZCBhZGRzIGEgZm9ybSBjb250cm9sIHRvIGEgZm9ybSAoZXhpc3Rpbmcgb3IgbmV3KSBiYXNlZCBvbiB0aGUgcHJvdmlkZWQgY29tcG9uZW50IHByb3BlcnRpZXMuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBpZCAtIFRoZSB1bmlxdWUgaWRlbnRpZmllciBvZiB0aGUgZm9ybS5cbiAgICogQHBhcmFtIHtGaWVsZFByb3BlcnRpZXN9IGNvbXBvbmVudFByb3BlcnRpZXMgLSBUaGUgcHJvcGVydGllcyBvZiB0aGUgY29tcG9uZW50IHRvIGNyZWF0ZSB0aGUgY29udHJvbCBmcm9tLlxuICAgKiBAcmV0dXJuIHtBYnN0cmFjdENvbnRyb2x9IFRoZSBmb3JtIG9yIGNyZWF0ZWQgY29udHJvbC5cbiAgICovXG4gIHN0YXRpYyBhZGRDb250cm9sRnJvbVByb3BzKGlkOiBzdHJpbmcsIGNvbXBvbmVudFByb3BlcnRpZXM6IEZpZWxkUHJvcGVydGllcywgcGFyZW50UHJvcHM/OiBGaWVsZFByb3BlcnRpZXMpOiBBYnN0cmFjdENvbnRyb2wge1xuICAgIGNvbnN0IGZvcm0gPSB0aGlzLmZvcm1SZWdpc3RyeS5nZXQoaWQpID8/IG5ldyBGb3JtR3JvdXAoe30pO1xuICAgIGlmICghdGhpcy5mb3JtUmVnaXN0cnkuaGFzKGlkKSlcbiAgICAgIHRoaXMuYWRkUmVnaXN0cnkoaWQsIGZvcm0pO1xuXG4gICAgaWYgKGNvbXBvbmVudFByb3BlcnRpZXMucGF0aClcbiAgICAgIHRoaXMuYWRkRm9ybUNvbnRyb2woZm9ybSwgY29tcG9uZW50UHJvcGVydGllcywgcGFyZW50UHJvcHMpO1xuXG4gICAgcmV0dXJuIGZvcm07XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFJldHJpZXZlcyBmb3JtIGRhdGEgZnJvbSBhIEZvcm1Hcm91cC5cbiAgICogQHN1bW1hcnkgRXh0cmFjdHMgYW5kIHByb2Nlc3NlcyB0aGUgZGF0YSBmcm9tIGEgRm9ybUdyb3VwLCBoYW5kbGluZyBkaWZmZXJlbnQgaW5wdXQgdHlwZXMgYW5kIG5lc3RlZCBmb3JtIGdyb3Vwcy5cbiAgICogQHBhcmFtIHtGb3JtR3JvdXB9IGZvcm1Hcm91cCAtIFRoZSBGb3JtR3JvdXAgdG8gZXh0cmFjdCBkYXRhIGZyb20uXG4gICAqIEByZXR1cm4ge1JlY29yZDxzdHJpbmcsIHVua25vd24+fSBBbiBvYmplY3QgY29udGFpbmluZyB0aGUgZm9ybSBkYXRhLlxuICAgKi9cbiAgc3RhdGljIGdldEZvcm1EYXRhKGZvcm1Hcm91cDogRm9ybUdyb3VwKTogUmVjb3JkPHN0cmluZywgdW5rbm93bj4ge1xuICAgIGNvbnN0IGRhdGE6IFJlY29yZDxzdHJpbmcsIHVua25vd24+ID0ge307XG4gICAgZm9yIChjb25zdCBrZXkgaW4gZm9ybUdyb3VwLmNvbnRyb2xzKSB7XG4gICAgICBjb25zdCBjb250cm9sID0gZm9ybUdyb3VwLmNvbnRyb2xzW2tleV07XG4gICAgICBjb25zdCBwYXJlbnRQcm9wcyA9IE5neEZvcm1TZXJ2aWNlLmdldFByb3BzRnJvbUNvbnRyb2woZm9ybUdyb3VwIGFzIEZvcm1Hcm91cCB8IEZvcm1BcnJheSk7XG4gICAgICBpZiAoIShjb250cm9sIGluc3RhbmNlb2YgRm9ybUNvbnRyb2wpKSB7XG4gICAgICAgIGNvbnN0IHZhbHVlID0gTmd4Rm9ybVNlcnZpY2UuZ2V0Rm9ybURhdGEoY29udHJvbCBhcyBGb3JtR3JvdXApO1xuICAgICAgICBjb25zdCBpc1ZhbGlkID0gY29udHJvbC52YWxpZDtcbiAgICAgICAgaWYocGFyZW50UHJvcHMubXVsdGlwbGUpIHtcbiAgICAgICAgICAgIGlmKGlzVmFsaWQpIHtcbiAgICAgICAgICAgICAgIGRhdGFba2V5XSA9IHZhbHVlO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgdGhpcy5yZXNldChjb250cm9sIGFzIEZvcm1Db250cm9sKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cbiAgICAgICAgZGF0YVtrZXldID0gdmFsdWU7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBwcm9wcyA9IE5neEZvcm1TZXJ2aWNlLmdldFByb3BzRnJvbUNvbnRyb2woY29udHJvbCBhcyBGb3JtQ29udHJvbCB8IEZvcm1BcnJheSk7XG4gICAgICBsZXQgdmFsdWUgPSBjb250cm9sLnZhbHVlO1xuICAgICAgaWYgKCFIVE1MNUNoZWNrVHlwZXMuaW5jbHVkZXMocHJvcHNbJ3R5cGUnXSkpIHtcbiAgICAgICAgc3dpdGNoIChwcm9wc1sndHlwZSddKSB7XG4gICAgICAgICAgY2FzZSBIVE1MNUlucHV0VHlwZXMuTlVNQkVSOlxuICAgICAgICAgICAgdmFsdWUgPSBwYXJzZVRvTnVtYmVyKHZhbHVlKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIGNhc2UgSFRNTDVJbnB1dFR5cGVzLkRBVEU6XG4gICAgICAgICAgY2FzZSBIVE1MNUlucHV0VHlwZXMuREFURVRJTUVfTE9DQUw6XG4gICAgICAgICAgICB2YWx1ZSA9IG5ldyBEYXRlKHZhbHVlKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICB2YWx1ZSA9IGVzY2FwZUh0bWwodmFsdWUpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBkYXRhW2tleV0gPSB2YWx1ZTtcbiAgICB9XG4gICAgTmd4Rm9ybVNlcnZpY2UuZW5hYmxlQWxsR3JvdXBDb250cm9scyhmb3JtR3JvdXAgYXMgRm9ybUdyb3VwKTtcbiAgICByZXR1cm4gZGF0YTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gVmFsaWRhdGVzIGZpZWxkcyBpbiBhIGZvcm0gY29udHJvbCBvciBmb3JtIGdyb3VwLlxuICAgKiBAc3VtbWFyeSBSZWN1cnNpdmVseSB2YWxpZGF0ZXMgYWxsIGZpZWxkcyBpbiBhIGZvcm0gY29udHJvbCBvciBmb3JtIGdyb3VwLCBtYXJraW5nIHRoZW0gYXMgdG91Y2hlZCBhbmQgZGlydHkuXG4gICAqIEBwYXJhbSB7QWJzdHJhY3RDb250cm9sfSBjb250cm9sIC0gVGhlIGNvbnRyb2wgb3IgZm9ybSBncm91cCB0byB2YWxpZGF0ZS5cbiAgICogQHBhcmFtIHtzdHJpbmd9IFtwYXRoXSAtIFRoZSBwYXRoIHRvIHRoZSBjb250cm9sIHdpdGhpbiB0aGUgZm9ybS5cbiAgICogQHJldHVybiB7Ym9vbGVhbn0gVHJ1ZSBpZiBhbGwgZmllbGRzIGFyZSB2YWxpZCwgZmFsc2Ugb3RoZXJ3aXNlLlxuICAgKiBAdGhyb3dzIHtFcnJvcn0gSWYgbm8gY29udHJvbCBpcyBmb3VuZCBhdCB0aGUgc3BlY2lmaWVkIHBhdGggb3IgaWYgdGhlIGNvbnRyb2wgdHlwZSBpcyB1bmtub3duLlxuICAgKi9cbiAgc3RhdGljIHZhbGlkYXRlRmllbGRzKGNvbnRyb2w6IEFic3RyYWN0Q29udHJvbCwgcGs/OiBzdHJpbmcsICBwYXRoPzogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgY29udHJvbCA9IHBhdGggPyBjb250cm9sLmdldChwYXRoKSBhcyBBYnN0cmFjdENvbnRyb2wgOiBjb250cm9sO1xuICAgIGlmICghY29udHJvbClcbiAgICAgIHRocm93IG5ldyBFcnJvcihgTm8gY29udHJvbCBmb3VuZCBhdCBwYXRoOiAke3BhdGggfHwgJ3Jvb3QnfS5gKTtcblxuICAgIGNvbnN0IGlzQWxsb3dlZCA9IFtGb3JtQXJyYXksIEZvcm1Hcm91cCwgRm9ybUNvbnRyb2xdLnNvbWUodHlwZSA9PiBjb250cm9sIGluc3RhbmNlb2YgdHlwZSk7XG4gICAgaWYgKCFpc0FsbG93ZWQpXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYFVua25vd24gY29udHJvbCB0eXBlIGF0OiAke3BhdGggfHwgJ3Jvb3QnfWApO1xuXG4gICAgY29udHJvbC5tYXJrQXNUb3VjaGVkKCk7XG4gICAgY29udHJvbC5tYXJrQXNEaXJ0eSgpO1xuICAgIGNvbnRyb2wudXBkYXRlVmFsdWVBbmRWYWxpZGl0eSh7IGVtaXRFdmVudDogdHJ1ZSB9KTtcblxuICAgIGlmIChjb250cm9sIGluc3RhbmNlb2YgRm9ybUdyb3VwKSB7XG4gICAgICBPYmplY3QudmFsdWVzKGNvbnRyb2wuY29udHJvbHMpLmZvckVhY2goY2hpbGRDb250cm9sID0+IHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZUZpZWxkcyhjaGlsZENvbnRyb2wpO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgaWYgKGNvbnRyb2wgaW5zdGFuY2VvZiBGb3JtQXJyYXkpIHtcbiAgICAgIGNvbnN0IHRvdGFsR3JvdXBzID0gY29udHJvbC5sZW5ndGg7XG4gICAgICBjb25zdCBoYXNWYWxpZCA9IGNvbnRyb2wuY29udHJvbHMuc29tZShjb250cm9sID0+IGNvbnRyb2wudmFsaWQpO1xuICAgICAgaWYodG90YWxHcm91cHMgPiAxICYmIGhhc1ZhbGlkKSB7XG4gICAgICAgICBmb3IgKGxldCBpID0gY29udHJvbC5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgICAgICAgIGNvbnN0IGNoaWxkQ29udHJvbCA9IGNvbnRyb2wuYXQoaSk7XG4gICAgICAgICAgLy8gZGlzYWJsZSBubyB2YWxpZCBncm91cHMgb24gYXJyYXlcbiAgICAgICAgICBpZiAoIWNoaWxkQ29udHJvbC52YWxpZCkge1xuICAgICAgICAgICAgKGNoaWxkQ29udHJvbC5wYXJlbnQgYXMgRm9ybUdyb3VwKS5zZXRFcnJvcnMobnVsbCk7XG4gICAgICAgICAgICAgKGNoaWxkQ29udHJvbC5wYXJlbnQgYXMgRm9ybUdyb3VwKS51cGRhdGVWYWx1ZUFuZFZhbGlkaXR5KHsgZW1pdEV2ZW50OiB0cnVlIH0pO1xuICAgICAgICAgICAgY2hpbGRDb250cm9sLmRpc2FibGUoKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy52YWxpZGF0ZUZpZWxkcyhjaGlsZENvbnRyb2wpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgT2JqZWN0LnZhbHVlcyhjb250cm9sLmNvbnRyb2xzKS5mb3JFYWNoKGNoaWxkQ29udHJvbCA9PiB7XG4gICAgICAgICAgdGhpcy52YWxpZGF0ZUZpZWxkcyhjaGlsZENvbnRyb2wpO1xuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBmdW5jdGlvbiBnZXRDb250cm9sTmFtZShjb250cm9sOiBBYnN0cmFjdENvbnRyb2wpOiBzdHJpbmcgfCBudWxsIHtcbiAgICAgIGNvbnN0IGdyb3VwID0gY29udHJvbC5wYXJlbnQgYXMgRm9ybUdyb3VwO1xuICAgICAgaWYgKCFncm91cClcbiAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIHJldHVybiBPYmplY3Qua2V5cyhncm91cC5jb250cm9scykuZmluZChuYW1lID0+IGNvbnRyb2wgPT09IGdyb3VwLmdldChuYW1lKSkgfHwgbnVsbDtcbiAgICB9XG5cbiAgICByZXR1cm4gIWdldENvbnRyb2xOYW1lKGNvbnRyb2wpID8gdHJ1ZSA6IGNvbnRyb2wudmFsaWQ7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIEdlbmVyYXRlcyB2YWxpZGF0b3JzIGZyb20gY29tcG9uZW50IHByb3BlcnRpZXMuXG4gICAqIEBzdW1tYXJ5IENyZWF0ZXMgYW4gYXJyYXkgb2YgVmFsaWRhdG9yRm4gYmFzZWQgb24gdGhlIHN1cHBvcnRlZCB2YWxpZGF0aW9uIGtleXMgaW4gdGhlIGNvbXBvbmVudCBwcm9wZXJ0aWVzLlxuICAgKiBAcGFyYW0ge0ZpZWxkUHJvcGVydGllc30gcHJvcHMgLSBUaGUgY29tcG9uZW50IHByb3BlcnRpZXMuXG4gICAqIEByZXR1cm4ge1ZhbGlkYXRvckZuW119IEFuIGFycmF5IG9mIHZhbGlkYXRvciBmdW5jdGlvbnMuXG4gICAqL1xuICBwcml2YXRlIHN0YXRpYyB2YWxpZGF0b3JzRnJvbVByb3BzKHByb3BzOiBGaWVsZFByb3BlcnRpZXMpOiBWYWxpZGF0b3JGbltdIHtcbiAgICBjb25zdCBzdXBwb3J0ZWRWYWxpZGF0aW9uS2V5cyA9IFZhbGlkYXRpb24ua2V5cygpO1xuICAgIHJldHVybiBPYmplY3Qua2V5cyhwcm9wcylcbiAgICAgIC5maWx0ZXIoKGs6IHN0cmluZykgPT4gc3VwcG9ydGVkVmFsaWRhdGlvbktleXMuaW5jbHVkZXMoaykpXG4gICAgICAubWFwKChrOiBzdHJpbmcpID0+IHtcbiAgICAgICAgcmV0dXJuIFZhbGlkYXRvckZhY3Rvcnkuc3Bhd24ocHJvcHMsIGspO1xuICAgICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIENyZWF0ZXMgYSBGb3JtQ29udHJvbCBmcm9tIGNvbXBvbmVudCBwcm9wZXJ0aWVzLlxuICAgKiBAc3VtbWFyeSBHZW5lcmF0ZXMgYSBGb3JtQ29udHJvbCB3aXRoIHZhbGlkYXRvcnMgYmFzZWQgb24gdGhlIHByb3ZpZGVkIGNvbXBvbmVudCBwcm9wZXJ0aWVzLlxuICAgKiBAcGFyYW0ge0ZpZWxkUHJvcGVydGllc30gcHJvcHMgLSBUaGUgY29tcG9uZW50IHByb3BlcnRpZXMuXG4gICAqIEBwYXJhbSB7RmllbGRVcGRhdGVNb2RlfSBbdXBkYXRlTW9kZT0nY2hhbmdlJ10gLSBUaGUgdXBkYXRlIG1vZGUgZm9yIHRoZSBjb250cm9sLlxuICAgKiBAcmV0dXJuIHtGb3JtQ29udHJvbH0gVGhlIGNyZWF0ZWQgRm9ybUNvbnRyb2wuXG4gICAqL1xuICBzdGF0aWMgZnJvbVByb3BzKHByb3BzOiBGaWVsZFByb3BlcnRpZXMsIHVwZGF0ZU1vZGU6IEZpZWxkVXBkYXRlTW9kZSA9ICdjaGFuZ2UnKTogRm9ybUNvbnRyb2wge1xuICAgIGNvbnN0IHZhbGlkYXRvcnMgPSB0aGlzLnZhbGlkYXRvcnNGcm9tUHJvcHMocHJvcHMpO1xuICAgIGNvbnN0IGNvbXBvc2VkID0gdmFsaWRhdG9ycy5sZW5ndGggPyBWYWxpZGF0b3JzLmNvbXBvc2UodmFsaWRhdG9ycykgOiBudWxsO1xuICAgIHJldHVybiBuZXcgRm9ybUNvbnRyb2woXG4gICAgICB7XG4gICAgICAgIHZhbHVlOlxuICAgICAgICAgIHByb3BzLnZhbHVlICYmIHByb3BzLnR5cGUgIT09IEhUTUw1SW5wdXRUeXBlcy5DSEVDS0JPWFxuICAgICAgICAgICAgPyBwcm9wcy50eXBlID09PSBIVE1MNUlucHV0VHlwZXMuREFURVxuICAgICAgICAgICAgICA/ICFpc1ZhbGlkRGF0ZShwYXJzZURhdGUocHJvcHMuZm9ybWF0IGFzIHN0cmluZywgcHJvcHMudmFsdWUgYXMgc3RyaW5nKSlcbiAgICAgICAgICAgICAgICA/IHVuZGVmaW5lZCA6IHByb3BzLnZhbHVlIDpcbiAgICAgICAgICAgICAgKHByb3BzLnZhbHVlIGFzIHVua25vd24pIDogdW5kZWZpbmVkLFxuICAgICAgICBkaXNhYmxlZDogcHJvcHMuZGlzYWJsZWQsXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICB2YWxpZGF0b3JzOiBjb21wb3NlZCxcbiAgICAgICAgdXBkYXRlT246IHVwZGF0ZU1vZGUsXG4gICAgICB9LFxuICAgICk7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFJldHJpZXZlcyBwcm9wZXJ0aWVzIGZyb20gYSBGb3JtQ29udHJvbC5cbiAgICogQHN1bW1hcnkgR2V0cyB0aGUgRmllbGRQcm9wZXJ0aWVzIGFzc29jaWF0ZWQgd2l0aCBhIEZvcm1Db250cm9sIGZyb20gdGhlIGludGVybmFsIFdlYWtNYXAuXG4gICAqIEBwYXJhbSB7Rm9ybUNvbnRyb2x9IGNvbnRyb2wgLSBUaGUgRm9ybUNvbnRyb2wgdG8gZ2V0IHByb3BlcnRpZXMgZm9yLlxuICAgKiBAcmV0dXJuIHtGaWVsZFByb3BlcnRpZXN9IFRoZSBwcm9wZXJ0aWVzIGFzc29jaWF0ZWQgd2l0aCB0aGUgY29udHJvbC5cbiAgICovXG4gIHN0YXRpYyBnZXRQcm9wc0Zyb21Db250cm9sKGNvbnRyb2w6IEZvcm1Db250cm9sIHwgRm9ybUFycmF5IHwgRm9ybUdyb3VwKTogRmllbGRQcm9wZXJ0aWVzIHtcbiAgICByZXR1cm4gdGhpcy5jb250cm9scy5nZXQoY29udHJvbCkgfHwge30gYXMgRmllbGRQcm9wZXJ0aWVzO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBGaW5kcyBhIHBhcmVudCBlbGVtZW50IHdpdGggYSBzcGVjaWZpYyB0YWcuXG4gICAqIEBzdW1tYXJ5IFRyYXZlcnNlcyB1cCB0aGUgRE9NIHRyZWUgdG8gZmluZCB0aGUgbmVhcmVzdCBwYXJlbnQgZWxlbWVudCB3aXRoIHRoZSBzcGVjaWZpZWQgdGFnLlxuICAgKiBAcGFyYW0ge0hUTUxFbGVtZW50fSBlbCAtIFRoZSBzdGFydGluZyBlbGVtZW50LlxuICAgKiBAcGFyYW0ge3N0cmluZ30gdGFnIC0gVGhlIHRhZyBuYW1lIHRvIHNlYXJjaCBmb3IuXG4gICAqIEByZXR1cm4ge0hUTUxFbGVtZW50fSBUaGUgZm91bmQgcGFyZW50IGVsZW1lbnQuXG4gICAqIEB0aHJvd3Mge0Vycm9yfSBJZiBubyBwYXJlbnQgd2l0aCB0aGUgc3BlY2lmaWVkIHRhZyBpcyBmb3VuZC5cbiAgICovXG4gIHN0YXRpYyBnZXRQYXJlbnRFbChlbDogSFRNTEVsZW1lbnQsIHRhZzogc3RyaW5nKTogSFRNTEVsZW1lbnQge1xuICAgIGxldCBwYXJlbnQ6IEhUTUxFbGVtZW50IHwgbnVsbDtcbiAgICB3aGlsZSAoKHBhcmVudCA9IGVsLnBhcmVudEVsZW1lbnQpICE9PSBudWxsKSB7XG4gICAgICBpZiAocGFyZW50LnRhZ05hbWUudG9Mb3dlckNhc2UoKSA9PT0gdGFnLnRvTG93ZXJDYXNlKCkpIHtcbiAgICAgICAgcmV0dXJuIHBhcmVudDtcbiAgICAgIH1cbiAgICAgIGVsID0gcGFyZW50O1xuICAgIH1cbiAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICBgTm8gcGFyZW50IHdpdGggdGhlIHRhZyAke3RhZ30gd2FzIGZvdW5kIGZvciBwcm92aWRlZCBlbGVtZW50YCxcbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBSZWdpc3RlcnMgYSBjb250cm9sIHdpdGggaXRzIHByb3BlcnRpZXMuXG4gICAqIEBzdW1tYXJ5IEFzc29jaWF0ZXMgYSBjb250cm9sIHdpdGggaXRzIHByb3BlcnRpZXMgaW4gdGhlIGludGVybmFsIFdlYWtNYXAuXG4gICAqIEBwYXJhbSB7QWJzdHJhY3RDb250cm9sfSBjb250cm9sIC0gVGhlIGNvbnRyb2wgdG8gcmVnaXN0ZXIuXG4gICAqIEBwYXJhbSB7RmllbGRQcm9wZXJ0aWVzfSBwcm9wcyAtIFRoZSBwcm9wZXJ0aWVzIHRvIGFzc29jaWF0ZSB3aXRoIHRoZSBjb250cm9sLlxuICAgKi9cbiAgc3RhdGljIHJlZ2lzdGVyKGNvbnRyb2w6IEFic3RyYWN0Q29udHJvbCwgcHJvcHM6IEZpZWxkUHJvcGVydGllcykge1xuICAgIHRoaXMuY29udHJvbHMuc2V0KGNvbnRyb2wsIHByb3BzKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gVW5yZWdpc3RlcnMgYSBjb250cm9sLlxuICAgKiBAc3VtbWFyeSBSZW1vdmVzIGEgY29udHJvbCBhbmQgaXRzIGFzc29jaWF0ZWQgcHJvcGVydGllcyBmcm9tIHRoZSBpbnRlcm5hbCBXZWFrTWFwLlxuICAgKiBAcGFyYW0ge0Fic3RyYWN0Q29udHJvbH0gY29udHJvbCAtIFRoZSBjb250cm9sIHRvIHVucmVnaXN0ZXIuXG4gICAqIEByZXR1cm4ge2Jvb2xlYW59IFRydWUgaWYgdGhlIGNvbnRyb2wgd2FzIHN1Y2Nlc3NmdWxseSB1bnJlZ2lzdGVyZWQsIGZhbHNlIG90aGVyd2lzZS5cbiAgICovXG4gIHN0YXRpYyB1bnJlZ2lzdGVyKGNvbnRyb2w6IEFic3RyYWN0Q29udHJvbCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLmNvbnRyb2xzLmRlbGV0ZShjb250cm9sKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gUmVzZXRzIGEgZm9ybSBncm91cC5cbiAgICogQHN1bW1hcnkgUmVjdXJzaXZlbHkgcmVzZXRzIGFsbCBjb250cm9scyBpbiBhIGZvcm0gZ3JvdXAsIGNsZWFyaW5nIHZhbHVlcywgZXJyb3JzLCBhbmQgbWFya2luZyB0aGVtIGFzIHByaXN0aW5lIGFuZCB1bnRvdWNoZWQuXG4gICAqIEBwYXJhbSB7Rm9ybUdyb3VwfSBmb3JtR3JvdXAgLSBUaGUgZm9ybSBncm91cCB0byByZXNldC5cbiAgICovXG4gIHN0YXRpYyByZXNldChmb3JtR3JvdXA6IEZvcm1Hcm91cCB8IEZvcm1Db250cm9sKTogdm9pZCB7XG4gICAgaWYoZm9ybUdyb3VwIGluc3RhbmNlb2YgRm9ybUNvbnRyb2wpIHtcbiAgICAgIGNvbnN0IGNvbnRyb2wgPSBmb3JtR3JvdXAgYXMgRm9ybUNvbnRyb2w7XG4gICAgICBjb25zdCB7IHR5cGUgfSA9IE5neEZvcm1TZXJ2aWNlLmdldFByb3BzRnJvbUNvbnRyb2woY29udHJvbCk7XG4gICAgICBpZiAoIUhUTUw1Q2hlY2tUeXBlcy5pbmNsdWRlcyh0eXBlKSlcbiAgICAgICAgY29udHJvbC5zZXRWYWx1ZShcIlwiKTtcbiAgICAgIGNvbnRyb2wubWFya0FzUHJpc3RpbmUoKTtcbiAgICAgIGNvbnRyb2wubWFya0FzVW50b3VjaGVkKCk7XG4gICAgICBjb250cm9sLnNldEVycm9ycyhudWxsKTtcbiAgICAgIGNvbnRyb2wudXBkYXRlVmFsdWVBbmRWYWxpZGl0eSgpO1xuICAgIH0gZWxzZSB7XG4gICAgICBmb3IgKGNvbnN0IGtleSBpbiBmb3JtR3JvdXAuY29udHJvbHMpIHtcbiAgICAgICAgY29uc3QgY29udHJvbCA9IGZvcm1Hcm91cC5jb250cm9sc1trZXldO1xuICAgICAgICBOZ3hGb3JtU2VydmljZS5yZXNldChjb250cm9sIGFzIEZvcm1Db250cm9sKTtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG4gICAgfVxuICB9XG59XG4iXX0=
917
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiTmd4Rm9ybVNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvbGliL2VuZ2luZS9OZ3hGb3JtU2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsVUFBVSxFQUFtQixlQUFlLEVBQUUsZUFBZSxFQUFFLGFBQWEsRUFBbUIsTUFBTSx5QkFBeUIsQ0FBQztBQUd4SSxPQUFPLEVBQUUsZUFBZSxFQUFFLFNBQVMsRUFBRSxXQUFXLEVBQUUsU0FBUyxFQUFlLFVBQVUsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQzdHLE9BQU8sRUFBRSxXQUFXLEVBQUUsU0FBUyxFQUFFLFNBQVMsRUFBRSxVQUFVLEVBQUUsVUFBVSxFQUFFLE1BQU0sZ0NBQWdDLENBQUM7QUFDM0csT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFDdEQsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLFlBQVksQ0FBQztBQUN6QyxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFDeEQsT0FBTyxFQUFFLGlCQUFpQixFQUFFLGtCQUFrQixFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFHNUU7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FxQ0c7QUFDSCxNQUFNLE9BQU8sY0FBYztJQUN6Qjs7Ozs7Ozs7O09BU0c7YUFDWSxhQUFRLEdBQThDLElBQUksT0FBTyxFQUFvQyxDQUFDO0lBRXJIOzs7Ozs7Ozs7T0FTRzthQUNZLGlCQUFZLEdBQTRCLElBQUksR0FBRyxFQUFzQixDQUFDO2FBRXRFLGVBQVUsR0FBYSxFQUFFLENBQUM7SUFFekM7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7T0FrQ0c7SUFDSCxNQUFNLENBQUMsVUFBVSxDQUFDLEVBQVUsRUFBRSxRQUFrQyxFQUFFLEVBQUUsV0FBb0IsSUFBSTtRQUMxRixNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsWUFBWSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLEtBQUssRUFBRSxLQUFLLElBQUksS0FBSyxFQUFFLEtBQUssR0FBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksU0FBUyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLFNBQVMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBQ3RILElBQUksQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsSUFBSSxRQUFRO1lBQ3hDLElBQUksQ0FBQyxXQUFXLENBQUMsRUFBRSxFQUFFLElBQTZCLENBQUMsQ0FBQztRQUN0RCxPQUFPLElBQTZCLENBQUM7SUFDdkMsQ0FBQztJQUdEOzs7Ozs7Ozs7Ozs7O09BYUc7SUFDSCxNQUFNLENBQUMsV0FBVyxDQUFDLE1BQWMsRUFBRSxTQUFxQjtRQUN0RCxJQUFJLElBQUksQ0FBQyxZQUFZLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQztZQUMvQixNQUFNLElBQUksS0FBSyxDQUFDLHdCQUF3QixNQUFNLDBCQUEwQixDQUFDLENBQUM7UUFDNUUsSUFBSSxDQUFDLFlBQVksQ0FBQyxHQUFHLENBQUMsTUFBTSxFQUFFLFNBQVMsQ0FBQyxDQUFDO0lBQzNDLENBQUM7SUFFRDs7Ozs7Ozs7Ozs7T0FXRztJQUNILE1BQU0sQ0FBQyxjQUFjLENBQUMsTUFBYztRQUNsQyxJQUFJLENBQUMsWUFBWSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQztJQUNuQyxDQUFDO0lBRUQ7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O09BbUNHO0lBQ0ssTUFBTSxDQUFDLGtCQUFrQixDQUFDLFNBQW9CLEVBQUUsSUFBWSxFQUFFLGNBQStCLEVBQUUsV0FBcUI7UUFDMUgsTUFBTSxVQUFVLEdBQUcsV0FBVyxFQUFFLENBQUMsVUFBVSxDQUFDLElBQUksV0FBVyxFQUFFLENBQUMsTUFBTSxDQUFDLEtBQUssT0FBTyxJQUFJLEtBQUssQ0FBQztRQUMzRixNQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQzlCLE1BQU0sV0FBVyxHQUFHLEtBQUssQ0FBQyxHQUFHLEVBQVksQ0FBQztRQUMxQyxNQUFNLEVBQUMsT0FBTyxFQUFDLEdBQUcsY0FBYyxDQUFBO1FBQ2hDLElBQUksWUFBWSxHQUFHLFNBQVMsQ0FBQztRQUU3QixTQUFTLHNCQUFzQixDQUFDLGNBQXlCO1lBQ3ZELE1BQU0sS0FBSyxHQUFJLGNBQTJCLENBQUMsaUJBQWlCLENBQUMsMEJBQTBCLENBQUMsSUFBSSxFQUFFLENBQUM7WUFDN0YsSUFBRyxDQUFDLEtBQUssQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLENBQUMsV0FBVyxDQUFDO2dCQUNyQyxLQUFLLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUMsRUFBRSxFQUFFLEtBQUssQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLEVBQUUsRUFBQyxDQUFDLFdBQVcsQ0FBQyxFQUFFLEVBQUMsR0FBRyxjQUFjLEVBQUMsRUFBQyxDQUFDLENBQUM7UUFDL0csQ0FBQztRQUVELEtBQUssTUFBTSxJQUFJLElBQUksS0FBSyxFQUFFLENBQUM7WUFDekIsSUFBSSxDQUFDLFlBQVksQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQztnQkFDNUIsTUFBTSxhQUFhLEdBQUcsQ0FBQyxVQUFVLElBQUksSUFBSSxLQUFLLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLFNBQVMsQ0FBQyxDQUFDLElBQUksU0FBUyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxTQUFTLENBQUMsRUFBRSxDQUFDLENBQUM7Z0JBQy9HLGFBQTBCLENBQUMsaUJBQWlCLENBQUMsMEJBQTBCLENBQUMsR0FBRztvQkFDMUUsT0FBTyxFQUFFLE9BQU8sSUFBSSxFQUFFO29CQUN0QixVQUFVLEVBQUUsVUFBVTtvQkFDdEIsSUFBSSxFQUFFLElBQUk7b0JBQ1YsRUFBRSxFQUFFLGNBQWMsRUFBRSxDQUFDLElBQUksQ0FBQyxJQUFJLFdBQVcsRUFBRSxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUU7b0JBQ3ZELENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxFQUFFLEVBQUU7aUJBQzBCLENBQUM7Z0JBRWxELElBQUcsWUFBWSxZQUFZLFNBQVMsRUFBRSxDQUFDO29CQUNwQyxZQUEwQixDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsQ0FBQztnQkFDbEQsQ0FBQztxQkFBTSxDQUFDO29CQUVOLEtBQUksTUFBTSxPQUFPLElBQUksTUFBTSxDQUFDLE1BQU0sQ0FBQyxhQUFhLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQzt3QkFDM0QsSUFBRyxPQUFPLFlBQVksV0FBVzs0QkFDL0IsSUFBSSxDQUFDLFFBQVEsQ0FBQyxPQUEwQixFQUFFLGNBQWMsQ0FBQyxDQUFDO29CQUM5RCxDQUFDO29CQUVELElBQUcsYUFBYSxZQUFZLGVBQWU7d0JBQ3pDLElBQUksQ0FBQyxRQUFRLENBQUMsYUFBZ0MsRUFBRSxjQUFjLENBQUMsQ0FBQztvQkFFbEUsWUFBWSxDQUFDLFVBQVUsQ0FBQyxJQUFJLEVBQUUsYUFBYSxDQUFDLENBQUM7Z0JBQy9DLENBQUM7WUFDSCxDQUFDO1lBQ0QsSUFBRyxPQUFPLElBQUksWUFBWSxZQUFZLFNBQVM7Z0JBQzdDLHNCQUFzQixDQUFDLFlBQVksQ0FBQyxDQUFDO1lBRXZDLFlBQVksR0FBRyxZQUFZLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBYyxDQUFDO1FBQ3JELENBQUM7UUFDRCxPQUFPLENBQUMsWUFBWSxFQUFFLFdBQVcsQ0FBQyxDQUFDO0lBQ3JDLENBQUM7SUFFRDs7Ozs7Ozs7Ozs7O09BWUc7SUFDSCxNQUFNLENBQUMsK0JBQStCLENBQUMsU0FBZ0MsRUFBRSxHQUFZLEVBQUUsY0FBbUM7UUFDeEgsSUFBRyxDQUFDLENBQUMsU0FBUyxZQUFZLFNBQVMsQ0FBQyxJQUFJLE9BQU8sY0FBYyxLQUFLLFVBQVUsQ0FBQyxNQUFNO1lBQ2pGLFNBQVMsR0FBRyxTQUFTLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxjQUF3QixDQUFjLElBQUksRUFBRSxDQUFDO1FBQzlFLE1BQU0sS0FBSyxHQUFJLFNBQXNCLEVBQUUsQ0FBQyxpQkFBaUIsQ0FBQywwQkFBMEIsQ0FBQyxJQUFJLEVBQUUsQ0FBQztRQUM1RixPQUFPLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsS0FBSyxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUMsSUFBSSxFQUFFLENBQUM7SUFDN0MsQ0FBQztJQUVEOzs7Ozs7Ozs7Ozs7O09BYUc7SUFDSCxNQUFNLENBQUMsZ0JBQWdCLENBQUMsU0FBb0IsRUFBRSxVQUFrQixFQUFFLFFBQWdCLENBQUM7UUFDakYsTUFBTSxjQUFjLEdBQUcsSUFBSSxDQUFDLCtCQUErQixDQUFDLFNBQVMsRUFBRSxTQUFTLENBQUMsS0FBSyxFQUFFLFVBQVUsQ0FBQyxDQUFDO1FBQ3BHLE1BQU0sQ0FBQyxPQUFPLENBQUMsY0FBMEIsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsRUFBRSxLQUFLLENBQUMsRUFBRSxFQUFFO1lBQy9ELE9BQU8sSUFBSSxDQUFDLGNBQWMsQ0FBQyxTQUFTLEVBQUUsS0FBSyxFQUFFLEVBQUMsUUFBUSxFQUFFLElBQUksRUFBQyxFQUFFLEtBQUssQ0FBQyxDQUFDO1FBQ3hFLENBQUMsQ0FBQyxDQUFDO1FBRUgsT0FBTyxJQUFJLENBQUMsa0JBQWtCLENBQUMsU0FBUyxFQUFFLFVBQVUsRUFBRSxLQUFLLENBQUMsQ0FBQztJQUMvRCxDQUFDO0lBRUQ7Ozs7Ozs7Ozs7OztPQVlHO0lBQ0gsTUFBTSxDQUFDLGtCQUFrQixDQUFDLFNBQW9CLEVBQUUsVUFBa0IsRUFBRSxRQUFnQixDQUFDO1FBQ25GLE1BQU0sVUFBVSxHQUFJLENBQUMsU0FBUyxDQUFDLEdBQUcsQ0FBQyxVQUFVLENBQUMsSUFBSSxTQUFTLENBQWUsQ0FBQyxFQUFFLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDckYsSUFBRyxVQUFVLFlBQVksU0FBUztZQUNoQyxPQUFPLFVBQVUsQ0FBQztRQUNwQixPQUFPLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxTQUFTLEVBQUUsVUFBVSxFQUFFLEtBQUssQ0FBQyxDQUFDO0lBQzdELENBQUM7SUFFRDs7Ozs7Ozs7Ozs7O09BWUc7SUFDSCxNQUFNLENBQUMsZUFBZSxDQUFDLFNBQW9CLEVBQUUsS0FBYSxFQUFFLFlBQTJCLGFBQWEsQ0FBQyxNQUFNO1FBQ3pHLE1BQU0sY0FBYyxHQUFHLFNBQVMsQ0FBQyxNQUFtQixDQUFDO1FBQ3JELE1BQU0sRUFBRSxHQUFHLElBQUksQ0FBQywrQkFBK0IsQ0FBQyxjQUFjLEVBQUUsa0JBQWtCLENBQUMsRUFBWSxDQUFXLENBQUM7UUFDM0csTUFBTSxXQUFXLEdBQUcsTUFBTSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFFdkQsNkNBQTZDO1FBQzdDLElBQUcsV0FBVyxLQUFLLEVBQUU7WUFDbkIsT0FBTyxJQUFJLENBQUM7UUFDZCxNQUFNLFlBQVksR0FBRyxXQUFXLENBQUMsR0FBRyxTQUFTLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxFQUFFLEtBQUssRUFBRSxFQUFFLElBQUksQ0FBQyxDQUFDO1FBQ3RFLElBQUcsU0FBUyxLQUFLLGFBQWEsQ0FBQyxNQUFNO1lBQ25DLE9BQU8sQ0FBQyxjQUFjLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFDLEtBQUssRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsS0FBSyxLQUFLLElBQUksV0FBVyxDQUFDLEdBQUcsS0FBSyxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsRUFBRSxLQUFLLEVBQUUsRUFBRSxJQUFJLENBQUMsS0FBSyxZQUFZLENBQUMsQ0FBQztRQUVuSSxPQUFPLENBQUMsY0FBYyxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsQ0FBQyxLQUFLLEVBQUUsQ0FBQyxFQUFFLEVBQUU7WUFDaEQsTUFBTSxLQUFLLEdBQUcsV0FBVyxDQUFDLEdBQUcsS0FBSyxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsRUFBRSxLQUFLLEVBQUUsRUFBRSxJQUFJLENBQUMsQ0FBQztZQUMzRCxPQUFPLENBQUMsS0FBSyxLQUFLLElBQUksWUFBWSxLQUFLLEtBQUssQ0FBQztRQUMvQyxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUM7SUFFRDs7Ozs7Ozs7OztPQVVHO0lBQ0gsTUFBTSxDQUFDLHNCQUFzQixDQUFDLFNBQWdDO1FBQzVELE1BQU0sQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLFFBQVEsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsRUFBRTtZQUM1QyxNQUFNLE9BQU8sR0FBRyxTQUFTLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1lBQ25DLElBQUksT0FBTyxZQUFZLFNBQVMsRUFBRSxDQUFDO2dCQUNqQyxPQUFPLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsRUFBRTtvQkFDL0IsSUFBSSxLQUFLLFlBQVksU0FBUyxFQUFFLENBQUM7d0JBQy9CLEtBQUssQ0FBQyxNQUFNLENBQUMsRUFBRSxTQUFTLEVBQUUsS0FBSyxFQUFFLENBQUMsQ0FBQzt3QkFDbkMsS0FBSyxDQUFDLHNCQUFzQixDQUFDLEVBQUUsU0FBUyxFQUFFLElBQUksRUFBRSxDQUFDLENBQUM7b0JBQ3BELENBQUM7Z0JBQ0gsQ0FBQyxDQUFDLENBQUM7WUFDTCxDQUFDO1FBQ0gsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDO0lBRUQ7Ozs7Ozs7Ozs7Ozs7OztPQWVHO0lBQ0ssTUFBTSxDQUFDLGNBQWMsQ0FBQyxTQUFxQixFQUFFLGNBQStCLEVBQUUsY0FBd0IsRUFBRSxFQUFFLFFBQWdCLENBQUM7UUFFakksTUFBTSxVQUFVLEdBQUcsV0FBVyxFQUFFLENBQUMsVUFBVSxDQUFDLElBQUksV0FBVyxFQUFFLENBQUMsTUFBTSxDQUFDLEtBQUssT0FBTyxJQUFJLEtBQUssQ0FBQztRQUMzRixNQUFNLEVBQUUsSUFBSSxFQUFFLE9BQU8sR0FBRyxHQUFHLGNBQWMsQ0FBQztRQUMxQyxJQUFHLFVBQVU7WUFDWCxjQUFjLENBQUMsSUFBSSxDQUFDLEdBQUcsY0FBYyxDQUFDLElBQUksQ0FBQyxJQUFJLFdBQVcsRUFBRSxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsQ0FBQztRQUMzRSxNQUFNLFFBQVEsR0FBRyxPQUFPLENBQUMsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsR0FBRyxPQUFPLElBQUksS0FBSyxJQUFJLElBQUksRUFBRSxDQUFDLENBQUMsQ0FBQyxHQUFHLE9BQU8sSUFBSSxJQUFJLEVBQUUsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDO1FBQ3BHLE1BQU0sQ0FBQyxXQUFXLEVBQUUsV0FBVyxDQUFDLEdBQUcsSUFBSSxDQUFDLGtCQUFrQixDQUFDLFNBQXNCLEVBQUUsUUFBUSxFQUFFLGNBQWMsRUFBRSxXQUFXLENBQUMsQ0FBQztRQUUxSCxJQUFJLENBQUMsV0FBVyxDQUFDLEdBQUcsQ0FBQyxXQUFXLENBQUMsRUFBRSxDQUFDO1lBQ2xDLE1BQU0sT0FBTyxHQUFHLGNBQWMsQ0FBQyxTQUFTLENBQ3RDLGNBQWMsRUFDZCxjQUFjLENBQUMsVUFBVSxJQUFJLFFBQVEsQ0FDdEMsQ0FBQztZQUNGLGNBQWMsQ0FBQyxRQUFRLENBQUMsT0FBTyxFQUFFLGNBQWMsQ0FBQyxDQUFDO1lBQ2pELElBQUksV0FBVyxZQUFZLFNBQVMsRUFBRSxDQUFDO2dCQUNyQyxXQUFXLENBQUMsVUFBVSxDQUFDLFdBQVcsRUFBRSxPQUFPLENBQUMsQ0FBQztZQUMvQyxDQUFDO1lBQ0QsSUFBRyxXQUFXLFlBQVksU0FBUyxFQUFFLENBQUM7Z0JBQ3BDLE1BQU0sSUFBSSxHQUFHLFdBQVcsQ0FBQyxRQUFRLENBQUUsY0FBMkIsRUFBRSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBYyxDQUFDO2dCQUMzRixJQUFHLElBQUksRUFBRSxDQUFDO29CQUNQLElBQUksQ0FBQyxVQUFVLENBQUMsV0FBVyxFQUFFLE9BQU8sQ0FBQyxDQUFDO2dCQUN6QyxDQUFDO3FCQUFNLENBQUM7b0JBQ04sV0FBVyxDQUFDLElBQUksQ0FBQyxFQUFDLENBQUMsV0FBVyxDQUFDLEVBQUUsT0FBTyxFQUFDLENBQUMsQ0FBQztnQkFDN0MsQ0FBQztZQUNILENBQUM7UUFDSCxDQUFDO1FBQ0QsTUFBTSxJQUFJLEdBQUcsV0FBVyxZQUFZLFNBQVMsQ0FBQyxDQUFDLENBQUMsV0FBVyxDQUFDLFFBQVEsQ0FBRSxjQUEyQixFQUFFLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLFdBQVcsQ0FBQztRQUMvSCxjQUFjLENBQUMsV0FBVyxDQUFDLEdBQUcsSUFBaUIsQ0FBQztRQUNoRCxjQUFjLENBQUMsYUFBYSxDQUFDLEdBQUcsV0FBVyxDQUFDLEdBQUcsQ0FBQyxXQUFXLENBQWdCLENBQUM7UUFDNUUsY0FBYyxDQUFDLFVBQVUsQ0FBQyxHQUFHLFVBQVUsQ0FBQTtJQUN6QyxDQUFDO0lBRUQ7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O09Bc0NHO0lBQ0gsTUFBTSxDQUFDLGtCQUFrQixDQUFDLE1BQWMsRUFBRSxJQUFhO1FBQ3JELE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxZQUFZLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQzNDLElBQUksQ0FBQyxJQUFJO1lBQ1AsTUFBTSxJQUFJLEtBQUssQ0FBQyxpQkFBaUIsTUFBTSw4QkFBOEIsQ0FBQyxDQUFDO1FBRXpFLElBQUksQ0FBQyxJQUFJO1lBQ1AsT0FBTyxJQUFJLENBQUM7UUFFZCxNQUFNLE9BQU8sR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQy9CLElBQUksQ0FBQyxPQUFPO1lBQ1YsTUFBTSxJQUFJLEtBQUssQ0FBQyxzQkFBc0IsSUFBSSx3QkFBd0IsTUFBTSxJQUFJLENBQUMsQ0FBQztRQUNoRixPQUFPLE9BQU8sQ0FBQztJQUNqQixDQUFDO0lBR0Q7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztPQThCRztJQUNILE1BQU0sQ0FBQyxzQkFBc0IsQ0FBQyxFQUFVLEVBQUUsV0FBb0IsS0FBSyxFQUFHLFFBQTRCO1FBQ2hHLE1BQU0sSUFBSSxHQUFHLElBQUksU0FBUyxDQUFDLEVBQUUsQ0FBQyxDQUFDO1FBQy9CLElBQUcsUUFBUSxFQUFFLE1BQU07WUFDakIsUUFBUSxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsRUFBRTtnQkFDdkIsSUFBSSxDQUFDLGNBQWMsQ0FBQyxJQUFJLEVBQUUsS0FBSyxDQUFDLEtBQXdCLENBQUMsQ0FBQztZQUM1RCxDQUFDLENBQUMsQ0FBQztRQUNMLElBQUksUUFBUTtZQUNWLElBQUksQ0FBQyxXQUFXLENBQUMsRUFBRSxFQUFFLElBQUksQ0FBQyxDQUFDO1FBQzdCLE9BQU8sSUFBSSxDQUFDO0lBQ2QsQ0FBQztJQUVEOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7T0E4Qkc7SUFDSCxNQUFNLENBQUMsd0JBQXdCLENBQUMsRUFBVSxFQUFFLFVBQThCLEVBQUUsV0FBb0IsS0FBSztRQUNuRyxNQUFNLElBQUksR0FBRyxJQUFJLFNBQVMsQ0FBQyxFQUFFLENBQUMsQ0FBQztRQUMvQixVQUFVLENBQUMsT0FBTyxDQUFDLFNBQVMsQ0FBQyxFQUFFO1lBQzdCLElBQUksQ0FBQyxjQUFjLENBQUMsSUFBSSxFQUFFLFNBQVMsQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUM5QyxDQUFDLENBQUMsQ0FBQztRQUVILElBQUksUUFBUTtZQUNWLElBQUksQ0FBQyxXQUFXLENBQUMsRUFBRSxFQUFFLElBQUksQ0FBQyxDQUFDO1FBRTdCLE9BQU8sSUFBSSxDQUFDO0lBQ2QsQ0FBQztJQUVEOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O09BK0JHO0lBQ0gsTUFBTSxDQUFDLG1CQUFtQixDQUFDLEVBQVUsRUFBRSxtQkFBb0MsRUFBRSxXQUE2QjtRQUN4RyxJQUFJLElBQUksR0FBRyxJQUFJLENBQUMsVUFBVSxDQUFDLEVBQUUsRUFBRSxXQUFXLEVBQUUsSUFBSSxDQUFDLENBQUM7UUFDbEQsTUFBTSxVQUFVLEdBQUksSUFBa0IsQ0FBQyxNQUFNLENBQUM7UUFDOUMsSUFBRyxXQUFXLEVBQUUsS0FBSyxJQUFJLFdBQVcsRUFBRSxLQUFLLEdBQUcsQ0FBQyxFQUFFLENBQUM7WUFDaEQsSUFBSSxLQUFLLEdBQUcsbUJBQW1CLENBQUMsSUFBSSxJQUFJLFdBQVcsQ0FBQyxJQUFJLENBQUM7WUFDekQsSUFBRyxDQUFDLENBQUMsT0FBTyxLQUFLLEtBQUssUUFBUSxDQUFDLElBQUksS0FBSyxLQUFLLENBQUM7Z0JBQzVDLE1BQU0sS0FBSyxDQUFDLHNEQUFzRCxtQkFBbUIsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDO1lBRWhHLElBQUcsS0FBSyxHQUFHLFVBQVUsRUFBRSxDQUFDO2dCQUN0QixJQUFJLElBQWlCLEVBQUUsQ0FBQyxXQUFXLENBQUMsSUFBSSxLQUFLLEtBQU0sSUFBaUIsQ0FBQyxXQUFXLENBQUMsQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDO29CQUMxRixLQUFLLEdBQUksSUFBaUIsQ0FBQyxXQUFXLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQztnQkFDbkQsQ0FBQztxQkFBTSxDQUFDO29CQUNMLElBQWlCLENBQUMsV0FBVyxDQUFDLEdBQUc7d0JBQ2hDLElBQUksRUFBRSxLQUFLO3dCQUNYLEtBQUssRUFBRSxVQUFVLEdBQUcsQ0FBQztxQkFDdEIsQ0FBQztvQkFDRixLQUFLLEdBQUcsVUFBVSxHQUFHLENBQUMsQ0FBQztnQkFDekIsQ0FBQztZQUNILENBQUM7WUFFRCxJQUFJLEtBQUssR0FBSSxJQUFrQixDQUFDLFFBQVEsQ0FBRSxLQUFnQixHQUFHLENBQUMsQ0FBQyxDQUFDO1lBQ2hFLElBQUcsQ0FBQyxLQUFLLEVBQUUsQ0FBQztnQkFDVixLQUFLLEdBQUcsSUFBSSxTQUFTLENBQUMsRUFBRSxDQUFDLENBQUM7Z0JBQ3pCLElBQWtCLENBQUMsTUFBTSxDQUFDLEtBQWUsRUFBRSxLQUFLLENBQUMsQ0FBQztZQUNyRCxDQUFDO1lBQ0QsSUFBSSxHQUFHLEtBQWtCLENBQUM7UUFDNUIsQ0FBQztRQUNELElBQUcsbUJBQW1CLENBQUMsSUFBSTtZQUN6QixJQUFJLENBQUMsY0FBYyxDQUFDLElBQUksRUFBRSxtQkFBbUIsRUFBRSxXQUFXLENBQUMsQ0FBQztRQUM5RCxPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7SUFFRDs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O09BMENHO0lBQ0gsTUFBTSxDQUFDLFdBQVcsQ0FBQyxTQUFvQjtRQUNyQyxNQUFNLElBQUksR0FBNEIsRUFBRSxDQUFDO1FBQ3pDLEtBQUssTUFBTSxHQUFHLElBQUksU0FBUyxDQUFDLFFBQVEsRUFBRSxDQUFDO1lBQ3JDLE1BQU0sT0FBTyxHQUFHLFNBQVMsQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLENBQUM7WUFDeEMsTUFBTSxXQUFXLEdBQUcsY0FBYyxDQUFDLG1CQUFtQixDQUFDLFNBQWtDLENBQUMsQ0FBQztZQUMzRixJQUFJLENBQUMsQ0FBQyxPQUFPLFlBQVksV0FBVyxDQUFDLEVBQUUsQ0FBQztnQkFDdEMsTUFBTSxLQUFLLEdBQUcsY0FBYyxDQUFDLFdBQVcsQ0FBQyxPQUFvQixDQUFDLENBQUM7Z0JBQy9ELE1BQU0sT0FBTyxHQUFHLE9BQU8sQ0FBQyxLQUFLLENBQUM7Z0JBQzlCLElBQUcsV0FBVyxDQUFDLFFBQVEsRUFBRSxDQUFDO29CQUN0QixJQUFHLE9BQU8sRUFBRSxDQUFDO3dCQUNWLElBQUksQ0FBQyxHQUFHLENBQUMsR0FBRyxLQUFLLENBQUM7b0JBQ3JCLENBQUM7eUJBQU0sQ0FBQzt3QkFDTixJQUFJLENBQUMsS0FBSyxDQUFDLE9BQXNCLENBQUMsQ0FBQztvQkFDckMsQ0FBQztvQkFFRCxTQUFTO2dCQUNiLENBQUM7Z0JBQ0QsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLEtBQUssQ0FBQztnQkFDbEIsU0FBUztZQUNYLENBQUM7WUFFRCxNQUFNLEtBQUssR0FBRyxjQUFjLENBQUMsbUJBQW1CLENBQUMsT0FBa0MsQ0FBQyxDQUFDO1lBQ3JGLElBQUksS0FBSyxHQUFHLE9BQU8sQ0FBQyxLQUFLLENBQUM7WUFDMUIsSUFBSSxDQUFDLGVBQWUsQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxDQUFDLEVBQUUsQ0FBQztnQkFDN0MsUUFBUSxLQUFLLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQztvQkFDdEIsS0FBSyxlQUFlLENBQUMsTUFBTTt3QkFDekIsS0FBSyxHQUFHLGFBQWEsQ0FBQyxLQUFLLENBQUMsQ0FBQzt3QkFDN0IsTUFBTTtvQkFDUixLQUFLLGVBQWUsQ0FBQyxJQUFJLENBQUM7b0JBQzFCLEtBQUssZUFBZSxDQUFDLGNBQWM7d0JBQ2pDLEtBQUssR0FBRyxJQUFJLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQzt3QkFDeEIsTUFBTTtvQkFDUjt3QkFDRSxLQUFLLEdBQUcsVUFBVSxDQUFDLEtBQUssQ0FBQyxDQUFDO2dCQUM5QixDQUFDO1lBQ0gsQ0FBQztZQUNELElBQUksQ0FBQyxHQUFHLENBQUMsR0FBRyxLQUFLLENBQUM7UUFDcEIsQ0FBQztRQUNELGNBQWMsQ0FBQyxzQkFBc0IsQ0FBQyxTQUFzQixDQUFDLENBQUM7UUFDOUQsT0FBTyxJQUFJLENBQUM7SUFDZCxDQUFDO0lBRUQ7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztPQWdERztJQUNILE1BQU0sQ0FBQyxjQUFjLENBQUMsT0FBd0IsRUFBRSxFQUFXLEVBQUcsSUFBYTtRQUN6RSxPQUFPLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBb0IsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDO1FBQ2hFLElBQUksQ0FBQyxPQUFPO1lBQ1YsTUFBTSxJQUFJLEtBQUssQ0FBQyw2QkFBNkIsSUFBSSxJQUFJLE1BQU0sR0FBRyxDQUFDLENBQUM7UUFFbEUsTUFBTSxTQUFTLEdBQUcsQ0FBQyxTQUFTLEVBQUUsU0FBUyxFQUFFLFdBQVcsQ0FBQyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLE9BQU8sWUFBWSxJQUFJLENBQUMsQ0FBQztRQUM1RixJQUFJLENBQUMsU0FBUztZQUNaLE1BQU0sSUFBSSxLQUFLLENBQUMsNEJBQTRCLElBQUksSUFBSSxNQUFNLEVBQUUsQ0FBQyxDQUFDO1FBRWhFLE9BQU8sQ0FBQyxhQUFhLEVBQUUsQ0FBQztRQUN4QixPQUFPLENBQUMsV0FBVyxFQUFFLENBQUM7UUFDdEIsT0FBTyxDQUFDLHNCQUFzQixDQUFDLEVBQUUsU0FBUyxFQUFFLElBQUksRUFBRSxDQUFDLENBQUM7UUFFcEQsSUFBSSxPQUFPLFlBQVksU0FBUyxFQUFFLENBQUM7WUFDakMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDLENBQUMsT0FBTyxDQUFDLFlBQVksQ0FBQyxFQUFFO2dCQUNyRCxJQUFJLENBQUMsY0FBYyxDQUFDLFlBQVksQ0FBQyxDQUFDO1lBQ3BDLENBQUMsQ0FBQyxDQUFDO1FBQ0wsQ0FBQztRQUVELElBQUksT0FBTyxZQUFZLFNBQVMsRUFBRSxDQUFDO1lBQ2pDLE1BQU0sV0FBVyxHQUFHLE9BQU8sQ0FBQyxNQUFNLENBQUM7WUFDbkMsTUFBTSxRQUFRLEdBQUcsT0FBTyxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLENBQUM7WUFDakUsSUFBRyxXQUFXLEdBQUcsQ0FBQyxJQUFJLFFBQVEsRUFBRSxDQUFDO2dCQUM5QixLQUFLLElBQUksQ0FBQyxHQUFHLE9BQU8sQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQztvQkFDOUMsTUFBTSxZQUFZLEdBQUcsT0FBTyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQztvQkFDbkMsbUNBQW1DO29CQUNuQyxJQUFJLENBQUMsWUFBWSxDQUFDLEtBQUssRUFBRSxDQUFDO3dCQUN2QixZQUFZLENBQUMsTUFBb0IsQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLENBQUM7d0JBQ2pELFlBQVksQ0FBQyxNQUFvQixDQUFDLHNCQUFzQixDQUFDLEVBQUUsU0FBUyxFQUFFLElBQUksRUFBRSxDQUFDLENBQUM7d0JBQ2hGLFlBQVksQ0FBQyxPQUFPLEVBQUUsQ0FBQztvQkFDekIsQ0FBQzt5QkFBTSxDQUFDO3dCQUNOLElBQUksQ0FBQyxjQUFjLENBQUMsWUFBWSxDQUFDLENBQUM7b0JBQ3BDLENBQUM7Z0JBQ0gsQ0FBQztZQUNILENBQUM7aUJBQU0sQ0FBQztnQkFDTixNQUFNLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUMsQ0FBQyxPQUFPLENBQUMsWUFBWSxDQUFDLEVBQUU7b0JBQ3JELElBQUksQ0FBQyxjQUFjLENBQUMsWUFBWSxDQUFDLENBQUM7Z0JBQ3BDLENBQUMsQ0FBQyxDQUFDO1lBQ0wsQ0FBQztRQUNILENBQUM7UUFFRCxxRUFBcUU7UUFDckUsK0NBQStDO1FBQy9DLGdCQUFnQjtRQUNoQixxQkFBcUI7UUFDckIsMEZBQTBGO1FBQzFGLElBQUk7UUFFSixPQUFPLE9BQU8sQ0FBQyxLQUFLLENBQUM7SUFDdkIsQ0FBQztJQUVEOzs7OztPQUtHO0lBQ0ssTUFBTSxDQUFDLG1CQUFtQixDQUFDLEtBQXNCO1FBQ3ZELE1BQU0sdUJBQXVCLEdBQUcsVUFBVSxDQUFDLElBQUksRUFBRSxDQUFDO1FBQ2xELE9BQU8sTUFBTSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUM7YUFDdEIsTUFBTSxDQUFDLENBQUMsQ0FBUyxFQUFFLEVBQUUsQ0FBQyx1QkFBdUIsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLENBQUM7YUFDMUQsR0FBRyxDQUFDLENBQUMsQ0FBUyxFQUFFLEVBQUU7WUFDakIsT0FBTyxnQkFBZ0IsQ0FBQyxLQUFLLENBQUMsS0FBSyxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBQzFDLENBQUMsQ0FBQyxDQUFDO0lBQ1AsQ0FBQztJQUVEOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O09Ba0NHO0lBQ0gsTUFBTSxDQUFDLFNBQVMsQ0FBQyxLQUFzQixFQUFFLGFBQThCLFFBQVE7UUFDN0UsTUFBTSxVQUFVLEdBQUcsSUFBSSxDQUFDLG1CQUFtQixDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQ25ELE1BQU0sUUFBUSxHQUFHLFVBQVUsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxPQUFPLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQztRQUMzRSxPQUFPLElBQUksV0FBVyxDQUNwQjtZQUNFLEtBQUssRUFDSCxLQUFLLENBQUMsS0FBSyxJQUFJLEtBQUssQ0FBQyxJQUFJLEtBQUssZUFBZSxDQUFDLFFBQVE7Z0JBQ3BELENBQUMsQ0FBQyxLQUFLLENBQUMsSUFBSSxLQUFLLGVBQWUsQ0FBQyxJQUFJO29CQUNuQyxDQUFDLENBQUMsQ0FBQyxXQUFXLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxNQUFnQixFQUFFLEtBQUssQ0FBQyxLQUFlLENBQUMsQ0FBQzt3QkFDdEUsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFDO29CQUM1QixLQUFLLENBQUMsS0FBaUIsQ0FBQyxDQUFDLENBQUMsU0FBUztZQUMxQyxRQUFRLEVBQUUsS0FBSyxDQUFDLFFBQVE7U0FDekIsRUFDRDtZQUNFLFVBQVUsRUFBRSxRQUFRO1lBQ3BCLFFBQVEsRUFBRSxVQUFVO1NBQ3JCLENBQ0YsQ0FBQztJQUNKLENBQUM7SUFFRDs7Ozs7Ozs7Ozs7T0FXRztJQUNILE1BQU0sQ0FBQyxtQkFBbUIsQ0FBQyxPQUE0QztRQUNyRSxPQUFPLElBQUksQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxJQUFJLEVBQXFCLENBQUM7SUFDN0QsQ0FBQztJQUVEOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7T0E4Qkc7SUFDSCxNQUFNLENBQUMsV0FBVyxDQUFDLEVBQWUsRUFBRSxHQUFXO1FBQzdDLElBQUksTUFBMEIsQ0FBQztRQUMvQixPQUFPLENBQUMsTUFBTSxHQUFHLEVBQUUsQ0FBQyxhQUFhLENBQUMsS0FBSyxJQUFJLEVBQUUsQ0FBQztZQUM1QyxJQUFJLE1BQU0sQ0FBQyxPQUFPLENBQUMsV0FBVyxFQUFFLEtBQUssR0FBRyxDQUFDLFdBQVcsRUFBRSxFQUFFLENBQUM7Z0JBQ3ZELE9BQU8sTUFBTSxDQUFDO1lBQ2hCLENBQUM7WUFDRCxFQUFFLEdBQUcsTUFBTSxDQUFDO1FBQ2QsQ0FBQztRQUNELE1BQU0sSUFBSSxLQUFLLENBQ2IsMEJBQTBCLEdBQUcsaUNBQWlDLENBQy9ELENBQUM7SUFDSixDQUFDO0lBRUQ7Ozs7Ozs7Ozs7OztPQVlHO0lBQ0gsTUFBTSxDQUFDLFFBQVEsQ0FBQyxPQUF3QixFQUFFLEtBQXNCO1FBQzlELElBQUksQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLE9BQU8sRUFBRSxLQUFLLENBQUMsQ0FBQztJQUNwQyxDQUFDO0lBRUQ7Ozs7O09BS0c7SUFDSCxNQUFNLENBQUMsVUFBVSxDQUFDLE9BQXdCO1FBQ3hDLE9BQU8sSUFBSSxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLENBQUM7SUFDdkMsQ0FBQztJQUVEOzs7O09BSUc7SUFDSCxNQUFNLENBQUMsS0FBSyxDQUFDLFNBQWtDO1FBQzdDLElBQUcsU0FBUyxZQUFZLFdBQVcsRUFBRSxDQUFDO1lBQ3BDLE1BQU0sT0FBTyxHQUFHLFNBQXdCLENBQUM7WUFDekMsTUFBTSxFQUFFLElBQUksRUFBRSxHQUFHLGNBQWMsQ0FBQyxtQkFBbUIsQ0FBQyxPQUFPLENBQUMsQ0FBQztZQUM3RCxJQUFJLENBQUMsZUFBZSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUM7Z0JBQ2pDLE9BQU8sQ0FBQyxRQUFRLENBQUMsRUFBRSxDQUFDLENBQUM7WUFDdkIsT0FBTyxDQUFDLGNBQWMsRUFBRSxDQUFDO1lBQ3pCLE9BQU8sQ0FBQyxlQUFlLEVBQUUsQ0FBQztZQUMxQixPQUFPLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxDQUFDO1lBQ3hCLE9BQU8sQ0FBQyxzQkFBc0IsRUFBRSxDQUFDO1FBQ25DLENBQUM7YUFBTSxDQUFDO1lBQ04sS0FBSyxNQUFNLEdBQUcsSUFBSSxTQUFTLENBQUMsUUFBUSxFQUFFLENBQUM7Z0JBQ3JDLE1BQU0sT0FBTyxHQUFHLFNBQVMsQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLENBQUM7Z0JBQ3hDLGNBQWMsQ0FBQyxLQUFLLENBQUMsT0FBc0IsQ0FBQyxDQUFDO2dCQUM3QyxTQUFTO1lBQ1gsQ0FBQztRQUNILENBQUM7SUFDSCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgZXNjYXBlSHRtbCwgRmllbGRQcm9wZXJ0aWVzLCBIVE1MNUNoZWNrVHlwZXMsIEhUTUw1SW5wdXRUeXBlcywgcGFyc2VUb051bWJlciwgVUlNb2RlbE1ldGFkYXRhIH0gZnJvbSAnQGRlY2FmLXRzL3VpLWRlY29yYXRvcnMnO1xuaW1wb3J0IHsgRmllbGRVcGRhdGVNb2RlLCBGb3JtUGFyZW50LCBGb3JtUGFyZW50R3JvdXAsIEtleVZhbHVlIH0gZnJvbSAnLi90eXBlcyc7XG5pbXBvcnQgeyBJQ29tcG9uZW50Q29uZmlnLCBJQ29tcG9uZW50SW5wdXQgfSBmcm9tICcuL2ludGVyZmFjZXMnO1xuaW1wb3J0IHsgQWJzdHJhY3RDb250cm9sLCBGb3JtQXJyYXksIEZvcm1Db250cm9sLCBGb3JtR3JvdXAsIFZhbGlkYXRvckZuLCBWYWxpZGF0b3JzIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuaW1wb3J0IHsgaXNWYWxpZERhdGUsIE1vZGVsS2V5cywgcGFyc2VEYXRlLCBQcmltaXRpdmVzLCBWYWxpZGF0aW9uIH0gZnJvbSAnQGRlY2FmLXRzL2RlY29yYXRvci12YWxpZGF0aW9uJztcbmltcG9ydCB7IFZhbGlkYXRvckZhY3RvcnkgfSBmcm9tICcuL1ZhbGlkYXRvckZhY3RvcnknO1xuaW1wb3J0IHsgY2xlYW5TcGFjZXMgfSBmcm9tICcuLi9oZWxwZXJzJztcbmltcG9ydCB7IE9wZXJhdGlvbktleXMgfSBmcm9tICdAZGVjYWYtdHMvZGItZGVjb3JhdG9ycyc7XG5pbXBvcnQgeyBBbmd1bGFyRW5naW5lS2V5cywgQmFzZUNvbXBvbmVudFByb3BzIH0gZnJvbSAnLi4vZW5naW5lL2NvbnN0YW50cyc7XG5cblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gU2VydmljZSBmb3IgbWFuYWdpbmcgQW5ndWxhciBmb3JtcyBhbmQgZm9ybSBjb250cm9scy5cbiAqIEBzdW1tYXJ5IFRoZSBOZ3hGb3JtU2VydmljZSBwcm92aWRlcyB1dGlsaXR5IG1ldGhvZHMgZm9yIGNyZWF0aW5nLCBtYW5hZ2luZywgYW5kIHZhbGlkYXRpbmcgQW5ndWxhciBmb3JtcyBhbmQgZm9ybSBjb250cm9scy4gSXQgaW5jbHVkZXMgZnVuY3Rpb25hbGl0eSBmb3IgcmVnaXN0ZXJpbmcgZm9ybXMsIGFkZGluZyBjb250cm9scywgdmFsaWRhdGluZyBmaWVsZHMsIGFuZCBoYW5kbGluZyBmb3JtIGRhdGEuXG4gKlxuICogQGNsYXNzXG4gKiBAcGFyYW0ge1dlYWtNYXA8QWJzdHJhY3RDb250cm9sLCBGaWVsZFByb3BlcnRpZXM+fSBjb250cm9scyAtIEEgV2Vha01hcCB0byBzdG9yZSBjb250cm9sIHByb3BlcnRpZXMuXG4gKiBAcGFyYW0ge01hcDxzdHJpbmcsIEZvcm1Hcm91cD59IGZvcm1SZWdpc3RyeSAtIEEgTWFwIHRvIHN0b3JlIHJlZ2lzdGVyZWQgZm9ybXMuXG4gKlxuICogQGV4YW1wbGVcbiAqIC8vIENyZWF0aW5nIGEgZm9ybSBmcm9tIGNvbXBvbmVudHNcbiAqIGNvbnN0IGNvbXBvbmVudHMgPSBbXG4gKiAgIHsgaW5wdXRzOiB7IG5hbWU6ICd1c2VybmFtZScsIHR5cGU6ICd0ZXh0JywgcmVxdWlyZWQ6IHRydWUgfSB9LFxuICogICB7IGlucHV0czogeyBuYW1lOiAncGFzc3dvcmQnLCB0eXBlOiAncGFzc3dvcmQnLCBtaW5MZW5ndGg6IDggfSB9XG4gKiBdO1xuICogY29uc3QgZm9ybSA9IE5neEZvcm1TZXJ2aWNlLmNyZWF0ZUZvcm1Gcm9tQ29tcG9uZW50cygnbG9naW5Gb3JtJywgY29tcG9uZW50cywgdHJ1ZSk7XG4gKlxuICogLy8gVmFsaWRhdGluZyBmaWVsZHNcbiAqIE5neEZvcm1TZXJ2aWNlLnZhbGlkYXRlRmllbGRzKGZvcm0pO1xuICpcbiAqIC8vIEdldHRpbmcgZm9ybSBkYXRhXG4gKiBjb25zdCBmb3JtRGF0YSA9IE5neEZvcm1TZXJ2aWNlLmdldEZvcm1EYXRhKGZvcm0pO1xuICpcbiAqIEBtZXJtYWlkXG4gKiBzZXF1ZW5jZURpYWdyYW1cbiAqICAgcGFydGljaXBhbnQgQyBhcyBDb21wb25lbnRcbiAqICAgcGFydGljaXBhbnQgTkZTIGFzIE5neEZvcm1TZXJ2aWNlXG4gKiAgIHBhcnRpY2lwYW50IEFGIGFzIEFuZ3VsYXIgRm9ybXNcbiAqICAgQy0+Pk5GUzogY3JlYXRlRm9ybUZyb21Db21wb25lbnRzKClcbiAqICAgTkZTLT4+QUY6IG5ldyBGb3JtR3JvdXAoKVxuICogICBORlMtPj5ORlM6IGFkZEZvcm1Db250cm9sKClcbiAqICAgTkZTLT4+QUY6IGFkZENvbnRyb2woKVxuICogICBORlMtLT4+QzogUmV0dXJuIEZvcm1Hcm91cFxuICogICBDLT4+TkZTOiB2YWxpZGF0ZUZpZWxkcygpXG4gKiAgIE5GUy0+PkFGOiBtYXJrQXNUb3VjaGVkKCksIG1hcmtBc0RpcnR5KCksIHVwZGF0ZVZhbHVlQW5kVmFsaWRpdHkoKVxuICogICBDLT4+TkZTOiBnZXRGb3JtRGF0YSgpXG4gKiAgIE5GUy0+PkFGOiBHZXQgY29udHJvbCB2YWx1ZXNcbiAqICAgTkZTLS0+PkM6IFJldHVybiBmb3JtIGRhdGFcbiAqL1xuZXhwb3J0IGNsYXNzIE5neEZvcm1TZXJ2aWNlIHtcbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBXZWFrTWFwIHRoYXQgc3RvcmVzIGNvbnRyb2wgcHJvcGVydGllcyBmb3IgZm9ybSBjb250cm9scy5cbiAgICogQHN1bW1hcnkgQSBXZWFrTWFwIHRoYXQgYXNzb2NpYXRlcyBBYnN0cmFjdENvbnRyb2wgaW5zdGFuY2VzIHdpdGggdGhlaXIgY29ycmVzcG9uZGluZyBGaWVsZFByb3BlcnRpZXMuXG4gICAqIFRoaXMgYWxsb3dzIHRoZSBzZXJ2aWNlIHRvIHRyYWNrIG1ldGFkYXRhIGZvciBmb3JtIGNvbnRyb2xzIHdpdGhvdXQgY3JlYXRpbmcgbWVtb3J5IGxlYWtzLlxuICAgKlxuICAgKiBAdHlwZSB7V2Vha01hcDxBYnN0cmFjdENvbnRyb2wsIEZpZWxkUHJvcGVydGllcz59XG4gICAqIEBwcml2YXRlXG4gICAqIEBzdGF0aWNcbiAgICogQG1lbWJlck9mIE5neEZvcm1TZXJ2aWNlXG4gICAqL1xuICBwcml2YXRlIHN0YXRpYyBjb250cm9sczogV2Vha01hcDxBYnN0cmFjdENvbnRyb2wsIEZpZWxkUHJvcGVydGllcz4gPSBuZXcgV2Vha01hcDxBYnN0cmFjdENvbnRyb2wsIEZpZWxkUHJvcGVydGllcz4oKTtcblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFJlZ2lzdHJ5IG9mIGZvcm0gZ3JvdXBzIGluZGV4ZWQgYnkgdGhlaXIgdW5pcXVlIGlkZW50aWZpZXJzLlxuICAgKiBAc3VtbWFyeSBBIE1hcCB0aGF0IHN0b3JlcyBGb3JtR3JvdXAgaW5zdGFuY2VzIHdpdGggdGhlaXIgdW5pcXVlIHN0cmluZyBpZGVudGlmaWVycy5cbiAgICogVGhpcyBhbGxvd3MgZ2xvYmFsIGFjY2VzcyB0byByZWdpc3RlcmVkIGZvcm1zIHRocm91Z2hvdXQgdGhlIGFwcGxpY2F0aW9uLlxuICAgKlxuICAgKiBAdHlwZSB7TWFwPHN0cmluZywgRm9ybUdyb3VwPn1cbiAgICogQHByaXZhdGVcbiAgICogQHN0YXRpY1xuICAgKiBAbWVtYmVyT2YgTmd4Rm9ybVNlcnZpY2VcbiAgICovXG4gIHByaXZhdGUgc3RhdGljIGZvcm1SZWdpc3RyeTogTWFwPHN0cmluZywgRm9ybVBhcmVudD4gPSBuZXcgTWFwPHN0cmluZywgRm9ybVBhcmVudD4oKTtcblxuICBwcml2YXRlIHN0YXRpYyBwYWdlTWFwcGVyOiBLZXlWYWx1ZSA9IHt9O1xuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gQ3JlYXRlcyBhIG5ldyBmb3JtIGdyb3VwIG9yIGZvcm0gYXJyYXkgd2l0aCB0aGUgc3BlY2lmaWVkIGlkZW50aWZpZXIuXG4gICAqIEBzdW1tYXJ5IEdlbmVyYXRlcyBhIEZvcm1Hcm91cCBvciBGb3JtQXJyYXkgYmFzZWQgb24gdGhlIHByb3ZpZGVkIHByb3BlcnRpZXMuIElmIHBhZ2VzIGFyZSBzcGVjaWZpZWRcbiAgICogYW5kIGdyZWF0ZXIgdGhhbiAxLCBjcmVhdGVzIGEgRm9ybUFycmF5OyBvdGhlcndpc2UgY3JlYXRlcyBhIEZvcm1Hcm91cC4gVGhlIGZvcm0gY2FuIG9wdGlvbmFsbHlcbiAgICogYmUgcmVnaXN0ZXJlZCBpbiB0aGUgZ2xvYmFsIGZvcm0gcmVnaXN0cnkgZm9yIGxhdGVyIGFjY2VzcyB0aHJvdWdob3V0IHRoZSBhcHBsaWNhdGlvbi5cbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmd9IGlkIC0gVW5pcXVlIGlkZW50aWZpZXIgZm9yIHRoZSBmb3JtXG4gICAqIEBwYXJhbSB7UGFydGlhbDxJQ29tcG9uZW50SW5wdXQ+fSBbcHJvcHM9e31dIC0gQ29uZmlndXJhdGlvbiBwcm9wZXJ0aWVzIGZvciB0aGUgZm9ybVxuICAgKiBAcGFyYW0ge2Jvb2xlYW59IFtyZWdpc3RyeT10cnVlXSAtIFdoZXRoZXIgdG8gcmVnaXN0ZXIgdGhlIGZvcm0gaW4gdGhlIGdsb2JhbCByZWdpc3RyeVxuICAgKiBAcmV0dXJuIHtGb3JtR3JvdXAgfCBGb3JtQXJyYXl9IFRoZSBjcmVhdGVkIGZvcm0gaW5zdGFuY2VcbiAgICpcbiAgICogQG1lcm1haWRcbiAgICogc2VxdWVuY2VEaWFncmFtXG4gICAqICAgcGFydGljaXBhbnQgQyBhcyBDb21wb25lbnRcbiAgICogICBwYXJ0aWNpcGFudCBORlMgYXMgTmd4Rm9ybVNlcnZpY2VcbiAgICogICBwYXJ0aWNpcGFudCBGUiBhcyBGb3JtIFJlZ2lzdHJ5XG4gICAqICAgcGFydGljaXBhbnQgQUYgYXMgQW5ndWxhciBGb3Jtc1xuICAgKlxuICAgKiAgIEMtPj5ORlM6IGNyZWF0ZUZvcm0oaWQsIHByb3BzLCByZWdpc3RyeSlcbiAgICogICBORlMtPj5GUjogQ2hlY2sgaWYgZm9ybSBleGlzdHNcbiAgICogICBhbHQgRm9ybSBkb2Vzbid0IGV4aXN0XG4gICAqICAgICBhbHQgcHJvcHMucGFnZXMgPiAxXG4gICAqICAgICAgIE5GUy0+PkFGOiBuZXcgRm9ybUFycmF5KFtdKVxuICAgKiAgICAgZWxzZVxuICAgKiAgICAgICBORlMtPj5BRjogbmV3IEZvcm1Hcm91cCh7fSlcbiAgICogICAgIGVuZFxuICAgKiAgICAgYWx0IHJlZ2lzdHJ5IGlzIHRydWVcbiAgICogICAgICAgTkZTLT4+RlI6IGFkZFJlZ2lzdHJ5KGlkLCBmb3JtKVxuICAgKiAgICAgZW5kXG4gICAqICAgZW5kXG4gICAqICAgTkZTLS0+PkM6IFJldHVybiBGb3JtR3JvdXAgfCBGb3JtQXJyYXlcbiAgICpcbiAgICogQHN0YXRpY1xuICAgKiBAbWVtYmVyT2YgTmd4Rm9ybVNlcnZpY2VcbiAgICovXG4gIHN0YXRpYyBjcmVhdGVGb3JtKGlkOiBzdHJpbmcsIHByb3BzOiBQYXJ0aWFsPElDb21wb25lbnRJbnB1dD4gPSB7fSwgcmVnaXN0cnk6IGJvb2xlYW4gPSB0cnVlKTogRm9ybUdyb3VwIHwgRm9ybUFycmF5IHtcbiAgICBjb25zdCBmb3JtID0gdGhpcy5mb3JtUmVnaXN0cnkuZ2V0KGlkKSA/PyAocHJvcHM/LnBhZ2VzICYmIHByb3BzPy5wYWdlcyAgPiAxID8gbmV3IEZvcm1BcnJheShbXSkgOiBuZXcgRm9ybUdyb3VwKHt9KSk7XG4gICAgaWYgKCF0aGlzLmZvcm1SZWdpc3RyeS5oYXMoaWQpICYmIHJlZ2lzdHJ5KVxuICAgICAgdGhpcy5hZGRSZWdpc3RyeShpZCwgZm9ybSBhcyBGb3JtQXJyYXkgfCBGb3JtR3JvdXApO1xuICAgIHJldHVybiBmb3JtIGFzIEZvcm1BcnJheSB8IEZvcm1Hcm91cDtcbiAgfVxuXG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBBZGRzIGEgZm9ybSB0byB0aGUgcmVnaXN0cnkuXG4gICAqIEBzdW1tYXJ5IFJlZ2lzdGVycyBhIEZvcm1Hcm91cCBvciBGb3JtQXJyYXkgd2l0aCBhIHVuaXF1ZSBpZGVudGlmaWVyIGZvciBnbG9iYWwgYWNjZXNzIHRocm91Z2hvdXRcbiAgICogdGhlIGFwcGxpY2F0aW9uLiBUaGlzIGFsbG93cyBmb3JtcyB0byBiZSByZXRyaWV2ZWQgYW5kIG1hbmFnZWQgY2VudHJhbGx5LiBUaHJvd3MgYW4gZXJyb3IgaWZcbiAgICogdGhlIGlkZW50aWZpZXIgaXMgYWxyZWFkeSBpbiB1c2UgdG8gcHJldmVudCBjb25mbGljdHMuXG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBmb3JtSWQgLSBUaGUgdW5pcXVlIGlkZW50aWZpZXIgZm9yIHRoZSBmb3JtXG4gICAqIEBwYXJhbSB7Rm9ybVBhcmVudH0gZm9ybUdyb3VwIC0gVGhlIEZvcm1Hcm91cCBvciBGb3JtQXJyYXkgdG8gYmUgcmVnaXN0ZXJlZFxuICAgKiBAcmV0dXJuIHt2b2lkfVxuICAgKiBAdGhyb3dzIHtFcnJvcn0gSWYgYSBGb3JtR3JvdXAgd2l0aCB0aGUgZ2l2ZW4gaWQgaXMgYWxyZWFkeSByZWdpc3RlcmVkXG4gICAqXG4gICAqIEBzdGF0aWNcbiAgICogQG1lbWJlck9mIE5neEZvcm1TZXJ2aWNlXG4gICAqL1xuICBzdGF0aWMgYWRkUmVnaXN0cnkoZm9ybUlkOiBzdHJpbmcsIGZvcm1Hcm91cDogRm9ybVBhcmVudCk6IHZvaWQge1xuICAgIGlmICh0aGlzLmZvcm1SZWdpc3RyeS5oYXMoZm9ybUlkKSlcbiAgICAgIHRocm93IG5ldyBFcnJvcihgQSBGb3JtR3JvdXAgd2l0aCBpZCAnJHtmb3JtSWR9JyBpcyBhbHJlYWR5IHJlZ2lzdGVyZWQuYCk7XG4gICAgdGhpcy5mb3JtUmVnaXN0cnkuc2V0KGZvcm1JZCwgZm9ybUdyb3VwKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gUmVtb3ZlcyBhIGZvcm0gZnJvbSB0aGUgcmVnaXN0cnkuXG4gICAqIEBzdW1tYXJ5IERlbGV0ZXMgYSBGb3JtR3JvdXAgb3IgRm9ybUFycmF5IGZyb20gdGhlIHJlZ2lzdHJ5IHVzaW5nIGl0cyB1bmlxdWUgaWRlbnRpZmllci5cbiAgICogVGhpcyBjbGVhbnMgdXAgdGhlIHJlZ2lzdHJ5IGFuZCBhbGxvd3MgdGhlIGlkZW50aWZpZXIgdG8gYmUgcmV1c2VkLiBUaGUgZm9ybSBpdHNlbGZcbiAgICogaXMgbm90IGRlc3Ryb3llZCwgb25seSByZW1vdmVkIGZyb20gdGhlIGNlbnRyYWwgcmVnaXN0cnkuXG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBmb3JtSWQgLSBUaGUgdW5pcXVlIGlkZW50aWZpZXIgb2YgdGhlIGZvcm0gdG8gYmUgcmVtb3ZlZFxuICAgKiBAcmV0dXJuIHt2b2lkfVxuICAgKlxuICAgKiBAc3RhdGljXG4gICAqIEBtZW1iZXJPZiBOZ3hGb3JtU2VydmljZVxuICAgKi9cbiAgc3RhdGljIHJlbW92ZVJlZ2lzdHJ5KGZvcm1JZDogc3RyaW5nKTogdm9pZCB7XG4gICAgdGhpcy5mb3JtUmVnaXN0cnkuZGVsZXRlKGZvcm1JZCk7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFJlc29sdmVzIHRoZSBwYXJlbnQgZ3JvdXAgYW5kIGNvbnRyb2wgbmFtZSBmcm9tIGEgcGF0aC5cbiAgICogQHN1bW1hcnkgVHJhdmVyc2VzIHRoZSBmb3JtIGdyb3VwIHN0cnVjdHVyZSB0byBmaW5kIHRoZSBwYXJlbnQgZ3JvdXAgYW5kIGNvbnRyb2wgbmFtZSBmb3IgYSBnaXZlbiBwYXRoLlxuICAgKiBIYW5kbGVzIGNvbXBsZXggbmVzdGVkIHN0cnVjdHVyZXMgaW5jbHVkaW5nIGFycmF5cyBhbmQgc3ViLWdyb3Vwcy4gQ3JlYXRlcyBtaXNzaW5nIGludGVybWVkaWF0ZVxuICAgKiBncm91cHMgYXMgbmVlZGVkIGFuZCBwcm9wZXJseSBjb25maWd1cmVzIEZvcm1BcnJheSBjb250cm9scyBmb3IgbXVsdGlwbGUgdmFsdWUgc2NlbmFyaW9zLlxuICAgKlxuICAgKiBAcGFyYW0ge0Zvcm1Hcm91cH0gZm9ybUdyb3VwIC0gVGhlIHJvb3QgRm9ybUdyb3VwIHRvIHRyYXZlcnNlXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBwYXRoIC0gVGhlIGRvdC1zZXBhcmF0ZWQgcGF0aCB0byB0aGUgY29udHJvbCAoZS5nLiwgJ3VzZXIuYWRkcmVzcy5zdHJlZXQnKVxuICAgKiBAcGFyYW0ge0lDb21wb25lbnRJbnB1dH0gY29tcG9uZW50UHJvcHMgLSBQcm9wZXJ0aWVzIGRlZmluaW5nIHRoZSBjb21wb25lbnQgY29uZmlndXJhdGlvblxuICAgKiBAcGFyYW0ge0tleVZhbHVlfSBwYXJlbnRQcm9wcyAtIFByb3BlcnRpZXMgZnJvbSB0aGUgcGFyZW50IGNvbXBvbmVudCBmb3IgY29udGV4dFxuICAgKiBAcmV0dXJuIHtGb3JtUGFyZW50R3JvdXB9IEEgdHVwbGUgY29udGFpbmluZyB0aGUgcGFyZW50IEZvcm1Hcm91cCBhbmQgdGhlIGNvbnRyb2wgbmFtZVxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAbWVybWFpZFxuICAgKiBzZXF1ZW5jZURpYWdyYW1cbiAgICogICBwYXJ0aWNpcGFudCBORlMgYXMgTmd4Rm9ybVNlcnZpY2VcbiAgICogICBwYXJ0aWNpcGFudCBGRyBhcyBGb3JtR3JvdXBcbiAgICogICBwYXJ0aWNpcGFudCBGQSBhcyBGb3JtQXJyYXlcbiAgICpcbiAgICogICBORlMtPj5ORlM6IFNwbGl0IHBhdGggaW50byBwYXJ0c1xuICAgKiAgIGxvb3AgRm9yIGVhY2ggcGF0aCBwYXJ0XG4gICAqICAgICBhbHQgQ29udHJvbCBkb2Vzbid0IGV4aXN0XG4gICAqICAgICAgIGFsdCBpc011bHRpcGxlIGFuZCBwYXJ0IGlzIGNoaWxkT2ZcbiAgICogICAgICAgICBORlMtPj5GQTogbmV3IEZvcm1BcnJheShbbmV3IEZvcm1Hcm91cCh7fSldKVxuICAgKiAgICAgICBlbHNlXG4gICAqICAgICAgICAgTkZTLT4+Rkc6IG5ldyBGb3JtR3JvdXAoe30pXG4gICAqICAgICAgIGVuZFxuICAgKiAgICAgICBORlMtPj5GRzogYWRkQ29udHJvbChwYXJ0LCBuZXdDb250cm9sKVxuICAgKiAgICAgZW5kXG4gICAqICAgICBORlMtPj5ORlM6IE5hdmlnYXRlIHRvIG5leHQgbGV2ZWxcbiAgICogICBlbmRcbiAgICogICBORlMtLT4+TkZTOiBSZXR1cm4gW3BhcmVudEdyb3VwLCBjb250cm9sTmFtZV1cbiAgICpcbiAgICogQHN0YXRpY1xuICAgKiBAbWVtYmVyT2YgTmd4Rm9ybVNlcnZpY2VcbiAgICovXG4gIHByaXZhdGUgc3RhdGljIHJlc29sdmVQYXJlbnRHcm91cChmb3JtR3JvdXA6IEZvcm1Hcm91cCwgcGF0aDogc3RyaW5nLCBjb21wb25lbnRQcm9wczogSUNvbXBvbmVudElucHV0LCBwYXJlbnRQcm9wczogS2V5VmFsdWUpOiBGb3JtUGFyZW50R3JvdXAge1xuICAgIGNvbnN0IGlzTXVsdGlwbGUgPSBwYXJlbnRQcm9wcz8uWydtdWx0aXBsZSddIHx8IHBhcmVudFByb3BzPy5bJ3R5cGUnXSA9PT0gJ0FycmF5JyB8fCBmYWxzZTtcbiAgICBjb25zdCBwYXJ0cyA9IHBhdGguc3BsaXQoJy4nKTtcbiAgICBjb25zdCBjb250cm9sTmFtZSA9IHBhcnRzLnBvcCgpIGFzIHN0cmluZztcbiAgICBjb25zdCB7Y2hpbGRPZn0gPSBjb21wb25lbnRQcm9wc1xuICAgIGxldCBjdXJyZW50R3JvdXAgPSBmb3JtR3JvdXA7XG5cbiAgICBmdW5jdGlvbiBzZXRBcnJheUNvbXBvbmVudFByb3BzKGZvcm1Hcm91cEFycmF5OiBGb3JtQXJyYXkpIHtcbiAgICAgIGNvbnN0IHByb3BzID0gKGZvcm1Hcm91cEFycmF5IGFzIEtleVZhbHVlKVtBbmd1bGFyRW5naW5lS2V5cy5GT1JNX0dST1VQX0NPTVBPTkVOVF9QUk9QU10gfHwge307XG4gICAgICAgIGlmKCFwcm9wc1tNb2RlbEtleXMuTU9ERUxdW2NvbnRyb2xOYW1lXSlcbiAgICAgICAgICBwcm9wc1tNb2RlbEtleXMuTU9ERUxdID0gT2JqZWN0LmFzc2lnbih7fSwgcHJvcHNbTW9kZWxLZXlzLk1PREVMXSwge1tjb250cm9sTmFtZV06IHsuLi5jb21wb25lbnRQcm9wc319KTtcbiAgICB9XG5cbiAgICBmb3IgKGNvbnN0IHBhcnQgb2YgcGFydHMpIHtcbiAgICAgIGlmICghY3VycmVudEdyb3VwLmdldChwYXJ0KSkge1xuICAgICAgICBjb25zdCBwYXJ0Rm9ybUdyb3VwID0gKGlzTXVsdGlwbGUgJiYgcGFydCA9PT0gY2hpbGRPZikgPyBuZXcgRm9ybUFycmF5KFtuZXcgRm9ybUdyb3VwKHt9KV0pIDogbmV3IEZvcm1Hcm91cCh7fSk7XG4gICAgICAgIChwYXJ0Rm9ybUdyb3VwIGFzIEtleVZhbHVlKVtBbmd1bGFyRW5naW5lS2V5cy5GT1JNX0dST1VQX0NPTVBPTkVOVF9QUk9QU10gPSB7XG4gICAgICAgICAgY2hpbGRPZjogY2hpbGRPZiB8fCAnJyxcbiAgICAgICAgICBpc011bHRpcGxlOiBpc011bHRpcGxlLFxuICAgICAgICAgIG5hbWU6IHBhcnQsXG4gICAgICAgICAgcGs6IGNvbXBvbmVudFByb3BzPy5bJ3BrJ10gfHwgcGFyZW50UHJvcHM/LlsncGsnXSB8fCAnJyxcbiAgICAgICAgICBbTW9kZWxLZXlzLk1PREVMXToge30sXG4gICAgICAgIH0gYXMgUGFydGlhbDxGaWVsZFByb3BlcnRpZXM+ICYge21vZGVsOiBLZXlWYWx1ZX07XG5cbiAgICAgICAgaWYoY3VycmVudEdyb3VwIGluc3RhbmNlb2YgRm9ybUFycmF5KSB7XG4gICAgICAgICAgKGN1cnJlbnRHcm91cCBhcyBGb3JtQXJyYXkpLnB1c2gocGFydEZvcm1Hcm91cCk7XG4gICAgICAgIH0gZWxzZSB7XG5cbiAgICAgICAgICBmb3IoY29uc3QgY29udHJvbCBvZiBPYmplY3QudmFsdWVzKHBhcnRGb3JtR3JvdXAuY29udHJvbHMpKSB7XG4gICAgICAgICAgICBpZihjb250cm9sIGluc3RhbmNlb2YgRm9ybUNvbnRyb2wpXG4gICAgICAgICAgICAgIHRoaXMucmVnaXN0ZXIoY29udHJvbCBhcyBBYnN0cmFjdENvbnRyb2wsIGNvbXBvbmVudFByb3BzKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZihwYXJ0Rm9ybUdyb3VwIGluc3RhbmNlb2YgQWJzdHJhY3RDb250cm9sKVxuICAgICAgICAgICAgdGhpcy5yZWdpc3RlcihwYXJ0Rm9ybUdyb3VwIGFzIEFic3RyYWN0Q29udHJvbCwgY29tcG9uZW50UHJvcHMpO1xuXG4gICAgICAgICAgY3VycmVudEdyb3VwLmFkZENvbnRyb2wocGFydCwgcGFydEZvcm1Hcm91cCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmKGNoaWxkT2YgJiYgY3VycmVudEdyb3VwIGluc3RhbmNlb2YgRm9ybUFycmF5KVxuICAgICAgICBzZXRBcnJheUNvbXBvbmVudFByb3BzKGN1cnJlbnRHcm91cCk7XG5cbiAgICAgIGN1cnJlbnRHcm91cCA9IGN1cnJlbnRHcm91cC5nZXQocGFydCkgYXMgRm9ybUdyb3VwO1xuICAgIH1cbiAgICByZXR1cm4gW2N1cnJlbnRHcm91cCwgY29udHJvbE5hbWVdO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBSZXRyaWV2ZXMgY29tcG9uZW50IHByb3BlcnRpZXMgZnJvbSBhIEZvcm1Hcm91cCBvciBGb3JtQXJyYXkuXG4gICAqIEBzdW1tYXJ5IEV4dHJhY3RzIGNvbXBvbmVudCBwcm9wZXJ0aWVzIHN0b3JlZCBpbiB0aGUgZm9ybSBncm91cCBtZXRhZGF0YS4gSWYgYSBGb3JtR3JvdXAgaXMgcHJvdmlkZWRcbiAgICogYW5kIGdyb3VwQXJyYXlOYW1lIGlzIHNwZWNpZmllZCwgaXQgd2lsbCBsb29rIGZvciB0aGUgRm9ybUFycmF5IHdpdGhpbiB0aGUgZm9ybSBzdHJ1Y3R1cmUuXG4gICAqXG4gICAqIEBwYXJhbSB7Rm9ybUdyb3VwIHwgRm9ybUFycmF5fSBmb3JtR3JvdXAgLSBUaGUgZm9ybSBncm91cCBvciBmb3JtIGFycmF5IHRvIGV4dHJhY3QgcHJvcGVydGllcyBmcm9tXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBba2V5XSAtIE9wdGlvbmFsIGtleSB0byByZXRyaWV2ZSBhIHNwZWNpZmljIHByb3BlcnR5XG4gICAqIEBwYXJhbSB7c3RyaW5nfSBbZ3JvdXBBcnJheU5hbWVdIC0gT3B0aW9uYWwgbmFtZSBvZiB0aGUgZ3JvdXAgYXJyYXkgaWYgZm9ybUdyb3VwIGlzIG5vdCBhIEZvcm1BcnJheVxuICAgKiBAcmV0dXJuIHtQYXJ0aWFsPEZpZWxkUHJvcGVydGllcz59IFRoZSBjb21wb25lbnQgcHJvcGVydGllcyBvciBhIHNwZWNpZmljIHByb3BlcnR5IGlmIGtleSBpcyBwcm92aWRlZFxuICAgKlxuICAgKiBAc3RhdGljXG4gICAqIEBtZW1iZXJPZiBOZ3hGb3JtU2VydmljZVxuICAgKi9cbiAgc3RhdGljIGdldENvbXBvbmVudFByb3BzRnJvbUdyb3VwQXJyYXkoZm9ybUdyb3VwOiBGb3JtR3JvdXAgfCBGb3JtQXJyYXksIGtleT86IHN0cmluZywgZ3JvdXBBcnJheU5hbWU/OiBzdHJpbmcgfCB1bmRlZmluZWQpOiBQYXJ0aWFsPEZpZWxkUHJvcGVydGllcz4ge1xuICAgIGlmKCEoZm9ybUdyb3VwIGluc3RhbmNlb2YgRm9ybUFycmF5KSAmJiB0eXBlb2YgZ3JvdXBBcnJheU5hbWUgPT09IFByaW1pdGl2ZXMuU1RSSU5HKVxuICAgICAgZm9ybUdyb3VwID0gZm9ybUdyb3VwLnJvb3QuZ2V0KGdyb3VwQXJyYXlOYW1lIGFzIHN0cmluZykgYXMgRm9ybUFycmF5IHx8IHt9O1xuICAgIGNvbnN0IHByb3BzID0gKGZvcm1Hcm91cCBhcyBLZXlWYWx1ZSk/LltBbmd1bGFyRW5naW5lS2V5cy5GT1JNX0dST1VQX0NPTVBPTkVOVF9QUk9QU10gfHwge307XG4gICAgcmV0dXJuICgha2V5ID8gcHJvcHMgOiBwcm9wcz8uW2tleV0pIHx8IHt9O1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBBZGRzIGEgbmV3IGdyb3VwIHRvIGEgcGFyZW50IEZvcm1BcnJheS5cbiAgICogQHN1bW1hcnkgQ3JlYXRlcyBhbmQgYWRkcyBhIG5ldyBGb3JtR3JvdXAgdG8gdGhlIHNwZWNpZmllZCBwYXJlbnQgRm9ybUFycmF5IGJhc2VkIG9uIHRoZVxuICAgKiBjb21wb25lbnQgcHJvcGVydGllcyBzdG9yZWQgaW4gdGhlIHBhcmVudCdzIG1ldGFkYXRhLiBUaGlzIGlzIHVzZWQgZm9yIGR5bmFtaWMgZm9ybSBhcnJheXNcbiAgICogd2hlcmUgbmV3IGdyb3VwcyBuZWVkIHRvIGJlIGFkZGVkIGF0IHJ1bnRpbWUuXG4gICAqXG4gICAqIEBwYXJhbSB7Rm9ybUdyb3VwfSBmb3JtR3JvdXAgLSBUaGUgcm9vdCBmb3JtIGdyb3VwIGNvbnRhaW5pbmcgdGhlIHBhcmVudCBGb3JtQXJyYXlcbiAgICogQHBhcmFtIHtzdHJpbmd9IHBhcmVudE5hbWUgLSBUaGUgbmFtZSBvZiB0aGUgcGFyZW50IEZvcm1BcnJheSB0byBhZGQgdGhlIGdyb3VwIHRvXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBbaW5kZXg9MV0gLSBUaGUgaW5kZXggcG9zaXRpb24gd2hlcmUgdGhlIG5ldyBncm91cCBzaG91bGQgYmUgYWRkZWRcbiAgICogQHJldHVybiB7Rm9ybUdyb3VwfSBUaGUgbmV3bHkgY3JlYXRlZCBhbmQgYWRkZWQgRm9ybUdyb3VwXG4gICAqXG4gICAqIEBzdGF0aWNcbiAgICogQG1lbWJlck9mIE5neEZvcm1TZXJ2aWNlXG4gICAqL1xuICBzdGF0aWMgYWRkR3JvdXBUb1BhcmVudChmb3JtR3JvdXA6IEZvcm1Hcm91cCwgcGFyZW50TmFtZTogc3RyaW5nLCBpbmRleDogbnVtYmVyID0gMSk6IEZvcm1Hcm91cCB7XG4gICAgY29uc3QgY29tcG9uZW50UHJvcHMgPSB0aGlzLmdldENvbXBvbmVudFByb3BzRnJvbUdyb3VwQXJyYXkoZm9ybUdyb3VwLCBNb2RlbEtleXMuTU9ERUwsIHBhcmVudE5hbWUpO1xuICAgIE9iamVjdC5lbnRyaWVzKGNvbXBvbmVudFByb3BzIGFzIEtleVZhbHVlKS5mb3JFYWNoKChbLCB2YWx1ZV0pID0+IHtcbiAgICAgIHJldHVybiB0aGlzLmFkZEZvcm1Db250cm9sKGZvcm1Hcm91cCwgdmFsdWUsIHttdWx0aXBsZTogdHJ1ZX0sIGluZGV4KTtcbiAgICB9KTtcblxuICAgIHJldHVybiB0aGlzLmdldEdyb3VwRnJvbVBhcmVudChmb3JtR3JvdXAsIHBhcmVudE5hbWUsIGluZGV4KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gUmV0cmlldmVzIGEgRm9ybUdyb3VwIGZyb20gYSBwYXJlbnQgRm9ybUFycmF5IGF0IHRoZSBzcGVjaWZpZWQgaW5kZXguXG4gICAqIEBzdW1tYXJ5IEdldHMgYSBGb3JtR3JvdXAgZnJvbSB0aGUgc3BlY2lmaWVkIHBhcmVudCBGb3JtQXJyYXkuIElmIHRoZSBncm91cCBkb2Vzbid0IGV4aXN0XG4gICAqIGF0IHRoZSBnaXZlbiBpbmRleCwgaXQgd2lsbCBjcmVhdGUgYSBuZXcgb25lIHVzaW5nIGFkZEdyb3VwVG9QYXJlbnQuXG4gICAqXG4gICAqIEBwYXJhbSB7Rm9ybUdyb3VwfSBmb3JtR3JvdXAgLSBUaGUgcm9vdCBmb3JtIGdyb3VwIGNvbnRhaW5pbmcgdGhlIHBhcmVudCBGb3JtQXJyYXlcbiAgICogQHBhcmFtIHtzdHJpbmd9IHBhcmVudE5hbWUgLSBUaGUgbmFtZSBvZiB0aGUgcGFyZW50IEZvcm1BcnJheSB0byByZXRyaWV2ZSB0aGUgZ3JvdXAgZnJvbVxuICAgKiBAcGFyYW0ge251bWJlcn0gW2luZGV4PTFdIC0gVGhlIGluZGV4IG9mIHRoZSBncm91cCB0byByZXRyaWV2ZVxuICAgKiBAcmV0dXJuIHtGb3JtR3JvdXB9IFRoZSBGb3JtR3JvdXAgYXQgdGhlIHNwZWNpZmllZCBpbmRleFxuICAgKlxuICAgKiBAc3RhdGljXG4gICAqIEBtZW1iZXJPZiBOZ3hGb3JtU2VydmljZVxuICAgKi9cbiAgc3RhdGljIGdldEdyb3VwRnJvbVBhcmVudChmb3JtR3JvdXA6IEZvcm1Hcm91cCwgcGFyZW50TmFtZTogc3RyaW5nLCBpbmRleDogbnVtYmVyID0gMSk6IEZvcm1Hcm91cCB7XG4gICAgY29uc3QgY2hpbGRHcm91cCA9ICgoZm9ybUdyb3VwLmdldChwYXJlbnROYW1lKSB8fCBmb3JtR3JvdXApIGFzIEZvcm1BcnJheSkuYXQoaW5kZXgpO1xuICAgIGlmKGNoaWxkR3JvdXAgaW5zdGFuY2VvZiBGb3JtR3JvdXApXG4gICAgICByZXR1cm4gY2hpbGRHcm91cDtcbiAgICByZXR1cm4gdGhpcy5hZGRHcm91cFRvUGFyZW50KGZvcm1Hcm91cCwgcGFyZW50TmFtZSwgaW5kZXgpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBDaGVja3MgaWYgYSB2YWx1ZSBpcyB1bmlxdWUgd2l0aGluIGEgRm9ybUFycmF5IGdyb3VwLlxuICAgKiBAc3VtbWFyeSBWYWxpZGF0ZXMgdGhhdCB0aGUgcHJpbWFyeSBrZXkgdmFsdWUgaW4gYSBGb3JtR3JvdXAgaXMgdW5pcXVlIGFtb25nIGFsbCBncm91cHNcbiAgICogaW4gdGhlIHBhcmVudCBGb3JtQXJyYXkuIFRoZSB1bmlxdWVuZXNzIGNoZWNrIGJlaGF2aW9yIGRpZmZlcnMgYmFzZWQgb24gdGhlIG9wZXJhdGlvbiB0eXBlLlxuICAgKlxuICAgKiBAcGFyYW0ge0Zvcm1Hcm91cH0gZm9ybUdyb3VwIC0gVGhlIEZvcm1Hcm91cCB0byBjaGVjayBmb3IgdW5pcXVlbmVzc1xuICAgKiBAcGFyYW0ge251bWJlcn0gaW5kZXggLSBUaGUgaW5kZXggb2YgdGhlIGN1cnJlbnQgZ3JvdXAgd2l0aGluIHRoZSBGb3JtQXJyYXlcbiAgICogQHBhcmFtIHtPcGVyYXRpb25LZXlzfSBbb3BlcmF0aW9uPU9wZXJhdGlvbktleXMuQ1JFQVRFXSAtIFRoZSB0eXBlIG9mIG9wZXJhdGlvbiBiZWluZyBwZXJmb3JtZWRcbiAgICogQHJldHVybiB7Ym9vbGVhbn0gVHJ1ZSBpZiB0aGUgdmFsdWUgaXMgdW5pcXVlLCBmYWxzZSBvdGhlcndpc2VcbiAgICpcbiAgICogQHN0YXRpY1xuICAgKiBAbWVtYmVyT2YgTmd4Rm9ybVNlcnZpY2VcbiAgICovXG4gIHN0YXRpYyBpc1VuaXF1ZU9uR3JvdXAoZm9ybUdyb3VwOiBGb3JtR3JvdXAsIGluZGV4OiBudW1iZXIsIG9wZXJhdGlvbjogT3BlcmF0aW9uS2V5cyA9IE9wZXJhdGlvbktleXMuQ1JFQVRFKTogYm9vbGVhbiB7XG4gICAgY29uc3QgZm9ybUdyb3VwQXJyYXkgPSBmb3JtR3JvdXAucGFyZW50IGFzIEZvcm1BcnJheTtcbiAgICBjb25zdCBwayA9IHRoaXMuZ2V0Q29tcG9uZW50UHJvcHNGcm9tR3JvdXBBcnJheShmb3JtR3JvdXBBcnJheSwgQmFzZUNvbXBvbmVudFByb3BzLlBLIGFzIHN0cmluZykgYXMgc3RyaW5nO1xuICAgIGNvbnN0IGNvbnRyb2xOYW1lID0gT2JqZWN0LmtleXMoZm9ybUdyb3VwLmNvbnRyb2xzKVswXTtcblxuICAgIC8vIG9ubHkgY2hlY2sgZm9yIHVuaXF1ZSBpZiBpcyB0aGUgcGsgY29udHJvbFxuICAgIGlmKGNvbnRyb2xOYW1lICE9PSBwaylcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIGNvbnN0IGNvbnRyb2xWYWx1ZSA9IGNsZWFuU3BhY2VzKGAke2Zvcm1Hcm91cC5nZXQocGspPy52YWx1ZX1gLCB0cnVlKTtcbiAgICBpZihvcGVyYXRpb24gPT09IE9wZXJhdGlvbktleXMuQ1JFQVRFKVxuICAgICAgcmV0dXJuICFmb3JtR3JvdXBBcnJheS5jb250cm9scy5zb21lKChncm91cCwgaSkgPT4gaSAhPT0gaW5kZXggJiYgY2xlYW5TcGFjZXMoYCR7Z3JvdXAuZ2V0KHBrKT8udmFsdWV9YCwgdHJ1ZSkgPT09IGNvbnRyb2xWYWx1ZSk7XG5cbiAgICByZXR1cm4gIWZvcm1Hcm91cEFycmF5LmNvbnRyb2xzLnNvbWUoKGdyb3VwLCBpKSA9PiB7XG4gICAgICBjb25zdCB2YWx1ZSA9IGNsZWFuU3BhY2VzKGAke2dyb3VwLmdldChwayk/LnZhbHVlfWAsIHRydWUpO1xuICAgICAgcmV0dXJuIGkgIT09IGluZGV4ICYmIGNvbnRyb2xWYWx1ZSA9PT0gdmFsdWU7XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIEVuYWJsZXMgYWxsIGNvbnRyb2xzIHdpdGhpbiBhIEZvcm1Hcm91cCBvciBGb3JtQXJyYXkuXG4gICAqIEBzdW1tYXJ5IFJlY3Vyc2l2ZWx5IGVuYWJsZXMgYWxsIGZvcm0gY29udHJvbHMgd2l0aGluIHRoZSBwcm92aWRlZCBGb3JtR3JvdXAgb3IgRm9ybUFycmF5LlxuICAgKiBUaGlzIGlzIHVzZWZ1bCBmb3IgbWFraW5nIGFsbCBjb250cm9scyBpbnRlcmFjdGl2ZSBhZnRlciB0aGV5IGhhdmUgYmVlbiBkaXNhYmxlZC5cbiAgICpcbiAgICogQHBhcmFtIHtGb3JtQXJyYXkgfCBGb3JtR3JvdXB9IGZvcm1Hcm91cCAtIFRoZSBGb3JtR3JvdXAgb3IgRm9ybUFycmF5IHRvIGVuYWJsZSBhbGwgY29udHJvbHMgZm9yXG4gICAqIEByZXR1cm4ge3ZvaWR9XG4gICAqXG4gICAqIEBzdGF0aWNcbiAgICogQG1lbWJlck9mIE5neEZvcm1TZXJ2aWNlXG4gICAqL1xuICBzdGF0aWMgZW5hYmxlQWxsR3JvdXBDb250cm9scyhmb3JtR3JvdXA6IEZvcm1BcnJheSB8IEZvcm1Hcm91cCk6IHZvaWQge1xuICAgIE9iamVjdC5rZXlzKGZvcm1Hcm91cC5jb250cm9scykuZm9yRWFjaChrZXkgPT4ge1xuICAgICAgY29uc3QgY29udHJvbCA9IGZvcm1Hcm91cC5nZXQoa2V5KTtcbiAgICAgIGlmIChjb250cm9sIGluc3RhbmNlb2YgRm9ybUFycmF5KSB7XG4gICAgICAgIGNvbnRyb2wuY29udHJvbHMuZm9yRWFjaChjaGlsZCA9PiB7XG4gICAgICAgICAgaWYgKGNoaWxkIGluc3RhbmNlb2YgRm9ybUdyb3VwKSB7XG4gICAgICAgICAgICBjaGlsZC5lbmFibGUoeyBlbWl0RXZlbnQ6IGZhbHNlIH0pO1xuICAgICAgICAgICAgY2hpbGQudXBkYXRlVmFsdWVBbmRWYWxpZGl0eSh7IGVtaXRFdmVudDogdHJ1ZSB9KTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBBZGRzIGEgZm9ybSBjb250cm9sIHRvIGEgZm9ybSBncm91cCBiYXNlZCBvbiBjb21wb25lbnQgcHJvcGVydGllcy5cbiAgICogQHN1bW1hcnkgQ3JlYXRlcyBhbmQgY29uZmlndXJlcyBhIEZvcm1Db250cm9sIHdpdGhpbiB0aGUgc3BlY2lmaWVkIEZvcm1Hcm91cCB1c2luZyB0aGUgcHJvdmlkZWRcbiAgICogY29tcG9uZW50IHByb3BlcnRpZXMuIEhhbmRsZXMgbmVzdGVkIHBhdGhzLCBtdWx0aXBsZSBjb250cm9scyAoRm9ybUFycmF5cyksIGFuZCBjb250cm9sIHJlZ2lzdHJhdGlvbi5cbiAgICogVGhpcyBtZXRob2Qgc3VwcG9ydHMgY29tcGxleCBmb3JtIHN0cnVjdHVyZXMgd2l0aCBuZXN0ZWQgZ3JvdXBzIGFuZCBhcnJheXMuXG4gICAqXG4gICAqIEBwYXJhbSB7Rm9ybUdyb3VwfSBmb3JtR3JvdXAgLSBUaGUgZm9ybSBncm91cCB0byBhZGQgdGhlIGNvbnRyb2wgdG9cbiAgICogQHBhcmFtIHtJQ29tcG9uZW50SW5wdXR9IGNvbXBvbmVudFByb3BzIC0gVGhlIGNvbXBvbmVudCBwcm9wZXJ0aWVzIGRlZmluaW5nIHRoZSBjb250cm9sIGNvbmZpZ3VyYXRpb25cbiAgICogQHBhcmFtIHtLZXlWYWx1ZX0gW3BhcmVudFByb3BzPXt9XSAtIFByb3BlcnRpZXMgZnJvbSB0aGUgcGFyZW50IGNvbXBvbmVudCBmb3IgY29udGV4dFxuICAgKiBAcGFyYW0ge251bWJlcn0gW2luZGV4PTBdIC0gVGhlIGluZGV4IGZvciBtdWx0aXBsZSBjb250cm9scyBpbiBGb3JtQXJyYXlzXG4gICAqIEByZXR1cm4ge3ZvaWR9XG4gICAqXG4gICAqIEBwcml2YXRlXG4gICAqIEBzdGF0aWNcbiAgICogQG1lbWJlck9mIE5neEZvcm1TZXJ2aWNlXG4gICAqL1xuICBwcml2YXRlIHN0YXRpYyBhZGRGb3JtQ29udHJvbChmb3JtR3JvdXA6IEZvcm1QYXJlbnQsIGNvbXBvbmVudFByb3BzOiBJQ29tcG9uZW50SW5wdXQsIHBhcmVudFByb3BzOiBLZXlWYWx1ZSA9IHt9LCBpbmRleDogbnVtYmVyID0gMCk6IHZvaWQge1xuXG4gICAgY29uc3QgaXNNdWx0aXBsZSA9IHBhcmVudFByb3BzPy5bJ211bHRpcGxlJ10gfHwgcGFyZW50UHJvcHM/LlsndHlwZSddID09PSAnQXJyYXknIHx8IGZhbHNlO1xuICAgIGNvbnN0IHsgbmFtZSwgY2hpbGRPZiwgfSA9IGNvbXBvbmVudFByb3BzO1xuICAgIGlmKGlzTXVsdGlwbGUpXG4gICAgICBjb21wb25lbnRQcm9wc1sncGsnXSA9IGNvbXBvbmVudFByb3BzWydwayddIHx8IHBhcmVudFByb3BzPy5bJ3BrJ10gfHwgJyc7XG4gICAgY29uc3QgZnVsbFBhdGggPSBjaGlsZE9mID8gaXNNdWx0aXBsZSA/IGAke2NoaWxkT2Z9LiR7aW5kZXh9LiR7bmFtZX1gIDogYCR7Y2hpbGRPZn0uJHtuYW1lfWAgOiBuYW1lO1xuICAgIGNvbnN0IFtwYXJlbnRHcm91cCwgY29udHJvbE5hbWVdID0gdGhpcy5yZXNvbHZlUGFyZW50R3JvdXAoZm9ybUdyb3VwIGFzIEZvcm1Hcm91cCwgZnVsbFBhdGgsIGNvbXBvbmVudFByb3BzLCBwYXJlbnRQcm9wcyk7XG5cbiAgICBpZiAoIXBhcmVudEdyb3VwLmdldChjb250cm9sTmFtZSkpIHtcbiAgICAgIGNvbnN0IGNvbnRyb2wgPSBOZ3hGb3JtU2VydmljZS5mcm9tUHJvcHMoXG4gICAgICAgIGNvbXBvbmVudFByb3BzLFxuICAgICAgICBjb21wb25lbnRQcm9wcy51cGRhdGVNb2RlIHx8ICdjaGFuZ2UnLFxuICAgICAgKTtcbiAgICAgIE5neEZvcm1TZXJ2aWNlLnJlZ2lzdGVyKGNvbnRyb2wsIGNvbXBvbmVudFByb3BzKTtcbiAgICAgIGlmIChwYXJlbnRHcm91cCBpbnN0YW5jZW9mIEZvcm1Hcm91cCkge1xuICAgICAgICBwYXJlbnRHcm91cC5hZGRDb250cm9sKGNvbnRyb2xOYW1lLCBjb250cm9sKTtcbiAgICAgIH1cbiAgICAgIGlmKHBhcmVudEdyb3VwIGluc3RhbmNlb2YgRm9ybUFycmF5KSB7XG4gICAgICAgIGNvbnN0IHJvb3QgPSBwYXJlbnRHcm91cC5jb250cm9sc1soY29tcG9uZW50UHJvcHMgYXMgS2V5VmFsdWUpPy5bJ3BhZ2UnXSAtIDFdIGFzIEZvcm1Hcm91cDtcbiAgICAgICAgaWYocm9vdCkge1xuICAgICAgICAgICByb290LmFkZENvbnRyb2woY29udHJvbE5hbWUsIGNvbnRyb2wpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHBhcmVudEdyb3VwLnB1c2goe1tjb250cm9sTmFtZV06IGNvbnRyb2x9KTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICBjb25zdCByb290ID0gcGFyZW50R3JvdXAgaW5zdGFuY2VvZiBGb3JtQXJyYXkgPyBwYXJlbnRHcm91cC5jb250cm9sc1soY29tcG9uZW50UHJvcHMgYXMgS2V5VmFsdWUpPy5bJ3BhZ2UnXSAtIDFdIDogcGFyZW50R3JvdXA7XG4gICAgY29tcG9uZW50UHJvcHNbJ2Zvcm1Hcm91cCddID0gcm9vdCBhcyBGb3JtR3JvdXA7XG4gICAgY29tcG9uZW50UHJvcHNbJ2Zvcm1Db250cm9sJ10gPSBwYXJlbnRHcm91cC5nZXQoY29udHJvbE5hbWUpIGFzIEZvcm1Db250cm9sO1xuICAgIGNvbXBvbmVudFByb3BzWydtdWx0aXBsZSddID0gaXNNdWx0aXBsZVxuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBSZXRyaWV2ZXMgYSBjb250cm9sIGZyb20gYSByZWdpc3RlcmVkIGZvcm0uXG4gICAqIEBzdW1tYXJ5IEZpbmRzIGFuZCByZXR1cm5zIGFuIEFic3RyYWN0Q29udHJvbCBmcm9tIGEgcmVnaXN0ZXJlZCBmb3JtIHVzaW5nIHRoZSBmb3JtIGlkIGFuZCBvcHRpb25hbCBwYXRoLlxuICAgKiBUaGlzIG1ldGhvZCBwcm92aWRlcyBjZW50cmFsaXplZCBhY2Nlc3MgdG8gZm9ybSBjb250cm9scyBhY3Jvc3MgdGhlIGFwcGxpY2F0aW9uIGJ5IGxldmVyYWdpbmdcbiAgICogdGhlIGZvcm0gcmVnaXN0cnkgc3lzdGVtLlxuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gZm9ybUlkIC0gVGhlIHVuaXF1ZSBpZGVudGlmaWVyIG9mIHRoZSBmb3JtIGluIHRoZSByZWdpc3RyeVxuICAgKiBAcGFyYW0ge3N0cmluZ30gW3BhdGhdIC0gVGhlIG9wdGlvbmFsIGRvdC1zZXBhcmF0ZWQgcGF0aCB0byBhIHNwZWNpZmljIGNvbnRyb2wgd2l0aGluIHRoZSBmb3JtXG4gICAqIEByZXR1cm4ge0Fic3RyYWN0Q29udHJvbH0gVGhlIHJlcXVlc3RlZCBBYnN0cmFjdENvbnRyb2wgKEZvcm1Hcm91cCwgRm9ybUFycmF5LCBvciBGb3JtQ29udHJvbClcbiAgICogQHRocm93cyB7RXJyb3J9IElmIHRoZSBmb3JtIGlzIG5vdCBmb3VuZCBpbiB0aGUgcmVnaXN0cnkgb3IgdGhlIGNvbnRyb2wgaXMgbm90IGZvdW5kIGluIHRoZSBmb3JtXG4gICAqXG4gICAqIEBtZXJtYWlkXG4gICAqIHNlcXVlbmNlRGlhZ3JhbVxuICAgKiAgIHBhcnRpY2lwYW50IEMgYXMgQ29tcG9uZW50XG4gICAqICAgcGFydGljaXBhbnQgTkZTIGFzIE5neEZvcm1TZXJ2aWNlXG4gICAqICAgcGFydGljaXBhbnQgRlIgYXMgRm9ybSBSZWdpc3RyeVxuICAgKlxuICAgKiAgIEMtPj5ORlM6IGdldENvbnRyb2xGcm9tRm9ybShmb3JtSWQsIHBhdGg/KVxuICAgKiAgIE5GUy0+PkZSOiBHZXQgZm9ybSBieSBmb3JtSWRcbiAgICogICBhbHQgRm9ybSBub3QgZm91bmRcbiAgICogICAgIEZSLS0+Pk5GUzogbnVsbFxuICAgKiAgICAgTkZTLS0+PkM6IFRocm93IEVycm9yXG4gICAqICAgZWxzZSBGb3JtIGZvdW5kXG4gICAqICAgICBGUi0tPj5ORlM6IFJldHVybiBmb3JtXG4gICAqICAgICBhbHQgcGF0aCBwcm92aWRlZFxuICAgKiAgICAgICBORlMtPj5ORlM6IGZvcm0uZ2V0KHBhdGgpXG4gICAqICAgICAgIGFsdCBDb250cm9sIG5vdCBmb3VuZFxuICAgKiAgICAgICAgIE5GUy0tPj5DOiBUaHJvdyBFcnJvclxuICAgKiAgICAgICBlbHNlXG4gICAqICAgICAgICAgTkZTLS0+PkM6IFJldHVybiBjb250cm9sXG4gICAqICAgICAgIGVuZFxuICAgKiAgICAgZWxzZVxuICAgKiAgICAgICBORlMtLT4+QzogUmV0dXJuIGZvcm1cbiAgICogICAgIGVuZFxuICAgKiAgIGVuZFxuICAgKlxuICAgKiBAc3RhdGljXG4gICAqIEBtZW1iZXJPZiBOZ3hGb3JtU2VydmljZVxuICAgKi9cbiAgc3RhdGljIGdldENvbnRyb2xGcm9tRm9ybShmb3JtSWQ6IHN0cmluZywgcGF0aD86IHN0cmluZyk6IEFic3RyYWN0Q29udHJvbCB7XG4gICAgY29uc3QgZm9ybSA9IHRoaXMuZm9ybVJlZ2lzdHJ5LmdldChmb3JtSWQpO1xuICAgIGlmICghZm9ybSlcbiAgICAgIHRocm93IG5ldyBFcnJvcihgRm9ybSB3aXRoIGlkICcke2Zvcm1JZH0nIG5vdCBmb3VuZCBpbiB0aGUgcmVnaXN0cnkuYCk7XG5cbiAgICBpZiAoIXBhdGgpXG4gICAgICByZXR1cm4gZm9ybTtcblxuICAgIGNvbnN0IGNvbnRyb2wgPSBmb3JtLmdldChwYXRoKTtcbiAgICBpZiAoIWNvbnRyb2wpXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYENvbnRyb2wgd2l0aCBwYXRoICcke3BhdGh9JyBub3QgZm91bmQgaW4gZm9ybSAnJHtmb3JtSWR9Jy5gKTtcbiAgICByZXR1cm4gY29udHJvbDtcbiAgfVxuXG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBDcmVhdGVzIGEgZm9ybSBmcm9tIFVJIG1vZGVsIG1ldGFkYXRhIGNoaWxkcmVuLlxuICAgKiBAc3VtbWFyeSBHZW5lcmF0ZXMgYSBGb3JtR3JvdXAgZnJvbSBhbiBhcnJheSBvZiBVSU1vZGVsTWV0YWRhdGEgb2JqZWN0cywgZXh0cmFjdGluZyBjb21wb25lbnRcbiAgICogcHJvcGVydGllcyBhbmQgY3JlYXRpbmcgYXBwcm9wcmlhdGUgZm9ybSBjb250cm9scy4gVGhpcyBtZXRob2QgaXMgc3BlY2lmaWNhbGx5IGRlc2lnbmVkIHRvIHdvcmtcbiAgICogd2l0aCB0aGUgVUkgZGVjb3JhdG9yIHN5c3RlbSBhbmQgcHJvdmlkZXMgYXV0b21hdGljIGZvcm0gZ2VuZXJhdGlvbiBmcm9tIG1ldGFkYXRhLlxuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gaWQgLSBVbmlxdWUgaWRlbnRpZmllciBmb3IgdGhlIGZvcm1cbiAgICogQHBhcmFtIHtib29sZWFufSBbcmVnaXN0cnk9ZmFsc2VdIC0gV2hldGhlciB0byByZWdpc3RlciB0aGUgY3JlYXRlZCBmb3JtIGluIHRoZSBnbG9iYWwgcmVnaXN0cnlcbiAgICogQHBhcmFtIHtVSU1vZGVsTWV0YWRhdGFbXX0gW2NoaWxkcmVuXSAtIEFycmF5IG9mIFVJIG1vZGVsIG1ldGFkYXRhIG9iamVjdHMgdG8gY3JlYXRlIGNvbnRyb2xzIGZyb21cbiAgICogQHJldHVybiB7Rm9ybUdyb3VwfSBUaGUgY3JlYXRlZCBGb3JtR3JvdXAgd2l0aCBjb250cm9scyBmb3IgZWFjaCBjaGlsZCBtZXRhZGF0YVxuICAgKlxuICAgKiBAbWVybWFpZFxuICAgKiBzZXF1ZW5jZURpYWdyYW1cbiAgICogICBwYXJ0aWNpcGFudCBDIGFzIENvbXBvbmVudFxuICAgKiAgIHBhcnRpY2lwYW50IE5GUyBhcyBOZ3hGb3JtU2VydmljZVxuICAgKiAgIHBhcnRpY2lwYW50IEFGIGFzIEFuZ3VsYXIgRm9ybXNcbiAgICpcbiAgICogICBDLT4+TkZTOiBjcmVhdGVGb3JtRnJvbUNoaWxkcmVuKGlkLCByZWdpc3RyeSwgY2hpbGRyZW4pXG4gICAqICAgTkZTLT4+QUY6IG5ldyBGb3JtR3JvdXAoe30pXG4gICAqICAgbG9vcCBGb3IgZWFjaCBjaGlsZCBtZXRhZGF0YVxuICAgKiAgICAgTkZTLT4+TkZTOiBhZGRGb3JtQ29udHJvbChmb3JtLCBjaGlsZC5wcm9wcylcbiAgICogICAgIE5GUy0+PkFGOiBDcmVhdGUgYW5kIGFkZCBGb3JtQ29udHJvbFxuICAgKiAgIGVuZFxuICAgKiAgIGFsdCByZWdpc3RyeSBpcyB0cnVlXG4gICAqICAgICBORlMtPj5ORlM6IGFkZFJlZ2lzdHJ5KGlkLCBmb3JtKVxuICAgKiAgIGVuZFxuICAgKiAgIE5GUy0tPj5DOiBSZXR1cm4gRm9ybUdyb3VwXG4gICAqXG4gICAqIEBzdGF0aWNcbiAgICogQG1lbWJlck9mIE5neEZvcm1TZXJ2aWNlXG4gICAqL1xuICBzdGF0aWMgY3JlYXRlRm9ybUZyb21DaGlsZHJlbihpZDogc3RyaW5nLCByZWdpc3RyeTogYm9vbGVhbiA9IGZhbHNlLCAgY2hpbGRyZW4/OiBVSU1vZGVsTWV0YWRhdGFbXSwpOiBGb3JtR3JvdXAge1xuICAgIGNvbnN0IGZvcm0gPSBuZXcgRm9ybUdyb3VwKHt9KTtcbiAgICBpZihjaGlsZHJlbj8ubGVuZ3RoKVxuICAgICAgY2hpbGRyZW4uZm9yRWFjaChjaGlsZCA9PiB7XG4gICAgICAgIHRoaXMuYWRkRm9ybUNvbnRyb2woZm9ybSwgY2hpbGQucHJvcHMgYXMgSUNvbXBvbmVudElucHV0KTtcbiAgICAgIH0pO1xuICAgIGlmIChyZWdpc3RyeSlcbiAgICAgIHRoaXMuYWRkUmVnaXN0cnkoaWQsIGZvcm0pO1xuICAgIHJldHVybiBmb3JtO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBDcmVhdGVzIGEgZm9ybSBmcm9tIGNvbXBvbmVudCBjb25maWd1cmF0aW9ucy5cbiAgICogQHN1bW1hcnkgR2VuZXJhdGVzIGEgRm9ybUdyb3VwIGJhc2VkIG9uIGFuIGFycmF5IG9mIGNvbXBvbmVudCBjb25maWd1cmF0aW9ucyBhbmQgb3B0aW9uYWxseSByZWdpc3RlcnMgaXQuXG4gICAqIFRoaXMgbWV0aG9kIHByb2Nlc3NlcyBjb21wb25lbnQgaW5wdXQgY29uZmlndXJhdGlvbnMgdG8gY3JlYXRlIGFwcHJvcHJpYXRlIGZvcm0gY29udHJvbHMgd2l0aFxuICAgKiB2YWxpZGF0aW9uIGFuZCBpbml0aWFsIHZhbHVlcy5cbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmd9IGlkIC0gVGhlIHVuaXF1ZSBpZGVudGlmaWVyIGZvciB0aGUgZm9ybVxuICAgKiBAcGFyYW0ge0lDb21wb25lbnRDb25maWdbXX0gY29tcG9uZW50cyAtIEFuIGFycmF5IG9mIGNvbXBvbmVudCBjb25maWd1cmF0aW9ucyBkZWZpbmluZyB0aGUgZm9ybSBzdHJ1Y3R1cmVcbiAgICogQHBhcmFtIHtib29sZWFufSBbcmVnaXN0cnk9ZmFsc2VdIC0gV2hldGhlciB0byByZWdpc3RlciB0aGUgY3JlYXRlZCBmb3JtIGluIHRoZSBnbG9iYWwgcmVnaXN0cnlcbiAgICogQHJldHVybiB7Rm9ybUdyb3VwfSBUaGUgY3JlYXRlZCBGb3JtR3JvdXAgd2l0aCBjb250cm9scyBmb3IgZWFjaCBjb21wb25lbnQgY29uZmlndXJhdGlvblxuICAgKlxuICAgKiBAbWVybWFpZFxuICAgKiBzZXF1ZW5jZURpYWdyYW1cbiAgICogICBwYXJ0aWNpcGFudCBDIGFzIENvbXBvbmVudFxuICAgKiAgIHBhcnRpY2lwYW50IE5GUyBhcyBOZ3hGb3JtU2VydmljZVxuICAgKiAgIHBhcnRpY2lwYW50IEFGIGFzIEFuZ3VsYXIgRm9ybXNcbiAgICpcbiAgICogICBDLT4+TkZTOiBjcmVhdGVGb3JtRnJvbUNvbXBvbmVudHMoaWQsIGNvbXBvbmVudHMsIHJlZ2lzdHJ5KVxuICAgKiAgIE5GUy0+PkFGOiBuZXcgRm9ybUdyb3VwKHt9KVxuICAgKiAgIGxvb3AgRm9yIGVhY2ggY29tcG9uZW50IGNvbmZpZ1xuICAgKiAgICAgTkZTLT4+TkZTOiBhZGRGb3JtQ29udHJvbChmb3JtLCBjb21wb25lbnQuaW5wdXRzKVxuICAgKiAgICAgTkZTLT4+QUY6IENyZWF0ZSBhbmQgYWRkIEZvcm1Db250cm9sXG4gICAqICAgZW5kXG4gICAqICAgYWx0IHJlZ2lzdHJ5IGlzIHRydWVcbiAgICogICAgIE5GUy0+Pk5GUzogYWRkUmVnaXN0cnkoaWQsIGZvcm0pXG4gICAqICAgZW5kXG4gICAqICAgTkZTLS0+PkM6IFJldHVybiBGb3JtR3JvdXBcbiAgICpcbiAgICogQHN0YXRpY1xuICAgKiBAbWVtYmVyT2YgTmd4Rm9ybVNlcnZpY2VcbiAgICovXG4gIHN0YXRpYyBjcmVhdGVGb3JtRnJvbUNvbXBvbmVudHMoaWQ6IHN0cmluZywgY29tcG9uZW50czogSUNvbXBvbmVudENvbmZpZ1tdLCByZWdpc3RyeTogYm9vbGVhbiA9IGZhbHNlKTogRm9ybUdyb3VwIHtcbiAgICBjb25zdCBmb3JtID0gbmV3IEZvcm1Hcm91cCh7fSk7XG4gICAgY29tcG9uZW50cy5mb3JFYWNoKGNvbXBvbmVudCA9PiB7XG4gICAgICB0aGlzLmFkZEZvcm1Db250cm9sKGZvcm0sIGNvbXBvbmVudC5pbnB1dHMpO1xuICAgIH0pO1xuXG4gICAgaWYgKHJlZ2lzdHJ5KVxuICAgICAgdGhpcy5hZGRSZWdpc3RyeShpZCwgZm9ybSk7XG5cbiAgICByZXR1cm4gZm9ybTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gQWRkcyBhIGNvbnRyb2wgdG8gYSBmb3JtIGJhc2VkIG9uIGNvbXBvbmVudCBwcm9wZXJ0aWVzLlxuICAgKiBAc3VtbWFyeSBDcmVhdGVzIGFuZCBhZGRzIGEgZm9ybSBjb250cm9sIHRvIGEgZm9ybSAoZXhpc3Rpbmcgb3IgbmV3KSBiYXNlZCBvbiB0aGUgcHJvdmlkZWQgY29tcG9uZW50IHByb3BlcnRpZXMuXG4gICAqIEhhbmRsZXMgbXVsdGktcGFnZSBmb3JtcyBieSBtYW5hZ2luZyBGb3JtQXJyYXkgc3RydWN0dXJlcyBhbmQgcHJvcGVyIGluZGV4aW5nLiBUaGlzIG1ldGhvZCBzdXBwb3J0c1xuICAgKiBjb21wbGV4IGZvcm0gc2NlbmFyaW9zIGluY2x1ZGluZyBuZXN0ZWQgY29udHJvbHMgYW5kIHBhZ2UtYmFzZWQgZm9ybSBvcmdhbml6YXRpb24uXG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBpZCAtIFRoZSB1bmlxdWUgaWRlbnRpZmllciBvZiB0aGUgZm9ybVxuICAgKiBAcGFyYW0ge0ZpZWxkUHJvcGVydGllc30gY29tcG9uZW50UHJvcGVydGllcyAtIFRoZSBwcm9wZXJ0aWVzIG9mIHRoZSBjb21wb25lbnQgdG8gY3JlYXRlIHRoZSBjb250cm9sIGZyb21cbiAgICogQHBhcmFtIHtGaWVsZFByb3BlcnRpZXN9IFtwYXJlbnRQcm9wc10gLSBPcHRpb25hbCBwYXJlbnQgcHJvcGVydGllcyBmb3IgY29udGV4dCBhbmQgY29uZmlndXJhdGlvblxuICAgKiBAcmV0dXJuIHtBYnN0cmFjdENvbnRyb2x9IFRoZSBmb3JtIG9yIGNyZWF0ZWQgY29udHJvbFxuICAgKlxuICAgKiBAbWVybWFpZFxuICAgKiBzZXF1ZW5jZURpYWdyYW1cbiAgICogICBwYXJ0aWNpcGFudCBDIGFzIENvbXBvbmVudFxuICAgKiAgIHBhcnRpY2lwYW50IE5GUyBhcyBOZ3hGb3JtU2VydmljZVxuICAgKiAgIHBhcnRpY2lwYW50IEYgYXMgRm9ybVxuICAgKlxuICAgKiAgIEMtPj5ORlM6IGFkZENvbnRyb2xGcm9tUHJvcHMoaWQsIGNvbXBvbmVudFByb3BzLCBwYXJlbnRQcm9wcz8pXG4gICAqICAgTkZTLT4+TkZTOiBjcmVhdGVGb3JtKGlkLCBwYXJlbnRQcm9wcywgdHJ1ZSlcbiAgICogICBhbHQgTXVsdGktcGFnZSBmb3JtIChwYXJlbnRQcm9wcy5wYWdlcyA+IDEpXG4gICAqICAgICBORlMtPj5ORlM6IENhbGN1bGF0ZSBwYWdlIGluZGV4XG4gICAqICAgICBORlMtPj5GOiBHZXQgb3IgY3JlYXRlIEZvcm1Hcm91cCBhdCBpbmRleFxuICAgKiAgICAgTkZTLT4+TkZTOiBTZXQgZm9ybSB0byBwYWdlIEZvcm1Hcm91cFxuICAgKiAgIGVuZFxuICAgKiAgIGFsdCBjb21wb25lbnRQcm9wZXJ0aWVzIGhhcyBwYXRoXG4gICAqICAgICBORlMtPj5ORlM6IGFkZEZvcm1Db250cm9sKGZvcm0sIGNvbXBvbmVudFByb3BlcnRpZXMsIHBhcmVudFByb3BzKVxuICAgKiAgIGVuZFxuICAgKiAgIE5GUy0tPj5DOiBSZXR1cm4gZm9ybS9jb250cm9sXG4gICAqXG4gICAqIEBzdGF0aWNcbiAgICogQG1lbWJlck9mIE5neEZvcm1TZXJ2aWNlXG4gICAqL1xuICBzdGF0aWMgYWRkQ29udHJvbEZyb21Qcm9wcyhpZDogc3RyaW5nLCBjb21wb25lbnRQcm9wZXJ0aWVzOiBGaWVsZFByb3BlcnRpZXMsIHBhcmVudFByb3BzPzogRmllbGRQcm9wZXJ0aWVzKTogQWJzdHJhY3RDb250cm9sIHtcbiAgICBsZXQgZm9ybSA9IHRoaXMuY3JlYXRlRm9ybShpZCwgcGFyZW50UHJvcHMsIHRydWUpO1xuICAgIGNvbnN0IGZvcm1MZW5ndGggPSAoZm9ybSBhcyBGb3JtQXJyYXkpLmxlbmd0aDtcbiAgICBpZihwYXJlbnRQcm9wcz8ucGFnZXMgJiYgcGFyZW50UHJvcHM/LnBhZ2VzID4gMSkge1xuICAgICAgbGV0IGluZGV4ID0gY29tcG9uZW50UHJvcGVydGllcy5wYWdlIHx8IHBhcmVudFByb3BzLnBhZ2U7XG4gICAgICBpZighKHR5cGVvZiBpbmRleCA9PT0gJ251bWJlcicpIHx8IGluZGV4ID09PSAwKVxuICAgICAgICB0aHJvdyBFcnJvcihgUHJvcGVydHkgJ3BhZ2UnIGlzIHJlcXVpcmVkIGFuZCBncmVhdGhlciB0aGFuIDAgb24gJHtjb21wb25lbnRQcm9wZXJ0aWVzLm5hbWV9YCk7XG5cbiAgICAgIGlmKGluZGV4ID4gZm9ybUxlbmd0aCkge1xuICAgICAgICBpZigoZm9ybSBhcyBLZXlWYWx1ZSk/LlsnbGFzdEluZGV4J10gJiYgaW5kZXggPT09IChmb3JtIGFzIEtleVZhbHVlKVsnbGFzdEluZGV4J11bJ3BhZ2UnXSkge1xuICAgICAgICAgIGluZGV4ID0gKGZvcm0gYXMgS2V5VmFsdWUpWydsYXN0SW5kZXgnXVsnaW5kZXgnXTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAoZm9ybSBhcyBLZXlWYWx1ZSlbJ2xhc3RJbmRleCddID0ge1xuICAgICAgICAgICAgcGFnZTogaW5kZXgsXG4gICAgICAgICAgICBpbmRleDogZm9ybUxlbmd0aCArIDFcbiAgICAgICAgICB9O1xuICAgICAgICAgIGluZGV4ID0gZm9ybUxlbmd0aCArIDE7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgbGV0IGdyb3VwID0gKGZvcm0gYXMgRm9ybUFycmF5KS5jb250cm9sc1soaW5kZXggYXMgbnVtYmVyKSAtIDFdO1xuICAgICAgaWYoIWdyb3VwKSB7XG4gICAgICAgIGdyb3VwID0gbmV3IEZvcm1Hcm91cCh7fSk7XG4gICAgICAgIChmb3JtIGFzIEZvcm1BcnJheSkuaW5zZXJ0KGluZGV4IGFzIG51bWJlciwgZ3JvdXApO1xuICAgICAgfVxuICAgICAgZm9ybSA9IGdyb3VwIGFzIEZvcm1Hcm91cDtcbiAgICB9XG4gICAgaWYoY29tcG9uZW50UHJvcGVydGllcy5wYXRoKVxuICAgICAgdGhpcy5hZGRGb3JtQ29udHJvbChmb3JtLCBjb21wb25lbnRQcm9wZXJ0aWVzLCBwYXJlbnRQcm9wcyk7XG4gICAgcmV0dXJuIGZvcm07XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFJldHJpZXZlcyBmb3JtIGRhdGEgZnJvbSBhIEZvcm1Hcm91cC5cbiAgICogQHN1bW1hcnkgRXh0cmFjdHMgYW5kIHByb2Nlc3NlcyB0aGUgZGF0YSBmcm9tIGEgRm9ybUdyb3VwLCBoYW5kbGluZyBkaWZmZXJlbnQgaW5wdXQgdHlwZXMgYW5kIG5lc3RlZCBmb3JtIGdyb3Vwcy5cbiAgICogUGVyZm9ybXMgdHlwZSBjb252ZXJzaW9uIGZvciB2YXJpb3VzIEhUTUw1IGlucHV0IHR5cGVzLCB2YWxpZGF0ZXMgbmVzdGVkIGNvbnRyb2xzLCBhbmQgbWFuYWdlc1xuICAgKiBtdWx0aXBsZSBjb250cm9sIHNjZW5hcmlvcy4gQXV0b21hdGljYWxseSBlbmFibGVzIGFsbCBncm91cCBjb250cm9scyBhZnRlciBkYXRhIGV4dHJhY3Rpb24uXG4gICAqXG4gICAqIEBwYXJhbSB7Rm9ybUdyb3VwfSBmb3JtR3JvdXAgLSBUaGUgRm9ybUdyb3VwIHRvIGV4dHJhY3QgZGF0YSBmcm9tXG4gICAqIEByZXR1cm4ge1JlY29yZDxzdHJpbmcsIHVua25vd24+fSBBbiBvYmplY3QgY29udGFpbmluZyB0aGUgcHJvY2Vzc2VkIGZvcm0gZGF0YSB3aXRoIHByb3BlciB0eXBlIGNvbnZlcnNpb25zXG4gICAqXG4gICAqIEBtZXJtYWlkXG4gICAqIHNlcXVlbmNlRGlhZ3JhbVxuICAgKiAgIHBhcnRpY2lwYW50IEMgYXMgQ29tcG9uZW50XG4gICAqICAgcGFydGljaXBhbnQgTkZTIGFzIE5neEZvcm1TZXJ2aWNlXG4gICAqICAgcGFydGljaXBhbnQgRkcgYXMgRm9ybUdyb3VwXG4gICAqICAgcGFydGljaXBhbnQgRkMgYXMgRm9ybUNvbnRyb2xcbiAgICpcbiAgICogICBDLT4+TkZTOiBnZXRGb3JtRGF0YShmb3JtR3JvdXApXG4gICAqICAgbG9vcCBGb3IgZWFjaCBjb250cm9sIGluIGZvcm1Hcm91cFxuICAgKiAgICAgYWx0IENvbnRyb2wgaXMgbm90IEZvcm1Db250cm9sXG4gICAqICAgICAgIE5GUy0+Pk5GUzogUmVjdXJzaXZlIGdldEZvcm1EYXRhKGNvbnRyb2wpXG4gICAqICAgICAgIGFsdCBwYXJlbnRQcm9wcy5tdWx0aXBsZSBhbmQgIWlzVmFsaWRcbiAgICogICAgICAgICBORlMtPj5ORlM6IHJlc2V0KGNvbnRyb2wpXG4gICAqICAgICAgIGVuZFxuICAgKiAgICAgZWxzZSBDb250cm9sIGlzIEZvcm1Db250cm9sXG4gICAqICAgICAgIE5GUy0+PkZDOiBHZXQgY29udHJvbCB2YWx1ZVxuICAgKiAgICAgICBORlMtPj5ORlM6IEFwcGx5IHR5cGUgY29udmVyc2lvbiBiYXNlZCBvbiBwcm9wcy50eXBlXG4gICAqICAgICAgIGFsdCBIVE1MNUNoZWNrVHlwZXNcbiAgICogICAgICAgICBORlMtPj5ORlM6IEtlZXAgYm9vbGVhbiB2YWx1ZVxuICAgKiAgICAgICBlbHNlIE5VTUJFUiB0eXBlXG4gICAqICAgICAgICAgTkZTLT4+TkZTOiBwYXJzZVRvTnVtYmVyKHZhbHVlKVxuICAgKiAgICAgICBlbHNlIERBVEUvREFURVRJTUUgdHlwZXNcbiAgICogICAgICAgICBORlMtPj5ORlM6IG5ldyBEYXRlKHZhbHVlKVxuICAgKiAgICAgICBlbHNlIE90aGVyIHR5cGVzXG4gICAqICAgICAgICAgTkZTLT4+TkZTOiBlc2NhcGVIdG1sKHZhbHVlKVxuICAgKiAgICAgICBlbmRcbiAgICogICAgIGVuZFxuICAgKiAgIGVuZFxuICAgKiAgIE5GUy0+Pk5GUzogZW5hYmxlQWxsR3JvdXBDb250cm9scyhmb3JtR3JvdXApXG4gICAqICAgTkZTLS0+PkM6IFJldHVybiBwcm9jZXNzZWQgZGF0YSBvYmplY3RcbiAgICpcbiAgICogQHN0YXRpY1xuICAgKiBAbWVtYmVyT2YgTmd4Rm9ybVNlcnZpY2VcbiAgICovXG4gIHN0YXRpYyBnZXRGb3JtRGF0YShmb3JtR3JvdXA6IEZvcm1Hcm91cCk6IFJlY29yZDxzdHJpbmcsIHVua25vd24+IHtcbiAgICBjb25zdCBkYXRhOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiA9IHt9O1xuICAgIGZvciAoY29uc3Qga2V5IGluIGZvcm1Hcm91cC5jb250cm9scykge1xuICAgICAgY29uc3QgY29udHJvbCA9IGZvcm1Hcm91cC5jb250cm9sc1trZXldO1xuICAgICAgY29uc3QgcGFyZW50UHJvcHMgPSBOZ3hGb3JtU2VydmljZS5nZXRQcm9wc0Zyb21Db250cm9sKGZvcm1Hcm91cCBhcyBGb3JtR3JvdXAgfCBGb3JtQXJyYXkpO1xuICAgICAgaWYgKCEoY29udHJvbCBpbnN0YW5jZW9mIEZvcm1Db250cm9sKSkge1xuICAgICAgICBjb25zdCB2YWx1ZSA9IE5neEZvcm1TZXJ2aWNlLmdldEZvcm1EYXRhKGNvbnRyb2wgYXMgRm9ybUdyb3VwKTtcbiAgICAgICAgY29uc3QgaXNWYWxpZCA9IGNvbnRyb2wudmFsaWQ7XG4gICAgICAgIGlmKHBhcmVudFByb3BzLm11bHRpcGxlKSB7XG4gICAgICAgICAgICBpZihpc1ZhbGlkKSB7XG4gICAgICAgICAgICAgICBkYXRhW2tleV0gPSB2YWx1ZTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIHRoaXMucmVzZXQoY29udHJvbCBhcyBGb3JtQ29udHJvbCk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG4gICAgICAgIGRhdGFba2V5XSA9IHZhbHVlO1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgcHJvcHMgPSBOZ3hGb3JtU2VydmljZS5nZXRQcm9wc0Zyb21Db250cm9sKGNvbnRyb2wgYXMgRm9ybUNvbnRyb2wgfCBGb3JtQXJyYXkpO1xuICAgICAgbGV0IHZhbHVlID0gY29udHJvbC52YWx1ZTtcbiAgICAgIGlmICghSFRNTDVDaGVja1R5cGVzLmluY2x1ZGVzKHByb3BzWyd0eXBlJ10pKSB7XG4gICAgICAgIHN3aXRjaCAocHJvcHNbJ3R5cGUnXSkge1xuICAgICAgICAgIGNhc2UgSFRNTDVJbnB1dFR5cGVzLk5VTUJFUjpcbiAgICAgICAgICAgIHZhbHVlID0gcGFyc2VUb051bWJlcih2YWx1ZSk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICBjYXNlIEhUTUw1SW5wdXRUeXBlcy5EQVRFOlxuICAgICAgICAgIGNhc2UgSFRNTDVJbnB1dFR5cGVzLkRBVEVUSU1FX0xPQ0FMOlxuICAgICAgICAgICAgdmFsdWUgPSBuZXcgRGF0ZSh2YWx1ZSk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgdmFsdWUgPSBlc2NhcGVIdG1sKHZhbHVlKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgZGF0YVtrZXldID0gdmFsdWU7XG4gICAgfVxuICAgIE5neEZvcm1TZXJ2aWNlLmVuYWJsZUFsbEdyb3VwQ29udHJvbHMoZm9ybUdyb3VwIGFzIEZvcm1Hcm91cCk7XG4gICAgcmV0dXJuIGRhdGE7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFZhbGlkYXRlcyBmaWVsZHMgaW4gYSBmb3JtIGNvbnRyb2wgb3IgZm9ybSBncm91cC5cbiAgICogQHN1bW1hcnkgUmVjdXJzaXZlbHkgdmFsaWRhdGVzIGFsbCBmaWVsZHMgaW4gYSBmb3JtIGNvbnRyb2wgb3IgZm9ybSBncm91cCwgbWFya2luZyB0aGVtIGFzIHRvdWNoZWQgYW5kIGRpcnR5LlxuICAgKiBQZXJmb3JtcyBjb21wcmVoZW5zaXZlIHZhbGlkYXRpb24gaW5jbHVkaW5nIHVuaXF1ZW5lc3MgY2hlY2tzIGZvciBwcmltYXJ5IGtleXMgaW4gRm9ybUFycmF5IHNjZW5hcmlvcy5cbiAgICogVGhpcyBtZXRob2QgZW5zdXJlcyBhbGwgdmFsaWRhdGlvbiBydWxlcyBhcmUgYXBwbGllZCBhbmQgZm9ybSBzdGF0ZSBpcyBwcm9wZXJseSB1cGRhdGVkLlxuICAgKlxuICAgKiBAcGFyYW0ge0Fic3RyYWN0Q29udHJvbH0gY29udHJvbCAtIFRoZSBjb250cm9sIG9yIGZvcm0gZ3JvdXAgdG8gdmFsaWRhdGVcbiAgICogQHBhcmFtIHtzdHJpbmd9IFtwa10gLSBPcHRpb25hbCBwcmltYXJ5IGtleSBmaWVsZCBuYW1lIGZvciB1bmlxdWVuZXNzIHZhbGlkYXRpb25cbiAgICogQHBhcmFtIHtzdHJpbmd9IFtwYXRoXSAtIFRoZSBwYXRoIHRvIHRoZSBjb250cm9sIHdpdGhpbiB0aGUgZm9ybSBmb3IgZXJyb3IgcmVwb3J0aW5nXG4gICAqIEByZXR1cm4ge2Jvb2xlYW59IFRydWUgaWYgYWxsIGZpZWxkcyBhcmUgdmFsaWQsIGZhbHNlIG90aGVyd2lzZVxuICAgKiBAdGhyb3dzIHtFcnJvcn0gSWYgbm8gY29udHJvbCBpcyBmb3VuZCBhdCB0aGUgc3BlY2lmaWVkIHBhdGggb3IgaWYgdGhlIGNvbnRyb2wgdHlwZSBpcyB1bmtub3duXG4gICAqXG4gICAqIEBtZXJtYWlkXG4gICAqIHNlcXVlbmNlRGlhZ3JhbVxuICAgKiAgIHBhcnRpY2lwYW50IEMgYXMgQ29tcG9uZW50XG4gICAqICAgcGFydGljaXBhbnQgTkZTIGFzIE5neEZvcm1TZXJ2aWNlXG4gICAqICAgcGFydGljaXBhbnQgRkMgYXMgRm9ybUNvbnRyb2xcbiAgICogICBwYXJ0aWNpcGFudCBGRyBhcyBGb3JtR3JvdXBcbiAgICogICBwYXJ0aWNpcGFudCBGQSBhcyBGb3JtQXJyYXlcbiAgICpcbiAgICogICBDLT4+TkZTOiB2YWxpZGF0ZUZpZWxkcyhjb250cm9sLCBwaz8sIHBhdGg/KVxuICAgKiAgIGFsdCBDb250cm9sIGlzIEZvcm1Db250cm9sXG4gICAqICAgICBORlMtPj5GQzogbWFya0FzVG91Y2hlZCgpXG4gICAqICAgICBORlMtPj5GQzogbWFya0FzRGlydHkoKVxuICAgKiAgICAgTkZTLT4+RkM6IHVwZGF0ZVZhbHVlQW5kVmFsaWRpdHkoKVxuICAgKiAgICAgYWx0IElzIGluIEZvcm1BcnJheSBncm91cFxuICAgKiAgICAgICBORlMtPj5ORlM6IENoZWNrIHVuaXF1ZW5lc3MgaW4gZ3JvdXBcbiAgICogICAgICAgYWx0IE5vdCB1bmlxdWVcbiAgICogICAgICAgICBORlMtPj5GQzogc2V0RXJyb3JzKHtub3RVbmlxdWU6IHRydWV9KVxuICAgKiAgICAgICBlbmRcbiAgICogICAgIGVuZFxuICAgKiAgICAgTkZTLS0+PkM6IFJldHVybiBjb250cm9sLnZhbGlkXG4gICAqICAgZWxzZSBDb250cm9sIGlzIEZvcm1Hcm91cFxuICAgKiAgICAgbG9vcCBGb3IgZWFjaCBjaGlsZCBjb250cm9sXG4gICAqICAgICAgIE5GUy0+Pk5GUzogUmVjdXJzaXZlIHZhbGlkYXRlRmllbGRzKGNoaWxkKVxuICAgKiAgICAgZW5kXG4gICAqICAgICBORlMtLT4+QzogUmV0dXJuIGFsbFZhbGlkXG4gICAqICAgZWxzZSBDb250cm9sIGlzIEZvcm1BcnJheVxuICAgKiAgICAgbG9vcCBGb3IgZWFjaCBhcnJheSBjb250cm9sXG4gICAqICAgICAgIE5GUy0+Pk5GUzogUmVjdXJzaXZlIHZhbGlkYXRlRmllbGRzKGNoaWxkKVxuICAgKiAgICAgZW5kXG4gICAqICAgICBORlMtLT4+QzogUmV0dXJuIGFsbFZhbGlkXG4gICAqICAgZWxzZSBVbmtub3duIGNvbnRyb2wgdHlwZVxuICAgKiAgICAgTkZTLS0+PkM6IFRocm93IEVycm9yXG4gICAqICAgZW5kXG4gICAqXG4gICAqIEBzdGF0aWNcbiAgICogQG1lbWJlck9mIE5neEZvcm1TZXJ2aWNlXG4gICAqL1xuICBzdGF0aWMgdmFsaWRhdGVGaWVsZHMoY29udHJvbDogQWJzdHJhY3RDb250cm9sLCBwaz86IHN0cmluZywgIHBhdGg/OiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICBjb250cm9sID0gcGF0aCA/IGNvbnRyb2wuZ2V0KHBhdGgpIGFzIEFic3RyYWN0Q29udHJvbCA6IGNvbnRyb2w7XG4gICAgaWYgKCFjb250cm9sKVxuICAgICAgdGhyb3cgbmV3IEVycm9yKGBObyBjb250cm9sIGZvdW5kIGF0IHBhdGg6ICR7cGF0aCB8fCAncm9vdCd9LmApO1xuXG4gICAgY29uc3QgaXNBbGxvd2VkID0gW0Zvcm1BcnJheSwgRm9ybUdyb3VwLCBGb3JtQ29udHJvbF0uc29tZSh0eXBlID0+IGNvbnRyb2wgaW5zdGFuY2VvZiB0eXBlKTtcbiAgICBpZiAoIWlzQWxsb3dlZClcbiAgICAgIHRocm93IG5ldyBFcnJvcihgVW5rbm93biBjb250cm9sIHR5cGUgYXQ6ICR7cGF0aCB8fCAncm9vdCd9YCk7XG5cbiAgICBjb250cm9sLm1hcmtBc1RvdWNoZWQoKTtcbiAgICBjb250cm9sLm1hcmtBc0RpcnR5KCk7XG4gICAgY29udHJvbC51cGRhdGVWYWx1ZUFuZFZhbGlkaXR5KHsgZW1pdEV2ZW50OiB0cnVlIH0pO1xuXG4gICAgaWYgKGNvbnRyb2wgaW5zdGFuY2VvZiBGb3JtR3JvdXApIHtcbiAgICAgIE9iamVjdC52YWx1ZXMoY29udHJvbC5jb250cm9scykuZm9yRWFjaChjaGlsZENvbnRyb2wgPT4ge1xuICAgICAgICB0aGlzLnZhbGlkYXRlRmllbGRzKGNoaWxkQ29udHJvbCk7XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICBpZiAoY29udHJvbCBpbnN0YW5jZW9mIEZvcm1BcnJheSkge1xuICAgICAgY29uc3QgdG90YWxHcm91cHMgPSBjb250cm9sLmxlbmd0aDtcbiAgICAgIGNvbnN0IGhhc1ZhbGlkID0gY29udHJvbC5jb250cm9scy5zb21lKGNvbnRyb2wgPT4gY29udHJvbC52YWxpZCk7XG4gICAgICBpZih0b3RhbEdyb3VwcyA+IDEgJiYgaGFzVmFsaWQpIHtcbiAgICAgICAgIGZvciAobGV0IGkgPSBjb250cm9sLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgICAgICAgY29uc3QgY2hpbGRDb250cm9sID0gY29udHJvbC5hdChpKTtcbiAgICAgICAgICAvLyBkaXNhYmxlIG5vIHZhbGlkIGdyb3VwcyBvbiBhcnJheVxuICAgICAgICAgIGlmICghY2hpbGRDb250cm9sLnZhbGlkKSB7XG4gICAgICAgICAgICAoY2hpbGRDb250cm9sLnBhcmVudCBhcyBGb3JtR3JvdXApLnNldEVycm9ycyhudWxsKTtcbiAgICAgICAgICAgICAoY2hpbGRDb250cm9sLnBhcmVudCBhcyBGb3JtR3JvdXApLnVwZGF0ZVZhbHVlQW5kVmFsaWRpdHkoeyBlbWl0RXZlbnQ6IHRydWUgfSk7XG4gICAgICAgICAgICBjaGlsZENvbnRyb2wuZGlzYWJsZSgpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLnZhbGlkYXRlRmllbGRzKGNoaWxkQ29udHJvbCk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBPYmplY3QudmFsdWVzKGNvbnRyb2wuY29udHJvbHMpLmZvckVhY2goY2hpbGRDb250cm9sID0+IHtcbiAgICAgICAgICB0aGlzLnZhbGlkYXRlRmllbGRzKGNoaWxkQ29udHJvbCk7XG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIGZ1bmN0aW9uIGdldENvbnRyb2xOYW1lKGNvbnRyb2w6IEFic3RyYWN0Q29udHJvbCk6IHN0cmluZyB8IG51bGwge1xuICAgIC8vICAgY29uc3QgZ3JvdXAgPSBjb250cm9sLnBhcmVudCBhcyBGb3JtR3JvdXA7XG4gICAgLy8gICBpZiAoIWdyb3VwKVxuICAgIC8vICAgICAgIHJldHVybiBudWxsO1xuICAgIC8vICAgcmV0dXJuIE9iamVjdC5rZXlzKGdyb3VwLmNvbnRyb2xzKS5maW5kKG5hbWUgPT4gY29udHJvbCA9PT0gZ3JvdXAuZ2V0KG5hbWUpKSB8fCBudWxsO1xuICAgIC8vIH1cblxuICAgIHJldHVybiBjb250cm9sLnZhbGlkO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBHZW5lcmF0ZXMgdmFsaWRhdG9ycyBmcm9tIGNvbXBvbmVudCBwcm9wZXJ0aWVzLlxuICAgKiBAc3VtbWFyeSBDcmVhdGVzIGFuIGFycmF5IG9mIFZhbGlkYXRvckZuIGJhc2VkIG9uIHRoZSBzdXBwb3J0ZWQgdmFsaWRhdGlvbiBrZXlzIGluIHRoZSBjb21wb25lbnQgcHJvcGVydGllcy5cbiAgICogQHBhcmFtIHtGaWVsZFByb3BlcnRpZXN9IHByb3BzIC0gVGhlIGNvbXBvbmVudCBwcm9wZXJ0aWVzLlxuICAgKiBAcmV0dXJuIHtWYWxpZGF0b3JGbltdfSBBbiBhcnJheSBvZiB2YWxpZGF0b3IgZnVuY3Rpb25zLlxuICAgKi9cbiAgcHJpdmF0ZSBzdGF0aWMgdmFsaWRhdG9yc0Zyb21Qcm9wcyhwcm9wczogRmllbGRQcm9wZXJ0aWVzKTogVmFsaWRhdG9yRm5bXSB7XG4gICAgY29uc3Qgc3VwcG9ydGVkVmFsaWRhdGlvbktleXMgPSBWYWxpZGF0aW9uLmtleXMoKTtcbiAgICByZXR1cm4gT2JqZWN0LmtleXMocHJvcHMpXG4gICAgICAuZmlsdGVyKChrOiBzdHJpbmcpID0+IHN1cHBvcnRlZFZhbGlkYXRpb25LZXlzLmluY2x1ZGVzKGspKVxuICAgICAgLm1hcCgoazogc3RyaW5nKSA9PiB7XG4gICAgICAgIHJldHVybiBWYWxpZGF0b3JGYWN0b3J5LnNwYXduKHByb3BzLCBrKTtcbiAgICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBDcmVhdGVzIGEgRm9ybUNvbnRyb2wgZnJvbSBjb21wb25lbnQgcHJvcGVydGllcy5cbiAgICogQHN1bW1hcnkgR2VuZXJhdGVzIGEgRm9ybUNvbnRyb2wgd2l0aCB2YWxpZGF0b3JzIGFuZCBpbml0aWFsIGNvbmZpZ3VyYXRpb24gYmFzZWQgb24gdGhlIHByb3ZpZGVkXG4gICAqIGNvbXBvbmVudCBwcm9wZXJ0aWVzLiBIYW5kbGVzIGRpZmZlcmVudCBpbnB1dCB0eXBlcywgc2V0cyBpbml0aWFsIHZhbHVlcywgYW5kIGNvbmZpZ3VyZXNcbiAgICogdmFsaWRhdGlvbiBydWxlcyBhbmQgdXBkYXRlIG1vZGVzLlxuICAgKlxuICAgKiBAcGFyYW0ge0ZpZWxkUHJvcGVydGllc30gcHJvcHMgLSBUaGUgY29tcG9uZW50IHByb3BlcnRpZXMgZGVmaW5pbmcgdGhlIGNvbnRyb2wgY29uZmlndXJhdGlvblxuICAgKiBAcGFyYW0ge0ZpZWxkVXBkYXRlTW9kZX0gW3VwZGF0ZU1vZGU9J2NoYW5nZSddIC0gVGhlIHVwZGF0ZSBtb2RlIGZvciB0aGUgY29udHJvbCAoJ2NoYW5nZScsICdibHVyJywgJ3N1Ym1pdCcpXG4gICAqIEByZXR1cm4ge0Zvcm1Db250cm9sfSBUaGUgY3JlYXRlZCBGb3JtQ29udHJvbCB3aXRoIHByb3BlciBjb25maWd1cmF0aW9uIGFuZCB2YWxpZGF0b3JzXG4gICAqXG4gICAqIEBtZXJtYWlkXG4gICAqIHNlcXVlbmNlRGlhZ3JhbVxuICAgKiAgIHBhcnRpY2lwYW50IEMgYXMgQ29tcG9uZW50XG4gICAqICAgcGFydGljaXBhbnQgTkZTIGFzIE5neEZvcm1TZXJ2aWNlXG4gICAqICAgcGFydGljaXBhbnQgVkYgYXMgVmFsaWRhdG9yRmFjdG9yeVxuICAgKiAgIHBhcnRpY2lwYW50IEFGIGFzIEFuZ3VsYXIgRm9ybXNcbiAgICpcbiAgICogICBDLT4+TkZTOiBmcm9tUHJvcHMocHJvcHMsIHVwZGF0ZU1vZGU/KVxuICAgKiAgIE5GUy0+Pk5GUzogdmFsaWRhdG9yc0Zyb21Qcm9wcyhwcm9wcylcbiAgICogICBORlMtPj5WRjogQ3JlYXRlIHZhbGlkYXRvcnMgZnJvbSBwcm9wc1xuICAgKiAgIFZGLS0+Pk5GUzogUmV0dXJuIHZhbGlkYXRvciBhcnJheVxuICAgKiAgIE5GUy0+Pk5GUzogQ29tcG9zZSB2YWxpZGF0b3JzXG4gICAqICAgYWx0IHByb3BzLnZhbHVlIGV4aXN0cyBhbmQgbm90IGNoZWNrYm94XG4gICAqICAgICBhbHQgcHJvcHMudHlwZSBpcyBEQVRFXG4gICAqICAgICAgIE5GUy0+Pk5GUzogVmFsaWRhdGUgZGF0ZSBmb3JtYXRcbiAgICogICAgIGVuZFxuICAgKiAgICAgTkZTLT4+TkZTOiBTZXQgaW5pdGlhbCB2YWx1ZVxuICAgKiAgIGVuZFxuICAgKiAgIE5GUy0+PkFGOiBuZXcgRm9ybUNvbnRyb2woY29uZmlnKVxuICAgKiAgIEFGLS0+Pk5GUzogUmV0dXJuIEZvcm1Db250cm9sXG4gICAqICAgTkZTLS0+PkM6IFJldHVybiBjb25maWd1cmVkIEZvcm1Db250cm9sXG4gICAqXG4gICAqIEBzdGF0aWNcbiAgICogQG1lbWJlck9mIE5neEZvcm1TZXJ2aWNlXG4gICAqL1xuICBzdGF0aWMgZnJvbVByb3BzKHByb3BzOiBGaWVsZFByb3BlcnRpZXMsIHVwZGF0ZU1vZGU6IEZpZWxkVXBkYXRlTW9kZSA9ICdjaGFuZ2UnKTogRm9ybUNvbnRyb2wge1xuICAgIGNvbnN0IHZhbGlkYXRvcnMgPSB0aGlzLnZhbGlkYXRvcnNGcm9tUHJvcHMocHJvcHMpO1xuICAgIGNvbnN0IGNvbXBvc2VkID0gdmFsaWRhdG9ycy5sZW5ndGggPyBWYWxpZGF0b3JzLmNvbXBvc2UodmFsaWRhdG9ycykgOiBudWxsO1xuICAgIHJldHVybiBuZXcgRm9ybUNvbnRyb2woXG4gICAgICB7XG4gICAgICAgIHZhbHVlOlxuICAgICAgICAgIHByb3BzLnZhbHVlICYmIHByb3BzLnR5cGUgIT09IEhUTUw1SW5wdXRUeXBlcy5DSEVDS0JPWFxuICAgICAgICAgICAgPyBwcm9wcy50eXBlID09PSBIVE1MNUlucHV0VHlwZXMuREFURVxuICAgICAgICAgICAgICA/ICFpc1ZhbGlkRGF0ZShwYXJzZURhdGUocHJvcHMuZm9ybWF0IGFzIHN0cmluZywgcHJvcHMudmFsdWUgYXMgc3RyaW5nKSlcbiAgICAgICAgICAgICAgICA/IHVuZGVmaW5lZCA6IHByb3BzLnZhbHVlIDpcbiAgICAgICAgICAgICAgKHByb3BzLnZhbHVlIGFzIHVua25vd24pIDogdW5kZWZpbmVkLFxuICAgICAgICBkaXNhYmxlZDogcHJvcHMuZGlzYWJsZWQsXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICB2YWxpZGF0b3JzOiBjb21wb3NlZCxcbiAgICAgICAgdXBkYXRlT246IHVwZGF0ZU1vZGUsXG4gICAgICB9LFxuICAgICk7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFJldHJpZXZlcyBwcm9wZXJ0aWVzIGZyb20gYSBGb3JtQ29udHJvbCwgRm9ybUFycmF5LCBvciBGb3JtR3JvdXAuXG4gICAqIEBzdW1tYXJ5IEdldHMgdGhlIEZpZWxkUHJvcGVydGllcyBhc3NvY2lhdGVkIHdpdGggYSBmb3JtIGNvbnRyb2wgZnJvbSB0aGUgaW50ZXJuYWwgV2Vha01hcC5cbiAgICogVGhpcyBtZXRob2QgcHJvdmlkZXMgYWNjZXNzIHRvIHRoZSBvcmlnaW5hbCBjb21wb25lbnQgcHJvcGVydGllcyB0aGF0IHdlcmUgdXNlZCB0byBjcmVhdGVcbiAgICogdGhlIGNvbnRyb2wsIGVuYWJsaW5nIHZhbGlkYXRpb24sIHJlbmRlcmluZywgYW5kIGJlaGF2aW9yIGNvbmZpZ3VyYXRpb24uXG4gICAqXG4gICAqIEBwYXJhbSB7Rm9ybUNvbnRyb2wgfCBGb3JtQXJyYXkgfCBGb3JtR3JvdXB9IGNvbnRyb2wgLSBUaGUgZm9ybSBjb250cm9sIHRvIGdldCBwcm9wZXJ0aWVzIGZvclxuICAgKiBAcmV0dXJuIHtGaWVsZFByb3BlcnRpZXN9IFRoZSBwcm9wZXJ0aWVzIGFzc29jaWF0ZWQgd2l0aCB0aGUgY29udHJvbCwgb3IgZW1wdHkgb2JqZWN0IGlmIG5vdCBmb3VuZFxuICAgKlxuICAgKiBAc3RhdGljXG4gICAqIEBtZW1iZXJPZiBOZ3hGb3JtU2VydmljZVxuICAgKi9cbiAgc3RhdGljIGdldFByb3BzRnJvbUNvbnRyb2woY29udHJvbDogRm9ybUNvbnRyb2wgfCBGb3JtQXJyYXkgfCBGb3JtR3JvdXApOiBGaWVsZFByb3BlcnRpZXMge1xuICAgIHJldHVybiB0aGlzLmNvbnRyb2xzLmdldChjb250cm9sKSB8fCB7fSBhcyBGaWVsZFByb3BlcnRpZXM7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIEZpbmRzIGEgcGFyZW50IGVsZW1lbnQgd2l0aCBhIHNwZWNpZmljIHRhZyBpbiB0aGUgRE9NIHRyZWUuXG4gICAqIEBzdW1tYXJ5IFRyYXZlcnNlcyB1cCB0aGUgRE9NIHRyZWUgdG8gZmluZCB0aGUgbmVhcmVzdCBwYXJlbnQgZWxlbWVudCB3aXRoIHRoZSBzcGVjaWZpZWQgdGFnIG5hbWUuXG4gICAqIFRoaXMgaXMgdXNlZnVsIGZvciBmaW5kaW5nIGNvbnRhaW5lciBlbGVtZW50cyBvciBzcGVjaWZpYyBwYXJlbnQgY29tcG9uZW50cyBpbiB0aGUgRE9NIGhpZXJhcmNoeS5cbiAgICogVGhlIHNlYXJjaCBpcyBjYXNlLWluc2Vuc2l0aXZlIGZvciB0YWcgbmFtZSBtYXRjaGluZy5cbiAgICpcbiAgICogQHBhcmFtIHtIVE1MRWxlbWVudH0gZWwgLSBUaGUgc3RhcnRpbmcgZWxlbWVudCB0byB0cmF2ZXJzZSBmcm9tXG4gICAqIEBwYXJhbSB7c3RyaW5nfSB0YWcgLSBUaGUgdGFnIG5hbWUgdG8gc2VhcmNoIGZvciAoY2FzZS1pbnNlbnNpdGl2ZSlcbiAgICogQHJldHVybiB7SFRNTEVsZW1lbnR9IFRoZSBmb3VuZCBwYXJlbnQgZWxlbWVudCB3aXRoIHRoZSBzcGVjaWZpZWQgdGFnXG4gICAqIEB0aHJvd3Mge0Vycm9yfSBJZiBubyBwYXJlbnQgd2l0aCB0aGUgc3BlY2lmaWVkIHRhZyBpcyBmb3VuZCBpbiB0aGUgRE9NIHRyZWVcbiAgICpcbiAgICogQG1lcm1haWRcbiAgICogc2VxdWVuY2VEaWFncmFtXG4gICAqICAgcGFydGljaXBhbnQgQyBhcyBDb21wb25lbnRcbiAgICogICBwYXJ0aWNpcGFudCBORlMgYXMgTmd4Rm9ybVNlcnZpY2VcbiAgICogICBwYXJ0aWNpcGFudCBET00gYXMgRE9NIFRyZWVcbiAgICpcbiAgICogICBDLT4+TkZTOiBnZXRQYXJlbnRFbChlbGVtZW50LCB0YWdOYW1lKVxuICAgKiAgIGxvb3AgVHJhdmVyc2UgdXAgRE9NIHRyZWVcbiAgICogICAgIE5GUy0+PkRPTTogR2V0IHBhcmVudEVsZW1lbnRcbiAgICogICAgIERPTS0tPj5ORlM6IFJldHVybiBwYXJlbnQgb3IgbnVsbFxuICAgKiAgICAgYWx0IFBhcmVudCBleGlzdHMgYW5kIHRhZyBtYXRjaGVzXG4gICAqICAgICAgIE5GUy0tPj5DOiBSZXR1cm4gcGFyZW50IGVsZW1lbnRcbiAgICogICAgIGVsc2UgUGFyZW50IGlzIG51bGxcbiAgICogICAgICAgTkZTLS0+PkM6IFRocm93IEVycm9yXG4gICAqICAgICBlbmRcbiAgICogICBlbmRcbiAgICpcbiAgICogQHN0YXRpY1xuICAgKiBAbWVtYmVyT2YgTmd4Rm9ybVNlcnZpY2VcbiAgICovXG4gIHN0YXRpYyBnZXRQYXJlbnRFbChlbDogSFRNTEVsZW1lbnQsIHRhZzogc3RyaW5nKTogSFRNTEVsZW1lbnQge1xuICAgIGxldCBwYXJlbnQ6IEhUTUxFbGVtZW50IHwgbnVsbDtcbiAgICB3aGlsZSAoKHBhcmVudCA9IGVsLnBhcmVudEVsZW1lbnQpICE9PSBudWxsKSB7XG4gICAgICBpZiAocGFyZW50LnRhZ05hbWUudG9Mb3dlckNhc2UoKSA9PT0gdGFnLnRvTG93ZXJDYXNlKCkpIHtcbiAgICAgICAgcmV0dXJuIHBhcmVudDtcbiAgICAgIH1cbiAgICAgIGVsID0gcGFyZW50O1xuICAgIH1cbiAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICBgTm8gcGFyZW50IHdpdGggdGhlIHRhZyAke3RhZ30gd2FzIGZvdW5kIGZvciBwcm92aWRlZCBlbGVtZW50YCxcbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBSZWdpc3RlcnMgYSBjb250cm9sIHdpdGggaXRzIHByb3BlcnRpZXMgaW4gdGhlIGludGVybmFsIFdlYWtNYXAuXG4gICAqIEBzdW1tYXJ5IEFzc29jaWF0ZXMgYSBmb3JtIGNvbnRyb2wgd2l0aCBpdHMgY29tcG9uZW50IHByb3BlcnRpZXMgZm9yIGxhdGVyIHJldHJpZXZhbC5cbiAgICogVGhpcyBlbmFibGVzIHRoZSBzZXJ2aWNlIHRvIG1haW50YWluIG1ldGFkYXRhIGFib3V0IGNvbnRyb2xzIHdpdGhvdXQgY3JlYXRpbmcgbWVtb3J5IGxlYWtzLFxuICAgKiBhcyBXZWFrTWFwIGF1dG9tYXRpY2FsbHkgY2xlYW5zIHVwIHJlZmVyZW5jZXMgd2hlbiBjb250cm9scyBhcmUgZ2FyYmFnZSBjb2xsZWN0ZWQuXG4gICAqXG4gICAqIEBwYXJhbSB7QWJzdHJhY3RDb250cm9sfSBjb250cm9sIC0gVGhlIGNvbnRyb2wgdG8gcmVnaXN0ZXIgKEZvcm1Db250cm9sLCBGb3JtR3JvdXAsIG9yIEZvcm1BcnJheSlcbiAgICogQHBhcmFtIHtGaWVsZFByb3BlcnRpZXN9IHByb3BzIC0gVGhlIHByb3BlcnRpZXMgdG8gYXNzb2NpYXRlIHdpdGggdGhlIGNvbnRyb2xcbiAgICogQHJldHVybiB7dm9pZH1cbiAgICpcbiAgICogQHN0YXRpY1xuICAgKiBAbWVtYmVyT2YgTmd4Rm9ybVNlcnZpY2VcbiAgICovXG4gIHN0YXRpYyByZWdpc3Rlcihjb250cm9sOiBBYnN0cmFjdENvbnRyb2wsIHByb3BzOiBGaWVsZFByb3BlcnRpZXMpOiB2b2lkIHtcbiAgICB0aGlzLmNvbnRyb2xzLnNldChjb250cm9sLCBwcm9wcyk7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFVucmVnaXN0ZXJzIGEgY29udHJvbC5cbiAgICogQHN1bW1hcnkgUmVtb3ZlcyBhIGNvbnRyb2wgYW5kIGl0cyBhc3NvY2lhdGVkIHByb3BlcnRpZXMgZnJvbSB0aGUgaW50ZXJuYWwgV2Vha01hcC5cbiAgICogQHBhcmFtIHtBYnN0cmFjdENvbnRyb2x9IGNvbnRyb2wgLSBUaGUgY29udHJvbCB0byB1bnJlZ2lzdGVyLlxuICAgKiBAcmV0dXJuIHtib29sZWFufSBUcnVlIGlmIHRoZSBjb250cm9sIHdhcyBzdWNjZXNzZnVsbHkgdW5yZWdpc3RlcmVkLCBmYWxzZSBvdGhlcndpc2UuXG4gICAqL1xuICBzdGF0aWMgdW5yZWdpc3Rlcihjb250cm9sOiBBYnN0cmFjdENvbnRyb2wpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5jb250cm9scy5kZWxldGUoY29udHJvbCk7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFJlc2V0cyBhIGZvcm0gZ3JvdXAuXG4gICAqIEBzdW1tYXJ5IFJlY3Vyc2l2ZWx5IHJlc2V0cyBhbGwgY29udHJvbHMgaW4gYSBmb3JtIGdyb3VwLCBjbGVhcmluZyB2YWx1ZXMsIGVycm9ycywgYW5kIG1hcmtpbmcgdGhlbSBhcyBwcmlzdGluZSBhbmQgdW50b3VjaGVkLlxuICAgKiBAcGFyYW0ge0Zvcm1Hcm91cH0gZm9ybUdyb3VwIC0gVGhlIGZvcm0gZ3JvdXAgdG8gcmVzZXQuXG4gICAqL1xuICBzdGF0aWMgcmVzZXQoZm9ybUdyb3VwOiBGb3JtR3JvdXAgfCBGb3JtQ29udHJvbCk6IHZvaWQge1xuICAgIGlmKGZvcm1Hcm91cCBpbnN0YW5jZW9mIEZvcm1Db250cm9sKSB7XG4gICAgICBjb25zdCBjb250cm9sID0gZm9ybUdyb3VwIGFzIEZvcm1Db250cm9sO1xuICAgICAgY29uc3QgeyB0eXBlIH0gPSBOZ3hGb3JtU2VydmljZS5nZXRQcm9wc0Zyb21Db250cm9sKGNvbnRyb2wpO1xuICAgICAgaWYgKCFIVE1MNUNoZWNrVHlwZXMuaW5jbHVkZXModHlwZSkpXG4gICAgICAgIGNvbnRyb2wuc2V0VmFsdWUoXCJcIik7XG4gICAgICBjb250cm9sLm1hcmtBc1ByaXN0aW5lKCk7XG4gICAgICBjb250cm9sLm1hcmtBc1VudG91Y2hlZCgpO1xuICAgICAgY29udHJvbC5zZXRFcnJvcnMobnVsbCk7XG4gICAgICBjb250cm9sLnVwZGF0ZVZhbHVlQW5kVmFsaWRpdHkoKTtcbiAgICB9IGVsc2Uge1xuICAgICAgZm9yIChjb25zdCBrZXkgaW4gZm9ybUdyb3VwLmNvbnRyb2xzKSB7XG4gICAgICAgIGNvbnN0IGNvbnRyb2wgPSBmb3JtR3JvdXAuY29udHJvbHNba2V5XTtcbiAgICAgICAgTmd4Rm9ybVNlcnZpY2UucmVzZXQoY29udHJvbCBhcyBGb3JtQ29udHJvbCk7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgIH1cbiAgfVxufVxuIl19