@decaf-ts/for-angular 0.0.5 → 0.0.7

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 (24) hide show
  1. package/dist/lib/components/component-renderer/component-renderer.component.d.ts +16 -7
  2. package/dist/lib/components/crud-field/crud-field.component.d.ts +1 -3
  3. package/dist/lib/components/crud-form/crud-form.component.d.ts +1 -1
  4. package/dist/lib/components/model-renderer/model-renderer.component.d.ts +5 -6
  5. package/dist/lib/engine/NgxCrudFormField.d.ts +3 -7
  6. package/dist/lib/engine/NgxRenderingEngine.d.ts +2 -3
  7. package/dist/lib/engine/NgxRenderingEngine2.d.ts +5 -6
  8. package/dist/lib/engine/ValidatorFactory.d.ts +2 -2
  9. package/dist/lib/engine/types.d.ts +69 -25
  10. package/dist/lib/esm2022/components/component-renderer/component-renderer.component.mjs +14 -10
  11. package/dist/lib/esm2022/components/crud-field/crud-field.component.mjs +20 -11
  12. package/dist/lib/esm2022/components/crud-form/crud-form.component.mjs +3 -4
  13. package/dist/lib/esm2022/components/model-renderer/model-renderer.component.mjs +10 -9
  14. package/dist/lib/esm2022/engine/NgxCrudFormField.mjs +21 -15
  15. package/dist/lib/esm2022/engine/NgxFormService.mjs +1 -1
  16. package/dist/lib/esm2022/engine/NgxRenderingEngine.mjs +2 -4
  17. package/dist/lib/esm2022/engine/NgxRenderingEngine2.mjs +5 -6
  18. package/dist/lib/esm2022/engine/ValidatorFactory.mjs +4 -4
  19. package/dist/lib/esm2022/engine/types.mjs +1 -1
  20. package/dist/lib/esm2022/for-angular.module.mjs +1 -1
  21. package/dist/lib/fesm2022/decaf-ts-for-angular.mjs +71 -56
  22. package/dist/lib/fesm2022/decaf-ts-for-angular.mjs.map +1 -1
  23. package/dist/lib/for-angular.module.d.ts +2 -1
  24. package/package.json +4 -6
@@ -1,6 +1,7 @@
1
1
  import { ComponentRef, EnvironmentInjector, EventEmitter, OnDestroy, OnInit, TemplateRef, ViewContainerRef } from '@angular/core';
2
- import { ModelRenderCustomEvent } from '../../engine';
2
+ import { KeyValue, RendererCustomEvent } from '../../engine';
3
3
  import { Logger } from '@decaf-ts/logging';
4
+ import { Model } from '@decaf-ts/decorator-validation';
4
5
  import * as i0 from "@angular/core";
5
6
  /**
6
7
  * @description Dynamic component renderer for Decaf Angular applications.
@@ -25,7 +26,7 @@ import * as i0 from "@angular/core";
25
26
  * +Record~string, unknown~ globals
26
27
  * +EnvironmentInjector injector
27
28
  * +ComponentRef~unknown~ component
28
- * +EventEmitter~ModelRenderCustomEvent~ listenEvent
29
+ * +EventEmitter~RendererCustomEvent~ listenEvent
29
30
  * +ngOnInit()
30
31
  * +ngOnDestroy()
31
32
  * +ngOnChanges(changes)
@@ -104,10 +105,10 @@ export declare class ComponentRendererComponent implements OnInit, OnDestroy {
104
105
  * dynamic component, creating a communication channel between the parent and the dynamically
105
106
  * rendered child.
106
107
  *
107
- * @type {EventEmitter<ModelRenderCustomEvent>}
108
+ * @type {EventEmitter<RendererCustomEvent>}
108
109
  * @memberOf ComponentRendererComponent
109
110
  */
110
- listenEvent: EventEmitter<ModelRenderCustomEvent>;
111
+ listenEvent: EventEmitter<RendererCustomEvent>;
111
112
  /**
112
113
  * @description Logger instance for the component.
113
114
  * @summary This property holds a Logger instance specific to this component.
@@ -119,8 +120,16 @@ export declare class ComponentRendererComponent implements OnInit, OnDestroy {
119
120
  * @memberOf ComponentRendererComponent
120
121
  */
121
122
  logger: Logger;
122
- parent: any;
123
- inner?: TemplateRef<any>;
123
+ /**
124
+ * @description Repository model for data operations.
125
+ * @summary The data model repository that this component will use for CRUD operations.
126
+ * This provides a connection to the data layer for retrieving and manipulating data.
127
+ *
128
+ * @type {Model| undefined}
129
+ */
130
+ model: Model | undefined;
131
+ parent: undefined | KeyValue;
132
+ inner?: TemplateRef<unknown>;
124
133
  /**
125
134
  * @description Creates an instance of ComponentRendererComponent.
126
135
  * @summary Initializes a new ComponentRendererComponent. This component doesn't require
@@ -263,5 +272,5 @@ export declare class ComponentRendererComponent implements OnInit, OnDestroy {
263
272
  */
264
273
  private unsubscribeEvents;
265
274
  static ɵfac: i0.ɵɵFactoryDeclaration<ComponentRendererComponent, never>;
266
- static ɵcmp: i0.ɵɵComponentDeclaration<ComponentRendererComponent, "ngx-decaf-component-renderer", never, { "tag": { "alias": "tag"; "required": true; }; "globals": { "alias": "globals"; "required": false; }; "parent": { "alias": "parent"; "required": false; }; }, { "listenEvent": "listenEvent"; }, never, never, true, never>;
275
+ static ɵcmp: i0.ɵɵComponentDeclaration<ComponentRendererComponent, "ngx-decaf-component-renderer", never, { "tag": { "alias": "tag"; "required": true; }; "globals": { "alias": "globals"; "required": false; }; "model": { "alias": "model"; "required": false; }; "parent": { "alias": "parent"; "required": false; }; }, { "listenEvent": "listenEvent"; }, never, never, true, never>;
267
276
  }
@@ -49,8 +49,6 @@ import * as i0 from "@angular/core";
49
49
  * @memberOf module:for-angular
50
50
  */
