@stratio/egeo
Version:
600 lines • 47.5 kB
JavaScript
/**
* @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==