UNPKG

@noaestudio/forms

Version:

Dynamic forms extension for Covalent

449 lines (448 loc) 31.1 kB
/** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ import { Component, Directive, Input, HostBinding, TemplateRef } from '@angular/core'; import { ViewChild, ViewContainerRef } from '@angular/core'; import { ComponentFactoryResolver, forwardRef } from '@angular/core'; import { NG_VALUE_ACCESSOR, FormControl } from '@angular/forms'; import { TemplatePortalDirective } from '@angular/cdk/portal'; import { TdDynamicFormsService } from './services/dynamic-forms.service'; import { AbstractControlValueAccessor } from './dynamic-elements/abstract-control-value-accesor'; const /** @type {?} */ noop = () => { // empty method }; const ɵ0 = noop; export const /** @type {?} */ ELEMENT_INPUT_CONTROL_VALUE_ACCESSOR = { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => TdDynamicElementComponent), multi: true, }; export class TdDynamicFormsErrorTemplate extends TemplatePortalDirective { /** * @param {?} templateRef * @param {?} viewContainerRef */ constructor(templateRef, viewContainerRef) { super(templateRef, viewContainerRef); } } TdDynamicFormsErrorTemplate.decorators = [ { type: Directive, args: [{ selector: '[tdDynamicFormsError]ng-template' },] }, ]; /** @nocollapse */ TdDynamicFormsErrorTemplate.ctorParameters = () => [ { type: TemplateRef, }, { type: ViewContainerRef, }, ]; TdDynamicFormsErrorTemplate.propDecorators = { "tdDynamicFormsError": [{ type: Input },], }; function TdDynamicFormsErrorTemplate_tsickle_Closure_declarations() { /** @type {!Array<{type: !Function, args: (undefined|!Array<?>)}>} */ TdDynamicFormsErrorTemplate.decorators; /** * @nocollapse * @type {function(): !Array<(null|{type: ?, decorators: (undefined|!Array<{type: !Function, args: (undefined|!Array<?>)}>)})>} */ TdDynamicFormsErrorTemplate.ctorParameters; /** @type {!Object<string,!Array<{type: !Function, args: (undefined|!Array<?>)}>>} */ TdDynamicFormsErrorTemplate.propDecorators; /** @type {?} */ TdDynamicFormsErrorTemplate.prototype.tdDynamicFormsError; } export class TdDynamicElementDirective { /** * @param {?} viewContainer */ constructor(viewContainer) { this.viewContainer = viewContainer; } } TdDynamicElementDirective.decorators = [ { type: Directive, args: [{ selector: '[tdDynamicContainer]', },] }, ]; /** @nocollapse */ TdDynamicElementDirective.ctorParameters = () => [ { type: ViewContainerRef, }, ]; function TdDynamicElementDirective_tsickle_Closure_declarations() { /** @type {!Array<{type: !Function, args: (undefined|!Array<?>)}>} */ TdDynamicElementDirective.decorators; /** * @nocollapse * @type {function(): !Array<(null|{type: ?, decorators: (undefined|!Array<{type: !Function, args: (undefined|!Array<?>)}>)})>} */ TdDynamicElementDirective.ctorParameters; /** @type {?} */ TdDynamicElementDirective.prototype.viewContainer; } export class TdDynamicElementComponent extends AbstractControlValueAccessor { /** * @param {?} _componentFactoryResolver * @param {?} _dynamicFormsService */ constructor(_componentFactoryResolver, _dynamicFormsService) { super(); this._componentFactoryResolver = _componentFactoryResolver; this._dynamicFormsService = _dynamicFormsService; /** * Sets label to be displayed. */ this.label = ''; /** * Sets type or element of element to be rendered. * Throws error if does not exist or no supported. */ this.type = undefined; /** * Sets required validation checkup (if supported by element). */ this.required = undefined; this.hidden = false; /** * Sets min validation checkup (if supported by element). */ this.min = undefined; /** * Sets max validation checkup (if supported by element). */ this.max = undefined; /** * Sets minLength validation checkup (if supported by element). */ this.minLength = undefined; /** * Sets maxLength validation checkup (if supported by element). */ this.maxLength = undefined; /** * Sets selections for array elements (if supported by element). */ this.selections = undefined; /** * Makes the select complex (if supported by element) */ this.selectComplex = false; /** * Makes the select multiple (if supported by element). */ this.selectMultiple = false; /** * Is the component searchable? (Tree selector only) */ this.searchable = false; /** * Flex for inputs that do not do flex automatically */ this.flex = 100; /** * Makes the components translatable */ this.translate = false; /** * Step for number inputs */ this.step = 1; /** * Generic delayed action for a button */ this.action = () => new Promise(resolve => { resolve({}); }); /** * Array hierarchical for render a tree */ this.treeItems = null; /** * Defines data structure for components wich renders flexible data */ this.schema = null; /** * Determinate if an item can be dragged */ this.draggable = false; /** * Allow pass meta info or functions that can be used by some components */ this.extras = null; /** * Extra fields for Organization. Could be used for other components. */ this.extraFields = []; this.chips = []; this.onModelChange = (_) => noop; } /** * @param {?} v * @return {?} */ set value(v) { if (v !== this._value) { this._value = v; this.onChange(v); this.onModelChange(v); } } /** * @return {?} */ get value() { return this._value; } /** * @return {?} */ get maxAttr() { return this.max; } /** * @return {?} */ get minAttr() { return this.min; } /** * @return {?} */ get stepAttr() { return this.step; } /** * @return {?} */ ngOnInit() { let /** @type {?} */ ref = this._componentFactoryResolver .resolveComponentFactory(this._dynamicFormsService.getDynamicElement(this.type, this.translate)) .create(this.childElement.viewContainer.injector); this.childElement.viewContainer.insert(ref.hostView); this._instance = ref.instance; this._instance.control = this.dynamicControl; this._instance.label = this.label; this._instance.type = this.type; this._instance.value = this.value; this._instance.required = this.required; this._instance.hidden = this.hidden; this._instance.min = this.min; this._instance.max = this.max; this._instance.minLength = this.minLength; this._instance.maxLength = this.maxLength; this._instance.selections = this.selections; this._instance.flex = this.flex; this._instance.selectComplex = this.selectComplex; this._instance.selectMultiple = this.selectMultiple; this._instance.searchable = this.searchable; this._instance.translate = this.translate; this._instance.step = this.step; this._instance.treeItems = this.treeItems; this._instance.action = this.action; this._instance.schema = this.schema; this._instance.draggable = this.draggable; this._instance.extras = this.extras; this._instance.extraFields = this.extraFields; this._instance.chips = this.chips; this._instance.registerOnChange((value) => { this.value = value; }); this.registerOnModelChange((value) => { // fix to check if value is NaN (type=number) if (!Number.isNaN(value)) { this._instance.value = value; } }); } /** * Reassign any inputs that have changed * @param {?} changes * @return {?} */ ngOnChanges(changes) { if (this._instance) { for (let /** @type {?} */ prop in changes) { this._instance[prop] = changes[prop].currentValue; } } } /** * Implemented as part of ControlValueAccessor. * @param {?} fn * @return {?} */ registerOnModelChange(fn) { this.onModelChange = fn; } } TdDynamicElementComponent.decorators = [ { type: Component, args: [{ providers: [TdDynamicFormsService, ELEMENT_INPUT_CONTROL_VALUE_ACCESSOR], selector: 'td-dynamic-element', template: '<div tdDynamicContainer></div>', },] }, ]; /** @nocollapse */ TdDynamicElementComponent.ctorParameters = () => [ { type: ComponentFactoryResolver, }, { type: TdDynamicFormsService, }, ]; TdDynamicElementComponent.propDecorators = { "dynamicControl": [{ type: Input },], "label": [{ type: Input },], "type": [{ type: Input },], "required": [{ type: Input },], "hidden": [{ type: Input },], "min": [{ type: Input },], "max": [{ type: Input },], "minLength": [{ type: Input },], "maxLength": [{ type: Input },], "selections": [{ type: Input },], "selectComplex": [{ type: Input },], "selectMultiple": [{ type: Input },], "searchable": [{ type: Input },], "flex": [{ type: Input },], "translate": [{ type: Input },], "step": [{ type: Input },], "action": [{ type: Input },], "treeItems": [{ type: Input },], "schema": [{ type: Input },], "draggable": [{ type: Input },], "extras": [{ type: Input },], "extraFields": [{ type: Input },], "chips": [{ type: Input },], "childElement": [{ type: ViewChild, args: [TdDynamicElementDirective,] },], "maxAttr": [{ type: HostBinding, args: ['attr.max',] },], "minAttr": [{ type: HostBinding, args: ['attr.min',] },], "stepAttr": [{ type: HostBinding, args: ['attr.step',] },], }; function TdDynamicElementComponent_tsickle_Closure_declarations() { /** @type {!Array<{type: !Function, args: (undefined|!Array<?>)}>} */ TdDynamicElementComponent.decorators; /** * @nocollapse * @type {function(): !Array<(null|{type: ?, decorators: (undefined|!Array<{type: !Function, args: (undefined|!Array<?>)}>)})>} */ TdDynamicElementComponent.ctorParameters; /** @type {!Object<string,!Array<{type: !Function, args: (undefined|!Array<?>)}>>} */ TdDynamicElementComponent.propDecorators; /** @type {?} */ TdDynamicElementComponent.prototype._instance; /** * Sets form control of the element. * @type {?} */ TdDynamicElementComponent.prototype.dynamicControl; /** * Sets label to be displayed. * @type {?} */ TdDynamicElementComponent.prototype.label; /** * Sets type or element of element to be rendered. * Throws error if does not exist or no supported. * @type {?} */ TdDynamicElementComponent.prototype.type; /** * Sets required validation checkup (if supported by element). * @type {?} */ TdDynamicElementComponent.prototype.required; /** @type {?} */ TdDynamicElementComponent.prototype.hidden; /** * Sets min validation checkup (if supported by element). * @type {?} */ TdDynamicElementComponent.prototype.min; /** * Sets max validation checkup (if supported by element). * @type {?} */ TdDynamicElementComponent.prototype.max; /** * Sets minLength validation checkup (if supported by element). * @type {?} */ TdDynamicElementComponent.prototype.minLength; /** * Sets maxLength validation checkup (if supported by element). * @type {?} */ TdDynamicElementComponent.prototype.maxLength; /** * Sets selections for array elements (if supported by element). * @type {?} */ TdDynamicElementComponent.prototype.selections; /** * Makes the select complex (if supported by element) * @type {?} */ TdDynamicElementComponent.prototype.selectComplex; /** * Makes the select multiple (if supported by element). * @type {?} */ TdDynamicElementComponent.prototype.selectMultiple; /** * Is the component searchable? (Tree selector only) * @type {?} */ TdDynamicElementComponent.prototype.searchable; /** * Flex for inputs that do not do flex automatically * @type {?} */ TdDynamicElementComponent.prototype.flex; /** * Makes the components translatable * @type {?} */ TdDynamicElementComponent.prototype.translate; /** * Step for number inputs * @type {?} */ TdDynamicElementComponent.prototype.step; /** * Generic delayed action for a button * @type {?} */ TdDynamicElementComponent.prototype.action; /** * Array hierarchical for render a tree * @type {?} */ TdDynamicElementComponent.prototype.treeItems; /** * Defines data structure for components wich renders flexible data * @type {?} */ TdDynamicElementComponent.prototype.schema; /** * Determinate if an item can be dragged * @type {?} */ TdDynamicElementComponent.prototype.draggable; /** * Allow pass meta info or functions that can be used by some components * @type {?} */ TdDynamicElementComponent.prototype.extras; /** * Extra fields for Organization. Could be used for other components. * @type {?} */ TdDynamicElementComponent.prototype.extraFields; /** @type {?} */ TdDynamicElementComponent.prototype.chips; /** @type {?} */ TdDynamicElementComponent.prototype.childElement; /** @type {?} */ TdDynamicElementComponent.prototype.onModelChange; /** @type {?} */ TdDynamicElementComponent.prototype._componentFactoryResolver; /** @type {?} */ TdDynamicElementComponent.prototype._dynamicFormsService; } export { ɵ0 }; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZHluYW1pYy1lbGVtZW50LmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiJuZzovL0Bjb3ZhbGVudC9keW5hbWljLWZvcm1zLyIsInNvdXJjZXMiOlsiZHluYW1pYy1lbGVtZW50LmNvbXBvbmVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7O0FBQUEsT0FBTyxFQUFFLFNBQVMsRUFBRSxTQUFTLEVBQUUsS0FBSyxFQUFFLFdBQVcsRUFBb0MsV0FBVyxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ3hILE9BQU8sRUFBRSxTQUFTLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDNUQsT0FBTyxFQUFFLHdCQUF3QixFQUFnQixVQUFVLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDbkYsT0FBTyxFQUF3QixpQkFBaUIsRUFBRSxXQUFXLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUN0RixPQUFPLEVBQUUsdUJBQXVCLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUU5RCxPQUFPLEVBQW1DLHFCQUFxQixFQUFFLE1BQU0sa0NBQWtDLENBQUM7QUFDMUcsT0FBTyxFQUFFLDRCQUE0QixFQUFFLE1BQU0sbURBQW1ELENBQUM7QUFFakcsdUJBQU0sSUFBSSxHQUFRLEdBQUcsRUFBRTs7Q0FFdEIsQ0FBQzs7QUFFRixNQUFNLENBQUMsdUJBQU0sb0NBQW9DLEdBQVE7SUFDeEQsT0FBTyxFQUFFLGlCQUFpQjtJQUMxQixXQUFXLEVBQUUsVUFBVSxDQUFDLEdBQUcsRUFBRSxDQUFDLHlCQUF5QixDQUFDO0lBQ3hELEtBQUssRUFBRSxJQUFJO0NBQ1gsQ0FBQztBQUdGLE1BQU0sa0NBQW1DLFNBQVEsdUJBQXVCOzs7OztJQUd2RSxZQUFZLFdBQTZCLEVBQUUsZ0JBQWtDO1FBQzVFLEtBQUssQ0FBQyxXQUFXLEVBQUUsZ0JBQWdCLENBQUMsQ0FBQztLQUNyQzs7O1lBTkQsU0FBUyxTQUFDLEVBQUMsUUFBUSxFQUFFLGtDQUFrQyxFQUFDOzs7O1lBbkI0QixXQUFXO1lBQzVFLGdCQUFnQjs7O29DQXFCbEMsS0FBSzs7Ozs7Ozs7Ozs7Ozs7O0FBU1AsTUFBTTs7OztJQUNMLFlBQW1CLGFBQStCO1FBQS9CLGtCQUFhLEdBQWIsYUFBYSxDQUFrQjtLQUFLOzs7WUFKdkQsU0FBUyxTQUFDO2dCQUNWLFFBQVEsRUFBRSxzQkFBc0I7YUFDaEM7Ozs7WUE3Qm1CLGdCQUFnQjs7Ozs7Ozs7Ozs7OztBQXVDcEMsTUFBTSxnQ0FBaUMsU0FBUSw0QkFBNEI7Ozs7O0lBOEkxRSxZQUFvQix5QkFBbUQsRUFDOUQ7UUFDUCxLQUFLLEVBQUUsQ0FBQztRQUZVLDhCQUF5QixHQUF6Qix5QkFBeUIsQ0FBMEI7UUFDOUQseUJBQW9CLEdBQXBCLG9CQUFvQjs7OztxQkF4SEosRUFBRTs7Ozs7b0JBTXVCLFNBQVM7Ozs7d0JBSzlCLFNBQVM7c0JBRVYsS0FBSzs7OzttQkFLVixTQUFTOzs7O21CQUtULFNBQVM7Ozs7eUJBS0gsU0FBUzs7Ozt5QkFLVCxTQUFTOzs7OzBCQUtULFNBQVM7Ozs7NkJBS0gsS0FBSzs7Ozs4QkFLSixLQUFLOzs7OzBCQUtULEtBQUs7Ozs7b0JBS1osR0FBRzs7Ozt5QkFLRyxLQUFLOzs7O29CQUtYLENBQUM7Ozs7c0JBS2EsR0FBRyxFQUFFLENBQUMsSUFBSSxPQUFPLENBQU0sT0FBTyxDQUFDLEVBQUUsR0FBRyxPQUFPLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDOzs7O3lCQUsvRCxJQUFJOzs7O3NCQUtQLElBQUk7Ozs7eUJBS0csS0FBSzs7OztzQkFLWixJQUFJOzs7OzJCQUtNLEVBQUU7cUJBRVgsRUFBRTs2QkFxRlgsQ0FBQyxDQUFNLEVBQUUsRUFBRSxDQUFDLElBQUk7S0EvRDlCOzs7OztJQTdJRixJQUFJLEtBQUssQ0FBQyxDQUFNO1FBQ2YsRUFBRSxDQUFDLENBQUMsQ0FBQyxLQUFLLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDO1lBQ3ZCLElBQUksQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDO1lBQ2hCLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDakIsSUFBSSxDQUFDLGFBQWEsQ0FBQyxDQUFDLENBQUMsQ0FBQztTQUN0QjtLQUNEOzs7O0lBQ0QsSUFBSSxLQUFLO1FBQ1IsTUFBTSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUM7S0FDbkI7Ozs7UUFtSEcsT0FBTztRQUNWLE1BQU0sQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDOzs7OztRQUliLE9BQU87UUFDVixNQUFNLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQzs7Ozs7UUFJYixRQUFRO1FBQ1gsTUFBTSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUM7Ozs7O0lBUWpCLFFBQVE7UUFDUCxxQkFBSSxHQUFHLEdBQXNCLElBQUksQ0FBQyx5QkFBeUI7YUFDekQsdUJBQXVCLENBQUMsSUFBSSxDQUFDLG9CQUFvQixDQUFDLGlCQUFpQixDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDO2FBQzlGLE1BQU0sQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLGFBQWEsQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUNuRCxJQUFJLENBQUMsWUFBWSxDQUFDLGFBQWEsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLFFBQVEsQ0FBQyxDQUFDO1FBQ3JELElBQUksQ0FBQyxTQUFTLEdBQUcsR0FBRyxDQUFDLFFBQVEsQ0FBQztRQUM5QixJQUFJLENBQUMsU0FBUyxDQUFDLE9BQU8sR0FBRyxJQUFJLENBQUMsY0FBYyxDQUFDO1FBQzdDLElBQUksQ0FBQyxTQUFTLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUM7UUFDbEMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQztRQUNoQyxJQUFJLENBQUMsU0FBUyxDQUFDLEtBQUssR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDO1FBQ2xDLElBQUksQ0FBQyxTQUFTLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUM7UUFDeEMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxNQUFNLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQztRQUNwQyxJQUFJLENBQUMsU0FBUyxDQUFDLEdBQUcsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDO1FBQzlCLElBQUksQ0FBQyxTQUFTLENBQUMsR0FBRyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUM7UUFDOUIsSUFBSSxDQUFDLFNBQVMsQ0FBQyxTQUFTLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQztRQUMxQyxJQUFJLENBQUMsU0FBUyxDQUFDLFNBQVMsR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDO1FBQzFDLElBQUksQ0FBQyxTQUFTLENBQUMsVUFBVSxHQUFHLElBQUksQ0FBQyxVQUFVLENBQUM7UUFDNUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQztRQUNoQyxJQUFJLENBQUMsU0FBUyxDQUFDLGFBQWEsR0FBRyxJQUFJLENBQUMsYUFBYSxDQUFDO1FBQ2xELElBQUksQ0FBQyxTQUFTLENBQUMsY0FBYyxHQUFHLElBQUksQ0FBQyxjQUFjLENBQUM7UUFDcEQsSUFBSSxDQUFDLFNBQVMsQ0FBQyxVQUFVLEdBQUcsSUFBSSxDQUFDLFVBQVUsQ0FBQztRQUM1QyxJQUFJLENBQUMsU0FBUyxDQUFDLFNBQVMsR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDO1FBQzFDLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUM7UUFDaEMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxTQUFTLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQztRQUMxQyxJQUFJLENBQUMsU0FBUyxDQUFDLE1BQU0sR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDO1FBQ3BDLElBQUksQ0FBQyxTQUFTLENBQUMsTUFBTSxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUM7UUFDcEMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxTQUFTLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQztRQUMxQyxJQUFJLENBQUMsU0FBUyxDQUFDLE1BQU0sR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDO1FBQ3BDLElBQUksQ0FBQyxTQUFTLENBQUMsV0FBVyxHQUFHLElBQUksQ0FBQyxXQUFXLENBQUM7UUFDOUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQztRQUVsQyxJQUFJLENBQUMsU0FBUyxDQUFDLGdCQUFnQixDQUFDLENBQUMsS0FBVSxFQUFFLEVBQUU7WUFDOUMsSUFBSSxDQUFDLEtBQUssR0FBRyxLQUFLLENBQUM7U0FDbkIsQ0FBQyxDQUFDO1FBQ0gsSUFBSSxDQUFDLHFCQUFxQixDQUFDLENBQUMsS0FBVSxFQUFFLEVBQUU7O1lBRXpDLEVBQUUsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7Z0JBQzFCLElBQUksQ0FBQyxTQUFTLENBQUMsS0FBSyxHQUFHLEtBQUssQ0FBQzthQUM3QjtTQUVELENBQUMsQ0FBQztLQUNIOzs7Ozs7SUFLRixXQUFXLENBQUMsT0FBc0I7UUFDakMsRUFBRSxDQUFDLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUM7WUFDcEIsR0FBRyxDQUFDLENBQUMscUJBQUksSUFBSSxJQUFJLE9BQU8sQ0FBQyxDQUFDLENBQUM7Z0JBQzFCLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLEdBQUcsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDLFlBQVksQ0FBQzthQUNsRDtTQUNEO0tBQ0Q7Ozs7OztJQUtELHFCQUFxQixDQUFDLEVBQU87UUFDNUIsSUFBSSxDQUFDLGFBQWEsR0FBRyxFQUFFLENBQUM7S0FDeEI7OztZQW5ORCxTQUFTLFNBQUM7Z0JBQ1YsU0FBUyxFQUFFLENBQUUscUJBQXFCLEVBQUUsb0NBQW9DLENBQUU7Z0JBQzFFLFFBQVEsRUFBRSxvQkFBb0I7Z0JBQzlCLFFBQVEsRUFBRSxnQ0FBZ0M7YUFDMUM7Ozs7WUFyQ1Esd0JBQXdCO1lBSVMscUJBQXFCOzs7K0JBb0Q3RCxLQUFLO3NCQUtMLEtBQUs7cUJBTUwsS0FBSzt5QkFLTCxLQUFLO3VCQUVMLEtBQUs7b0JBS0wsS0FBSztvQkFLTCxLQUFLOzBCQUtMLEtBQUs7MEJBS0wsS0FBSzsyQkFLTCxLQUFLOzhCQUtMLEtBQUs7K0JBS0wsS0FBSzsyQkFLTCxLQUFLO3FCQUtMLEtBQUs7MEJBS0wsS0FBSztxQkFLTCxLQUFLO3VCQUtMLEtBQUs7MEJBS0wsS0FBSzt1QkFLTCxLQUFLOzBCQUtMLEtBQUs7dUJBS0wsS0FBSzs0QkFLTCxLQUFLO3NCQUVMLEtBQUs7NkJBRUwsU0FBUyxTQUFDLHlCQUF5Qjt3QkFFbkMsV0FBVyxTQUFDLFVBQVU7d0JBS3RCLFdBQVcsU0FBQyxVQUFVO3lCQUt0QixXQUFXLFNBQUMsV0FBVyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbXBvbmVudCwgRGlyZWN0aXZlLCBJbnB1dCwgSG9zdEJpbmRpbmcsIE9uSW5pdCwgU2ltcGxlQ2hhbmdlcywgT25DaGFuZ2VzLCBUZW1wbGF0ZVJlZiB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5pbXBvcnQgeyBWaWV3Q2hpbGQsIFZpZXdDb250YWluZXJSZWYgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuaW1wb3J0IHsgQ29tcG9uZW50RmFjdG9yeVJlc29sdmVyLCBDb21wb25lbnRSZWYsIGZvcndhcmRSZWYgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuaW1wb3J0IHsgQ29udHJvbFZhbHVlQWNjZXNzb3IsIE5HX1ZBTFVFX0FDQ0VTU09SLCBGb3JtQ29udHJvbCB9IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcclxuaW1wb3J0IHsgVGVtcGxhdGVQb3J0YWxEaXJlY3RpdmUgfSBmcm9tICdAYW5ndWxhci9jZGsvcG9ydGFsJztcclxuXHJcbmltcG9ydCB7IFRkRHluYW1pY0VsZW1lbnQsIFRkRHluYW1pY1R5cGUsIFRkRHluYW1pY0Zvcm1zU2VydmljZSB9IGZyb20gJy4vc2VydmljZXMvZHluYW1pYy1mb3Jtcy5zZXJ2aWNlJztcclxuaW1wb3J0IHsgQWJzdHJhY3RDb250cm9sVmFsdWVBY2Nlc3NvciB9IGZyb20gJy4vZHluYW1pYy1lbGVtZW50cy9hYnN0cmFjdC1jb250cm9sLXZhbHVlLWFjY2Vzb3InO1xyXG5cclxuY29uc3Qgbm9vcDogYW55ID0gKCkgPT4ge1xyXG5cdC8vIGVtcHR5IG1ldGhvZFxyXG59O1xyXG5cclxuZXhwb3J0IGNvbnN0IEVMRU1FTlRfSU5QVVRfQ09OVFJPTF9WQUxVRV9BQ0NFU1NPUjogYW55ID0ge1xyXG5cdHByb3ZpZGU6IE5HX1ZBTFVFX0FDQ0VTU09SLFxyXG5cdHVzZUV4aXN0aW5nOiBmb3J3YXJkUmVmKCgpID0+IFRkRHluYW1pY0VsZW1lbnRDb21wb25lbnQpLFxyXG5cdG11bHRpOiB0cnVlLFxyXG59O1xyXG5cclxuQERpcmVjdGl2ZSh7c2VsZWN0b3I6ICdbdGREeW5hbWljRm9ybXNFcnJvcl1uZy10ZW1wbGF0ZSd9KVxyXG5leHBvcnQgY2xhc3MgVGREeW5hbWljRm9ybXNFcnJvclRlbXBsYXRlIGV4dGVuZHMgVGVtcGxhdGVQb3J0YWxEaXJlY3RpdmUge1xyXG5cclxuXHRASW5wdXQoKSB0ZER5bmFtaWNGb3Jtc0Vycm9yOiBzdHJpbmc7XHJcblx0Y29uc3RydWN0b3IodGVtcGxhdGVSZWY6IFRlbXBsYXRlUmVmPGFueT4sIHZpZXdDb250YWluZXJSZWY6IFZpZXdDb250YWluZXJSZWYpIHtcclxuXHRcdHN1cGVyKHRlbXBsYXRlUmVmLCB2aWV3Q29udGFpbmVyUmVmKTtcclxuXHR9XHJcbn1cclxuXHJcbkBEaXJlY3RpdmUoe1xyXG5cdHNlbGVjdG9yOiAnW3RkRHluYW1pY0NvbnRhaW5lcl0nLFxyXG59KVxyXG5leHBvcnQgY2xhc3MgVGREeW5hbWljRWxlbWVudERpcmVjdGl2ZSB7XHJcblx0Y29uc3RydWN0b3IocHVibGljIHZpZXdDb250YWluZXI6IFZpZXdDb250YWluZXJSZWYpIHsgfVxyXG59XHJcblxyXG5AQ29tcG9uZW50KHtcclxuXHRwcm92aWRlcnM6IFsgVGREeW5hbWljRm9ybXNTZXJ2aWNlLCBFTEVNRU5UX0lOUFVUX0NPTlRST0xfVkFMVUVfQUNDRVNTT1IgXSxcclxuXHRzZWxlY3RvcjogJ3RkLWR5bmFtaWMtZWxlbWVudCcsXHJcblx0dGVtcGxhdGU6ICc8ZGl2IHRkRHluYW1pY0NvbnRhaW5lcj48L2Rpdj4nLFxyXG59KVxyXG5leHBvcnQgY2xhc3MgVGREeW5hbWljRWxlbWVudENvbXBvbmVudCBleHRlbmRzIEFic3RyYWN0Q29udHJvbFZhbHVlQWNjZXNzb3IgaW1wbGVtZW50cyBDb250cm9sVmFsdWVBY2Nlc3NvciwgT25Jbml0LCBPbkNoYW5nZXMge1xyXG5cclxuXHRwcml2YXRlIF9pbnN0YW5jZTogYW55O1xyXG5cclxuXHRzZXQgdmFsdWUodjogYW55KSB7XHJcblx0XHRpZiAodiAhPT0gdGhpcy5fdmFsdWUpIHtcclxuXHRcdFx0dGhpcy5fdmFsdWUgPSB2O1xyXG5cdFx0XHR0aGlzLm9uQ2hhbmdlKHYpO1xyXG5cdFx0XHR0aGlzLm9uTW9kZWxDaGFuZ2Uodik7XHJcblx0XHR9XHJcblx0fVxyXG5cdGdldCB2YWx1ZSgpOiBhbnkge1xyXG5cdFx0cmV0dXJuIHRoaXMuX3ZhbHVlO1xyXG5cdH1cclxuXHJcblx0LyoqXHJcblx0KiBTZXRzIGZvcm0gY29udHJvbCBvZiB0aGUgZWxlbWVudC5cclxuXHQqL1xyXG5cdEBJbnB1dCgpIGR5bmFtaWNDb250cm9sOiBGb3JtQ29udHJvbDtcclxuXHJcblx0LyoqXHJcblx0KiBTZXRzIGxhYmVsIHRvIGJlIGRpc3BsYXllZC5cclxuXHQqL1xyXG5cdEBJbnB1dCgpIGxhYmVsOiBzdHJpbmcgPSAnJztcclxuXHJcblx0LyoqXHJcblx0KiBTZXRzIHR5cGUgb3IgZWxlbWVudCBvZiBlbGVtZW50IHRvIGJlIHJlbmRlcmVkLlxyXG5cdCogVGhyb3dzIGVycm9yIGlmIGRvZXMgbm90IGV4aXN0IG9yIG5vIHN1cHBvcnRlZC5cclxuXHQqL1xyXG5cdEBJbnB1dCgpIHR5cGU6IFRkRHluYW1pY0VsZW1lbnQgfCBUZER5bmFtaWNUeXBlID0gdW5kZWZpbmVkO1xyXG5cclxuXHQvKipcclxuXHQqIFNldHMgcmVxdWlyZWQgdmFsaWRhdGlvbiBjaGVja3VwIChpZiBzdXBwb3J0ZWQgYnkgZWxlbWVudCkuXHJcblx0Ki9cclxuXHRASW5wdXQoKSByZXF1aXJlZDogYm9vbGVhbiA9IHVuZGVmaW5lZDtcclxuXHJcblx0QElucHV0KCkgaGlkZGVuIDogYm9vbGVhbiA9IGZhbHNlO1xyXG5cclxuXHQvKipcclxuXHQqIFNldHMgbWluIHZhbGlkYXRpb24gY2hlY2t1cCAoaWYgc3VwcG9ydGVkIGJ5IGVsZW1lbnQpLlxyXG5cdCovXHJcblx0QElucHV0KCkgbWluOiBudW1iZXIgPSB1bmRlZmluZWQ7XHJcblxyXG5cdC8qKlxyXG5cdCogU2V0cyBtYXggdmFsaWRhdGlvbiBjaGVja3VwIChpZiBzdXBwb3J0ZWQgYnkgZWxlbWVudCkuXHJcblx0Ki9cclxuXHRASW5wdXQoKSBtYXg6IG51bWJlciA9IHVuZGVmaW5lZDtcclxuXHJcblx0LyoqXHJcblx0KiBTZXRzIG1pbkxlbmd0aCB2YWxpZGF0aW9uIGNoZWNrdXAgKGlmIHN1cHBvcnRlZCBieSBlbGVtZW50KS5cclxuXHQqL1xyXG5cdEBJbnB1dCgpIG1pbkxlbmd0aDogbnVtYmVyID0gdW5kZWZpbmVkO1xyXG5cclxuXHQvKipcclxuXHQqIFNldHMgbWF4TGVuZ3RoIHZhbGlkYXRpb24gY2hlY2t1cCAoaWYgc3VwcG9ydGVkIGJ5IGVsZW1lbnQpLlxyXG5cdCovXHJcblx0QElucHV0KCkgbWF4TGVuZ3RoOiBudW1iZXIgPSB1bmRlZmluZWQ7XHJcblxyXG5cdC8qKlxyXG5cdCogU2V0cyBzZWxlY3Rpb25zIGZvciBhcnJheSBlbGVtZW50cyAoaWYgc3VwcG9ydGVkIGJ5IGVsZW1lbnQpLlxyXG5cdCovXHJcblx0QElucHV0KCkgc2VsZWN0aW9uczogYW55W10gPSB1bmRlZmluZWQ7XHJcblxyXG5cdC8qKlxyXG5cdCogTWFrZXMgdGhlIHNlbGVjdCBjb21wbGV4IChpZiBzdXBwb3J0ZWQgYnkgZWxlbWVudClcclxuXHQqL1xyXG5cdEBJbnB1dCgpIHNlbGVjdENvbXBsZXggOiBib29sZWFuID0gZmFsc2U7XHJcblxyXG5cdC8qKlxyXG5cdCogTWFrZXMgdGhlIHNlbGVjdCBtdWx0aXBsZSAoaWYgc3VwcG9ydGVkIGJ5IGVsZW1lbnQpLlxyXG5cdCovXHJcblx0QElucHV0KCkgc2VsZWN0TXVsdGlwbGUgOiBib29sZWFuID0gZmFsc2U7XHJcblxyXG5cdC8qKlxyXG5cdCogSXMgdGhlIGNvbXBvbmVudCBzZWFyY2hhYmxlPyAoVHJlZSBzZWxlY3RvciBvbmx5KVxyXG5cdCovXHJcblx0QElucHV0KCkgc2VhcmNoYWJsZSA6IGJvb2xlYW4gPSBmYWxzZTtcclxuXHJcblx0LyoqXHJcblx0KiBGbGV4IGZvciBpbnB1dHMgdGhhdCBkbyBub3QgZG8gZmxleCBhdXRvbWF0aWNhbGx5XHJcblx0Ki9cclxuXHRASW5wdXQoKSBmbGV4IDogbnVtYmVyID0gMTAwO1xyXG5cclxuXHQvKipcclxuXHQqIE1ha2VzIHRoZSBjb21wb25lbnRzIHRyYW5zbGF0YWJsZVxyXG5cdCovXHJcblx0QElucHV0KCkgdHJhbnNsYXRlIDogYm9vbGVhbiA9IGZhbHNlO1xyXG5cclxuXHQvKipcclxuXHQqIFN0ZXAgZm9yIG51bWJlciBpbnB1dHNcclxuXHQqL1xyXG5cdEBJbnB1dCgpIHN0ZXAgOiBudW1iZXIgPSAxO1xyXG5cclxuXHQvKipcclxuXHQqIEdlbmVyaWMgZGVsYXllZCBhY3Rpb24gZm9yIGEgYnV0dG9uXHJcblx0Ki9cclxuXHRASW5wdXQoKSBhY3Rpb24gOiAoKSA9PiBQcm9taXNlPGFueT4gPSAoKSA9PiBuZXcgUHJvbWlzZTxhbnk+KHJlc29sdmUgPT4geyByZXNvbHZlKHt9KTsgfSkgO1xyXG5cclxuXHQvKipcclxuXHQqIEFycmF5IGhpZXJhcmNoaWNhbCBmb3IgcmVuZGVyIGEgdHJlZVxyXG5cdCovXHJcblx0QElucHV0KCkgdHJlZUl0ZW1zIDogYW55ID0gbnVsbDtcclxuXHJcblx0LyoqXHJcblx0KiBEZWZpbmVzIGRhdGEgc3RydWN0dXJlIGZvciBjb21wb25lbnRzIHdpY2ggcmVuZGVycyBmbGV4aWJsZSBkYXRhXHJcblx0Ki9cclxuXHRASW5wdXQoKSBzY2hlbWEgOiBhbnkgPSBudWxsO1xyXG5cclxuXHQvKipcclxuXHQqIERldGVybWluYXRlIGlmIGFuIGl0ZW0gY2FuIGJlIGRyYWdnZWRcclxuXHQqL1xyXG5cdEBJbnB1dCgpIGRyYWdnYWJsZSA6IGJvb2xlYW4gPSBmYWxzZTtcclxuXHJcblx0LyoqXHJcblx0KiBBbGxvdyBwYXNzIG1ldGEgaW5mbyBvciBmdW5jdGlvbnMgdGhhdCBjYW4gYmUgdXNlZCBieSBzb21lIGNvbXBvbmVudHNcclxuXHQqL1xyXG5cdEBJbnB1dCgpIGV4dHJhcyA6IGFueSA9IG51bGw7XHJcblxyXG5cdC8qKlxyXG5cdCogRXh0cmEgZmllbGRzIGZvciBPcmdhbml6YXRpb24uIENvdWxkIGJlIHVzZWQgZm9yIG90aGVyIGNvbXBvbmVudHMuXHJcblx0Ki9cclxuXHRASW5wdXQoKSBleHRyYUZpZWxkcyA6IHN0cmluZ1tdID0gW107XHJcblxyXG5cdEBJbnB1dCgpIGNoaXBzIDogYW55W10gPSBbXTtcclxuXHJcblx0QFZpZXdDaGlsZChUZER5bmFtaWNFbGVtZW50RGlyZWN0aXZlKSBjaGlsZEVsZW1lbnQ6IFRkRHluYW1pY0VsZW1lbnREaXJlY3RpdmU7XHJcblxyXG5cdEBIb3N0QmluZGluZygnYXR0ci5tYXgnKVxyXG5cdGdldCBtYXhBdHRyKCk6IGFueSB7XHJcblx0XHRyZXR1cm4gdGhpcy5tYXg7XHJcblx0fVxyXG5cclxuXHRASG9zdEJpbmRpbmcoJ2F0dHIubWluJylcclxuXHRnZXQgbWluQXR0cigpOiBhbnkge1xyXG5cdFx0cmV0dXJuIHRoaXMubWluO1xyXG5cdH1cclxuXHJcblx0QEhvc3RCaW5kaW5nKCdhdHRyLnN0ZXAnKVxyXG5cdGdldCBzdGVwQXR0cigpOiBhbnkge1xyXG5cdFx0cmV0dXJuIHRoaXMuc3RlcDtcclxuXHR9XHJcblxyXG5cdGNvbnN0cnVjdG9yKHByaXZhdGUgX2NvbXBvbmVudEZhY3RvcnlSZXNvbHZlcjogQ29tcG9uZW50RmFjdG9yeVJlc29sdmVyLFxyXG5cdFx0cHJpdmF0ZSBfZHluYW1pY0Zvcm1zU2VydmljZTogVGREeW5hbWljRm9ybXNTZXJ2aWNlKSB7XHJcblx0XHRcdHN1cGVyKCk7XHJcblx0XHR9XHJcblxyXG5cdFx0bmdPbkluaXQoKTogdm9pZCB7XHJcblx0XHRcdGxldCByZWY6IENvbXBvbmVudFJlZjxhbnk+ID0gdGhpcy5fY29tcG9uZW50RmFjdG9yeVJlc29sdmVyXHJcblx0XHRcdFx0LnJlc29sdmVDb21wb25lbnRGYWN0b3J5KHRoaXMuX2R5bmFtaWNGb3Jtc1NlcnZpY2UuZ2V0RHluYW1pY0VsZW1lbnQodGhpcy50eXBlLHRoaXMudHJhbnNsYXRlKSlcclxuXHRcdFx0XHQuY3JlYXRlKHRoaXMuY2hpbGRFbGVtZW50LnZpZXdDb250YWluZXIuaW5qZWN0b3IpO1xyXG5cdFx0XHR0aGlzLmNoaWxkRWxlbWVudC52aWV3Q29udGFpbmVyLmluc2VydChyZWYuaG9zdFZpZXcpO1xyXG5cdFx0XHR0aGlzLl9pbnN0YW5jZSA9IHJlZi5pbnN0YW5jZTtcclxuXHRcdFx0dGhpcy5faW5zdGFuY2UuY29udHJvbCA9IHRoaXMuZHluYW1pY0NvbnRyb2w7XHJcblx0XHRcdHRoaXMuX2luc3RhbmNlLmxhYmVsID0gdGhpcy5sYWJlbDtcclxuXHRcdFx0dGhpcy5faW5zdGFuY2UudHlwZSA9IHRoaXMudHlwZTtcclxuXHRcdFx0dGhpcy5faW5zdGFuY2UudmFsdWUgPSB0aGlzLnZhbHVlO1xyXG5cdFx0XHR0aGlzLl9pbnN0YW5jZS5yZXF1aXJlZCA9IHRoaXMucmVxdWlyZWQ7XHJcblx0XHRcdHRoaXMuX2luc3RhbmNlLmhpZGRlbiA9IHRoaXMuaGlkZGVuO1xyXG5cdFx0XHR0aGlzLl9pbnN0YW5jZS5taW4gPSB0aGlzLm1pbjtcclxuXHRcdFx0dGhpcy5faW5zdGFuY2UubWF4ID0gdGhpcy5tYXg7XHJcblx0XHRcdHRoaXMuX2luc3RhbmNlLm1pbkxlbmd0aCA9IHRoaXMubWluTGVuZ3RoO1xyXG5cdFx0XHR0aGlzLl9pbnN0YW5jZS5tYXhMZW5ndGggPSB0aGlzLm1heExlbmd0aDtcclxuXHRcdFx0dGhpcy5faW5zdGFuY2Uuc2VsZWN0aW9ucyA9IHRoaXMuc2VsZWN0aW9ucztcclxuXHRcdFx0dGhpcy5faW5zdGFuY2UuZmxleCA9IHRoaXMuZmxleDtcclxuXHRcdFx0dGhpcy5faW5zdGFuY2Uuc2VsZWN0Q29tcGxleCA9IHRoaXMuc2VsZWN0Q29tcGxleDtcclxuXHRcdFx0dGhpcy5faW5zdGFuY2Uuc2VsZWN0TXVsdGlwbGUgPSB0aGlzLnNlbGVjdE11bHRpcGxlO1xyXG5cdFx0XHR0aGlzLl9pbnN0YW5jZS5zZWFyY2hhYmxlID0gdGhpcy5zZWFyY2hhYmxlO1xyXG5cdFx0XHR0aGlzLl9pbnN0YW5jZS50cmFuc2xhdGUgPSB0aGlzLnRyYW5zbGF0ZTtcclxuXHRcdFx0dGhpcy5faW5zdGFuY2Uuc3RlcCA9IHRoaXMuc3RlcDtcclxuXHRcdFx0dGhpcy5faW5zdGFuY2UudHJlZUl0ZW1zID0gdGhpcy50cmVlSXRlbXM7XHJcblx0XHRcdHRoaXMuX2luc3RhbmNlLmFjdGlvbiA9IHRoaXMuYWN0aW9uO1xyXG5cdFx0XHR0aGlzLl9pbnN0YW5jZS5zY2hlbWEgPSB0aGlzLnNjaGVtYTtcclxuXHRcdFx0dGhpcy5faW5zdGFuY2UuZHJhZ2dhYmxlID0gdGhpcy5kcmFnZ2FibGU7XHJcblx0XHRcdHRoaXMuX2luc3RhbmNlLmV4dHJhcyA9IHRoaXMuZXh0cmFzO1xyXG5cdFx0XHR0aGlzLl9pbnN0YW5jZS5leHRyYUZpZWxkcyA9IHRoaXMuZXh0cmFGaWVsZHM7XHJcblx0XHRcdHRoaXMuX2luc3RhbmNlLmNoaXBzID0gdGhpcy5jaGlwcztcclxuXHJcblx0XHRcdHRoaXMuX2luc3RhbmNlLnJlZ2lzdGVyT25DaGFuZ2UoKHZhbHVlOiBhbnkpID0+IHtcclxuXHRcdFx0XHR0aGlzLnZhbHVlID0gdmFsdWU7XHJcblx0XHRcdH0pO1xyXG5cdFx0XHR0aGlzLnJlZ2lzdGVyT25Nb2RlbENoYW5nZSgodmFsdWU6IGFueSkgPT4ge1xyXG5cdFx0XHRcdC8vIGZpeCB0byBjaGVjayBpZiB2YWx1ZSBpcyBOYU4gKHR5cGU9bnVtYmVyKVxyXG5cdFx0XHRcdGlmICghTnVtYmVyLmlzTmFOKHZhbHVlKSkge1xyXG5cdFx0XHRcdFx0dGhpcy5faW5zdGFuY2UudmFsdWUgPSB2YWx1ZTtcclxuXHRcdFx0XHR9XHJcblxyXG5cdFx0XHR9KTtcclxuXHRcdH1cclxuXHJcblx0LyoqXHJcblx0KiBSZWFzc2lnbiBhbnkgaW5wdXRzIHRoYXQgaGF2ZSBjaGFuZ2VkXHJcblx0Ki9cclxuXHRuZ09uQ2hhbmdlcyhjaGFuZ2VzOiBTaW1wbGVDaGFuZ2VzKTogdm9pZCB7XHJcblx0XHRpZiAodGhpcy5faW5zdGFuY2UpIHtcclxuXHRcdFx0Zm9yIChsZXQgcHJvcCBpbiBjaGFuZ2VzKSB7XHJcblx0XHRcdFx0dGhpcy5faW5zdGFuY2VbcHJvcF0gPSBjaGFuZ2VzW3Byb3BdLmN1cnJlbnRWYWx1ZTtcclxuXHRcdFx0fVxyXG5cdFx0fVxyXG5cdH1cclxuXHJcblx0LyoqXHJcblx0KiBJbXBsZW1lbnRlZCBhcyBwYXJ0IG9mIENvbnRyb2xWYWx1ZUFjY2Vzc29yLlxyXG5cdCovXHJcblx0cmVnaXN0ZXJPbk1vZGVsQ2hhbmdlKGZuOiBhbnkpOiB2b2lkIHtcclxuXHRcdHRoaXMub25Nb2RlbENoYW5nZSA9IGZuO1xyXG5cdH1cclxuXHJcblx0b25Nb2RlbENoYW5nZSA9IChfOiBhbnkpID0+IG5vb3A7XHJcbn1cclxuIl19