51
51
  export declare class CrudFieldComponent extends NgxCrudFormField implements OnInit, OnDestroy, AfterViewInit {
52
- protected elementRef: ElementRef;
53
- constructor(elementRef: ElementRef);
54
52
  /**
55
53
  * @description The CRUD operation being performed.
56
54
  * @summary Specifies which CRUD operation (Create, Read, Update, Delete) the field is being used for.
@@ -324,7 +322,7 @@ export declare class CrudFieldComponent extends NgxCrudFormField implements OnIn
324
322
  * @type {SelectInterface}
325
323
  * @memberOf CrudFieldComponent
326
324
  */
327
- interface?: SelectInterface;
325
+ interface: SelectInterface;
328
326
  /**
329
327
  * @description Options for select or radio inputs.
330
328
  * @summary Provides the list of options for select or radio inputs. Each option can have a value and a label.
@@ -42,7 +42,7 @@ export declare class CrudFormComponent implements OnInit, FormElement, OnDestroy
42
42
  options: CrudFormOptions;
43
43
  action?: string;
44
44
  operation: CrudOperations;
45
- handlers: Record<string, (...args: any[]) => any | Promise<any>>;
45
+ handlers: Record<string, (...args: unknown[]) => unknown | Promise<unknown>>;
46
46
  formGroup: FormGroup | undefined;
47
47
  /**
48
48
  * @description Path to the parent FormGroup, if nested.
@@ -1,7 +1,7 @@
1
- import { EventEmitter, Injector, OnChanges, OnDestroy, SimpleChanges, TemplateRef, ViewContainerRef } from '@angular/core';
1
+ import { EventEmitter, OnChanges, OnDestroy, SimpleChanges, TemplateRef, ViewContainerRef } from '@angular/core';
2
2
  import { Model } from '@decaf-ts/decorator-validation';
3
3
  import { AngularDynamicOutput, RenderedModel } from '../../engine';
4
- import { ModelRenderCustomEvent } from 'src/lib/engine/types';
4
+ import { RendererCustomEvent } from 'src/lib/engine/types';
5
5
  import * as i0 from "@angular/core";
6
6
  /**
7
7
  * @description Component for rendering dynamic models
@@ -32,7 +32,6 @@ import * as i0 from "@angular/core";
32
32
  * ModelRenderer-->>App: Emit events
33
33
  */
34
34
  export declare class ModelRendererComponent<M extends Model> implements OnChanges, OnDestroy, RenderedModel {
35
- private injector;
36
35
  /**
37
36
  * @description Input model to be rendered
38
37
  * @summary Can be a Model instance or a JSON string representation of a model
@@ -45,7 +44,7 @@ export declare class ModelRendererComponent<M extends Model> implements OnChange
45
44
  /**
46
45
  * @description Template reference for inner content
47
46
  */
48
- inner?: TemplateRef<any>;
47
+ inner?: TemplateRef<unknown>;
49
48
  /**
50
49
  * @description Output of the rendered model
51
50
  */
@@ -61,7 +60,7 @@ export declare class ModelRendererComponent<M extends Model> implements OnChange
61
60
  /**
62
61
  * @description Event emitter for custom events from the rendered component
63
62
  */
64
- listenEvent: EventEmitter<ModelRenderCustomEvent>;
63
+ listenEvent: EventEmitter<RendererCustomEvent>;
65
64
  /**
66
65
  * @description Instance of the NgxRenderingEngine2
67
66
  */
@@ -70,7 +69,7 @@ export declare class ModelRendererComponent<M extends Model> implements OnChange
70
69
  * @description Instance of the rendered component
71
70
  */
72
71
  private instance;
73
- constructor(injector: Injector);
72
+ private injector;
74
73
  /**
75
74
  * @description Refreshes the rendered model
76
75
  * @param {string | M} model - The model to be rendered
@@ -12,7 +12,6 @@ import { ElementRef } from '@angular/core';
12
12
  * implementing both CrudFormField and ControlValueAccessor interfaces.
13
13
  */
14
14
  export declare abstract class NgxCrudFormField implements ControlValueAccessor, FieldProperties {
15
- protected elementRef: ElementRef;
16
15
  /**
17
16
  * @summary Reference to the component's element
18
17
  * @description ElementRef representing the component's native element
@@ -51,7 +50,7 @@ export declare abstract class NgxCrudFormField implements ControlValueAccessor,
51
50
  greaterThan?: string;
52
51
  greaterThanOrEqual?: string;
53
52
  value: string | number | Date;
54
- protected constructor(elementRef: ElementRef);
53
+ private translateService;
55
54
  /**
56
55
  * @summary Parent HTML element
57
56
  * @description Reference to the parent HTML element of the field
@@ -113,10 +112,7 @@ export declare abstract class NgxCrudFormField implements ControlValueAccessor,
113
112
  /**
114
113
  * @summary Get field errors
115
114
  * @description Retrieves all errors associated with the field
116
- * @returns {Array<{key: string, message: string}>} An array of error objects
115
+ * @returns {string|void} An array of error objects
117
116
  */
118
- getErrors(parent: HTMLElement): {
119
- key: string;
120
- message: string;
121
- }[];
117
+ getErrors(parent: HTMLElement): string | void;
122
118
  }
@@ -87,15 +87,14 @@ export declare class NgxRenderingEngine extends RenderingEngine<AngularFieldDefi
87
87
  * FromField-->>Render: AngularDynamicOutput
88
88
  * Render-->>Client: return AngularDynamicOutput
89
89
  */
90
- render<M extends Model>(model: M, globalProps: Record<string, unknown>, vcr: ViewContainerRef, injector: Injector, tpl: TemplateRef<any>): AngularDynamicOutput;
90
+ render<M extends Model>(model: M, globalProps: Record<string, unknown>, vcr: ViewContainerRef, injector: Injector, tpl: TemplateRef<unknown>): AngularDynamicOutput;
91
91
  /**
92
92
  * @description Initializes the rendering engine
93
93
  * @summary This method initializes the rendering engine. It checks if the engine is already initialized
94
94
  * and sets the initialized flag to true. This method is called before the engine is used.
95
- * @param {...any[]} args - Initialization arguments
96
95
  * @return {Promise<void>} A promise that resolves when initialization is complete
97
96
  */
98
- initialize(...args: any[]): Promise<void>;
97
+ initialize(): Promise<void>;
99
98
  /**
100
99
  * @description Registers a component with the rendering engine
101
100
  * @summary This static method registers a component constructor with the rendering engine
@@ -115,10 +115,10 @@ export declare class NgxRenderingEngine2 extends RenderingEngine<AngularFieldDef
115
115
  * @param {ComponentMirror<unknown>} metadata - The component metadata for input validation
116
116
  * @param {ViewContainerRef} vcr - The view container reference for component creation
117
117
  * @param {Injector} injector - The Angular injector for dependency injection
118
- * @param {any} [template=[]] - The template nodes to project into the component
118
+ * @param {Node[]} [template=[]] - The template nodes to project into the component
119
119
  * @return {ComponentRef<unknown>} The created component reference
120
120
  */
121
- static createComponent(component: Type<unknown>, inputs: KeyValue | undefined, metadata: ComponentMirror<unknown>, vcr: ViewContainerRef, injector: Injector, template?: any): ComponentRef<unknown>;
121
+ static createComponent(component: Type<unknown>, inputs: KeyValue | undefined, metadata: ComponentMirror<unknown>, vcr: ViewContainerRef, injector: Injector, template?: Node[]): ComponentRef<unknown>;
122
122
  /**
123
123
  * @description Extracts decorator metadata from a model
124
124
  * @summary This method provides access to the field definition generated from a model's
@@ -170,17 +170,16 @@ export declare class NgxRenderingEngine2 extends RenderingEngine<AngularFieldDef
170
170
  * FromField-->>Render: AngularDynamicOutput
171
171
  * Render-->>Client: return AngularDynamicOutput
172
172
  */
173
- render<M extends Model>(model: M, globalProps: Record<string, unknown>, vcr: ViewContainerRef, injector: Injector, tpl: TemplateRef<any>): AngularDynamicOutput;
173
+ render<M extends Model>(model: M, globalProps: Record<string, unknown>, vcr: ViewContainerRef, injector: Injector, tpl: TemplateRef<unknown>): AngularDynamicOutput;
174
174
  /**
175
175
  * @description Initializes the rendering engine
176
176
  * @summary This method initializes the rendering engine. It checks if the engine is already initialized
177
177
  * and sets the initialized flag to true. This method is called before the engine is used
178
178
  * to ensure it's properly set up for rendering operations.
179
179
  *
180
- * @param {...any[]} args - Initialization arguments
181
180
  * @return {Promise<void>} A promise that resolves when initialization is complete
182
181
  */
183
- initialize(...args: any[]): Promise<void>;
182
+ initialize(): Promise<void>;
184
183
  /**
185
184
  * @description Registers a component with the rendering engine
186
185
  * @summary This static method registers a component constructor with the rendering engine
@@ -203,7 +202,7 @@ export declare class NgxRenderingEngine2 extends RenderingEngine<AngularFieldDef
203
202
  * @param {string} [selector] - Optional selector to retrieve a specific component
204
203
  * @return {Object|Array} Either a specific component or an array of all components
205
204
  */
206
- static components(selector?: string): object | any[];
205
+ static components(selector?: string): object | string[];
207
206
  /**
208
207
  * @description Generates a key for reflection metadata
209
208
  * @summary This static method generates a key for reflection metadata by prefixing the input key
@@ -9,7 +9,7 @@ export declare class ValidatorFactory {
9
9
  * Enables Validators handling method to access parent and child properties using consistent dot-notation in Angular forms.
10
10
  *
11
11
  * @param {AbstractControl} control - The control to wrap in a proxy.
12
- * @returns {PathProxy<any>} A proxy object exposing form values and enabling recursive parent access.
12
+ * @returns {PathProxy<unknown>} A proxy object exposing form values and enabling recursive parent access.
13
13
  */
14
- static createProxy(control: AbstractControl): PathProxy<any>;
14
+ static createProxy(control: AbstractControl): PathProxy<unknown>;
15
15
  }
@@ -1,9 +1,25 @@
1
1
  import { IonCheckbox, IonInput, IonSelect, IonTextarea } from '@ionic/angular';
2
2
  import { TextFieldTypes } from '@ionic/core';
3
- import { Injector, Type } from '@angular/core';
3
+ import { EnvironmentInjector, Injector, Type } from '@angular/core';
4
4
  import { FormControl, FormGroup } from '@angular/forms';
5
5
  import { FieldProperties } from '@decaf-ts/ui-decorators';
6
+ /**
7
+ * @description Generic key-value pair type
8
+ * @summary Represents a generic object with string keys and any type of values.
9
+ * This is commonly used for dynamic data structures where the properties are not known at compile time.
10
+ * @typedef {Record<string, any>} KeyValue
11
+ * @memberOf module:engine
12
+ */
6
13
  export type KeyValue = Record<string, any>;
14
+ /**
15
+ * @description Generic function type
16
+ * @summary Represents a function that accepts any number of arguments of any type
17
+ * and returns any type. This is useful for defining function parameters or variables
18
+ * where the exact function signature is not known at compile time.
19
+ * @typedef FunctionLike
20
+ * @memberOf module:engine
21
+ */
22
+ export type FunctionLike = (...args: any[]) => any;
7
23
  /**
8
24
  * @description Element size options for UI components
9
25
  * @summary Defines the possible size values that can be applied to UI elements.
@@ -203,6 +219,15 @@ export type HTMLFormTarget = '_blank' | '_self' | '_parent' | '_top' | string;
203
219
  export interface IListComponentRefreshEvent {
204
220
  data: KeyValue[];
205
221
  }
222
+ /**
223
+ * @description Form service control structure
224
+ * @summary Defines the structure for a form control managed by the form service.
225
+ * Contains the FormGroup control and the associated field properties for rendering.
226
+ * @interface FormServiceControl
227
+ * @property {FormGroup} control - The Angular FormGroup for the control
228
+ * @property {AngularFieldDefinition} props - The field properties for rendering the control
229
+ * @memberOf module:engine
230
+ */
206
231
  export interface FormServiceControl {
207
232
  control: FormGroup;
208
233
  props: AngularFieldDefinition;
@@ -217,20 +242,14 @@ export interface FormServiceControl {
217
242
  */
218
243
  export type FormServiceControls = Record<string, Record<string, FormServiceControl>>;
219
244
  /**
220
- * @description Interface for model render custom events
221
- * @summary Defines the structure of custom events triggered during model rendering.
222
- * Contains the event detail, component name, and event name.
223
- * @interface ModelRenderCustomEvent
224
- * @property {BaseCustomEvent} detail - The detailed event information
225
- * @property {string} component - The component that triggered the event
226
- * @property {string} name - The name of the event
245
+ * @description Renderer custom event type
246
+ * @summary Combines BaseCustomEvent with KeyValue properties to create a flexible
247
+ * custom event type for renderer components. This allows events to carry both
248
+ * standard event properties and additional custom data.
249
+ * @typedef RendererCustomEvent
227
250
  * @memberOf module:engine
228
251
  */
229
- export interface ModelRenderCustomEvent {
230
- detail: BaseCustomEvent;
231
- component: string;
232
- name: string;
233
- }
252
+ export type RendererCustomEvent = BaseCustomEvent & KeyValue;
234
253
  /**
235
254
  * @description Interface for list item custom events
236
255
  * @summary Defines the structure of custom events triggered by list items.
@@ -260,34 +279,59 @@ export interface ListItemCustomEvent extends BaseCustomEvent {
260
279
  * @memberOf module:engine
261
280
  */
262
281
  export interface BaseCustomEvent {
263
- data: any;
264
- target?: HTMLElement;
265
- name?: string;
282
+ name: string;
266
283
  component: string;
284
+ data?: unknown;
285
+ target?: HTMLElement;
267
286
  }
268
287
  /**
269
- * @description Base interface for custom events
270
- * @summary Defines the base structure for custom events in the application.
271
- * Contains properties for the event data, target element, name, and component.
272
- * @interface BaseCustomEvent
273
- * @property {any} data - The data associated with the event
274
- * @property {HTMLElement} [target] - The target element that triggered the event
275
- * @property {string} [name] - The name of the event
276
- * @property {string} component - The component that triggered the event
288
+ * @description CRUD form event type
289
+ * @summary Extends BaseCustomEvent to include optional handlers for CRUD form operations.
290
+ * This event type is used for form-related actions like create, read, update, and delete operations.
291
+ * @typedef CrudFormEvent
292
+ * @property {Record<string, any>} [handlers] - Optional handlers for form operations
277
293
  * @memberOf module:engine
278
294
  */
279
295
  export type CrudFormEvent = BaseCustomEvent & {
280
296
  handlers?: Record<string, any>;
281
297
  };
298
+ /**
299
+ * @description Component input properties
300
+ * @summary Extends FieldProperties with additional properties specific to Angular components.
301
+ * Includes update mode for form controls and optional FormGroup and FormControl references.
302
+ * @interface ComponentInput
303
+ * @property {FieldUpdateMode} [updateMode] - When the field value should be updated
304
+ * @property {FormGroup} [formGroup] - Optional FormGroup reference
305
+ * @property {FormControl} [formControl] - Optional FormControl reference
306
+ * @memberOf module:engine
307
+ */
282
308
  export interface ComponentInput extends FieldProperties {
283
309
  updateMode?: FieldUpdateMode;
284
310
  formGroup?: FormGroup;
285
311
  formControl?: FormControl;
286
312
  }
313
+ /**
314
+ * @description Component configuration structure
315
+ * @summary Defines the configuration for dynamically creating Angular components.
316
+ * Contains the component name, input properties, injector, and optional child components.
317
+ * @interface ComponentConfig
318
+ * @property {string} component - The name of the component to render
319
+ * @property {ComponentInput} inputs - The input properties for the component
320
+ * @property {EnvironmentInjector | Injector} injector - The Angular injector for dependency injection
321
+ * @property {ComponentConfig[]} [children] - Optional child component configurations
322
+ * @memberOf module:engine
323
+ */
287
324
  export interface ComponentConfig {
288
325
  component: string;
289
326
  inputs: ComponentInput;
290
- injector: any;
327
+ injector: EnvironmentInjector | Injector;
291
328
  children?: ComponentConfig[];
292
329
  }
330
+ /**
331
+ * @description Form parent group tuple
332
+ * @summary Represents a tuple containing a FormGroup and its associated string identifier.
333
+ * This is used for managing hierarchical form structures and parent-child relationships.
334
+ * @typedef {[FormGroup, string]} FormParentGroup
335
+ * @memberOf module:engine
336
+ */
293
337
  export type FormParentGroup = [FormGroup, string];
@@ -26,7 +26,7 @@ import * as i1 from "@angular/common";
26
26
  * +Record~string, unknown~ globals
27
27
  * +EnvironmentInjector injector
28
28
  * +ComponentRef~unknown~ component
29
- * +EventEmitter~ModelRenderCustomEvent~ listenEvent
29
+ * +EventEmitter~RendererCustomEvent~ listenEvent
30
30
  * +ngOnInit()
31
31
  * +ngOnDestroy()
32
32
  * +ngOnChanges(changes)
@@ -82,7 +82,7 @@ export class ComponentRendererComponent {
82
82
  * dynamic component, creating a communication channel between the parent and the dynamically
83
83
  * rendered child.
84
84
  *
85
- * @type {EventEmitter<ModelRenderCustomEvent>}
85
+ * @type {EventEmitter<RendererCustomEvent>}
86
86
  * @memberOf ComponentRendererComponent
87
87
  */
88
88
  this.listenEvent = new EventEmitter();
@@ -113,9 +113,12 @@ export class ComponentRendererComponent {
113
113
  * @memberOf ComponentRendererComponent
114
114
  */
115
115
  ngOnInit() {
116
- if (!this.parent)
116
+ if (!this.parent) {
117
117
  this.createComponent(this.tag, this.globals);
118
- this.createParentComponent();
118
+ }
119
+ else {
120
+ this.createParentComponent();
121
+ }
119
122
  }
120
123
  /**
121
124
  * @description Cleans up resources when the component is destroyed.
@@ -178,8 +181,9 @@ export class ComponentRendererComponent {
178
181
  ?.constructor;
179
182
  const metadata = reflectComponentType(component);
180
183
  const componentInputs = metadata.inputs;
181
- const props = globals?.['item'];
182
- delete props['tag'];
184
+ const props = globals?.['item'] || globals?.['props'] || {};
185
+ if (props?.['tag'])
186
+ delete props['tag'];
183
187
  const inputKeys = Object.keys(props);
184
188
  const unmappedKeys = [];
185
189
  for (const input of inputKeys) {
@@ -191,8 +195,6 @@ export class ComponentRendererComponent {
191
195
  unmappedKeys.push(input);
192
196
  }
193
197
  }
194
- if (unmappedKeys.length)
195
- this.logger.info(`Unmapped input properties for component ${tag}: ${unmappedKeys.join(', ')}`);
196
198
  this.vcr.clear();
197
199
  this.component = NgxRenderingEngine2.createComponent(component, props, metadata, this.vcr, this.injector, []);
198
200
  this.subscribeEvents();
@@ -285,7 +287,7 @@ export class ComponentRendererComponent {
285
287
  }
286
288
  }
287
289
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ComponentRendererComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
288
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: ComponentRendererComponent, isStandalone: true, selector: "ngx-decaf-component-renderer", inputs: { tag: "tag", globals: "globals", parent: "parent" }, outputs: { listenEvent: "listenEvent" }, viewQueries: [{ propertyName: "vcr", first: true, predicate: ["componentViewContainer"], descendants: true, read: ViewContainerRef, static: true }, { propertyName: "inner", first: true, predicate: ["inner"], descendants: true, read: TemplateRef, static: true }], ngImport: i0, template: "<ng-template #componentViewContainer></ng-template>\n\n<ng-template #inner>\n @if(parent?.children?.length) {\n @for(child of parent.children; track child) {\n @if(!child.children?.length) {\n <ng-container\n *ngComponentOutlet=\"\n child.component;\n injector: child.injector;\n inputs: child.inputs;\n content:child.content;\n \"\n />\n } @else {\n <ngx-decaf-component-renderer [parent]=\"child\"> </ngx-decaf-component-renderer>\n }\n }\n }\n</ng-template>\n\n\n", styles: [""], dependencies: [{ kind: "component", type: ComponentRendererComponent, selector: "ngx-decaf-component-renderer", inputs: ["tag", "globals", "parent"], outputs: ["listenEvent"] }, { kind: "ngmodule", type: ForAngularModule }, { kind: "directive", type: i1.NgComponentOutlet, selector: "[ngComponentOutlet]", inputs: ["ngComponentOutlet", "ngComponentOutletInputs", "ngComponentOutletInjector", "ngComponentOutletContent", "ngComponentOutletNgModule", "ngComponentOutletNgModuleFactory"] }] }); }
290
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: ComponentRendererComponent, isStandalone: true, selector: "ngx-decaf-component-renderer", inputs: { tag: "tag", globals: "globals", model: "model", parent: "parent" }, outputs: { listenEvent: "listenEvent" }, viewQueries: [{ propertyName: "vcr", first: true, predicate: ["componentViewContainer"], descendants: true, read: ViewContainerRef, static: true }, { propertyName: "inner", first: true, predicate: ["inner"], descendants: true, read: TemplateRef, static: true }], ngImport: i0, template: "<ng-template #componentViewContainer></ng-template>\n\n<ng-template #inner>\n @if(parent?.children?.length) {\n @for(child of parent.children; track child) {\n @if(!child.children?.length) {\n <ng-container\n *ngComponentOutlet=\"\n child.component;\n injector: child.injector;\n inputs: child.inputs;\n content:child.content;\n \"\n />\n } @else {\n <ngx-decaf-component-renderer [parent]=\"child\"> </ngx-decaf-component-renderer>\n }\n }\n }\n</ng-template>\n\n\n", styles: [""], dependencies: [{ kind: "component", type: ComponentRendererComponent, selector: "ngx-decaf-component-renderer", inputs: ["tag", "globals", "model", "parent"], outputs: ["listenEvent"] }, { kind: "ngmodule", type: ForAngularModule }, { kind: "directive", type: i1.NgComponentOutlet, selector: "[ngComponentOutlet]", inputs: ["ngComponentOutlet", "ngComponentOutletInputs", "ngComponentOutletInjector", "ngComponentOutletContent", "ngComponentOutletNgModule", "ngComponentOutletNgModuleFactory"] }] }); }
289
291
  }
290
292
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ComponentRendererComponent, decorators: [{
291
293
  type: Component,
@@ -300,10 +302,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImpo
300
302
  type: Input
301
303
  }], listenEvent: [{
302
304
  type: Output
305
+ }], model: [{
306
+ type: Input
303
307
  }], parent: [{
304
308
  type: Input
305
309
  }], inner: [{
306
310
  type: ViewChild,
307
311
  args: ['inner', { read: TemplateRef, static: true }]
308
312
  }] } });
309
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29tcG9uZW50LXJlbmRlcmVyLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3NyYy9saWIvY29tcG9uZW50cy9jb21wb25lbnQtcmVuZGVyZXIvY29tcG9uZW50LXJlbmRlcmVyLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uL3NyYy9saWIvY29tcG9uZW50cy9jb21wb25lbnQtcmVuZGVyZXIvY29tcG9uZW50LXJlbmRlcmVyLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFDTCxTQUFTLEVBR1QsbUJBQW1CLEVBQ25CLFlBQVksRUFDWixNQUFNLEVBRU4sS0FBSyxFQUdMLE1BQU0sRUFDTixvQkFBb0IsRUFDcEIsV0FBVyxFQUVYLFNBQVMsRUFDVCxnQkFBZ0IsR0FDakIsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0sb0NBQW9DLENBQUM7QUFFekUsT0FBTyxFQUFFLGdCQUFnQixFQUFFLFNBQVMsRUFBRSxNQUFNLDRCQUE0QixDQUFDOzs7QUFHekU7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBc0NHO0FBUUgsTUFBTSxPQUFPLDBCQUEwQjtJQWtHckM7Ozs7Ozs7T0FPRztJQUNIO1FBOUVBOzs7Ozs7Ozs7O1dBVUc7UUFFSCxZQUFPLEdBQTRCLEVBQUUsQ0FBQztRQUV0Qzs7Ozs7Ozs7O1dBU0c7UUFDSCxhQUFRLEdBQXdCLE1BQU0sQ0FBQyxtQkFBbUIsQ0FBQyxDQUFDO1FBYTVEOzs7Ozs7Ozs7V0FTRztRQUVILGdCQUFXLEdBQ1QsSUFBSSxZQUFZLEVBQTBCLENBQUM7UUFlN0MsV0FBTSxHQUFRLFNBQVMsQ0FBQztRQWV0QixJQUFJLENBQUMsTUFBTSxHQUFHLFNBQVMsQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUNoQyxDQUFDO0lBRUQ7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7T0FzQkc7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R0F2VVUsMEJBQTBCO21HQUExQiwwQkFBMEIseVJBV3NCLGdCQUFnQix1R0FvRi9DLFdBQVcsMkNDcEt6QywrbUJBc0JBLDBERCtDYSwwQkFBMEIsd0lBSDNCLGdCQUFnQjs7NEZBR2YsMEJBQTBCO2tCQVB0QyxTQUFTOytCQUNFLDhCQUE4QixXQUcvQixDQUFDLGdCQUFnQixDQUFDLGNBQ2YsSUFBSTt3REFjaEIsR0FBRztzQkFERixTQUFTO3VCQUFDLHdCQUF3QixFQUFFLEVBQUUsTUFBTSxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsZ0JBQWdCLEVBQUU7Z0JBZTdFLEdBQUc7c0JBREYsS0FBSzt1QkFBQyxFQUFFLFFBQVEsRUFBRSxJQUFJLEVBQUU7Z0JBZXpCLE9BQU87c0JBRE4sS0FBSztnQkFxQ04sV0FBVztzQkFEVixNQUFNO2dCQWlCUCxNQUFNO3NCQURMLEtBQUs7Z0JBS04sS0FBSztzQkFESixTQUFTO3VCQUFDLE9BQU8sRUFBRSxFQUFFLElBQUksRUFBRSxXQUFXLEVBQUUsTUFBTSxFQUFFLElBQUksRUFBRSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gIENvbXBvbmVudCxcbiAgQ29tcG9uZW50TWlycm9yLFxuICBDb21wb25lbnRSZWYsXG4gIEVudmlyb25tZW50SW5qZWN0b3IsXG4gIEV2ZW50RW1pdHRlcixcbiAgaW5qZWN0LFxuICBJbmplY3RvcixcbiAgSW5wdXQsXG4gIE9uRGVzdHJveSxcbiAgT25Jbml0LFxuICBPdXRwdXQsXG4gIHJlZmxlY3RDb21wb25lbnRUeXBlLFxuICBUZW1wbGF0ZVJlZixcbiAgVHlwZSxcbiAgVmlld0NoaWxkLFxuICBWaWV3Q29udGFpbmVyUmVmLFxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IE5neFJlbmRlcmluZ0VuZ2luZTIgfSBmcm9tICdzcmMvbGliL2VuZ2luZS9OZ3hSZW5kZXJpbmdFbmdpbmUyJztcbmltcG9ydCB7IEJhc2VDdXN0b21FdmVudCwgS2V5VmFsdWUsIE1vZGVsUmVuZGVyQ3VzdG9tRXZlbnQgfSBmcm9tICcuLi8uLi9lbmdpbmUnO1xuaW1wb3J0IHsgRm9yQW5ndWxhck1vZHVsZSwgZ2V0TG9nZ2VyIH0gZnJvbSAnc3JjL2xpYi9mb3ItYW5ndWxhci5tb2R1bGUnO1xuaW1wb3J0IHsgTG9nZ2VyIH0gZnJvbSAnQGRlY2FmLXRzL2xvZ2dpbmcnO1xuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBEeW5hbWljIGNvbXBvbmVudCByZW5kZXJlciBmb3IgRGVjYWYgQW5ndWxhciBhcHBsaWNhdGlvbnMuXG4gKiBAc3VtbWFyeSBUaGlzIGNvbXBvbmVudCBwcm92aWRlcyBhIGZsZXhpYmxlIHdheSB0byBkeW5hbWljYWxseSByZW5kZXIgQW5ndWxhciBjb21wb25lbnRzXG4gKiBhdCBydW50aW1lIGJhc2VkIG9uIGEgdGFnIG5hbWUuIEl0IGhhbmRsZXMgdGhlIGNyZWF0aW9uLCBwcm9wZXJ0eSBiaW5kaW5nLCBhbmQgZXZlbnRcbiAqIHN1YnNjcmlwdGlvbiBmb3IgZHluYW1pY2FsbHkgbG9hZGVkIGNvbXBvbmVudHMuIFRoaXMgaXMgcGFydGljdWxhcmx5IHVzZWZ1bCBmb3JcbiAqIGJ1aWxkaW5nIGNvbmZpZ3VyYWJsZSBVSXMgd2hlcmUgY29tcG9uZW50cyBuZWVkIHRvIGJlIGRldGVybWluZWQgYXQgcnVudGltZS5cbiAqXG4gKiBAY29tcG9uZW50IHtDb21wb25lbnRSZW5kZXJlckNvbXBvbmVudH1cbiAqIEBleGFtcGxlXG4gKiA8bmd4LWRlY2FmLWNvbXBvbmVudC1yZW5kZXJlclxuICogICBbdGFnXT1cInRhZ1wiXG4gKiAgIFtnbG9iYWxzXT1cImdsb2JhbHNcIlxuICogICAobGlzdGVuRXZlbnQpPVwibGlzdGVuRXZlbnQoJGV2ZW50KVwiPlxuICogPC9uZ3gtZGVjYWYtY29tcG9uZW50LXJlbmRlcmVyPlxuICpcbiAqIEBtZXJtYWlkXG4gKiBjbGFzc0RpYWdyYW1cbiAqICAgY2xhc3MgQ29tcG9uZW50UmVuZGVyZXJDb21wb25lbnQge1xuICogICAgICtWaWV3Q29udGFpbmVyUmVmIHZjclxuICogICAgICtzdHJpbmcgdGFnXG4gKiAgICAgK1JlY29yZH5zdHJpbmcsIHVua25vd25+IGdsb2JhbHNcbiAqICAgICArRW52aXJvbm1lbnRJbmplY3RvciBpbmplY3RvclxuICogICAgICtDb21wb25lbnRSZWZ+dW5rbm93bn4gY29tcG9uZW50XG4gKiAgICAgK0V2ZW50RW1pdHRlcn5Nb2RlbFJlbmRlckN1c3RvbUV2ZW50fiBsaXN0ZW5FdmVudFxuICogICAgICtuZ09uSW5pdCgpXG4gKiAgICAgK25nT25EZXN0cm95KClcbiAqICAgICArbmdPbkNoYW5nZXMoY2hhbmdlcylcbiAqICAgICAtY3JlYXRlQ29tcG9uZW50KHRhZywgZ2xvYmFscylcbiAqICAgICAtc3Vic2NyaWJlRXZlbnRzKClcbiAqICAgICAtdW5zdWJzY3JpYmVFdmVudHMoKVxuICogICB9XG4gKiAgIENvbXBvbmVudFJlbmRlcmVyQ29tcG9uZW50IC0tfD4gT25Jbml0XG4gKiAgIENvbXBvbmVudFJlbmRlcmVyQ29tcG9uZW50IC0tfD4gT25DaGFuZ2VzXG4gKiAgIENvbXBvbmVudFJlbmRlcmVyQ29tcG9uZW50IC0tfD4gT25EZXN0cm95XG4gKlxuICogQGltcGxlbWVudHMge09uSW5pdH1cbiAqIEBpbXBsZW1lbnRzIHtPbkNoYW5nZXN9XG4gKiBAaW1wbGVtZW50cyB7T25EZXN0cm95fVxuICovXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICduZ3gtZGVjYWYtY29tcG9uZW50LXJlbmRlcmVyJyxcbiAgdGVtcGxhdGVVcmw6ICcuL2NvbXBvbmVudC1yZW5kZXJlci5jb21wb25lbnQuaHRtbCcsXG4gIHN0eWxlVXJsczogWycuL2NvbXBvbmVudC1yZW5kZXJlci5jb21wb25lbnQuc2NzcyddLFxuICBpbXBvcnRzOiBbRm9yQW5ndWxhck1vZHVsZV0sXG4gIHN0YW5kYWxvbmU6IHRydWUsXG59KVxuZXhwb3J0IGNsYXNzIENvbXBvbmVudFJlbmRlcmVyQ29tcG9uZW50XG4gIGltcGxlbWVudHMgT25Jbml0LCBPbkRlc3Ryb3kge1xuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFJlZmVyZW5jZSB0byB0aGUgY29udGFpbmVyIHdoZXJlIHRoZSBkeW5hbWljIGNvbXBvbmVudCB3aWxsIGJlIHJlbmRlcmVkLlxuICAgKiBAc3VtbWFyeSBUaGlzIFZpZXdDb250YWluZXJSZWYgcHJvdmlkZXMgdGhlIGNvbnRhaW5lciB3aGVyZSB0aGUgZHluYW1pY2FsbHkgY3JlYXRlZFxuICAgKiBjb21wb25lbnQgd2lsbCBiZSBpbnNlcnRlZCBpbnRvIHRoZSBET00uIEl0J3MgbWFya2VkIGFzIHN0YXRpYyB0byBlbnN1cmUgaXQncyBhdmFpbGFibGVcbiAgICogZHVyaW5nIHRoZSBuZ09uSW5pdCBsaWZlY3ljbGUgaG9vayB3aGVuIHRoZSBjb21wb25lbnQgaXMgY3JlYXRlZC5cbiAgICpcbiAgICogQHR5cGUge1ZpZXdDb250YWluZXJSZWZ9XG4gICAqIEBtZW1iZXJPZiBDb21wb25lbnRSZW5kZXJlckNvbXBvbmVudFxuICAgKi9cbiAgQFZpZXdDaGlsZCgnY29tcG9uZW50Vmlld0NvbnRhaW5lcicsIHsgc3RhdGljOiB0cnVlLCByZWFkOiBWaWV3Q29udGFpbmVyUmVmIH0pXG4gIHZjciE6IFZpZXdDb250YWluZXJSZWY7XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBUaGUgdGFnIG5hbWUgb2YgdGhlIGNvbXBvbmVudCB0byBiZSBkeW5hbWljYWxseSByZW5kZXJlZC5cbiAgICogQHN1bW1hcnkgVGhpcyBpbnB1dCBwcm9wZXJ0eSBzcGVjaWZpZXMgd2hpY2ggY29tcG9uZW50IHNob3VsZCBiZSByZW5kZXJlZCBieSBwcm92aWRpbmdcbiAgICogaXRzIHJlZ2lzdGVyZWQgdGFnIG5hbWUuIFRoZSB0YWcgbXVzdCBjb3JyZXNwb25kIHRvIGEgY29tcG9uZW50IHRoYXQgaGFzIGJlZW4gcmVnaXN0ZXJlZFxuICAgKiB3aXRoIHRoZSBOZ3hSZW5kZXJpbmdFbmdpbmUyLiBUaGlzIGlzIGEgcmVxdWlyZWQgaW5wdXQgYXMgaXQgZGV0ZXJtaW5lcyB3aGljaCBjb21wb25lbnRcbiAgICogdG8gY3JlYXRlLlxuICAgKlxuICAgKiBAdHlwZSB7c3RyaW5nfVxuICAgKiBAcmVxdWlyZWRcbiAgICogQG1lbWJlck9mIENvbXBvbmVudFJlbmRlcmVyQ29tcG9uZW50XG4gICAqL1xuICBASW5wdXQoeyByZXF1aXJlZDogdHJ1ZSB9KVxuICB0YWchOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBHbG9iYWwgcHJvcGVydGllcyB0byBwYXNzIHRvIHRoZSByZW5kZXJlZCBjb21wb25lbnQuXG4gICAqIEBzdW1tYXJ5IFRoaXMgaW5wdXQgcHJvcGVydHkgYWxsb3dzIHBhc3NpbmcgYSBzZXQgb2YgcHJvcGVydGllcyB0byB0aGUgZHluYW1pY2FsbHlcbiAgICogcmVuZGVyZWQgY29tcG9uZW50LiBUaGVzZSBwcm9wZXJ0aWVzIHdpbGwgYmUgbWFwcGVkIHRvIHRoZSBjb21wb25lbnQncyBpbnB1dHMgaWYgdGhleVxuICAgKiBtYXRjaC4gUHJvcGVydGllcyB0aGF0IGRvbid0IG1hdGNoIGFueSBpbnB1dCBvbiB0aGUgdGFyZ2V0IGNvbXBvbmVudCB3aWxsIGJlIGZpbHRlcmVkIG91dFxuICAgKiB3aXRoIGEgd2FybmluZy5cbiAgICpcbiAgICogQHR5cGUge1JlY29yZDxzdHJpbmcsIHVua25vd24+fVxuICAgKiBAZGVmYXVsdCB7fVxuICAgKiBAbWVtYmVyT2YgQ29tcG9uZW50UmVuZGVyZXJDb21wb25lbnRcbiAgICovXG4gIEBJbnB1dCgpXG4gIGdsb2JhbHM6IFJlY29yZDxzdHJpbmcsIHVua25vd24+ID0ge307XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBJbmplY3RvciB1c2VkIGZvciBkZXBlbmRlbmN5IGluamVjdGlvbiBpbiB0aGUgZHluYW1pYyBjb21wb25lbnQuXG4gICAqIEBzdW1tYXJ5IFRoaXMgaW5qZWN0b3IgaXMgdXNlZCB3aGVuIGNyZWF0aW5nIHRoZSBkeW5hbWljIGNvbXBvbmVudCB0byBwcm92aWRlIGl0IHdpdGhcbiAgICogYWNjZXNzIHRvIHRoZSBhcHBsaWNhdGlvbidzIGRlcGVuZGVuY3kgaW5qZWN0aW9uIHN5c3RlbS4gSXQgZW5zdXJlcyB0aGF0IHRoZSBkeW5hbWljYWxseVxuICAgKiBjcmVhdGVkIGNvbXBvbmVudCBjYW4gYWNjZXNzIHRoZSBzYW1lIHNlcnZpY2VzIGFuZCBkZXBlbmRlbmNpZXMgYXMgc3RhdGljYWxseSBjcmVhdGVkXG4gICAqIGNvbXBvbmVudHMuXG4gICAqXG4gICAqIEB0eXBlIHtFbnZpcm9ubWVudEluamVjdG9yfVxuICAgKiBAbWVtYmVyT2YgQ29tcG9uZW50UmVuZGVyZXJDb21wb25lbnRcbiAgICovXG4gIGluamVjdG9yOiBFbnZpcm9ubWVudEluamVjdG9yID0gaW5qZWN0KEVudmlyb25tZW50SW5qZWN0b3IpO1xuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gUmVmZXJlbmNlIHRvIHRoZSBkeW5hbWljYWxseSBjcmVhdGVkIGNvbXBvbmVudC5cbiAgICogQHN1bW1hcnkgVGhpcyBwcm9wZXJ0eSBob2xkcyBhIHJlZmVyZW5jZSB0byB0aGUgQ29tcG9uZW50UmVmIG9mIHRoZSBkeW5hbWljYWxseSBjcmVhdGVkXG4gICAqIGNvbXBvbmVudC4gSXQncyB1c2VkIHRvIGludGVyYWN0IHdpdGggdGhlIGNvbXBvbmVudCBpbnN0YW5jZSwgc3Vic2NyaWJlIHRvIGl0cyBldmVudHMsXG4gICAqIGFuZCBwcm9wZXJseSBkZXN0cm95IGl0IHdoZW4gdGhlIHJlbmRlcmVyIGlzIGRlc3Ryb3llZC5cbiAgICpcbiAgICogQHR5cGUge0NvbXBvbmVudFJlZjx1bmtub3duPn1cbiAgICogQG1lbWJlck9mIENvbXBvbmVudFJlbmRlcmVyQ29tcG9uZW50XG4gICAqL1xuICBjb21wb25lbnQhOiBDb21wb25lbnRSZWY8dW5rbm93bj47XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBFdmVudCBlbWl0dGVyIGZvciBldmVudHMgZnJvbSB0aGUgcmVuZGVyZWQgY29tcG9uZW50LlxuICAgKiBAc3VtbWFyeSBUaGlzIG91dHB1dCBwcm9wZXJ0eSBlbWl0cyBldmVudHMgdGhhdCBvcmlnaW5hdGUgZnJvbSB0aGUgZHluYW1pY2FsbHkgcmVuZGVyZWRcbiAgICogY29tcG9uZW50LiBJdCBhbGxvd3MgdGhlIHBhcmVudCBjb21wb25lbnQgdG8gbGlzdGVuIGZvciBhbmQgcmVzcG9uZCB0byBldmVudHMgZnJvbSB0aGVcbiAgICogZHluYW1pYyBjb21wb25lbnQsIGNyZWF0aW5nIGEgY29tbXVuaWNhdGlvbiBjaGFubmVsIGJldHdlZW4gdGhlIHBhcmVudCBhbmQgdGhlIGR5bmFtaWNhbGx5XG4gICAqIHJlbmRlcmVkIGNoaWxkLlxuICAgKlxuICAgKiBAdHlwZSB7RXZlbnRFbWl0dGVyPE1vZGVsUmVuZGVyQ3VzdG9tRXZlbnQ+fVxuICAgKiBAbWVtYmVyT2YgQ29tcG9uZW50UmVuZGVyZXJDb21wb25lbnRcbiAgICovXG4gIEBPdXRwdXQoKVxuICBsaXN0ZW5FdmVudDogRXZlbnRFbWl0dGVyPE1vZGVsUmVuZGVyQ3VzdG9tRXZlbnQ+ID1cbiAgICBuZXcgRXZlbnRFbWl0dGVyPE1vZGVsUmVuZGVyQ3VzdG9tRXZlbnQ+KCk7XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBMb2dnZXIgaW5zdGFuY2UgZm9yIHRoZSBjb21wb25lbnQuXG4gICAqIEBzdW1tYXJ5IFRoaXMgcHJvcGVydHkgaG9sZHMgYSBMb2dnZXIgaW5zdGFuY2Ugc3BlY2lmaWMgdG8gdGhpcyBjb21wb25lbnQuXG4gICAqIEl0J3MgdXNlZCB0byBsb2cgaW5mb3JtYXRpb24sIHdhcm5pbmdzLCBhbmQgZXJyb3JzIHJlbGF0ZWQgdG8gdGhlIGNvbXBvbmVudCdzXG4gICAqIG9wZXJhdGlvbnMsIHBhcnRpY3VsYXJseSB1c2VmdWwgZm9yIGRlYnVnZ2luZyBhbmQgbW9uaXRvcmluZyB0aGUgZHluYW1pY1xuICAgKiBjb21wb25lbnQgcmVuZGVyaW5nIHByb2Nlc3MuXG4gICAqXG4gICAqIEB0eXBlIHtMb2dnZXJ9XG4gICAqIEBtZW1iZXJPZiBDb21wb25lbnRSZW5kZXJlckNvbXBvbmVudFxuICAgKi9cbiAgbG9nZ2VyITogTG9nZ2VyO1xuXG4gIEBJbnB1dCgpXG4gIHBhcmVudDogYW55ID0gdW5kZWZpbmVkO1xuXG5cbiAgQFZpZXdDaGlsZCgnaW5uZXInLCB7IHJlYWQ6IFRlbXBsYXRlUmVmLCBzdGF0aWM6IHRydWUgfSlcbiAgaW5uZXI/OiBUZW1wbGF0ZVJlZjxhbnk+O1xuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gQ3JlYXRlcyBhbiBpbnN0YW5jZSBvZiBDb21wb25lbnRSZW5kZXJlckNvbXBvbmVudC5cbiAgICogQHN1bW1hcnkgSW5pdGlhbGl6ZXMgYSBuZXcgQ29tcG9uZW50UmVuZGVyZXJDb21wb25lbnQuIFRoaXMgY29tcG9uZW50IGRvZXNuJ3QgcmVxdWlyZVxuICAgKiBhbnkgZGVwZW5kZW5jaWVzIHRvIGJlIGluamVjdGVkIGluIGl0cyBjb25zdHJ1Y3RvciBhcyBpdCB1c2VzIHRoZSBpbmplY3QgZnVuY3Rpb24gdG9cbiAgICogb2J0YWluIHRoZSBFbnZpcm9ubWVudEluamVjdG9yLlxuICAgKlxuICAgKiBAbWVtYmVyT2YgQ29tcG9uZW50UmVuZGVyZXJDb21wb25lbnRcbiAgICovXG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIHRoaXMubG9nZ2VyID0gZ2V0TG9nZ2VyKHRoaXMpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBJbml0aWFsaXplcyB0aGUgY29tcG9uZW50IGFmdGVyIEFuZ3VsYXIgZmlyc3QgZGlzcGxheXMgdGhlIGRhdGEtYm91bmQgcHJvcGVydGllcy5cbiAgICogQHN1bW1hcnkgU2V0cyB1cCB0aGUgY29tcG9uZW50IGJ5IGNyZWF0aW5nIHRoZSBkeW5hbWljIGNvbXBvbmVudCBzcGVjaWZpZWQgYnkgdGhlIHRhZyBpbnB1dC5cbiAgICogVGhpcyBtZXRob2QgaXMgY2FsbGVkIG9uY2Ugd2hlbiB0aGUgY29tcG9uZW50IGlzIGluaXRpYWxpemVkIGFuZCB0cmlnZ2VycyB0aGUgZHluYW1pY1xuICAgKiBjb21wb25lbnQgY3JlYXRpb24gcHJvY2VzcyB3aXRoIHRoZSBwcm92aWRlZCB0YWcgbmFtZSBhbmQgZ2xvYmFsIHByb3BlcnRpZXMuXG4gICAqXG4gICAqIEBtZXJtYWlkXG4gICAqIHNlcXVlbmNlRGlhZ3JhbVxuICAgKiAgIHBhcnRpY2lwYW50IEEgYXMgQW5ndWxhciBMaWZlY3ljbGVcbiAgICogICBwYXJ0aWNpcGFudCBDIGFzIENvbXBvbmVudFJlbmRlcmVyQ29tcG9uZW50XG4gICAqICAgcGFydGljaXBhbnQgUiBhcyBOZ3hSZW5kZXJpbmdFbmdpbmUyXG4gICAqXG4gICAqICAgQS0+PkM6IG5nT25Jbml0KClcbiAgICogICBDLT4+QzogY3JlYXRlQ29tcG9uZW50KHRhZywgZ2xvYmFscylcbiAgICogICBDLT4+UjogY29tcG9uZW50cyh0YWcpXG4gICAqICAgUi0tPj5DOiBSZXR1cm4gY29tcG9uZW50IGNvbnN0cnVjdG9yXG4gICAqICAgQy0+PkM6IFByb2Nlc3MgY29tcG9uZW50IGlucHV0c1xuICAgKiAgIEMtPj5DOiBDcmVhdGUgY29tcG9uZW50IGluc3RhbmNlXG4gICAqICAgQy0+PkM6IHN1YnNjcmliZUV2ZW50cygpXG4gICAqXG4gICAqIEByZXR1cm4ge3ZvaWR9XG4gICAqIEBtZW1iZXJPZiBDb21wb25lbnRSZW5kZXJlckNvbXBvbmVudFxuICAgKi9cbiAgbmdPbkluaXQoKTogdm9pZCB7XG4gICAgaWYgKCF0aGlzLnBhcmVudClcbiAgICAgIHRoaXMuY3JlYXRlQ29tcG9uZW50KHRoaXMudGFnLCB0aGlzLmdsb2JhbHMpO1xuICAgIHRoaXMuY3JlYXRlUGFyZW50Q29tcG9uZW50KCk7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIENsZWFucyB1cCByZXNvdXJjZXMgd2hlbiB0aGUgY29tcG9uZW50IGlzIGRlc3Ryb3llZC5cbiAgICogQHN1bW1hcnkgUGVyZm9ybXMgY2xlYW51cCBvcGVyYXRpb25zIHdoZW4gdGhlIGNvbXBvbmVudCBpcyBiZWluZyBkZXN0cm95ZWQgYnkgQW5ndWxhci5cbiAgICogVGhpcyBpbmNsdWRlcyB1bnN1YnNjcmliaW5nIGZyb20gYWxsIGV2ZW50IGVtaXR0ZXJzIG9mIHRoZSBkeW5hbWljIGNvbXBvbmVudCBhbmRcbiAgICogZGVzdHJveWluZyB0aGUgcmVuZGVyaW5nIGVuZ2luZSBpbnN0YW5jZSB0byBwcmV2ZW50IG1lbW9yeSBsZWFrcy5cbiAgICpcbiAgICogQG1lcm1haWRcbiAgICogc2VxdWVuY2VEaWFncmFtXG4gICAqICAgcGFydGljaXBhbnQgQSBhcyBBbmd1bGFyIExpZmVjeWNsZVxuICAgKiAgIHBhcnRpY2lwYW50IEMgYXMgQ29tcG9uZW50UmVuZGVyZXJDb21wb25lbnRcbiAgICogICBwYXJ0aWNpcGFudCBSIGFzIE5neFJlbmRlcmluZ0VuZ2luZTJcbiAgICpcbiAgICogICBBLT4+QzogbmdPbkRlc3Ryb3koKVxuICAgKiAgIGFsdCBjb21wb25lbnQgZXhpc3RzXG4gICAqICAgICBDLT4+QzogdW5zdWJzY3JpYmVFdmVudHMoKVxuICAgKiAgICAgQy0+PlI6IGRlc3Ryb3koKVxuICAgKiAgIGVuZFxuICAgKlxuICAgKiBAcmV0dXJuIHtQcm9taXNlPHZvaWQ+fSBBIHByb21pc2UgdGhhdCByZXNvbHZlcyB3aGVuIGNsZWFudXAgaXMgY29tcGxldGVcbiAgICogQG1lbWJlck9mIENvbXBvbmVudFJlbmRlcmVyQ29tcG9uZW50XG4gICAqL1xuICBhc3luYyBuZ09uRGVzdHJveSgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBpZiAodGhpcy5jb21wb25lbnQpIHtcbiAgICAgIHRoaXMudW5zdWJzY3JpYmVFdmVudHMoKTtcbiAgICAgIE5neFJlbmRlcmluZ0VuZ2luZTIuZGVzdHJveSgpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gQ3JlYXRlcyBhbmQgcmVuZGVycyBhIGR5bmFtaWMgY29tcG9uZW50LlxuICAgKiBAc3VtbWFyeSBUaGlzIG1ldGhvZCBoYW5kbGVzIHRoZSBjcmVhdGlvbiBvZiBhIGR5bmFtaWMgY29tcG9uZW50IGJhc2VkIG9uIHRoZSBwcm92aWRlZCB0YWcuXG4gICAqIEl0IHJldHJpZXZlcyB0aGUgY29tcG9uZW50IGNvbnN0cnVjdG9yIGZyb20gdGhlIHJlbmRlcmluZyBlbmdpbmUsIHByb2Nlc3NlcyBpdHMgaW5wdXRzLFxuICAgKiBmaWx0ZXJzIG91dCB1bm1hcHBlZCBwcm9wZXJ0aWVzLCBjcmVhdGVzIHRoZSBjb21wb25lbnQgaW5zdGFuY2UsIGFuZCBzZXRzIHVwIGV2ZW50IHN1YnNjcmlwdGlvbnMuXG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSB0YWcgLSBUaGUgdGFnIG5hbWUgb2YgdGhlIGNvbXBvbmVudCB0byBjcmVhdGVcbiAgICogQHBhcmFtIHtLZXlWYWx1ZX0gZ2xvYmFscyAtIEdsb2JhbCBwcm9wZXJ0aWVzIHRvIHBhc3MgdG8gdGhlIGNvbXBvbmVudFxuICAgKiBAcmV0dXJuIHt2b2lkfVxuICAgKlxuICAgKiBAbWVybWFpZFxuICAgKiBzZXF1ZW5jZURpYWdyYW1cbiAgICogICBwYXJ0aWNpcGFudCBDIGFzIENvbXBvbmVudFJlbmRlcmVyQ29tcG9uZW50XG4gICAqICAgcGFydGljaXBhbnQgUiBhcyBOZ3hSZW5kZXJpbmdFbmdpbmUyXG4gICAqICAgcGFydGljaXBhbnQgViBhcyBWaWV3Q29udGFpbmVyUmVmXG4gICAqXG4gICAqICAgQy0+PlI6IGNvbXBvbmVudHModGFnKVxuICAgKiAgIFItLT4+QzogUmV0dXJuIGNvbXBvbmVudCBjb25zdHJ1Y3RvclxuICAgKiAgIEMtPj5DOiByZWZsZWN0Q29tcG9uZW50VHlwZShjb21wb25lbnQpXG4gICAqICAgQy0+PkM6IFByb2Nlc3MgaW5wdXQgcHJvcGVydGllc1xuICAgKiAgIEMtPj5DOiBGaWx0ZXIgdW5tYXBwZWQgcHJvcGVydGllc1xuICAgKiAgIEMtPj5WOiBjbGVhcigpXG4gICAqICAgQy0+PlI6IGNyZWF0ZUNvbXBvbmVudChjb21wb25lbnQsIHByb3BzLCBtZXRhZGF0YSwgdmNyLCBpbmplY3RvciwgW10pXG4gICAqICAgUi0tPj5DOiBSZXR1cm4gY29tcG9uZW50IHJlZmVyZW5jZVxuICAgKiAgIEMtPj5DOiBzdWJzY3JpYmVFdmVudHMoKVxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAbWVtYmVyT2YgQ29tcG9uZW50UmVuZGVyZXJDb21wb25lbnRcbiAgICovXG4gIHByaXZhdGUgY3JlYXRlQ29tcG9uZW50KHRhZzogc3RyaW5nLCBnbG9iYWxzOiBLZXlWYWx1ZSA9IHt9KTogdm9pZCB7XG4gICAgY29uc3QgY29tcG9uZW50ID0gTmd4UmVuZGVyaW5nRW5naW5lMi5jb21wb25lbnRzKHRhZylcbiAgICAgID8uY29uc3RydWN0b3IgYXMgVHlwZTx1bmtub3duPjtcbiAgICBjb25zdCBtZXRhZGF0YSA9IHJlZmxlY3RDb21wb25lbnRUeXBlKGNvbXBvbmVudCk7XG4gICAgY29uc3QgY29tcG9uZW50SW5wdXRzID0gKG1ldGFkYXRhIGFzIENvbXBvbmVudE1pcnJvcjx1bmtub3duPikuaW5wdXRzO1xuICAgIGNvbnN0IHByb3BzID0gZ2xvYmFscz8uWydpdGVtJ107XG4gICAgZGVsZXRlIHByb3BzWyd0YWcnXTtcbiAgICBjb25zdCBpbnB1dEtleXMgPSBPYmplY3Qua2V5cyhwcm9wcyk7XG4gICAgY29uc3QgdW5tYXBwZWRLZXlzID0gW107XG5cbiAgICBmb3IgKGNvbnN0IGlucHV0IG9mIGlucHV0S2V5cykge1xuICAgICAgaWYgKCFpbnB1dEtleXMubGVuZ3RoKSBicmVhaztcbiAgICAgIGNvbnN0IHByb3AgPSBjb21wb25lbnRJbnB1dHMuZmluZChcbiAgICAgICAgKGl0ZW06IHsgcHJvcE5hbWU6IHN0cmluZyB9KSA9PiBpdGVtLnByb3BOYW1lID09PSBpbnB1dCxcbiAgICAgICk7XG4gICAgICBpZiAoIXByb3ApIHtcbiAgICAgICAgZGVsZXRlIHByb3BzW2lucHV0XTtcbiAgICAgICAgdW5tYXBwZWRLZXlzLnB1c2goaW5wdXQpO1xuICAgICAgfVxuICAgIH1cbiAgICBpZiAodW5tYXBwZWRLZXlzLmxlbmd0aClcbiAgICAgIHRoaXMubG9nZ2VyLmluZm8oYFVubWFwcGVkIGlucHV0IHByb3BlcnRpZXMgZm9yIGNvbXBvbmVudCAke3RhZ306ICR7dW5tYXBwZWRLZXlzLmpvaW4oJywgJyl9YCk7XG5cbiAgICB0aGlzLnZjci5jbGVhcigpO1xuICAgIHRoaXMuY29tcG9uZW50ID0gTmd4UmVuZGVyaW5nRW5naW5lMi5jcmVhdGVDb21wb25lbnQoXG4gICAgICBjb21wb25lbnQsXG4gICAgICBwcm9wcyxcbiAgICAgIG1ldGFkYXRhIGFzIENvbXBvbmVudE1pcnJvcjx1bmtub3duPixcbiAgICAgIHRoaXMudmNyLFxuICAgICAgdGhpcy5pbmplY3RvciBhcyBJbmplY3RvcixcbiAgICAgIFtdLFxuICAgICk7XG4gICAgdGhpcy5zdWJzY3JpYmVFdmVudHMoKTtcbiAgfVxuXG4gIGNyZWF0ZVBhcmVudENvbXBvbmVudCgpIHtcbiAgICBjb25zdCB7IGNvbXBvbmVudCwgaW5wdXRzIH0gPSB0aGlzLnBhcmVudDtcbiAgICBjb25zdCBtZXRhZGF0YSA9IHJlZmxlY3RDb21wb25lbnRUeXBlKGNvbXBvbmVudCkgYXMgQ29tcG9uZW50TWlycm9yPHVua25vd24+O1xuICAgIGNvbnN0IHRlbXBsYXRlID0gdGhpcy52Y3IuY3JlYXRlRW1iZWRkZWRWaWV3KHRoaXMuaW5uZXIgYXMgVGVtcGxhdGVSZWY8YW55PiwgdGhpcy5pbmplY3Rvcikucm9vdE5vZGVzO1xuICAgIHRoaXMuY29tcG9uZW50ID0gTmd4UmVuZGVyaW5nRW5naW5lMi5jcmVhdGVDb21wb25lbnQoXG4gICAgICBjb21wb25lbnQsXG4gICAgICBpbnB1dHMsXG4gICAgICBtZXRhZGF0YSxcbiAgICAgIHRoaXMudmNyLFxuICAgICAgdGhpcy5pbmplY3RvcixcbiAgICAgIHRlbXBsYXRlLFxuICAgICk7XG4gICAgdGhpcy5zdWJzY3JpYmVFdmVudHMoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gU3Vic2NyaWJlcyB0byBldmVudHMgZW1pdHRlZCBieSB0aGUgZHluYW1pYyBjb21wb25lbnQuXG4gICAqIEBzdW1tYXJ5IFRoaXMgbWV0aG9kIHNldHMgdXAgc3Vic2NyaXB0aW9ucyB0byBhbGwgRXZlbnRFbWl0dGVyIHByb3BlcnRpZXMgb2YgdGhlXG4gICAqIGR5bmFtaWNhbGx5IGNyZWF0ZWQgY29tcG9uZW50LiBXaGVuIGFuIGV2ZW50IGlzIGVtaXR0ZWQgYnkgdGhlIGR5bmFtaWMgY29tcG9uZW50LFxuICAgKiBpdCBpcyBjYXB0dXJlZCBhbmQgcmUtZW1pdHRlZCB0aHJvdWdoIHRoZSBsaXN0ZW5FdmVudCBvdXRwdXQgcHJvcGVydHkgd2l0aCBhZGRpdGlvbmFsXG4gICAqIG1ldGFkYXRhIGFib3V0IHRoZSBldmVudCBzb3VyY2UuXG4gICAqXG4gICAqIEBtZXJtYWlkXG4gICAqIHNlcXVlbmNlRGlhZ3JhbVxuICAgKiAgIHBhcnRpY2lwYW50IEMgYXMgQ29tcG9uZW50UmVuZGVyZXJDb21wb25lbnRcbiAgICogICBwYXJ0aWNpcGFudCBEIGFzIER5bmFtaWMgQ29tcG9uZW50XG4gICAqICAgcGFydGljaXBhbnQgUCBhcyBQYXJlbnQgQ29tcG9uZW50XG4gICAqXG4gICAqICAgQy0+PkM6IHN1YnNjcmliZUV2ZW50cygpXG4gICAqICAgQy0+PkQ6IEdldCBpbnN0YW5jZSBwcm9wZXJ0aWVzXG4gICAqICAgbG9vcCBGb3IgZWFjaCBwcm9wZXJ0eVxuICAgKiAgICAgQy0+PkM6IENoZWNrIGlmIHByb3BlcnR5IGlzIEV2ZW50RW1pdHRlclxuICAgKiAgICAgYWx0IGlzIEV2ZW50RW1pdHRlclxuICAgKiAgICAgICBDLT4+RDogU3Vic2NyaWJlIHRvIGV2ZW50XG4gICAqICAgICAgIEQtLT4+QzogRXZlbnQgZW1pdHRlZFxuICAgKiAgICAgICBDLT4+UDogUmUtZW1pdCBldmVudCB3aXRoIG1ldGFkYXRhXG4gICAqICAgICBlbmRcbiAgICogICBlbmRcbiAgICpcbiAgICogQHByaXZhdGVcbiAgICogQHJldHVybiB7dm9pZH1cbiAgICogQG1lbWJlck9mIENvbXBvbmVudFJlbmRlcmVyQ29tcG9uZW50XG4gICAqL1xuICBwcml2YXRlIHN1YnNjcmliZUV2ZW50cygpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5jb21wb25lbnQpIHtcbiAgICAgIGNvbnN0IGluc3RhbmNlID0gdGhpcy5jb21wb25lbnQ/Lmluc3RhbmNlIGFzIGFueTtcbiAgICAgIGNvbnN0IGNvbXBvbmVudEtleXMgPSBPYmplY3Qua2V5cyhpbnN0YW5jZSk7XG4gICAgICBmb3IgKGNvbnN0IGtleSBvZiBjb21wb25lbnRLZXlzKSB7XG4gICAgICAgIGNvbnN0IHZhbHVlID0gaW5zdGFuY2Vba2V5XTtcbiAgICAgICAgaWYgKHZhbHVlIGluc3RhbmNlb2YgRXZlbnRFbWl0dGVyKVxuICAgICAgICAgIChpbnN0YW5jZSBhcyBLZXlWYWx1ZSlba2V5XS5zdWJzY3JpYmUoXG4gICAgICAgICAgICAoZXZlbnQ6IFBhcnRpYWw8QmFzZUN1c3RvbUV2ZW50PikgPT4ge1xuICAgICAgICAgICAgICB0aGlzLmxpc3RlbkV2ZW50LmVtaXQoe1xuICAgICAgICAgICAgICAgIG5hbWU6IGtleSxcbiAgICAgICAgICAgICAgICAuLi5ldmVudCxcbiAgICAgICAgICAgICAgfSBhcyBNb2RlbFJlbmRlckN1c3RvbUV2ZW50KTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFVuc3Vic2NyaWJlcyBmcm9tIGFsbCBldmVudHMgb2YgdGhlIGR5bmFtaWMgY29tcG9uZW50LlxuICAgKiBAc3VtbWFyeSBUaGlzIG1ldGhvZCBjbGVhbnMgdXAgZXZlbnQgc3Vic2NyaXB0aW9ucyB3aGVuIHRoZSBjb21wb25lbnQgaXMgYmVpbmcgZGVzdHJveWVkLlxuICAgKiBJdCBpdGVyYXRlcyB0aHJvdWdoIGFsbCBwcm9wZXJ0aWVzIG9mIHRoZSBkeW5hbWljIGNvbXBvbmVudCBpbnN0YW5jZSBhbmQgdW5zdWJzY3JpYmVzXG4gICAqIGZyb20gYW55IEV2ZW50RW1pdHRlciBwcm9wZXJ0aWVzIHRvIHByZXZlbnQgbWVtb3J5IGxlYWtzIGFuZCB1bmV4cGVjdGVkIGJlaGF2aW9yIGFmdGVyXG4gICAqIHRoZSBjb21wb25lbnQgaXMgZGVzdHJveWVkLlxuICAgKlxuICAgKiBAbWVybWFpZFxuICAgKiBzZXF1ZW5jZURpYWdyYW1cbiAgICogICBwYXJ0aWNpcGFudCBDIGFzIENvbXBvbmVudFJlbmRlcmVyQ29tcG9uZW50XG4gICAqICAgcGFydGljaXBhbnQgRCBhcyBEeW5hbWljIENvbXBvbmVudFxuICAgKlxuICAgKiAgIEMtPj5DOiB1bnN1YnNjcmliZUV2ZW50cygpXG4gICAqICAgQy0+PkQ6IEdldCBpbnN0YW5jZSBwcm9wZXJ0aWVzXG4gICAqICAgbG9vcCBGb3IgZWFjaCBwcm9wZXJ0eVxuICAgKiAgICAgQy0+PkM6IENoZWNrIGlmIHByb3BlcnR5IGlzIEV2ZW50RW1pdHRlclxuICAgKiAgICAgYWx0IGlzIEV2ZW50RW1pdHRlclxuICAgKiAgICAgICBDLT4+RDogVW5zdWJzY3JpYmUgZnJvbSBldmVudFxuICAgKiAgICAgZW5kXG4gICAqICAgZW5kXG4gICAqXG4gICAqIEBwcml2YXRlXG4gICAqIEByZXR1cm4ge3ZvaWR9XG4gICAqIEBtZW1iZXJPZiBDb21wb25lbnRSZW5kZXJlckNvbXBvbmVudFxuICAgKi9cbiAgcHJpdmF0ZSB1bnN1YnNjcmliZUV2ZW50cygpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5jb21wb25lbnQpIHtcbiAgICAgIGNvbnN0IGluc3RhbmNlID0gdGhpcy5jb21wb25lbnQ/Lmluc3RhbmNlIGFzIGFueTtcbiAgICAgIGNvbnN0IGNvbXBvbmVudEtleXMgPSBPYmplY3Qua2V5cyhpbnN0YW5jZSk7XG4gICAgICBmb3IgKGNvbnN0IGtleSBvZiBjb21wb25lbnRLZXlzKSB7XG4gICAgICAgIGNvbnN0IHZhbHVlID0gaW5zdGFuY2Vba2V5XTtcbiAgICAgICAgaWYgKHZhbHVlIGluc3RhbmNlb2YgRXZlbnRFbWl0dGVyKSBpbnN0YW5jZVtrZXldLnVuc3Vic2NyaWJlKCk7XG4gICAgICB9XG4gICAgfVxuICB9XG59XG4iLCI8bmctdGVtcGxhdGUgI2NvbXBvbmVudFZpZXdDb250YWluZXI+PC9uZy10ZW1wbGF0ZT5cblxuPG5nLXRlbXBsYXRlICNpbm5lcj5cbiAgQGlmKHBhcmVudD8uY2hpbGRyZW4/Lmxlbmd0aCkge1xuICAgIEBmb3IoY2hpbGQgb2YgcGFyZW50LmNoaWxkcmVuOyB0cmFjayBjaGlsZCkge1xuICAgICAgICBAaWYoIWNoaWxkLmNoaWxkcmVuPy5sZW5ndGgpIHtcbiAgICAgICAgICA8bmctY29udGFpbmVyXG4gICAgICAgICAgICAgICAgKm5nQ29tcG9uZW50T3V0bGV0PVwiXG4gICAgICAgICAgICAgICAgICBjaGlsZC5jb21wb25lbnQ7XG4gICAgICAgICAgICAgICAgICBpbmplY3RvcjogY2hpbGQuaW5qZWN0b3I7XG4gICAgICAgICAgICAgICAgICBpbnB1dHM6IGNoaWxkLmlucHV0cztcbiAgICAgICAgICAgICAgICAgIGNvbnRlbnQ6Y2hpbGQuY29udGVudDtcbiAgICAgICAgICAgICAgICBcIlxuICAgICAgICAgIC8+XG4gICAgICAgIH0gQGVsc2Uge1xuICAgICAgICAgIDxuZ3gtZGVjYWYtY29tcG9uZW50LXJlbmRlcmVyIFtwYXJlbnRdPVwiY2hpbGRcIj4gPC9uZ3gtZGVjYWYtY29tcG9uZW50LXJlbmRlcmVyPlxuICAgICAgICB9XG4gICAgIH1cbiAgfVxuPC9uZy10ZW1wbGF0ZT5cblxuXG4iXX0=
313
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29tcG9uZW50LXJlbmRlcmVyLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3NyYy9saWIvY29tcG9uZW50cy9jb21wb25lbnQtcmVuZGVyZXIvY29tcG9uZW50LXJlbmRlcmVyLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uL3NyYy9saWIvY29tcG9uZW50cy9jb21wb25lbnQtcmVuZGVyZXIvY29tcG9uZW50LXJlbmRlcmVyLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFDTCxTQUFTLEVBR1QsbUJBQW1CLEVBQ25CLFlBQVksRUFDWixNQUFNLEVBRU4sS0FBSyxFQUdMLE1BQU0sRUFDTixvQkFBb0IsRUFDcEIsV0FBVyxFQUVYLFNBQVMsRUFDVCxnQkFBZ0IsR0FDakIsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0sb0NBQW9DLENBQUM7QUFFekUsT0FBTyxFQUFFLGdCQUFnQixFQUFFLFNBQVMsRUFBRSxNQUFNLDRCQUE0QixDQUFDOzs7QUFJekU7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBc0NHO0FBUUgsTUFBTSxPQUFPLDBCQUEwQjtJQTRHckM7Ozs7Ozs7T0FPRztJQUNIO1FBeEZBOzs7Ozs7Ozs7O1dBVUc7UUFFSCxZQUFPLEdBQTRCLEVBQUUsQ0FBQztRQUV0Qzs7Ozs7Ozs7O1dBU0c7UUFDSCxhQUFRLEdBQXdCLE1BQU0sQ0FBQyxtQkFBbUIsQ0FBQyxDQUFDO1FBYTVEOzs7Ozs7Ozs7V0FTRztRQUVILGdCQUFXLEdBQ1QsSUFBSSxZQUFZLEVBQXVCLENBQUM7UUF5QjFDLFdBQU0sR0FBeUIsU0FBUyxDQUFDO1FBZXZDLElBQUksQ0FBQyxNQUFNLEdBQUcsU0FBUyxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQ2hDLENBQUM7SUFFRDs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztPQXNC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VSwwQkFBMEI7bUdBQTFCLDBCQUEwQix5U0FXc0IsZ0JBQWdCLHVHQThGL0MsV0FBVywyQ0MvS3pDLCttQkFzQkEsMEREZ0RhLDBCQUEwQixpSkFIM0IsZ0JBQWdCOzs0RkFHZiwwQkFBMEI7a0JBUHRDLFNBQVM7K0JBQ0UsOEJBQThCLFdBRy9CLENBQUMsZ0JBQWdCLENBQUMsY0FDZixJQUFJO3dEQWNoQixHQUFHO3NCQURGLFNBQVM7dUJBQUMsd0JBQXdCLEVBQUUsRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxnQkFBZ0IsRUFBRTtnQkFlN0UsR0FBRztzQkFERixLQUFLO3VCQUFDLEVBQUUsUUFBUSxFQUFFLElBQUksRUFBRTtnQkFlekIsT0FBTztzQkFETixLQUFLO2dCQXFDTixXQUFXO3NCQURWLE1BQU07Z0JBd0JQLEtBQUs7c0JBREosS0FBSztnQkFJTixNQUFNO3NCQURMLEtBQUs7Z0JBS04sS0FBSztzQkFESixTQUFTO3VCQUFDLE9BQU8sRUFBRSxFQUFFLElBQUksRUFBRSxXQUFXLEVBQUUsTUFBTSxFQUFFLElBQUksRUFBRSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gIENvbXBvbmVudCxcbiAgQ29tcG9uZW50TWlycm9yLFxuICBDb21wb25lbnRSZWYsXG4gIEVudmlyb25tZW50SW5qZWN0b3IsXG4gIEV2ZW50RW1pdHRlcixcbiAgaW5qZWN0LFxuICBJbmplY3RvcixcbiAgSW5wdXQsXG4gIE9uRGVzdHJveSxcbiAgT25Jbml0LFxuICBPdXRwdXQsXG4gIHJlZmxlY3RDb21wb25lbnRUeXBlLFxuICBUZW1wbGF0ZVJlZixcbiAgVHlwZSxcbiAgVmlld0NoaWxkLFxuICBWaWV3Q29udGFpbmVyUmVmLFxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IE5neFJlbmRlcmluZ0VuZ2luZTIgfSBmcm9tICdzcmMvbGliL2VuZ2luZS9OZ3hSZW5kZXJpbmdFbmdpbmUyJztcbmltcG9ydCB7IEJhc2VDdXN0b21FdmVudCwgS2V5VmFsdWUsIFJlbmRlcmVyQ3VzdG9tRXZlbnQgfSBmcm9tICcuLi8uLi9lbmdpbmUnO1xuaW1wb3J0IHsgRm9yQW5ndWxhck1vZHVsZSwgZ2V0TG9nZ2VyIH0gZnJvbSAnc3JjL2xpYi9mb3ItYW5ndWxhci5tb2R1bGUnO1xuaW1wb3J0IHsgTG9nZ2VyIH0gZnJvbSAnQGRlY2FmLXRzL2xvZ2dpbmcnO1xuaW1wb3J0IHsgTW9kZWwgfSBmcm9tICdAZGVjYWYtdHMvZGVjb3JhdG9yLXZhbGlkYXRpb24nO1xuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBEeW5hbWljIGNvbXBvbmVudCByZW5kZXJlciBmb3IgRGVjYWYgQW5ndWxhciBhcHBsaWNhdGlvbnMuXG4gKiBAc3VtbWFyeSBUaGlzIGNvbXBvbmVudCBwcm92aWRlcyBhIGZsZXhpYmxlIHdheSB0byBkeW5hbWljYWxseSByZW5kZXIgQW5ndWxhciBjb21wb25lbnRzXG4gKiBhdCBydW50aW1lIGJhc2VkIG9uIGEgdGFnIG5hbWUuIEl0IGhhbmRsZXMgdGhlIGNyZWF0aW9uLCBwcm9wZXJ0eSBiaW5kaW5nLCBhbmQgZXZlbnRcbiAqIHN1YnNjcmlwdGlvbiBmb3IgZHluYW1pY2FsbHkgbG9hZGVkIGNvbXBvbmVudHMuIFRoaXMgaXMgcGFydGljdWxhcmx5IHVzZWZ1bCBmb3JcbiAqIGJ1aWxkaW5nIGNvbmZpZ3VyYWJsZSBVSXMgd2hlcmUgY29tcG9uZW50cyBuZWVkIHRvIGJlIGRldGVybWluZWQgYXQgcnVudGltZS5cbiAqXG4gKiBAY29tcG9uZW50IHtDb21wb25lbnRSZW5kZXJlckNvbXBvbmVudH1cbiAqIEBleGFtcGxlXG4gKiA8bmd4LWRlY2FmLWNvbXBvbmVudC1yZW5kZXJlclxuICogICBbdGFnXT1cInRhZ1wiXG4gKiAgIFtnbG9iYWxzXT1cImdsb2JhbHNcIlxuICogICAobGlzdGVuRXZlbnQpPVwibGlzdGVuRXZlbnQoJGV2ZW50KVwiPlxuICogPC9uZ3gtZGVjYWYtY29tcG9uZW50LXJlbmRlcmVyPlxuICpcbiAqIEBtZXJtYWlkXG4gKiBjbGFzc0RpYWdyYW1cbiAqICAgY2xhc3MgQ29tcG9uZW50UmVuZGVyZXJDb21wb25lbnQge1xuICogICAgICtWaWV3Q29udGFpbmVyUmVmIHZjclxuICogICAgICtzdHJpbmcgdGFnXG4gKiAgICAgK1JlY29yZH5zdHJpbmcsIHVua25vd25+IGdsb2JhbHNcbiAqICAgICArRW52aXJvbm1lbnRJbmplY3RvciBpbmplY3RvclxuICogICAgICtDb21wb25lbnRSZWZ+dW5rbm93bn4gY29tcG9uZW50XG4gKiAgICAgK0V2ZW50RW1pdHRlcn5SZW5kZXJlckN1c3RvbUV2ZW50fiBsaXN0ZW5FdmVudFxuICogICAgICtuZ09uSW5pdCgpXG4gKiAgICAgK25nT25EZXN0cm95KClcbiAqICAgICArbmdPbkNoYW5nZXMoY2hhbmdlcylcbiAqICAgICAtY3JlYXRlQ29tcG9uZW50KHRhZywgZ2xvYmFscylcbiAqICAgICAtc3Vic2NyaWJlRXZlbnRzKClcbiAqICAgICAtdW5zdWJzY3JpYmVFdmVudHMoKVxuICogICB9XG4gKiAgIENvbXBvbmVudFJlbmRlcmVyQ29tcG9uZW50IC0tfD4gT25Jbml0XG4gKiAgIENvbXBvbmVudFJlbmRlcmVyQ29tcG9uZW50IC0tfD4gT25DaGFuZ2VzXG4gKiAgIENvbXBvbmVudFJlbmRlcmVyQ29tcG9uZW50IC0tfD4gT25EZXN0cm95XG4gKlxuICogQGltcGxlbWVudHMge09uSW5pdH1cbiAqIEBpbXBsZW1lbnRzIHtPbkNoYW5nZXN9XG4gKiBAaW1wbGVtZW50cyB7T25EZXN0cm95fVxuICovXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICduZ3gtZGVjYWYtY29tcG9uZW50LXJlbmRlcmVyJyxcbiAgdGVtcGxhdGVVcmw6ICcuL2NvbXBvbmVudC1yZW5kZXJlci5jb21wb25lbnQuaHRtbCcsXG4gIHN0eWxlVXJsczogWycuL2NvbXBvbmVudC1yZW5kZXJlci5jb21wb25lbnQuc2NzcyddLFxuICBpbXBvcnRzOiBbRm9yQW5ndWxhck1vZHVsZV0sXG4gIHN0YW5kYWxvbmU6IHRydWUsXG59KVxuZXhwb3J0IGNsYXNzIENvbXBvbmVudFJlbmRlcmVyQ29tcG9uZW50XG4gIGltcGxlbWVudHMgT25Jbml0LCBPbkRlc3Ryb3kge1xuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFJlZmVyZW5jZSB0byB0aGUgY29udGFpbmVyIHdoZXJlIHRoZSBkeW5hbWljIGNvbXBvbmVudCB3aWxsIGJlIHJlbmRlcmVkLlxuICAgKiBAc3VtbWFyeSBUaGlzIFZpZXdDb250YWluZXJSZWYgcHJvdmlkZXMgdGhlIGNvbnRhaW5lciB3aGVyZSB0aGUgZHluYW1pY2FsbHkgY3JlYXRlZFxuICAgKiBjb21wb25lbnQgd2lsbCBiZSBpbnNlcnRlZCBpbnRvIHRoZSBET00uIEl0J3MgbWFya2VkIGFzIHN0YXRpYyB0byBlbnN1cmUgaXQncyBhdmFpbGFibGVcbiAgICogZHVyaW5nIHRoZSBuZ09uSW5pdCBsaWZlY3ljbGUgaG9vayB3aGVuIHRoZSBjb21wb25lbnQgaXMgY3JlYXRlZC5cbiAgICpcbiAgICogQHR5cGUge1ZpZXdDb250YWluZXJSZWZ9XG4gICAqIEBtZW1iZXJPZiBDb21wb25lbnRSZW5kZXJlckNvbXBvbmVudFxuICAgKi9cbiAgQFZpZXdDaGlsZCgnY29tcG9uZW50Vmlld0NvbnRhaW5lcicsIHsgc3RhdGljOiB0cnVlLCByZWFkOiBWaWV3Q29udGFpbmVyUmVmIH0pXG4gIHZjciE6IFZpZXdDb250YWluZXJSZWY7XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBUaGUgdGFnIG5hbWUgb2YgdGhlIGNvbXBvbmVudCB0byBiZSBkeW5hbWljYWxseSByZW5kZXJlZC5cbiAgICogQHN1bW1hcnkgVGhpcyBpbnB1dCBwcm9wZXJ0eSBzcGVjaWZpZXMgd2hpY2ggY29tcG9uZW50IHNob3VsZCBiZSByZW5kZXJlZCBieSBwcm92aWRpbmdcbiAgICogaXRzIHJlZ2lzdGVyZWQgdGFnIG5hbWUuIFRoZSB0YWcgbXVzdCBjb3JyZXNwb25kIHRvIGEgY29tcG9uZW50IHRoYXQgaGFzIGJlZW4gcmVnaXN0ZXJlZFxuICAgKiB3aXRoIHRoZSBOZ3hSZW5kZXJpbmdFbmdpbmUyLiBUaGlzIGlzIGEgcmVxdWlyZWQgaW5wdXQgYXMgaXQgZGV0ZXJtaW5lcyB3aGljaCBjb21wb25lbnRcbiAgICogdG8gY3JlYXRlLlxuICAgKlxuICAgKiBAdHlwZSB7c3RyaW5nfVxuICAgKiBAcmVxdWlyZWRcbiAgICogQG1lbWJlck9mIENvbXBvbmVudFJlbmRlcmVyQ29tcG9uZW50XG4gICAqL1xuICBASW5wdXQoeyByZXF1aXJlZDogdHJ1ZSB9KVxuICB0YWchOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBHbG9iYWwgcHJvcGVydGllcyB0byBwYXNzIHRvIHRoZSByZW5kZXJlZCBjb21wb25lbnQuXG4gICAqIEBzdW1tYXJ5IFRoaXMgaW5wdXQgcHJvcGVydHkgYWxsb3dzIHBhc3NpbmcgYSBzZXQgb2YgcHJvcGVydGllcyB0byB0aGUgZHluYW1pY2FsbHlcbiAgICogcmVuZGVyZWQgY29tcG9uZW50LiBUaGVzZSBwcm9wZXJ0aWVzIHdpbGwgYmUgbWFwcGVkIHRvIHRoZSBjb21wb25lbnQncyBpbnB1dHMgaWYgdGhleVxuICAgKiBtYXRjaC4gUHJvcGVydGllcyB0aGF0IGRvbid0IG1hdGNoIGFueSBpbnB1dCBvbiB0aGUgdGFyZ2V0IGNvbXBvbmVudCB3aWxsIGJlIGZpbHRlcmVkIG91dFxuICAgKiB3aXRoIGEgd2FybmluZy5cbiAgICpcbiAgICogQHR5cGUge1JlY29yZDxzdHJpbmcsIHVua25vd24+fVxuICAgKiBAZGVmYXVsdCB7fVxuICAgKiBAbWVtYmVyT2YgQ29tcG9uZW50UmVuZGVyZXJDb21wb25lbnRcbiAgICovXG4gIEBJbnB1dCgpXG4gIGdsb2JhbHM6IFJlY29yZDxzdHJpbmcsIHVua25vd24+ID0ge307XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBJbmplY3RvciB1c2VkIGZvciBkZXBlbmRlbmN5IGluamVjdGlvbiBpbiB0aGUgZHluYW1pYyBjb21wb25lbnQuXG4gICAqIEBzdW1tYXJ5IFRoaXMgaW5qZWN0b3IgaXMgdXNlZCB3aGVuIGNyZWF0aW5nIHRoZSBkeW5hbWljIGNvbXBvbmVudCB0byBwcm92aWRlIGl0IHdpdGhcbiAgICogYWNjZXNzIHRvIHRoZSBhcHBsaWNhdGlvbidzIGRlcGVuZGVuY3kgaW5qZWN0aW9uIHN5c3RlbS4gSXQgZW5zdXJlcyB0aGF0IHRoZSBkeW5hbWljYWxseVxuICAgKiBjcmVhdGVkIGNvbXBvbmVudCBjYW4gYWNjZXNzIHRoZSBzYW1lIHNlcnZpY2VzIGFuZCBkZXBlbmRlbmNpZXMgYXMgc3RhdGljYWxseSBjcmVhdGVkXG4gICAqIGNvbXBvbmVudHMuXG4gICAqXG4gICAqIEB0eXBlIHtFbnZpcm9ubWVudEluamVjdG9yfVxuICAgKiBAbWVtYmVyT2YgQ29tcG9uZW50UmVuZGVyZXJDb21wb25lbnRcbiAgICovXG4gIGluamVjdG9yOiBFbnZpcm9ubWVudEluamVjdG9yID0gaW5qZWN0KEVudmlyb25tZW50SW5qZWN0b3IpO1xuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gUmVmZXJlbmNlIHRvIHRoZSBkeW5hbWljYWxseSBjcmVhdGVkIGNvbXBvbmVudC5cbiAgICogQHN1bW1hcnkgVGhpcyBwcm9wZXJ0eSBob2xkcyBhIHJlZmVyZW5jZSB0byB0aGUgQ29tcG9uZW50UmVmIG9mIHRoZSBkeW5hbWljYWxseSBjcmVhdGVkXG4gICAqIGNvbXBvbmVudC4gSXQncyB1c2VkIHRvIGludGVyYWN0IHdpdGggdGhlIGNvbXBvbmVudCBpbnN0YW5jZSwgc3Vic2NyaWJlIHRvIGl0cyBldmVudHMsXG4gICAqIGFuZCBwcm9wZXJseSBkZXN0cm95IGl0IHdoZW4gdGhlIHJlbmRlcmVyIGlzIGRlc3Ryb3llZC5cbiAgICpcbiAgICogQHR5cGUge0NvbXBvbmVudFJlZjx1bmtub3duPn1cbiAgICogQG1lbWJlck9mIENvbXBvbmVudFJlbmRlcmVyQ29tcG9uZW50XG4gICAqL1xuICBjb21wb25lbnQhOiBDb21wb25lbnRSZWY8dW5rbm93bj47XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBFdmVudCBlbWl0dGVyIGZvciBldmVudHMgZnJvbSB0aGUgcmVuZGVyZWQgY29tcG9uZW50LlxuICAgKiBAc3VtbWFyeSBUaGlzIG91dHB1dCBwcm9wZXJ0eSBlbWl0cyBldmVudHMgdGhhdCBvcmlnaW5hdGUgZnJvbSB0aGUgZHluYW1pY2FsbHkgcmVuZGVyZWRcbiAgICogY29tcG9uZW50LiBJdCBhbGxvd3MgdGhlIHBhcmVudCBjb21wb25lbnQgdG8gbGlzdGVuIGZvciBhbmQgcmVzcG9uZCB0byBldmVudHMgZnJvbSB0aGVcbiAgICogZHluYW1pYyBjb21wb25lbnQsIGNyZWF0aW5nIGEgY29tbXVuaWNhdGlvbiBjaGFubmVsIGJldHdlZW4gdGhlIHBhcmVudCBhbmQgdGhlIGR5bmFtaWNhbGx5XG4gICAqIHJlbmRlcmVkIGNoaWxkLlxuICAgKlxuICAgKiBAdHlwZSB7RXZlbnRFbWl0dGVyPFJlbmRlcmVyQ3VzdG9tRXZlbnQ+fVxuICAgKiBAbWVtYmVyT2YgQ29tcG9uZW50UmVuZGVyZXJDb21wb25lbnRcbiAgICovXG4gIEBPdXRwdXQoKVxuICBsaXN0ZW5FdmVudDogRXZlbnRFbWl0dGVyPFJlbmRlcmVyQ3VzdG9tRXZlbnQ+ID1cbiAgICBuZXcgRXZlbnRFbWl0dGVyPFJlbmRlcmVyQ3VzdG9tRXZlbnQ+KCk7XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBMb2dnZXIgaW5zdGFuY2UgZm9yIHRoZSBjb21wb25lbnQuXG4gICAqIEBzdW1tYXJ5IFRoaXMgcHJvcGVydHkgaG9sZHMgYSBMb2dnZXIgaW5zdGFuY2Ugc3BlY2lmaWMgdG8gdGhpcyBjb21wb25lbnQuXG4gICAqIEl0J3MgdXNlZCB0byBsb2cgaW5mb3JtYXRpb24sIHdhcm5pbmdzLCBhbmQgZXJyb3JzIHJlbGF0ZWQgdG8gdGhlIGNvbXBvbmVudCdzXG4gICAqIG9wZXJhdGlvbnMsIHBhcnRpY3VsYXJseSB1c2VmdWwgZm9yIGRlYnVnZ2luZyBhbmQgbW9uaXRvcmluZyB0aGUgZHluYW1pY1xuICAgKiBjb21wb25lbnQgcmVuZGVyaW5nIHByb2Nlc3MuXG4gICAqXG4gICAqIEB0eXBlIHtMb2dnZXJ9XG4gICAqIEBtZW1iZXJPZiBDb21wb25lbnRSZW5kZXJlckNvbXBvbmVudFxuICAgKi9cbiAgbG9nZ2VyITogTG9nZ2VyO1xuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gUmVwb3NpdG9yeSBtb2RlbCBmb3IgZGF0YSBvcGVyYXRpb25zLlxuICAgKiBAc3VtbWFyeSBUaGUgZGF0YSBtb2RlbCByZXBvc2l0b3J5IHRoYXQgdGhpcyBjb21wb25lbnQgd2lsbCB1c2UgZm9yIENSVUQgb3BlcmF0aW9ucy5cbiAgICogVGhpcyBwcm92aWRlcyBhIGNvbm5lY3Rpb24gdG8gdGhlIGRhdGEgbGF5ZXIgZm9yIHJldHJpZXZpbmcgYW5kIG1hbmlwdWxhdGluZyBkYXRhLlxuICAgKlxuICAgKiBAdHlwZSB7TW9kZWx8IHVuZGVmaW5lZH1cbiAgICovXG4gIEBJbnB1dCgpXG4gIG1vZGVsITogIE1vZGVsIHwgdW5kZWZpbmVkO1xuXG4gIEBJbnB1dCgpXG4gIHBhcmVudDogdW5kZWZpbmVkIHwgS2V5VmFsdWUgPSB1bmRlZmluZWQ7XG5cblxuICBAVmlld0NoaWxkKCdpbm5lcicsIHsgcmVhZDogVGVtcGxhdGVSZWYsIHN0YXRpYzogdHJ1ZSB9KVxuICBpbm5lcj86IFRlbXBsYXRlUmVmPHVua25vd24+O1xuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gQ3JlYXRlcyBhbiBpbnN0YW5jZSBvZiBDb21wb25lbnRSZW5kZXJlckNvbXBvbmVudC5cbiAgICogQHN1bW1hcnkgSW5pdGlhbGl6ZXMgYSBuZXcgQ29tcG9uZW50UmVuZGVyZXJDb21wb25lbnQuIFRoaXMgY29tcG9uZW50IGRvZXNuJ3QgcmVxdWlyZVxuICAgKiBhbnkgZGVwZW5kZW5jaWVzIHRvIGJlIGluamVjdGVkIGluIGl0cyBjb25zdHJ1Y3RvciBhcyBpdCB1c2VzIHRoZSBpbmplY3QgZnVuY3Rpb24gdG9cbiAgICogb2J0YWluIHRoZSBFbnZpcm9ubWVudEluamVjdG9yLlxuICAgKlxuICAgKiBAbWVtYmVyT2YgQ29tcG9uZW50UmVuZGVyZXJDb21wb25lbnRcbiAgICovXG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIHRoaXMubG9nZ2VyID0gZ2V0TG9nZ2VyKHRoaXMpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBJbml0aWFsaXplcyB0aGUgY29tcG9uZW50IGFmdGVyIEFuZ3VsYXIgZmlyc3QgZGlzcGxheXMgdGhlIGRhdGEtYm91bmQgcHJvcGVydGllcy5cbiAgICogQHN1bW1hcnkgU2V0cyB1cCB0aGUgY29tcG9uZW50IGJ5IGNyZWF0aW5nIHRoZSBkeW5hbWljIGNvbXBvbmVudCBzcGVjaWZpZWQgYnkgdGhlIHRhZyBpbnB1dC5cbiAgICogVGhpcyBtZXRob2QgaXMgY2FsbGVkIG9uY2Ugd2hlbiB0aGUgY29tcG9uZW50IGlzIGluaXRpYWxpemVkIGFuZCB0cmlnZ2VycyB0aGUgZHluYW1pY1xuICAgKiBjb21wb25lbnQgY3JlYXRpb24gcHJvY2VzcyB3aXRoIHRoZSBwcm92aWRlZCB0YWcgbmFtZSBhbmQgZ2xvYmFsIHByb3BlcnRpZXMuXG4gICAqXG4gICAqIEBtZXJtYWlkXG4gICAqIHNlcXVlbmNlRGlhZ3JhbVxuICAgKiAgIHBhcnRpY2lwYW50IEEgYXMgQW5ndWxhciBMaWZlY3ljbGVcbiAgICogICBwYXJ0aWNpcGFudCBDIGFzIENvbXBvbmVudFJlbmRlcmVyQ29tcG9uZW50XG4gICAqICAgcGFydGljaXBhbnQgUiBhcyBOZ3hSZW5kZXJpbmdFbmdpbmUyXG4gICAqXG4gICAqICAgQS0+PkM6IG5nT25Jbml0KClcbiAgICogICBDLT4+QzogY3JlYXRlQ29tcG9uZW50KHRhZywgZ2xvYmFscylcbiAgICogICBDLT4+UjogY29tcG9uZW50cyh0YWcpXG4gICAqICAgUi0tPj5DOiBSZXR1cm4gY29tcG9uZW50IGNvbnN0cnVjdG9yXG4gICAqICAgQy0+PkM6IFByb2Nlc3MgY29tcG9uZW50IGlucHV0c1xuICAgKiAgIEMtPj5DOiBDcmVhdGUgY29tcG9uZW50IGluc3RhbmNlXG4gICAqICAgQy0+PkM6IHN1YnNjcmliZUV2ZW50cygpXG4gICAqXG4gICAqIEByZXR1cm4ge3ZvaWR9XG4gICAqIEBtZW1iZXJPZiBDb21wb25lbnRSZW5kZXJlckNvbXBvbmVudFxuICAgKi9cbiAgbmdPbkluaXQoKTogdm9pZCB7XG4gICAgaWYgKCF0aGlzLnBhcmVudCkge1xuICAgICAgdGhpcy5jcmVhdGVDb21wb25lbnQodGhpcy50YWcsIHRoaXMuZ2xvYmFscyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuY3JlYXRlUGFyZW50Q29tcG9uZW50KCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBDbGVhbnMgdXAgcmVzb3VyY2VzIHdoZW4gdGhlIGNvbXBvbmVudCBpcyBkZXN0cm95ZWQuXG4gICAqIEBzdW1tYXJ5IFBlcmZvcm1zIGNsZWFudXAgb3BlcmF0aW9ucyB3aGVuIHRoZSBjb21wb25lbnQgaXMgYmVpbmcgZGVzdHJveWVkIGJ5IEFuZ3VsYXIuXG4gICAqIFRoaXMgaW5jbHVkZXMgdW5zdWJzY3JpYmluZyBmcm9tIGFsbCBldmVudCBlbWl0dGVycyBvZiB0aGUgZHluYW1pYyBjb21wb25lbnQgYW5kXG4gICAqIGRlc3Ryb3lpbmcgdGhlIHJlbmRlcmluZyBlbmdpbmUgaW5zdGFuY2UgdG8gcHJldmVudCBtZW1vcnkgbGVha3MuXG4gICAqXG4gICAqIEBtZXJtYWlkXG4gICAqIHNlcXVlbmNlRGlhZ3JhbVxuICAgKiAgIHBhcnRpY2lwYW50IEEgYXMgQW5ndWxhciBMaWZlY3ljbGVcbiAgICogICBwYXJ0aWNpcGFudCBDIGFzIENvbXBvbmVudFJlbmRlcmVyQ29tcG9uZW50XG4gICAqICAgcGFydGljaXBhbnQgUiBhcyBOZ3hSZW5kZXJpbmdFbmdpbmUyXG4gICAqXG4gICAqICAgQS0+PkM6IG5nT25EZXN0cm95KClcbiAgICogICBhbHQgY29tcG9uZW50IGV4aXN0c1xuICAgKiAgICAgQy0+PkM6IHVuc3Vic2NyaWJlRXZlbnRzKClcbiAgICogICAgIEMtPj5SOiBkZXN0cm95KClcbiAgICogICBlbmRcbiAgICpcbiAgICogQHJldHVybiB7UHJvbWlzZTx2b2lkPn0gQSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgd2hlbiBjbGVhbnVwIGlzIGNvbXBsZXRlXG4gICAqIEBtZW1iZXJPZiBDb21wb25lbnRSZW5kZXJlckNvbXBvbmVudFxuICAgKi9cbiAgYXN5bmMgbmdPbkRlc3Ryb3koKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgaWYgKHRoaXMuY29tcG9uZW50KSB7XG4gICAgICB0aGlzLnVuc3Vic2NyaWJlRXZlbnRzKCk7XG4gICAgICBOZ3hSZW5kZXJpbmdFbmdpbmUyLmRlc3Ryb3koKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIENyZWF0ZXMgYW5kIHJlbmRlcnMgYSBkeW5hbWljIGNvbXBvbmVudC5cbiAgICogQHN1bW1hcnkgVGhpcyBtZXRob2QgaGFuZGxlcyB0aGUgY3JlYXRpb24gb2YgYSBkeW5hbWljIGNvbXBvbmVudCBiYXNlZCBvbiB0aGUgcHJvdmlkZWQgdGFnLlxuICAgKiBJdCByZXRyaWV2ZXMgdGhlIGNvbXBvbmVudCBjb25zdHJ1Y3RvciBmcm9tIHRoZSByZW5kZXJpbmcgZW5naW5lLCBwcm9jZXNzZXMgaXRzIGlucHV0cyxcbiAgICogZmlsdGVycyBvdXQgdW5tYXBwZWQgcHJvcGVydGllcywgY3JlYXRlcyB0aGUgY29tcG9uZW50IGluc3RhbmNlLCBhbmQgc2V0cyB1cCBldmVudCBzdWJzY3JpcHRpb25zLlxuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gdGFnIC0gVGhlIHRhZyBuYW1lIG9mIHRoZSBjb21wb25lbnQgdG8gY3JlYXRlXG4gICAqIEBwYXJhbSB7S2V5VmFsdWV9IGdsb2JhbHMgLSBHbG9iYWwgcHJvcGVydGllcyB0byBwYXNzIHRvIHRoZSBjb21wb25lbnRcbiAgICogQHJldHVybiB7dm9pZH1cbiAgICpcbiAgICogQG1lcm1haWRcbiAgICogc2VxdWVuY2VEaWFncmFtXG4gICAqICAgcGFydGljaXBhbnQgQyBhcyBDb21wb25lbnRSZW5kZXJlckNvbXBvbmVudFxuICAgKiAgIHBhcnRpY2lwYW50IFIgYXMgTmd4UmVuZGVyaW5nRW5naW5lMlxuICAgKiAgIHBhcnRpY2lwYW50IFYgYXMgVmlld0NvbnRhaW5lclJlZlxuICAgKlxuICAgKiAgIEMtPj5SOiBjb21wb25lbnRzKHRhZylcbiAgICogICBSLS0+PkM6IFJldHVybiBjb21wb25lbnQgY29uc3RydWN0b3JcbiAgICogICBDLT4+QzogcmVmbGVjdENvbXBvbmVudFR5cGUoY29tcG9uZW50KVxuICAgKiAgIEMtPj5DOiBQcm9jZXNzIGlucHV0IHByb3BlcnRpZXNcbiAgICogICBDLT4+QzogRmlsdGVyIHVubWFwcGVkIHByb3BlcnRpZXNcbiAgICogICBDLT4+VjogY2xlYXIoKVxuICAgKiAgIEMtPj5SOiBjcmVhdGVDb21wb25lbnQoY29tcG9uZW50LCBwcm9wcywgbWV0YWRhdGEsIHZjciwgaW5qZWN0b3IsIFtdKVxuICAgKiAgIFItLT4+QzogUmV0dXJuIGNvbXBvbmVudCByZWZlcmVuY2VcbiAgICogICBDLT4+Qzogc3Vic2NyaWJlRXZlbnRzKClcbiAgICpcbiAgICogQHByaXZhdGVcbiAgICogQG1lbWJlck9mIENvbXBvbmVudFJlbmRlcmVyQ29tcG9uZW50XG4gICAqL1xuICBwcml2YXRlIGNyZWF0ZUNvbXBvbmVudCh0YWc6IHN0cmluZywgZ2xvYmFsczogS2V5VmFsdWUgPSB7fSk6IHZvaWQge1xuICAgIGNvbnN0IGNvbXBvbmVudCA9IE5neFJlbmRlcmluZ0VuZ2luZTIuY29tcG9uZW50cyh0YWcpXG4gICAgICA/LmNvbnN0cnVjdG9yIGFzIFR5cGU8dW5rbm93bj47XG4gICAgY29uc3QgbWV0YWRhdGEgPSByZWZsZWN0Q29tcG9uZW50VHlwZShjb21wb25lbnQpO1xuICAgIGNvbnN0IGNvbXBvbmVudElucHV0cyA9IChtZXRhZGF0YSBhcyBDb21wb25lbnRNaXJyb3I8dW5rbm93bj4pLmlucHV0cztcbiAgICBjb25zdCBwcm9wcyA9IGdsb2JhbHM/LlsnaXRlbSddIHx8IGdsb2JhbHM/LlsncHJvcHMnXSB8fCB7fTtcbiAgICBpZihwcm9wcz8uWyd0YWcnXSlcbiAgICAgIGRlbGV0ZSBwcm9wc1sndGFnJ107XG4gICAgY29uc3QgaW5wdXRLZXlzID0gT2JqZWN0LmtleXMocHJvcHMpO1xuICAgIGNvbnN0IHVubWFwcGVkS2V5cyA9IFtdO1xuXG4gICAgZm9yIChjb25zdCBpbnB1dCBvZiBpbnB1dEtleXMpIHtcbiAgICAgIGlmICghaW5wdXRLZXlzLmxlbmd0aCkgYnJlYWs7XG4gICAgICBjb25zdCBwcm9wID0gY29tcG9uZW50SW5wdXRzLmZpbmQoXG4gICAgICAgIChpdGVtOiB7IHByb3BOYW1lOiBzdHJpbmcgfSkgPT4gaXRlbS5wcm9wTmFtZSA9PT0gaW5wdXQsXG4gICAgICApO1xuICAgICAgaWYgKCFwcm9wKSB7XG4gICAgICAgIGRlbGV0ZSBwcm9wc1tpbnB1dF07XG4gICAgICAgIHVubWFwcGVkS2V5cy5wdXNoKGlucHV0KTtcbiAgICAgIH1cbiAgICB9XG4gICAgdGhpcy52Y3IuY2xlYXIoKTtcbiAgICB0aGlzLmNvbXBvbmVudCA9IE5neFJlbmRlcmluZ0VuZ2luZTIuY3JlYXRlQ29tcG9uZW50KFxuICAgICAgY29tcG9uZW50LFxuICAgICAgcHJvcHMsXG4gICAgICBtZXRhZGF0YSBhcyBDb21wb25lbnRNaXJyb3I8dW5rbm93bj4sXG4gICAgICB0aGlzLnZjcixcbiAgICAgIHRoaXMuaW5qZWN0b3IgYXMgSW5qZWN0b3IsXG4gICAgICBbXSxcbiAgICApO1xuICAgIHRoaXMuc3Vic2NyaWJlRXZlbnRzKCk7XG4gIH1cblxuICBjcmVhdGVQYXJlbnRDb21wb25lbnQoKSB7XG4gICAgY29uc3QgeyBjb21wb25lbnQsIGlucHV0cyB9ID0gdGhpcy5wYXJlbnQgYXMgS2V5VmFsdWU7XG4gICAgY29uc3QgbWV0YWRhdGEgPSByZWZsZWN0Q29tcG9uZW50VHlwZShjb21wb25lbnQpIGFzIENvbXBvbmVudE1pcnJvcjx1bmtub3duPjtcbiAgICBjb25zdCB0ZW1wbGF0ZSA9IHRoaXMudmNyLmNyZWF0ZUVtYmVkZGVkVmlldyh0aGlzLmlubmVyIGFzIFRlbXBsYXRlUmVmPHVua25vd24+LCB0aGlzLmluamVjdG9yKS5yb290Tm9kZXM7XG4gICAgdGhpcy5jb21wb25lbnQgPSBOZ3hSZW5kZXJpbmdFbmdpbmUyLmNyZWF0ZUNvbXBvbmVudChcbiAgICAgIGNvbXBvbmVudCxcbiAgICAgIGlucHV0cyxcbiAgICAgIG1ldGFkYXRhLFxuICAgICAgdGhpcy52Y3IsXG4gICAgICB0aGlzLmluamVjdG9yLFxuICAgICAgdGVtcGxhdGUsXG4gICAgKTtcbiAgICB0aGlzLnN1YnNjcmliZUV2ZW50cygpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBTdWJzY3JpYmVzIHRvIGV2ZW50cyBlbWl0dGVkIGJ5IHRoZSBkeW5hbWljIGNvbXBvbmVudC5cbiAgICogQHN1bW1hcnkgVGhpcyBtZXRob2Qgc2V0cyB1cCBzdWJzY3JpcHRpb25zIHRvIGFsbCBFdmVudEVtaXR0ZXIgcHJvcGVydGllcyBvZiB0aGVcbiAgICogZHluYW1pY2FsbHkgY3JlYXRlZCBjb21wb25lbnQuIFdoZW4gYW4gZXZlbnQgaXMgZW1pdHRlZCBieSB0aGUgZHluYW1pYyBjb21wb25lbnQsXG4gICAqIGl0IGlzIGNhcHR1cmVkIGFuZCByZS1lbWl0dGVkIHRocm91Z2ggdGhlIGxpc3RlbkV2ZW50IG91dHB1dCBwcm9wZXJ0eSB3aXRoIGFkZGl0aW9uYWxcbiAgICogbWV0YWRhdGEgYWJvdXQgdGhlIGV2ZW50IHNvdXJjZS5cbiAgICpcbiAgICogQG1lcm1haWRcbiAgICogc2VxdWVuY2VEaWFncmFtXG4gICAqICAgcGFydGljaXBhbnQgQyBhcyBDb21wb25lbnRSZW5kZXJlckNvbXBvbmVudFxuICAgKiAgIHBhcnRpY2lwYW50IEQgYXMgRHluYW1pYyBDb21wb25lbnRcbiAgICogICBwYXJ0aWNpcGFudCBQIGFzIFBhcmVudCBDb21wb25lbnRcbiAgICpcbiAgICogICBDLT4+Qzogc3Vic2NyaWJlRXZlbnRzKClcbiAgICogICBDLT4+RDogR2V0IGluc3RhbmNlIHByb3BlcnRpZXNcbiAgICogICBsb29wIEZvciBlYWNoIHByb3BlcnR5XG4gICAqICAgICBDLT4+QzogQ2hlY2sgaWYgcHJvcGVydHkgaXMgRXZlbnRFbWl0dGVyXG4gICAqICAgICBhbHQgaXMgRXZlbnRFbWl0dGVyXG4gICAqICAgICAgIEMtPj5EOiBTdWJzY3JpYmUgdG8gZXZlbnRcbiAgICogICAgICAgRC0tPj5DOiBFdmVudCBlbWl0dGVkXG4gICAqICAgICAgIEMtPj5QOiBSZS1lbWl0IGV2ZW50IHdpdGggbWV0YWRhdGFcbiAgICogICAgIGVuZFxuICAgKiAgIGVuZFxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcmV0dXJuIHt2b2lkfVxuICAgKiBAbWVtYmVyT2YgQ29tcG9uZW50UmVuZGVyZXJDb21wb25lbnRcbiAgICovXG4gIHByaXZhdGUgc3Vic2NyaWJlRXZlbnRzKCk6IHZvaWQge1xuICAgIGlmICh0aGlzLmNvbXBvbmVudCkge1xuICAgICAgY29uc3QgaW5zdGFuY2UgPSB0aGlzLmNvbXBvbmVudD8uaW5zdGFuY2UgYXMgS2V5VmFsdWU7XG4gICAgICBjb25zdCBjb21wb25lbnRLZXlzID0gT2JqZWN0LmtleXMoaW5zdGFuY2UpO1xuICAgICAgZm9yIChjb25zdCBrZXkgb2YgY29tcG9uZW50S2V5cykge1xuICAgICAgICBjb25zdCB2YWx1ZSA9IGluc3RhbmNlW2tleV07XG4gICAgICAgIGlmICh2YWx1ZSBpbnN0YW5jZW9mIEV2ZW50RW1pdHRlcilcbiAgICAgICAgICAoaW5zdGFuY2UgYXMgS2V5VmFsdWUpW2tleV0uc3Vic2NyaWJlKFxuICAgICAgICAgICAgKGV2ZW50OiBQYXJ0aWFsPEJhc2VDdXN0b21FdmVudD4pID0+IHtcbiAgICAgICAgICAgICAgdGhpcy5saXN0ZW5FdmVudC5lbWl0KHtcbiAgICAgICAgICAgICAgICBuYW1lOiBrZXksXG4gICAgICAgICAgICAgICAgLi4uZXZlbnQsXG4gICAgICAgICAgICAgIH0gYXMgUmVuZGVyZXJDdXN0b21FdmVudCk7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBVbnN1YnNjcmliZXMgZnJvbSBhbGwgZXZlbnRzIG9mIHRoZSBkeW5hbWljIGNvbXBvbmVudC5cbiAgICogQHN1bW1hcnkgVGhpcyBtZXRob2QgY2xlYW5zIHVwIGV2ZW50IHN1YnNjcmlwdGlvbnMgd2hlbiB0aGUgY29tcG9uZW50IGlzIGJlaW5nIGRlc3Ryb3llZC5cbiAgICogSXQgaXRlcmF0ZXMgdGhyb3VnaCBhbGwgcHJvcGVydGllcyBvZiB0aGUgZHluYW1pYyBjb21wb25lbnQgaW5zdGFuY2UgYW5kIHVuc3Vic2NyaWJlc1xuICAgKiBmcm9tIGFueSBFdmVudEVtaXR0ZXIgcHJvcGVydGllcyB0byBwcmV2ZW50IG1lbW9yeSBsZWFrcyBhbmQgdW5leHBlY3RlZCBiZWhhdmlvciBhZnRlclxuICAgKiB0aGUgY29tcG9uZW50IGlzIGRlc3Ryb3llZC5cbiAgICpcbiAgICogQG1lcm1haWRcbiAgICogc2VxdWVuY2VEaWFncmFtXG4gICAqICAgcGFydGljaXBhbnQgQyBhcyBDb21wb25lbnRSZW5kZXJlckNvbXBvbmVudFxuICAgKiAgIHBhcnRpY2lwYW50IEQgYXMgRHluYW1pYyBDb21wb25lbnRcbiAgICpcbiAgICogICBDLT4+QzogdW5zdWJzY3JpYmVFdmVudHMoKVxuICAgKiAgIEMtPj5EOiBHZXQgaW5zdGFuY2UgcHJvcGVydGllc1xuICAgKiAgIGxvb3AgRm9yIGVhY2ggcHJvcGVydHlcbiAgICogICAgIEMtPj5DOiBDaGVjayBpZiBwcm9wZXJ0eSBpcyBFdmVudEVtaXR0ZXJcbiAgICogICAgIGFsdCBpcyBFdmVudEVtaXR0ZXJcbiAgICogICAgICAgQy0+PkQ6IFVuc3Vic2NyaWJlIGZyb20gZXZlbnRcbiAgICogICAgIGVuZFxuICAgKiAgIGVuZFxuICAgKlxuICAgKiBAcHJpdmF0ZVxuICAgKiBAcmV0dXJuIHt2b2lkfVxuICAgKiBAbWVtYmVyT2YgQ29tcG9uZW50UmVuZGVyZXJDb21wb25lbnRcbiAgICovXG4gIHByaXZhdGUgdW5zdWJzY3JpYmVFdmVudHMoKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuY29tcG9uZW50KSB7XG4gICAgICBjb25zdCBpbnN0YW5jZSA9IHRoaXMuY29tcG9uZW50Py5pbnN0YW5jZSBhcyBLZXlWYWx1ZTtcbiAgICAgIGNvbnN0IGNvbXBvbmVudEtleXMgPSBPYmplY3Qua2V5cyhpbnN0YW5jZSk7XG4gICAgICBmb3IgKGNvbnN0IGtleSBvZiBjb21wb25lbnRLZXlzKSB7XG4gICAgICAgIGNvbnN0IHZhbHVlID0gaW5zdGFuY2Vba2V5XTtcbiAgICAgICAgaWYgKHZhbHVlIGluc3RhbmNlb2YgRXZlbnRFbWl0dGVyKSBpbnN0YW5jZVtrZXldLnVuc3Vic2NyaWJlKCk7XG4gICAgICB9XG4gICAgfVxuICB9XG59XG4iLCI8bmctdGVtcGxhdGUgI2NvbXBvbmVudFZpZXdDb250YWluZXI+PC9uZy10ZW1wbGF0ZT5cblxuPG5nLXRlbXBsYXRlICNpbm5lcj5cbiAgQGlmKHBhcmVudD8uY2hpbGRyZW4/Lmxlbmd0aCkge1xuICAgIEBmb3IoY2hpbGQgb2YgcGFyZW50LmNoaWxkcmVuOyB0cmFjayBjaGlsZCkge1xuICAgICAgICBAaWYoIWNoaWxkLmNoaWxkcmVuPy5sZW5ndGgpIHtcbiAgICAgICAgICA8bmctY29udGFpbmVyXG4gICAgICAgICAgICAgICAgKm5nQ29tcG9uZW50T3V0bGV0PVwiXG4gICAgICAgICAgICAgICAgICBjaGlsZC5jb21wb25lbnQ7XG4gICAgICAgICAgICAgICAgICBpbmplY3RvcjogY2hpbGQuaW5qZWN0b3I7XG4gICAgICAgICAgICAgICAgICBpbnB1dHM6IGNoaWxkLmlucHV0cztcbiAgICAgICAgICAgICAgICAgIGNvbnRlbnQ6Y2hpbGQuY29udGVudDtcbiAgICAgICAgICAgICAgICBcIlxuICAgICAgICAgIC8+XG4gICAgICAgIH0gQGVsc2Uge1xuICAgICAgICAgIDxuZ3gtZGVjYWYtY29tcG9uZW50LXJlbmRlcmVyIFtwYXJlbnRdPVwiY2hpbGRcIj4gPC9uZ3gtZGVjYWYtY29tcG9uZW50LXJlbmRlcmVyPlxuICAgICAgICB9XG4gICAgIH1cbiAgfVxuPC9uZy10ZW1wbGF0ZT5cblxuXG4iXX0=