@decaf-ts/for-angular 0.0.23 → 0.0.25

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 (36) 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 -0
  6. package/components/layout/layout.component.d.ts +1 -24
  7. package/components/model-renderer/model-renderer.component.d.ts +6 -1
  8. package/components/stepped-form/stepped-form.component.d.ts +255 -0
  9. package/engine/NgxBaseComponent.d.ts +2 -2
  10. package/engine/NgxCrudFormField.d.ts +1 -0
  11. package/engine/NgxFormService.d.ts +381 -48
  12. package/engine/NgxRenderingEngine.d.ts +4 -2
  13. package/engine/interfaces.d.ts +1 -1
  14. package/engine/types.d.ts +4 -3
  15. package/esm2022/components/component-renderer/component-renderer.component.mjs +10 -4
  16. package/esm2022/components/crud-field/crud-field.component.mjs +14 -3
  17. package/esm2022/components/crud-form/crud-form.component.mjs +3 -3
  18. package/esm2022/components/empty-state/empty-state.component.mjs +2 -2
  19. package/esm2022/components/fieldset/fieldset.component.mjs +5 -3
  20. package/esm2022/components/for-angular-components.module.mjs +12 -7
  21. package/esm2022/components/index.mjs +2 -1
  22. package/esm2022/components/layout/layout.component.mjs +4 -29
  23. package/esm2022/components/list/list.component.mjs +3 -3
  24. package/esm2022/components/model-renderer/model-renderer.component.mjs +10 -3
  25. package/esm2022/components/stepped-form/stepped-form.component.mjs +306 -0
  26. package/esm2022/engine/NgxBaseComponent.mjs +10 -4
  27. package/esm2022/engine/NgxCrudFormField.mjs +19 -17
  28. package/esm2022/engine/NgxFormService.mjs +438 -57
  29. package/esm2022/engine/NgxRenderingEngine.mjs +21 -10
  30. package/esm2022/engine/ValidatorFactory.mjs +4 -4
  31. package/esm2022/engine/interfaces.mjs +1 -1
  32. package/esm2022/engine/types.mjs +1 -1
  33. package/esm2022/i18n/data/en.json +5 -0
  34. package/fesm2022/decaf-ts-for-angular.mjs +837 -137
  35. package/fesm2022/decaf-ts-for-angular.mjs.map +1 -1
  36. package/package.json +1 -1
@@ -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