UNPKG

@stratio/egeo

Version:
600 lines 47.5 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> * * ``` * */ var StFormComponent = /** @class */ (function () { function StFormComponent() { /** * \@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 {?} */ function () { }); } /** * @return {?} */ StFormComponent.prototype.ngOnInit = /** * @return {?} */ function () { if (this.schema.dependencies) { this._parentFields = Object.keys(this.schema.dependencies); } }; /** * @return {?} */ StFormComponent.prototype.ngAfterViewInit = /** * @return {?} */ function () { if (!this.forceValidations) { this.form.form.markAsPristine(); } }; /** * @return {?} */ StFormComponent.prototype.ngAfterViewChecked = /** * @return {?} */ function () { var _this = this; if (this._parentFields && this.form.control && this.form.control.controls) { var _loop_1 = function (i) { /** @type {?} */ var parentField = this_1._parentFields[i]; if (!this_1._parentFieldSubscription[i] && this_1.form.control.controls[parentField]) { this_1._parentFieldSubscription[i] = this_1.form.control.controls[this_1._parentFields[i]].valueChanges.subscribe((/** * @param {?} value * @return {?} */ function (value) { if (!value) { /** @type {?} */ var childrenFields = _this.schema.dependencies[parentField]; for (var j = 0; j < childrenFields.length; ++j) { if (_this.form.controls[childrenFields[j]]) { _this._value[childrenFields[j]] = undefined; } } } })); } }; var this_1 = this; for (var i = 0; i < this._parentFields.length; ++i) { _loop_1(i); } } }; // Function to call when the value changes. // Function to call when the value changes. /** * @param {?} _ * @return {?} */ StFormComponent.prototype.onChange = // Function to call when the value changes. /** * @param {?} _ * @return {?} */ function (_) { }; /** * @param {?} control * @return {?} */ StFormComponent.prototype.validate = /** * @param {?} control * @return {?} */ function (control) { var _this = this; /** @type {?} */ var errors = null; if (this.form) { Object.keys(this.form.controls).forEach((/** * @param {?} propertyName * @return {?} */ function (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 {?} */ StFormComponent.prototype.isRequired = /** * @param {?} propertyName * @return {?} */ function (propertyName) { return propertyName && this.schema.required && this.schema.required.indexOf(propertyName) !== -1; }; /** * @return {?} */ StFormComponent.prototype.isCollapsedSection = /** * @return {?} */ function () { 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 {?} */ StFormComponent.prototype.iShowMoreSection = /** * @return {?} */ function () { return this.schema.type === 'object' && this.schema.ui && this.schema.ui.component === FORM_UI_COMPONENT.SHOW_MORE; }; /** * @param {?} propertyName * @return {?} */ StFormComponent.prototype.isAParentField = /** * @param {?} propertyName * @return {?} */ function (propertyName) { return this.schema.dependencies && this.schema.dependencies[propertyName] && this.schema.dependencies[propertyName].length > 0; }; /** * @return {?} */ StFormComponent.prototype.getOptionalButtonLabel = /** * @return {?} */ function () { /** @type {?} */ var label = 'Additional options'; if (this.parentName || this.schema.title) { label += ' of '; label += this.parentName || this.schema.title; } return label; }; /** * @return {?} */ StFormComponent.prototype.onChangeOptionalFieldsVisibility = /** * @return {?} */ function () { this.showCollapsedSectionFields = !this.showCollapsedSectionFields; }; /** * @param {?} propertyName * @return {?} */ StFormComponent.prototype.getFieldClasses = /** * @param {?} propertyName * @return {?} */ function (propertyName) { return { 'hidden': this.isCollapsedSection() && !this.showCollapsedSectionFields, 'parent-field': this.isAParentField(propertyName) || (this.isASwitchSection() && this.isTheFirstField(propertyName)) }; }; /** * @param {?} propertyName * @return {?} */ StFormComponent.prototype.fieldHasToBeCreated = /** * @param {?} propertyName * @return {?} */ function (propertyName) { /** @type {?} */ var createField = true; /** @type {?} */ var 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 {?} */ StFormComponent.prototype.isRelatedField = /** * @param {?} propertyName * @return {?} */ function (propertyName) { return this.schema.properties[propertyName].ui && this.schema.properties[propertyName].ui.relatedTo; }; // When value is received from outside // When value is received from outside /** * @param {?} value * @return {?} */ StFormComponent.prototype.writeValue = // When value is received from outside /** * @param {?} value * @return {?} */ function (value) { if (value) { this.onChange(value); this.innerValue = value; } }; /** * @param {?} value * @param {?} property * @return {?} */ StFormComponent.prototype.onChangeProperty = /** * @param {?} value * @param {?} property * @return {?} */ function (value, property) { var _this = this; this._value[property] = value; this.valueChange.emit(this._value); setTimeout((/** * @return {?} */ function () { _this.onChange(_this._value); })); }; // Registry the change function to propagate internal model changes // Registry the change function to propagate internal model changes /** * @param {?} fn * @return {?} */ StFormComponent.prototype.registerOnChange = // Registry the change function to propagate internal model changes /** * @param {?} fn * @return {?} */ function (fn) { this.onChange = fn; }; // Registry the touch function to propagate internal touch events TODO: make this function. // Registry the touch function to propagate internal touch events TODO: make this function. /** * @param {?} fn * @return {?} */ StFormComponent.prototype.registerOnTouched = // Registry the touch function to propagate internal touch events TODO: make this function. /** * @param {?} fn * @return {?} */ function (fn) { this.onTouched = fn; }; // Allows Angular to disable the form. // Allows Angular to disable the form. /** * @param {?} disable * @return {?} */ StFormComponent.prototype.setDisabledState = // Allows Angular to disable the form. /** * @param {?} disable * @return {?} */ function (disable) { if (disable) { this.form.control.disable(); } else { this.form.control.enable(); } }; /** * @return {?} */ StFormComponent.prototype.ngOnDestroy = /** * @return {?} */ function () { if (this._parentFieldSubscription) { for (var i = 0; i < this._parentFieldSubscription.length; ++i) { this._parentFieldSubscription[i].unsubscribe(); } } }; /** * @return {?} */ StFormComponent.prototype.isInADisabledSection = /** * @return {?} */ function () { if (this.isASwitchSection()) { /** @type {?} */ var sectionEnabler = Object.keys(this.schema.properties)[0]; return !(this.form && this.form.controls[sectionEnabler] && this.form.controls[sectionEnabler].value); } return false; }; /** * @return {?} */ StFormComponent.prototype.isASwitchSection = /** * @return {?} */ function () { return this.schema.ui && this.schema.ui.component === FORM_UI_COMPONENT.SWITCH; }; /** * @return {?} */ StFormComponent.prototype.isAnAccordion = /** * @return {?} */ function () { return this.schema.ui && this.schema.ui.component === FORM_UI_COMPONENT.ACCORDION; }; /** * @return {?} */ StFormComponent.prototype.onClickTitle = /** * @return {?} */ function () { if (this.isAnAccordion()) { this.onChangeOptionalFieldsVisibility(); } }; /** * @param {?} propertyName * @return {?} */ StFormComponent.prototype.isTheFirstField = /** * @param {?} propertyName * @return {?} */ function (propertyName) { return propertyName === Object.keys(this.schema.properties)[0]; }; /** * @private * @param {?} propertyName * @return {?} */ StFormComponent.prototype.getParentField = /** * @private * @param {?} propertyName * @return {?} */ function (propertyName) { var _this = this; /** @type {?} */ var parentField = undefined; if (this.schema.dependencies) { Object.keys(this.schema.dependencies).forEach((/** * @param {?} key * @return {?} */ function (key) { if (_this.schema.dependencies[key].indexOf(propertyName) !== -1) { parentField = key; } })); } return parentField; }; /** * @private * @param {?} propertyName * @return {?} */ StFormComponent.prototype.fulfillDependencyVisibility = /** * @private * @param {?} propertyName * @return {?} */ function (propertyName) { /** @type {?} */ var fulfill = true; /** @type {?} */ var propertySchema = this.schema.properties[propertyName]; if (propertySchema.ui && propertySchema.ui.visible) { /** @type {?} */ var keys = Object.keys(propertySchema.ui.visible); /** @type {?} */ var 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 {?} */ function () { return StFormComponent; })), multi: true }, { provide: NG_VALIDATORS, useExisting: forwardRef((/** * @return {?} */ function () { 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 },] }] }; return StFormComponent; }()); export { StFormComponent }; 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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3QtZm9ybS5jb21wb25lbnQuanMiLCJzb3VyY2VSb290Ijoibmc6Ly9Ac3RyYXRpby9lZ2VvLyIsInNvdXJjZXMiOlsibGliL3N0LWZvcm0vc3QtZm9ybS5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7O0FBVUEsT0FBTyxFQUNKLFNBQVMsRUFDVCxLQUFLLEVBQ0wsTUFBTSxFQUNOLFVBQVUsRUFDVixTQUFTLEVBQ1QsWUFBWSxFQUNaLHVCQUF1QixFQUt6QixNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQXdCLGlCQUFpQixFQUFFLE1BQU0sRUFBRSxhQUFhLEVBQWUsTUFBTSxnQkFBZ0IsQ0FBQztBQUc3RyxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxpQ0FBaUMsQ0FBQzs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFpQnBFO0lBQUE7Ozs7UUFrQlksaUJBQVksR0FBVyxDQUFDLENBQUM7Ozs7O1FBTXpCLDJCQUFzQixHQUFXLGdDQUFnQyxDQUFDOzs7OztRQUtsRSw0QkFBdUIsR0FBVyxDQUFDLENBQUMsQ0FBQzs7Ozs7UUFRckMsaUJBQVksR0FBWSxJQUFJLENBQUM7Ozs7UUFFNUIsZ0JBQVcsR0FBc0IsSUFBSSxZQUFZLEVBQU8sQ0FBQztRQUk1RCwrQkFBMEIsR0FBWSxLQUFLLENBQUM7UUFDNUMsZUFBVSxHQUFRLEVBQUUsQ0FBQztRQUNwQixXQUFNLEdBQVEsRUFBRSxDQUFDO1FBQ2pCLDZCQUF3QixHQUFtQixFQUFFLENBQUM7UUF3Q3RELGNBQVM7OztRQUFHO1FBQ1osQ0FBQyxFQUFBO0lBeUtKLENBQUM7Ozs7SUEvTUUsa0NBQVE7OztJQUFSO1FBQ0csSUFBSSxJQUFJLENBQUMsTUFBTSxDQUFDLFlBQVksRUFBRTtZQUMzQixJQUFJLENBQUMsYUFBYSxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxZQUFZLENBQUMsQ0FBQztTQUM3RDtJQUNKLENBQUM7Ozs7SUFFRCx5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Ozs7O0lBRXRDLHNDQUFtRTs7SUFFbkUsK0JBQWlEOztJQUVqRCxxREFBbUQ7O0lBQ25ELHFDQUE0Qjs7Ozs7SUFDNUIsaUNBQXlCOzs7OztJQUN6QixtREFBc0Q7Ozs7O0lBQ3RELHdDQUFnQzs7SUF1Q2hDLG9DQUNDIiwic291cmNlc0NvbnRlbnQiOlsiLypcbiAqIMKpIDIwMTcgU3RyYXRpbyBCaWcgRGF0YSBJbmMuLCBTdWN1cnNhbCBlbiBFc3Bhw7FhLlxuICpcbiAqIFRoaXMgc29mdHdhcmUgaXMgbGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMC5cbiAqIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7XG4gKiB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLlxuICogU2VlIHRoZSB0ZXJtcyBvZiB0aGUgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLlxuICpcbiAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBBcGFjaGUtMi4wLlxuICovXG5pbXBvcnQge1xuICAgQ29tcG9uZW50LFxuICAgSW5wdXQsXG4gICBPdXRwdXQsXG4gICBmb3J3YXJkUmVmLFxuICAgVmlld0NoaWxkLFxuICAgRXZlbnRFbWl0dGVyLFxuICAgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksXG4gICBBZnRlclZpZXdDaGVja2VkLFxuICAgT25Jbml0LFxuICAgT25EZXN0cm95LFxuICAgQWZ0ZXJWaWV3SW5pdFxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IENvbnRyb2xWYWx1ZUFjY2Vzc29yLCBOR19WQUxVRV9BQ0NFU1NPUiwgTmdGb3JtLCBOR19WQUxJREFUT1JTLCBGb3JtQ29udHJvbCB9IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcbmltcG9ydCB7IFN1YnNjcmlwdGlvbiB9IGZyb20gJ3J4anMnO1xuXG5pbXBvcnQgeyBGT1JNX1VJX0NPTVBPTkVOVCB9IGZyb20gJy4vc2hhcmVkL3VpLWNvbXBvbmVudC5pbnRlcmZhY2UnO1xuLyoqXG4gKiBAZGVzY3JpcHRpb24ge0NvbXBvbmVudH0gW0R5bmFtaWMgZm9ybV1cbiAqXG4gKiBUaGUgZm9ybSBjb21wb25lbnQgYWxsb3dzIHRvIGdlbmVyYXRlIGZvcm1zIGR5bmFtaWNhbGx5IHVzaW5nIGEgSlNPTiBzY2hlbWEuXG4gKlxuICogQGV4YW1wbGVcbiAqXG4gKiB7aHRtbH1cbiAqXG4gKiBgYGBcbiAqIDxzdC1mb3JtIFtzY2hlbWFdPVwianNvblNjaGVtYVwiIFsobmdNb2RlbCldPVwibW9kZWxcIiAjZm9ybU1vZGVsPVwibmdNb2RlbFwiPlxuICogPC9zdC1mb3JtPlxuICpcbiAqIGBgYFxuICpcbiAqL1xuQENvbXBvbmVudCh7XG4gICBzZWxlY3RvcjogJ3N0LWZvcm0nLFxuICAgdGVtcGxhdGVVcmw6ICcuL3N0LWZvcm0uY29tcG9uZW50Lmh0bWwnLFxuICAgc3R5bGVVcmxzOiBbJy4vc3QtZm9ybS5jb21wb25lbnQuc2NzcyddLFxuICAgaG9zdDogeyBjbGFzczogJ3N0LWZvcm0nIH0sXG4gICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaCxcbiAgIHByb3ZpZGVyczogW1xuICAgICAgeyBwcm92aWRlOiBOR19WQUxVRV9BQ0NFU1NPUiwgdXNlRXhpc3Rpbmc6IGZvcndhcmRSZWYoKCkgPT4gU3RGb3JtQ29tcG9uZW50KSwgbXVsdGk6IHRydWUgfSxcbiAgICAgIHsgcHJvdmlkZTogTkdfVkFMSURBVE9SUywgdXNlRXhpc3Rpbmc6IGZvcndhcmRSZWYoKCkgPT4gU3RGb3JtQ29tcG9uZW50KSwgbXVsdGk6IHRydWUgfVxuICAgXVxufSlcblxuZXhwb3J0IGNsYXNzIFN0Rm9ybUNvbXBvbmVudCBpbXBsZW1lbnRzIEFmdGVyVmlld0luaXQsIEFmdGVyVmlld0NoZWNrZWQsIENvbnRyb2xWYWx1ZUFjY2Vzc29yLCBPbkluaXQsIE9uRGVzdHJveSB7XG4gICAvKiogQElucHV0IHthbnl9IFtzY2hlbWE9XSBKU09OIHNjaGVtYSBuZWVkZWQgdG8gZ2VuZXJhdGUgdGhlIGZvcm0gKi9cbiAgIEBJbnB1dCgpIHNjaGVtYTogYW55O1xuICAgLyoqIEBJbnB1dCB7c3RyaW5nfSBbcGFyZW50TmFtZT1dIE5hbWUgb2YgdGhlIHBhcmVudCBzZWN0aW9uLiBCeSBkZWZhdWx0LCBpdCBpcyB1bmRlZmluZWQgKi9cbiAgIEBJbnB1dCgpIHBhcmVudE5hbWU6IHN0cmluZztcbiAgIC8qKiBASW5wdXQge3N0cmluZ30gW25lc3RpbmdMZXZlbD0wXSBUaGlzIGluZm9ybXMgYWJvdXQgdGhlIG5lc3RpbmcgbGV2ZWwgb2YgdGhlIGZvcm0uIFRoaXMgaW5wdXQgaXMgb25seSB1c2VkIGZvciBkZXNpZ24gcHVycG9zZXMgKi9cbiAgIEBJbnB1dCgpIG5lc3RpbmdMZXZlbDogbnVtYmVyID0gMDtcbiAgIC8qKiBASW5wdXQge2Jvb2xlYW59IFtmb3JjZVZhbGlkYXRpb25zPV0gQm9vbGVhbiB0byBmb3JjZSB0aGUgZmllbGQgdmFsaWRhdGlvbnMgKi9cbiAgIEBJbnB1dCgpIGZvcmNlVmFsaWRhdGlvbnM6IGJvb2xlYW47XG4gICAvKiogQElucHV0IHtzdHJpbmd9IFtkaXNhYmxlZFNlY3Rpb25NZXNzYWdlPSdmb3IgdGhpcyBpbnN0YW5jZSBpcyBkaXNhYmxlZC4nXVxuICAgICogIE1lc3NhZ2UgZGlzcGxheWVkIHdoZW4gYSBzZWN0aW9uIGlzIGRpc2FibGVkLiBUaGlzIGlzIGFsd2F5cyBkaXNwbGF5ZWQgYWZ0ZXIgdGhlIHNlY3Rpb24gbmFtZVxuICAgICovXG4gICBASW5wdXQoKSBkaXNhYmxlZFNlY3Rpb25NZXNzYWdlOiBzdHJpbmcgPSAnZm9yIHRoaXMgaW5zdGFuY2UgaXMgZGlzYWJsZWQuJztcblxuICAgLyoqIEBJbnB1dCB7bnVtYmVyfSBbc2VjdGlvbkRlc2NyaXB0aW9uTGV2ZWw9LTFdIExldmVsIG9mIHRoZSBzZWN0aW9uIHRvIHdoaWNoIGRlc2NyaXB0aW9uIGlzIGRpc3BsYXllZC5cbiAgICAqIEJ5IGRlZmF1bHQsIHNlY3Rpb24gZGVzY3JpcHRpb25zIGFyZSBub3QgZGlzcGxheWVkLlxuICAgICovXG4gICBASW5wdXQoKSBzZWN0aW9uRGVzY3JpcHRpb25MZXZlbDogbnVtYmVyID0gLTE7XG5cbiAgIC8qKiBASW5wdXQge251bWJlcn0gW3RleHRGaWVsZE1heFdpZHRoPV0gTWF4aW11bSB3aWR0aCBvZiBhIGZpZWxkIG5lZWRlZCB0byBwYWludCBhIGlucHV0IG9yIHRleHRhcmVhICovXG4gICBASW5wdXQoKSB0ZXh0RmllbGRNYXhXaWR0aDogbnVtYmVyO1xuXG4gICAvKiogQElucHV0IHtib29sZWFufSBbc2hvd1Rvb2x0aXBzPS0xXSBFbmFibGUgb3IgZGlzYWJsZSBkaXNwbGF5aW5nIG9mIHRvb2x0aXBzXG4gICAgKiBCeSBkZWZhdWx0LCB0b29sdGlwcyBhcmUgZGlzcGxheWVkXG4gICAgKi9cbiAgIEBJbnB1dCgpIHNob3dUb29sdGlwczogYm9vbGVhbiA9IHRydWU7XG4gICAvKiogQE91dHB1dCB7YW55fSBbdmFsdWVDaGFuZ2U9XSBFdmVudCBlbWl0dGVkIHdoZW4gdmFsdWUgaXMgY2hhbmdlZC4gVGhpcyBlbWl0cyB0aGUgY3VycmVudCBmb3JtIHZhbHVlICovXG4gICBAT3V0cHV0KCkgdmFsdWVDaGFuZ2U6IEV2ZW50RW1pdHRlcjxhbnk+ID0gbmV3IEV2ZW50RW1pdHRlcjxhbnk+KCk7XG5cbiAgIEBWaWV3Q2hpbGQoJ2Zvcm0nLCB7c3RhdGljOiBmYWxzZX0pIGZvcm06IE5nRm9ybTtcblxuICAgcHVibGljIHNob3dDb2xsYXBzZWRTZWN0aW9uRmllbGRzOiBib29sZWFuID0gZmFsc2U7XG4gICBwdWJsaWMgaW5uZXJWYWx1ZTogYW55ID0ge307XG4gICBwcml2YXRlIF92YWx1ZTogYW55ID0ge307XG4gICBwcml2YXRlIF9wYXJlbnRGaWVsZFN1YnNjcmlwdGlvbjogU3Vic2NyaXB0aW9uW10gPSBbXTtcbiAgIHByaXZhdGUgX3BhcmVudEZpZWxkczogc3RyaW5nW107XG5cbiAgIG5nT25Jbml0KCk6IHZvaWQge1xuICAgICAgaWYgKHRoaXMuc2NoZW1hLmRlcGVuZGVuY2llcykge1xuICAgICAgICAgdGhpcy5fcGFyZW50RmllbGRzID0gT2JqZWN0LmtleXModGhpcy5zY2hlbWEuZGVwZW5kZW5jaWVzKTtcbiAgICAgIH1cbiAgIH1cblxuICAgbmdBZnRlclZpZXdJbml0KCk6IHZvaWQge1xuICAgICAgaWYgKCF0aGlzLmZvcmNlVmFsaWRhdGlvbnMpIHtcbiAgICAgICAgICAgIHRoaXMuZm9ybS5mb3JtLm1hcmtBc1ByaXN0aW5lKCk7XG4gICAgICB9XG4gICB9XG5cbiAgIG5nQWZ0ZXJWaWV3Q2hlY2tlZCgpOiB2b2lkIHtcbiAgICAgIGlmICh0aGlzLl9wYXJlbnRGaWVsZHMgJiYgdGhpcy5mb3JtLmNvbnRyb2wgJiYgdGhpcy5mb3JtLmNvbnRyb2wuY29udHJvbHMpIHtcbiAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5fcGFyZW50RmllbGRzLmxlbmd0aDsgKytpKSB7XG4gICAgICAgICAgICBsZXQgcGFyZW50RmllbGQ6IHN0cmluZyA9IHRoaXMuX3BhcmVudEZpZWxkc1tpXTtcbiAgICAgICAgICAgIGlmICghdGhpcy5fcGFyZW50RmllbGRTdWJzY3JpcHRpb25baV0gJiYgdGhpcy5mb3JtLmNvbnRyb2wuY29udHJvbHNbcGFyZW50RmllbGRdKSB7XG5cbiAgICAgICAgICAgICAgIHRoaXMuX3BhcmVudEZpZWxkU3Vic2NyaXB0aW9uW2ldID0gdGhpcy5mb3JtLmNvbnRyb2wuY29udHJvbHNbdGhpcy5fcGFyZW50RmllbGRzW2ldXS52YWx1ZUNoYW5nZXMuc3Vic2NyaWJlKCh2YWx1ZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgaWYgKCF2YWx1ZSkge1xuICAgICAgICAgICAgICAgICAgICAgbGV0IGNoaWxkcmVuRmllbGRzOiBzdHJpbmdbXSA9IHRoaXMuc2NoZW1hLmRlcGVuZGVuY2llc1twYXJlbnRGaWVsZF07XG4gICAgICAgICAgICAgICAgICAgICBmb3IgKGxldCBqID0gMDsgaiA8IGNoaWxkcmVuRmllbGRzLmxlbmd0aDsgKytqKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5mb3JtLmNvbnRyb2xzW2NoaWxkcmVuRmllbGRzW2pdXSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5fdmFsdWVbY2hpbGRyZW5GaWVsZHNbal1dID0gdW5kZWZpbmVkO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICB9XG4gICAgICB9XG4gICB9XG5cbiAgIC8vIEZ1bmN0aW9uIHRvIGNhbGwgd2hlbiB0aGUgdmFsdWUgY2hhbmdlcy5cbiAgIG9uQ2hhbmdlKF86IGFueSk6IHZvaWQge1xuICAgfVxuXG4gICBvblRvdWNoZWQgPSAoKSA9PiB7XG4gICB9XG5cbiAgIHZhbGlkYXRlKGNvbnRyb2w6IEZvcm1Db250cm9sKTogYW55IHtcbiAgICAgIGxldCBlcnJvcnM6IGFueSA9IG51bGw7XG4gICAgICBpZiAodGhpcy5mb3JtKSB7XG4gICAgICAgICBPYmplY3Qua2V5cyh0aGlzLmZvcm0uY29udHJvbHMpLmZvckVhY2goKHByb3BlcnR5TmFtZSkgPT4ge1xuICAgICAgICAgICAgaWYgKHRoaXMuZm9ybS5jb250cm9sc1twcm9wZXJ0eU5hbWVdICYmIHRoaXMuZm9ybS5jb250cm9sc1twcm9wZXJ0eU5hbWVdLmVycm9ycykge1xuICAgICAgICAgICAgICAgaWYgKCFlcnJvcnMpIHtcbiAgICAgICAgICAgICAgICAgIGVycm9ycyA9IHt9O1xuICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgZXJyb3JzW3Byb3BlcnR5TmFtZV0gPSB0aGlzLmZvcm0uY29udHJvbHNbcHJvcGVydHlOYW1lXS5lcnJvcnM7XG4gICAgICAgICAgICB9XG4gICAgICAgICB9KTtcblxuICAgICAgICAgdGhpcy5mb3JtLmNvbnRyb2wuc2V0RXJyb3JzKGVycm9ycyk7XG4gICAgICB9XG4gICAgICByZXR1cm4gZXJyb3JzO1xuICAgfVxuXG4gICBpc1JlcXVpcmVkKHByb3BlcnR5TmFtZTogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgICByZXR1cm4gcHJvcGVydHlOYW1lICYmIHRoaXMuc2NoZW1hLnJlcXVpcmVkICYmIHRoaXMuc2NoZW1hLnJlcXVpcmVkLmluZGV4T2YocHJvcGVydHlOYW1lKSAhPT0gLTE7XG4gICB9XG5cbiAgIGlzQ29sbGFwc2VkU2VjdGlvbigpOiBib29sZWFuIHtcbiAgICAgIHJldHVybiB0aGlzLnNjaGVtYS50eXBlID09PSAnb2JqZWN0JyAmJiB0aGlzLnNjaGVtYS51aSAmJlxuICAgICAgICAgKHRoaXMuc2NoZW1hLnVpLmNvbXBvbmVudCA9PT0gRk9STV9VSV9DT01QT05FTlQuU0hPV19NT1JFIHx8IHRoaXMuc2NoZW1hLnVpLmNvbXBvbmVudCA9PT0gRk9STV9VSV9DT01QT05FTlQuQUNDT1JESU9OKTtcbiAgIH1cblxuICAgaVNob3dNb3JlU2VjdGlvbigpOiBib29sZWFuIHtcbiAgICAgIHJldHVybiB0aGlzLnNjaGVtYS50eXBlID09PSAnb2JqZWN0JyAmJiB0aGlzLnNjaGVtYS51aSAmJiB0aGlzLnNjaGVtYS51aS5jb21wb25lbnQgPT09IEZPUk1fVUlfQ09NUE9ORU5ULlNIT1dfTU9SRTtcbiAgIH1cblxuICAgaXNBUGFyZW50RmllbGQocHJvcGVydHlOYW1lOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICAgIHJldHVybiB0aGlzLnNjaGVtYS5kZXBlbmRlbmNpZXMgJiYgdGhpcy5zY2hlbWEuZGVwZW5kZW5jaWVzW3Byb3BlcnR5TmFtZV0gJiYgdGhpcy5zY2hlbWEuZGVwZW5kZW5jaWVzW3Byb3BlcnR5TmFtZV0ubGVuZ3RoID4gMDtcbiAgIH1cblxuICAgZ2V0T3B0aW9uYWxCdXR0b25MYWJlbCgpOiBzdHJpbmcge1xuICAgICAgbGV0IGxhYmVsOiBzdHJpbmcgPSAnQWRkaXRpb25hbCBvcHRpb25zJztcblxuICAgICAgaWYgKHRoaXMucGFyZW50TmFtZSB8fCB0aGlzLnNjaGVtYS50aXRsZSkge1xuICAgICAgICAgbGFiZWwgKz0gJyBvZiAnO1xuICAgICAgICAgbGFiZWwgKz0gdGhpcy5wYXJlbnROYW1lIHx8IHRoaXMuc2NoZW1hLnRpdGxlO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gbGFiZWw7XG4gICB9XG5cbiAgIG9uQ2hhbmdlT3B0aW9uYWxGaWVsZHNWaXNpYmlsaXR5KCk6IHZvaWQge1xuICAgICAgdGhpcy5zaG93Q29sbGFwc2VkU2VjdGlvbkZpZWxkcyA9ICF0aGlzLnNob3dDb2xsYXBzZWRTZWN0aW9uRmllbGRzO1xuICAgfVxuXG4gICBnZXRGaWVsZENsYXNzZXMocHJvcGVydHlOYW1lOiBzdHJpbmcpOiBhbnkge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgICdoaWRkZW4nOiB0aGlzLmlzQ29sbGFwc2VkU2VjdGlvbigpICYmICF0aGlzLnNob3dDb2xsYXBzZWRTZWN0aW9uRmllbGRzLFxuICAgICAgICAgJ3BhcmVudC1maWVsZCc6IHRoaXMuaXNBUGFyZW50RmllbGQocHJvcGVydHlOYW1lKSB8fCAodGhpcy5pc0FTd2l0Y2hTZWN0aW9uKCkgJiYgdGhpcy5pc1RoZUZpcnN0RmllbGQocHJvcGVydHlOYW1lKSlcbiAgICAgIH07XG4gICB9XG5cbiAgIGZpZWxkSGFzVG9CZUNyZWF0ZWQocHJvcGVydHlOYW1lOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICAgIGxldCBjcmVhdGVGaWVsZDogYm9vbGVhbiA9IHRydWU7XG4gICAgICBsZXQgcGFyZW50RmllbGQ6IHN0cmluZyA9IHRoaXMuZ2V0UGFyZW50RmllbGQocHJvcGVydHlOYW1lKTtcbiAgICAgIGlmICgoKHBhcmVudEZpZWxkICYmICF0aGlzLl92YWx1ZVtwYXJlbnRGaWVsZF0pIHx8ICh0aGlzLmlzSW5BRGlzYWJsZWRTZWN0aW9uKCkgJiYgIXRoaXMuaXNUaGVGaXJzdEZpZWxkKHByb3BlcnR5TmFtZSkpKVxuICAgICAgICAgfHwgIXRoaXMuZnVsZmlsbERlcGVuZGVuY3lWaXNpYmlsaXR5KHByb3BlcnR5TmFtZSkpIHtcbiAgICAgICAgIGNyZWF0ZUZpZWxkID0gZmFsc2U7XG4gICAgICAgICB0aGlzLl92YWx1ZVtwcm9wZXJ0eU5hbWVdID0gdW5kZWZpbmVkO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGNyZWF0ZUZpZWxkO1xuICAgfVxuXG4gICBpc1JlbGF0ZWRGaWVsZChwcm9wZXJ0eU5hbWU6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgICAgcmV0dXJuIHRoaXMuc2NoZW1hLnByb3BlcnRpZXNbcHJvcGVydHlOYW1lXS51aSAmJiB0aGlzLnNjaGVtYS5wcm9wZXJ0aWVzW3Byb3BlcnR5TmFtZV0udWkucmVsYXRlZFRvO1xuICAgfVxuXG4gICAvLyBXaGVuIHZhbHVlIGlzIHJlY2VpdmVkIGZyb20gb3V0c2lkZVxuICAgd3JpdGVWYWx1ZSh2YWx1ZTogYW55KTogdm9pZCB7XG4gICAgICBpZiAodmFsdWUpIHtcbiAgICAgICAgIHRoaXMub25DaGFuZ2UodmFsdWUpO1xuICAgICAgICAgdGhpcy5pbm5lclZhbHVlID0gdmFsdWU7XG4gICAgICB9XG4gICB9XG5cbiAgIG9uQ2hhbmdlUHJvcGVydHkodmFsdWU6IGFueSwgcHJvcGVydHk6IHN0cmluZyk6IHZvaWQge1xuICAgICAgdGhpcy5fdmFsdWVbcHJvcGVydHldID0gdmFsdWU7XG4gICAgICB0aGlzLnZhbHVlQ2hhbmdlLmVtaXQodGhpcy5fdmFsdWUpO1xuICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICB0aGlzLm9uQ2hhbmdlKHRoaXMuX3ZhbHVlKTtcbiAgICAgIH0pO1xuICAgfVxuXG4gICAvLyBSZWdpc3RyeSB0aGUgY2hhbmdlIGZ1bmN0aW9uIHRvIHByb3BhZ2F0ZSBpbnRlcm5hbCBtb2RlbCBjaGFuZ2VzXG4gICByZWdpc3Rlck9uQ2hhbmdlKGZuOiAoXzogYW55KSA9PiB2b2lkKTogdm9pZCB7XG4gICAgICB0aGlzLm9uQ2hhbmdlID0gZm47XG4gICB9XG5cbiAgIC8vIFJlZ2lzdHJ5IHRoZSB0b3VjaCBmdW5jdGlvbiB0byBwcm9wYWdhdGUgaW50ZXJuYWwgdG91Y2ggZXZlbnRzIFRPRE86IG1ha2UgdGhpcyBmdW5jdGlvbi5cbiAgIHJlZ2lzdGVyT25Ub3VjaGVkKGZuOiAoKSA9PiB2b2lkKTogdm9pZCB7XG4gICAgICB0aGlzLm9uVG91Y2hlZCA9IGZuO1xuICAgfVxuXG4gICAvLyBBbGxvd3MgQW5ndWxhciB0byBkaXNhYmxlIHRoZSBmb3JtLlxuICAgc2V0RGlzYWJsZWRTdGF0ZShkaXNhYmxlOiBib29sZWFuKTogdm9pZCB7XG4gICAgICBpZiAoZGlzYWJsZSkge1xuICAgICAgICAgdGhpcy5mb3JtLmNvbnRyb2wuZGlzYWJsZSgpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgIHRoaXMuZm9ybS5jb250cm9sLmVuYWJsZSgpO1xuICAgICAgfVxuICAgfVxuXG4gICBuZ09uRGVzdHJveSgpOiB2b2lkIHtcbiAgICAgIGlmICh0aGlzLl9wYXJlbnRGaWVsZFN1YnNjcmlwdGlvbikge1xuICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLl9wYXJlbnRGaWVsZFN1YnNjcmlwdGlvbi5sZW5ndGg7ICsraSkge1xuICAgICAgICAgICAgdGhpcy5fcGFyZW50RmllbGRTdWJzY3JpcHRpb25baV0udW5zdWJzY3JpYmUoKTtcbiAgICAgICAgIH1cbiAgICAgIH1cbiAgIH1cblxuICAgaXNJbkFEaXNhYmxlZFNlY3Rpb24oKTogYm9vbGVhbiB7XG4gICAgICBpZiAodGhpcy5pc0FTd2l0Y2hTZWN0aW9uKCkpIHtcbiAgICAgICAgIGxldCBzZWN0aW9uRW5hYmxlcjogc3RyaW5nID0gT2JqZWN0LmtleXModGhpcy5zY2hlbWEucHJvcGVydGllcylbMF07XG4gICAgICAgICByZXR1cm4gISh0aGlzLmZvcm0gJiYgdGhpcy5mb3JtLmNvbnRyb2xzW3NlY3Rpb25FbmFibGVyXSAmJiB0aGlzLmZvcm0uY29udHJvbHNbc2VjdGlvbkVuYWJsZXJdLnZhbHVlKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBmYWxzZTtcbiAgIH1cblxuICAgaXNBU3dpdGNoU2VjdGlvbigpOiBib29sZWFuIHtcbiAgICAgIHJldHVybiB0aGlzLnNjaGVtYS51aSAmJiB0aGlzLnNjaGVtYS51aS5jb21wb25lbnQgPT09IEZPUk1fVUlfQ09NUE9ORU5ULlNXSVRDSDtcbiAgIH1cblxuICAgaXNBbkFjY29yZGlvbigpOiBib29sZWFuIHtcbiAgICAgIHJldHVybiB0aGlzLnNjaGVtYS51aSAmJiB0aGlzLnNjaGVtYS51aS5jb21wb25lbnQgPT09IEZPUk1fVUlfQ09NUE9ORU5ULkFDQ09SRElPTjtcbiAgIH1cblxuICAgb25DbGlja1RpdGxlKCk6IHZvaWQge1xuICAgICAgaWYgKHRoaXMuaXNBbkFjY29yZGlvbigpKSB7XG4gICAgICAgICB0aGlzLm9uQ2hhbmdlT3B0aW9uYWxGaWVsZHNWaXNpYmlsaXR5KCk7XG4gICAgICB9XG4gICB9XG5cbiAgIGlzVGhlRmlyc3RGaWVsZChwcm9wZXJ0eU5hbWU6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgICAgcmV0dXJuIHByb3BlcnR5TmFtZSA9PT0gT2JqZWN0LmtleXModGhpcy5zY2hlbWEucHJvcGVydGllcylbMF07XG4gICB9XG5cbiAgIHByaXZhdGUgZ2V0UGFyZW50RmllbGQocHJvcGVydHlOYW1lOiBzdHJpbmcpOiBzdHJpbmcge1xuICAgICAgbGV0IHBhcmVudEZpZWxkOiBzdHJpbmcgPSB1bmRlZmluZWQ7XG4gICAgICBpZiAodGhpcy5zY2hlbWEuZGVwZW5kZW5jaWVzKSB7XG4gICAgICAgICBPYmplY3Qua2V5cyh0aGlzLnNjaGVtYS5kZXBlbmRlbmNpZXMpLmZvckVhY2goKGtleTogc3RyaW5nKSA9PiB7XG4gICAgICAgICAgICBpZiAodGhpcy5zY2hlbWEuZGVwZW5kZW5jaWVzW2tleV0uaW5kZXhPZihwcm9wZXJ0eU5hbWUpICE9PSAtMSkge1xuICAgICAgICAgICAgICAgcGFyZW50RmllbGQgPSBrZXk7XG4gICAgICAgICAgICB9XG4gICAgICAgICB9KTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBwYXJlbnRGaWVsZDtcbiAgIH1cblxuICAgcHJpdmF0ZSBmdWxmaWxsRGVwZW5kZW5jeVZpc2liaWxpdHkocHJvcGVydHlOYW1lOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICAgIGxldCBmdWxmaWxsOiBib29sZWFuID0gdHJ1ZTtcbiAgICAgIGxldCBwcm9wZXJ0eVNjaGVtYTogYW55ID0gdGhpcy5zY2hlbWEucHJvcGVydGllc1twcm9wZXJ0eU5hbWVdO1xuICAgICAgaWYgKHByb3BlcnR5U2NoZW1hLnVpICYmIHByb3BlcnR5U2NoZW1hLnVpLnZpc2libGUpIHtcbiAgICAgICAgIGNvbnN0IGtleXM6IHN0cmluZ1tdID0gT2JqZWN0LmtleXMocHJvcGVydHlTY2hlbWEudWkudmlzaWJsZSk7XG4gICAgICAgICBsZXQgaSA9IDA7XG4gICAgICAgICB3aGlsZSAoZnVsZmlsbCAmJiBpIDwga2V5cy5sZW5ndGggJiYgcHJvcGVydHlTY2hlbWEudWkudmlzaWJsZS5oYXNPd25Qcm9wZXJ0eShrZXlzW2ldKSkge1xuICAgICAgICAgICAgaWYgKHRoaXMuX3ZhbHVlW2tleXNbaV1dICE9PSBwcm9wZXJ0eVNjaGVtYS51aS52aXNpYmxlW2tleXNbaV1dKSB7XG4gICAgICAgICAgICAgICBmdWxmaWxsID0gZmFsc2U7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICArK2k7XG4gICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gZnVsZmlsbDtcbiAgIH1cbn1cbiJdfQ==