@decaf-ts/ui-decorators 0.5.9 → 0.5.10

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 (58) hide show
  1. package/README.md +422 -12
  2. package/dist/ui-decorators.cjs +497 -51
  3. package/dist/ui-decorators.esm.cjs +497 -51
  4. package/lib/esm/index.d.ts +7 -3
  5. package/lib/esm/index.js +8 -4
  6. package/lib/esm/model/Renderable.d.ts +15 -0
  7. package/lib/esm/model/Renderable.js +1 -1
  8. package/lib/esm/model/decorators.d.ts +92 -14
  9. package/lib/esm/model/decorators.js +94 -16
  10. package/lib/esm/model/index.d.ts +0 -4
  11. package/lib/esm/model/index.js +1 -5
  12. package/lib/esm/model/model.d.ts +156 -50
  13. package/lib/esm/model/model.js +1 -1
  14. package/lib/esm/model/overrides.d.ts +8 -0
  15. package/lib/esm/model/overrides.js +19 -1
  16. package/lib/esm/ui/Rendering.js +15 -4
  17. package/lib/esm/ui/constants.d.ts +147 -4
  18. package/lib/esm/ui/constants.js +148 -5
  19. package/lib/esm/ui/decorators.d.ts +185 -21
  20. package/lib/esm/ui/decorators.js +189 -25
  21. package/lib/esm/ui/errors.d.ts +28 -0
  22. package/lib/esm/ui/errors.js +29 -1
  23. package/lib/esm/ui/index.d.ts +0 -4
  24. package/lib/esm/ui/index.js +1 -5
  25. package/lib/esm/ui/interfaces.d.ts +25 -0
  26. package/lib/esm/ui/interfaces.js +9 -1
  27. package/lib/esm/ui/types.d.ts +63 -5
  28. package/lib/esm/ui/types.js +9 -1
  29. package/lib/esm/ui/utils.d.ts +1 -1
  30. package/lib/esm/ui/utils.js +2 -2
  31. package/lib/index.cjs +8 -4
  32. package/lib/index.d.ts +7 -3
  33. package/lib/model/Renderable.cjs +1 -1
  34. package/lib/model/Renderable.d.ts +15 -0
  35. package/lib/model/decorators.cjs +94 -16
  36. package/lib/model/decorators.d.ts +92 -14
  37. package/lib/model/index.cjs +1 -5
  38. package/lib/model/index.d.ts +0 -4
  39. package/lib/model/model.cjs +1 -1
  40. package/lib/model/model.d.ts +156 -50
  41. package/lib/model/overrides.cjs +19 -1
  42. package/lib/model/overrides.d.ts +8 -0
  43. package/lib/ui/Rendering.cjs +15 -4
  44. package/lib/ui/constants.cjs +148 -5
  45. package/lib/ui/constants.d.ts +147 -4
  46. package/lib/ui/decorators.cjs +189 -25
  47. package/lib/ui/decorators.d.ts +185 -21
  48. package/lib/ui/errors.cjs +29 -1
  49. package/lib/ui/errors.d.ts +28 -0
  50. package/lib/ui/index.cjs +1 -5
  51. package/lib/ui/index.d.ts +0 -4
  52. package/lib/ui/interfaces.cjs +9 -1
  53. package/lib/ui/interfaces.d.ts +25 -0
  54. package/lib/ui/types.cjs +9 -1
  55. package/lib/ui/types.d.ts +63 -5
  56. package/lib/ui/utils.cjs +2 -2
  57. package/lib/ui/utils.d.ts +1 -1
  58. package/package.json +1 -1
@@ -5,8 +5,57 @@
5
5
  })(this, (function (exports, decoratorValidation, reflection, dbDecorators) { 'use strict';
6
6
 
7
7
  /**
8
- * @enum UIKeys
9
- * @category Constants
8
+ * @description Constants and enums for UI rendering and validation
9
+ * @summary Defines keys, mappings, and HTML5 input types for UI components
10
+ * This module provides constants used throughout the UI decorators library for
11
+ * rendering, validation, and HTML element generation.
12
+ * @module ui/constants
13
+ * @memberOf module:ui-decorators
14
+ */
15
+ /**
16
+ * @description Key constants used for UI metadata and rendering
17
+ * @summary Collection of string constants used as keys for UI-related metadata
18
+ * These keys are used throughout the library to store and retrieve metadata related to
19
+ * UI models, elements, properties, and validation rules.
20
+ *
21
+ * @typedef {Object} UIKeysType
22
+ * @property {string} REFLECT - Base reflection key for UI metadata
23
+ * @property {string} UIMODEL - Key for UI model metadata
24
+ * @property {string} RENDERED_BY - Key for specifying rendering engine
25
+ * @property {string} ELEMENT - Key for element metadata
26
+ * @property {string} PROP - Key for property metadata
27
+ * @property {string} NAME - Key for name attribute
28
+ * @property {string} NAME_PREFIX - Prefix for input names
29
+ * @property {string} CUSTOM_PROPS - Key for custom validation properties
30
+ * @property {string} UILISTITEM - Key for list item metadata
31
+ * @property {string} UILISTPROP - Key for list property metadata
32
+ * @property {string} TYPE - Key for type metadata
33
+ * @property {string} SUB_TYPE - Key for subtype metadata
34
+ * @property {string} HIDDEN - Key for hidden attribute
35
+ * @property {string} FORMAT - Key for format metadata
36
+ * @property {string} READ_ONLY - Key for readonly attribute
37
+ * @property {string} REQUIRED - Key for required validation
38
+ * @property {string} MIN - Key for minimum value validation
39
+ * @property {string} MIN_LENGTH - Key for minimum length validation
40
+ * @property {string} MAX - Key for maximum value validation
41
+ * @property {string} MAX_LENGTH - Key for maximum length validation
42
+ * @property {string} PATTERN - Key for pattern validation
43
+ * @property {string} URL - Key for URL validation
44
+ * @property {string} STEP - Key for step validation
45
+ * @property {string} DATE - Key for date validation
46
+ * @property {string} EMAIL - Key for email validation
47
+ * @property {string} PASSWORD - Key for password validation
48
+ * @property {string} EQUALS - Key for equality validation
49
+ * @property {string} DIFF - Key for difference validation
50
+ * @property {string} LESS_THAN - Key for less than validation
51
+ * @property {string} LESS_THAN_OR_EQUAL - Key for less than or equal validation
52
+ * @property {string} GREATER_THAN - Key for greater than validation
53
+ * @property {string} GREATER_THAN_OR_EQUAL - Key for greater than or equal validation
54
+ *
55
+ * @const UIKeys
56
+ * @type {UIKeysType}
57
+ * @readonly
58
+ * @memberOf module:ui-decorators
10
59
  */
11
60
  const UIKeys = {
12
61
  REFLECT: `${decoratorValidation.ModelKeys.REFLECT}.ui.`,
@@ -42,6 +91,23 @@
42
91
  GREATER_THAN: decoratorValidation.ValidationKeys.GREATER_THAN,
43
92
  GREATER_THAN_OR_EQUAL: decoratorValidation.ValidationKeys.GREATER_THAN_OR_EQUAL,
44
93
  };
94
+ /**
95
+ * @description Mapping of input types to their corresponding validators
96
+ * @summary Maps special input types to their validator classes
97
+ * This constant maps input types like email, URL, date, and password to their
98
+ * corresponding validator classes from the decorator-validation library.
99
+ *
100
+ * @typedef {Object.<string, Constructor<Validator>>} ValidatableByTypeMap
101
+ * @property {Constructor<EmailValidator>} email - Validator for email inputs
102
+ * @property {Constructor<URLValidator>} url - Validator for URL inputs
103
+ * @property {Constructor<DateValidator>} date - Validator for date inputs
104
+ * @property {Constructor<PasswordValidator>} password - Validator for password inputs
105
+ *
106
+ * @const ValidatableByType
107
+ * @type {ValidatableByTypeMap}
108
+ * @readonly
109
+ * @memberOf module:ui-decorators
110
+ */
45
111
  const ValidatableByType = {
46
112
  [UIKeys.EMAIL]: decoratorValidation.EmailValidator,
47
113
  [UIKeys.URL]: decoratorValidation.URLValidator,
@@ -49,9 +115,30 @@
49
115
  [UIKeys.PASSWORD]: decoratorValidation.PasswordValidator,
50
116
  };
51
117
  /**
52
- * @constant ValidatableByAttribute
118
+ * @description Mapping of validation attributes to their corresponding validators
119
+ * @summary Maps HTML validation attributes to their validator classes
120
+ * This constant maps HTML validation attributes like required, min, max, pattern, etc.
121
+ * to their corresponding validator classes from the decorator-validation library.
122
+ *
123
+ * @typedef {Object.<string, Constructor<Validator>>} ValidatableByAttributeMap
124
+ * @property {Constructor<RequiredValidator>} required - Validator for required fields
125
+ * @property {Constructor<MinValidator>} min - Validator for minimum value
126
+ * @property {Constructor<MaxValidator>} max - Validator for maximum value
127
+ * @property {Constructor<StepValidator>} step - Validator for step value
128
+ * @property {Constructor<MinLengthValidator>} minlength - Validator for minimum length
129
+ * @property {Constructor<MaxLengthValidator>} maxlength - Validator for maximum length
130
+ * @property {Constructor<PatternValidator>} pattern - Validator for regex pattern
131
+ * @property {Constructor<EqualsValidator>} equals - Validator for equality
132
+ * @property {Constructor<DiffValidator>} diff - Validator for difference
133
+ * @property {Constructor<LessThanValidator>} lessthan - Validator for less than comparison
134
+ * @property {Constructor<LessThanOrEqualValidator>} lessthanorequal - Validator for less than or equal comparison
135
+ * @property {Constructor<GreaterThanValidator>} greaterthan - Validator for greater than comparison
136
+ * @property {Constructor<GreaterThanOrEqualValidator>} greaterthanorequal - Validator for greater than or equal comparison
53
137
  *
54
- * @memberOf ui-decorators-web.ui
138
+ * @const ValidatableByAttribute
139
+ * @type {ValidatableByAttributeMap}
140
+ * @readonly
141
+ * @memberOf module:ui-decorators
55
142
  */
56
143
  const ValidatableByAttribute = {
57
144
  [UIKeys.REQUIRED]: decoratorValidation.RequiredValidator,
@@ -68,7 +155,52 @@
68
155
  [UIKeys.GREATER_THAN]: decoratorValidation.GreaterThanValidator,
69
156
  [UIKeys.GREATER_THAN_OR_EQUAL]: decoratorValidation.GreaterThanOrEqualValidator,
70
157
  };
158
+ /**
159
+ * @description Standard date format string for HTML5 date inputs
160
+ * @summary Format string for HTML5 date inputs (yyyy-MM-dd)
161
+ * This constant defines the standard date format string used for HTML5 date inputs.
162
+ *
163
+ * @const HTML5DateFormat
164
+ * @type {string}
165
+ * @readonly
166
+ * @memberOf module:ui-decorators
167
+ */
71
168
  const HTML5DateFormat = "yyyy-MM-dd";
169
+ /**
170
+ * @description Collection of HTML5 input type values
171
+ * @summary Maps input type constants to their HTML attribute values
172
+ * This constant provides a mapping of input type constants to their corresponding
173
+ * HTML attribute values for use in form elements.
174
+ *
175
+ * @typedef {Object} HTML5InputTypesMap
176
+ * @property {string} BUTTON - Button input type
177
+ * @property {string} CHECKBOX - Checkbox input type
178
+ * @property {string} COLOR - Color picker input type
179
+ * @property {string} DATE - Date picker input type
180
+ * @property {string} DATETIME_LOCAL - Local datetime picker input type
181
+ * @property {string} EMAIL - Email input type with validation
182
+ * @property {string} FILE - File upload input type
183
+ * @property {string} HIDDEN - Hidden input type
184
+ * @property {string} IMAGE - Image input type
185
+ * @property {string} MONTH - Month picker input type
186
+ * @property {string} NUMBER - Numeric input type
187
+ * @property {string} PASSWORD - Password input type with masked text
188
+ * @property {string} RADIO - Radio button input type
189
+ * @property {string} RANGE - Range slider input type
190
+ * @property {string} RESET - Form reset button input type
191
+ * @property {string} SEARCH - Search input type
192
+ * @property {string} SUBMIT - Form submit button input type
193
+ * @property {string} TEL - Telephone number input type
194
+ * @property {string} TEXT - Basic text input type
195
+ * @property {string} TIME - Time picker input type
196
+ * @property {string} URL - URL input type with validation
197
+ * @property {string} WEEK - Week picker input type
198
+ *
199
+ * @const HTML5InputTypes
200
+ * @type {HTML5InputTypesMap}
201
+ * @readonly
202
+ * @memberOf module:ui-decorators
203
+ */
72
204
  const HTML5InputTypes = {
73
205
  BUTTON: "button",
74
206
  CHECKBOX: "checkbox",
@@ -93,12 +225,51 @@
93
225
  URL: UIKeys.URL,
94
226
  WEEK: "week",
95
227
  };
228
+ /**
229
+ * @description Array of HTML5 input types that use checkboxes
230
+ * @summary List of input types that represent checkable controls
231
+ * This constant defines an array of HTML5 input types that represent
232
+ * checkable controls (checkbox and radio).
233
+ *
234
+ * @const HTML5CheckTypes
235
+ * @type {string[]}
236
+ * @readonly
237
+ * @memberOf module:ui-decorators
238
+ */
96
239
  const HTML5CheckTypes = [
97
240
  HTML5InputTypes.CHECKBOX,
98
241
  HTML5InputTypes.RADIO,
99
242
  ];
100
243
 
244
+ /**
245
+ * @description Error thrown when a rendering operation fails
246
+ * @summary Specialized error for rendering failures in UI components
247
+ * This error is thrown when the rendering engine encounters an error while
248
+ * attempting to render a UI component or model.
249
+ *
250
+ * @param {string|Error} msg The error message or original error
251
+ *
252
+ * @class RenderingError
253
+ * @extends BaseError
254
+ * @category Errors
255
+ *
256
+ * @example
257
+ * // Throwing a rendering error
258
+ * try {
259
+ * // Rendering code that might fail
260
+ * if (!component.canRender()) {
261
+ * throw new RenderingError('Component cannot be rendered');
262
+ * }
263
+ * } catch (error) {
264
+ * console.error('Rendering failed:', error.message);
265
+ * }
266
+ */
101
267
  class RenderingError extends dbDecorators.BaseError {
268
+ /**
269
+ * @description Creates a new RenderingError instance
270
+ * @summary Initializes the error with a message or original error
271
+ * @param {string|Error} msg The error message or original error
272
+ */
102
273
  constructor(msg) {
103
274
  super(RenderingError.name, msg);
104
275
  }
@@ -107,7 +278,7 @@
107
278
  /**
108
279
  * @function formatByType
109
280
  *
110
- * @memberOf ui-decorators-web.ui
281
+ * @memberOf module:ui-decorators
111
282
  */
112
283
  function formatByType(type, value, ...args) {
113
284
  if (type === UIKeys.DATE) {
@@ -340,6 +511,9 @@
340
511
  let children;
341
512
  let childProps = item?.props || {};
342
513
  let mapper = {};
514
+ const getPath = (parent, prop) => {
515
+ return parent ? [parent, prop].join(".") : prop;
516
+ };
343
517
  if (uiDecorators) {
344
518
  const validationDecorators = reflection.Reflection.getAllPropertyDecorators(model, decoratorValidation.ValidationKeys.REFLECT);
345
519
  for (const key in uiDecorators) {
@@ -365,7 +539,10 @@
365
539
  if (!constructable)
366
540
  Clazz = new (decoratorValidation.Model.get(dec.props?.name))();
367
541
  children = children || [];
368
- const childDefinition = this.toFieldDefinition(submodel || Clazz, globalProps, false);
542
+ const childrenGlobalProps = Object.assign({}, globalProps || {}, {
543
+ childOf: getPath(globalProps?.childOf, key),
544
+ });
545
+ const childDefinition = this.toFieldDefinition(submodel || Clazz, childrenGlobalProps, false);
369
546
  children.push(childDefinition);
370
547
  break;
371
548
  }
@@ -381,9 +558,14 @@
381
558
  }
382
559
  case UIKeys.ELEMENT: {
383
560
  children = children || [];
561
+ const uiProps = dec.props;
562
+ const props = Object.assign({}, uiProps.props, {
563
+ path: getPath(globalProps?.childOf, uiProps.props.name),
564
+ childOf: undefined, // The childOf prop is passed by globalProps when it is a nested prop
565
+ }, globalProps);
384
566
  const childDefinition = {
385
- tag: dec.props.tag,
386
- props: Object.assign({}, dec.props.props, globalProps),
567
+ tag: uiProps.tag,
568
+ props,
387
569
  };
388
570
  const validationDecs = validationDecorators[key];
389
571
  const typeDec = validationDecs.shift();
@@ -512,13 +694,35 @@
512
694
  }
513
695
 
514
696
  /**
515
- * Tags the model as a uimodel, giving it the 'render' method
697
+ * @description Decorator that tags a class as a UI model
698
+ * @summary Adds rendering capabilities to a model class by providing a render method
699
+ * This decorator applies metadata to the class that enables it to be rendered by the UI rendering engine.
700
+ * The model will be rendered with the specified tag and properties.
701
+ *
702
+ * @param {string} [tag] The HTML tag to use when rendering this model (defaults to class name)
703
+ * @param {Record<string, any>} [props] Additional properties to pass to the rendered element
704
+ * @return {Function} A class decorator function
516
705
  *
517
- * @param {string} [tag] optional param. will render the provided elment wrapping the attribute uielements
518
- * @param {{}} [props] optional param. Attributes to be passed to the tag element
519
- * @param {function(any): void} [instanceCallback] optional callback returning the instance after creation for additional logic
706
+ * @function uimodel
707
+ * @category Class Decorators
520
708
  *
521
- * @decorator uimodel
709
+ * @example
710
+ * // Basic usage with default tag (class name)
711
+ * @uimodel()
712
+ * class UserProfile extends Model {
713
+ * @attribute()
714
+ * name: string;
715
+ *
716
+ * @attribute()
717
+ * email: string;
718
+ * }
719
+ *
720
+ * // Usage with custom tag and properties
721
+ * @uimodel('div', { class: 'user-card' })
722
+ * class UserCard extends Model {
723
+ * @attribute()
724
+ * username: string;
725
+ * }
522
726
  *
523
727
  * @mermaid
524
728
  * sequenceDiagram
@@ -531,8 +735,6 @@
531
735
  * constructor->>uimodel: returns instance
532
736
  * uimodel->>instance: adds the render method
533
737
  * uimodel->>System: returns UIModel instance
534
- *
535
- * @category Decorators
536
738
  */
537
739
  function uimodel(tag, props) {
538
740
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
@@ -544,27 +746,85 @@
544
746
  return reflection.metadata(RenderingEngine.key(UIKeys.UIMODEL), meta)(original);
545
747
  };
546
748
  }
749
+ /**
750
+ * @description Decorator that specifies which rendering engine to use for a model
751
+ * @summary Associates a model with a specific rendering engine implementation
752
+ * This decorator allows you to override the default rendering engine for a specific model class,
753
+ * enabling different rendering strategies for different models.
754
+ *
755
+ * @param {string} engine The name of the rendering engine to use
756
+ * @return {Function} A class decorator function
757
+ *
758
+ * @function renderedBy
759
+ * @category Class Decorators
760
+ *
761
+ * @example
762
+ * // Specify a custom rendering engine for a model
763
+ * @uimodel()
764
+ * @renderedBy('react')
765
+ * class ReactComponent extends Model {
766
+ * @attribute()
767
+ * title: string;
768
+ * }
769
+ *
770
+ * @mermaid
771
+ * sequenceDiagram
772
+ * participant System
773
+ * participant renderedBy
774
+ * participant Model
775
+ * participant RenderingEngine
776
+ * System->>renderedBy: apply to Model
777
+ * renderedBy->>Model: adds engine metadata
778
+ * Model->>RenderingEngine: uses specified engine
779
+ * RenderingEngine->>System: renders with custom engine
780
+ */
547
781
  function renderedBy(engine) {
548
782
  return reflection.apply(reflection.metadata(RenderingEngine.key(UIKeys.RENDERED_BY), engine));
549
783
  }
550
784
  /**
551
- * Tags the model as a list item for UI rendering, specifying how it should be rendered in list contexts
785
+ * @description Decorator that tags a model as a list item for UI rendering
786
+ * @summary Specifies how a model should be rendered when displayed in a list context
787
+ * This decorator applies metadata to the class that enables it to be rendered as a list item
788
+ * by the UI rendering engine. The model will be rendered with the specified tag and properties
789
+ * when it appears in a list.
790
+ *
791
+ * @param {string} [tag] The HTML tag to use when rendering this model as a list item (defaults to class name)
792
+ * @param {Record<string, any>} [props] Additional properties to pass to the rendered list item element
793
+ * @return {Function} A class decorator function
552
794
  *
553
- * @param {string} [tag] optional param. will render the provided element as the list item container
554
- * @param {{}} [props] optional param. Attributes to be passed to the tag element
795
+ * @function uilistitem
796
+ * @category Class Decorators
555
797
  *
556
- * @decorator uilistitem
798
+ * @example
799
+ * // Basic usage with default tag (class name)
800
+ * @uimodel()
801
+ * @uilistitem()
802
+ * class TodoItem extends Model {
803
+ * @attribute()
804
+ * title: string;
805
+ *
806
+ * @attribute()
807
+ * completed: boolean;
808
+ * }
809
+ *
810
+ * // Usage with custom tag and properties
811
+ * @uimodel()
812
+ * @uilistitem('li', { class: 'list-group-item' })
813
+ * class ListItem extends Model {
814
+ * @attribute()
815
+ * text: string;
816
+ * }
557
817
  *
558
818
  * @mermaid
559
819
  * sequenceDiagram
560
820
  * participant System
561
821
  * participant uilistitem
562
822
  * participant Model
823
+ * participant RenderingEngine
563
824
  * System->>uilistitem: apply to Model
564
825
  * uilistitem->>Model: adds list item metadata
565
- * Model->>System: returns Model with list item rendering capabilities
566
- *
567
- * @category Decorators
826
+ * Model->>RenderingEngine: uses list item metadata when in list context
827
+ * RenderingEngine->>System: renders with list item styling
568
828
  */
569
829
  function uilistitem(tag, props) {
570
830
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
@@ -573,61 +833,206 @@
573
833
  item: {
574
834
  tag: tag || original.name,
575
835
  props: props,
576
- }
836
+ },
577
837
  };
578
838
  return reflection.metadata(RenderingEngine.key(UIKeys.UILISTITEM), meta)(original);
579
839
  };
580
840
  }
581
841
 
842
+ /**
843
+ * @description Module that extends the Model prototype with rendering capabilities
844
+ * @summary Adds the render method to all Model instances from decorator-validation
845
+ * This module implements the Renderable interface for the Model class by adding a render method
846
+ * to its prototype. This allows any Model instance to be rendered using the RenderingEngine.
847
+ * @module model/overrides
848
+ * @memberOf module:ui-decorators/model
849
+ */
850
+ /**
851
+ * @description Renders the model using the appropriate rendering engine
852
+ * @summary Delegates rendering to the RenderingEngine based on model metadata
853
+ * This method implements the render method from the Renderable interface for all Model instances.
854
+ * It uses the RenderingEngine to determine how to render the model based on its metadata.
855
+ *
856
+ * @template M Type of the model being rendered
857
+ * @param {any[]} args Additional arguments to pass to the rendering engine
858
+ * @return {any} The rendered output in the format determined by the rendering engine
859
+ */
582
860
  decoratorValidation.Model.prototype.render = function (...args) {
583
861
  return RenderingEngine.render(this, ...args);
584
862
  };
585
863
 
586
864
  /**
587
- * @namespace ui-decorators.ui.decorators
588
- * @memberOf ui-decorators.ui
865
+ * @description Decorator that hides a property during specific CRUD operations
866
+ * @summary Controls property visibility based on operation type
867
+ * This decorator allows you to specify which CRUD operations should hide a property
868
+ * in the UI. The property will only be visible during operations not specified.
869
+ *
870
+ * @param operations - The CRUD operations during which the property should be hidden
871
+ * @return {Function} A property decorator function
872
+ *
873
+ * @function hideOn
874
+ * @category Property Decorators
875
+ *
876
+ * @example
877
+ * // Hide the password field during READ operations
878
+ * class User {
879
+ * @attribute()
880
+ * username: string;
881
+ *
882
+ * @attribute()
883
+ * @hideOn(OperationKeys.READ)
884
+ * password: string;
885
+ * }
886
+ *
887
+ * @mermaid
888
+ * sequenceDiagram
889
+ * participant Model
890
+ * participant hideOn
891
+ * participant RenderingEngine
892
+ * participant UI
893
+ * Model->>hideOn: Apply to property
894
+ * hideOn->>Model: Add hidden metadata
895
+ * RenderingEngine->>Model: Check if property should be hidden
896
+ * Model->>RenderingEngine: Return hidden operations
897
+ * RenderingEngine->>UI: Render or hide based on current operation
589
898
  */
590
899
  function hideOn(...operations) {
591
900
  return decoratorValidation.propMetadata(RenderingEngine.key(UIKeys.HIDDEN), operations);
592
901
  }
902
+ /**
903
+ * @description Decorator that completely hides a property in all UI operations
904
+ * @summary Makes a property invisible in all CRUD operations
905
+ * This decorator is a convenience wrapper around hideOn that hides a property
906
+ * during all CRUD operations (CREATE, READ, UPDATE, DELETE).
907
+ *
908
+ * @return {Function} A property decorator function
909
+ *
910
+ * @function hidden
911
+ * @category Property Decorators
912
+ *
913
+ * @example
914
+ * // Completely hide the internalId field in the UI
915
+ * class Product {
916
+ * @attribute()
917
+ * name: string;
918
+ *
919
+ * @attribute()
920
+ * @hidden()
921
+ * internalId: string;
922
+ * }
923
+ *
924
+ * @mermaid
925
+ * sequenceDiagram
926
+ * participant Model
927
+ * participant hidden
928
+ * participant hideOn
929
+ * participant RenderingEngine
930
+ * Model->>hidden: Apply to property
931
+ * hidden->>hideOn: Call with all operations
932
+ * hideOn->>Model: Add hidden metadata
933
+ * RenderingEngine->>Model: Check if property should be hidden
934
+ * Model->>RenderingEngine: Return all operations
935
+ * RenderingEngine->>UI: Always hide property
936
+ */
593
937
  function hidden() {
594
938
  return hideOn(dbDecorators.OperationKeys.CREATE, dbDecorators.OperationKeys.READ, dbDecorators.OperationKeys.UPDATE, dbDecorators.OperationKeys.DELETE);
595
939
  }
596
940
  /**
597
- * Adds the UIElement definition as metadata to the property, allowing it to be read by any {@link RenderStrategy}
941
+ * @description Decorator that specifies how a property should be rendered as a UI element
942
+ * @summary Maps a model property to a specific UI element with custom properties
943
+ * This decorator allows you to define which HTML element or component should be used
944
+ * to render a specific property, along with any additional properties to pass to that element.
598
945
  *
599
- * @param {string} tag The component/HTML element tag name
600
- * @param {{}} [props] The properties to pass to that component/HTML Element
601
- * @param serialize
946
+ * @param {string} tag The HTML element or component tag name to use for rendering
947
+ * @param {Record<string, any>} [props] Additional properties to pass to the element
948
+ * @param {boolean} [serialize=false] Whether the property should be serialized
949
+ * @return {Function} A property decorator function
602
950
  *
603
- * @decorator uielement
951
+ * @function uielement
952
+ * @category Property Decorators
604
953
  *
605
- * @category Decorators
606
- * @subcategory ui-decorators
954
+ * @example
955
+ * // Render a property as a text input
956
+ * class LoginForm {
957
+ * @attribute()
958
+ * @uielement('input', { type: 'text', placeholder: 'Enter username' })
959
+ * username: string;
960
+ *
961
+ * @attribute()
962
+ * @uielement('input', { type: 'password', placeholder: 'Enter password' })
963
+ * password: string;
964
+ *
965
+ * @attribute()
966
+ * @uielement('button', { class: 'btn-primary' })
967
+ * submit: string = 'Login';
968
+ * }
969
+ *
970
+ * @mermaid
971
+ * sequenceDiagram
972
+ * participant Model
973
+ * participant uielement
974
+ * participant RenderingEngine
975
+ * participant UI
976
+ * Model->>uielement: Apply to property
977
+ * uielement->>Model: Add element metadata
978
+ * RenderingEngine->>Model: Get element metadata
979
+ * Model->>RenderingEngine: Return tag and props
980
+ * RenderingEngine->>UI: Render with specified element
607
981
  */
608
982
  function uielement(tag, props, serialize = false) {
609
983
  return (original, propertyKey) => {
610
984
  const metadata = {
611
985
  tag: tag,
612
986
  serialize: serialize,
613
- props: Object.assign({
987
+ props: Object.assign({}, props || {}, {
614
988
  name: propertyKey,
615
- }, props || {}),
989
+ }),
616
990
  };
617
991
  return decoratorValidation.propMetadata(RenderingEngine.key(UIKeys.ELEMENT), metadata)(original, propertyKey);
618
992
  };
619
993
  }
620
994
  /**
621
- * Adds the UIProp definition as metadata to the property, allowing it to be read by any {@link RenderStrategy}
995
+ * @description Decorator that maps a model property to a UI component property
996
+ * @summary Specifies how a property should be passed to a UI component
997
+ * This decorator allows you to define how a model property should be mapped to
998
+ * a property of the UI component when rendering. It requires the class to be
999
+ * decorated with @uimodel.
622
1000
  *
623
- * this requires a '@uimodel' with a defined tag
1001
+ * @param {string} [propName] The name of the property to pass to the component (defaults to the property key)
1002
+ * @param {boolean} [stringify=false] Whether to stringify the property value
1003
+ * @return {Function} A property decorator function
624
1004
  *
625
- * @param {string} [propName] the property name that will be passed to the component. defaults to the PropertyKey
1005
+ * @function uiprop
1006
+ * @category Property Decorators
626
1007
  *
627
- * @decorator uiprop
1008
+ * @example
1009
+ * // Map model properties to component properties
1010
+ * @uimodel('user-profile')
1011
+ * class UserProfile {
1012
+ * @attribute()
1013
+ * @uiprop() // Will be passed as 'fullName' to the component
1014
+ * fullName: string;
628
1015
  *
629
- * @category Decorators
630
- * @subcategory ui-decorators
1016
+ * @attribute()
1017
+ * @uiprop('userEmail') // Will be passed as 'userEmail' to the component
1018
+ * email: string;
1019
+ *
1020
+ * @attribute()
1021
+ * @uiprop('userData', true) // Will be passed as stringified JSON
1022
+ * userData: Record<string, any>;
1023
+ * }
1024
+ *
1025
+ * @mermaid
1026
+ * sequenceDiagram
1027
+ * participant Model
1028
+ * participant uiprop
1029
+ * participant RenderingEngine
1030
+ * participant Component
1031
+ * Model->>uiprop: Apply to property
1032
+ * uiprop->>Model: Add prop metadata
1033
+ * RenderingEngine->>Model: Get prop metadata
1034
+ * Model->>RenderingEngine: Return prop name and stringify flag
1035
+ * RenderingEngine->>Component: Pass property with specified name
631
1036
  */
632
1037
  function uiprop(propName = undefined, stringify = false) {
633
1038
  return (target, propertyKey) => {
@@ -639,37 +1044,78 @@
639
1044
  };
640
1045
  }
641
1046
  /**
642
- * Adds the UIListProp definition as metadata to the property, allowing it to be read by any {@link RenderStrategy}
1047
+ * @description Decorator that maps a model property to a list item component
1048
+ * @summary Specifies how a property should be rendered in a list context
1049
+ * This decorator allows you to define how a model property containing a list
1050
+ * should be rendered. It requires the class to be decorated with @uilistitem.
1051
+ *
1052
+ * @param {string} [propName] The name of the property to pass to the list component (defaults to the property key)
1053
+ * @param {Record<string, any>} [props] Additional properties to pass to the list container
1054
+ * @return {Function} A property decorator function
643
1055
  *
644
- * this requires a '@uilistitem' with a defined tag
1056
+ * @function uilistprop
1057
+ * @category Property Decorators
645
1058
  *
646
- * @param {string} [propName] the property name that will be passed to the component. defaults to the PropertyKey
1059
+ * @example
1060
+ * // Define a list property with custom rendering
1061
+ * @uimodel('todo-list')
1062
+ * class TodoList {
1063
+ * @attribute()
1064
+ * title: string;
647
1065
  *
648
- * @decorator uiprop
1066
+ * @attribute()
1067
+ * @uilistprop('items', { class: 'todo-items-container' })
1068
+ * items: TodoItem[];
1069
+ * }
649
1070
  *
650
- * @category Decorators
651
- * @subcategory ui-decorators
1071
+ * @uilistitem('li', { class: 'todo-item' })
1072
+ * class TodoItem extends Model {
1073
+ * @attribute()
1074
+ * text: string;
1075
+ *
1076
+ * @attribute()
1077
+ * completed: boolean;
1078
+ * }
1079
+ *
1080
+ * @mermaid
1081
+ * sequenceDiagram
1082
+ * participant Model
1083
+ * participant uilistprop
1084
+ * participant RenderingEngine
1085
+ * participant ListContainer
1086
+ * participant ListItems
1087
+ * Model->>uilistprop: Apply to property
1088
+ * uilistprop->>Model: Add list prop metadata
1089
+ * RenderingEngine->>Model: Get list prop metadata
1090
+ * Model->>RenderingEngine: Return prop name and container props
1091
+ * RenderingEngine->>ListContainer: Create container with props
1092
+ * RenderingEngine->>ListItems: Render each item using @uilistitem
1093
+ * ListContainer->>RenderingEngine: Return rendered list
652
1094
  */
653
1095
  function uilistprop(propName = undefined, props) {
654
1096
  return (target, propertyKey) => {
655
1097
  const metadata = {
656
1098
  name: propName || propertyKey,
657
- props: props || {}
1099
+ props: props || {},
658
1100
  };
659
1101
  decoratorValidation.propMetadata(RenderingEngine.key(UIKeys.UILISTPROP), metadata)(target, propertyKey);
660
1102
  };
661
1103
  }
662
1104
 
663
1105
  /**
1106
+ * @description UI decorators module for TypeScript applications
1107
+ * @summary A collection of decorators and utilities for building UI components in TypeScript applications.
1108
+ * This module exports functionality from both the model and UI submodules, providing decorators for
1109
+ * rendering, component definition, and UI state management.
664
1110
  * @module ui-decorators
665
1111
  */
666
1112
  /**
667
- * @summary stores the current package version
668
- * @description this is how you should document a constant
1113
+ * @description Current package version string
1114
+ * @summary Stores the current package version for reference
669
1115
  * @const VERSION
670
1116
  * @memberOf module:ui-decorators
671
1117
  */
672
- const VERSION = "0.5.9";
1118
+ const VERSION = "0.5.10";
673
1119
 
674
1120
  exports.HTML5CheckTypes = HTML5CheckTypes;
675
1121
  exports.HTML5DateFormat = HTML5DateFormat;
@@ -696,4 +1142,4 @@
696
1142
  exports.uiprop = uiprop;
697
1143
 
698
1144
  }));
