UNPKG

@stratio/egeo

Version:
476 lines 43.4 kB
/** * @fileoverview added by tsickle * Generated from: lib/st-form/st-form.component.ts * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /* * © 2017 Stratio Big Data Inc., Sucursal en España. * * This software is licensed under the Apache License, Version 2.0. * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the terms of the License for more details. * * SPDX-License-Identifier: Apache-2.0. */ import { Component, Input, Output, forwardRef, ViewChild, EventEmitter, ChangeDetectionStrategy } from '@angular/core'; import { NG_VALUE_ACCESSOR, NgForm, NG_VALIDATORS } from '@angular/forms'; import { FORM_UI_COMPONENT } from './shared/ui-component.interface'; /** * \@description {Component} [Dynamic form] * * The form component allows to generate forms dynamically using a JSON schema. * * \@example * * {html} * * ``` * <st-form [schema]="jsonSchema" [(ngModel)]="model" #formModel="ngModel"> * </st-form> * * ``` * */ export class StFormComponent { constructor() { /** * \@Input {string} [nestingLevel=0] This informs about the nesting level of the form. This input is only used for design purposes */ this.nestingLevel = 0; /** * \@Input {string} [disabledSectionMessage='for this instance is disabled.'] * Message displayed when a section is disabled. This is always displayed after the section name */ this.disabledSectionMessage = 'for this instance is disabled.'; /** * \@Input {number} [sectionDescriptionLevel=-1] Level of the section to which description is displayed. * By default, section descriptions are not displayed. */ this.sectionDescriptionLevel = -1; /** * \@Input {boolean} [showTooltips=-1] Enable or disable displaying of tooltips * By default, tooltips are displayed */ this.showTooltips = true; /** * \@Output {any} [valueChange=] Event emitted when value is changed. This emits the current form value */ this.valueChange = new EventEmitter(); this.showCollapsedSectionFields = false; this.innerValue = {}; this._value = {}; this._parentFieldSubscription = []; this.onTouched = (/** * @return {?} */ () => { }); } /** * @return {?} */ ngOnInit() { if (this.schema.dependencies) { this._parentFields = Object.keys(this.schema.dependencies); } } /** * @return {?} */ ngAfterViewInit() { if (!this.forceValidations) { this.form.form.markAsPristine(); } } /** * @return {?} */ ngAfterViewChecked() { if (this._parentFields && this.form.control && this.form.control.controls) { for (let i = 0; i < this._parentFields.length; ++i) { /** @type {?} */ let parentField = this._parentFields[i]; if (!this._parentFieldSubscription[i] && this.form.control.controls[parentField]) { this._parentFieldSubscription[i] = this.form.control.controls[this._parentFields[i]].valueChanges.subscribe((/** * @param {?} value * @return {?} */ (value) => { if (!value) { /** @type {?} */ let childrenFields = this.schema.dependencies[parentField]; for (let j = 0; j < childrenFields.length; ++j) { if (this.form.controls[childrenFields[j]]) { this._value[childrenFields[j]] = undefined; } } } })); } } } } // Function to call when the value changes. /** * @param {?} _ * @return {?} */ onChange(_) { } /** * @param {?} control * @return {?} */ validate(control) { /** @type {?} */ let errors = null; if (this.form) { Object.keys(this.form.controls).forEach((/** * @param {?} propertyName * @return {?} */ (propertyName) => { if (this.form.controls[propertyName] && this.form.controls[propertyName].errors) { if (!errors) { errors = {}; } errors[propertyName] = this.form.controls[propertyName].errors; } })); this.form.control.setErrors(errors); } return errors; } /** * @param {?} propertyName * @return {?} */ isRequired(propertyName) { return propertyName && this.schema.required && this.schema.required.indexOf(propertyName) !== -1; } /** * @return {?} */ isCollapsedSection() { return this.schema.type === 'object' && this.schema.ui && (this.schema.ui.component === FORM_UI_COMPONENT.SHOW_MORE || this.schema.ui.component === FORM_UI_COMPONENT.ACCORDION); } /** * @return {?} */ iShowMoreSection() { return this.schema.type === 'object' && this.schema.ui && this.schema.ui.component === FORM_UI_COMPONENT.SHOW_MORE; } /** * @param {?} propertyName * @return {?} */ isAParentField(propertyName) { return this.schema.dependencies && this.schema.dependencies[propertyName] && this.schema.dependencies[propertyName].length > 0; } /** * @return {?} */ getOptionalButtonLabel() { /** @type {?} */ let label = 'Additional options'; if (this.parentName || this.schema.title) { label += ' of '; label += this.parentName || this.schema.title; } return label; } /** * @return {?} */ onChangeOptionalFieldsVisibility() { this.showCollapsedSectionFields = !this.showCollapsedSectionFields; } /** * @param {?} propertyName * @return {?} */ getFieldClasses(propertyName) { return { 'hidden': this.isCollapsedSection() && !this.showCollapsedSectionFields, 'parent-field': this.isAParentField(propertyName) || (this.isASwitchSection() && this.isTheFirstField(propertyName)) }; } /** * @param {?} propertyName * @return {?} */ fieldHasToBeCreated(propertyName) { /** @type {?} */ let createField = true; /** @type {?} */ let parentField = this.getParentField(propertyName); if (((parentField && !this._value[parentField]) || (this.isInADisabledSection() && !this.isTheFirstField(propertyName))) || !this.fulfillDependencyVisibility(propertyName)) { createField = false; this._value[propertyName] = undefined; } return createField; } /** * @param {?} propertyName * @return {?} */ isRelatedField(propertyName) { return this.schema.properties[propertyName].ui && this.schema.properties[propertyName].ui.relatedTo; } // When value is received from outside /** * @param {?} value * @return {?} */ writeValue(value) { if (value) { this.onChange(value); this.innerValue = value; } } /** * @param {?} value * @param {?} property * @return {?} */ onChangeProperty(value, property) { this._value[property] = value; this.valueChange.emit(this._value); setTimeout((/** * @return {?} */ () => { this.onChange(this._value); })); } // Registry the change function to propagate internal model changes /** * @param {?} fn * @return {?} */ registerOnChange(fn) { this.onChange = fn; } // Registry the touch function to propagate internal touch events TODO: make this function. /** * @param {?} fn * @return {?} */ registerOnTouched(fn) { this.onTouched = fn; } // Allows Angular to disable the form. /** * @param {?} disable * @return {?} */ setDisabledState(disable) { if (disable) { this.form.control.disable(); } else { this.form.control.enable(); } } /** * @return {?} */ ngOnDestroy() { if (this._parentFieldSubscription) { for (let i = 0; i < this._parentFieldSubscription.length; ++i) { this._parentFieldSubscription[i].unsubscribe(); } } } /** * @return {?} */ isInADisabledSection() { if (this.isASwitchSection()) { /** @type {?} */ let sectionEnabler = Object.keys(this.schema.properties)[0]; return !(this.form && this.form.controls[sectionEnabler] && this.form.controls[sectionEnabler].value); } return false; } /** * @return {?} */ isASwitchSection() { return this.schema.ui && this.schema.ui.component === FORM_UI_COMPONENT.SWITCH; } /** * @return {?} */ isAnAccordion() { return this.schema.ui && this.schema.ui.component === FORM_UI_COMPONENT.ACCORDION; } /** * @return {?} */ onClickTitle() { if (this.isAnAccordion()) { this.onChangeOptionalFieldsVisibility(); } } /** * @param {?} propertyName * @return {?} */ isTheFirstField(propertyName) { return propertyName === Object.keys(this.schema.properties)[0]; } /** * @private * @param {?} propertyName * @return {?} */ getParentField(propertyName) { /** @type {?} */ let parentField = undefined; if (this.schema.dependencies) { Object.keys(this.schema.dependencies).forEach((/** * @param {?} key * @return {?} */ (key) => { if (this.schema.dependencies[key].indexOf(propertyName) !== -1) { parentField = key; } })); } return parentField; } /** * @private * @param {?} propertyName * @return {?} */ fulfillDependencyVisibility(propertyName) { /** @type {?} */ let fulfill = true; /** @type {?} */ let propertySchema = this.schema.properties[propertyName]; if (propertySchema.ui && propertySchema.ui.visible) { /** @type {?} */ const keys = Object.keys(propertySchema.ui.visible); /** @type {?} */ let i = 0; while (fulfill && i < keys.length && propertySchema.ui.visible.hasOwnProperty(keys[i])) { if (this._value[keys[i]] !== propertySchema.ui.visible[keys[i]]) { fulfill = false; } ++i; } } return fulfill; } } StFormComponent.decorators = [ { type: Component, args: [{ selector: 'st-form', template: "<!--\n\n \u00A9 2017 Stratio Big Data Inc., Sucursal en Espa\u00F1a.\n\n This software is licensed under the Apache License, Version 2.0.\n This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;\n without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n See the terms of the License for more details.\n\n SPDX-License-Identifier: Apache-2.0.\n\n-->\n<form #form=\"ngForm\" *ngIf=\"innerValue\"\n [ngClass]=\"{'category': nestingLevel === 0,\n 'section': nestingLevel === 1,\n 'subsection': nestingLevel > 1,\n 'accordion': isAnAccordion(),\n 'accordion--open': isAnAccordion() && showCollapsedSectionFields}\"\n novalidate>\n <h1 *ngIf=\"schema.title && !isASwitchSection()\" class=\"title\" (click)=\"onClickTitle()\">{{schema.title}}</h1>\n <p *ngIf=\"schema.description && nestingLevel <= sectionDescriptionLevel\" class=\"description\">{{schema.description}}</p>\n <span class=\"optional-fields-button\" *ngIf=\"iShowMoreSection()\">\n <button class=\"button button-link\"\n (click)=\"onChangeOptionalFieldsVisibility()\">\n <span> <i\n [ngClass]=\"{'icon-arrow2_down': showCollapsedSectionFields, 'icon-arrow2_right': !showCollapsedSectionFields}\"></i> {{getOptionalButtonLabel()}}</span>\n </button>\n </span>\n <ng-container *ngFor=\"let property of schema.properties | stObjectToArray; let index = index;\">\n <div class=\"form-field-container\">\n <st-form-field *ngIf=\"property.value.type !== 'object' && fieldHasToBeCreated(property.key)\" class=\"form-field\"\n [schema]=\"property\"\n [name]=\"property.key\"\n [maxWidth]=\"textFieldMaxWidth\"\n [ngModel]=\"innerValue[property.key]\"\n [forceValidations]=\"forceValidations\"\n (ngModelChange)=\"onChangeProperty($event, property.key)\"\n [required]=\"isRequired(property.key)\"\n [hasDependencies]=\"isAParentField(property.key) || (isASwitchSection() && isTheFirstField(property.key))\"\n [ngClass]=\"getFieldClasses(property.key)\"\n [showTooltip]=\"showTooltips\"\n [qaTag]=\"property.key\"\n [attr.id]=\"property.key + '-form-field'\">\n </st-form-field>\n\n <div *ngIf=\"property.value.type === 'object' && fieldHasToBeCreated(property.key)\">\n <st-form\n [hidden]=\"isCollapsedSection() && !showCollapsedSectionFields\"\n [schema]=\"property.value\"\n [parentName]=\"schema.title\"\n [name]=\"property.key\"\n [textFieldMaxWidth]=\"textFieldMaxWidth\"\n [ngModel]=\"innerValue[property.key]\"\n (ngModelChange)=\"onChangeProperty($event, property.key)\"\n [attr.id]=\"property.key + '-section'\"\n [nestingLevel]=\"nestingLevel + 1\"\n [showTooltips]=\"showTooltips\"\n [sectionDescriptionLevel]=\"sectionDescriptionLevel\">\n </st-form>\n </div>\n </div>\n <span class=\"line-break\" *ngIf=\"!isRelatedField(property.key)\"></span>\n </ng-container>\n\n <p *ngIf=\"isInADisabledSection()\" class=\"disabled-section-info\"> {{schema.title}} {{disabledSectionMessage}}</p>\n</form>\n", host: { class: 'st-form' }, changeDetection: ChangeDetectionStrategy.OnPush, providers: [ { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef((/** * @return {?} */ () => StFormComponent)), multi: true }, { provide: NG_VALIDATORS, useExisting: forwardRef((/** * @return {?} */ () => StFormComponent)), multi: true } ], styles: ["@charset \"UTF-8\";.form-field{display:block;padding-bottom:20px}.form-field.hidden{visibility:hidden;position:absolute}.section-title{padding:10px 0 20px}"] }] } ]; StFormComponent.propDecorators = { schema: [{ type: Input }], parentName: [{ type: Input }], nestingLevel: [{ type: Input }], forceValidations: [{ type: Input }], disabledSectionMessage: [{ type: Input }], sectionDescriptionLevel: [{ type: Input }], textFieldMaxWidth: [{ type: Input }], showTooltips: [{ type: Input }], valueChange: [{ type: Output }], form: [{ type: ViewChild, args: ['form', { static: false },] }] }; if (false) { /** * \@Input {any} [schema=] JSON schema needed to generate the form * @type {?} */ StFormComponent.prototype.schema; /** * \@Input {string} [parentName=] Name of the parent section. By default, it is undefined * @type {?} */ StFormComponent.prototype.parentName; /** * \@Input {string} [nestingLevel=0] This informs about the nesting level of the form. This input is only used for design purposes * @type {?} */ StFormComponent.prototype.nestingLevel; /** * \@Input {boolean} [forceValidations=] Boolean to force the field validations * @type {?} */ StFormComponent.prototype.forceValidations; /** * \@Input {string} [disabledSectionMessage='for this instance is disabled.'] * Message displayed when a section is disabled. This is always displayed after the section name * @type {?} */ StFormComponent.prototype.disabledSectionMessage; /** * \@Input {number} [sectionDescriptionLevel=-1] Level of the section to which description is displayed. * By default, section descriptions are not displayed. * @type {?} */ StFormComponent.prototype.sectionDescriptionLevel; /** * \@Input {number} [textFieldMaxWidth=] Maximum width of a field needed to paint a input or textarea * @type {?} */ StFormComponent.prototype.textFieldMaxWidth; /** * \@Input {boolean} [showTooltips=-1] Enable or disable displaying of tooltips * By default, tooltips are displayed * @type {?} */ StFormComponent.prototype.showTooltips; /** * \@Output {any} [valueChange=] Event emitted when value is changed. This emits the current form value * @type {?} */ StFormComponent.prototype.valueChange; /** @type {?} */ StFormComponent.prototype.form; /** @type {?} */ StFormComponent.prototype.showCollapsedSectionFields; /** @type {?} */ StFormComponent.prototype.innerValue; /** * @type {?} * @private */ StFormComponent.prototype._value; /** * @type {?} * @private */ StFormComponent.prototype._parentFieldSubscription; /** * @type {?} * @private */ StFormComponent.prototype._parentFields; /** @type {?} */ StFormComponent.prototype.onTouched; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3QtZm9ybS5jb21wb25lbnQuanMiLCJzb3VyY2VSb290Ijoibmc6Ly9Ac3RyYXRpby9lZ2VvLyIsInNvdXJjZXMiOlsibGliL3N0LWZvcm0vc3QtZm9ybS5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7O0FBVUEsT0FBTyxFQUNKLFNBQVMsRUFDVCxLQUFLLEVBQ0wsTUFBTSxFQUNOLFVBQVUsRUFDVixTQUFTLEVBQ1QsWUFBWSxFQUNaLHVCQUF1QixFQUt6QixNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQXdCLGlCQUFpQixFQUFFLE1BQU0sRUFBRSxhQUFhLEVBQWUsTUFBTSxnQkFBZ0IsQ0FBQztBQUc3RyxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxpQ0FBaUMsQ0FBQzs7Ozs7Ozs7Ozs7Ozs7Ozs7QUE2QnBFLE1BQU0sT0FBTyxlQUFlO0lBWjVCOzs7O1FBa0JZLGlCQUFZLEdBQVcsQ0FBQyxDQUFDOzs7OztRQU16QiwyQkFBc0IsR0FBVyxnQ0FBZ0MsQ0FBQzs7Ozs7UUFLbEUsNEJBQXVCLEdBQVcsQ0FBQyxDQUFDLENBQUM7Ozs7O1FBUXJDLGlCQUFZLEdBQVksSUFBSSxDQUFDOzs7O1FBRTVCLGdCQUFXLEdBQXNCLElBQUksWUFBWSxFQUFPLENBQUM7UUFJNUQsK0JBQTBCLEdBQVksS0FBSyxDQUFDO1FBQzVDLGVBQVUsR0FBUSxFQUFFLENBQUM7UUFDcEIsV0FBTSxHQUFRLEVBQUUsQ0FBQztRQUNqQiw2QkFBd0IsR0FBbUIsRUFBRSxDQUFDO1FBd0N0RCxjQUFTOzs7UUFBRyxHQUFHLEVBQUU7UUFDakIsQ0FBQyxFQUFBO0lBeUtKLENBQUM7Ozs7SUEvTUUsUUFBUTtRQUNMLElBQUksSUFBSSxDQUFDLE1BQU0sQ0FBQyxZQUFZLEVBQUU7WUFDM0IsSUFBSSxDQUFDLGFBQWEsR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsWUFBWSxDQUFDLENBQUM7U0FDN0Q7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QixlQUFlLEVBQUUsdUJBQXVCLENBQUMsTUFBTTtnQkFDL0MsU0FBUyxFQUFFO29CQUNSLEVBQUUsT0FBTyxFQUFFLGlCQUFpQixFQUFFLFdBQVcsRUFBRSxVQUFVOzs7d0JBQUMsR0FBRyxFQUFFLENBQUMsZUFBZSxFQUFDLEVBQUUsS0FBSyxFQUFFLElBQUksRUFBRTtvQkFDM0YsRUFBRSxPQUFPLEVBQUUsYUFBYSxFQUFFLFdBQVcsRUFBRSxVQUFVOzs7d0JBQUMsR0FBRyxFQUFFLENBQUMsZUFBZSxFQUFDLEVBQUUsS0FBSyxFQUFFLElBQUksRUFBRTtpQkFDekY7O2FBQ0g7OztxQkFJRyxLQUFLO3lCQUVMLEtBQUs7MkJBRUwsS0FBSzsrQkFFTCxLQUFLO3FDQUlMLEtBQUs7c0NBS0wsS0FBSztnQ0FHTCxLQUFLOzJCQUtMLEtBQUs7MEJBRUwsTUFBTTttQkFFTixTQUFTLFNBQUMsTUFBTSxFQUFFLEVBQUMsTUFBTSxFQUFFLEtBQUssRUFBQzs7Ozs7OztJQTNCbEMsaUNBQXFCOzs7OztJQUVyQixxQ0FBNEI7Ozs7O0lBRTVCLHVDQUFrQzs7Ozs7SUFFbEMsMkNBQW1DOzs7Ozs7SUFJbkMsaURBQTJFOzs7Ozs7SUFLM0Usa0RBQThDOzs7OztJQUc5Qyw0Q0FBbUM7Ozs7OztJQUtuQyx1Q0FBc0M7Ozs7O0lBRXRDLHNDQUFtRTs7SUFFbkUsK0JBQWlEOztJQUVqRCxxREFBbUQ7O0lBQ25ELHFDQUE0Qjs7Ozs7SUFDNUIsaUNBQXlCOzs7OztJQUN6QixtREFBc0Q7Ozs7O0lBQ3RELHdDQUFnQzs7SUF1Q2hDLG9DQUNDIiwic291cmNlc0NvbnRlbnQiOlsiLypcbiAqIMKpIDIwMTcgU3RyYXRpbyBCaWcgRGF0YSBJbmMuLCBTdWN1cnNhbCBlbiBFc3Bhw7FhLlxuICpcbiAqIFRoaXMgc29mdHdhcmUgaXMgbGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMC5cbiAqIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7XG4gKiB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLlxuICogU2VlIHRoZSB0ZXJtcyBvZiB0aGUgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLlxuICpcbiAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBBcGFjaGUtMi4wLlxuICovXG5pbXBvcnQge1xuICAgQ29tcG9uZW50LFxuICAgSW5wdXQsXG4gICBPdXRwdXQsXG4gICBmb3J3YXJkUmVmLFxuICAgVmlld0NoaWxkLFxuICAgRXZlbnRFbWl0dGVyLFxuICAgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksXG4gICBBZnRlclZpZXdDaGVja2VkLFxuICAgT25Jbml0LFxuICAgT25EZXN0cm95LFxuICAgQWZ0ZXJWaWV3SW5pdFxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IENvbnRyb2xWYWx1ZUFjY2Vzc29yLCBOR19WQUxVRV9BQ0NFU1NPUiwgTmdGb3JtLCBOR19WQUxJREFUT1JTLCBGb3JtQ29udHJvbCB9IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcbmltcG9ydCB7IFN1YnNjcmlwdGlvbiB9IGZyb20gJ3J4anMnO1xuXG5pbXBvcnQgeyBGT1JNX1VJX0NPTVBPTkVOVCB9IGZyb20gJy4vc2hhcmVkL3VpLWNvbXBvbmVudC5pbnRlcmZhY2UnO1xuLyoqXG4gKiBAZGVzY3JpcHRpb24ge0NvbXBvbmVudH0gW0R5bmFtaWMgZm9ybV1cbiAqXG4gKiBUaGUgZm9ybSBjb21wb25lbnQgYWxsb3dzIHRvIGdlbmVyYXRlIGZvcm1zIGR5bmFtaWNhbGx5IHVzaW5nIGEgSlNPTiBzY2hlbWEuXG4gKlxuICogQGV4YW1wbGVcbiAqXG4gKiB7aHRtbH1cbiAqXG4gKiBgYGBcbiAqIDxzdC1mb3JtIFtzY2hlbWFdPVwianNvblNjaGVtYVwiIFsobmdNb2RlbCldPVwibW9kZWxcIiAjZm9ybU1vZGVsPVwibmdNb2RlbFwiPlxuICogPC9zdC1mb3JtPlxuICpcbiAqIGBgYFxuICpcbiAqL1xuQENvbXBvbmVudCh7XG4gICBzZWxlY3RvcjogJ3N0LWZvcm0nLFxuICAgdGVtcGxhdGVVcmw6ICcuL3N0LWZvcm0uY29tcG9uZW50Lmh0bWwnLFxuICAgc3R5bGVVcmxzOiBbJy4vc3QtZm9ybS5jb21wb25lbnQuc2NzcyddLFxuICAgaG9zdDogeyBjbGFzczogJ3N0LWZvcm0nIH0sXG4gICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaCxcbiAgIHByb3ZpZGVyczogW1xuICAgICAgeyBwcm92aWRlOiBOR19WQUxVRV9BQ0NFU1NPUiwgdXNlRXhpc3Rpbmc6IGZvcndhcmRSZWYoKCkgPT4gU3RGb3JtQ29tcG9uZW50KSwgbXVsdGk6IHRydWUgfSxcbiAgICAgIHsgcHJvdmlkZTogTkdfVkFMSURBVE9SUywgdXNlRXhpc3Rpbmc6IGZvcndhcmRSZWYoKCkgPT4gU3RGb3JtQ29tcG9uZW50KSwgbXVsdGk6IHRydWUgfVxuICAgXVxufSlcblxuZXhwb3J0IGNsYXNzIFN0Rm9ybUNvbXBvbmVudCBpbXBsZW1lbnRzIEFmdGVyVmlld0luaXQsIEFmdGVyVmlld0NoZWNrZWQsIENvbnRyb2xWYWx1ZUFjY2Vzc29yLCBPbkluaXQsIE9uRGVzdHJveSB7XG4gICAvKiogQElucHV0IHthbnl9IFtzY2hlbWE9XSBKU09OIHNjaGVtYSBuZWVkZWQgdG8gZ2VuZXJhdGUgdGhlIGZvcm0gKi9cbiAgIEBJbnB1dCgpIHNjaGVtYTogYW55O1xuICAgLyoqIEBJbnB1dCB7c3RyaW5nfSBbcGFyZW50TmFtZT1dIE5hbWUgb2YgdGhlIHBhcmVudCBzZWN0aW9uLiBCeSBkZWZhdWx0LCBpdCBpcyB1bmRlZmluZWQgKi9cbiAgIEBJbnB1dCgpIHBhcmVudE5hbWU6IHN0cmluZztcbiAgIC8qKiBASW5wdXQge3N0cmluZ30gW25lc3RpbmdMZXZlbD0wXSBUaGlzIGluZm9ybXMgYWJvdXQgdGhlIG5lc3RpbmcgbGV2ZWwgb2YgdGhlIGZvcm0uIFRoaXMgaW5wdXQgaXMgb25seSB1c2VkIGZvciBkZXNpZ24gcHVycG9zZXMgKi9cbiAgIEBJbnB1dCgpIG5lc3RpbmdMZXZlbDogbnVtYmVyID0gMDtcbiAgIC8qKiBASW5wdXQge2Jvb2xlYW59IFtmb3JjZVZhbGlkYXRpb25zPV0gQm9vbGVhbiB0byBmb3JjZSB0aGUgZmllbGQgdmFsaWRhdGlvbnMgKi9cbiAgIEBJbnB1dCgpIGZvcmNlVmFsaWRhdGlvbnM6IGJvb2xlYW47XG4gICAvKiogQElucHV0IHtzdHJpbmd9IFtkaXNhYmxlZFNlY3Rpb25NZXNzYWdlPSdmb3IgdGhpcyBpbnN0YW5jZSBpcyBkaXNhYmxlZC4nXVxuICAgICogIE1lc3NhZ2UgZGlzcGxheWVkIHdoZW4gYSBzZWN0aW9uIGlzIGRpc2FibGVkLiBUaGlzIGlzIGFsd2F5cyBkaXNwbGF5ZWQgYWZ0ZXIgdGhlIHNlY3Rpb24gbmFtZVxuICAgICovXG4gICBASW5wdXQoKSBkaXNhYmxlZFNlY3Rpb25NZXNzYWdlOiBzdHJpbmcgPSAnZm9yIHRoaXMgaW5zdGFuY2UgaXMgZGlzYWJsZWQuJztcblxuICAgLyoqIEBJbnB1dCB7bnVtYmVyfSBbc2VjdGlvbkRlc2NyaXB0aW9uTGV2ZWw9LTFdIExldmVsIG9mIHRoZSBzZWN0aW9uIHRvIHdoaWNoIGRlc2NyaXB0aW9uIGlzIGRpc3BsYXllZC5cbiAgICAqIEJ5IGRlZmF1bHQsIHNlY3Rpb24gZGVzY3JpcHRpb25zIGFyZSBub3QgZGlzcGxheWVkLlxuICAgICovXG4gICBASW5wdXQoKSBzZWN0aW9uRGVzY3JpcHRpb25MZXZlbDogbnVtYmVyID0gLTE7XG5cbiAgIC8qKiBASW5wdXQge251bWJlcn0gW3RleHRGaWVsZE1heFdpZHRoPV0gTWF4aW11bSB3aWR0aCBvZiBhIGZpZWxkIG5lZWRlZCB0byBwYWludCBhIGlucHV0IG9yIHRleHRhcmVhICovXG4gICBASW5wdXQoKSB0ZXh0RmllbGRNYXhXaWR0aDogbnVtYmVyO1xuXG4gICAvKiogQElucHV0IHtib29sZWFufSBbc2hvd1Rvb2x0aXBzPS0xXSBFbmFibGUgb3IgZGlzYWJsZSBkaXNwbGF5aW5nIG9mIHRvb2x0aXBzXG4gICAgKiBCeSBkZWZhdWx0LCB0b29sdGlwcyBhcmUgZGlzcGxheWVkXG4gICAgKi9cbiAgIEBJbnB1dCgpIHNob3dUb29sdGlwczogYm9vbGVhbiA9IHRydWU7XG4gICAvKiogQE91dHB1dCB7YW55fSBbdmFsdWVDaGFuZ2U9XSBFdmVudCBlbWl0dGVkIHdoZW4gdmFsdWUgaXMgY2hhbmdlZC4gVGhpcyBlbWl0cyB0aGUgY3VycmVudCBmb3JtIHZhbHVlICovXG4gICBAT3V0cHV0KCkgdmFsdWVDaGFuZ2U6IEV2ZW50RW1pdHRlcjxhbnk+ID0gbmV3IEV2ZW50RW1pdHRlcjxhbnk+KCk7XG5cbiAgIEBWaWV3Q2hpbGQoJ2Zvcm0nLCB7c3RhdGljOiBmYWxzZX0pIGZvcm06IE5nRm9ybTtcblxuICAgcHVibGljIHNob3dDb2xsYXBzZWRTZWN0aW9uRmllbGRzOiBib29sZWFuID0gZmFsc2U7XG4gICBwdWJsaWMgaW5uZXJWYWx1ZTogYW55ID0ge307XG4gICBwcml2YXRlIF92YWx1ZTogYW55ID0ge307XG4gICBwcml2YXRlIF9wYXJlbnRGaWVsZFN1YnNjcmlwdGlvbjogU3Vic2NyaXB0aW9uW10gPSBbXTtcbiAgIHByaXZhdGUgX3BhcmVudEZpZWxkczogc3RyaW5nW107XG5cbiAgIG5nT25Jbml0KCk6IHZvaWQge1xuICAgICAgaWYgKHRoaXMuc2NoZW1hLmRlcGVuZGVuY2llcykge1xuICAgICAgICAgdGhpcy5fcGFyZW50RmllbGRzID0gT2JqZWN0LmtleXModGhpcy5zY2hlbWEuZGVwZW5kZW5jaWVzKTtcbiAgICAgIH1cbiAgIH1cblxuICAgbmdBZnRlclZpZXdJbml0KCk6IHZvaWQge1xuICAgICAgaWYgKCF0aGlzLmZvcmNlVmFsaWRhdGlvbnMpIHtcbiAgICAgICAgICAgIHRoaXMuZm9ybS5mb3JtLm1hcmtBc1ByaXN0aW5lKCk7XG4gICAgICB9XG4gICB9XG5cbiAgIG5nQWZ0ZXJWaWV3Q2hlY2tlZCgpOiB2b2lkIHtcbiAgICAgIGlmICh0aGlzLl9wYXJlbnRGaWVsZHMgJiYgdGhpcy5mb3JtLmNvbnRyb2wgJiYgdGhpcy5mb3JtLmNvbnRyb2wuY29udHJvbHMpIHtcbiAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5fcGFyZW50RmllbGRzLmxlbmd0aDsgKytpKSB7XG4gICAgICAgICAgICBsZXQgcGFyZW50RmllbGQ6IHN0cmluZyA9IHRoaXMuX3BhcmVudEZpZWxkc1tpXTtcbiAgICAgICAgICAgIGlmICghdGhpcy5fcGFyZW50RmllbGRTdWJzY3JpcHRpb25baV0gJiYgdGhpcy5mb3JtLmNvbnRyb2wuY29udHJvbHNbcGFyZW50RmllbGRdKSB7XG5cbiAgICAgICAgICAgICAgIHRoaXMuX3BhcmVudEZpZWxkU3Vic2NyaXB0aW9uW2ldID0gdGhpcy5mb3JtLmNvbnRyb2wuY29udHJvbHNbdGhpcy5fcGFyZW50RmllbGRzW2ldXS52YWx1ZUNoYW5nZXMuc3Vic2NyaWJlKCh2YWx1ZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgaWYgKCF2YWx1ZSkge1xuICAgICAgICAgICAgICAgICAgICAgbGV0IGNoaWxkcmVuRmllbGRzOiBzdHJpbmdbXSA9IHRoaXMuc2NoZW1hLmRlcGVuZGVuY2llc1twYXJlbnRGaWVsZF07XG4gICAgICAgICAgICAgICAgICAgICBmb3IgKGxldCBqID0gMDsgaiA8IGNoaWxkcmVuRmllbGRzLmxlbmd0aDsgKytqKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5mb3JtLmNvbnRyb2xzW2NoaWxkcmVuRmllbGRzW2pdXSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fdmFsdWVbY2hpbGRyZW5GaWVsZHNbal1dID0gdW5kZWZpbmVkO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICB9XG4gICAgICB9XG4gICB9XG5cbiAgIC8vIEZ1bmN0aW9uIHRvIGNhbGwgd2hlbiB0aGUgdmFsdWUgY2hhbmdlcy5cbiAgIG9uQ2hhbmdlKF86IGFueSk6IHZvaWQge1xuICAgfVxuXG4gICBvblRvdWNoZWQgPSAoKSA9PiB7XG4gICB9XG5cbiAgIHZhbGlkYXRlKGNvbnRyb2w6IEZvcm1Db250cm9sKTogYW55IHtcbiAgICAgIGxldCBlcnJvcnM6IGFueSA9IG51bGw7XG4gICAgICBpZiAodGhpcy5mb3JtKSB7XG4gICAgICAgICBPYmplY3Qua2V5cyh0aGlzLmZvcm0uY29udHJvbHMpLmZvckVhY2goKHByb3BlcnR5TmFtZSkgPT4ge1xuICAgICAgICAgICAgaWYgKHRoaXMuZm9ybS5jb250cm9sc1twcm9wZXJ0eU5hbWVdICYmIHRoaXMuZm9ybS5jb250cm9sc1twcm9wZXJ0eU5hbWVdLmVycm9ycykge1xuICAgICAgICAgICAgICAgaWYgKCFlcnJvcnMpIHtcbiAgICAgICAgICAgICAgICAgIGVycm9ycyA9IHt9O1xuICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgZXJyb3JzW3Byb3BlcnR5TmFtZV0gPSB0aGlzLmZvcm0uY29udHJvbHNbcHJvcGVydHlOYW1lXS5lcnJvcnM7XG4gICAgICAgICAgICB9XG4gICAgICAgICB9KTtcblxuICAgICAgICAgdGhpcy5mb3JtLmNvbnRyb2wuc2V0RXJyb3JzKGVycm9ycyk7XG4gICAgICB9XG4gICAgICByZXR1cm4gZXJyb3JzO1xuICAgfVxuXG4gICBpc1JlcXVpcmVkKHByb3BlcnR5TmFtZTogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgICByZXR1cm4gcHJvcGVydHlOYW1lICYmIHRoaXMuc2NoZW1hLnJlcXVpcmVkICYmIHRoaXMuc2NoZW1hLnJlcXVpcmVkLmluZGV4T2YocHJvcGVydHlOYW1lKSAhPT0gLTE7XG4gICB9XG5cbiAgIGlzQ29sbGFwc2VkU2VjdGlvbigpOiBib29sZWFuIHtcbiAgICAgIHJldHVybiB0aGlzLnNjaGVtYS50eXBlID09PSAnb2JqZWN0JyAmJiB0aGlzLnNjaGVtYS51aSAmJlxuICAgICAgICAgKHRoaXMuc2NoZW1hLnVpLmNvbXBvbmVudCA9PT0gRk9STV9VSV9DT01QT05FTlQuU0hPV19NT1JFIHx8IHRoaXMuc2NoZW1hLnVpLmNvbXBvbmVudCA9PT0gRk9STV9VSV9DT01QT05FTlQuQUNDT1JESU9OKTtcbiAgIH1cblxuICAgaVNob3dNb3JlU2VjdGlvbigpOiBib29sZWFuIHtcbiAgICAgIHJldHVybiB0aGlzLnNjaGVtYS50eXBlID09PSAnb2JqZWN0JyAmJiB0aGlzLnNjaGVtYS51aSAmJiB0aGlzLnNjaGVtYS51aS5jb21wb25lbnQgPT09IEZPUk1fVUlfQ09NUE9ORU5ULlNIT1dfTU9SRTtcbiAgIH1cblxuICAgaXNBUGFyZW50RmllbGQocHJvcGVydHlOYW1lOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICAgIHJldHVybiB0aGlzLnNjaGVtYS5kZXBlbmRlbmNpZXMgJiYgdGhpcy5zY2hlbWEuZGVwZW5kZW5jaWVzW3Byb3BlcnR5TmFtZV0gJiYgdGhpcy5zY2hlbWEuZGVwZW5kZW5jaWVzW3Byb3BlcnR5TmFtZV0ubGVuZ3RoID4gMDtcbiAgIH1cblxuICAgZ2V0T3B0aW9uYWxCdXR0b25MYWJlbCgpOiBzdHJpbmcge1xuICAgICAgbGV0IGxhYmVsOiBzdHJpbmcgPSAnQWRkaXRpb25hbCBvcHRpb25zJztcblxuICAgICAgaWYgKHRoaXMucGFyZW50TmFtZSB8fCB0aGlzLnNjaGVtYS50aXRsZSkge1xuICAgICAgICAgbGFiZWwgKz0gJyBvZiAnO1xuICAgICAgICAgbGFiZWwgKz0gdGhpcy5wYXJlbnROYW1lIHx8IHRoaXMuc2NoZW1hLnRpdGxlO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gbGFiZWw7XG4gICB9XG5cbiAgIG9uQ2hhbmdlT3B0aW9uYWxGaWVsZHNWaXNpYmlsaXR5KCk6IHZvaWQge1xuICAgICAgdGhpcy5zaG93Q29sbGFwc2VkU2VjdGlvbkZpZWxkcyA9ICF0aGlzLnNob3dDb2xsYXBzZWRTZWN0aW9uRmllbGRzO1xuICAgfVxuXG4gICBnZXRGaWVsZENsYXNzZXMocHJvcGVydHlOYW1lOiBzdHJpbmcpOiBhbnkge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgICdoaWRkZW4nOiB0aGlzLmlzQ29sbGFwc2VkU2VjdGlvbigpICYmICF0aGlzLnNob3dDb2xsYXBzZWRTZWN0aW9uRmllbGRzLFxuICAgICAgICAgJ3BhcmVudC1maWVsZCc6IHRoaXMuaXNBUGFyZW50RmllbGQocHJvcGVydHlOYW1lKSB8fCAodGhpcy5pc0FTd2l0Y2hTZWN0aW9uKCkgJiYgdGhpcy5pc1RoZUZpcnN0RmllbGQocHJvcGVydHlOYW1lKSlcbiAgICAgIH07XG4gICB9XG5cbiAgIGZpZWxkSGFzVG9CZUNyZWF0ZWQocHJvcGVydHlOYW1lOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICAgIGxldCBjcmVhdGVGaWVsZDogYm9vbGVhbiA9IHRydWU7XG4gICAgICBsZXQgcGFyZW50RmllbGQ6IHN0cmluZyA9IHRoaXMuZ2V0UGFyZW50RmllbGQocHJvcGVydHlOYW1lKTtcbiAgICAgIGlmICgoKHBhcmVudEZpZWxkICYmICF0aGlzLl92YWx1ZVtwYXJlbnRGaWVsZF0pIHx8ICh0aGlzLmlzSW5BRGlzYWJsZWRTZWN0aW9uKCkgJiYgIXRoaXMuaXNUaGVGaXJzdEZpZWxkKHByb3BlcnR5TmFtZSkpKVxuICAgICAgICAgfHwgIXRoaXMuZnVsZmlsbERlcGVuZGVuY3lWaXNpYmlsaXR5KHByb3BlcnR5TmFtZSkpIHtcbiAgICAgICAgIGNyZWF0ZUZpZWxkID0gZmFsc2U7XG4gICAgICAgICB0aGlzLl92YWx1ZVtwcm9wZXJ0eU5hbWVdID0gdW5kZWZpbmVkO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGNyZWF0ZUZpZWxkO1xuICAgfVxuXG4gICBpc1JlbGF0ZWRGaWVsZChwcm9wZXJ0eU5hbWU6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgICAgcmV0dXJuIHRoaXMuc2NoZW1hLnByb3BlcnRpZXNbcHJvcGVydHlOYW1lXS51aSAmJiB0aGlzLnNjaGVtYS5wcm9wZXJ0aWVzW3Byb3BlcnR5TmFtZV0udWkucmVsYXRlZFRvO1xuICAgfVxuXG4gICAvLyBXaGVuIHZhbHVlIGlzIHJlY2VpdmVkIGZyb20gb3V0c2lkZVxuICAgd3JpdGVWYWx1ZSh2YWx1ZTogYW55KTogdm9pZCB7XG4gICAgICBpZiAodmFsdWUpIHtcbiAgICAgICAgIHRoaXMub25DaGFuZ2UodmFsdWUpO1xuICAgICAgICAgdGhpcy5pbm5lclZhbHVlID0gdmFsdWU7XG4gICAgICB9XG4gICB9XG5cbiAgIG9uQ2hhbmdlUHJvcGVydHkodmFsdWU6IGFueSwgcHJvcGVydHk6IHN0cmluZyk6IHZvaWQge1xuICAgICAgdGhpcy5fdmFsdWVbcHJvcGVydHldID0gdmFsdWU7XG4gICAgICB0aGlzLnZhbHVlQ2hhbmdlLmVtaXQodGhpcy5fdmFsdWUpO1xuICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICB0aGlzLm9uQ2hhbmdlKHRoaXMuX3ZhbHVlKTtcbiAgICAgIH0pO1xuICAgfVxuXG4gICAvLyBSZWdpc3RyeSB0aGUgY2hhbmdlIGZ1bmN0aW9uIHRvIHByb3BhZ2F0ZSBpbnRlcm5hbCBtb2RlbCBjaGFuZ2VzXG4gICByZWdpc3Rlck9uQ2hhbmdlKGZuOiAoXzogYW55KSA9PiB2b2lkKTogdm9pZCB7XG4gICAgICB0aGlzLm9uQ2hhbmdlID0gZm47XG4gICB9XG5cbiAgIC8vIFJlZ2lzdHJ5IHRoZSB0b3VjaCBmdW5jdGlvbiB0byBwcm9wYWdhdGUgaW50ZXJuYWwgdG91Y2ggZXZlbnRzIFRPRE86IG1ha2UgdGhpcyBmdW5jdGlvbi5cbiAgIHJlZ2lzdGVyT25Ub3VjaGVkKGZuOiAoKSA9PiB2b2lkKTogdm9pZCB7XG4gICAgICB0aGlzLm9uVG91Y2hlZCA9IGZuO1xuICAgfVxuXG4gICAvLyBBbGxvd3MgQW5ndWxhciB0byBkaXNhYmxlIHRoZSBmb3JtLlxuICAgc2V0RGlzYWJsZWRTdGF0ZShkaXNhYmxlOiBib29sZWFuKTogdm9pZCB7XG4gICAgICBpZiAoZGlzYWJsZSkge1xuICAgICAgICAgdGhpcy5mb3JtLmNvbnRyb2wuZGlzYWJsZSgpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgIHRoaXMuZm9ybS5jb250cm9sLmVuYWJsZSgpO1xuICAgICAgfVxuICAgfVxuXG4gICBuZ09uRGVzdHJveSgpOiB2b2lkIHtcbiAgICAgIGlmICh0aGlzLl9wYXJlbnRGaWVsZFN1YnNjcmlwdGlvbikge1xuICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLl9wYXJlbnRGaWVsZFN1YnNjcmlwdGlvbi5sZW5ndGg7ICsraSkge1xuICAgICAgICAgICAgdGhpcy5fcGFyZW50RmllbGRTdWJzY3JpcHRpb25baV0udW5zdWJzY3JpYmUoKTtcbiAgICAgICAgIH1cbiAgICAgIH1cbiAgIH1cblxuICAgaXNJbkFEaXNhYmxlZFNlY3Rpb24oKTogYm9vbGVhbiB7XG4gICAgICBpZiAodGhpcy5pc0FTd2l0Y2hTZWN0aW9uKCkpIHtcbiAgICAgICAgIGxldCBzZWN0aW9uRW5hYmxlcjogc3RyaW5nID0gT2JqZWN0LmtleXModGhpcy5zY2hlbWEucHJvcGVydGllcylbMF07XG4gICAgICAgICByZXR1cm4gISh0aGlzLmZvcm0gJiYgdGhpcy5mb3JtLmNvbnRyb2xzW3NlY3Rpb25FbmFibGVyXSAmJiB0aGlzLmZvcm0uY29udHJvbHNbc2VjdGlvbkVuYWJsZXJdLnZhbHVlKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBmYWxzZTtcbiAgIH1cblxuICAgaXNBU3dpdGNoU2VjdGlvbigpOiBib29sZWFuIHtcbiAgICAgIHJldHVybiB0aGlzLnNjaGVtYS51aSAmJiB0aGlzLnNjaGVtYS51aS5jb21wb25lbnQgPT09IEZPUk1fVUlfQ09NUE9ORU5ULlNXSVRDSDtcbiAgIH1cblxuICAgaXNBbkFjY29yZGlvbigpOiBib29sZWFuIHtcbiAgICAgIHJldHVybiB0aGlzLnNjaGVtYS51aSAmJiB0aGlzLnNjaGVtYS51aS5jb21wb25lbnQgPT09IEZPUk1fVUlfQ09NUE9ORU5ULkFDQ09SRElPTjtcbiAgIH1cblxuICAgb25DbGlja1RpdGxlKCk6IHZvaWQge1xuICAgICAgaWYgKHRoaXMuaXNBbkFjY29yZGlvbigpKSB7XG4gICAgICAgICB0aGlzLm9uQ2hhbmdlT3B0aW9uYWxGaWVsZHNWaXNpYmlsaXR5KCk7XG4gICAgICB9XG4gICB9XG5cbiAgIGlzVGhlRmlyc3RGaWVsZChwcm9wZXJ0eU5hbWU6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgICAgcmV0dXJuIHByb3BlcnR5TmFtZSA9PT0gT2JqZWN0LmtleXModGhpcy5zY2hlbWEucHJvcGVydGllcylbMF07XG4gICB9XG5cbiAgIHByaXZhdGUgZ2V0UGFyZW50RmllbGQocHJvcGVydHlOYW1lOiBzdHJpbmcpOiBzdHJpbmcge1xuICAgICAgbGV0IHBhcmVudEZpZWxkOiBzdHJpbmcgPSB1bmRlZmluZWQ7XG4gICAgICBpZiAodGhpcy5zY2hlbWEuZGVwZW5kZW5jaWVzKSB7XG4gICAgICAgICBPYmplY3Qua2V5cyh0aGlzLnNjaGVtYS5kZXBlbmRlbmNpZXMpLmZvckVhY2goKGtleTogc3RyaW5nKSA9PiB7XG4gICAgICAgICAgICBpZiAodGhpcy5zY2hlbWEuZGVwZW5kZW5jaWVzW2tleV0uaW5kZXhPZihwcm9wZXJ0eU5hbWUpICE9PSAtMSkge1xuICAgICAgICAgICAgICAgcGFyZW50RmllbGQgPSBrZXk7XG4gICAgICAgICAgICB9XG4gICAgICAgICB9KTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBwYXJlbnRGaWVsZDtcbiAgIH1cblxuICAgcHJpdmF0ZSBmdWxmaWxsRGVwZW5kZW5jeVZpc2liaWxpdHkocHJvcGVydHlOYW1lOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICAgIGxldCBmdWxmaWxsOiBib29sZWFuID0gdHJ1ZTtcbiAgICAgIGxldCBwcm9wZXJ0eVNjaGVtYTogYW55ID0gdGhpcy5zY2hlbWEucHJvcGVydGllc1twcm9wZXJ0eU5hbWVdO1xuICAgICAgaWYgKHByb3BlcnR5U2NoZW1hLnVpICYmIHByb3BlcnR5U2NoZW1hLnVpLnZpc2libGUpIHtcbiAgICAgICAgIGNvbnN0IGtleXM6IHN0cmluZ1tdID0gT2JqZWN0LmtleXMocHJvcGVydHlTY2hlbWEudWkudmlzaWJsZSk7XG4gICAgICAgICBsZXQgaSA9IDA7XG4gICAgICAgICB3aGlsZSAoZnVsZmlsbCAmJiBpIDwga2V5cy5sZW5ndGggJiYgcHJvcGVydHlTY2hlbWEudWkudmlzaWJsZS5oYXNPd25Qcm9wZXJ0eShrZXlzW2ldKSkge1xuICAgICAgICAgICAgaWYgKHRoaXMuX3ZhbHVlW2tleXNbaV1dICE9PSBwcm9wZXJ0eVNjaGVtYS51aS52aXNpYmxlW2tleXNbaV1dKSB7XG4gICAgICAgICAgICAgICBmdWxmaWxsID0gZmFsc2U7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICArK2k7XG4gICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gZnVsZmlsbDtcbiAgIH1cbn1cbiJdfQ==