699
- //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidWktZGVjb3JhdG9ycy5janMiLCJzb3VyY2VzIjpbIi4uL3NyYy91aS9jb25zdGFudHMudHMiLCIuLi9zcmMvdWkvZXJyb3JzLnRzIiwiLi4vc3JjL3VpL3V0aWxzLnRzIiwiLi4vc3JjL3VpL1JlbmRlcmluZy50cyIsIi4uL3NyYy9tb2RlbC9kZWNvcmF0b3JzLnRzIiwiLi4vc3JjL21vZGVsL292ZXJyaWRlcy50cyIsIi4uL3NyYy91aS9kZWNvcmF0b3JzLnRzIiwiLi4vc3JjL2luZGV4LnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gIENvbnN0cnVjdG9yLFxuICBEYXRlVmFsaWRhdG9yLFxuICBEaWZmVmFsaWRhdG9yLFxuICBFbWFpbFZhbGlkYXRvcixcbiAgRXF1YWxzVmFsaWRhdG9yLFxuICBHcmVhdGVyVGhhbk9yRXF1YWxWYWxpZGF0b3IsXG4gIEdyZWF0ZXJUaGFuVmFsaWRhdG9yLFxuICBMZXNzVGhhbk9yRXF1YWxWYWxpZGF0b3IsXG4gIExlc3NUaGFuVmFsaWRhdG9yLFxuICBNYXhMZW5ndGhWYWxpZGF0b3IsXG4gIE1heFZhbGlkYXRvcixcbiAgTWluTGVuZ3RoVmFsaWRhdG9yLFxuICBNaW5WYWxpZGF0b3IsXG4gIE1vZGVsS2V5cyxcbiAgUGFzc3dvcmRWYWxpZGF0b3IsXG4gIFBhdHRlcm5WYWxpZGF0b3IsXG4gIFJlcXVpcmVkVmFsaWRhdG9yLFxuICBTdGVwVmFsaWRhdG9yLFxuICBVUkxWYWxpZGF0b3IsXG4gIFZhbGlkYXRpb25LZXlzLFxuICBWYWxpZGF0b3IsXG59IGZyb20gXCJAZGVjYWYtdHMvZGVjb3JhdG9yLXZhbGlkYXRpb25cIjtcblxuLyoqXG4gKiBAZW51bSBVSUtleXNcbiAqIEBjYXRlZ29yeSBDb25zdGFudHNcbiAqL1xuZXhwb3J0IGNvbnN0IFVJS2V5cyA9IHtcbiAgUkVGTEVDVDogYCR7TW9kZWxLZXlzLlJFRkxFQ1R9LnVpLmAsXG4gIFVJTU9ERUw6IFwidWltb2RlbFwiLFxuICBSRU5ERVJFRF9CWTogXCJyZW5kZXJlZC1ieVwiLFxuICBFTEVNRU5UOiBcImVsZW1lbnRcIixcbiAgUFJPUDogXCJwcm9wXCIsXG4gIE5BTUU6IFwibmFtZVwiLFxuICBOQU1FX1BSRUZJWDogXCJpbnB1dC1cIixcbiAgQ1VTVE9NX1BST1BTOiBcImN1c3RvbVZhbGlkYXRpb25Qcm9wc1wiLFxuXG4gIFVJTElTVElURU06IFwidWlsaXN0aXRlbVwiLFxuICBVSUxJU1RQUk9QOiBcImxpc3Rwcm9wXCIsXG5cbiAgVFlQRTogXCJ0eXBlXCIsXG4gIFNVQl9UWVBFOiBcInN1YnR5cGVcIixcblxuICBISURERU46IFwiaGlkZGVuXCIsXG4gIEZPUk1BVDogXCJmb3JtYXRcIixcblxuICBSRUFEX09OTFk6IFwicmVhZG9ubHlcIixcbiAgUkVRVUlSRUQ6IFZhbGlkYXRpb25LZXlzLlJFUVVJUkVELFxuICBNSU46IFZhbGlkYXRpb25LZXlzLk1JTixcbiAgTUlOX0xFTkdUSDogVmFsaWRhdGlvbktleXMuTUlOX0xFTkdUSCxcbiAgTUFYOiBWYWxpZGF0aW9uS2V5cy5NQVgsXG4gIE1BWF9MRU5HVEg6IFZhbGlkYXRpb25LZXlzLk1BWF9MRU5HVEgsXG4gIFBBVFRFUk46IFZhbGlkYXRpb25LZXlzLlBBVFRFUk4sXG4gIFVSTDogVmFsaWRhdGlvbktleXMuVVJMLFxuICBTVEVQOiBWYWxpZGF0aW9uS2V5cy5TVEVQLFxuICBEQVRFOiBWYWxpZGF0aW9uS2V5cy5EQVRFLFxuICBFTUFJTDogVmFsaWRhdGlvbktleXMuRU1BSUwsXG4gIFBBU1NXT1JEOiBWYWxpZGF0aW9uS2V5cy5QQVNTV09SRCxcbiAgRVFVQUxTOiBWYWxpZGF0aW9uS2V5cy5FUVVBTFMsXG4gIERJRkY6IFZhbGlkYXRpb25LZXlzLkRJRkYsXG4gIExFU1NfVEhBTjogVmFsaWRhdGlvbktleXMuTEVTU19USEFOLFxuICBMRVNTX1RIQU5fT1JfRVFVQUw6IFZhbGlkYXRpb25LZXlzLkxFU1NfVEhBTl9PUl9FUVVBTCxcbiAgR1JFQVRFUl9USEFOOiBWYWxpZGF0aW9uS2V5cy5HUkVBVEVSX1RIQU4sXG4gIEdSRUFURVJfVEhBTl9PUl9FUVVBTDogVmFsaWRhdGlvbktleXMuR1JFQVRFUl9USEFOX09SX0VRVUFMLFxufTtcblxuZXhwb3J0IGNvbnN0IFZhbGlkYXRhYmxlQnlUeXBlOiBSZWNvcmQ8c3RyaW5nLCBDb25zdHJ1Y3RvcjxWYWxpZGF0b3I+PiA9IHtcbiAgW1VJS2V5cy5FTUFJTF06IEVtYWlsVmFsaWRhdG9yLFxuICBbVUlLZXlzLlVSTF06IFVSTFZhbGlkYXRvcixcbiAgW1VJS2V5cy5EQVRFXTogRGF0ZVZhbGlkYXRvcixcbiAgW1VJS2V5cy5QQVNTV09SRF06IFBhc3N3b3JkVmFsaWRhdG9yLFxufTtcblxuLyoqXG4gKiBAY29uc3RhbnQgVmFsaWRhdGFibGVCeUF0dHJpYnV0ZVxuICpcbiAqIEBtZW1iZXJPZiB1aS1kZWNvcmF0b3JzLXdlYi51aVxuICovXG5leHBvcnQgY29uc3QgVmFsaWRhdGFibGVCeUF0dHJpYnV0ZTogUmVjb3JkPHN0cmluZywgQ29uc3RydWN0b3I8VmFsaWRhdG9yPj4gPSB7XG4gIFtVSUtleXMuUkVRVUlSRURdOiBSZXF1aXJlZFZhbGlkYXRvcixcbiAgW1VJS2V5cy5NSU5dOiBNaW5WYWxpZGF0b3IsXG4gIFtVSUtleXMuTUFYXTogTWF4VmFsaWRhdG9yLFxuICBbVUlLZXlzLlNURVBdOiBTdGVwVmFsaWRhdG9yLFxuICBbVUlLZXlzLk1JTl9MRU5HVEhdOiBNaW5MZW5ndGhWYWxpZGF0b3IsXG4gIFtVSUtleXMuTUFYX0xFTkdUSF06IE1heExlbmd0aFZhbGlkYXRvcixcbiAgW1VJS2V5cy5QQVRURVJOXTogUGF0dGVyblZhbGlkYXRvcixcbiAgW1VJS2V5cy5FUVVBTFNdOiBFcXVhbHNWYWxpZGF0b3IsXG4gIFtVSUtleXMuRElGRl06IERpZmZWYWxpZGF0b3IsXG4gIFtVSUtleXMuTEVTU19USEFOXTogTGVzc1RoYW5WYWxpZGF0b3IsXG4gIFtVSUtleXMuTEVTU19USEFOX09SX0VRVUFMXTogTGVzc1RoYW5PckVxdWFsVmFsaWRhdG9yLFxuICBbVUlLZXlzLkdSRUFURVJfVEhBTl06IEdyZWF0ZXJUaGFuVmFsaWRhdG9yLFxuICBbVUlLZXlzLkdSRUFURVJfVEhBTl9PUl9FUVVBTF06IEdyZWF0ZXJUaGFuT3JFcXVhbFZhbGlkYXRvcixcbn07XG5cbmV4cG9ydCBjb25zdCBIVE1MNURhdGVGb3JtYXQgPSBcInl5eXktTU0tZGRcIjtcblxuZXhwb3J0IGNvbnN0IEhUTUw1SW5wdXRUeXBlcyA9IHtcbiAgQlVUVE9OOiBcImJ1dHRvblwiLFxuICBDSEVDS0JPWDogXCJjaGVja2JveFwiLFxuICBDT0xPUjogXCJjb2xvclwiLFxuICBEQVRFOiBVSUtleXMuREFURSxcbiAgREFURVRJTUVfTE9DQUw6IFwiZGF0ZXRpbWUtbG9jYWxcIixcbiAgRU1BSUw6IFVJS2V5cy5FTUFJTCxcbiAgRklMRTogXCJmaWxlXCIsXG4gIEhJRERFTjogXCJoaWRkZW5cIixcbiAgSU1BR0U6IFwiaW1hZ2VcIixcbiAgTU9OVEg6IFwibW9udGhcIixcbiAgTlVNQkVSOiBcIm51bWJlclwiLFxuICBQQVNTV09SRDogVUlLZXlzLlBBU1NXT1JELFxuICBSQURJTzogXCJyYWRpb1wiLFxuICBSQU5HRTogXCJyYW5nZVwiLFxuICBSRVNFVDogXCJyZXNldFwiLFxuICBTRUFSQ0g6IFwic2VhcmNoXCIsXG4gIFNVQk1JVDogXCJzdWJtaXRcIixcbiAgVEVMOiBcInRlbFwiLFxuICBURVhUOiBcInRleHRcIixcbiAgVElNRTogXCJ0aW1lXCIsXG4gIFVSTDogVUlLZXlzLlVSTCxcbiAgV0VFSzogXCJ3ZWVrXCIsXG59O1xuXG5leHBvcnQgY29uc3QgSFRNTDVDaGVja1R5cGVzID0gW1xuICBIVE1MNUlucHV0VHlwZXMuQ0hFQ0tCT1gsXG4gIEhUTUw1SW5wdXRUeXBlcy5SQURJTyxcbl07XG4iLCJpbXBvcnQgeyBCYXNlRXJyb3IgfSBmcm9tIFwiQGRlY2FmLXRzL2RiLWRlY29yYXRvcnNcIjtcblxuZXhwb3J0IGNsYXNzIFJlbmRlcmluZ0Vycm9yIGV4dGVuZHMgQmFzZUVycm9yIHtcbiAgY29uc3RydWN0b3IobXNnOiBzdHJpbmcgfCBFcnJvcikge1xuICAgIHN1cGVyKFJlbmRlcmluZ0Vycm9yLm5hbWUsIG1zZyk7XG4gIH1cbn1cbiIsImltcG9ydCB7XG4gIGZvcm1hdERhdGUsXG4gIE1vZGVsLFxuICBwYXJzZURhdGUsXG4gIFJlc2VydmVkTW9kZWxzLFxufSBmcm9tIFwiQGRlY2FmLXRzL2RlY29yYXRvci12YWxpZGF0aW9uXCI7XG5pbXBvcnQgeyBIVE1MNURhdGVGb3JtYXQsIEhUTUw1SW5wdXRUeXBlcywgVUlLZXlzIH0gZnJvbSBcIi4vY29uc3RhbnRzXCI7XG5pbXBvcnQgeyBmaW5kTW9kZWxJZCwgSW50ZXJuYWxFcnJvciB9IGZyb20gXCJAZGVjYWYtdHMvZGItZGVjb3JhdG9yc1wiO1xuaW1wb3J0IHsgRmllbGRQcm9wZXJ0aWVzIH0gZnJvbSBcIi4vdHlwZXNcIjtcblxuLyoqXG4gKiBAZnVuY3Rpb24gZm9ybWF0QnlUeXBlXG4gKlxuICogQG1lbWJlck9mIHVpLWRlY29yYXRvcnMtd2ViLnVpXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBmb3JtYXRCeVR5cGUoXG4gIHR5cGU6IGFueSxcbiAgdmFsdWU6IGFueSxcbiAgLi4uYXJnczogdW5rbm93bltdXG4pOiBzdHJpbmcgfCBudW1iZXIge1xuICBpZiAodHlwZSA9PT0gVUlLZXlzLkRBVEUpIHtcbiAgICBjb25zdCBmb3JtYXQ6IHN0cmluZyA9IChhcmdzLnNoaWZ0KCkgYXMgc3RyaW5nKSB8fCBIVE1MNURhdGVGb3JtYXQ7XG4gICAgcmV0dXJuIGZvcm1hdERhdGUobmV3IERhdGUodmFsdWUpLCBmb3JtYXQpO1xuICB9XG4gIHJldHVybiB2YWx1ZTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHBhcnNlVmFsdWVCeVR5cGUoXG4gIHR5cGU6IHN0cmluZyxcbiAgdmFsdWU6IHN0cmluZyB8IG51bWJlcixcbiAgZmllbGRQcm9wczogRmllbGRQcm9wZXJ0aWVzXG4pOiBzdHJpbmcgfCBudW1iZXIgfCBEYXRlIHtcbiAgbGV0IHJlc3VsdDogc3RyaW5nIHwgbnVtYmVyIHwgRGF0ZSB8IHVuZGVmaW5lZCA9IHVuZGVmaW5lZDtcbiAgc3dpdGNoICh0eXBlKSB7XG4gICAgY2FzZSBIVE1MNUlucHV0VHlwZXMuTlVNQkVSOlxuICAgICAgcmVzdWx0ID0gcGFyc2VUb051bWJlcih2YWx1ZSk7XG4gICAgICBicmVhaztcbiAgICBjYXNlIEhUTUw1SW5wdXRUeXBlcy5EQVRFOiB7XG4gICAgICBjb25zdCBmb3JtYXQ6IHN0cmluZyB8IHVuZGVmaW5lZCA9IGZpZWxkUHJvcHMuZm9ybWF0O1xuICAgICAgcmVzdWx0ID1cbiAgICAgICAgdHlwZW9mIHZhbHVlID09PSBSZXNlcnZlZE1vZGVscy5OVU1CRVJcbiAgICAgICAgICA/IG5ldyBEYXRlKHZhbHVlKVxuICAgICAgICAgIDogdmFsdWVcbiAgICAgICAgICAgID8gZm9ybWF0XG4gICAgICAgICAgICAgID8gcGFyc2VEYXRlKGZvcm1hdCwgdmFsdWUpXG4gICAgICAgICAgICAgIDogbmV3IERhdGUodmFsdWUpXG4gICAgICAgICAgICA6IHVuZGVmaW5lZDtcbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgICBkZWZhdWx0OlxuICAgICAgcmVzdWx0ID1cbiAgICAgICAgdHlwZW9mIHZhbHVlID09PSBSZXNlcnZlZE1vZGVscy5TVFJJTkdcbiAgICAgICAgICA/IGVzY2FwZUh0bWwodmFsdWUgYXMgc3RyaW5nKVxuICAgICAgICAgIDogcmVzdWx0O1xuICB9XG4gIGlmICh0eXBlb2YgcmVzdWx0ID09PSBcInVuZGVmaW5lZFwiKSB7XG4gICAgdGhyb3cgbmV3IEludGVybmFsRXJyb3IoXG4gICAgICBgRmFpbGVkIHRvIHBhcnNlIHZhbHVlIG9mIHR5cGUgJHt0eXBlfSBmcm9tICR7dHlwZW9mIHZhbHVlfSAtICR7dmFsdWV9YFxuICAgICk7XG4gIH1cbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHBhcnNlVG9OdW1iZXIodmFsdWU6IHN0cmluZyB8IG51bWJlcikge1xuICBpZiAodHlwZW9mIHZhbHVlID09PSBcIm51bWJlclwiICYmICFpc05hTih2YWx1ZSkpIHJldHVybiB2YWx1ZTtcblxuICBjb25zdCBwYXJzZWQgPSBOdW1iZXIodmFsdWUpO1xuICBpZiAoIWlzTmFOKHBhcnNlZCkpIHJldHVybiBwYXJzZWQ7XG5cbiAgcmV0dXJuIHVuZGVmaW5lZDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGVzY2FwZUh0bWwodmFsdWU6IHN0cmluZykge1xuICBpZiAoIXZhbHVlKSByZXR1cm4gdmFsdWU7XG5cbiAgY29uc3QgdGFnc1RvUmVwbGFjZTogUmVjb3JkPHN0cmluZywgc3RyaW5nPiA9IHtcbiAgICBcIiZcIjogXCImYW1wO1wiLFxuICAgIFwiPFwiOiBcIiZsdDtcIixcbiAgICBcIj5cIjogXCImZ3Q7XCIsXG4gIH07XG4gIHJldHVybiBgJHt2YWx1ZX1gLnJlcGxhY2UoL1smPD5dL2csICh0YWcpID0+IHtcbiAgICByZXR1cm4gdGFnc1RvUmVwbGFjZVt0YWddIHx8IHRhZztcbiAgfSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiByZXZlcnRIdG1sKHZhbHVlOiBzdHJpbmcpIHtcbiAgY29uc3QgdGFnc1RvUmVwbGFjZTogUmVjb3JkPHN0cmluZywgc3RyaW5nPiA9IHtcbiAgICBcIiZhbXA7XCI6IFwiJlwiLFxuICAgIFwiJmx0O1wiOiBcIjxcIixcbiAgICBcIiZndDtcIjogXCI+XCIsXG4gIH07XG5cbiAgcmV0dXJuIGAke3ZhbHVlfWAucmVwbGFjZSgvJmx0O3wmZ3Q7fCZhbXA7L2csICh0YWcpID0+IHtcbiAgICByZXR1cm4gdGFnc1RvUmVwbGFjZVt0YWddIHx8IHRhZztcbiAgfSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZW5lcmF0ZVVJTW9kZWxJRDxNIGV4dGVuZHMgTW9kZWw+KG1vZGVsOiBNKSB7XG4gIGxldCBpZDogc3RyaW5nIHwgbnVtYmVyIHwgYmlnaW50O1xuICB0cnkge1xuICAgIGlkID0gZmluZE1vZGVsSWQobW9kZWwpIGFzIHN0cmluZyB8IG51bWJlcjtcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVudXNlZC12YXJzXG4gIH0gY2F0Y2ggKGU6IHVua25vd24pIHtcbiAgICBpZCA9IERhdGUubm93KCk7XG4gIH1cbiAgY29uc3QgbmFtZSA9IG1vZGVsLmNvbnN0cnVjdG9yLm5hbWU7XG4gIHJldHVybiBgJHtuYW1lfS0ke2lkfWA7XG59XG4iLCJpbXBvcnQgeyBJbnRlcm5hbEVycm9yIH0gZnJvbSBcIkBkZWNhZi10cy9kYi1kZWNvcmF0b3JzXCI7XG5pbXBvcnQge1xuICBDb25zdHJ1Y3RvcixcbiAgTW9kZWwsXG4gIE1vZGVsQ29uc3RydWN0b3IsXG4gIFJlc2VydmVkTW9kZWxzLFxuICBWYWxpZGF0aW9uS2V5cyxcbiAgVmFsaWRhdGlvbk1ldGFkYXRhLFxufSBmcm9tIFwiQGRlY2FmLXRzL2RlY29yYXRvci12YWxpZGF0aW9uXCI7XG5pbXBvcnQge1xuICBIVE1MNURhdGVGb3JtYXQsXG4gIEhUTUw1SW5wdXRUeXBlcyxcbiAgVUlLZXlzLFxuICBWYWxpZGF0YWJsZUJ5QXR0cmlidXRlLFxuICBWYWxpZGF0YWJsZUJ5VHlwZSxcbn0gZnJvbSBcIi4vY29uc3RhbnRzXCI7XG5pbXBvcnQge1xuICBGaWVsZERlZmluaXRpb24sXG4gIEZpZWxkUHJvcGVydGllcyxcbiAgVUlFbGVtZW50TWV0YWRhdGEsXG4gIFVJTGlzdEl0ZW1FbGVtZW50TWV0YWRhdGEsXG4gIFVJTGlzdEl0ZW1Nb2RlbE1ldGFkYXRhLFxuICBVSU1vZGVsTWV0YWRhdGEsXG4gIFVJUHJvcE1ldGFkYXRhLFxufSBmcm9tIFwiLi90eXBlc1wiO1xuaW1wb3J0IHsgUmVuZGVyaW5nRXJyb3IgfSBmcm9tIFwiLi9lcnJvcnNcIjtcbmltcG9ydCB7IERlY29yYXRvck1ldGFkYXRhLCBSZWZsZWN0aW9uIH0gZnJvbSBcIkBkZWNhZi10cy9yZWZsZWN0aW9uXCI7XG5pbXBvcnQgeyBmb3JtYXRCeVR5cGUsIGdlbmVyYXRlVUlNb2RlbElEIH0gZnJvbSBcIi4vdXRpbHNcIjtcblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gQWJzdHJhY3QgY2xhc3MgZm9yIHJlbmRlcmluZyBVSSBjb21wb25lbnRzIGJhc2VkIG9uIG1vZGVsIG1ldGFkYXRhLlxuICogQHN1bW1hcnkgVGhlIFJlbmRlcmluZ0VuZ2luZSBjbGFzcyBwcm92aWRlcyBhIGZyYW1ld29yayBmb3IgY29udmVydGluZyBtb2RlbCBtZXRhZGF0YSBpbnRvIFVJIGZpZWxkIGRlZmluaXRpb25zLlxuICogSXQgaGFuZGxlcyB0aGUgdHJhbnNsYXRpb24gb2YgbW9kZWwgcHJvcGVydGllcyB0byBVSSBlbGVtZW50cywgYXBwbGllcyB2YWxpZGF0aW9uIHJ1bGVzLCBhbmQgbWFuYWdlcyBkaWZmZXJlbnQgcmVuZGVyaW5nIGZsYXZvcnMuXG4gKiBUaGlzIGNsYXNzIGlzIGRlc2lnbmVkIHRvIGJlIGV4dGVuZGVkIGJ5IHNwZWNpZmljIHJlbmRlcmluZyBpbXBsZW1lbnRhdGlvbnMuXG4gKlxuICogQHRlbXBsYXRlIFQgVGhlIHR5cGUgb2YgdGhlIHJlbmRlcmluZyByZXN1bHQsIGRlZmF1bHRzIHRvIHZvaWRcbiAqIEB0ZW1wbGF0ZSBSIFRoZSB0eXBlIG9mIHRoZSBmaWVsZCBkZWZpbml0aW9uLCBkZWZhdWx0cyB0byBGaWVsZERlZmluaXRpb248VD5cbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gZmxhdm91ciAtIFRoZSBmbGF2b3Igb2YgdGhlIHJlbmRlcmluZyBlbmdpbmUuXG4gKlxuICogQGNsYXNzIFJlbmRlcmluZ0VuZ2luZVxuICovXG5leHBvcnQgYWJzdHJhY3QgY2xhc3MgUmVuZGVyaW5nRW5naW5lPFQgPSB2b2lkLCBSID0gRmllbGREZWZpbml0aW9uPFQ+PiB7XG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gQ2FjaGUgZm9yIHN0b3JpbmcgcmVuZGVyaW5nIGVuZ2luZSBpbnN0YW5jZXMgb3IgY29uc3RydWN0b3JzLlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAc3RhdGljXG4gICAqL1xuICBwcml2YXRlIHN0YXRpYyBjYWNoZTogUmVjb3JkPFxuICAgIHN0cmluZyxcbiAgICB8IENvbnN0cnVjdG9yPFJlbmRlcmluZ0VuZ2luZTx1bmtub3duLCB1bmtub3duPj5cbiAgICB8IFJlbmRlcmluZ0VuZ2luZTx1bmtub3duLCB1bmtub3duPlxuICA+ID0ge307XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBUaGUgY3VycmVudGx5IGFjdGl2ZSByZW5kZXJpbmcgZW5naW5lLlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAc3RhdGljXG4gICAqL1xuICBwcml2YXRlIHN0YXRpYyBjdXJyZW50OlxuICAgIHwgQ29uc3RydWN0b3I8UmVuZGVyaW5nRW5naW5lPHVua25vd24sIHVua25vd24+PlxuICAgIHwgUmVuZGVyaW5nRW5naW5lPHVua25vd24sIHVua25vd24+O1xuXG4gIC8qKlxuICAgKiBGbGFnIGluZGljYXRpbmcgd2hldGhlciB0aGUgcmVuZGVyaW5nIGVuZ2luZSBoYXMgYmVlbiBpbml0aWFsaXplZC5cbiAgICovXG4gIHByb3RlY3RlZCBpbml0aWFsaXplZDogYm9vbGVhbiA9IGZhbHNlO1xuXG4gIHByb3RlY3RlZCBjb25zdHJ1Y3RvcihyZWFkb25seSBmbGF2b3VyOiBzdHJpbmcpIHtcbiAgICBSZW5kZXJpbmdFbmdpbmUucmVnaXN0ZXIodGhpcyk7XG4gICAgY29uc29sZS5sb2coYGRlY2FmJ3MgJHtmbGF2b3VyfSByZW5kZXJpbmcgZW5naW5lIGxvYWRlZGApO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBJbml0aWFsaXplcyB0aGUgcmVuZGVyaW5nIGVuZ2luZS5cbiAgICogQHN1bW1hcnkgQWJzdHJhY3QgbWV0aG9kIHRvIGJlIGltcGxlbWVudGVkIGJ5IHN1YmNsYXNzZXMgZm9yIHNwZWNpZmljIGluaXRpYWxpemF0aW9uIGxvZ2ljLlxuICAgKlxuICAgKiBAcGFyYW0gey4uLmFueVtdfSBhcmdzIC0gQW55IGFkZGl0aW9uYWwgYXJndW1lbnRzIG5lZWRlZCBmb3IgaW5pdGlhbGl6YXRpb24uXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fSBBIHByb21pc2UgdGhhdCByZXNvbHZlcyB3aGVuIGluaXRpYWxpemF0aW9uIGlzIGNvbXBsZXRlLlxuICAgKlxuICAgKiBAYWJzdHJhY3RcbiAgICovXG4gIGFic3RyYWN0IGluaXRpYWxpemUoLi4uYXJnczogYW55W10pOiBQcm9taXNlPHZvaWQ+O1xuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gVHJhbnNsYXRlcyBiZXR3ZWVuIG1vZGVsIHR5cGVzIGFuZCBIVE1MIGlucHV0IHR5cGVzLlxuICAgKiBAc3VtbWFyeSBDb252ZXJ0cyBtb2RlbCBkYXRhIHR5cGVzIHRvIGFwcHJvcHJpYXRlIEhUTUwgaW5wdXQgdHlwZXMgYW5kIHZpY2UgdmVyc2EuXG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgLSBUaGUga2V5IHRvIHRyYW5zbGF0ZS5cbiAgICogQHBhcmFtIHtib29sZWFufSBbdG9WaWV3PXRydWVdIC0gRGlyZWN0aW9uIG9mIHRyYW5zbGF0aW9uICh0cnVlIGZvciBtb2RlbCB0byB2aWV3LCBmYWxzZSBmb3IgdmlldyB0byBtb2RlbCkuXG4gICAqIEByZXR1cm5zIHtzdHJpbmd9IFRoZSB0cmFuc2xhdGVkIHR5cGUuXG4gICAqL1xuICB0cmFuc2xhdGUoa2V5OiBzdHJpbmcsIHRvVmlldzogYm9vbGVhbiA9IHRydWUpOiBzdHJpbmcge1xuICAgIGlmICh0b1ZpZXcpIHtcbiAgICAgIHN3aXRjaCAoa2V5KSB7XG4gICAgICAgIGNhc2UgUmVzZXJ2ZWRNb2RlbHMuU1RSSU5HOlxuICAgICAgICAgIHJldHVybiBIVE1MNUlucHV0VHlwZXMuVEVYVDtcbiAgICAgICAgY2FzZSBSZXNlcnZlZE1vZGVscy5OVU1CRVI6XG4gICAgICAgIGNhc2UgUmVzZXJ2ZWRNb2RlbHMuQklHSU5UOlxuICAgICAgICAgIHJldHVybiBIVE1MNUlucHV0VHlwZXMuTlVNQkVSO1xuICAgICAgICBjYXNlIFJlc2VydmVkTW9kZWxzLkJPT0xFQU46XG4gICAgICAgICAgcmV0dXJuIEhUTUw1SW5wdXRUeXBlcy5DSEVDS0JPWDtcbiAgICAgICAgY2FzZSBSZXNlcnZlZE1vZGVscy5EQVRFOlxuICAgICAgICAgIHJldHVybiBIVE1MNUlucHV0VHlwZXMuREFURTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgc3dpdGNoIChrZXkpIHtcbiAgICAgICAgY2FzZSBIVE1MNUlucHV0VHlwZXMuVEVYVDpcbiAgICAgICAgY2FzZSBIVE1MNUlucHV0VHlwZXMuRU1BSUw6XG4gICAgICAgIGNhc2UgSFRNTDVJbnB1dFR5cGVzLkNPTE9SOlxuICAgICAgICBjYXNlIEhUTUw1SW5wdXRUeXBlcy5QQVNTV09SRDpcbiAgICAgICAgY2FzZSBIVE1MNUlucHV0VHlwZXMuVEVMOlxuICAgICAgICBjYXNlIEhUTUw1SW5wdXRUeXBlcy5VUkw6XG4gICAgICAgICAgcmV0dXJuIFJlc2VydmVkTW9kZWxzLlNUUklORztcbiAgICAgICAgY2FzZSBIVE1MNUlucHV0VHlwZXMuTlVNQkVSOlxuICAgICAgICAgIHJldHVybiBSZXNlcnZlZE1vZGVscy5OVU1CRVI7XG4gICAgICAgIGNhc2UgSFRNTDVJbnB1dFR5cGVzLkNIRUNLQk9YOlxuICAgICAgICAgIHJldHVybiBSZXNlcnZlZE1vZGVscy5CT09MRUFOO1xuICAgICAgICBjYXNlIEhUTUw1SW5wdXRUeXBlcy5EQVRFOlxuICAgICAgICBjYXNlIEhUTUw1SW5wdXRUeXBlcy5EQVRFVElNRV9MT0NBTDpcbiAgICAgICAgY2FzZSBIVE1MNUlucHV0VHlwZXMuVElNRTpcbiAgICAgICAgICByZXR1cm4gUmVzZXJ2ZWRNb2RlbHMuREFURTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGtleTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gQ2hlY2tzIGlmIGEgdHlwZSBpcyB2YWxpZGF0YWJsZSBieSBpdHMgbmF0dXJlLlxuICAgKiBAc3VtbWFyeSBEZXRlcm1pbmVzIGlmIGEgZ2l2ZW4gVUkga2V5IHJlcHJlc2VudHMgYSB0eXBlIHRoYXQgaXMgaW5oZXJlbnRseSB2YWxpZGF0YWJsZS5cbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmd9IGtleSAtIFRoZSBVSSBrZXkgdG8gY2hlY2suXG4gICAqIEByZXR1cm5zIHtib29sZWFufSBUcnVlIGlmIHRoZSB0eXBlIGlzIHZhbGlkYXRhYmxlLCBmYWxzZSBvdGhlcndpc2UuXG4gICAqL1xuICBwcm90ZWN0ZWQgaXNWYWxpZGF0YWJsZUJ5VHlwZShrZXk6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgIHJldHVybiBPYmplY3Qua2V5cyhWYWxpZGF0YWJsZUJ5VHlwZSkuaW5jbHVkZXMoa2V5KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gQ2hlY2tzIGlmIGEgdHlwZSBpcyB2YWxpZGF0YWJsZSBieSBhdHRyaWJ1dGUuXG4gICAqIEBzdW1tYXJ5IERldGVybWluZXMgaWYgYSBnaXZlbiBVSSBrZXkgcmVwcmVzZW50cyBhIHZhbGlkYXRpb24gdGhhdCBjYW4gYmUgYXBwbGllZCBhcyBhbiBhdHRyaWJ1dGUuXG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgLSBUaGUgVUkga2V5IHRvIGNoZWNrLlxuICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gVHJ1ZSBpZiB0aGUgdHlwZSBpcyB2YWxpZGF0YWJsZSBieSBhdHRyaWJ1dGUsIGZhbHNlIG90aGVyd2lzZS5cbiAgICovXG4gIHByb3RlY3RlZCBpc1ZhbGlkYXRhYmxlQnlBdHRyaWJ1dGUoa2V5OiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICByZXR1cm4gT2JqZWN0LmtleXMoVmFsaWRhdGFibGVCeUF0dHJpYnV0ZSkuaW5jbHVkZXMoa2V5KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gQ29udmVydHMgdmFsaWRhdGlvbiBtZXRhZGF0YSB0byBhbiBhdHRyaWJ1dGUgdmFsdWUuXG4gICAqIEBzdW1tYXJ5IFRyYW5zZm9ybXMgdmFsaWRhdGlvbiBtZXRhZGF0YSBpbnRvIGEgdmFsdWUgc3VpdGFibGUgZm9yIHVzZSBhcyBhbiBIVE1MIGF0dHJpYnV0ZS5cbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmd9IGtleSAtIFRoZSB2YWxpZGF0aW9uIGtleS5cbiAgICogQHBhcmFtIHtWYWxpZGF0aW9uTWV0YWRhdGF9IHZhbHVlIC0gVGhlIHZhbGlkYXRpb24gbWV0YWRhdGEuXG4gICAqIEByZXR1cm5zIHtzdHJpbmcgfCBudW1iZXIgfCBib29sZWFufSBUaGUgY29udmVydGVkIGF0dHJpYnV0ZSB2YWx1ZS5cbiAgICogQHRocm93cyB7RXJyb3J9IElmIHRoZSBnaXZlbiBrZXkgaXMgbm90IHZhbGlkYXRhYmxlIGJ5IGF0dHJpYnV0ZS5cbiAgICovXG4gIHByb3RlY3RlZCB0b0F0dHJpYnV0ZVZhbHVlKFxuICAgIGtleTogc3RyaW5nLFxuICAgIHZhbHVlOiBWYWxpZGF0aW9uTWV0YWRhdGFcbiAgKTogc3RyaW5nIHwgbnVtYmVyIHwgYm9vbGVhbiB7XG4gICAgaWYgKCFPYmplY3Qua2V5cyhWYWxpZGF0YWJsZUJ5QXR0cmlidXRlKS5pbmNsdWRlcyhrZXkpKVxuICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICBgSW52YWxpZCBhdHRyaWJ1dGUga2V5IFwiJHtrZXl9XCIuIEV4cGVjdGVkIG9uZSBvZjogJHtPYmplY3Qua2V5cyhWYWxpZGF0YWJsZUJ5QXR0cmlidXRlKS5qb2luKFwiLCBcIil9LmBcbiAgICAgICk7XG5cbiAgICByZXR1cm4ga2V5ID09PSBVSUtleXMuUkVRVUlSRUQgPyB0cnVlIDogdmFsdWVba2V5XTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gQ29udmVydHMgYSBtb2RlbCB0byBhIGZpZWxkIGRlZmluaXRpb24uXG4gICAqIEBzdW1tYXJ5IFByb2Nlc3NlcyBhIG1vZGVsIGluc3RhbmNlLCBleHRyYWN0aW5nIFVJLXJlbGF0ZWQgbWV0YWRhdGEgYW5kIHZhbGlkYXRpb24gcnVsZXMgdG8gY3JlYXRlIGEgZmllbGQgZGVmaW5pdGlvbi5cbiAgICpcbiAgICogQHRlbXBsYXRlIE0gVHlwZSBleHRlbmRpbmcgTW9kZWxcbiAgICogQHRlbXBsYXRlIFQgVHlwZSByZWZlcmVuY2luZyB0aGUgc3BlY2lmaWMgUmVuZGVyaW5nIGVuZ2luZSBmaWVsZCBwcm9wZXJ0aWVzL2lucHV0c1xuICAgKiBAcGFyYW0ge019IG1vZGVsIC0gVGhlIG1vZGVsIGluc3RhbmNlIHRvIGNvbnZlcnQuXG4gICAqIEBwYXJhbSB7UmVjb3JkPHN0cmluZywgdW5rbm93bj59IFtnbG9iYWxQcm9wcz17fV0gLSBHbG9iYWwgcHJvcGVydGllcyB0byBhcHBseSB0byBhbGwgY2hpbGQgZWxlbWVudHMuXG4gICAqIEBwYXJhbSB7Ym9vbGVhbn0gW2dlbmVyYXRlSWQ9dHJ1ZV0gLSBGbGFnIGluZGljYXRpbmcgd2hldGhlciB0byBwb3B1bGF0ZSB0aGUgcmVuZGVyZXJJZCBwcm9wZXJ0eS5cbiAgICogQHJldHVybnMge0ZpZWxkRGVmaW5pdGlvbjxUPn0gQSBmaWVsZCBkZWZpbml0aW9uIG9iamVjdCByZXByZXNlbnRpbmcgdGhlIFVJIHN0cnVjdHVyZSBvZiB0aGUgbW9kZWwuXG4gICAqIEB0aHJvd3Mge1JlbmRlcmluZ0Vycm9yfSBJZiBubyBVSSBkZWZpbml0aW9ucyBhcmUgc2V0IGZvciB0aGUgbW9kZWwgb3IgaWYgdGhlcmUgYXJlIGludmFsaWQgZGVjb3JhdG9ycy5cbiAgICpcbiAgICogQG1lcm1haWRcbiAgICogc2VxdWVuY2VEaWFncmFtXG4gICAqICBwYXJ0aWNpcGFudCBDIGFzIENsaWVudFxuICAgKiAgcGFydGljaXBhbnQgUkUgYXMgUmVuZGVyaW5nRW5naW5lXG4gICAqICBwYXJ0aWNpcGFudCBSIGFzIFJlZmxlY3Rpb25cbiAgICogIHBhcnRpY2lwYW50IE0gYXMgTW9kZWxcbiAgICogIEMtPj5SRTogdG9GaWVsZERlZmluaXRpb24obW9kZWwsIGdsb2JhbFByb3BzKVxuICAgKiAgUkUtPj5SOiBnZXRNZXRhZGF0YShVSUtleXMuVUlNT0RFTCwgbW9kZWwuY29uc3RydWN0b3IpXG4gICAqICBSLS0+PlJFOiBVSU1vZGVsTWV0YWRhdGFcbiAgICogIFJFLT4+UjogZ2V0QWxsUHJvcGVydHlEZWNvcmF0b3JzKG1vZGVsLCBVSUtleXMuUkVGTEVDVClcbiAgICogIFItLT4+UkU6IFJlY29yZDxzdHJpbmcsIERlY29yYXRvck1ldGFkYXRhW10+XG4gICAqICBSRS0+PlI6IGdldEFsbFByb3BlcnR5RGVjb3JhdG9ycyhtb2RlbCwgVmFsaWRhdGlvbktleXMuUkVGTEVDVClcbiAgICogIFItLT4+UkU6IFJlY29yZDxzdHJpbmcsIERlY29yYXRvck1ldGFkYXRhPFZhbGlkYXRpb25NZXRhZGF0YT5bXT5cbiAgICogIGxvb3AgRm9yIGVhY2ggcHJvcGVydHlcbiAgICogICAgUkUtPj5SRTogUHJvY2VzcyBVSSBkZWNvcmF0b3JzXG4gICAqICAgIFJFLT4+UkU6IEFwcGx5IHZhbGlkYXRpb24gcnVsZXNcbiAgICogIGVuZFxuICAgKiAgUkUtLT4+QzogRmllbGREZWZpbml0aW9uPFQ+XG4gICAqL1xuICBwcm90ZWN0ZWQgdG9GaWVsZERlZmluaXRpb248TSBleHRlbmRzIE1vZGVsPihcbiAgICBtb2RlbDogTSxcbiAgICBnbG9iYWxQcm9wczogUmVjb3JkPHN0cmluZywgdW5rbm93bj4gPSB7fSxcbiAgICBnZW5lcmF0ZUlkOiBib29sZWFuID0gdHJ1ZVxuICApOiBGaWVsZERlZmluaXRpb248VD4ge1xuICAgIGNvbnN0IGNsYXNzRGVjb3JhdG9yczogW1VJTW9kZWxNZXRhZGF0YSwgVUlMaXN0SXRlbU1vZGVsTWV0YWRhdGFdID0gW1xuICAgICAgUmVmbGVjdC5nZXRNZXRhZGF0YShcbiAgICAgICAgUmVuZGVyaW5nRW5naW5lLmtleShVSUtleXMuVUlNT0RFTCksXG4gICAgICAgIG1vZGVsLmNvbnN0cnVjdG9yXG4gICAgICApIHx8XG4gICAgICAgIFJlZmxlY3QuZ2V0TWV0YWRhdGEoXG4gICAgICAgICAgUmVuZGVyaW5nRW5naW5lLmtleShVSUtleXMuVUlNT0RFTCksXG4gICAgICAgICAgTW9kZWwuZ2V0KG1vZGVsLmNvbnN0cnVjdG9yLm5hbWUpIGFzIGFueVxuICAgICAgICApLFxuICAgICAgUmVmbGVjdC5nZXRNZXRhZGF0YShcbiAgICAgICAgUmVuZGVyaW5nRW5naW5lLmtleShVSUtleXMuVUlMSVNUSVRFTSksXG4gICAgICAgIG1vZGVsLmNvbnN0cnVjdG9yXG4gICAgICApIHx8XG4gICAgICAgIFJlZmxlY3QuZ2V0TWV0YWRhdGEoXG4gICAgICAgICAgUmVuZGVyaW5nRW5naW5lLmtleShVSUtleXMuVUlMSVNUSVRFTSksXG4gICAgICAgICAgTW9kZWwuZ2V0KG1vZGVsLmNvbnN0cnVjdG9yLm5hbWUpIGFzIGFueVxuICAgICAgICApLFxuICAgIF07XG5cbiAgICBpZiAoIWNsYXNzRGVjb3JhdG9ycylcbiAgICAgIHRocm93IG5ldyBSZW5kZXJpbmdFcnJvcihcbiAgICAgICAgYE5vIHVpIGRlZmluaXRpb25zIHNldCBmb3IgbW9kZWwgJHttb2RlbC5jb25zdHJ1Y3Rvci5uYW1lfS4gRGlkIHlvdSB1c2UgQHVpbW9kZWw/YFxuICAgICAgKTtcblxuICAgIGNvbnN0IGNsYXNzRGVjb3JhdG9yID0gT2JqZWN0LmFzc2lnbih7fSwgLi4uY2xhc3NEZWNvcmF0b3JzKTtcbiAgICBjb25zdCB7IHRhZywgcHJvcHMsIGl0ZW0gfSA9IGNsYXNzRGVjb3JhdG9yO1xuXG4gICAgY29uc3QgdWlEZWNvcmF0b3JzOiBSZWNvcmQ8c3RyaW5nLCBEZWNvcmF0b3JNZXRhZGF0YVtdPiA9XG4gICAgICBSZWZsZWN0aW9uLmdldEFsbFByb3BlcnR5RGVjb3JhdG9ycyhtb2RlbCwgVUlLZXlzLlJFRkxFQ1QpIGFzIFJlY29yZDxcbiAgICAgICAgc3RyaW5nLFxuICAgICAgICBEZWNvcmF0b3JNZXRhZGF0YVtdXG4gICAgICA+O1xuICAgIGxldCBjaGlsZHJlbjogRmllbGREZWZpbml0aW9uPFJlY29yZDxzdHJpbmcsIGFueT4+W10gfCB1bmRlZmluZWQ7XG4gICAgbGV0IGNoaWxkUHJvcHM6IFJlY29yZDxzdHJpbmcsIGFueT4gPSBpdGVtPy5wcm9wcyB8fCB7fTtcbiAgICBsZXQgbWFwcGVyOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+ID0ge307XG5cbiAgICBpZiAodWlEZWNvcmF0b3JzKSB7XG4gICAgICBjb25zdCB2YWxpZGF0aW9uRGVjb3JhdG9yczogUmVjb3JkPFxuICAgICAgICBzdHJpbmcsXG4gICAgICAgIERlY29yYXRvck1ldGFkYXRhPFZhbGlkYXRpb25NZXRhZGF0YT5bXVxuICAgICAgPiA9IFJlZmxlY3Rpb24uZ2V0QWxsUHJvcGVydHlEZWNvcmF0b3JzKFxuICAgICAgICBtb2RlbCxcbiAgICAgICAgVmFsaWRhdGlvbktleXMuUkVGTEVDVFxuICAgICAgKSBhcyBSZWNvcmQ8c3RyaW5nLCBEZWNvcmF0b3JNZXRhZGF0YTxWYWxpZGF0aW9uTWV0YWRhdGE+W10+O1xuXG4gICAgICBmb3IgKGNvbnN0IGtleSBpbiB1aURlY29yYXRvcnMpIHtcbiAgICAgICAgY29uc3QgZGVjcyA9IHVpRGVjb3JhdG9yc1trZXldO1xuICAgICAgICBjb25zdCB0eXBlcyA9IE9iamVjdC52YWx1ZXMoZGVjcykuZmlsdGVyKFxuICAgICAgICAgIChpdGVtKSA9PiBpdGVtLmtleSA9PT0gVUlLZXlzLlBST1AgfHwgaXRlbS5rZXkgPT09IFVJS2V5cy5FTEVNRU5UXG4gICAgICAgICk7XG4gICAgICAgIGlmICh0eXBlcz8ubGVuZ3RoID4gMSlcbiAgICAgICAgICB0aHJvdyBuZXcgUmVuZGVyaW5nRXJyb3IoXG4gICAgICAgICAgICBgT25seSBvbmUgdHlwZSBvZiBkZWNvcmF0aW9uIGlzIGFsbG93ZWQuIFBsZWFzZSBjaG9vc2UgYmV0d2VlbiBAdWlwcm9wIGFuZCBAdWllbGVtZW50YFxuICAgICAgICAgICk7XG4gICAgICAgIGRlY3Muc2hpZnQoKTtcbiAgICAgICAgZGVjcy5mb3JFYWNoKChkZWMpID0+IHtcbiAgICAgICAgICBpZiAoIWRlYykgdGhyb3cgbmV3IFJlbmRlcmluZ0Vycm9yKGBObyBkZWNvcmF0b3IgZm91bmRgKTtcblxuICAgICAgICAgIHN3aXRjaCAoZGVjLmtleSkge1xuICAgICAgICAgICAgY2FzZSBVSUtleXMuUFJPUDoge1xuICAgICAgICAgICAgICBpZiAoIU1vZGVsLmlzUHJvcGVydHlNb2RlbChtb2RlbCwga2V5KSkge1xuICAgICAgICAgICAgICAgIGNoaWxkUHJvcHNba2V5XSA9IGRlYy5wcm9wcyBhcyBVSVByb3BNZXRhZGF0YTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgIGxldCBDbGF6ejtcbiAgICAgICAgICAgICAgY29uc3Qgc3VibW9kZWwgPSAobW9kZWwgYXMgUmVjb3JkPHN0cmluZywgYW55Pilba2V5XSBhcyBNb2RlbDtcbiAgICAgICAgICAgICAgY29uc3QgY29uc3RydWN0YWJsZSA9XG4gICAgICAgICAgICAgICAgdHlwZW9mIHN1Ym1vZGVsID09PSBcIm9iamVjdFwiICYmXG4gICAgICAgICAgICAgICAgc3VibW9kZWwgIT09IG51bGwgJiZcbiAgICAgICAgICAgICAgICAhQXJyYXkuaXNBcnJheShzdWJtb2RlbCk7XG4gICAgICAgICAgICAgIGlmICghY29uc3RydWN0YWJsZSlcbiAgICAgICAgICAgICAgICBDbGF6eiA9IG5ldyAoTW9kZWwuZ2V0KFxuICAgICAgICAgICAgICAgICAgZGVjLnByb3BzPy5uYW1lIGFzIHN0cmluZ1xuICAgICAgICAgICAgICAgICkgYXMgTW9kZWxDb25zdHJ1Y3RvcjxNb2RlbD4pKCk7XG5cbiAgICAgICAgICAgICAgY2hpbGRyZW4gPSBjaGlsZHJlbiB8fCBbXTtcbiAgICAgICAgICAgICAgY29uc3QgY2hpbGREZWZpbml0aW9uID0gdGhpcy50b0ZpZWxkRGVmaW5pdGlvbihcbiAgICAgICAgICAgICAgICBzdWJtb2RlbCB8fCBDbGF6eixcbiAgICAgICAgICAgICAgICBnbG9iYWxQcm9wcyxcbiAgICAgICAgICAgICAgICBmYWxzZVxuICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICBjaGlsZHJlbi5wdXNoKFxuICAgICAgICAgICAgICAgIGNoaWxkRGVmaW5pdGlvbiBhcyBGaWVsZERlZmluaXRpb248UmVjb3JkPHN0cmluZywgYW55Pj5cbiAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXNlIFVJS2V5cy5VSUxJU1RQUk9QOiB7XG4gICAgICAgICAgICAgIG1hcHBlciA9IG1hcHBlciB8fCB7fTtcbiAgICAgICAgICAgICAgbWFwcGVyW2RlYy5wcm9wcz8ubmFtZSBhcyBzdHJpbmddID0ga2V5O1xuICAgICAgICAgICAgICBjb25zdCBwcm9wcyA9IE9iamVjdC5hc3NpZ24oXG4gICAgICAgICAgICAgICAge30sXG4gICAgICAgICAgICAgICAgY2xhc3NEZWNvcmF0b3IucHJvcHM/Lml0ZW0gfHwge30sXG4gICAgICAgICAgICAgICAgaXRlbT8ucHJvcHMgfHwge30sXG4gICAgICAgICAgICAgICAgZGVjLnByb3BzPy5wcm9wcyB8fCB7fSxcbiAgICAgICAgICAgICAgICBnbG9iYWxQcm9wc1xuICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICBjaGlsZFByb3BzID0ge1xuICAgICAgICAgICAgICAgIHRhZzogaXRlbT8udGFnIHx8IHByb3BzLnJlbmRlciB8fCBcIlwiLFxuICAgICAgICAgICAgICAgIHByb3BzOiBPYmplY3QuYXNzaWduKHt9LCBjaGlsZFByb3BzPy5wcm9wcywgeyBtYXBwZXIgfSwgcHJvcHMpLFxuICAgICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2FzZSBVSUtleXMuRUxFTUVOVDoge1xuICAgICAgICAgICAgICBjaGlsZHJlbiA9IGNoaWxkcmVuIHx8IFtdO1xuICAgICAgICAgICAgICBjb25zdCBjaGlsZERlZmluaXRpb246IEZpZWxkRGVmaW5pdGlvbjxSZWNvcmQ8c3RyaW5nLCBhbnk+PiA9IHtcbiAgICAgICAgICAgICAgICB0YWc6IChkZWMucHJvcHMgYXMgVUlFbGVtZW50TWV0YWRhdGEpLnRhZyxcbiAgICAgICAgICAgICAgICBwcm9wczogT2JqZWN0LmFzc2lnbihcbiAgICAgICAgICAgICAgICAgIHt9LFxuICAgICAgICAgICAgICAgICAgKGRlYy5wcm9wcyBhcyBVSUVsZW1lbnRNZXRhZGF0YSkucHJvcHMgYXMgYW55LFxuICAgICAgICAgICAgICAgICAgZ2xvYmFsUHJvcHNcbiAgICAgICAgICAgICAgICApLFxuICAgICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICAgIGNvbnN0IHZhbGlkYXRpb25EZWNzOiBEZWNvcmF0b3JNZXRhZGF0YTxWYWxpZGF0aW9uTWV0YWRhdGE+W10gPVxuICAgICAgICAgICAgICAgIHZhbGlkYXRpb25EZWNvcmF0b3JzW1xuICAgICAgICAgICAgICAgICAga2V5XG4gICAgICAgICAgICAgICAgXSBhcyBEZWNvcmF0b3JNZXRhZGF0YTxWYWxpZGF0aW9uTWV0YWRhdGE+W107XG5cbiAgICAgICAgICAgICAgY29uc3QgdHlwZURlYzogRGVjb3JhdG9yTWV0YWRhdGFPYmplY3QgPVxuICAgICAgICAgICAgICAgIHZhbGlkYXRpb25EZWNzLnNoaWZ0KCkgYXMgRGVjb3JhdG9yTWV0YWRhdGE7XG4gICAgICAgICAgICAgIGZvciAoY29uc3QgZGVjIG9mIHZhbGlkYXRpb25EZWNzKSB7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuaXNWYWxpZGF0YWJsZUJ5QXR0cmlidXRlKGRlYy5rZXkpKSB7XG4gICAgICAgICAgICAgICAgICBjaGlsZERlZmluaXRpb24ucHJvcHNbdGhpcy50cmFuc2xhdGUoZGVjLmtleSldID1cbiAgICAgICAgICAgICAgICAgICAgdGhpcy50b0F0dHJpYnV0ZVZhbHVlKGRlYy5rZXksIGRlYy5wcm9wcyk7XG4gICAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuaXNWYWxpZGF0YWJsZUJ5VHlwZShkZWMua2V5KSkge1xuICAgICAgICAgICAgICAgICAgaWYgKGRlYy5rZXkgPT09IEhUTUw1SW5wdXRUeXBlcy5EQVRFKSB7XG4gICAgICAgICAgICAgICAgICAgIGNoaWxkRGVmaW5pdGlvbi5wcm9wc1tVSUtleXMuRk9STUFUXSA9XG4gICAgICAgICAgICAgICAgICAgICAgZGVjLnByb3BzLmZvcm1hdCB8fCBIVE1MNURhdGVGb3JtYXQ7XG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICBjaGlsZERlZmluaXRpb24ucHJvcHNbVUlLZXlzLlRZUEVdID0gZGVjLmtleTtcbiAgICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgIGlmICghY2hpbGREZWZpbml0aW9uLnByb3BzW1VJS2V5cy5UWVBFXSkge1xuICAgICAgICAgICAgICAgIGNvbnN0IGJhc2ljVHlwZSA9ICh0eXBlRGVjLnByb3BzIGFzIHsgbmFtZTogc3RyaW5nIH0pLm5hbWU7XG4gICAgICAgICAgICAgICAgY2hpbGREZWZpbml0aW9uLnByb3BzW1VJS2V5cy5UWVBFXSA9IHRoaXMudHJhbnNsYXRlKFxuICAgICAgICAgICAgICAgICAgYmFzaWNUeXBlLnRvTG93ZXJDYXNlKCksXG4gICAgICAgICAgICAgICAgICB0cnVlXG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgIGNoaWxkRGVmaW5pdGlvbi5wcm9wcy52YWx1ZSA9IGZvcm1hdEJ5VHlwZShcbiAgICAgICAgICAgICAgICBjaGlsZERlZmluaXRpb24ucHJvcHNbVUlLZXlzLlRZUEVdLFxuICAgICAgICAgICAgICAgIG1vZGVsW2tleSBhcyBrZXlvZiBNXSxcbiAgICAgICAgICAgICAgICBjaGlsZERlZmluaXRpb24ucHJvcHNbVUlLZXlzLkZPUk1BVF1cbiAgICAgICAgICAgICAgKTtcblxuICAgICAgICAgICAgICBjaGlsZHJlbi5wdXNoKGNoaWxkRGVmaW5pdGlvbik7XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgdGhyb3cgbmV3IFJlbmRlcmluZ0Vycm9yKGBJbnZhbGlkIGtleTogJHtkZWMua2V5fWApO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgY29uc3QgcmVzdWx0OiBGaWVsZERlZmluaXRpb248VD4gPSB7XG4gICAgICB0YWc6IHRhZyxcbiAgICAgIGl0ZW06IGNoaWxkUHJvcHMgYXMgVUlMaXN0SXRlbUVsZW1lbnRNZXRhZGF0YSxcbiAgICAgIHByb3BzOiBPYmplY3QuYXNzaWduKHt9LCBwcm9wcywgZ2xvYmFsUHJvcHMpIGFzIFQgJiBGaWVsZFByb3BlcnRpZXMsXG4gICAgICBjaGlsZHJlbjogY2hpbGRyZW4gYXMgRmllbGREZWZpbml0aW9uPGFueT5bXSxcbiAgICB9O1xuXG4gICAgaWYgKGdlbmVyYXRlSWQpIHJlc3VsdC5yZW5kZXJlcklkID0gZ2VuZXJhdGVVSU1vZGVsSUQobW9kZWwpO1xuXG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gUmVuZGVycyBhIG1vZGVsIHdpdGggZ2xvYmFsIHByb3BlcnRpZXMgYW5kIGFkZGl0aW9uYWwgYXJndW1lbnRzLlxuICAgKiBAc3VtbWFyeSBBYnN0cmFjdCBtZXRob2QgdG8gYmUgaW1wbGVtZW50ZWQgYnkgc3ViY2xhc3NlcyB0byBkZWZpbmUgc3BlY2lmaWMgcmVuZGVyaW5nIGJlaGF2aW9yLlxuICAgKlxuICAgKiBAdGVtcGxhdGUgTSBUeXBlIGV4dGVuZGluZyBNb2RlbFxuICAgKiBAdGVtcGxhdGUgUiBSZW5kZXJpbmcgZW5naW5lIGltcGxlbWVudGF0aW9uIHNwZWNpZmljIG91dHB1dCB0eXBlXG4gICAqIEBwYXJhbSB7TX0gbW9kZWwgLSBUaGUgbW9kZWwgdG8gYmUgcmVuZGVyZWQuXG4gICAqIEBwYXJhbSB7UmVjb3JkPHN0cmluZywgdW5rbm93bj59IGdsb2JhbFByb3BzIC0gR2xvYmFsIHByb3BlcnRpZXMgdG8gYmUgYXBwbGllZCB0byBhbGwgZWxlbWVudHMgZHVyaW5nIHJlbmRlcmluZy5cbiAgICogQHBhcmFtIHsuLi5hbnlbXX0gYXJncyAtIEFkZGl0aW9uYWwgYXJndW1lbnRzIHRoYXQgbWF5IGJlIHJlcXVpcmVkIGZvciBzcGVjaWZpYyByZW5kZXJpbmcgaW1wbGVtZW50YXRpb25zLlxuICAgKiBAcmV0dXJucyB7Un0gVGhlIHJlbmRlcmVkIHJlc3VsdCwgdHlwZSBkZXBlbmRzIG9uIHRoZSBzcGVjaWZpYyBpbXBsZW1lbnRhdGlvbi5cbiAgICpcbiAgICogQGFic3RyYWN0XG4gICAqL1xuICBhYnN0cmFjdCByZW5kZXI8TSBleHRlbmRzIE1vZGVsPihcbiAgICBtb2RlbDogTSxcbiAgICBnbG9iYWxQcm9wczogUmVjb3JkPHN0cmluZywgdW5rbm93bj4sXG4gICAgLi4uYXJnczogYW55W11cbiAgKTogUjtcblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFJlZ2lzdGVycyBhIHJlbmRlcmluZyBlbmdpbmUgaW5zdGFuY2UuXG4gICAqIEBzdW1tYXJ5IEFkZHMgYSByZW5kZXJpbmcgZW5naW5lIHRvIHRoZSBzdGF0aWMgY2FjaGUgYW5kIHNldHMgaXQgYXMgdGhlIGN1cnJlbnQgZW5naW5lLlxuICAgKlxuICAgKiBAcGFyYW0ge1JlbmRlcmluZ0VuZ2luZTx1bmtub3duLCB1bmtub3duPn0gZW5naW5lIC0gVGhlIHJlbmRlcmluZyBlbmdpbmUgdG8gcmVnaXN0ZXIuXG4gICAqIEB0aHJvd3Mge0ludGVybmFsRXJyb3J9IElmIGFuIGVuZ2luZSB3aXRoIHRoZSBzYW1lIGZsYXZvciBhbHJlYWR5IGV4aXN0cy5cbiAgICpcbiAgICogQHN0YXRpY1xuICAgKi9cbiAgc3RhdGljIHJlZ2lzdGVyKGVuZ2luZTogUmVuZGVyaW5nRW5naW5lPHVua25vd24sIHVua25vd24+KSB7XG4gICAgaWYgKGVuZ2luZS5mbGF2b3VyIGluIHRoaXMuY2FjaGUpXG4gICAgICB0aHJvdyBuZXcgSW50ZXJuYWxFcnJvcihcbiAgICAgICAgYFJlbmRlcmluZyBlbmdpbmUgdW5kZXIgJHtlbmdpbmUuZmxhdm91cn0gYWxyZWFkeSBleGlzdHNgXG4gICAgICApO1xuICAgIHRoaXMuY2FjaGVbZW5naW5lLmZsYXZvdXJdID0gZW5naW5lO1xuICAgIHRoaXMuY3VycmVudCA9IGVuZ2luZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gUmV0cmlldmVzIG9yIGluaXRpYWxpemVzIGEgcmVuZGVyaW5nIGVuZ2luZS5cbiAgICogQHN1bW1hcnkgR2V0cyBhbiBleGlzdGluZyBlbmdpbmUgaW5zdGFuY2Ugb3IgY3JlYXRlcyBhbmQgaW5pdGlhbGl6ZXMgYSBuZXcgb25lIGlmIGdpdmVuIGEgY29uc3RydWN0b3IuXG4gICAqXG4gICAqIEB0ZW1wbGF0ZSBPIFRoZSB0eXBlIG9mIHRoZSByZW5kZXJpbmcgZW5naW5lIG91dHB1dFxuICAgKiBAcGFyYW0ge0NvbnN0cnVjdG9yPFJlbmRlcmluZ0VuZ2luZTxPPj4gfCBSZW5kZXJpbmdFbmdpbmU8Tz59IG9iaiAtIFRoZSBlbmdpbmUgaW5zdGFuY2Ugb3IgY29uc3RydWN0b3IuXG4gICAqIEByZXR1cm5zIHtSZW5kZXJpbmdFbmdpbmU8Tz59IFRoZSBpbml0aWFsaXplZCByZW5kZXJpbmcgZW5naW5lLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAc3RhdGljXG4gICAqL1xuICBwcml2YXRlIHN0YXRpYyBnZXRPckJvb3Q8Tz4oXG4gICAgb2JqOiBDb25zdHJ1Y3RvcjxSZW5kZXJpbmdFbmdpbmU8Tz4+IHwgUmVuZGVyaW5nRW5naW5lPE8+XG4gICk6IFJlbmRlcmluZ0VuZ2luZTxPPiB7XG4gICAgaWYgKG9iaiBpbnN0YW5jZW9mIFJlbmRlcmluZ0VuZ2luZSkgcmV0dXJuIG9iaiBhcyBSZW5kZXJpbmdFbmdpbmU8Tz47XG4gICAgY29uc3QgZW5naW5lOiBSZW5kZXJpbmdFbmdpbmU8Tz4gPSBuZXcgb2JqKCk7XG4gICAgZW5naW5lLmluaXRpYWxpemUoKTsgLy8gbWFrZSB0aGUgYm9vdGluZyBhc3luYy4gdXNlIHRoZSBpbml0aWFsaXplZCBmbGFnIHRvIGNvbnRyb2wgaXRcbiAgICByZXR1cm4gZW5naW5lIGFzIFJlbmRlcmluZ0VuZ2luZTxPPjtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gUmV0cmlldmVzIGEgcmVuZGVyaW5nIGVuZ2luZSBieSBmbGF2b3IuXG4gICAqIEBzdW1tYXJ5IEdldHMgdGhlIGN1cnJlbnQgcmVuZGVyaW5nIGVuZ2luZSBvciBhIHNwZWNpZmljIG9uZSBieSBmbGF2b3IuXG4gICAqXG4gICAqIEB0ZW1wbGF0ZSBPIFRoZSB0eXBlIG9mIHRoZSByZW5kZXJpbmcgZW5naW5lIG91dHB1dFxuICAgKiBAcGFyYW0ge3N0cmluZ30gW2ZsYXZvdXJdIC0gVGhlIGZsYXZvciBvZiB0aGUgcmVuZGVyaW5nIGVuZ2luZSB0byByZXRyaWV2ZS5cbiAgICogQHJldHVybnMge1JlbmRlcmluZ0VuZ2luZTxPPn0gVGhlIHJlcXVlc3RlZCByZW5kZXJpbmcgZW5naW5lLlxuICAgKiBAdGhyb3dzIHtJbnRlcm5hbEVycm9yfSBJZiB0aGUgcmVxdWVzdGVkIGZsYXZvciBkb2VzIG5vdCBleGlzdC5cbiAgICpcbiAgICogQHN0YXRpY1xuICAgKi9cbiAgc3RhdGljIGdldDxPPihmbGF2b3VyPzogc3RyaW5nKTogUmVuZGVyaW5nRW5naW5lPE8+IHtcbiAgICBpZiAoIWZsYXZvdXIpXG4gICAgICByZXR1cm4gdGhpcy5nZXRPckJvb3Q8Tz4oXG4gICAgICAgIHRoaXMuY3VycmVudCBhcyBDb25zdHJ1Y3RvcjxSZW5kZXJpbmdFbmdpbmU8Tz4+IHwgUmVuZGVyaW5nRW5naW5lPE8+XG4gICAgICApO1xuICAgIGlmICghKGZsYXZvdXIgaW4gdGhpcy5jYWNoZSkpXG4gICAgICB0aHJvdyBuZXcgSW50ZXJuYWxFcnJvcihcbiAgICAgICAgYFJlbmRlcmluZyBlbmdpbmUgdW5kZXIgJHtmbGF2b3VyfSBkb2VzIG5vdCBleGlzdGBcbiAgICAgICk7XG4gICAgcmV0dXJuIHRoaXMuZ2V0T3JCb290PE8+KFxuICAgICAgdGhpcy5jYWNoZVtmbGF2b3VyXSBhc1xuICAgICAgICB8IENvbnN0cnVjdG9yPFJlbmRlcmluZ0VuZ2luZTxPPj5cbiAgICAgICAgfCBSZW5kZXJpbmdFbmdpbmU8Tz5cbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBSZW5kZXJzIGEgbW9kZWwgdXNpbmcgdGhlIGFwcHJvcHJpYXRlIHJlbmRlcmluZyBlbmdpbmUuXG4gICAqIEBzdW1tYXJ5IERldGVybWluZXMgdGhlIGNvcnJlY3QgcmVuZGVyaW5nIGVuZ2luZSBmb3IgYSBtb2RlbCBhbmQgaW52b2tlcyBpdHMgcmVuZGVyIG1ldGhvZC5cbiAgICpcbiAgICogQHRlbXBsYXRlIE0gVHlwZSBleHRlbmRpbmcgTW9kZWxcbiAgICogQHBhcmFtIHtNfSBtb2RlbCAtIFRoZSBtb2RlbCB0byByZW5kZXIuXG4gICAqIEBwYXJhbSB7Li4uYW55W119IGFyZ3MgLSBBZGRpdGlvbmFsIGFyZ3VtZW50cyB0byBwYXNzIHRvIHRoZSByZW5kZXIgbWV0aG9kLlxuICAgKiBAcmV0dXJucyB7YW55fSBUaGUgcmVzdWx0IG9mIHRoZSByZW5kZXJpbmcgcHJvY2Vzcy5cbiAgICogQHRocm93cyB7SW50ZXJuYWxFcnJvcn0gSWYgbm8gcmVnaXN0ZXJlZCBtb2RlbCBpcyBmb3VuZC5cbiAgICpcbiAgICogQHN0YXRpY1xuICAgKi9cbiAgc3RhdGljIHJlbmRlcjxNIGV4dGVuZHMgTW9kZWw+KG1vZGVsOiBNLCAuLi5hcmdzOiBhbnlbXSk6IGFueSB7XG4gICAgY29uc3QgY29uc3RydWN0b3IgPSBNb2RlbC5nZXQobW9kZWwuY29uc3RydWN0b3IubmFtZSk7XG4gICAgaWYgKCFjb25zdHJ1Y3RvcikgdGhyb3cgbmV3IEludGVybmFsRXJyb3IoXCJObyBtb2RlbCByZWdpc3RlcmVkIGZvdW5kXCIpO1xuICAgIGNvbnN0IGZsYXZvdXIgPSBSZWZsZWN0LmdldE1ldGFkYXRhKFxuICAgICAgUmVuZGVyaW5nRW5naW5lLmtleShVSUtleXMuUkVOREVSRURfQlkpLFxuICAgICAgY29uc3RydWN0b3IgYXMgTW9kZWxDb25zdHJ1Y3RvcjxNb2RlbD5cbiAgICApO1xuXG4gICAgLy8gQHRzLWV4cGVjdC1lcnJvciBmb3IgdGhlIHZhciBhcmdzIHR5cGUgY2hlY2tcbiAgICByZXR1cm4gUmVuZGVyaW5nRW5naW5lLmdldChmbGF2b3VyKS5yZW5kZXIobW9kZWwsIC4uLmFyZ3MpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBHZW5lcmF0ZXMgYSBtZXRhZGF0YSBrZXkgZm9yIFVJLXJlbGF0ZWQgcHJvcGVydGllcy5cbiAgICogQHN1bW1hcnkgUHJlZml4ZXMgYSBnaXZlbiBrZXkgd2l0aCB0aGUgVUkgcmVmbGVjdGlvbiBwcmVmaXguXG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgLSBUaGUga2V5IHRvIHByZWZpeC5cbiAgICogQHJldHVybnMge3N0cmluZ30gVGhlIHByZWZpeGVkIGtleS5cbiAgICpcbiAgICogQHN0YXRpY1xuICAgKi9cbiAgc3RhdGljIGtleShrZXk6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgcmV0dXJuIGAke1VJS2V5cy5SRUZMRUNUfSR7a2V5fWA7XG4gIH1cbn1cbiIsImltcG9ydCB7IFVJS2V5cyB9IGZyb20gXCIuLi91aS9jb25zdGFudHNcIjtcbmltcG9ydCB7IGFwcGx5LCBtZXRhZGF0YSB9IGZyb20gXCJAZGVjYWYtdHMvcmVmbGVjdGlvblwiO1xuaW1wb3J0IHsgUmVuZGVyaW5nRW5naW5lIH0gZnJvbSBcIi4uL3VpL1JlbmRlcmluZ1wiO1xuaW1wb3J0IHsgVUlMaXN0SXRlbU1vZGVsTWV0YWRhdGEsIFVJTW9kZWxNZXRhZGF0YSB9IGZyb20gXCIuLi91aS90eXBlc1wiO1xuXG4vKipcbiAqIFRhZ3MgdGhlIG1vZGVsIGFzIGEgdWltb2RlbCwgZ2l2aW5nIGl0IHRoZSAncmVuZGVyJyBtZXRob2RcbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gW3RhZ10gb3B0aW9uYWwgcGFyYW0uIHdpbGwgcmVuZGVyIHRoZSBwcm92aWRlZCBlbG1lbnQgd3JhcHBpbmcgdGhlIGF0dHJpYnV0ZSB1aWVsZW1lbnRzXG4gKiBAcGFyYW0ge3t9fSBbcHJvcHNdIG9wdGlvbmFsIHBhcmFtLiBBdHRyaWJ1dGVzIHRvIGJlIHBhc3NlZCB0byB0aGUgdGFnIGVsZW1lbnRcbiAqIEBwYXJhbSB7ZnVuY3Rpb24oYW55KTogdm9pZH0gW2luc3RhbmNlQ2FsbGJhY2tdIG9wdGlvbmFsIGNhbGxiYWNrIHJldHVybmluZyB0aGUgaW5zdGFuY2UgYWZ0ZXIgY3JlYXRpb24gZm9yIGFkZGl0aW9uYWwgbG9naWNcbiAqXG4gKiBAZGVjb3JhdG9yIHVpbW9kZWxcbiAqXG4gKiBAbWVybWFpZFxuICogc2VxdWVuY2VEaWFncmFtXG4gKiAgIHBhcnRpY2lwYW50IFN5c3RlbVxuICogICBwYXJ0aWNpcGFudCB1aW1vZGVsXG4gKiAgIHBhcnRpY2lwYW50IGNvbnN0cnVjdG9yXG4gKiAgIHBhcnRpY2lwYW50IGluc3RhbmNlXG4gKiAgIFN5c3RlbS0+PnVpbW9kZWw6ZG8oY29uc3RydWN0b3IpXG4gKiAgIHVpbW9kZWwtPj5jb25zdHJ1Y3RvcjogRXhlY3V0ZXMgdGhlIGNvbnN0cnVjdG9yXG4gKiAgIGNvbnN0cnVjdG9yLT4+dWltb2RlbDogcmV0dXJucyBpbnN0YW5jZVxuICogICB1aW1vZGVsLT4+aW5zdGFuY2U6IGFkZHMgdGhlIHJlbmRlciBtZXRob2RcbiAqICAgdWltb2RlbC0+PlN5c3RlbTogcmV0dXJucyBVSU1vZGVsIGluc3RhbmNlXG4gKlxuICogQGNhdGVnb3J5IERlY29yYXRvcnNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHVpbW9kZWwodGFnPzogc3RyaW5nLCBwcm9wcz86IFJlY29yZDxzdHJpbmcsIGFueT4pIHtcbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnVzZWQtdmFyc1xuICByZXR1cm4gKG9yaWdpbmFsOiBhbnksIHByb3BlcnR5S2V5PzogYW55KSA9PiB7XG4gICAgY29uc3QgbWV0YTogVUlNb2RlbE1ldGFkYXRhID0ge1xuICAgICAgdGFnOiB0YWcgfHwgb3JpZ2luYWwubmFtZSxcbiAgICAgIHByb3BzOiBwcm9wcyxcbiAgICB9O1xuICAgIHJldHVybiBtZXRhZGF0YShSZW5kZXJpbmdFbmdpbmUua2V5KFVJS2V5cy5VSU1PREVMKSwgbWV0YSkob3JpZ2luYWwpO1xuICB9O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gcmVuZGVyZWRCeShlbmdpbmU6IHN0cmluZykge1xuICByZXR1cm4gYXBwbHkobWV0YWRhdGEoUmVuZGVyaW5nRW5naW5lLmtleShVSUtleXMuUkVOREVSRURfQlkpLCBlbmdpbmUpKTtcbn1cblxuLyoqXG4gKiBUYWdzIHRoZSBtb2RlbCBhcyBhIGxpc3QgaXRlbSBmb3IgVUkgcmVuZGVyaW5nLCBzcGVjaWZ5aW5nIGhvdyBpdCBzaG91bGQgYmUgcmVuZGVyZWQgaW4gbGlzdCBjb250ZXh0c1xuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBbdGFnXSBvcHRpb25hbCBwYXJhbS4gd2lsbCByZW5kZXIgdGhlIHByb3ZpZGVkIGVsZW1lbnQgYXMgdGhlIGxpc3QgaXRlbSBjb250YWluZXJcbiAqIEBwYXJhbSB7e319IFtwcm9wc10gb3B0aW9uYWwgcGFyYW0uIEF0dHJpYnV0ZXMgdG8gYmUgcGFzc2VkIHRvIHRoZSB0YWcgZWxlbWVudFxuICpcbiAqIEBkZWNvcmF0b3IgdWlsaXN0aXRlbVxuICpcbiAqIEBtZXJtYWlkXG4gKiBzZXF1ZW5jZURpYWdyYW1cbiAqICAgcGFydGljaXBhbnQgU3lzdGVtXG4gKiAgIHBhcnRpY2lwYW50IHVpbGlzdGl0ZW1cbiAqICAgcGFydGljaXBhbnQgTW9kZWxcbiAqICAgU3lzdGVtLT4+dWlsaXN0aXRlbTogYXBwbHkgdG8gTW9kZWxcbiAqICAgdWlsaXN0aXRlbS0+Pk1vZGVsOiBhZGRzIGxpc3QgaXRlbSBtZXRhZGF0YVxuICogICBNb2RlbC0+PlN5c3RlbTogcmV0dXJucyBNb2RlbCB3aXRoIGxpc3QgaXRlbSByZW5kZXJpbmcgY2FwYWJpbGl0aWVzXG4gKlxuICogQGNhdGVnb3J5IERlY29yYXRvcnNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHVpbGlzdGl0ZW0odGFnPzogc3RyaW5nLCAgcHJvcHM/OiBSZWNvcmQ8c3RyaW5nLCBhbnk+KSB7XG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnNcbiAgcmV0dXJuIChvcmlnaW5hbDogYW55LCBwcm9wZXJ0eUtleT86IGFueSkgPT4ge1xuICAgIGNvbnN0IG1ldGE6IFVJTGlzdEl0ZW1Nb2RlbE1ldGFkYXRhID0geyBcbiAgICAgIGl0ZW06IHtcbiAgICAgICAgdGFnOiB0YWcgfHwgb3JpZ2luYWwubmFtZSxcbiAgICAgICAgcHJvcHM6IHByb3BzLFxuICAgICAgfSBcbiAgICAgIFxuICAgIH07XG4gICAgcmV0dXJuIG1ldGFkYXRhKFJlbmRlcmluZ0VuZ2luZS5rZXkoVUlLZXlzLlVJTElTVElURU0pLCBtZXRhKShvcmlnaW5hbCk7XG4gIH07XG59IiwiaW1wb3J0IHsgTW9kZWwgfSBmcm9tIFwiQGRlY2FmLXRzL2RlY29yYXRvci12YWxpZGF0aW9uXCI7XG5pbXBvcnQgeyBSZW5kZXJpbmdFbmdpbmUgfSBmcm9tIFwiLi4vdWkvUmVuZGVyaW5nXCI7XG5cbk1vZGVsLnByb3RvdHlwZS5yZW5kZXIgPSBmdW5jdGlvbiA8TSBleHRlbmRzIE1vZGVsPih0aGlzOiBNLCAuLi5hcmdzOiBhbnlbXSkge1xuICByZXR1cm4gUmVuZGVyaW5nRW5naW5lLnJlbmRlcih0aGlzLCAuLi5hcmdzKTtcbn07XG4iLCJpbXBvcnQgXCJyZWZsZWN0LW1ldGFkYXRhXCI7XG5pbXBvcnQgeyBVSUtleXMgfSBmcm9tIFwiLi9jb25zdGFudHNcIjtcbmltcG9ydCB7IHByb3BNZXRhZGF0YSB9IGZyb20gXCJAZGVjYWYtdHMvZGVjb3JhdG9yLXZhbGlkYXRpb25cIjtcbmltcG9ydCB7IENydWRPcGVyYXRpb25LZXlzLCBVSUVsZW1lbnRNZXRhZGF0YSwgVUlMaXN0UHJvcE1ldGFkYXRhLCBVSVByb3BNZXRhZGF0YSB9IGZyb20gXCIuL3R5cGVzXCI7XG5pbXBvcnQgeyBSZW5kZXJpbmdFbmdpbmUgfSBmcm9tIFwiLi9SZW5kZXJpbmdcIjtcbmltcG9ydCB7IE9wZXJhdGlvbktleXMgfSBmcm9tIFwiQGRlY2FmLXRzL2RiLWRlY29yYXRvcnNcIjtcblxuLyoqXG4gKiBAbmFtZXNwYWNlIHVpLWRlY29yYXRvcnMudWkuZGVjb3JhdG9yc1xuICogQG1lbWJlck9mIHVpLWRlY29yYXRvcnMudWlcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gaGlkZU9uKC4uLm9wZXJhdGlvbnM6IENydWRPcGVyYXRpb25LZXlzW10pIHtcbiAgcmV0dXJuIHByb3BNZXRhZGF0YTxDcnVkT3BlcmF0aW9uS2V5c1tdPihcbiAgICBSZW5kZXJpbmdFbmdpbmUua2V5KFVJS2V5cy5ISURERU4pLFxuICAgIG9wZXJhdGlvbnNcbiAgKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGhpZGRlbigpIHtcbiAgcmV0dXJuIGhpZGVPbihcbiAgICBPcGVyYXRpb25LZXlzLkNSRUFURSxcbiAgICBPcGVyYXRpb25LZXlzLlJFQUQsXG4gICAgT3BlcmF0aW9uS2V5cy5VUERBVEUsXG4gICAgT3BlcmF0aW9uS2V5cy5ERUxFVEVcbiAgKTtcbn1cblxuLyoqXG4gKiBBZGRzIHRoZSBVSUVsZW1lbnQgZGVmaW5pdGlvbiBhcyBtZXRhZGF0YSB0byB0aGUgcHJvcGVydHksIGFsbG93aW5nIGl0IHRvIGJlIHJlYWQgYnkgYW55IHtAbGluayBSZW5kZXJTdHJhdGVneX1cbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gdGFnIFRoZSBjb21wb25lbnQvSFRNTCBlbGVtZW50IHRhZyBuYW1lXG4gKiBAcGFyYW0ge3t9fSBbcHJvcHNdIFRoZSBwcm9wZXJ0aWVzIHRvIHBhc3MgdG8gdGhhdCBjb21wb25lbnQvSFRNTCBFbGVtZW50XG4gKiBAcGFyYW0gc2VyaWFsaXplXG4gKlxuICogQGRlY29yYXRvciB1aWVsZW1lbnRcbiAqXG4gKiBAY2F0ZWdvcnkgRGVjb3JhdG9yc1xuICogQHN1YmNhdGVnb3J5IHVpLWRlY29yYXRvcnNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHVpZWxlbWVudChcbiAgdGFnOiBzdHJpbmcsXG4gIHByb3BzPzogUmVjb3JkPHN0cmluZywgYW55PixcbiAgc2VyaWFsaXplOiBib29sZWFuID0gZmFsc2Vcbikge1xuICByZXR1cm4gKG9yaWdpbmFsOiBhbnksIHByb3BlcnR5S2V5PzogYW55KSA9PiB7XG4gICAgY29uc3QgbWV0YWRhdGE6IFVJRWxlbWVudE1ldGFkYXRhID0ge1xuICAgICAgdGFnOiB0YWcsXG4gICAgICBzZXJpYWxpemU6IHNlcmlhbGl6ZSxcbiAgICAgIHByb3BzOiBPYmplY3QuYXNzaWduKFxuICAgICAgICB7XG4gICAgICAgICAgbmFtZTogcHJvcGVydHlLZXksXG4gICAgICAgIH0sXG4gICAgICAgIHByb3BzIHx8IHt9XG4gICAgICApLFxuICAgIH07XG5cbiAgICByZXR1cm4gcHJvcE1ldGFkYXRhKFJlbmRlcmluZ0VuZ2luZS5rZXkoVUlLZXlzLkVMRU1FTlQpLCBtZXRhZGF0YSkoXG4gICAgICBvcmlnaW5hbCxcbiAgICAgIHByb3BlcnR5S2V5XG4gICAgKTtcbiAgfTtcbn1cblxuLyoqXG4gKiBBZGRzIHRoZSBVSVByb3AgZGVmaW5pdGlvbiBhcyBtZXRhZGF0YSB0byB0aGUgcHJvcGVydHksIGFsbG93aW5nIGl0IHRvIGJlIHJlYWQgYnkgYW55IHtAbGluayBSZW5kZXJTdHJhdGVneX1cbiAqXG4gKiB0aGlzIHJlcXVpcmVzIGEgJ0B1aW1vZGVsJyB3aXRoIGEgZGVmaW5lZCB0YWdcbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gW3Byb3BOYW1lXSB0aGUgcHJvcGVydHkgbmFtZSB0aGF0IHdpbGwgYmUgcGFzc2VkIHRvIHRoZSBjb21wb25lbnQuIGRlZmF1bHRzIHRvIHRoZSBQcm9wZXJ0eUtleVxuICpcbiAqIEBkZWNvcmF0b3IgdWlwcm9wXG4gKlxuICogQGNhdGVnb3J5IERlY29yYXRvcnNcbiAqIEBzdWJjYXRlZ29yeSB1aS1kZWNvcmF0b3JzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB1aXByb3AoXG4gIHByb3BOYW1lOiBzdHJpbmcgfCB1bmRlZmluZWQgPSB1bmRlZmluZWQsXG4gIHN0cmluZ2lmeTogYm9vbGVhbiA9IGZhbHNlXG4pIHtcbiAgcmV0dXJuICh0YXJnZXQ6IGFueSwgcHJvcGVydHlLZXk6IHN0cmluZykgPT4ge1xuICAgIGNvbnN0IG1ldGFkYXRhOiBVSVByb3BNZXRhZGF0YSA9IHtcbiAgICAgIG5hbWU6IHByb3BOYW1lIHx8IHByb3BlcnR5S2V5LFxuICAgICAgc3RyaW5naWZ5OiBzdHJpbmdpZnksXG4gICAgfTtcbiAgICBwcm9wTWV0YWRhdGEoUmVuZGVyaW5nRW5naW5lLmtleShVSUtleXMuUFJPUCksIG1ldGFkYXRhKShcbiAgICAgIHRhcmdldCxcbiAgICAgIHByb3BlcnR5S2V5XG4gICAgKTtcbiAgfTtcbn1cblxuXG4vKipcbiAqIEFkZHMgdGhlIFVJTGlzdFByb3AgZGVmaW5pdGlvbiBhcyBtZXRhZGF0YSB0byB0aGUgcHJvcGVydHksIGFsbG93aW5nIGl0IHRvIGJlIHJlYWQgYnkgYW55IHtAbGluayBSZW5kZXJTdHJhdGVneX1cbiAqXG4gKiB0aGlzIHJlcXVpcmVzIGEgJ0B1aWxpc3RpdGVtJyB3aXRoIGEgZGVmaW5lZCB0YWdcbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gW3Byb3BOYW1lXSB0aGUgcHJvcGVydHkgbmFtZSB0aGF0IHdpbGwgYmUgcGFzc2VkIHRvIHRoZSBjb21wb25lbnQuIGRlZmF1bHRzIHRvIHRoZSBQcm9wZXJ0eUtleVxuICpcbiAqIEBkZWNvcmF0b3IgdWlwcm9wXG4gKlxuICogQGNhdGVnb3J5IERlY29yYXRvcnNcbiAqIEBzdWJjYXRlZ29yeSB1aS1kZWNvcmF0b3JzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB1aWxpc3Rwcm9wKFxuICBwcm9wTmFtZTogc3RyaW5nIHwgdW5kZWZpbmVkID0gdW5kZWZpbmVkLFxuICBwcm9wcz86IFJlY29yZDxzdHJpbmcsIGFueT4sXG4pIHtcbiAgcmV0dXJuICh0YXJnZXQ6IGFueSwgcHJvcGVydHlLZXk6IHN0cmluZykgPT4ge1xuICAgICAgY29uc3QgbWV0YWRhdGE6IFBhcnRpYWw8VUlMaXN0UHJvcE1ldGFkYXRhPiA9IHtcbiAgICAgIG5hbWU6IHByb3BOYW1lIHx8IHByb3BlcnR5S2V5LFxuICAgICAgcHJvcHM6IHByb3BzIHx8IHt9XG4gICAgfTtcbiAgICBwcm9wTWV0YWRhdGEoUmVuZGVyaW5nRW5naW5lLmtleShVSUtleXMuVUlMSVNUUFJPUCksIG1ldGFkYXRhKShcbiAgICAgIHRhcmdldCxcbiAgICAgIHByb3BlcnR5S2V5XG4gICAgKTtcbiAgfTtcbn1cbiIsIi8qKlxuICogQG1vZHVsZSB1aS1kZWNvcmF0b3JzXG4gKi9cblxuZXhwb3J0ICogZnJvbSBcIi4vbW9kZWxcIjtcbmV4cG9ydCAqIGZyb20gXCIuL3VpXCI7XG5cbi8qKlxuICogQHN1bW1hcnkgc3RvcmVzIHRoZSBjdXJyZW50IHBhY2thZ2UgdmVyc2lvblxuICogQGRlc2NyaXB0aW9uIHRoaXMgaXMgaG93IHlvdSBzaG91bGQgZG9jdW1lbnQgYSBjb25zdGFudFxuICogQGNvbnN0IFZFUlNJT05cbiAqIEBtZW1iZXJPZiBtb2R1bGU6dWktZGVjb3JhdG9yc1xuICovXG5leHBvcnQgY29uc3QgVkVSU0lPTiA9IFwiIyNWRVJTSU9OIyNcIjtcbiJdLCJuYW1lcyI6WyJNb2RlbEtleXMiLCJWYWxpZGF0aW9uS2V5cyIsIkVtYWlsVmFsaWRhdG9yIiwiVVJMVmFsaWRhdG9yIiwiRGF0ZVZhbGlkYXRvciIsIlBhc3N3b3JkVmFsaWRhdG9yIiwiUmVxdWlyZWRWYWxpZGF0b3IiLCJNaW5WYWxpZGF0b3IiLCJNYXhWYWxpZGF0b3IiLCJTdGVwVmFsaWRhdG9yIiwiTWluTGVuZ3RoVmFsaWRhdG9yIiwiTWF4TGVuZ3RoVmFsaWRhdG9yIiwiUGF0dGVyblZhbGlkYXRvciIsIkVxdWFsc1ZhbGlkYXRvciIsIkRpZmZWYWxpZGF0b3IiLCJMZXNzVGhhblZhbGlkYXRvciIsIkxlc3NUaGFuT3JFcXVhbFZhbGlkYXRvciIsIkdyZWF0ZXJUaGFuVmFsaWRhdG9yIiwiR3JlYXRlclRoYW5PckVxdWFsVmFsaWRhdG9yIiwiQmFzZUVycm9yIiwiZm9ybWF0RGF0ZSIsIlJlc2VydmVkTW9kZWxzIiwicGFyc2VEYXRlIiwiSW50ZXJuYWxFcnJvciIsImZpbmRNb2RlbElkIiwiTW9kZWwiLCJSZWZsZWN0aW9uIiwibWV0YWRhdGEiLCJhcHBseSIsInByb3BNZXRhZGF0YSIsIk9wZXJhdGlvbktleXMiXSwibWFwcGluZ3MiOiI7Ozs7OztJQXdCQTs7O0lBR0c7QUFDVSxVQUFBLE1BQU0sR0FBRztJQUNwQixJQUFBLE9BQU8sRUFBRSxDQUFBLEVBQUdBLDZCQUFTLENBQUMsT0FBTyxDQUFNLElBQUEsQ0FBQTtJQUNuQyxJQUFBLE9BQU8sRUFBRSxTQUFTO0lBQ2xCLElBQUEsV0FBVyxFQUFFLGFBQWE7SUFDMUIsSUFBQSxPQUFPLEVBQUUsU0FBUztJQUNsQixJQUFBLElBQUksRUFBRSxNQUFNO0lBQ1osSUFBQSxJQUFJLEVBQUUsTUFBTTtJQUNaLElBQUEsV0FBVyxFQUFFLFFBQVE7SUFDckIsSUFBQSxZQUFZLEVBQUUsdUJBQXVCO0lBRXJDLElBQUEsVUFBVSxFQUFFLFlBQVk7SUFDeEIsSUFBQSxVQUFVLEVBQUUsVUFBVTtJQUV0QixJQUFBLElBQUksRUFBRSxNQUFNO0lBQ1osSUFBQSxRQUFRLEVBQUUs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
1145
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidWktZGVjb3JhdG9ycy5janMiLCJzb3VyY2VzIjpbIi4uL3NyYy91aS9jb25zdGFudHMudHMiLCIuLi9zcmMvdWkvZXJyb3JzLnRzIiwiLi4vc3JjL3VpL3V0aWxzLnRzIiwiLi4vc3JjL3VpL1JlbmRlcmluZy50cyIsIi4uL3NyYy9tb2RlbC9kZWNvcmF0b3JzLnRzIiwiLi4vc3JjL21vZGVsL292ZXJyaWRlcy50cyIsIi4uL3NyYy91aS9kZWNvcmF0b3JzLnRzIiwiLi4vc3JjL2luZGV4LnRzIl0sInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQGRlc2NyaXB0aW9uIENvbnN0YW50cyBhbmQgZW51bXMgZm9yIFVJIHJlbmRlcmluZyBhbmQgdmFsaWRhdGlvblxuICogQHN1bW1hcnkgRGVmaW5lcyBrZXlzLCBtYXBwaW5ncywgYW5kIEhUTUw1IGlucHV0IHR5cGVzIGZvciBVSSBjb21wb25lbnRzXG4gKiBUaGlzIG1vZHVsZSBwcm92aWRlcyBjb25zdGFudHMgdXNlZCB0aHJvdWdob3V0IHRoZSBVSSBkZWNvcmF0b3JzIGxpYnJhcnkgZm9yXG4gKiByZW5kZXJpbmcsIHZhbGlkYXRpb24sIGFuZCBIVE1MIGVsZW1lbnQgZ2VuZXJhdGlvbi5cbiAqIEBtb2R1bGUgdWkvY29uc3RhbnRzXG4gKiBAbWVtYmVyT2YgbW9kdWxlOnVpLWRlY29yYXRvcnNcbiAqL1xuXG5pbXBvcnQge1xuICBDb25zdHJ1Y3RvcixcbiAgRGF0ZVZhbGlkYXRvcixcbiAgRGlmZlZhbGlkYXRvcixcbiAgRW1haWxWYWxpZGF0b3IsXG4gIEVxdWFsc1ZhbGlkYXRvcixcbiAgR3JlYXRlclRoYW5PckVxdWFsVmFsaWRhdG9yLFxuICBHcmVhdGVyVGhhblZhbGlkYXRvcixcbiAgTGVzc1RoYW5PckVxdWFsVmFsaWRhdG9yLFxuICBMZXNzVGhhblZhbGlkYXRvcixcbiAgTWF4TGVuZ3RoVmFsaWRhdG9yLFxuICBNYXhWYWxpZGF0b3IsXG4gIE1pbkxlbmd0aFZhbGlkYXRvcixcbiAgTWluVmFsaWRhdG9yLFxuICBNb2RlbEtleXMsXG4gIFBhc3N3b3JkVmFsaWRhdG9yLFxuICBQYXR0ZXJuVmFsaWRhdG9yLFxuICBSZXF1aXJlZFZhbGlkYXRvcixcbiAgU3RlcFZhbGlkYXRvcixcbiAgVVJMVmFsaWRhdG9yLFxuICBWYWxpZGF0aW9uS2V5cyxcbiAgVmFsaWRhdG9yLFxufSBmcm9tIFwiQGRlY2FmLXRzL2RlY29yYXRvci12YWxpZGF0aW9uXCI7XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIEtleSBjb25zdGFudHMgdXNlZCBmb3IgVUkgbWV0YWRhdGEgYW5kIHJlbmRlcmluZ1xuICogQHN1bW1hcnkgQ29sbGVjdGlvbiBvZiBzdHJpbmcgY29uc3RhbnRzIHVzZWQgYXMga2V5cyBmb3IgVUktcmVsYXRlZCBtZXRhZGF0YVxuICogVGhlc2Uga2V5cyBhcmUgdXNlZCB0aHJvdWdob3V0IHRoZSBsaWJyYXJ5IHRvIHN0b3JlIGFuZCByZXRyaWV2ZSBtZXRhZGF0YSByZWxhdGVkIHRvXG4gKiBVSSBtb2RlbHMsIGVsZW1lbnRzLCBwcm9wZXJ0aWVzLCBhbmQgdmFsaWRhdGlvbiBydWxlcy5cbiAqXG4gKiBAdHlwZWRlZiB7T2JqZWN0fSBVSUtleXNUeXBlXG4gKiBAcHJvcGVydHkge3N0cmluZ30gUkVGTEVDVCAtIEJhc2UgcmVmbGVjdGlvbiBrZXkgZm9yIFVJIG1ldGFkYXRhXG4gKiBAcHJvcGVydHkge3N0cmluZ30gVUlNT0RFTCAtIEtleSBmb3IgVUkgbW9kZWwgbWV0YWRhdGFcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBSRU5ERVJFRF9CWSAtIEtleSBmb3Igc3BlY2lmeWluZyByZW5kZXJpbmcgZW5naW5lXG4gKiBAcHJvcGVydHkge3N0cmluZ30gRUxFTUVOVCAtIEtleSBmb3IgZWxlbWVudCBtZXRhZGF0YVxuICogQHByb3BlcnR5IHtzdHJpbmd9IFBST1AgLSBLZXkgZm9yIHByb3BlcnR5IG1ldGFkYXRhXG4gKiBAcHJvcGVydHkge3N0cmluZ30gTkFNRSAtIEtleSBmb3IgbmFtZSBhdHRyaWJ1dGVcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBOQU1FX1BSRUZJWCAtIFByZWZpeCBmb3IgaW5wdXQgbmFtZXNcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBDVVNUT01fUFJPUFMgLSBLZXkgZm9yIGN1c3RvbSB2YWxpZGF0aW9uIHByb3BlcnRpZXNcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBVSUxJU1RJVEVNIC0gS2V5IGZvciBsaXN0IGl0ZW0gbWV0YWRhdGFcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBVSUxJU1RQUk9QIC0gS2V5IGZvciBsaXN0IHByb3BlcnR5IG1ldGFkYXRhXG4gKiBAcHJvcGVydHkge3N0cmluZ30gVFlQRSAtIEtleSBmb3IgdHlwZSBtZXRhZGF0YVxuICogQHByb3BlcnR5IHtzdHJpbmd9IFNVQl9UWVBFIC0gS2V5IGZvciBzdWJ0eXBlIG1ldGFkYXRhXG4gKiBAcHJvcGVydHkge3N0cmluZ30gSElEREVOIC0gS2V5IGZvciBoaWRkZW4gYXR0cmlidXRlXG4gKiBAcHJvcGVydHkge3N0cmluZ30gRk9STUFUIC0gS2V5IGZvciBmb3JtYXQgbWV0YWRhdGFcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBSRUFEX09OTFkgLSBLZXkgZm9yIHJlYWRvbmx5IGF0dHJpYnV0ZVxuICogQHByb3BlcnR5IHtzdHJpbmd9IFJFUVVJUkVEIC0gS2V5IGZvciByZXF1aXJlZCB2YWxpZGF0aW9uXG4gKiBAcHJvcGVydHkge3N0cmluZ30gTUlOIC0gS2V5IGZvciBtaW5pbXVtIHZhbHVlIHZhbGlkYXRpb25cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBNSU5fTEVOR1RIIC0gS2V5IGZvciBtaW5pbXVtIGxlbmd0aCB2YWxpZGF0aW9uXG4gKiBAcHJvcGVydHkge3N0cmluZ30gTUFYIC0gS2V5IGZvciBtYXhpbXVtIHZhbHVlIHZhbGlkYXRpb25cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBNQVhfTEVOR1RIIC0gS2V5IGZvciBtYXhpbXVtIGxlbmd0aCB2YWxpZGF0aW9uXG4gKiBAcHJvcGVydHkge3N0cmluZ30gUEFUVEVSTiAtIEtleSBmb3IgcGF0dGVybiB2YWxpZGF0aW9uXG4gKiBAcHJvcGVydHkge3N0cmluZ30gVVJMIC0gS2V5IGZvciBVUkwgdmFsaWRhdGlvblxuICogQHByb3BlcnR5IHtzdHJpbmd9IFNURVAgLSBLZXkgZm9yIHN0ZXAgdmFsaWRhdGlvblxuICogQHByb3BlcnR5IHtzdHJpbmd9IERBVEUgLSBLZXkgZm9yIGRhdGUgdmFsaWRhdGlvblxuICogQHByb3BlcnR5IHtzdHJpbmd9IEVNQUlMIC0gS2V5IGZvciBlbWFpbCB2YWxpZGF0aW9uXG4gKiBAcHJvcGVydHkge3N0cmluZ30gUEFTU1dPUkQgLSBLZXkgZm9yIHBhc3N3b3JkIHZhbGlkYXRpb25cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBFUVVBTFMgLSBLZXkgZm9yIGVxdWFsaXR5IHZhbGlkYXRpb25cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBESUZGIC0gS2V5IGZvciBkaWZmZXJlbmNlIHZhbGlkYXRpb25cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBMRVNTX1RIQU4gLSBLZXkgZm9yIGxlc3MgdGhhbiB2YWxpZGF0aW9uXG4gKiBAcHJvcGVydHkge3N0cmluZ30gTEVTU19USEFOX09SX0VRVUFMIC0gS2V5IGZvciBsZXNzIHRoYW4gb3IgZXF1YWwgdmFsaWRhdGlvblxuICogQHByb3BlcnR5IHtzdHJpbmd9IEdSRUFURVJfVEhBTiAtIEtleSBmb3IgZ3JlYXRlciB0aGFuIHZhbGlkYXRpb25cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBHUkVBVEVSX1RIQU5fT1JfRVFVQUwgLSBLZXkgZm9yIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB2YWxpZGF0aW9uXG4gKlxuICogQGNvbnN0IFVJS2V5c1xuICogQHR5cGUge1VJS2V5c1R5cGV9XG4gKiBAcmVhZG9ubHlcbiAqIEBtZW1iZXJPZiBtb2R1bGU6dWktZGVjb3JhdG9yc1xuICovXG5leHBvcnQgY29uc3QgVUlLZXlzID0ge1xuICBSRUZMRUNUOiBgJHtNb2RlbEtleXMuUkVGTEVDVH0udWkuYCxcbiAgVUlNT0RFTDogXCJ1aW1vZGVsXCIsXG4gIFJFTkRFUkVEX0JZOiBcInJlbmRlcmVkLWJ5XCIsXG4gIEVMRU1FTlQ6IFwiZWxlbWVudFwiLFxuICBQUk9QOiBcInByb3BcIixcbiAgTkFNRTogXCJuYW1lXCIsXG4gIE5BTUVfUFJFRklYOiBcImlucHV0LVwiLFxuICBDVVNUT01fUFJPUFM6IFwiY3VzdG9tVmFsaWRhdGlvblByb3BzXCIsXG5cbiAgVUlMSVNUSVRFTTogXCJ1aWxpc3RpdGVtXCIsXG4gIFVJTElTVFBST1A6IFwibGlzdHByb3BcIixcblxuICBUWVBFOiBcInR5cGVcIixcbiAgU1VCX1RZUEU6IFwic3VidHlwZVwiLFxuXG4gIEhJRERFTjogXCJoaWRkZW5cIixcbiAgRk9STUFUOiBcImZvcm1hdFwiLFxuXG4gIFJFQURfT05MWTogXCJyZWFkb25seVwiLFxuICBSRVFVSVJFRDogVmFsaWRhdGlvbktleXMuUkVRVUlSRUQsXG4gIE1JTjogVmFsaWRhdGlvbktleXMuTUlOLFxuICBNSU5fTEVOR1RIOiBWYWxpZGF0aW9uS2V5cy5NSU5fTEVOR1RILFxuICBNQVg6IFZhbGlkYXRpb25LZXlzLk1BWCxcbiAgTUFYX0xFTkdUSDogVmFsaWRhdGlvbktleXMuTUFYX0xFTkdUSCxcbiAgUEFUVEVSTjogVmFsaWRhdGlvbktleXMuUEFUVEVSTixcbiAgVVJMOiBWYWxpZGF0aW9uS2V5cy5VUkwsXG4gIFNURVA6IFZhbGlkYXRpb25LZXlzLlNURVAsXG4gIERBVEU6IFZhbGlkYXRpb25LZXlzLkRBVEUsXG4gIEVNQUlMOiBWYWxpZGF0aW9uS2V5cy5FTUFJTCxcbiAgUEFTU1dPUkQ6IFZhbGlkYXRpb25LZXlzLlBBU1NXT1JELFxuICBFUVVBTFM6IFZhbGlkYXRpb25LZXlzLkVRVUFMUyxcbiAgRElGRjogVmFsaWRhdGlvbktleXMuRElGRixcbiAgTEVTU19USEFOOiBWYWxpZGF0aW9uS2V5cy5MRVNTX1RIQU4sXG4gIExFU1NfVEhBTl9PUl9FUVVBTDogVmFsaWRhdGlvbktleXMuTEVTU19USEFOX09SX0VRVUFMLFxuICBHUkVBVEVSX1RIQU46IFZhbGlkYXRpb25LZXlzLkdSRUFURVJfVEhBTixcbiAgR1JFQVRFUl9USEFOX09SX0VRVUFMOiBWYWxpZGF0aW9uS2V5cy5HUkVBVEVSX1RIQU5fT1JfRVFVQUwsXG59O1xuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBNYXBwaW5nIG9mIGlucHV0IHR5cGVzIHRvIHRoZWlyIGNvcnJlc3BvbmRpbmcgdmFsaWRhdG9yc1xuICogQHN1bW1hcnkgTWFwcyBzcGVjaWFsIGlucHV0IHR5cGVzIHRvIHRoZWlyIHZhbGlkYXRvciBjbGFzc2VzXG4gKiBUaGlzIGNvbnN0YW50IG1hcHMgaW5wdXQgdHlwZXMgbGlrZSBlbWFpbCwgVVJMLCBkYXRlLCBhbmQgcGFzc3dvcmQgdG8gdGhlaXJcbiAqIGNvcnJlc3BvbmRpbmcgdmFsaWRhdG9yIGNsYXNzZXMgZnJvbSB0aGUgZGVjb3JhdG9yLXZhbGlkYXRpb24gbGlicmFyeS5cbiAqXG4gKiBAdHlwZWRlZiB7T2JqZWN0LjxzdHJpbmcsIENvbnN0cnVjdG9yPFZhbGlkYXRvcj4+fSBWYWxpZGF0YWJsZUJ5VHlwZU1hcFxuICogQHByb3BlcnR5IHtDb25zdHJ1Y3RvcjxFbWFpbFZhbGlkYXRvcj59IGVtYWlsIC0gVmFsaWRhdG9yIGZvciBlbWFpbCBpbnB1dHNcbiAqIEBwcm9wZXJ0eSB7Q29uc3RydWN0b3I8VVJMVmFsaWRhdG9yPn0gdXJsIC0gVmFsaWRhdG9yIGZvciBVUkwgaW5wdXRzXG4gKiBAcHJvcGVydHkge0NvbnN0cnVjdG9yPERhdGVWYWxpZGF0b3I+fSBkYXRlIC0gVmFsaWRhdG9yIGZvciBkYXRlIGlucHV0c1xuICogQHByb3BlcnR5IHtDb25zdHJ1Y3RvcjxQYXNzd29yZFZhbGlkYXRvcj59IHBhc3N3b3JkIC0gVmFsaWRhdG9yIGZvciBwYXNzd29yZCBpbnB1dHNcbiAqXG4gKiBAY29uc3QgVmFsaWRhdGFibGVCeVR5cGVcbiAqIEB0eXBlIHtWYWxpZGF0YWJsZUJ5VHlwZU1hcH1cbiAqIEByZWFkb25seVxuICogQG1lbWJlck9mIG1vZHVsZTp1aS1kZWNvcmF0b3JzXG4gKi9cbmV4cG9ydCBjb25zdCBWYWxpZGF0YWJsZUJ5VHlwZTogUmVjb3JkPHN0cmluZywgQ29uc3RydWN0b3I8VmFsaWRhdG9yPj4gPSB7XG4gIFtVSUtleXMuRU1BSUxdOiBFbWFpbFZhbGlkYXRvcixcbiAgW1VJS2V5cy5VUkxdOiBVUkxWYWxpZGF0b3IsXG4gIFtVSUtleXMuREFURV06IERhdGVWYWxpZGF0b3IsXG4gIFtVSUtleXMuUEFTU1dPUkRdOiBQYXNzd29yZFZhbGlkYXRvcixcbn07XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIE1hcHBpbmcgb2YgdmFsaWRhdGlvbiBhdHRyaWJ1dGVzIHRvIHRoZWlyIGNvcnJlc3BvbmRpbmcgdmFsaWRhdG9yc1xuICogQHN1bW1hcnkgTWFwcyBIVE1MIHZhbGlkYXRpb24gYXR0cmlidXRlcyB0byB0aGVpciB2YWxpZGF0b3IgY2xhc3Nlc1xuICogVGhpcyBjb25zdGFudCBtYXBzIEhUTUwgdmFsaWRhdGlvbiBhdHRyaWJ1dGVzIGxpa2UgcmVxdWlyZWQsIG1pbiwgbWF4LCBwYXR0ZXJuLCBldGMuXG4gKiB0byB0aGVpciBjb3JyZXNwb25kaW5nIHZhbGlkYXRvciBjbGFzc2VzIGZyb20gdGhlIGRlY29yYXRvci12YWxpZGF0aW9uIGxpYnJhcnkuXG4gKlxuICogQHR5cGVkZWYge09iamVjdC48c3RyaW5nLCBDb25zdHJ1Y3RvcjxWYWxpZGF0b3I+Pn0gVmFsaWRhdGFibGVCeUF0dHJpYnV0ZU1hcFxuICogQHByb3BlcnR5IHtDb25zdHJ1Y3RvcjxSZXF1aXJlZFZhbGlkYXRvcj59IHJlcXVpcmVkIC0gVmFsaWRhdG9yIGZvciByZXF1aXJlZCBmaWVsZHNcbiAqIEBwcm9wZXJ0eSB7Q29uc3RydWN0b3I8TWluVmFsaWRhdG9yPn0gbWluIC0gVmFsaWRhdG9yIGZvciBtaW5pbXVtIHZhbHVlXG4gKiBAcHJvcGVydHkge0NvbnN0cnVjdG9yPE1heFZhbGlkYXRvcj59IG1heCAtIFZhbGlkYXRvciBmb3IgbWF4aW11bSB2YWx1ZVxuICogQHByb3BlcnR5IHtDb25zdHJ1Y3RvcjxTdGVwVmFsaWRhdG9yPn0gc3RlcCAtIFZhbGlkYXRvciBmb3Igc3RlcCB2YWx1ZVxuICogQHByb3BlcnR5IHtDb25zdHJ1Y3RvcjxNaW5MZW5ndGhWYWxpZGF0b3I+fSBtaW5sZW5ndGggLSBWYWxpZGF0b3IgZm9yIG1pbmltdW0gbGVuZ3RoXG4gKiBAcHJvcGVydHkge0NvbnN0cnVjdG9yPE1heExlbmd0aFZhbGlkYXRvcj59IG1heGxlbmd0aCAtIFZhbGlkYXRvciBmb3IgbWF4aW11bSBsZW5ndGhcbiAqIEBwcm9wZXJ0eSB7Q29uc3RydWN0b3I8UGF0dGVyblZhbGlkYXRvcj59IHBhdHRlcm4gLSBWYWxpZGF0b3IgZm9yIHJlZ2V4IHBhdHRlcm5cbiAqIEBwcm9wZXJ0eSB7Q29uc3RydWN0b3I8RXF1YWxzVmFsaWRhdG9yPn0gZXF1YWxzIC0gVmFsaWRhdG9yIGZvciBlcXVhbGl0eVxuICogQHByb3BlcnR5IHtDb25zdHJ1Y3RvcjxEaWZmVmFsaWRhdG9yPn0gZGlmZiAtIFZhbGlkYXRvciBmb3IgZGlmZmVyZW5jZVxuICogQHByb3BlcnR5IHtDb25zdHJ1Y3RvcjxMZXNzVGhhblZhbGlkYXRvcj59IGxlc3N0aGFuIC0gVmFsaWRhdG9yIGZvciBsZXNzIHRoYW4gY29tcGFyaXNvblxuICogQHByb3BlcnR5IHtDb25zdHJ1Y3RvcjxMZXNzVGhhbk9yRXF1YWxWYWxpZGF0b3I+fSBsZXNzdGhhbm9yZXF1YWwgLSBWYWxpZGF0b3IgZm9yIGxlc3MgdGhhbiBvciBlcXVhbCBjb21wYXJpc29uXG4gKiBAcHJvcGVydHkge0NvbnN0cnVjdG9yPEdyZWF0ZXJUaGFuVmFsaWRhdG9yPn0gZ3JlYXRlcnRoYW4gLSBWYWxpZGF0b3IgZm9yIGdyZWF0ZXIgdGhhbiBjb21wYXJpc29uXG4gKiBAcHJvcGVydHkge0NvbnN0cnVjdG9yPEdyZWF0ZXJUaGFuT3JFcXVhbFZhbGlkYXRvcj59IGdyZWF0ZXJ0aGFub3JlcXVhbCAtIFZhbGlkYXRvciBmb3IgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIGNvbXBhcmlzb25cbiAqXG4gKiBAY29uc3QgVmFsaWRhdGFibGVCeUF0dHJpYnV0ZVxuICogQHR5cGUge1ZhbGlkYXRhYmxlQnlBdHRyaWJ1dGVNYXB9XG4gKiBAcmVhZG9ubHlcbiAqIEBtZW1iZXJPZiBtb2R1bGU6dWktZGVjb3JhdG9yc1xuICovXG5leHBvcnQgY29uc3QgVmFsaWRhdGFibGVCeUF0dHJpYnV0ZTogUmVjb3JkPHN0cmluZywgQ29uc3RydWN0b3I8VmFsaWRhdG9yPj4gPSB7XG4gIFtVSUtleXMuUkVRVUlSRURdOiBSZXF1aXJlZFZhbGlkYXRvcixcbiAgW1VJS2V5cy5NSU5dOiBNaW5WYWxpZGF0b3IsXG4gIFtVSUtleXMuTUFYXTogTWF4VmFsaWRhdG9yLFxuICBbVUlLZXlzLlNURVBdOiBTdGVwVmFsaWRhdG9yLFxuICBbVUlLZXlzLk1JTl9MRU5HVEhdOiBNaW5MZW5ndGhWYWxpZGF0b3IsXG4gIFtVSUtleXMuTUFYX0xFTkdUSF06IE1heExlbmd0aFZhbGlkYXRvcixcbiAgW1VJS2V5cy5QQVRURVJOXTogUGF0dGVyblZhbGlkYXRvcixcbiAgW1VJS2V5cy5FUVVBTFNdOiBFcXVhbHNWYWxpZGF0b3IsXG4gIFtVSUtleXMuRElGRl06IERpZmZWYWxpZGF0b3IsXG4gIFtVSUtleXMuTEVTU19USEFOXTogTGVzc1RoYW5WYWxpZGF0b3IsXG4gIFtVSUtleXMuTEVTU19USEFOX09SX0VRVUFMXTogTGVzc1RoYW5PckVxdWFsVmFsaWRhdG9yLFxuICBbVUlLZXlzLkdSRUFURVJfVEhBTl06IEdyZWF0ZXJUaGFuVmFsaWRhdG9yLFxuICBbVUlLZXlzLkdSRUFURVJfVEhBTl9PUl9FUVVBTF06IEdyZWF0ZXJUaGFuT3JFcXVhbFZhbGlkYXRvcixcbn07XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIFN0YW5kYXJkIGRhdGUgZm9ybWF0IHN0cmluZyBmb3IgSFRNTDUgZGF0ZSBpbnB1dHNcbiAqIEBzdW1tYXJ5IEZvcm1hdCBzdHJpbmcgZm9yIEhUTUw1IGRhdGUgaW5wdXRzICh5eXl5LU1NLWRkKVxuICogVGhpcyBjb25zdGFudCBkZWZpbmVzIHRoZSBzdGFuZGFyZCBkYXRlIGZvcm1hdCBzdHJpbmcgdXNlZCBmb3IgSFRNTDUgZGF0ZSBpbnB1dHMuXG4gKlxuICogQGNvbnN0IEhUTUw1RGF0ZUZvcm1hdFxuICogQHR5cGUge3N0cmluZ31cbiAqIEByZWFkb25seVxuICogQG1lbWJlck9mIG1vZHVsZTp1aS1kZWNvcmF0b3JzXG4gKi9cbmV4cG9ydCBjb25zdCBIVE1MNURhdGVGb3JtYXQgPSBcInl5eXktTU0tZGRcIjtcblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gQ29sbGVjdGlvbiBvZiBIVE1MNSBpbnB1dCB0eXBlIHZhbHVlc1xuICogQHN1bW1hcnkgTWFwcyBpbnB1dCB0eXBlIGNvbnN0YW50cyB0byB0aGVpciBIVE1MIGF0dHJpYnV0ZSB2YWx1ZXNcbiAqIFRoaXMgY29uc3RhbnQgcHJvdmlkZXMgYSBtYXBwaW5nIG9mIGlucHV0IHR5cGUgY29uc3RhbnRzIHRvIHRoZWlyIGNvcnJlc3BvbmRpbmdcbiAqIEhUTUwgYXR0cmlidXRlIHZhbHVlcyBmb3IgdXNlIGluIGZvcm0gZWxlbWVudHMuXG4gKlxuICogQHR5cGVkZWYge09iamVjdH0gSFRNTDVJbnB1dFR5cGVzTWFwXG4gKiBAcHJvcGVydHkge3N0cmluZ30gQlVUVE9OIC0gQnV0dG9uIGlucHV0IHR5cGVcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBDSEVDS0JPWCAtIENoZWNrYm94IGlucHV0IHR5cGVcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBDT0xPUiAtIENvbG9yIHBpY2tlciBpbnB1dCB0eXBlXG4gKiBAcHJvcGVydHkge3N0cmluZ30gREFURSAtIERhdGUgcGlja2VyIGlucHV0IHR5cGVcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBEQVRFVElNRV9MT0NBTCAtIExvY2FsIGRhdGV0aW1lIHBpY2tlciBpbnB1dCB0eXBlXG4gKiBAcHJvcGVydHkge3N0cmluZ30gRU1BSUwgLSBFbWFpbCBpbnB1dCB0eXBlIHdpdGggdmFsaWRhdGlvblxuICogQHByb3BlcnR5IHtzdHJpbmd9IEZJTEUgLSBGaWxlIHVwbG9hZCBpbnB1dCB0eXBlXG4gKiBAcHJvcGVydHkge3N0cmluZ30gSElEREVOIC0gSGlkZGVuIGlucHV0IHR5cGVcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBJTUFHRSAtIEltYWdlIGlucHV0IHR5cGVcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBNT05USCAtIE1vbnRoIHBpY2tlciBpbnB1dCB0eXBlXG4gKiBAcHJvcGVydHkge3N0cmluZ30gTlVNQkVSIC0gTnVtZXJpYyBpbnB1dCB0eXBlXG4gKiBAcHJvcGVydHkge3N0cmluZ30gUEFTU1dPUkQgLSBQYXNzd29yZCBpbnB1dCB0eXBlIHdpdGggbWFza2VkIHRleHRcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBSQURJTyAtIFJhZGlvIGJ1dHRvbiBpbnB1dCB0eXBlXG4gKiBAcHJvcGVydHkge3N0cmluZ30gUkFOR0UgLSBSYW5nZSBzbGlkZXIgaW5wdXQgdHlwZVxuICogQHByb3BlcnR5IHtzdHJpbmd9IFJFU0VUIC0gRm9ybSByZXNldCBidXR0b24gaW5wdXQgdHlwZVxuICogQHByb3BlcnR5IHtzdHJpbmd9IFNFQVJDSCAtIFNlYXJjaCBpbnB1dCB0eXBlXG4gKiBAcHJvcGVydHkge3N0cmluZ30gU1VCTUlUIC0gRm9ybSBzdWJtaXQgYnV0dG9uIGlucHV0IHR5cGVcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBURUwgLSBUZWxlcGhvbmUgbnVtYmVyIGlucHV0IHR5cGVcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBURVhUIC0gQmFzaWMgdGV4dCBpbnB1dCB0eXBlXG4gKiBAcHJvcGVydHkge3N0cmluZ30gVElNRSAtIFRpbWUgcGlja2VyIGlucHV0IHR5cGVcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBVUkwgLSBVUkwgaW5wdXQgdHlwZSB3aXRoIHZhbGlkYXRpb25cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBXRUVLIC0gV2VlayBwaWNrZXIgaW5wdXQgdHlwZVxuICpcbiAqIEBjb25zdCBIVE1MNUlucHV0VHlwZXNcbiAqIEB0eXBlIHtIVE1MNUlucHV0VHlwZXNNYXB9XG4gKiBAcmVhZG9ubHlcbiAqIEBtZW1iZXJPZiBtb2R1bGU6dWktZGVjb3JhdG9yc1xuICovXG5leHBvcnQgY29uc3QgSFRNTDVJbnB1dFR5cGVzID0ge1xuICBCVVRUT046IFwiYnV0dG9uXCIsXG4gIENIRUNLQk9YOiBcImNoZWNrYm94XCIsXG4gIENPTE9SOiBcImNvbG9yXCIsXG4gIERBVEU6IFVJS2V5cy5EQVRFLFxuICBEQVRFVElNRV9MT0NBTDogXCJkYXRldGltZS1sb2NhbFwiLFxuICBFTUFJTDogVUlLZXlzLkVNQUlMLFxuICBGSUxFOiBcImZpbGVcIixcbiAgSElEREVOOiBcImhpZGRlblwiLFxuICBJTUFHRTogXCJpbWFnZVwiLFxuICBNT05USDogXCJtb250aFwiLFxuICBOVU1CRVI6IFwibnVtYmVyXCIsXG4gIFBBU1NXT1JEOiBVSUtleXMuUEFTU1dPUkQsXG4gIFJBRElPOiBcInJhZGlvXCIsXG4gIFJBTkdFOiBcInJhbmdlXCIsXG4gIFJFU0VUOiBcInJlc2V0XCIsXG4gIFNFQVJDSDogXCJzZWFyY2hcIixcbiAgU1VCTUlUOiBcInN1Ym1pdFwiLFxuICBURUw6IFwidGVsXCIsXG4gIFRFWFQ6IFwidGV4dFwiLFxuICBUSU1FOiBcInRpbWVcIixcbiAgVVJMOiBVSUtleXMuVVJMLFxuICBXRUVLOiBcIndlZWtcIixcbn07XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIEFycmF5IG9mIEhUTUw1IGlucHV0IHR5cGVzIHRoYXQgdXNlIGNoZWNrYm94ZXNcbiAqIEBzdW1tYXJ5IExpc3Qgb2YgaW5wdXQgdHlwZXMgdGhhdCByZXByZXNlbnQgY2hlY2thYmxlIGNvbnRyb2xzXG4gKiBUaGlzIGNvbnN0YW50IGRlZmluZXMgYW4gYXJyYXkgb2YgSFRNTDUgaW5wdXQgdHlwZXMgdGhhdCByZXByZXNlbnRcbiAqIGNoZWNrYWJsZSBjb250cm9scyAoY2hlY2tib3ggYW5kIHJhZGlvKS5cbiAqXG4gKiBAY29uc3QgSFRNTDVDaGVja1R5cGVzXG4gKiBAdHlwZSB7c3RyaW5nW119XG4gKiBAcmVhZG9ubHlcbiAqIEBtZW1iZXJPZiBtb2R1bGU6dWktZGVjb3JhdG9yc1xuICovXG5leHBvcnQgY29uc3QgSFRNTDVDaGVja1R5cGVzID0gW1xuICBIVE1MNUlucHV0VHlwZXMuQ0hFQ0tCT1gsXG4gIEhUTUw1SW5wdXRUeXBlcy5SQURJTyxcbl07XG4iLCJpbXBvcnQgeyBCYXNlRXJyb3IgfSBmcm9tIFwiQGRlY2FmLXRzL2RiLWRlY29yYXRvcnNcIjtcblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gRXJyb3IgdGhyb3duIHdoZW4gYSByZW5kZXJpbmcgb3BlcmF0aW9uIGZhaWxzXG4gKiBAc3VtbWFyeSBTcGVjaWFsaXplZCBlcnJvciBmb3IgcmVuZGVyaW5nIGZhaWx1cmVzIGluIFVJIGNvbXBvbmVudHNcbiAqIFRoaXMgZXJyb3IgaXMgdGhyb3duIHdoZW4gdGhlIHJlbmRlcmluZyBlbmdpbmUgZW5jb3VudGVycyBhbiBlcnJvciB3aGlsZVxuICogYXR0ZW1wdGluZyB0byByZW5kZXIgYSBVSSBjb21wb25lbnQgb3IgbW9kZWwuXG4gKlxuICogQHBhcmFtIHtzdHJpbmd8RXJyb3J9IG1zZyBUaGUgZXJyb3IgbWVzc2FnZSBvciBvcmlnaW5hbCBlcnJvclxuICpcbiAqIEBjbGFzcyBSZW5kZXJpbmdFcnJvclxuICogQGV4dGVuZHMgQmFzZUVycm9yXG4gKiBAY2F0ZWdvcnkgRXJyb3JzXG4gKlxuICogQGV4YW1wbGVcbiAqIC8vIFRocm93aW5nIGEgcmVuZGVyaW5nIGVycm9yXG4gKiB0cnkge1xuICogICAvLyBSZW5kZXJpbmcgY29kZSB0aGF0IG1pZ2h0IGZhaWxcbiAqICAgaWYgKCFjb21wb25lbnQuY2FuUmVuZGVyKCkpIHtcbiAqICAgICB0aHJvdyBuZXcgUmVuZGVyaW5nRXJyb3IoJ0NvbXBvbmVudCBjYW5ub3QgYmUgcmVuZGVyZWQnKTtcbiAqICAgfVxuICogfSBjYXRjaCAoZXJyb3IpIHtcbiAqICAgY29uc29sZS5lcnJvcignUmVuZGVyaW5nIGZhaWxlZDonLCBlcnJvci5tZXNzYWdlKTtcbiAqIH1cbiAqL1xuZXhwb3J0IGNsYXNzIFJlbmRlcmluZ0Vycm9yIGV4dGVuZHMgQmFzZUVycm9yIHtcbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBDcmVhdGVzIGEgbmV3IFJlbmRlcmluZ0Vycm9yIGluc3RhbmNlXG4gICAqIEBzdW1tYXJ5IEluaXRpYWxpemVzIHRoZSBlcnJvciB3aXRoIGEgbWVzc2FnZSBvciBvcmlnaW5hbCBlcnJvclxuICAgKiBAcGFyYW0ge3N0cmluZ3xFcnJvcn0gbXNnIFRoZSBlcnJvciBtZXNzYWdlIG9yIG9yaWdpbmFsIGVycm9yXG4gICAqL1xuICBjb25zdHJ1Y3Rvcihtc2c6IHN0cmluZyB8IEVycm9yKSB7XG4gICAgc3VwZXIoUmVuZGVyaW5nRXJyb3IubmFtZSwgbXNnKTtcbiAgfVxufVxuIiwiaW1wb3J0IHtcbiAgZm9ybWF0RGF0ZSxcbiAgTW9kZWwsXG4gIHBhcnNlRGF0ZSxcbiAgUmVzZXJ2ZWRNb2RlbHMsXG59IGZyb20gXCJAZGVjYWYtdHMvZGVjb3JhdG9yLXZhbGlkYXRpb25cIjtcbmltcG9ydCB7IEhUTUw1RGF0ZUZvcm1hdCwgSFRNTDVJbnB1dFR5cGVzLCBVSUtleXMgfSBmcm9tIFwiLi9jb25zdGFudHNcIjtcbmltcG9ydCB7IGZpbmRNb2RlbElkLCBJbnRlcm5hbEVycm9yIH0gZnJvbSBcIkBkZWNhZi10cy9kYi1kZWNvcmF0b3JzXCI7XG5pbXBvcnQgeyBGaWVsZFByb3BlcnRpZXMgfSBmcm9tIFwiLi90eXBlc1wiO1xuXG4vKipcbiAqIEBmdW5jdGlvbiBmb3JtYXRCeVR5cGVcbiAqXG4gKiBAbWVtYmVyT2YgbW9kdWxlOnVpLWRlY29yYXRvcnNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGZvcm1hdEJ5VHlwZShcbiAgdHlwZTogYW55LFxuICB2YWx1ZTogYW55LFxuICAuLi5hcmdzOiB1bmtub3duW11cbik6IHN0cmluZyB8IG51bWJlciB7XG4gIGlmICh0eXBlID09PSBVSUtleXMuREFURSkge1xuICAgIGNvbnN0IGZvcm1hdDogc3RyaW5nID0gKGFyZ3Muc2hpZnQoKSBhcyBzdHJpbmcpIHx8IEhUTUw1RGF0ZUZvcm1hdDtcbiAgICByZXR1cm4gZm9ybWF0RGF0ZShuZXcgRGF0ZSh2YWx1ZSksIGZvcm1hdCk7XG4gIH1cbiAgcmV0dXJuIHZhbHVlO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gcGFyc2VWYWx1ZUJ5VHlwZShcbiAgdHlwZTogc3RyaW5nLFxuICB2YWx1ZTogc3RyaW5nIHwgbnVtYmVyLFxuICBmaWVsZFByb3BzOiBGaWVsZFByb3BlcnRpZXNcbik6IHN0cmluZyB8IG51bWJlciB8IERhdGUge1xuICBsZXQgcmVzdWx0OiBzdHJpbmcgfCBudW1iZXIgfCBEYXRlIHwgdW5kZWZpbmVkID0gdW5kZWZpbmVkO1xuICBzd2l0Y2ggKHR5cGUpIHtcbiAgICBjYXNlIEhUTUw1SW5wdXRUeXBlcy5OVU1CRVI6XG4gICAgICByZXN1bHQgPSBwYXJzZVRvTnVtYmVyKHZhbHVlKTtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgSFRNTDVJbnB1dFR5cGVzLkRBVEU6IHtcbiAgICAgIGNvbnN0IGZvcm1hdDogc3RyaW5nIHwgdW5kZWZpbmVkID0gZmllbGRQcm9wcy5mb3JtYXQ7XG4gICAgICByZXN1bHQgPVxuICAgICAgICB0eXBlb2YgdmFsdWUgPT09IFJlc2VydmVkTW9kZWxzLk5VTUJFUlxuICAgICAgICAgID8gbmV3IERhdGUodmFsdWUpXG4gICAgICAgICAgOiB2YWx1ZVxuICAgICAgICAgICAgPyBmb3JtYXRcbiAgICAgICAgICAgICAgPyBwYXJzZURhdGUoZm9ybWF0LCB2YWx1ZSlcbiAgICAgICAgICAgICAgOiBuZXcgRGF0ZSh2YWx1ZSlcbiAgICAgICAgICAgIDogdW5kZWZpbmVkO1xuICAgICAgYnJlYWs7XG4gICAgfVxuICAgIGRlZmF1bHQ6XG4gICAgICByZXN1bHQgPVxuICAgICAgICB0eXBlb2YgdmFsdWUgPT09IFJlc2VydmVkTW9kZWxzLlNUUklOR1xuICAgICAgICAgID8gZXNjYXBlSHRtbCh2YWx1ZSBhcyBzdHJpbmcpXG4gICAgICAgICAgOiByZXN1bHQ7XG4gIH1cbiAgaWYgKHR5cGVvZiByZXN1bHQgPT09IFwidW5kZWZpbmVkXCIpIHtcbiAgICB0aHJvdyBuZXcgSW50ZXJuYWxFcnJvcihcbiAgICAgIGBGYWlsZWQgdG8gcGFyc2UgdmFsdWUgb2YgdHlwZSAke3R5cGV9IGZyb20gJHt0eXBlb2YgdmFsdWV9IC0gJHt2YWx1ZX1gXG4gICAgKTtcbiAgfVxuICByZXR1cm4gcmVzdWx0O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gcGFyc2VUb051bWJlcih2YWx1ZTogc3RyaW5nIHwgbnVtYmVyKSB7XG4gIGlmICh0eXBlb2YgdmFsdWUgPT09IFwibnVtYmVyXCIgJiYgIWlzTmFOKHZhbHVlKSkgcmV0dXJuIHZhbHVlO1xuXG4gIGNvbnN0IHBhcnNlZCA9IE51bWJlcih2YWx1ZSk7XG4gIGlmICghaXNOYU4ocGFyc2VkKSkgcmV0dXJuIHBhcnNlZDtcblxuICByZXR1cm4gdW5kZWZpbmVkO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZXNjYXBlSHRtbCh2YWx1ZTogc3RyaW5nKSB7XG4gIGlmICghdmFsdWUpIHJldHVybiB2YWx1ZTtcblxuICBjb25zdCB0YWdzVG9SZXBsYWNlOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+ID0ge1xuICAgIFwiJlwiOiBcIiZhbXA7XCIsXG4gICAgXCI8XCI6IFwiJmx0O1wiLFxuICAgIFwiPlwiOiBcIiZndDtcIixcbiAgfTtcbiAgcmV0dXJuIGAke3ZhbHVlfWAucmVwbGFjZSgvWyY8Pl0vZywgKHRhZykgPT4ge1xuICAgIHJldHVybiB0YWdzVG9SZXBsYWNlW3RhZ10gfHwgdGFnO1xuICB9KTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHJldmVydEh0bWwodmFsdWU6IHN0cmluZykge1xuICBjb25zdCB0YWdzVG9SZXBsYWNlOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+ID0ge1xuICAgIFwiJmFtcDtcIjogXCImXCIsXG4gICAgXCImbHQ7XCI6IFwiPFwiLFxuICAgIFwiJmd0O1wiOiBcIj5cIixcbiAgfTtcblxuICByZXR1cm4gYCR7dmFsdWV9YC5yZXBsYWNlKC8mbHQ7fCZndDt8JmFtcDsvZywgKHRhZykgPT4ge1xuICAgIHJldHVybiB0YWdzVG9SZXBsYWNlW3RhZ10gfHwgdGFnO1xuICB9KTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdlbmVyYXRlVUlNb2RlbElEPE0gZXh0ZW5kcyBNb2RlbD4obW9kZWw6IE0pIHtcbiAgbGV0IGlkOiBzdHJpbmcgfCBudW1iZXIgfCBiaWdpbnQ7XG4gIHRyeSB7XG4gICAgaWQgPSBmaW5kTW9kZWxJZChtb2RlbCkgYXMgc3RyaW5nIHwgbnVtYmVyO1xuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnNcbiAgfSBjYXRjaCAoZTogdW5rbm93bikge1xuICAgIGlkID0gRGF0ZS5ub3coKTtcbiAgfVxuICBjb25zdCBuYW1lID0gbW9kZWwuY29uc3RydWN0b3IubmFtZTtcbiAgcmV0dXJuIGAke25hbWV9LSR7aWR9YDtcbn1cbiIsImltcG9ydCB7IEludGVybmFsRXJyb3IgfSBmcm9tIFwiQGRlY2FmLXRzL2RiLWRlY29yYXRvcnNcIjtcbmltcG9ydCB7XG4gIENvbnN0cnVjdG9yLFxuICBNb2RlbCxcbiAgTW9kZWxDb25zdHJ1Y3RvcixcbiAgUmVzZXJ2ZWRNb2RlbHMsXG4gIFZhbGlkYXRpb25LZXlzLFxuICBWYWxpZGF0aW9uTWV0YWRhdGEsXG59IGZyb20gXCJAZGVjYWYtdHMvZGVjb3JhdG9yLXZhbGlkYXRpb25cIjtcbmltcG9ydCB7XG4gIEhUTUw1RGF0ZUZvcm1hdCxcbiAgSFRNTDVJbnB1dFR5cGVzLFxuICBVSUtleXMsXG4gIFZhbGlkYXRhYmxlQnlBdHRyaWJ1dGUsXG4gIFZhbGlkYXRhYmxlQnlUeXBlLFxufSBmcm9tIFwiLi9jb25zdGFudHNcIjtcbmltcG9ydCB7XG4gIEZpZWxkRGVmaW5pdGlvbixcbiAgRmllbGRQcm9wZXJ0aWVzLFxuICBVSUVsZW1lbnRNZXRhZGF0YSxcbiAgVUlMaXN0SXRlbUVsZW1lbnRNZXRhZGF0YSxcbiAgVUlMaXN0SXRlbU1vZGVsTWV0YWRhdGEsXG4gIFVJTW9kZWxNZXRhZGF0YSxcbiAgVUlQcm9wTWV0YWRhdGEsXG59IGZyb20gXCIuL3R5cGVzXCI7XG5pbXBvcnQgeyBSZW5kZXJpbmdFcnJvciB9IGZyb20gXCIuL2Vycm9yc1wiO1xuaW1wb3J0IHsgRGVjb3JhdG9yTWV0YWRhdGEsIFJlZmxlY3Rpb24gfSBmcm9tIFwiQGRlY2FmLXRzL3JlZmxlY3Rpb25cIjtcbmltcG9ydCB7IGZvcm1hdEJ5VHlwZSwgZ2VuZXJhdGVVSU1vZGVsSUQgfSBmcm9tIFwiLi91dGlsc1wiO1xuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBBYnN0cmFjdCBjbGFzcyBmb3IgcmVuZGVyaW5nIFVJIGNvbXBvbmVudHMgYmFzZWQgb24gbW9kZWwgbWV0YWRhdGEuXG4gKiBAc3VtbWFyeSBUaGUgUmVuZGVyaW5nRW5naW5lIGNsYXNzIHByb3ZpZGVzIGEgZnJhbWV3b3JrIGZvciBjb252ZXJ0aW5nIG1vZGVsIG1ldGFkYXRhIGludG8gVUkgZmllbGQgZGVmaW5pdGlvbnMuXG4gKiBJdCBoYW5kbGVzIHRoZSB0cmFuc2xhdGlvbiBvZiBtb2RlbCBwcm9wZXJ0aWVzIHRvIFVJIGVsZW1lbnRzLCBhcHBsaWVzIHZhbGlkYXRpb24gcnVsZXMsIGFuZCBtYW5hZ2VzIGRpZmZlcmVudCByZW5kZXJpbmcgZmxhdm9ycy5cbiAqIFRoaXMgY2xhc3MgaXMgZGVzaWduZWQgdG8gYmUgZXh0ZW5kZWQgYnkgc3BlY2lmaWMgcmVuZGVyaW5nIGltcGxlbWVudGF0aW9ucy5cbiAqXG4gKiBAdGVtcGxhdGUgVCBUaGUgdHlwZSBvZiB0aGUgcmVuZGVyaW5nIHJlc3VsdCwgZGVmYXVsdHMgdG8gdm9pZFxuICogQHRlbXBsYXRlIFIgVGhlIHR5cGUgb2YgdGhlIGZpZWxkIGRlZmluaXRpb24sIGRlZmF1bHRzIHRvIEZpZWxkRGVmaW5pdGlvbjxUPlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBmbGF2b3VyIC0gVGhlIGZsYXZvciBvZiB0aGUgcmVuZGVyaW5nIGVuZ2luZS5cbiAqXG4gKiBAY2xhc3MgUmVuZGVyaW5nRW5naW5lXG4gKi9cbmV4cG9ydCBhYnN0cmFjdCBjbGFzcyBSZW5kZXJpbmdFbmdpbmU8VCA9IHZvaWQsIFIgPSBGaWVsZERlZmluaXRpb248VD4+IHtcbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBDYWNoZSBmb3Igc3RvcmluZyByZW5kZXJpbmcgZW5naW5lIGluc3RhbmNlcyBvciBjb25zdHJ1Y3RvcnMuXG4gICAqIEBwcml2YXRlXG4gICAqIEBzdGF0aWNcbiAgICovXG4gIHByaXZhdGUgc3RhdGljIGNhY2hlOiBSZWNvcmQ8XG4gICAgc3RyaW5nLFxuICAgIHwgQ29uc3RydWN0b3I8UmVuZGVyaW5nRW5naW5lPHVua25vd24sIHVua25vd24+PlxuICAgIHwgUmVuZGVyaW5nRW5naW5lPHVua25vd24sIHVua25vd24+XG4gID4gPSB7fTtcblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFRoZSBjdXJyZW50bHkgYWN0aXZlIHJlbmRlcmluZyBlbmdpbmUuXG4gICAqIEBwcml2YXRlXG4gICAqIEBzdGF0aWNcbiAgICovXG4gIHByaXZhdGUgc3RhdGljIGN1cnJlbnQ6XG4gICAgfCBDb25zdHJ1Y3RvcjxSZW5kZXJpbmdFbmdpbmU8dW5rbm93biwgdW5rbm93bj4+XG4gICAgfCBSZW5kZXJpbmdFbmdpbmU8dW5rbm93biwgdW5rbm93bj47XG5cbiAgLyoqXG4gICAqIEZsYWcgaW5kaWNhdGluZyB3aGV0aGVyIHRoZSByZW5kZXJpbmcgZW5naW5lIGhhcyBiZWVuIGluaXRpYWxpemVkLlxuICAgKi9cbiAgcHJvdGVjdGVkIGluaXRpYWxpemVkOiBib29sZWFuID0gZmFsc2U7XG5cbiAgcHJvdGVjdGVkIGNvbnN0cnVjdG9yKHJlYWRvbmx5IGZsYXZvdXI6IHN0cmluZykge1xuICAgIFJlbmRlcmluZ0VuZ2luZS5yZWdpc3Rlcih0aGlzKTtcbiAgICBjb25zb2xlLmxvZyhgZGVjYWYncyAke2ZsYXZvdXJ9IHJlbmRlcmluZyBlbmdpbmUgbG9hZGVkYCk7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIEluaXRpYWxpemVzIHRoZSByZW5kZXJpbmcgZW5naW5lLlxuICAgKiBAc3VtbWFyeSBBYnN0cmFjdCBtZXRob2QgdG8gYmUgaW1wbGVtZW50ZWQgYnkgc3ViY2xhc3NlcyBmb3Igc3BlY2lmaWMgaW5pdGlhbGl6YXRpb24gbG9naWMuXG4gICAqXG4gICAqIEBwYXJhbSB7Li4uYW55W119IGFyZ3MgLSBBbnkgYWRkaXRpb25hbCBhcmd1bWVudHMgbmVlZGVkIGZvciBpbml0aWFsaXphdGlvbi5cbiAgICogQHJldHVybnMge1Byb21pc2U8dm9pZD59IEEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHdoZW4gaW5pdGlhbGl6YXRpb24gaXMgY29tcGxldGUuXG4gICAqXG4gICAqIEBhYnN0cmFjdFxuICAgKi9cbiAgYWJzdHJhY3QgaW5pdGlhbGl6ZSguLi5hcmdzOiBhbnlbXSk6IFByb21pc2U8dm9pZD47XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBUcmFuc2xhdGVzIGJldHdlZW4gbW9kZWwgdHlwZXMgYW5kIEhUTUwgaW5wdXQgdHlwZXMuXG4gICAqIEBzdW1tYXJ5IENvbnZlcnRzIG1vZGVsIGRhdGEgdHlwZXMgdG8gYXBwcm9wcmlhdGUgSFRNTCBpbnB1dCB0eXBlcyBhbmQgdmljZSB2ZXJzYS5cbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmd9IGtleSAtIFRoZSBrZXkgdG8gdHJhbnNsYXRlLlxuICAgKiBAcGFyYW0ge2Jvb2xlYW59IFt0b1ZpZXc9dHJ1ZV0gLSBEaXJlY3Rpb24gb2YgdHJhbnNsYXRpb24gKHRydWUgZm9yIG1vZGVsIHRvIHZpZXcsIGZhbHNlIGZvciB2aWV3IHRvIG1vZGVsKS5cbiAgICogQHJldHVybnMge3N0cmluZ30gVGhlIHRyYW5zbGF0ZWQgdHlwZS5cbiAgICovXG4gIHRyYW5zbGF0ZShrZXk6IHN0cmluZywgdG9WaWV3OiBib29sZWFuID0gdHJ1ZSk6IHN0cmluZyB7XG4gICAgaWYgKHRvVmlldykge1xuICAgICAgc3dpdGNoIChrZXkpIHtcbiAgICAgICAgY2FzZSBSZXNlcnZlZE1vZGVscy5TVFJJTkc6XG4gICAgICAgICAgcmV0dXJuIEhUTUw1SW5wdXRUeXBlcy5URVhUO1xuICAgICAgICBjYXNlIFJlc2VydmVkTW9kZWxzLk5VTUJFUjpcbiAgICAgICAgY2FzZSBSZXNlcnZlZE1vZGVscy5CSUdJTlQ6XG4gICAgICAgICAgcmV0dXJuIEhUTUw1SW5wdXRUeXBlcy5OVU1CRVI7XG4gICAgICAgIGNhc2UgUmVzZXJ2ZWRNb2RlbHMuQk9PTEVBTjpcbiAgICAgICAgICByZXR1cm4gSFRNTDVJbnB1dFR5cGVzLkNIRUNLQk9YO1xuICAgICAgICBjYXNlIFJlc2VydmVkTW9kZWxzLkRBVEU6XG4gICAgICAgICAgcmV0dXJuIEhUTUw1SW5wdXRUeXBlcy5EQVRFO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBzd2l0Y2ggKGtleSkge1xuICAgICAgICBjYXNlIEhUTUw1SW5wdXRUeXBlcy5URVhUOlxuICAgICAgICBjYXNlIEhUTUw1SW5wdXRUeXBlcy5FTUFJTDpcbiAgICAgICAgY2FzZSBIVE1MNUlucHV0VHlwZXMuQ09MT1I6XG4gICAgICAgIGNhc2UgSFRNTDVJbnB1dFR5cGVzLlBBU1NXT1JEOlxuICAgICAgICBjYXNlIEhUTUw1SW5wdXRUeXBlcy5URUw6XG4gICAgICAgIGNhc2UgSFRNTDVJbnB1dFR5cGVzLlVSTDpcbiAgICAgICAgICByZXR1cm4gUmVzZXJ2ZWRNb2RlbHMuU1RSSU5HO1xuICAgICAgICBjYXNlIEhUTUw1SW5wdXRUeXBlcy5OVU1CRVI6XG4gICAgICAgICAgcmV0dXJuIFJlc2VydmVkTW9kZWxzLk5VTUJFUjtcbiAgICAgICAgY2FzZSBIVE1MNUlucHV0VHlwZXMuQ0hFQ0tCT1g6XG4gICAgICAgICAgcmV0dXJuIFJlc2VydmVkTW9kZWxzLkJPT0xFQU47XG4gICAgICAgIGNhc2UgSFRNTDVJbnB1dFR5cGVzLkRBVEU6XG4gICAgICAgIGNhc2UgSFRNTDVJbnB1dFR5cGVzLkRBVEVUSU1FX0xPQ0FMOlxuICAgICAgICBjYXNlIEhUTUw1SW5wdXRUeXBlcy5USU1FOlxuICAgICAgICAgIHJldHVybiBSZXNlcnZlZE1vZGVscy5EQVRFO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4ga2V5O1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBDaGVja3MgaWYgYSB0eXBlIGlzIHZhbGlkYXRhYmxlIGJ5IGl0cyBuYXR1cmUuXG4gICAqIEBzdW1tYXJ5IERldGVybWluZXMgaWYgYSBnaXZlbiBVSSBrZXkgcmVwcmVzZW50cyBhIHR5cGUgdGhhdCBpcyBpbmhlcmVudGx5IHZhbGlkYXRhYmxlLlxuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZ30ga2V5IC0gVGhlIFVJIGtleSB0byBjaGVjay5cbiAgICogQHJldHVybnMge2Jvb2xlYW59IFRydWUgaWYgdGhlIHR5cGUgaXMgdmFsaWRhdGFibGUsIGZhbHNlIG90aGVyd2lzZS5cbiAgICovXG4gIHByb3RlY3RlZCBpc1ZhbGlkYXRhYmxlQnlUeXBlKGtleTogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIE9iamVjdC5rZXlzKFZhbGlkYXRhYmxlQnlUeXBlKS5pbmNsdWRlcyhrZXkpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBDaGVja3MgaWYgYSB0eXBlIGlzIHZhbGlkYXRhYmxlIGJ5IGF0dHJpYnV0ZS5cbiAgICogQHN1bW1hcnkgRGV0ZXJtaW5lcyBpZiBhIGdpdmVuIFVJIGtleSByZXByZXNlbnRzIGEgdmFsaWRhdGlvbiB0aGF0IGNhbiBiZSBhcHBsaWVkIGFzIGFuIGF0dHJpYnV0ZS5cbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmd9IGtleSAtIFRoZSBVSSBrZXkgdG8gY2hlY2suXG4gICAqIEByZXR1cm5zIHtib29sZWFufSBUcnVlIGlmIHRoZSB0eXBlIGlzIHZhbGlkYXRhYmxlIGJ5IGF0dHJpYnV0ZSwgZmFsc2Ugb3RoZXJ3aXNlLlxuICAgKi9cbiAgcHJvdGVjdGVkIGlzVmFsaWRhdGFibGVCeUF0dHJpYnV0ZShrZXk6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgIHJldHVybiBPYmplY3Qua2V5cyhWYWxpZGF0YWJsZUJ5QXR0cmlidXRlKS5pbmNsdWRlcyhrZXkpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBDb252ZXJ0cyB2YWxpZGF0aW9uIG1ldGFkYXRhIHRvIGFuIGF0dHJpYnV0ZSB2YWx1ZS5cbiAgICogQHN1bW1hcnkgVHJhbnNmb3JtcyB2YWxpZGF0aW9uIG1ldGFkYXRhIGludG8gYSB2YWx1ZSBzdWl0YWJsZSBmb3IgdXNlIGFzIGFuIEhUTUwgYXR0cmlidXRlLlxuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZ30ga2V5IC0gVGhlIHZhbGlkYXRpb24ga2V5LlxuICAgKiBAcGFyYW0ge1ZhbGlkYXRpb25NZXRhZGF0YX0gdmFsdWUgLSBUaGUgdmFsaWRhdGlvbiBtZXRhZGF0YS5cbiAgICogQHJldHVybnMge3N0cmluZyB8IG51bWJlciB8IGJvb2xlYW59IFRoZSBjb252ZXJ0ZWQgYXR0cmlidXRlIHZhbHVlLlxuICAgKiBAdGhyb3dzIHtFcnJvcn0gSWYgdGhlIGdpdmVuIGtleSBpcyBub3QgdmFsaWRhdGFibGUgYnkgYXR0cmlidXRlLlxuICAgKi9cbiAgcHJvdGVjdGVkIHRvQXR0cmlidXRlVmFsdWUoXG4gICAga2V5OiBzdHJpbmcsXG4gICAgdmFsdWU6IFZhbGlkYXRpb25NZXRhZGF0YVxuICApOiBzdHJpbmcgfCBudW1iZXIgfCBib29sZWFuIHtcbiAgICBpZiAoIU9iamVjdC5rZXlzKFZhbGlkYXRhYmxlQnlBdHRyaWJ1dGUpLmluY2x1ZGVzKGtleSkpXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgIGBJbnZhbGlkIGF0dHJpYnV0ZSBrZXkgXCIke2tleX1cIi4gRXhwZWN0ZWQgb25lIG9mOiAke09iamVjdC5rZXlzKFZhbGlkYXRhYmxlQnlBdHRyaWJ1dGUpLmpvaW4oXCIsIFwiKX0uYFxuICAgICAgKTtcblxuICAgIHJldHVybiBrZXkgPT09IFVJS2V5cy5SRVFVSVJFRCA/IHRydWUgOiB2YWx1ZVtrZXldO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBDb252ZXJ0cyBhIG1vZGVsIHRvIGEgZmllbGQgZGVmaW5pdGlvbi5cbiAgICogQHN1bW1hcnkgUHJvY2Vzc2VzIGEgbW9kZWwgaW5zdGFuY2UsIGV4dHJhY3RpbmcgVUktcmVsYXRlZCBtZXRhZGF0YSBhbmQgdmFsaWRhdGlvbiBydWxlcyB0byBjcmVhdGUgYSBmaWVsZCBkZWZpbml0aW9uLlxuICAgKlxuICAgKiBAdGVtcGxhdGUgTSBUeXBlIGV4dGVuZGluZyBNb2RlbFxuICAgKiBAdGVtcGxhdGUgVCBUeXBlIHJlZmVyZW5jaW5nIHRoZSBzcGVjaWZpYyBSZW5kZXJpbmcgZW5naW5lIGZpZWxkIHByb3BlcnRpZXMvaW5wdXRzXG4gICAqIEBwYXJhbSB7TX0gbW9kZWwgLSBUaGUgbW9kZWwgaW5zdGFuY2UgdG8gY29udmVydC5cbiAgICogQHBhcmFtIHtSZWNvcmQ8c3RyaW5nLCB1bmtub3duPn0gW2dsb2JhbFByb3BzPXt9XSAtIEdsb2JhbCBwcm9wZXJ0aWVzIHRvIGFwcGx5IHRvIGFsbCBjaGlsZCBlbGVtZW50cy5cbiAgICogQHBhcmFtIHtib29sZWFufSBbZ2VuZXJhdGVJZD10cnVlXSAtIEZsYWcgaW5kaWNhdGluZyB3aGV0aGVyIHRvIHBvcHVsYXRlIHRoZSByZW5kZXJlcklkIHByb3BlcnR5LlxuICAgKiBAcmV0dXJucyB7RmllbGREZWZpbml0aW9uPFQ+fSBBIGZpZWxkIGRlZmluaXRpb24gb2JqZWN0IHJlcHJlc2VudGluZyB0aGUgVUkgc3RydWN0dXJlIG9mIHRoZSBtb2RlbC5cbiAgICogQHRocm93cyB7UmVuZGVyaW5nRXJyb3J9IElmIG5vIFVJIGRlZmluaXRpb25zIGFyZSBzZXQgZm9yIHRoZSBtb2RlbCBvciBpZiB0aGVyZSBhcmUgaW52YWxpZCBkZWNvcmF0b3JzLlxuICAgKlxuICAgKiBAbWVybWFpZFxuICAgKiBzZXF1ZW5jZURpYWdyYW1cbiAgICogIHBhcnRpY2lwYW50IEMgYXMgQ2xpZW50XG4gICAqICBwYXJ0aWNpcGFudCBSRSBhcyBSZW5kZXJpbmdFbmdpbmVcbiAgICogIHBhcnRpY2lwYW50IFIgYXMgUmVmbGVjdGlvblxuICAgKiAgcGFydGljaXBhbnQgTSBhcyBNb2RlbFxuICAgKiAgQy0+PlJFOiB0b0ZpZWxkRGVmaW5pdGlvbihtb2RlbCwgZ2xvYmFsUHJvcHMpXG4gICAqICBSRS0+PlI6IGdldE1ldGFkYXRhKFVJS2V5cy5VSU1PREVMLCBtb2RlbC5jb25zdHJ1Y3RvcilcbiAgICogIFItLT4+UkU6IFVJTW9kZWxNZXRhZGF0YVxuICAgKiAgUkUtPj5SOiBnZXRBbGxQcm9wZXJ0eURlY29yYXRvcnMobW9kZWwsIFVJS2V5cy5SRUZMRUNUKVxuICAgKiAgUi0tPj5SRTogUmVjb3JkPHN0cmluZywgRGVjb3JhdG9yTWV0YWRhdGFbXT5cbiAgICogIFJFLT4+UjogZ2V0QWxsUHJvcGVydHlEZWNvcmF0b3JzKG1vZGVsLCBWYWxpZGF0aW9uS2V5cy5SRUZMRUNUKVxuICAgKiAgUi0tPj5SRTogUmVjb3JkPHN0cmluZywgRGVjb3JhdG9yTWV0YWRhdGE8VmFsaWRhdGlvbk1ldGFkYXRhPltdPlxuICAgKiAgbG9vcCBGb3IgZWFjaCBwcm9wZXJ0eVxuICAgKiAgICBSRS0+PlJFOiBQcm9jZXNzIFVJIGRlY29yYXRvcnNcbiAgICogICAgUkUtPj5SRTogQXBwbHkgdmFsaWRhdGlvbiBydWxlc1xuICAgKiAgZW5kXG4gICAqICBSRS0tPj5DOiBGaWVsZERlZmluaXRpb248VD5cbiAgICovXG4gIHByb3RlY3RlZCB0b0ZpZWxkRGVmaW5pdGlvbjxNIGV4dGVuZHMgTW9kZWw+KFxuICAgIG1vZGVsOiBNLFxuICAgIGdsb2JhbFByb3BzOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiA9IHt9LFxuICAgIGdlbmVyYXRlSWQ6IGJvb2xlYW4gPSB0cnVlXG4gICk6IEZpZWxkRGVmaW5pdGlvbjxUPiB7XG4gICAgY29uc3QgY2xhc3NEZWNvcmF0b3JzOiBbVUlNb2RlbE1ldGFkYXRhLCBVSUxpc3RJdGVtTW9kZWxNZXRhZGF0YV0gPSBbXG4gICAgICBSZWZsZWN0LmdldE1ldGFkYXRhKFxuICAgICAgICBSZW5kZXJpbmdFbmdpbmUua2V5KFVJS2V5cy5VSU1PREVMKSxcbiAgICAgICAgbW9kZWwuY29uc3RydWN0b3JcbiAgICAgICkgfHxcbiAgICAgICAgUmVmbGVjdC5nZXRNZXRhZGF0YShcbiAgICAgICAgICBSZW5kZXJpbmdFbmdpbmUua2V5KFVJS2V5cy5VSU1PREVMKSxcbiAgICAgICAgICBNb2RlbC5nZXQobW9kZWwuY29uc3RydWN0b3IubmFtZSkgYXMgYW55XG4gICAgICAgICksXG4gICAgICBSZWZsZWN0LmdldE1ldGFkYXRhKFxuICAgICAgICBSZW5kZXJpbmdFbmdpbmUua2V5KFVJS2V5cy5VSUxJU1RJVEVNKSxcbiAgICAgICAgbW9kZWwuY29uc3RydWN0b3JcbiAgICAgICkgfHxcbiAgICAgICAgUmVmbGVjdC5nZXRNZXRhZGF0YShcbiAgICAgICAgICBSZW5kZXJpbmdFbmdpbmUua2V5KFVJS2V5cy5VSUxJU1RJVEVNKSxcbiAgICAgICAgICBNb2RlbC5nZXQobW9kZWwuY29uc3RydWN0b3IubmFtZSkgYXMgYW55XG4gICAgICAgICksXG4gICAgXTtcblxuICAgIGlmICghY2xhc3NEZWNvcmF0b3JzKVxuICAgICAgdGhyb3cgbmV3IFJlbmRlcmluZ0Vycm9yKFxuICAgICAgICBgTm8gdWkgZGVmaW5pdGlvbnMgc2V0IGZvciBtb2RlbCAke21vZGVsLmNvbnN0cnVjdG9yLm5hbWV9LiBEaWQgeW91IHVzZSBAdWltb2RlbD9gXG4gICAgICApO1xuXG4gICAgY29uc3QgY2xhc3NEZWNvcmF0b3IgPSBPYmplY3QuYXNzaWduKHt9LCAuLi5jbGFzc0RlY29yYXRvcnMpO1xuICAgIGNvbnN0IHsgdGFnLCBwcm9wcywgaXRlbSB9ID0gY2xhc3NEZWNvcmF0b3I7XG5cbiAgICBjb25zdCB1aURlY29yYXRvcnM6IFJlY29yZDxzdHJpbmcsIERlY29yYXRvck1ldGFkYXRhW10+ID1cbiAgICAgIFJlZmxlY3Rpb24uZ2V0QWxsUHJvcGVydHlEZWNvcmF0b3JzKG1vZGVsLCBVSUtleXMuUkVGTEVDVCkgYXMgUmVjb3JkPFxuICAgICAgICBzdHJpbmcsXG4gICAgICAgIERlY29yYXRvck1ldGFkYXRhW11cbiAgICAgID47XG4gICAgbGV0IGNoaWxkcmVuOiBGaWVsZERlZmluaXRpb248UmVjb3JkPHN0cmluZywgYW55Pj5bXSB8IHVuZGVmaW5lZDtcbiAgICBsZXQgY2hpbGRQcm9wczogUmVjb3JkPHN0cmluZywgYW55PiA9IGl0ZW0/LnByb3BzIHx8IHt9O1xuICAgIGxldCBtYXBwZXI6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4gPSB7fTtcblxuICAgIGNvbnN0IGdldFBhdGggPSAocGFyZW50OiBzdHJpbmcgfCB1bmRlZmluZWQsIHByb3A6IHN0cmluZykgPT4ge1xuICAgICAgcmV0dXJuIHBhcmVudCA/IFtwYXJlbnQsIHByb3BdLmpvaW4oXCIuXCIpIDogcHJvcDtcbiAgICB9O1xuXG4gICAgaWYgKHVpRGVjb3JhdG9ycykge1xuICAgICAgY29uc3QgdmFsaWRhdGlvbkRlY29yYXRvcnM6IFJlY29yZDxcbiAgICAgICAgc3RyaW5nLFxuICAgICAgICBEZWNvcmF0b3JNZXRhZGF0YTxWYWxpZGF0aW9uTWV0YWRhdGE+W11cbiAgICAgID4gPSBSZWZsZWN0aW9uLmdldEFsbFByb3BlcnR5RGVjb3JhdG9ycyhcbiAgICAgICAgbW9kZWwsXG4gICAgICAgIFZhbGlkYXRpb25LZXlzLlJFRkxFQ1RcbiAgICAgICkgYXMgUmVjb3JkPHN0cmluZywgRGVjb3JhdG9yTWV0YWRhdGE8VmFsaWRhdGlvbk1ldGFkYXRhPltdPjtcblxuICAgICAgZm9yIChjb25zdCBrZXkgaW4gdWlEZWNvcmF0b3JzKSB7XG4gICAgICAgIGNvbnN0IGRlY3MgPSB1aURlY29yYXRvcnNba2V5XTtcbiAgICAgICAgY29uc3QgdHlwZXMgPSBPYmplY3QudmFsdWVzKGRlY3MpLmZpbHRlcihcbiAgICAgICAgICAoaXRlbSkgPT4gaXRlbS5rZXkgPT09IFVJS2V5cy5QUk9QIHx8IGl0ZW0ua2V5ID09PSBVSUtleXMuRUxFTUVOVFxuICAgICAgICApO1xuICAgICAgICBpZiAodHlwZXM/Lmxlbmd0aCA+IDEpXG4gICAgICAgICAgdGhyb3cgbmV3IFJlbmRlcmluZ0Vycm9yKFxuICAgICAgICAgICAgYE9ubHkgb25lIHR5cGUgb2YgZGVjb3JhdGlvbiBpcyBhbGxvd2VkLiBQbGVhc2UgY2hvb3NlIGJldHdlZW4gQHVpcHJvcCBhbmQgQHVpZWxlbWVudGBcbiAgICAgICAgICApO1xuICAgICAgICBkZWNzLnNoaWZ0KCk7XG4gICAgICAgIGRlY3MuZm9yRWFjaCgoZGVjKSA9PiB7XG4gICAgICAgICAgaWYgKCFkZWMpIHRocm93IG5ldyBSZW5kZXJpbmdFcnJvcihgTm8gZGVjb3JhdG9yIGZvdW5kYCk7XG5cbiAgICAgICAgICBzd2l0Y2ggKGRlYy5rZXkpIHtcbiAgICAgICAgICAgIGNhc2UgVUlLZXlzLlBST1A6IHtcbiAgICAgICAgICAgICAgaWYgKCFNb2RlbC5pc1Byb3BlcnR5TW9kZWwobW9kZWwsIGtleSkpIHtcbiAgICAgICAgICAgICAgICBjaGlsZFByb3BzW2tleV0gPSBkZWMucHJvcHMgYXMgVUlQcm9wTWV0YWRhdGE7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICBsZXQgQ2xheno7XG4gICAgICAgICAgICAgIGNvbnN0IHN1Ym1vZGVsID0gKG1vZGVsIGFzIFJlY29yZDxzdHJpbmcsIGFueT4pW2tleV0gYXMgTW9kZWw7XG4gICAgICAgICAgICAgIGNvbnN0IGNvbnN0cnVjdGFibGUgPVxuICAgICAgICAgICAgICAgIHR5cGVvZiBzdWJtb2RlbCA9PT0gXCJvYmplY3RcIiAmJlxuICAgICAgICAgICAgICAgIHN1Ym1vZGVsICE9PSBudWxsICYmXG4gICAgICAgICAgICAgICAgIUFycmF5LmlzQXJyYXkoc3VibW9kZWwpO1xuICAgICAgICAgICAgICBpZiAoIWNvbnN0cnVjdGFibGUpXG4gICAgICAgICAgICAgICAgQ2xhenogPSBuZXcgKE1vZGVsLmdldChcbiAgICAgICAgICAgICAgICAgIGRlYy5wcm9wcz8ubmFtZSBhcyBzdHJpbmdcbiAgICAgICAgICAgICAgICApIGFzIE1vZGVsQ29uc3RydWN0b3I8TW9kZWw+KSgpO1xuXG4gICAgICAgICAgICAgIGNoaWxkcmVuID0gY2hpbGRyZW4gfHwgW107XG4gICAgICAgICAgICAgIGNvbnN0IGNoaWxkcmVuR2xvYmFsUHJvcHMgPSBPYmplY3QuYXNzaWduKHt9LCBnbG9iYWxQcm9wcyB8fCB7fSwge1xuICAgICAgICAgICAgICAgIGNoaWxkT2Y6IGdldFBhdGgoZ2xvYmFsUHJvcHM/LmNoaWxkT2YgYXMgc3RyaW5nLCBrZXkpLFxuICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgY29uc3QgY2hpbGREZWZpbml0aW9uID0gdGhpcy50b0ZpZWxkRGVmaW5pdGlvbihcbiAgICAgICAgICAgICAgICBzdWJtb2RlbCB8fCBDbGF6eixcbiAgICAgICAgICAgICAgICBjaGlsZHJlbkdsb2JhbFByb3BzLFxuICAgICAgICAgICAgICAgIGZhbHNlXG4gICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgIGNoaWxkcmVuLnB1c2goXG4gICAgICAgICAgICAgICAgY2hpbGREZWZpbml0aW9uIGFzIEZpZWxkRGVmaW5pdGlvbjxSZWNvcmQ8c3RyaW5nLCBhbnk+PlxuICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhc2UgVUlLZXlzLlVJTElTVFBST1A6IHtcbiAgICAgICAgICAgICAgbWFwcGVyID0gbWFwcGVyIHx8IHt9O1xuICAgICAgICAgICAgICBtYXBwZXJbZGVjLnByb3BzPy5uYW1lIGFzIHN0cmluZ10gPSBrZXk7XG4gICAgICAgICAgICAgIGNvbnN0IHByb3BzID0gT2JqZWN0LmFzc2lnbihcbiAgICAgICAgICAgICAgICB7fSxcbiAgICAgICAgICAgICAgICBjbGFzc0RlY29yYXRvci5wcm9wcz8uaXRlbSB8fCB7fSxcbiAgICAgICAgICAgICAgICBpdGVtPy5wcm9wcyB8fCB7fSxcbiAgICAgICAgICAgICAgICBkZWMucHJvcHM/LnByb3BzIHx8IHt9LFxuICAgICAgICAgICAgICAgIGdsb2JhbFByb3BzXG4gICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgIGNoaWxkUHJvcHMgPSB7XG4gICAgICAgICAgICAgICAgdGFnOiBpdGVtPy50YWcgfHwgcHJvcHMucmVuZGVyIHx8IFwiXCIsXG4gICAgICAgICAgICAgICAgcHJvcHM6IE9iamVjdC5hc3NpZ24oe30sIGNoaWxkUHJvcHM/LnByb3BzLCB7IG1hcHBlciB9LCBwcm9wcyksXG4gICAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXNlIFVJS2V5cy5FTEVNRU5UOiB7XG4gICAgICAgICAgICAgIGNoaWxkcmVuID0gY2hpbGRyZW4gfHwgW107XG5cbiAgICAgICAgICAgICAgY29uc3QgdWlQcm9wczogVUlFbGVtZW50TWV0YWRhdGEgPSBkZWMucHJvcHMgYXMgVUlFbGVtZW50TWV0YWRhdGE7XG4gICAgICAgICAgICAgIGNvbnN0IHByb3BzID0gT2JqZWN0LmFzc2lnbihcbiAgICAgICAgICAgICAgICB7fSxcbiAgICAgICAgICAgICAgICB1aVByb3BzLnByb3BzIGFzIGFueSxcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICBwYXRoOiBnZXRQYXRoKFxuICAgICAgICAgICAgICAgICAgICBnbG9iYWxQcm9wcz8uY2hpbGRPZiBhcyBzdHJpbmcsXG4gICAgICAgICAgICAgICAgICAgIHVpUHJvcHMucHJvcHMhLm5hbWVcbiAgICAgICAgICAgICAgICAgICksXG4gICAgICAgICAgICAgICAgICBjaGlsZE9mOiB1bmRlZmluZWQsIC8vIFRoZSBjaGlsZE9mIHByb3AgaXMgcGFzc2VkIGJ5IGdsb2JhbFByb3BzIHdoZW4gaXQgaXMgYSBuZXN0ZWQgcHJvcFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgZ2xvYmFsUHJvcHNcbiAgICAgICAgICAgICAgKTtcblxuICAgICAgICAgICAgICBjb25zdCBjaGlsZERlZmluaXRpb246IEZpZWxkRGVmaW5pdGlvbjxSZWNvcmQ8c3RyaW5nLCBhbnk+PiA9IHtcbiAgICAgICAgICAgICAgICB0YWc6IHVpUHJvcHMudGFnLFxuICAgICAgICAgICAgICAgIHByb3BzLFxuICAgICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICAgIGNvbnN0IHZhbGlkYXRpb25EZWNzOiBEZWNvcmF0b3JNZXRhZGF0YTxWYWxpZGF0aW9uTWV0YWRhdGE+W10gPVxuICAgICAgICAgICAgICAgIHZhbGlkYXRpb25EZWNvcmF0b3JzW1xuICAgICAgICAgICAgICAgICAga2V5XG4gICAgICAgICAgICAgICAgXSBhcyBEZWNvcmF0b3JNZXRhZGF0YTxWYWxpZGF0aW9uTWV0YWRhdGE+W107XG5cbiAgICAgICAgICAgICAgY29uc3QgdHlwZURlYzogRGVjb3JhdG9yTWV0YWRhdGFPYmplY3QgPVxuICAgICAgICAgICAgICAgIHZhbGlkYXRpb25EZWNzLnNoaWZ0KCkgYXMgRGVjb3JhdG9yTWV0YWRhdGE7XG4gICAgICAgICAgICAgIGZvciAoY29uc3QgZGVjIG9mIHZhbGlkYXRpb25EZWNzKSB7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuaXNWYWxpZGF0YWJsZUJ5QXR0cmlidXRlKGRlYy5rZXkpKSB7XG4gICAgICAgICAgICAgICAgICBjaGlsZERlZmluaXRpb24ucHJvcHNbdGhpcy50cmFuc2xhdGUoZGVjLmtleSldID1cbiAgICAgICAgICAgICAgICAgICAgdGhpcy50b0F0dHJpYnV0ZVZhbHVlKGRlYy5rZXksIGRlYy5wcm9wcyk7XG4gICAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuaXNWYWxpZGF0YWJsZUJ5VHlwZShkZWMua2V5KSkge1xuICAgICAgICAgICAgICAgICAgaWYgKGRlYy5rZXkgPT09IEhUTUw1SW5wdXRUeXBlcy5EQVRFKSB7XG4gICAgICAgICAgICAgICAgICAgIGNoaWxkRGVmaW5pdGlvbi5wcm9wc1tVSUtleXMuRk9STUFUXSA9XG4gICAgICAgICAgICAgICAgICAgICAgZGVjLnByb3BzLmZvcm1hdCB8fCBIVE1MNURhdGVGb3JtYXQ7XG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICBjaGlsZERlZmluaXRpb24ucHJvcHNbVUlLZXlzLlRZUEVdID0gZGVjLmtleTtcbiAgICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgIGlmICghY2hpbGREZWZpbml0aW9uLnByb3BzW1VJS2V5cy5UWVBFXSkge1xuICAgICAgICAgICAgICAgIGNvbnN0IGJhc2ljVHlwZSA9ICh0eXBlRGVjLnByb3BzIGFzIHsgbmFtZTogc3RyaW5nIH0pLm5hbWU7XG4gICAgICAgICAgICAgICAgY2hpbGREZWZpbml0aW9uLnByb3BzW1VJS2V5cy5UWVBFXSA9IHRoaXMudHJhbnNsYXRlKFxuICAgICAgICAgICAgICAgICAgYmFzaWNUeXBlLnRvTG93ZXJDYXNlKCksXG4gICAgICAgICAgICAgICAgICB0cnVlXG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgIGNoaWxkRGVmaW5pdGlvbi5wcm9wcy52YWx1ZSA9IGZvcm1hdEJ5VHlwZShcbiAgICAgICAgICAgICAgICBjaGlsZERlZmluaXRpb24ucHJvcHNbVUlLZXlzLlRZUEVdLFxuICAgICAgICAgICAgICAgIG1vZGVsW2tleSBhcyBrZXlvZiBNXSxcbiAgICAgICAgICAgICAgICBjaGlsZERlZmluaXRpb24ucHJvcHNbVUlLZXlzLkZPUk1BVF1cbiAgICAgICAgICAgICAgKTtcblxuICAgICAgICAgICAgICBjaGlsZHJlbi5wdXNoKGNoaWxkRGVmaW5pdGlvbik7XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgdGhyb3cgbmV3IFJlbmRlcmluZ0Vycm9yKGBJbnZhbGlkIGtleTogJHtkZWMua2V5fWApO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgY29uc3QgcmVzdWx0OiBGaWVsZERlZmluaXRpb248VD4gPSB7XG4gICAgICB0YWc6IHRhZyxcbiAgICAgIGl0ZW06IGNoaWxkUHJvcHMgYXMgVUlMaXN0SXRlbUVsZW1lbnRNZXRhZGF0YSxcbiAgICAgIHByb3BzOiBPYmplY3QuYXNzaWduKHt9LCBwcm9wcywgZ2xvYmFsUHJvcHMpIGFzIFQgJiBGaWVsZFByb3BlcnRpZXMsXG4gICAgICBjaGlsZHJlbjogY2hpbGRyZW4gYXMgRmllbGREZWZpbml0aW9uPGFueT5bXSxcbiAgICB9O1xuXG4gICAgaWYgKGdlbmVyYXRlSWQpIHJlc3VsdC5yZW5kZXJlcklkID0gZ2VuZXJhdGVVSU1vZGVsSUQobW9kZWwpO1xuXG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gUmVuZGVycyBhIG1vZGVsIHdpdGggZ2xvYmFsIHByb3BlcnRpZXMgYW5kIGFkZGl0aW9uYWwgYXJndW1lbnRzLlxuICAgKiBAc3VtbWFyeSBBYnN0cmFjdCBtZXRob2QgdG8gYmUgaW1wbGVtZW50ZWQgYnkgc3ViY2xhc3NlcyB0byBkZWZpbmUgc3BlY2lmaWMgcmVuZGVyaW5nIGJlaGF2aW9yLlxuICAgKlxuICAgKiBAdGVtcGxhdGUgTSBUeXBlIGV4dGVuZGluZyBNb2RlbFxuICAgKiBAdGVtcGxhdGUgUiBSZW5kZXJpbmcgZW5naW5lIGltcGxlbWVudGF0aW9uIHNwZWNpZmljIG91dHB1dCB0eXBlXG4gICAqIEBwYXJhbSB7TX0gbW9kZWwgLSBUaGUgbW9kZWwgdG8gYmUgcmVuZGVyZWQuXG4gICAqIEBwYXJhbSB7UmVjb3JkPHN0cmluZywgdW5rbm93bj59IGdsb2JhbFByb3BzIC0gR2xvYmFsIHByb3BlcnRpZXMgdG8gYmUgYXBwbGllZCB0byBhbGwgZWxlbWVudHMgZHVyaW5nIHJlbmRlcmluZy5cbiAgICogQHBhcmFtIHsuLi5hbnlbXX0gYXJncyAtIEFkZGl0aW9uYWwgYXJndW1lbnRzIHRoYXQgbWF5IGJlIHJlcXVpcmVkIGZvciBzcGVjaWZpYyByZW5kZXJpbmcgaW1wbGVtZW50YXRpb25zLlxuICAgKiBAcmV0dXJucyB7Un0gVGhlIHJlbmRlcmVkIHJlc3VsdCwgdHlwZSBkZXBlbmRzIG9uIHRoZSBzcGVjaWZpYyBpbXBsZW1lbnRhdGlvbi5cbiAgICpcbiAgICogQGFic3RyYWN0XG4gICAqL1xuICBhYnN0cmFjdCByZW5kZXI8TSBleHRlbmRzIE1vZGVsPihcbiAgICBtb2RlbDogTSxcbiAgICBnbG9iYWxQcm9wczogUmVjb3JkPHN0cmluZywgdW5rbm93bj4sXG4gICAgLi4uYXJnczogYW55W11cbiAgKTogUjtcblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFJlZ2lzdGVycyBhIHJlbmRlcmluZyBlbmdpbmUgaW5zdGFuY2UuXG4gICAqIEBzdW1tYXJ5IEFkZHMgYSByZW5kZXJpbmcgZW5naW5lIHRvIHRoZSBzdGF0aWMgY2FjaGUgYW5kIHNldHMgaXQgYXMgdGhlIGN1cnJlbnQgZW5naW5lLlxuICAgKlxuICAgKiBAcGFyYW0ge1JlbmRlcmluZ0VuZ2luZTx1bmtub3duLCB1bmtub3duPn0gZW5naW5lIC0gVGhlIHJlbmRlcmluZyBlbmdpbmUgdG8gcmVnaXN0ZXIuXG4gICAqIEB0aHJvd3Mge0ludGVybmFsRXJyb3J9IElmIGFuIGVuZ2luZSB3aXRoIHRoZSBzYW1lIGZsYXZvciBhbHJlYWR5IGV4aXN0cy5cbiAgICpcbiAgICogQHN0YXRpY1xuICAgKi9cbiAgc3RhdGljIHJlZ2lzdGVyKGVuZ2luZTogUmVuZGVyaW5nRW5naW5lPHVua25vd24sIHVua25vd24+KSB7XG4gICAgaWYgKGVuZ2luZS5mbGF2b3VyIGluIHRoaXMuY2FjaGUpXG4gICAgICB0aHJvdyBuZXcgSW50ZXJuYWxFcnJvcihcbiAgICAgICAgYFJlbmRlcmluZyBlbmdpbmUgdW5kZXIgJHtlbmdpbmUuZmxhdm91cn0gYWxyZWFkeSBleGlzdHNgXG4gICAgICApO1xuICAgIHRoaXMuY2FjaGVbZW5naW5lLmZsYXZvdXJdID0gZW5naW5lO1xuICAgIHRoaXMuY3VycmVudCA9IGVuZ2luZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gUmV0cmlldmVzIG9yIGluaXRpYWxpemVzIGEgcmVuZGVyaW5nIGVuZ2luZS5cbiAgICogQHN1bW1hcnkgR2V0cyBhbiBleGlzdGluZyBlbmdpbmUgaW5zdGFuY2Ugb3IgY3JlYXRlcyBhbmQgaW5pdGlhbGl6ZXMgYSBuZXcgb25lIGlmIGdpdmVuIGEgY29uc3RydWN0b3IuXG4gICAqXG4gICAqIEB0ZW1wbGF0ZSBPIFRoZSB0eXBlIG9mIHRoZSByZW5kZXJpbmcgZW5naW5lIG91dHB1dFxuICAgKiBAcGFyYW0ge0NvbnN0cnVjdG9yPFJlbmRlcmluZ0VuZ2luZTxPPj4gfCBSZW5kZXJpbmdFbmdpbmU8Tz59IG9iaiAtIFRoZSBlbmdpbmUgaW5zdGFuY2Ugb3IgY29uc3RydWN0b3IuXG4gICAqIEByZXR1cm5zIHtSZW5kZXJpbmdFbmdpbmU8Tz59IFRoZSBpbml0aWFsaXplZCByZW5kZXJpbmcgZW5naW5lLlxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAc3RhdGljXG4gICAqL1xuICBwcml2YXRlIHN0YXRpYyBnZXRPckJvb3Q8Tz4oXG4gICAgb2JqOiBDb25zdHJ1Y3RvcjxSZW5kZXJpbmdFbmdpbmU8Tz4+IHwgUmVuZGVyaW5nRW5naW5lPE8+XG4gICk6IFJlbmRlcmluZ0VuZ2luZTxPPiB7XG4gICAgaWYgKG9iaiBpbnN0YW5jZW9mIFJlbmRlcmluZ0VuZ2luZSkgcmV0dXJuIG9iaiBhcyBSZW5kZXJpbmdFbmdpbmU8Tz47XG4gICAgY29uc3QgZW5naW5lOiBSZW5kZXJpbmdFbmdpbmU8Tz4gPSBuZXcgb2JqKCk7XG4gICAgZW5naW5lLmluaXRpYWxpemUoKTsgLy8gbWFrZSB0aGUgYm9vdGluZyBhc3luYy4gdXNlIHRoZSBpbml0aWFsaXplZCBmbGFnIHRvIGNvbnRyb2wgaXRcbiAgICByZXR1cm4gZW5naW5lIGFzIFJlbmRlcmluZ0VuZ2luZTxPPjtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gUmV0cmlldmVzIGEgcmVuZGVyaW5nIGVuZ2luZSBieSBmbGF2b3IuXG4gICAqIEBzdW1tYXJ5IEdldHMgdGhlIGN1cnJlbnQgcmVuZGVyaW5nIGVuZ2luZSBvciBhIHNwZWNpZmljIG9uZSBieSBmbGF2b3IuXG4gICAqXG4gICAqIEB0ZW1wbGF0ZSBPIFRoZSB0eXBlIG9mIHRoZSByZW5kZXJpbmcgZW5naW5lIG91dHB1dFxuICAgKiBAcGFyYW0ge3N0cmluZ30gW2ZsYXZvdXJdIC0gVGhlIGZsYXZvciBvZiB0aGUgcmVuZGVyaW5nIGVuZ2luZSB0byByZXRyaWV2ZS5cbiAgICogQHJldHVybnMge1JlbmRlcmluZ0VuZ2luZTxPPn0gVGhlIHJlcXVlc3RlZCByZW5kZXJpbmcgZW5naW5lLlxuICAgKiBAdGhyb3dzIHtJbnRlcm5hbEVycm9yfSBJZiB0aGUgcmVxdWVzdGVkIGZsYXZvciBkb2VzIG5vdCBleGlzdC5cbiAgICpcbiAgICogQHN0YXRpY1xuICAgKi9cbiAgc3RhdGljIGdldDxPPihmbGF2b3VyPzogc3RyaW5nKTogUmVuZGVyaW5nRW5naW5lPE8+IHtcbiAgICBpZiAoIWZsYXZvdXIpXG4gICAgICByZXR1cm4gdGhpcy5nZXRPckJvb3Q8Tz4oXG4gICAgICAgIHRoaXMuY3VycmVudCBhcyBDb25zdHJ1Y3RvcjxSZW5kZXJpbmdFbmdpbmU8Tz4+IHwgUmVuZGVyaW5nRW5naW5lPE8+XG4gICAgICApO1xuICAgIGlmICghKGZsYXZvdXIgaW4gdGhpcy5jYWNoZSkpXG4gICAgICB0aHJvdyBuZXcgSW50ZXJuYWxFcnJvcihcbiAgICAgICAgYFJlbmRlcmluZyBlbmdpbmUgdW5kZXIgJHtmbGF2b3VyfSBkb2VzIG5vdCBleGlzdGBcbiAgICAgICk7XG4gICAgcmV0dXJuIHRoaXMuZ2V0T3JCb290PE8+KFxuICAgICAgdGhpcy5jYWNoZVtmbGF2b3VyXSBhc1xuICAgICAgICB8IENvbnN0cnVjdG9yPFJlbmRlcmluZ0VuZ2luZTxPPj5cbiAgICAgICAgfCBSZW5kZXJpbmdFbmdpbmU8Tz5cbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBSZW5kZXJzIGEgbW9kZWwgdXNpbmcgdGhlIGFwcHJvcHJpYXRlIHJlbmRlcmluZyBlbmdpbmUuXG4gICAqIEBzdW1tYXJ5IERldGVybWluZXMgdGhlIGNvcnJlY3QgcmVuZGVyaW5nIGVuZ2luZSBmb3IgYSBtb2RlbCBhbmQgaW52b2tlcyBpdHMgcmVuZGVyIG1ldGhvZC5cbiAgICpcbiAgICogQHRlbXBsYXRlIE0gVHlwZSBleHRlbmRpbmcgTW9kZWxcbiAgICogQHBhcmFtIHtNfSBtb2RlbCAtIFRoZSBtb2RlbCB0byByZW5kZXIuXG4gICAqIEBwYXJhbSB7Li4uYW55W119IGFyZ3MgLSBBZGRpdGlvbmFsIGFyZ3VtZW50cyB0byBwYXNzIHRvIHRoZSByZW5kZXIgbWV0aG9kLlxuICAgKiBAcmV0dXJucyB7YW55fSBUaGUgcmVzdWx0IG9mIHRoZSByZW5kZXJpbmcgcHJvY2Vzcy5cbiAgICogQHRocm93cyB7SW50ZXJuYWxFcnJvcn0gSWYgbm8gcmVnaXN0ZXJlZCBtb2RlbCBpcyBmb3VuZC5cbiAgICpcbiAgICogQHN0YXRpY1xuICAgKi9cbiAgc3RhdGljIHJlbmRlcjxNIGV4dGVuZHMgTW9kZWw+KG1vZGVsOiBNLCAuLi5hcmdzOiBhbnlbXSk6IGFueSB7XG4gICAgY29uc3QgY29uc3RydWN0b3IgPSBNb2RlbC5nZXQobW9kZWwuY29uc3RydWN0b3IubmFtZSk7XG4gICAgaWYgKCFjb25zdHJ1Y3RvcikgdGhyb3cgbmV3IEludGVybmFsRXJyb3IoXCJObyBtb2RlbCByZWdpc3RlcmVkIGZvdW5kXCIpO1xuICAgIGNvbnN0IGZsYXZvdXIgPSBSZWZsZWN0LmdldE1ldGFkYXRhKFxuICAgICAgUmVuZGVyaW5nRW5naW5lLmtleShVSUtleXMuUkVOREVSRURfQlkpLFxuICAgICAgY29uc3RydWN0b3IgYXMgTW9kZWxDb25zdHJ1Y3RvcjxNb2RlbD5cbiAgICApO1xuXG4gICAgLy8gQHRzLWV4cGVjdC1lcnJvciBmb3IgdGhlIHZhciBhcmdzIHR5cGUgY2hlY2tcbiAgICByZXR1cm4gUmVuZGVyaW5nRW5naW5lLmdldChmbGF2b3VyKS5yZW5kZXIobW9kZWwsIC4uLmFyZ3MpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBHZW5lcmF0ZXMgYSBtZXRhZGF0YSBrZXkgZm9yIFVJLXJlbGF0ZWQgcHJvcGVydGllcy5cbiAgICogQHN1bW1hcnkgUHJlZml4ZXMgYSBnaXZlbiBrZXkgd2l0aCB0aGUgVUkgcmVmbGVjdGlvbiBwcmVmaXguXG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgLSBUaGUga2V5IHRvIHByZWZpeC5cbiAgICogQHJldHVybnMge3N0cmluZ30gVGhlIHByZWZpeGVkIGtleS5cbiAgICpcbiAgICogQHN0YXRpY1xuICAgKi9cbiAgc3RhdGljIGtleShrZXk6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgcmV0dXJuIGAke1VJS2V5cy5SRUZMRUNUfSR7a2V5fWA7XG4gIH1cbn1cbiIsImltcG9ydCB7IFVJS2V5cyB9IGZyb20gXCIuLi91aS9jb25zdGFudHNcIjtcbmltcG9ydCB7IGFwcGx5LCBtZXRhZGF0YSB9IGZyb20gXCJAZGVjYWYtdHMvcmVmbGVjdGlvblwiO1xuaW1wb3J0IHsgUmVuZGVyaW5nRW5naW5lIH0gZnJvbSBcIi4uL3VpL1JlbmRlcmluZ1wiO1xuaW1wb3J0IHsgVUlMaXN0SXRlbU1vZGVsTWV0YWRhdGEsIFVJTW9kZWxNZXRhZGF0YSB9IGZyb20gXCIuLi91aS90eXBlc1wiO1xuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBEZWNvcmF0b3IgdGhhdCB0YWdzIGEgY2xhc3MgYXMgYSBVSSBtb2RlbFxuICogQHN1bW1hcnkgQWRkcyByZW5kZXJpbmcgY2FwYWJpbGl0aWVzIHRvIGEgbW9kZWwgY2xhc3MgYnkgcHJvdmlkaW5nIGEgcmVuZGVyIG1ldGhvZFxuICogVGhpcyBkZWNvcmF0b3IgYXBwbGllcyBtZXRhZGF0YSB0byB0aGUgY2xhc3MgdGhhdCBlbmFibGVzIGl0IHRvIGJlIHJlbmRlcmVkIGJ5IHRoZSBVSSByZW5kZXJpbmcgZW5naW5lLlxuICogVGhlIG1vZGVsIHdpbGwgYmUgcmVuZGVyZWQgd2l0aCB0aGUgc3BlY2lmaWVkIHRhZyBhbmQgcHJvcGVydGllcy5cbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gW3RhZ10gVGhlIEhUTUwgdGFnIHRvIHVzZSB3aGVuIHJlbmRlcmluZyB0aGlzIG1vZGVsIChkZWZhdWx0cyB0byBjbGFzcyBuYW1lKVxuICogQHBhcmFtIHtSZWNvcmQ8c3RyaW5nLCBhbnk+fSBbcHJvcHNdIEFkZGl0aW9uYWwgcHJvcGVydGllcyB0byBwYXNzIHRvIHRoZSByZW5kZXJlZCBlbGVtZW50XG4gKiBAcmV0dXJuIHtGdW5jdGlvbn0gQSBjbGFzcyBkZWNvcmF0b3IgZnVuY3Rpb25cbiAqXG4gKiBAZnVuY3Rpb24gdWltb2RlbFxuICogQGNhdGVnb3J5IENsYXNzIERlY29yYXRvcnNcbiAqXG4gKiBAZXhhbXBsZVxuICogLy8gQmFzaWMgdXNhZ2Ugd2l0aCBkZWZhdWx0IHRhZyAoY2xhc3MgbmFtZSlcbiAqIEB1aW1vZGVsKClcbiAqIGNsYXNzIFVzZXJQcm9maWxlIGV4dGVuZHMgTW9kZWwge1xuICogICBAYXR0cmlidXRlKClcbiAqICAgbmFtZTogc3RyaW5nO1xuICpcbiAqICAgQGF0dHJpYnV0ZSgpXG4gKiAgIGVtYWlsOiBzdHJpbmc7XG4gKiB9XG4gKlxuICogLy8gVXNhZ2Ugd2l0aCBjdXN0b20gdGFnIGFuZCBwcm9wZXJ0aWVzXG4gKiBAdWltb2RlbCgnZGl2JywgeyBjbGFzczogJ3VzZXItY2FyZCcgfSlcbiAqIGNsYXNzIFVzZXJDYXJkIGV4dGVuZHMgTW9kZWwge1xuICogICBAYXR0cmlidXRlKClcbiAqICAgdXNlcm5hbWU6IHN0cmluZztcbiAqIH1cbiAqXG4gKiBAbWVybWFpZFxuICogc2VxdWVuY2VEaWFncmFtXG4gKiAgIHBhcnRpY2lwYW50IFN5c3RlbVxuICogICBwYXJ0aWNpcGFudCB1aW1vZGVsXG4gKiAgIHBhcnRpY2lwYW50IGNvbnN0cnVjdG9yXG4gKiAgIHBhcnRpY2lwYW50IGluc3RhbmNlXG4gKiAgIFN5c3RlbS0+PnVpbW9kZWw6ZG8oY29uc3RydWN0b3IpXG4gKiAgIHVpbW9kZWwtPj5jb25zdHJ1Y3RvcjogRXhlY3V0ZXMgdGhlIGNvbnN0cnVjdG9yXG4gKiAgIGNvbnN0cnVjdG9yLT4+dWltb2RlbDogcmV0dXJucyBpbnN0YW5jZVxuICogICB1aW1vZGVsLT4+aW5zdGFuY2U6IGFkZHMgdGhlIHJlbmRlciBtZXRob2RcbiAqICAgdWltb2RlbC0+PlN5c3RlbTogcmV0dXJucyBVSU1vZGVsIGluc3RhbmNlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB1aW1vZGVsKHRhZz86IHN0cmluZywgcHJvcHM/OiBSZWNvcmQ8c3RyaW5nLCBhbnk+KSB7XG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnNcbiAgcmV0dXJuIChvcmlnaW5hbDogYW55LCBwcm9wZXJ0eUtleT86IGFueSkgPT4ge1xuICAgIGNvbnN0IG1ldGE6IFVJTW9kZWxNZXRhZGF0YSA9IHtcbiAgICAgIHRhZzogdGFnIHx8IG9yaWdpbmFsLm5hbWUsXG4gICAgICBwcm9wczogcHJvcHMsXG4gICAgfTtcbiAgICByZXR1cm4gbWV0YWRhdGEoUmVuZGVyaW5nRW5naW5lLmtleShVSUtleXMuVUlNT0RFTCksIG1ldGEpKG9yaWdpbmFsKTtcbiAgfTtcbn1cblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gRGVjb3JhdG9yIHRoYXQgc3BlY2lmaWVzIHdoaWNoIHJlbmRlcmluZyBlbmdpbmUgdG8gdXNlIGZvciBhIG1vZGVsXG4gKiBAc3VtbWFyeSBBc3NvY2lhdGVzIGEgbW9kZWwgd2l0aCBhIHNwZWNpZmljIHJlbmRlcmluZyBlbmdpbmUgaW1wbGVtZW50YXRpb25cbiAqIFRoaXMgZGVjb3JhdG9yIGFsbG93cyB5b3UgdG8gb3ZlcnJpZGUgdGhlIGRlZmF1bHQgcmVuZGVyaW5nIGVuZ2luZSBmb3IgYSBzcGVjaWZpYyBtb2RlbCBjbGFzcyxcbiAqIGVuYWJsaW5nIGRpZmZlcmVudCByZW5kZXJpbmcgc3RyYXRlZ2llcyBmb3IgZGlmZmVyZW50IG1vZGVscy5cbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gZW5naW5lIFRoZSBuYW1lIG9mIHRoZSByZW5kZXJpbmcgZW5naW5lIHRvIHVzZVxuICogQHJldHVybiB7RnVuY3Rpb259IEEgY2xhc3MgZGVjb3JhdG9yIGZ1bmN0aW9uXG4gKlxuICogQGZ1bmN0aW9uIHJlbmRlcmVkQnlcbiAqIEBjYXRlZ29yeSBDbGFzcyBEZWNvcmF0b3JzXG4gKlxuICogQGV4YW1wbGVcbiAqIC8vIFNwZWNpZnkgYSBjdXN0b20gcmVuZGVyaW5nIGVuZ2luZSBmb3IgYSBtb2RlbFxuICogQHVpbW9kZWwoKVxuICogQHJlbmRlcmVkQnkoJ3JlYWN0JylcbiAqIGNsYXNzIFJlYWN0Q29tcG9uZW50IGV4dGVuZHMgTW9kZWwge1xuICogICBAYXR0cmlidXRlKClcbiAqICAgdGl0bGU6IHN0cmluZztcbiAqIH1cbiAqXG4gKiBAbWVybWFpZFxuICogc2VxdWVuY2VEaWFncmFtXG4gKiAgIHBhcnRpY2lwYW50IFN5c3RlbVxuICogICBwYXJ0aWNpcGFudCByZW5kZXJlZEJ5XG4gKiAgIHBhcnRpY2lwYW50IE1vZGVsXG4gKiAgIHBhcnRpY2lwYW50IFJlbmRlcmluZ0VuZ2luZVxuICogICBTeXN0ZW0tPj5yZW5kZXJlZEJ5OiBhcHBseSB0byBNb2RlbFxuICogICByZW5kZXJlZEJ5LT4+TW9kZWw6IGFkZHMgZW5naW5lIG1ldGFkYXRhXG4gKiAgIE1vZGVsLT4+UmVuZGVyaW5nRW5naW5lOiB1c2VzIHNwZWNpZmllZCBlbmdpbmVcbiAqICAgUmVuZGVyaW5nRW5naW5lLT4+U3lzdGVtOiByZW5kZXJzIHdpdGggY3VzdG9tIGVuZ2luZVxuICovXG5leHBvcnQgZnVuY3Rpb24gcmVuZGVyZWRCeShlbmdpbmU6IHN0cmluZykge1xuICByZXR1cm4gYXBwbHkobWV0YWRhdGEoUmVuZGVyaW5nRW5naW5lLmtleShVSUtleXMuUkVOREVSRURfQlkpLCBlbmdpbmUpKTtcbn1cblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gRGVjb3JhdG9yIHRoYXQgdGFncyBhIG1vZGVsIGFzIGEgbGlzdCBpdGVtIGZvciBVSSByZW5kZXJpbmdcbiAqIEBzdW1tYXJ5IFNwZWNpZmllcyBob3cgYSBtb2RlbCBzaG91bGQgYmUgcmVuZGVyZWQgd2hlbiBkaXNwbGF5ZWQgaW4gYSBsaXN0IGNvbnRleHRcbiAqIFRoaXMgZGVjb3JhdG9yIGFwcGxpZXMgbWV0YWRhdGEgdG8gdGhlIGNsYXNzIHRoYXQgZW5hYmxlcyBpdCB0byBiZSByZW5kZXJlZCBhcyBhIGxpc3QgaXRlbVxuICogYnkgdGhlIFVJIHJlbmRlcmluZyBlbmdpbmUuIFRoZSBtb2RlbCB3aWxsIGJlIHJlbmRlcmVkIHdpdGggdGhlIHNwZWNpZmllZCB0YWcgYW5kIHByb3BlcnRpZXNcbiAqIHdoZW4gaXQgYXBwZWFycyBpbiBhIGxpc3QuXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IFt0YWddIFRoZSBIVE1MIHRhZyB0byB1c2Ugd2hlbiByZW5kZXJpbmcgdGhpcyBtb2RlbCBhcyBhIGxpc3QgaXRlbSAoZGVmYXVsdHMgdG8gY2xhc3MgbmFtZSlcbiAqIEBwYXJhbSB7UmVjb3JkPHN0cmluZywgYW55Pn0gW3Byb3BzXSBBZGRpdGlvbmFsIHByb3BlcnRpZXMgdG8gcGFzcyB0byB0aGUgcmVuZGVyZWQgbGlzdCBpdGVtIGVsZW1lbnRcbiAqIEByZXR1cm4ge0Z1bmN0aW9ufSBBIGNsYXNzIGRlY29yYXRvciBmdW5jdGlvblxuICpcbiAqIEBmdW5jdGlvbiB1aWxpc3RpdGVtXG4gKiBAY2F0ZWdvcnkgQ2xhc3MgRGVjb3JhdG9yc1xuICpcbiAqIEBleGFtcGxlXG4gKiAvLyBCYXNpYyB1c2FnZSB3aXRoIGRlZmF1bHQgdGFnIChjbGFzcyBuYW1lKVxuICogQHVpbW9kZWwoKVxuICogQHVpbGlzdGl0ZW0oKVxuICogY2xhc3MgVG9kb0l0ZW0gZXh0ZW5kcyBNb2RlbCB7XG4gKiAgIEBhdHRyaWJ1dGUoKVxuICogICB0aXRsZTogc3RyaW5nO1xuICpcbiAqICAgQGF0dHJpYnV0ZSgpXG4gKiAgIGNvbXBsZXRlZDogYm9vbGVhbjtcbiAqIH1cbiAqXG4gKiAvLyBVc2FnZSB3aXRoIGN1c3RvbSB0YWcgYW5kIHByb3BlcnRpZXNcbiAqIEB1aW1vZGVsKClcbiAqIEB1aWxpc3RpdGVtKCdsaScsIHsgY2xhc3M6ICdsaXN0LWdyb3VwLWl0ZW0nIH0pXG4gKiBjbGFzcyBMaXN0SXRlbSBleHRlbmRzIE1vZGVsIHtcbiAqICAgQGF0dHJpYnV0ZSgpXG4gKiAgIHRleHQ6IHN0cmluZztcbiAqIH1cbiAqXG4gKiBAbWVybWFpZFxuICogc2VxdWVuY2VEaWFncmFtXG4gKiAgIHBhcnRpY2lwYW50IFN5c3RlbVxuICogICBwYXJ0aWNpcGFudCB1aWxpc3RpdGVtXG4gKiAgIHBhcnRpY2lwYW50IE1vZGVsXG4gKiAgIHBhcnRpY2lwYW50IFJlbmRlcmluZ0VuZ2luZVxuICogICBTeXN0ZW0tPj51aWxpc3RpdGVtOiBhcHBseSB0byBNb2RlbFxuICogICB1aWxpc3RpdGVtLT4+TW9kZWw6IGFkZHMgbGlzdCBpdGVtIG1ldGFkYXRhXG4gKiAgIE1vZGVsLT4+UmVuZGVyaW5nRW5naW5lOiB1c2VzIGxpc3QgaXRlbSBtZXRhZGF0YSB3aGVuIGluIGxpc3QgY29udGV4dFxuICogICBSZW5kZXJpbmdFbmdpbmUtPj5TeXN0ZW06IHJlbmRlcnMgd2l0aCBsaXN0IGl0ZW0gc3R5bGluZ1xuICovXG5leHBvcnQgZnVuY3Rpb24gdWlsaXN0aXRlbSh0YWc/OiBzdHJpbmcsIHByb3BzPzogUmVjb3JkPHN0cmluZywgYW55Pikge1xuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVudXNlZC12YXJzXG4gIHJldHVybiAob3JpZ2luYWw6IGFueSwgcHJvcGVydHlLZXk/OiBhbnkpID0+IHtcbiAgICBjb25zdCBtZXRhOiBVSUxpc3RJdGVtTW9kZWxNZXRhZGF0YSA9IHtcbiAgICAgIGl0ZW06IHtcbiAgICAgICAgdGFnOiB0YWcgfHwgb3JpZ2luYWwubmFtZSxcbiAgICAgICAgcHJvcHM6IHByb3BzLFxuICAgICAgfSxcbiAgICB9O1xuICAgIHJldHVybiBtZXRhZGF0YShSZW5kZXJpbmdFbmdpbmUua2V5KFVJS2V5cy5VSUxJU1RJVEVNKSwgbWV0YSkob3JpZ2luYWwpO1xuICB9O1xufVxuIiwiLyoqXG4gKiBAZGVzY3JpcHRpb24gTW9kdWxlIHRoYXQgZXh0ZW5kcyB0aGUgTW9kZWwgcHJvdG90eXBlIHdpdGggcmVuZGVyaW5nIGNhcGFiaWxpdGllc1xuICogQHN1bW1hcnkgQWRkcyB0aGUgcmVuZGVyIG1ldGhvZCB0byBhbGwgTW9kZWwgaW5zdGFuY2VzIGZyb20gZGVjb3JhdG9yLXZhbGlkYXRpb25cbiAqIFRoaXMgbW9kdWxlIGltcGxlbWVudHMgdGhlIFJlbmRlcmFibGUgaW50ZXJmYWNlIGZvciB0aGUgTW9kZWwgY2xhc3MgYnkgYWRkaW5nIGEgcmVuZGVyIG1ldGhvZFxuICogdG8gaXRzIHByb3RvdHlwZS4gVGhpcyBhbGxvd3MgYW55IE1vZGVsIGluc3RhbmNlIHRvIGJlIHJlbmRlcmVkIHVzaW5nIHRoZSBSZW5kZXJpbmdFbmdpbmUuXG4gKiBAbW9kdWxlIG1vZGVsL292ZXJyaWRlc1xuICogQG1lbWJlck9mIG1vZHVsZTp1aS1kZWNvcmF0b3JzL21vZGVsXG4gKi9cblxuaW1wb3J0IHsgTW9kZWwgfSBmcm9tIFwiQGRlY2FmLXRzL2RlY29yYXRvci12YWxpZGF0aW9uXCI7XG5pbXBvcnQgeyBSZW5kZXJpbmdFbmdpbmUgfSBmcm9tIFwiLi4vdWkvUmVuZGVyaW5nXCI7XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIFJlbmRlcnMgdGhlIG1vZGVsIHVzaW5nIHRoZSBhcHByb3ByaWF0ZSByZW5kZXJpbmcgZW5naW5lXG4gKiBAc3VtbWFyeSBEZWxlZ2F0ZXMgcmVuZGVyaW5nIHRvIHRoZSBSZW5kZXJpbmdFbmdpbmUgYmFzZWQgb24gbW9kZWwgbWV0YWRhdGFcbiAqIFRoaXMgbWV0aG9kIGltcGxlbWVudHMgdGhlIHJlbmRlciBtZXRob2QgZnJvbSB0aGUgUmVuZGVyYWJsZSBpbnRlcmZhY2UgZm9yIGFsbCBNb2RlbCBpbnN0YW5jZXMuXG4gKiBJdCB1c2VzIHRoZSBSZW5kZXJpbmdFbmdpbmUgdG8gZGV0ZXJtaW5lIGhvdyB0byByZW5kZXIgdGhlIG1vZGVsIGJhc2VkIG9uIGl0cyBtZXRhZGF0YS5cbiAqXG4gKiBAdGVtcGxhdGUgTSBUeXBlIG9mIHRoZSBtb2RlbCBiZWluZyByZW5kZXJlZFxuICogQHBhcmFtIHthbnlbXX0gYXJncyBBZGRpdGlvbmFsIGFyZ3VtZW50cyB0byBwYXNzIHRvIHRoZSByZW5kZXJpbmcgZW5naW5lXG4gKiBAcmV0dXJuIHthbnl9IFRoZSByZW5kZXJlZCBvdXRwdXQgaW4gdGhlIGZvcm1hdCBkZXRlcm1pbmVkIGJ5IHRoZSByZW5kZXJpbmcgZW5naW5lXG4gKi9cbk1vZGVsLnByb3RvdHlwZS5yZW5kZXIgPSBmdW5jdGlvbiA8TSBleHRlbmRzIE1vZGVsPih0aGlzOiBNLCAuLi5hcmdzOiBhbnlbXSkge1xuICByZXR1cm4gUmVuZGVyaW5nRW5naW5lLnJlbmRlcih0aGlzLCAuLi5hcmdzKTtcbn07XG4iLCJpbXBvcnQgXCJyZWZsZWN0LW1ldGFkYXRhXCI7XG5pbXBvcnQgeyBVSUtleXMgfSBmcm9tIFwiLi9jb25zdGFudHNcIjtcbmltcG9ydCB7IHByb3BNZXRhZGF0YSB9IGZyb20gXCJAZGVjYWYtdHMvZGVjb3JhdG9yLXZhbGlkYXRpb25cIjtcbmltcG9ydCB7XG4gIENydWRPcGVyYXRpb25LZXlzLFxuICBVSUVsZW1lbnRNZXRhZGF0YSxcbiAgVUlMaXN0UHJvcE1ldGFkYXRhLFxuICBVSVByb3BNZXRhZGF0YSxcbn0gZnJvbSBcIi4vdHlwZXNcIjtcbmltcG9ydCB7IFJlbmRlcmluZ0VuZ2luZSB9IGZyb20gXCIuL1JlbmRlcmluZ1wiO1xuaW1wb3J0IHsgT3BlcmF0aW9uS2V5cyB9IGZyb20gXCJAZGVjYWYtdHMvZGItZGVjb3JhdG9yc1wiO1xuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBEZWNvcmF0b3IgdGhhdCBoaWRlcyBhIHByb3BlcnR5IGR1cmluZyBzcGVjaWZpYyBDUlVEIG9wZXJhdGlvbnNcbiAqIEBzdW1tYXJ5IENvbnRyb2xzIHByb3BlcnR5IHZpc2liaWxpdHkgYmFzZWQgb24gb3BlcmF0aW9uIHR5cGVcbiAqIFRoaXMgZGVjb3JhdG9yIGFsbG93cyB5b3UgdG8gc3BlY2lmeSB3aGljaCBDUlVEIG9wZXJhdGlvbnMgc2hvdWxkIGhpZGUgYSBwcm9wZXJ0eVxuICogaW4gdGhlIFVJLiBUaGUgcHJvcGVydHkgd2lsbCBvbmx5IGJlIHZpc2libGUgZHVyaW5nIG9wZXJhdGlvbnMgbm90IHNwZWNpZmllZC5cbiAqXG4gKiBAcGFyYW0gb3BlcmF0aW9ucyAtIFRoZSBDUlVEIG9wZXJhdGlvbnMgZHVyaW5nIHdoaWNoIHRoZSBwcm9wZXJ0eSBzaG91bGQgYmUgaGlkZGVuXG4gKiBAcmV0dXJuIHtGdW5jdGlvbn0gQSBwcm9wZXJ0eSBkZWNvcmF0b3IgZnVuY3Rpb25cbiAqXG4gKiBAZnVuY3Rpb24gaGlkZU9uXG4gKiBAY2F0ZWdvcnkgUHJvcGVydHkgRGVjb3JhdG9yc1xuICpcbiAqIEBleGFtcGxlXG4gKiAvLyBIaWRlIHRoZSBwYXNzd29yZCBmaWVsZCBkdXJpbmcgUkVBRCBvcGVyYXRpb25zXG4gKiBjbGFzcyBVc2VyIHtcbiAqICAgQGF0dHJpYnV0ZSgpXG4gKiAgIHVzZXJuYW1lOiBzdHJpbmc7XG4gKlxuICogICBAYXR0cmlidXRlKClcbiAqICAgQGhpZGVPbihPcGVyYXRpb25LZXlzLlJFQUQpXG4gKiAgIHBhc3N3b3JkOiBzdHJpbmc7XG4gKiB9XG4gKlxuICogQG1lcm1haWRcbiAqIHNlcXVlbmNlRGlhZ3JhbVxuICogICBwYXJ0aWNpcGFudCBNb2RlbFxuICogICBwYXJ0aWNpcGFudCBoaWRlT25cbiAqICAgcGFydGljaXBhbnQgUmVuZGVyaW5nRW5naW5lXG4gKiAgIHBhcnRpY2lwYW50IFVJXG4gKiAgIE1vZGVsLT4+aGlkZU9uOiBBcHBseSB0byBwcm9wZXJ0eVxuICogICBoaWRlT24tPj5Nb2RlbDogQWRkIGhpZGRlbiBtZXRhZGF0YVxuICogICBSZW5kZXJpbmdFbmdpbmUtPj5Nb2RlbDogQ2hlY2sgaWYgcHJvcGVydHkgc2hvdWxkIGJlIGhpZGRlblxuICogICBNb2RlbC0+PlJlbmRlcmluZ0VuZ2luZTogUmV0dXJuIGhpZGRlbiBvcGVyYXRpb25zXG4gKiAgIFJlbmRlcmluZ0VuZ2luZS0+PlVJOiBSZW5kZXIgb3IgaGlkZSBiYXNlZCBvbiBjdXJyZW50IG9wZXJhdGlvblxuICovXG5leHBvcnQgZnVuY3Rpb24gaGlkZU9uKC4uLm9wZXJhdGlvbnM6IENydWRPcGVyYXRpb25LZXlzW10pIHtcbiAgcmV0dXJuIHByb3BNZXRhZGF0YTxDcnVkT3BlcmF0aW9uS2V5c1tdPihcbiAgICBSZW5kZXJpbmdFbmdpbmUua2V5KFVJS2V5cy5ISURERU4pLFxuICAgIG9wZXJhdGlvbnNcbiAgKTtcbn1cblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gRGVjb3JhdG9yIHRoYXQgY29tcGxldGVseSBoaWRlcyBhIHByb3BlcnR5IGluIGFsbCBVSSBvcGVyYXRpb25zXG4gKiBAc3VtbWFyeSBNYWtlcyBhIHByb3BlcnR5IGludmlzaWJsZSBpbiBhbGwgQ1JVRCBvcGVyYXRpb25zXG4gKiBUaGlzIGRlY29yYXRvciBpcyBhIGNvbnZlbmllbmNlIHdyYXBwZXIgYXJvdW5kIGhpZGVPbiB0aGF0IGhpZGVzIGEgcHJvcGVydHlcbiAqIGR1cmluZyBhbGwgQ1JVRCBvcGVyYXRpb25zIChDUkVBVEUsIFJFQUQsIFVQREFURSwgREVMRVRFKS5cbiAqXG4gKiBAcmV0dXJuIHtGdW5jdGlvbn0gQSBwcm9wZXJ0eSBkZWNvcmF0b3IgZnVuY3Rpb25cbiAqXG4gKiBAZnVuY3Rpb24gaGlkZGVuXG4gKiBAY2F0ZWdvcnkgUHJvcGVydHkgRGVjb3JhdG9yc1xuICpcbiAqIEBleGFtcGxlXG4gKiAvLyBDb21wbGV0ZWx5IGhpZGUgdGhlIGludGVybmFsSWQgZmllbGQgaW4gdGhlIFVJXG4gKiBjbGFzcyBQcm9kdWN0IHtcbiAqICAgQGF0dHJpYnV0ZSgpXG4gKiAgIG5hbWU6IHN0cmluZztcbiAqXG4gKiAgIEBhdHRyaWJ1dGUoKVxuICogICBAaGlkZGVuKClcbiAqICAgaW50ZXJuYWxJZDogc3RyaW5nO1xuICogfVxuICpcbiAqIEBtZXJtYWlkXG4gKiBzZXF1ZW5jZURpYWdyYW1cbiAqICAgcGFydGljaXBhbnQgTW9kZWxcbiAqICAgcGFydGljaXBhbnQgaGlkZGVuXG4gKiAgIHBhcnRpY2lwYW50IGhpZGVPblxuICogICBwYXJ0aWNpcGFudCBSZW5kZXJpbmdFbmdpbmVcbiAqICAgTW9kZWwtPj5oaWRkZW46IEFwcGx5IHRvIHByb3BlcnR5XG4gKiAgIGhpZGRlbi0+PmhpZGVPbjogQ2FsbCB3aXRoIGFsbCBvcGVyYXRpb25zXG4gKiAgIGhpZGVPbi0+Pk1vZGVsOiBBZGQgaGlkZGVuIG1ldGFkYXRhXG4gKiAgIFJlbmRlcmluZ0VuZ2luZS0+Pk1vZGVsOiBDaGVjayBpZiBwcm9wZXJ0eSBzaG91bGQgYmUgaGlkZGVuXG4gKiAgIE1vZGVsLT4+UmVuZGVyaW5nRW5naW5lOiBSZXR1cm4gYWxsIG9wZXJhdGlvbnNcbiAqICAgUmVuZGVyaW5nRW5naW5lLT4+VUk6IEFsd2F5cyBoaWRlIHByb3BlcnR5XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBoaWRkZW4oKSB7XG4gIHJldHVybiBoaWRlT24oXG4gICAgT3BlcmF0aW9uS2V5cy5DUkVBVEUsXG4gICAgT3BlcmF0aW9uS2V5cy5SRUFELFxuICAgIE9wZXJhdGlvbktleXMuVVBEQVRFLFxuICAgIE9wZXJhdGlvbktleXMuREVMRVRFXG4gICk7XG59XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIERlY29yYXRvciB0aGF0IHNwZWNpZmllcyBob3cgYSBwcm9wZXJ0eSBzaG91bGQgYmUgcmVuZGVyZWQgYXMgYSBVSSBlbGVtZW50XG4gKiBAc3VtbWFyeSBNYXBzIGEgbW9kZWwgcHJvcGVydHkgdG8gYSBzcGVjaWZpYyBVSSBlbGVtZW50IHdpdGggY3VzdG9tIHByb3BlcnRpZXNcbiAqIFRoaXMgZGVjb3JhdG9yIGFsbG93cyB5b3UgdG8gZGVmaW5lIHdoaWNoIEhUTUwgZWxlbWVudCBvciBjb21wb25lbnQgc2hvdWxkIGJlIHVzZWRcbiAqIHRvIHJlbmRlciBhIHNwZWNpZmljIHByb3BlcnR5LCBhbG9uZyB3aXRoIGFueSBhZGRpdGlvbmFsIHByb3BlcnRpZXMgdG8gcGFzcyB0byB0aGF0IGVsZW1lbnQuXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IHRhZyBUaGUgSFRNTCBlbGVtZW50IG9yIGNvbXBvbmVudCB0YWcgbmFtZSB0byB1c2UgZm9yIHJlbmRlcmluZ1xuICogQHBhcmFtIHtSZWNvcmQ8c3RyaW5nLCBhbnk+fSBbcHJvcHNdIEFkZGl0aW9uYWwgcHJvcGVydGllcyB0byBwYXNzIHRvIHRoZSBlbGVtZW50XG4gKiBAcGFyYW0ge2Jvb2xlYW59IFtzZXJpYWxpemU9ZmFsc2VdIFdoZXRoZXIgdGhlIHByb3BlcnR5IHNob3VsZCBiZSBzZXJpYWxpemVkXG4gKiBAcmV0dXJuIHtGdW5jdGlvbn0gQSBwcm9wZXJ0eSBkZWNvcmF0b3IgZnVuY3Rpb25cbiAqXG4gKiBAZnVuY3Rpb24gdWllbGVtZW50XG4gKiBAY2F0ZWdvcnkgUHJvcGVydHkgRGVjb3JhdG9yc1xuICpcbiAqIEBleGFtcGxlXG4gKiAvLyBSZW5kZXIgYSBwcm9wZXJ0eSBhcyBhIHRleHQgaW5wdXRcbiAqIGNsYXNzIExvZ2luRm9ybSB7XG4gKiAgIEBhdHRyaWJ1dGUoKVxuICogICBAdWllbGVtZW50KCdpbnB1dCcsIHsgdHlwZTogJ3RleHQnLCBwbGFjZWhvbGRlcjogJ0VudGVyIHVzZXJuYW1lJyB9KVxuICogICB1c2VybmFtZTogc3RyaW5nO1xuICpcbiAqICAgQGF0dHJpYnV0ZSgpXG4gKiAgIEB1aWVsZW1lbnQoJ2lucHV0JywgeyB0eXBlOiAncGFzc3dvcmQnLCBwbGFjZWhvbGRlcjogJ0VudGVyIHBhc3N3b3JkJyB9KVxuICogICBwYXNzd29yZDogc3RyaW5nO1xuICpcbiAqICAgQGF0dHJpYnV0ZSgpXG4gKiAgIEB1aWVsZW1lbnQoJ2J1dHRvbicsIHsgY2xhc3M6ICdidG4tcHJpbWFyeScgfSlcbiAqICAgc3VibWl0OiBzdHJpbmcgPSAnTG9naW4nO1xuICogfVxuICpcbiAqIEBtZXJtYWlkXG4gKiBzZXF1ZW5jZURpYWdyYW1cbiAqICAgcGFydGljaXBhbnQgTW9kZWxcbiAqICAgcGFydGljaXBhbnQgdWllbGVtZW50XG4gKiAgIHBhcnRpY2lwYW50IFJlbmRlcmluZ0VuZ2luZVxuICogICBwYXJ0aWNpcGFudCBVSVxuICogICBNb2RlbC0+PnVpZWxlbWVudDogQXBwbHkgdG8gcHJvcGVydHlcbiAqICAgdWllbGVtZW50LT4+TW9kZWw6IEFkZCBlbGVtZW50IG1ldGFkYXRhXG4gKiAgIFJlbmRlcmluZ0VuZ2luZS0+Pk1vZGVsOiBHZXQgZWxlbWVudCBtZXRhZGF0YVxuICogICBNb2RlbC0+PlJlbmRlcmluZ0VuZ2luZTogUmV0dXJuIHRhZyBhbmQgcHJvcHNcbiAqICAgUmVuZGVyaW5nRW5naW5lLT4+VUk6IFJlbmRlciB3aXRoIHNwZWNpZmllZCBlbGVtZW50XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB1aWVsZW1lbnQoXG4gIHRhZzogc3RyaW5nLFxuICBwcm9wcz86IFJlY29yZDxzdHJpbmcsIGFueT4sXG4gIHNlcmlhbGl6ZTogYm9vbGVhbiA9IGZhbHNlXG4pIHtcbiAgcmV0dXJuIChvcmlnaW5hbDogYW55LCBwcm9wZXJ0eUtleT86IGFueSkgPT4ge1xuICAgIGNvbnN0IG1ldGFkYXRhOiBVSUVsZW1lbnRNZXRhZGF0YSA9IHtcbiAgICAgIHRhZzogdGFnLFxuICAgICAgc2VyaWFsaXplOiBzZXJpYWxpemUsXG4gICAgICBwcm9wczogT2JqZWN0LmFzc2lnbih7fSwgcHJvcHMgfHwge30sIHtcbiAgICAgICAgbmFtZTogcHJvcGVydHlLZXksXG4gICAgICB9KSxcbiAgICB9O1xuXG4gICAgcmV0dXJuIHByb3BNZXRhZGF0YShSZW5kZXJpbmdFbmdpbmUua2V5KFVJS2V5cy5FTEVNRU5UKSwgbWV0YWRhdGEpKFxuICAgICAgb3JpZ2luYWwsXG4gICAgICBwcm9wZXJ0eUtleVxuICAgICk7XG4gIH07XG59XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIERlY29yYXRvciB0aGF0IG1hcHMgYSBtb2RlbCBwcm9wZXJ0eSB0byBhIFVJIGNvbXBvbmVudCBwcm9wZXJ0eVxuICogQHN1bW1hcnkgU3BlY2lmaWVzIGhvdyBhIHByb3BlcnR5IHNob3VsZCBiZSBwYXNzZWQgdG8gYSBVSSBjb21wb25lbnRcbiAqIFRoaXMgZGVjb3JhdG9yIGFsbG93cyB5b3UgdG8gZGVmaW5lIGhvdyBhIG1vZGVsIHByb3BlcnR5IHNob3VsZCBiZSBtYXBwZWQgdG9cbiAqIGEgcHJvcGVydHkgb2YgdGhlIFVJIGNvbXBvbmVudCB3aGVuIHJlbmRlcmluZy4gSXQgcmVxdWlyZXMgdGhlIGNsYXNzIHRvIGJlXG4gKiBkZWNvcmF0ZWQgd2l0aCBAdWltb2RlbC5cbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gW3Byb3BOYW1lXSBUaGUgbmFtZSBvZiB0aGUgcHJvcGVydHkgdG8gcGFzcyB0byB0aGUgY29tcG9uZW50IChkZWZhdWx0cyB0byB0aGUgcHJvcGVydHkga2V5KVxuICogQHBhcmFtIHtib29sZWFufSBbc3RyaW5naWZ5PWZhbHNlXSBXaGV0aGVyIHRvIHN0cmluZ2lmeSB0aGUgcHJvcGVydHkgdmFsdWVcbiAqIEByZXR1cm4ge0Z1bmN0aW9ufSBBIHByb3BlcnR5IGRlY29yYXRvciBmdW5jdGlvblxuICpcbiAqIEBmdW5jdGlvbiB1aXByb3BcbiAqIEBjYXRlZ29yeSBQcm9wZXJ0eSBEZWNvcmF0b3JzXG4gKlxuICogQGV4YW1wbGVcbiAqIC8vIE1hcCBtb2RlbCBwcm9wZXJ0aWVzIHRvIGNvbXBvbmVudCBwcm9wZXJ0aWVzXG4gKiBAdWltb2RlbCgndXNlci1wcm9maWxlJylcbiAqIGNsYXNzIFVzZXJQcm9maWxlIHtcbiAqICAgQGF0dHJpYnV0ZSgpXG4gKiAgIEB1aXByb3AoKSAvLyBXaWxsIGJlIHBhc3NlZCBhcyAnZnVsbE5hbWUnIHRvIHRoZSBjb21wb25lbnRcbiAqICAgZnVsbE5hbWU6IHN0cmluZztcbiAqXG4gKiAgIEBhdHRyaWJ1dGUoKVxuICogICBAdWlwcm9wKCd1c2VyRW1haWwnKSAvLyBXaWxsIGJlIHBhc3NlZCBhcyAndXNlckVtYWlsJyB0byB0aGUgY29tcG9uZW50XG4gKiAgIGVtYWlsOiBzdHJpbmc7XG4gKlxuICogICBAYXR0cmlidXRlKClcbiAqICAgQHVpcHJvcCgndXNlckRhdGEnLCB0cnVlKSAvLyBXaWxsIGJlIHBhc3NlZCBhcyBzdHJpbmdpZmllZCBKU09OXG4gKiAgIHVzZXJEYXRhOiBSZWNvcmQ8c3RyaW5nLCBhbnk+O1xuICogfVxuICpcbiAqIEBtZXJtYWlkXG4gKiBzZXF1ZW5jZURpYWdyYW1cbiAqICAgcGFydGljaXBhbnQgTW9kZWxcbiAqICAgcGFydGljaXBhbnQgdWlwcm9wXG4gKiAgIHBhcnRpY2lwYW50IFJlbmRlcmluZ0VuZ2luZVxuICogICBwYXJ0aWNpcGFudCBDb21wb25lbnRcbiAqICAgTW9kZWwtPj51aXByb3A6IEFwcGx5IHRvIHByb3BlcnR5XG4gKiAgIHVpcHJvcC0+Pk1vZGVsOiBBZGQgcHJvcCBtZXRhZGF0YVxuICogICBSZW5kZXJpbmdFbmdpbmUtPj5Nb2RlbDogR2V0IHByb3AgbWV0YWRhdGFcbiAqICAgTW9kZWwtPj5SZW5kZXJpbmdFbmdpbmU6IFJldHVybiBwcm9wIG5hbWUgYW5kIHN0cmluZ2lmeSBmbGFnXG4gKiAgIFJlbmRlcmluZ0VuZ2luZS0+PkNvbXBvbmVudDogUGFzcyBwcm9wZXJ0eSB3aXRoIHNwZWNpZmllZCBuYW1lXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB1aXByb3AoXG4gIHByb3BOYW1lOiBzdHJpbmcgfCB1bmRlZmluZWQgPSB1bmRlZmluZWQsXG4gIHN0cmluZ2lmeTogYm9vbGVhbiA9IGZhbHNlXG4pIHtcbiAgcmV0dXJuICh0YXJnZXQ6IGFueSwgcHJvcGVydHlLZXk6IHN0cmluZykgPT4ge1xuICAgIGNvbnN0IG1ldGFkYXRhOiBVSVByb3BNZXRhZGF0YSA9IHtcbiAgICAgIG5hbWU6IHByb3BOYW1lIHx8IHByb3BlcnR5S2V5LFxuICAgICAgc3RyaW5naWZ5OiBzdHJpbmdpZnksXG4gICAgfTtcbiAgICBwcm9wTWV0YWRhdGEoUmVuZGVyaW5nRW5naW5lLmtleShVSUtleXMuUFJPUCksIG1ldGFkYXRhKShcbiAgICAgIHRhcmdldCxcbiAgICAgIHByb3BlcnR5S2V5XG4gICAgKTtcbiAgfTtcbn1cblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gRGVjb3JhdG9yIHRoYXQgbWFwcyBhIG1vZGVsIHByb3BlcnR5IHRvIGEgbGlzdCBpdGVtIGNvbXBvbmVudFxuICogQHN1bW1hcnkgU3BlY2lmaWVzIGhvdyBhIHByb3BlcnR5IHNob3VsZCBiZSByZW5kZXJlZCBpbiBhIGxpc3QgY29udGV4dFxuICogVGhpcyBkZWNvcmF0b3IgYWxsb3dzIHlvdSB0byBkZWZpbmUgaG93IGEgbW9kZWwgcHJvcGVydHkgY29udGFpbmluZyBhIGxpc3RcbiAqIHNob3VsZCBiZSByZW5kZXJlZC4gSXQgcmVxdWlyZXMgdGhlIGNsYXNzIHRvIGJlIGRlY29yYXRlZCB3aXRoIEB1aWxpc3RpdGVtLlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBbcHJvcE5hbWVdIFRoZSBuYW1lIG9mIHRoZSBwcm9wZXJ0eSB0byBwYXNzIHRvIHRoZSBsaXN0IGNvbXBvbmVudCAoZGVmYXVsdHMgdG8gdGhlIHByb3BlcnR5IGtleSlcbiAqIEBwYXJhbSB7UmVjb3JkPHN0cmluZywgYW55Pn0gW3Byb3BzXSBBZGRpdGlvbmFsIHByb3BlcnRpZXMgdG8gcGFzcyB0byB0aGUgbGlzdCBjb250YWluZXJcbiAqIEByZXR1cm4ge0Z1bmN0aW9ufSBBIHByb3BlcnR5IGRlY29yYXRvciBmdW5jdGlvblxuICpcbiAqIEBmdW5jdGlvbiB1aWxpc3Rwcm9wXG4gKiBAY2F0ZWdvcnkgUHJvcGVydHkgRGVjb3JhdG9yc1xuICpcbiAqIEBleGFtcGxlXG4gKiAvLyBEZWZpbmUgYSBsaXN0IHByb3BlcnR5IHdpdGggY3VzdG9tIHJlbmRlcmluZ1xuICogQHVpbW9kZWwoJ3RvZG8tbGlzdCcpXG4gKiBjbGFzcyBUb2RvTGlzdCB7XG4gKiAgIEBhdHRyaWJ1dGUoKVxuICogICB0aXRsZTogc3RyaW5nO1xuICpcbiAqICAgQGF0dHJpYnV0ZSgpXG4gKiAgIEB1aWxpc3Rwcm9wKCdpdGVtcycsIHsgY2xhc3M6ICd0b2RvLWl0ZW1zLWNvbnRhaW5lcicgfSlcbiAqICAgaXRlbXM6IFRvZG9JdGVtW107XG4gKiB9XG4gKlxuICogQHVpbGlzdGl0ZW0oJ2xpJywgeyBjbGFzczogJ3RvZG8taXRlbScgfSlcbiAqIGNsYXNzIFRvZG9JdGVtIGV4dGVuZHMgTW9kZWwge1xuICogICBAYXR0cmlidXRlKClcbiAqICAgdGV4dDogc3RyaW5nO1xuICpcbiAqICAgQGF0dHJpYnV0ZSgpXG4gKiAgIGNvbXBsZXRlZDogYm9vbGVhbjtcbiAqIH1cbiAqXG4gKiBAbWVybWFpZFxuICogc2VxdWVuY2VEaWFncmFtXG4gKiAgIHBhcnRpY2lwYW50IE1vZGVsXG4gKiAgIHBhcnRpY2lwYW50IHVpbGlzdHByb3BcbiAqICAgcGFydGljaXBhbnQgUmVuZGVyaW5nRW5naW5lXG4gKiAgIHBhcnRpY2lwYW50IExpc3RDb250YWluZXJcbiAqICAgcGFydGljaXBhbnQgTGlzdEl0ZW1zXG4gKiAgIE1vZGVsLT4+dWlsaXN0cHJvcDogQXBwbHkgdG8gcHJvcGVydHlcbiAqICAgdWlsaXN0cHJvcC0+Pk1vZGVsOiBBZGQgbGlzdCBwcm9wIG1ldGFkYXRhXG4gKiAgIFJlbmRlcmluZ0VuZ2luZS0+Pk1vZGVsOiBHZXQgbGlzdCBwcm9wIG1ldGFkYXRhXG4gKiAgIE1vZGVsLT4+UmVuZGVyaW5nRW5naW5lOiBSZXR1cm4gcHJvcCBuYW1lIGFuZCBjb250YWluZXIgcHJvcHNcbiAqICAgUmVuZGVyaW5nRW5naW5lLT4+TGlzdENvbnRhaW5lcjogQ3JlYXRlIGNvbnRhaW5lciB3aXRoIHByb3BzXG4gKiAgIFJlbmRlcmluZ0VuZ2luZS0+Pkxpc3RJdGVtczogUmVuZGVyIGVhY2ggaXRlbSB1c2luZyBAdWlsaXN0aXRlbVxuICogICBMaXN0Q29udGFpbmVyLT4+UmVuZGVyaW5nRW5naW5lOiBSZXR1cm4gcmVuZGVyZWQgbGlzdFxuICovXG5leHBvcnQgZnVuY3Rpb24gdWlsaXN0cHJvcChcbiAgcHJvcE5hbWU6IHN0cmluZyB8IHVuZGVmaW5lZCA9IHVuZGVmaW5lZCxcbiAgcHJvcHM/OiBSZWNvcmQ8c3RyaW5nLCBhbnk+XG4pIHtcbiAgcmV0dXJuICh0YXJnZXQ6IGFueSwgcHJvcGVydHlLZXk6IHN0cmluZykgPT4ge1xuICAgIGNvbnN0IG1ldGFkYXRhOiBQYXJ0aWFsPFVJTGlzdFByb3BNZXRhZGF0YT4gPSB7XG4gICAgICBuYW1lOiBwcm9wTmFtZSB8fCBwcm9wZXJ0eUtleSxcbiAgICAgIHByb3BzOiBwcm9wcyB8fCB7fSxcbiAgICB9O1xuICAgIHByb3BNZXRhZGF0YShSZW5kZXJpbmdFbmdpbmUua2V5KFVJS2V5cy5VSUxJU1RQUk9QKSwgbWV0YWRhdGEpKFxuICAgICAgdGFyZ2V0LFxuICAgICAgcHJvcGVydHlLZXlcbiAgICApO1xuICB9O1xufVxuIiwiLyoqXG4gKiBAZGVzY3JpcHRpb24gVUkgZGVjb3JhdG9ycyBtb2R1bGUgZm9yIFR5cGVTY3JpcHQgYXBwbGljYXRpb25zXG4gKiBAc3VtbWFyeSBBIGNvbGxlY3Rpb24gb2YgZGVjb3JhdG9ycyBhbmQgdXRpbGl0aWVzIGZvciBidWlsZGluZyBVSSBjb21wb25lbnRzIGluIFR5cGVTY3JpcHQgYXBwbGljYXRpb25zLlxuICogVGhpcyBtb2R1bGUgZXhwb3J0cyBmdW5jdGlvbmFsaXR5IGZyb20gYm90aCB0aGUgbW9kZWwgYW5kIFVJIHN1Ym1vZHVsZXMsIHByb3ZpZGluZyBkZWNvcmF0b3JzIGZvclxuICogcmVuZGVyaW5nLCBjb21wb25lbnQgZGVmaW5pdGlvbiwgYW5kIFVJIHN0YXRlIG1hbmFnZW1lbnQuXG4gKiBAbW9kdWxlIHVpLWRlY29yYXRvcnNcbiAqL1xuXG5leHBvcnQgKiBmcm9tIFwiLi9tb2RlbFwiO1xuZXhwb3J0ICogZnJvbSBcIi4vdWlcIjtcblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gQ3VycmVudCBwYWNrYWdlIHZlcnNpb24gc3RyaW5nXG4gKiBAc3VtbWFyeSBTdG9yZXMgdGhlIGN1cnJlbnQgcGFja2FnZSB2ZXJzaW9uIGZvciByZWZlcmVuY2VcbiAqIEBjb25zdCBWRVJTSU9OXG4gKiBAbWVtYmVyT2YgbW9kdWxlOnVpLWRlY29yYXRvcnNcbiAqL1xuZXhwb3J0IGNvbnN0IFZFUlNJT04gPSBcIiMjVkVSU0lPTiMjXCI7XG4iXSwibmFtZXMiOlsiTW9kZWxLZXlzIiwiVmFsaWRhdGlvbktleXMiLCJFbWFpbFZhbGlkYXRvciIsIlVSTFZhbGlkYXRvciIsIkRhdGVWYWxpZGF0b3IiLCJQYXNzd29yZFZhbGlkYXRvciIsIlJlcXVpcmVkVmFsaWRhdG9yIiwiTWluVmFsaWRhdG9yIiwiTWF4VmFsaWRhdG9yIiwiU3RlcFZhbGlkYXRvciIsIk1pbkxlbmd0aFZhbGlkYXRvciIsIk1heExlbmd0aFZhbGlkYXRvciIsIlBhdHRlcm5WYWxpZGF0b3IiLCJFcXVhbHNWYWxpZGF0b3IiLCJEaWZmVmFsaWRhdG9yIiwiTGVzc1RoYW5WYWxpZGF0b3IiLCJMZXNzVGhhbk9yRXF1YWxWYWxpZGF0b3IiLCJHcmVhdGVyVGhhblZhbGlkYXRvciIsIkdyZWF0ZXJUaGFuT3JFcXVhbFZhbGlkYXRvciIsIkJhc2VFcnJvciIsImZvcm1hdERhdGUiLCJSZXNlcnZlZE1vZGVscyIsInBhcnNlRGF0ZSIsIkludGVybmFsRXJyb3IiLCJmaW5kTW9kZWxJZCIsIk1vZGVsIiwiUmVmbGVjdGlvbiIsIm1ldGFkYXRhIiwiYXBwbHkiLCJwcm9wTWV0YWRhdGEiLCJPcGVyYXRpb25LZXlzIl0sIm1hcHBpbmdzIjoiOzs7Ozs7SUFBQTs7Ozs7OztJQU9HO0lBMEJIOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztJQTRDRztBQUNVLFVBQUEsTUFBTSxHQUFHO0lBQ3BCLElBQUEsT0FBTyxFQUFFLENBQUEsRUFBR0EsNkJBQVMsQ0FBQyxPQUFPLENBQU0sSUFBQSxDQUFBO0lBQ25DLElBQUEsT0FBTyxFQUFFLFNBQVM7SUFDbEIsSUFBQSxXQUFXLEVBQUUsYUFBYTtJQUMxQixJQUFBLE9BQU8sRUFBRSxTQUFTO0lBQ2xCLElBQUEsSUFBSSxFQUFFLE1BQU07SUFDWixJQUFBLElBQUksRUFBRSxNQUFNO0lBQ1osSUFBQSxXQUFXLEVBQUUsUUFBUTtJQUNyQixJQUFBLFlBQVksRUFBRSx1QkFBdUI7SUFFckMsSUFBQSxVQUFVLEVBQUUsWUFBWTtJQUN4QixJQUFBLFVBQVUsRUFBRSxVQUFVO0lBRXRCLElBQUEsSUFBSSxFQUFFLE1BQU07SUFDWixJQUFBLFFBQVEsRUFBRSxTQUFTO0lBRW5CLElBQUEsTUFBTSxFQUFFLFFBQVE7SUFDaEIsSUFBQSxNQUFN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