@stratio/egeo
Version:
663 lines • 48.2 kB
JavaScript
/**
* @fileoverview added by tsickle
* Generated from: lib/st-dynamic-table/st-dynamic-table.component.ts
* @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
import * as tslib_1 from "tslib";
/*
* © 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 { ChangeDetectionStrategy, ChangeDetectorRef, Component, EventEmitter, Input, Output, TemplateRef } from '@angular/core';
import { StEgeo, StRequired } from '../decorators/require-decorators';
import { Order } from '../st-table/shared/order';
import { StDynamicTableUtils } from './utils/st-dynamic-table.utils';
import { StTableIconClasses } from '../st-table/st-table.interface';
/**
* \@description {Component} [Dynamic Table]
*
* The table component has been designed to be able to create a table deducing its columns using a json schema
*
* * \@model
*
* [StDynamicTableHeader] {./st-dynamic-table.model.ts#StDynamicTableHeader}
* [StDynamicTableUISpecification] {./st-dynamic-table.model.ts#StDynamicTableUISpecification}
* [StDynamicTableUserInterface] {./st-dynamic-table.model.ts#StDynamicTableUserInterface}
*
* \@example
*
* {html}
*
* ```
* <st-dynamic-table [jsonSchema]="jsonSchema"
* [items]="sortedUsers"
* [sortable]="true"
* [filterable]="true"
* [hasHoverMenu]="true"
* [currentOrder]="currentOrder"
* [activeHoverMenu]="activeHoverMenuPosition"
* [templateContentFilter]="filterContent"
* (changeOrder)="onSortTable($event)"
* (showHoverMenu)="onShowHoverMenu($event)">
* <st-dropdown-menu st-dynamic-table-hover-menu
* class="hover-menu"
* [items]="rowActions"
* [active]="activeHoverMenuPosition[3] !== undefined"
* [visualMode]="1">
* </st-dropdown-menu>
* </st-dynamic-table>
* ```
*
*/
var StDynamicTableComponent = /** @class */ (function () {
function StDynamicTableComponent(_cd) {
this._cd = _cd;
/**
* \@Input {boolean} [header=true] Boolean to show or hide the header
*/
this.header = true;
/**
* \@Input {boolean} [sortable=true] Boolean to make sortable the table, To enable sorting of columns use
* the new "sortable" field inside stTableHeader model
*/
this.sortable = true;
/**
* \@Input {boolean} [filterable=false] Boolean to make filterable the table, To enable filtering of columns use
* the new "filterable" field inside stTableHeader model (necessary define filterConfig).
*/
this.filterable = false;
/**
* \@Input {boolean} [selectable=false] Boolean to show or hide a checkboxes in the first cell of rows
*/
this.selectable = false;
/**
* \@Input {boolean} [selectableAll=false] Boolean to show or hide a checkbox in the header to select or
* deselect all rows
*/
this.selectableAll = false;
/**
* \@Input {boolean[]} [selected=''] Boolean list to indicate if a row is selected
*/
this.selected = [];
/**
* \@Input {boolean} [fixedHeader=false] Boolean to fix the table header
*/
this.fixedHeader = false;
/**
* \@Input {boolean} [stickyHoverMenu=false] Boolean to fix hover menu always visible
*/
this.stickyHoverMenu = false;
/**
* \@Input {StTableIconClasses} [iconClasses=''] List of icon classes
*/
this.iconClasses = new StTableIconClasses();
/**
* \@Input {string} [hoverButton='icon-ellipsis'] It specifies the icon class of the hover button displayed when user puts mouse over a row
*/
this.hoverButton = 'icon-ellipsis';
/**
* \@Input {string} [locale=en-US] Locale used to format dates
*/
this.locale = 'en-US';
/**
* \@Output {Order} [changeOrder=''] Event emitted with the new order which has to be applied to the table rows
*/
this.changeOrder = new EventEmitter();
/**
* \@Output {boolean} [selectAll=''] Event emitted when user interacts with the checkbox to select or deselect
* all rows
*/
this.selectAll = new EventEmitter();
/**
* \@Output {EventEmitter<StTableHeader[]>} [fields=] Event emitted when header fields are being loaded
*/
this.updateFields = new EventEmitter();
/**
* \@Output {string} [clickFilter=] Event emitted when using filters custom template
*/
this.clickFilter = new EventEmitter();
/**
* \@Output {StTableHeader[]} [selectFilters=] Event emitted when user interacts with filter button without a custom template
*/
this.selectFilters = new EventEmitter();
/**
* \@Output {EventEmitter<number} [showHoverMenu=] Event emitted when user clicks on hover button of a row
*/
this.showHoverMenu = new EventEmitter();
/**
* \@Output {Object(checked: boolean, row: number)} [selectRow=] Event emitted when user clicks on checkbox of a row
*/
this.selectRow = new EventEmitter();
/**
* \@Output {StDynamicTableClickCellEvent} [clickCell=] Event emitted when user clicks on a cell
*/
this.clickCell = new EventEmitter();
this.fields = [];
this.statusFilter = [];
this._fkSeparator = ' - ';
this._activeFilterFields = [];
}
Object.defineProperty(StDynamicTableComponent.prototype, "jsonSchema", {
/** @Input {JSONSchema4} [jsonSchema=] Json schema to define its structure */
get: /**
* \@Input {JSONSchema4} [jsonSchema=] Json schema to define its structure
* @return {?}
*/
function () {
return this._jsonSchema;
},
set: /**
* @param {?} _jsonSchema
* @return {?}
*/
function (_jsonSchema) {
this._jsonSchema = _jsonSchema;
this._manageFieldsUpdate();
},
enumerable: true,
configurable: true
});
Object.defineProperty(StDynamicTableComponent.prototype, "uiDefinitions", {
/** @Input {StDynamicTableUserInterface} [uiDefinitions=''] UI definition for each field */
get: /**
* \@Input {StDynamicTableUserInterface} [uiDefinitions=''] UI definition for each field
* @return {?}
*/
function () {
return this._uiDefinitions;
},
set: /**
* @param {?} _uiDefinitions
* @return {?}
*/
function (_uiDefinitions) {
this._uiDefinitions = _uiDefinitions;
this._manageFieldsUpdate();
},
enumerable: true,
configurable: true
});
Object.defineProperty(StDynamicTableComponent.prototype, "activeFilterFields", {
/** @Input {string[]} [activeFilterFields=] List of current filtered fields */
get: /**
* \@Input {string[]} [activeFilterFields=] List of current filtered fields
* @return {?}
*/
function () {
return this._activeFilterFields;
},
set: /**
* @param {?} _activeFilterFields
* @return {?}
*/
function (_activeFilterFields) {
this._activeFilterFields = _activeFilterFields;
this._updateStatusFilters();
},
enumerable: true,
configurable: true
});
/**
* @param {?} selectedFilter
* @return {?}
*/
StDynamicTableComponent.prototype.onFilterClick = /**
* @param {?} selectedFilter
* @return {?}
*/
function (selectedFilter) {
this.clickFilter.emit(selectedFilter);
};
/**
* @param {?} order
* @return {?}
*/
StDynamicTableComponent.prototype.onChangeOrder = /**
* @param {?} order
* @return {?}
*/
function (order) {
if (order) {
this.changeOrder.emit(order);
}
};
/**
* @param {?} checked
* @return {?}
*/
StDynamicTableComponent.prototype.onSelectAll = /**
* @param {?} checked
* @return {?}
*/
function (checked) {
this.selectAll.emit(checked);
};
/**
* @param {?} selectedFilters
* @return {?}
*/
StDynamicTableComponent.prototype.onSelectedFilters = /**
* @param {?} selectedFilters
* @return {?}
*/
function (selectedFilters) {
this.selectFilters.emit(selectedFilters);
};
/**
* @param {?} row
* @return {?}
*/
StDynamicTableComponent.prototype.onShowHoverMenu = /**
* @param {?} row
* @return {?}
*/
function (row) {
this.showHoverMenu.emit(row);
};
/**
* @return {?}
*/
StDynamicTableComponent.prototype.onLeaveRow = /**
* @return {?}
*/
function () {
this.showHoverMenu.emit(undefined);
};
/**
* @param {?} value
* @param {?} field
* @return {?}
*/
StDynamicTableComponent.prototype.onClickCell = /**
* @param {?} value
* @param {?} field
* @return {?}
*/
function (value, field) {
if (field.clickable) {
this.clickCell.emit({
header: field,
value: value
});
}
};
/**
* @param {?} item
* @param {?} field
* @return {?}
*/
StDynamicTableComponent.prototype.getCellContent = /**
* @param {?} item
* @param {?} field
* @return {?}
*/
function (item, field) {
if (field.fk && field.group) {
/** @type {?} */
var groupLabel = field.group.split(this._fkSeparator)
.map((/**
* @param {?} _groupKey
* @return {?}
*/
function (_groupKey) { return item[_groupKey]; }))
.join(this._fkSeparator);
return groupLabel.length > this._fkSeparator.length ? groupLabel : item[field.id];
}
/** @type {?} */
var uiDefinition = this.uiDefinitions && this.uiDefinitions[field.id];
if (uiDefinition && uiDefinition.dateFormat) {
return StDynamicTableUtils.formatDate((/** @type {?} */ (item[field.id])), uiDefinition.dateFormat, this.locale);
}
return item[field.id];
};
/**
* @param {?} field
* @return {?}
*/
StDynamicTableComponent.prototype.getCellStyles = /**
* @param {?} field
* @return {?}
*/
function (field) {
/** @type {?} */
var uiDefinition = this.uiDefinitions && this.uiDefinitions[field.id];
return uiDefinition && uiDefinition.styles;
};
/**
* @param {?} checkboxEvent
* @param {?} row
* @return {?}
*/
StDynamicTableComponent.prototype.onSelectRow = /**
* @param {?} checkboxEvent
* @param {?} row
* @return {?}
*/
function (checkboxEvent, row) {
this.selectRow.emit({ checked: checkboxEvent.checked, row: row });
};
/**
* @private
* @return {?}
*/
StDynamicTableComponent.prototype._manageFieldsUpdate = /**
* @private
* @return {?}
*/
function () {
this.fields = StDynamicTableUtils.getHeaderFieldsFromJsonSchema(this._jsonSchema, this._uiDefinitions);
this.updateFields.emit(this.fields);
this._updateStatusFilters();
this._cd.markForCheck();
};
/**
* @private
* @return {?}
*/
StDynamicTableComponent.prototype._updateStatusFilters = /**
* @private
* @return {?}
*/
function () {
var _this = this;
this.statusFilter = [];
if (this._activeFilterFields && this._activeFilterFields.length && this.fields && this.fields.length) {
this._activeFilterFields.forEach((/**
* @param {?} _fieldId
* @return {?}
*/
function (_fieldId) {
/** @type {?} */
var position = _this.fields.findIndex((/**
* @param {?} _field
* @return {?}
*/
function (_field) { return _field.id === _fieldId; }));
if (position > -1) {
_this.statusFilter[position] = true;
}
}));
}
};
StDynamicTableComponent.ctorParameters = function () { return [
{ type: ChangeDetectorRef }
]; };
StDynamicTableComponent.decorators = [
{ type: Component, args: [{
selector: 'st-dynamic-table',
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\n<st-table *ngIf=\"fields && fields.length && items\"\n class=\"st-dynamic-table\"\n [fields]=\"fields\"\n [header]=\"header\"\n [sortable]=\"sortable\"\n [filterable]=\"filterable\"\n [selectableAll]=\"selectableAll\"\n [hasHoverMenu]=\"hasHoverMenu\"\n [fixedHeader]=\"fixedHeader\"\n [stickyHoverMenu]=\"stickyHoverMenu\"\n [currentOrder]=\"currentOrder\"\n [customClasses]=\"customClasses\"\n [selectedAll]=\"selectedAll\"\n [templateContentFilter]=\"templateContentFilter\"\n [statusFilter]=\"statusFilter\"\n [iconClasses]=\"iconClasses\"\n (selectAll)=\"onSelectAll($event)\"\n (changeOrder)=\"onChangeOrder($event)\"\n (selectFilters)=\"onSelectedFilters($event)\"\n (clickFilter)=\"onFilterClick($event)\">\n <tbody>\n <tr st-table-row *ngFor=\"let item of items; let row = index\" [selected]=\"selected[row]\" (mouseleave)=\"onLeaveRow()\">\n <td st-table-cell st-table-row-content\n *ngFor=\"let field of fields; let cell = index\"\n [ngStyle]=\"getCellStyles(fields[cell])\">\n\n <st-checkbox *ngIf=\"selectable && !cell\"\n class=\"st-table__checkbox\"\n [checked]=\"selected[row]\"\n (change)=\"onSelectRow($event, row)\">\n </st-checkbox>\n <span\n [ngClass]=\"{clickable: field.clickable}\"\n (click)=\"onClickCell(item[field.id], field)\">\n {{getCellContent(item, field)}}\n </span>\n </td>\n <td st-table-row-hover class=\"st-table-hover\" *ngIf=\"hasHoverMenu\">\n <i class=\"icon {{hoverButton}}\" (click)=\"onShowHoverMenu(row)\"></i>\n <ng-content select='[st-dynamic-table-hover-menu]' *ngIf=\"activeHoverMenu === row\"></ng-content>\n </td>\n </tr>\n </tbody>\n</st-table>\n",
changeDetection: ChangeDetectionStrategy.OnPush,
styles: ["@charset \"UTF-8\";:host{width:100%}:host .st-dynamic-table{max-height:100%;min-width:100%}:host .st-table-hover>i{cursor:pointer}:host .clickable{cursor:pointer}"]
}] }
];
/** @nocollapse */
StDynamicTableComponent.ctorParameters = function () { return [
{ type: ChangeDetectorRef }
]; };
StDynamicTableComponent.propDecorators = {
items: [{ type: Input }],
qaTag: [{ type: Input }],
header: [{ type: Input }],
sortable: [{ type: Input }],
filterable: [{ type: Input }],
selectable: [{ type: Input }],
selectableAll: [{ type: Input }],
selected: [{ type: Input }],
currentOrder: [{ type: Input }],
customClasses: [{ type: Input }],
fixedHeader: [{ type: Input }],
stickyHoverMenu: [{ type: Input }],
iconClasses: [{ type: Input }],
activeHoverMenu: [{ type: Input }],
hasHoverMenu: [{ type: Input }],
hoverButton: [{ type: Input }],
selectedAll: [{ type: Input }],
locale: [{ type: Input }],
templateContentFilter: [{ type: Input }],
changeOrder: [{ type: Output }],
selectAll: [{ type: Output }],
updateFields: [{ type: Output }],
clickFilter: [{ type: Output }],
selectFilters: [{ type: Output }],
showHoverMenu: [{ type: Output }],
selectRow: [{ type: Output }],
clickCell: [{ type: Output }],
jsonSchema: [{ type: Input }],
uiDefinitions: [{ type: Input }],
activeFilterFields: [{ type: Input }]
};
tslib_1.__decorate([
StRequired(),
tslib_1.__metadata("design:type", Array)
], StDynamicTableComponent.prototype, "items", void 0);
tslib_1.__decorate([
StRequired(),
tslib_1.__metadata("design:type", Object),
tslib_1.__metadata("design:paramtypes", [Object])
], StDynamicTableComponent.prototype, "jsonSchema", null);
/**
* \@description {Component} [Dynamic Table]
*
* The table component has been designed to be able to create a table deducing its columns using a json schema
*
* * \@model
*
* [StDynamicTableHeader] {./st-dynamic-table.model.ts#StDynamicTableHeader}
* [StDynamicTableUISpecification] {./st-dynamic-table.model.ts#StDynamicTableUISpecification}
* [StDynamicTableUserInterface] {./st-dynamic-table.model.ts#StDynamicTableUserInterface}
*
* \@example
*
* {html}
*
* ```
* <st-dynamic-table [jsonSchema]="jsonSchema"
* [items]="sortedUsers"
* [sortable]="true"
* [filterable]="true"
* [hasHoverMenu]="true"
* [currentOrder]="currentOrder"
* [activeHoverMenu]="activeHoverMenuPosition"
* [templateContentFilter]="filterContent"
* (changeOrder)="onSortTable($event)"
* (showHoverMenu)="onShowHoverMenu($event)">
* <st-dropdown-menu st-dynamic-table-hover-menu
* class="hover-menu"
* [items]="rowActions"
* [active]="activeHoverMenuPosition[3] !== undefined"
* [visualMode]="1">
* </st-dropdown-menu>
* </st-dynamic-table>
* ```
*
*/
StDynamicTableComponent = tslib_1.__decorate([
StEgeo(),
tslib_1.__metadata("design:paramtypes", [ChangeDetectorRef])
], StDynamicTableComponent);
return StDynamicTableComponent;
}());
export { StDynamicTableComponent };
if (false) {
/**
* \@Input {Object([key: string]: any)[]} [items=''] Item list displayed as table rows
* @type {?}
*/
StDynamicTableComponent.prototype.items;
/**
* \@Input {string} [qaTag=''] Prefix used to generate the id values for qa tests
* @type {?}
*/
StDynamicTableComponent.prototype.qaTag;
/**
* \@Input {boolean} [header=true] Boolean to show or hide the header
* @type {?}
*/
StDynamicTableComponent.prototype.header;
/**
* \@Input {boolean} [sortable=true] Boolean to make sortable the table, To enable sorting of columns use
* the new "sortable" field inside stTableHeader model
* @type {?}
*/
StDynamicTableComponent.prototype.sortable;
/**
* \@Input {boolean} [filterable=false] Boolean to make filterable the table, To enable filtering of columns use
* the new "filterable" field inside stTableHeader model (necessary define filterConfig).
* @type {?}
*/
StDynamicTableComponent.prototype.filterable;
/**
* \@Input {boolean} [selectable=false] Boolean to show or hide a checkboxes in the first cell of rows
* @type {?}
*/
StDynamicTableComponent.prototype.selectable;
/**
* \@Input {boolean} [selectableAll=false] Boolean to show or hide a checkbox in the header to select or
* deselect all rows
* @type {?}
*/
StDynamicTableComponent.prototype.selectableAll;
/**
* \@Input {boolean[]} [selected=''] Boolean list to indicate if a row is selected
* @type {?}
*/
StDynamicTableComponent.prototype.selected;
/**
* \@Input {Order} [currentOrder=''] It specifies what is the current order applied to the table
* @type {?}
*/
StDynamicTableComponent.prototype.currentOrder;
/**
* \@Input {string} [customClasses=] Classes for adding styles to table tag from outside. These can be: separated-rows
* @type {?}
*/
StDynamicTableComponent.prototype.customClasses;
/**
* \@Input {boolean} [fixedHeader=false] Boolean to fix the table header
* @type {?}
*/
StDynamicTableComponent.prototype.fixedHeader;
/**
* \@Input {boolean} [stickyHoverMenu=false] Boolean to fix hover menu always visible
* @type {?}
*/
StDynamicTableComponent.prototype.stickyHoverMenu;
/**
* \@Input {StTableIconClasses} [iconClasses=''] List of icon classes
* @type {?}
*/
StDynamicTableComponent.prototype.iconClasses;
/**
* \@Input {number} [activeHoverMenu=] Position of the current active hover menu
* @type {?}
*/
StDynamicTableComponent.prototype.activeHoverMenu;
/**
* \@Input {boolean} [hasHoverMenu=] It specifies if a menu has to be displayed when user puts the mouse over
* the rows. Remember to add a cell with the selector st-table-row-hover for adding content to the menu
* @type {?}
*/
StDynamicTableComponent.prototype.hasHoverMenu;
/**
* \@Input {string} [hoverButton='icon-ellipsis'] It specifies the icon class of the hover button displayed when user puts mouse over a row
* @type {?}
*/
StDynamicTableComponent.prototype.hoverButton;
/**
* \@Input {boolean} [selectedAll=] It specifies if all rows are selected
* @type {?}
*/
StDynamicTableComponent.prototype.selectedAll;
/**
* \@Input {string} [locale=en-US] Locale used to format dates
* @type {?}
*/
StDynamicTableComponent.prototype.locale;
/**
* \@Input {TemplateRef} [templateContentFilter=undefined] Reference to paint a custom template inside popover content
* @type {?}
*/
StDynamicTableComponent.prototype.templateContentFilter;
/**
* \@Output {Order} [changeOrder=''] Event emitted with the new order which has to be applied to the table rows
* @type {?}
*/
StDynamicTableComponent.prototype.changeOrder;
/**
* \@Output {boolean} [selectAll=''] Event emitted when user interacts with the checkbox to select or deselect
* all rows
* @type {?}
*/
StDynamicTableComponent.prototype.selectAll;
/**
* \@Output {EventEmitter<StTableHeader[]>} [fields=] Event emitted when header fields are being loaded
* @type {?}
*/
StDynamicTableComponent.prototype.updateFields;
/**
* \@Output {string} [clickFilter=] Event emitted when using filters custom template
* @type {?}
*/
StDynamicTableComponent.prototype.clickFilter;
/**
* \@Output {StTableHeader[]} [selectFilters=] Event emitted when user interacts with filter button without a custom template
* @type {?}
*/
StDynamicTableComponent.prototype.selectFilters;
/**
* \@Output {EventEmitter<number} [showHoverMenu=] Event emitted when user clicks on hover button of a row
* @type {?}
*/
StDynamicTableComponent.prototype.showHoverMenu;
/**
* \@Output {Object(checked: boolean, row: number)} [selectRow=] Event emitted when user clicks on checkbox of a row
* @type {?}
*/
StDynamicTableComponent.prototype.selectRow;
/**
* \@Output {StDynamicTableClickCellEvent} [clickCell=] Event emitted when user clicks on a cell
* @type {?}
*/
StDynamicTableComponent.prototype.clickCell;
/** @type {?} */
StDynamicTableComponent.prototype.fields;
/** @type {?} */
StDynamicTableComponent.prototype.statusFilter;
/**
* @type {?}
* @private
*/
StDynamicTableComponent.prototype._jsonSchema;
/**
* @type {?}
* @private
*/
StDynamicTableComponent.prototype._uiDefinitions;
/**
* @type {?}
* @private
*/
StDynamicTableComponent.prototype._templateContentFilter;
/**
* @type {?}
* @private
*/
StDynamicTableComponent.prototype._fkSeparator;
/**
* @type {?}
* @private
*/
StDynamicTableComponent.prototype._activeFilterFields;
/**
* @type {?}
* @private
*/
StDynamicTableComponent.prototype._cd;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3QtZHluYW1pYy10YWJsZS5jb21wb25lbnQuanMiLCJzb3VyY2VSb290Ijoibmc6Ly9Ac3RyYXRpby9lZ2VvLyIsInNvdXJjZXMiOlsibGliL3N0LWR5bmFtaWMtdGFibGUvc3QtZHluYW1pYy10YWJsZS5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7OztBQVVBLE9BQU8sRUFBRSx1QkFBdUIsRUFBRSxpQkFBaUIsRUFBRSxTQUFTLEVBQUUsWUFBWSxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUUsV0FBVyxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBR2hJLE9BQU8sRUFBRSxNQUFNLEVBQUUsVUFBVSxFQUFFLE1BQU0sa0NBQWtDLENBQUM7QUFDdEUsT0FBTyxFQUFFLEtBQUssRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBQ2pELE9BQU8sRUFBRSxtQkFBbUIsRUFBRSxNQUFNLGdDQUFnQyxDQUFDO0FBRXJFLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLGdDQUFnQyxDQUFDOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztJQWdJakUsaUNBQW9CLEdBQXNCO1FBQXRCLFFBQUcsR0FBSCxHQUFHLENBQW1COzs7O1FBNUVqQyxXQUFNLEdBQVksSUFBSSxDQUFDOzs7OztRQUt2QixhQUFRLEdBQVksSUFBSSxDQUFDOzs7OztRQUt6QixlQUFVLEdBQVksS0FBSyxDQUFDOzs7O1FBSTVCLGVBQVUsR0FBWSxLQUFLLENBQUM7Ozs7O1FBSzVCLGtCQUFhLEdBQVksS0FBSyxDQUFDOzs7O1FBRS9CLGFBQVEsR0FBZSxFQUFFLENBQUM7Ozs7UUFNMUIsZ0JBQVcsR0FBWSxLQUFLLENBQUM7Ozs7UUFFN0Isb0JBQWUsR0FBWSxLQUFLLENBQUM7Ozs7UUFFakMsZ0JBQVcsR0FBd0IsSUFBSSxrQkFBa0IsRUFBRSxDQUFDOzs7O1FBUzVELGdCQUFXLEdBQVcsZUFBZSxDQUFDOzs7O1FBSXRDLFdBQU0sR0FBVyxPQUFP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RSxrREFBa0M7Ozs7OztJQUlsQywrQ0FBZ0M7Ozs7O0lBR2hDLDhDQUErQzs7Ozs7SUFFL0MsOENBQStCOzs7OztJQUUvQix5Q0FBa0M7Ozs7O0lBRWxDLHdEQUFrRDs7Ozs7SUFFbEQsOENBQXVFOzs7Ozs7SUFJdkUsNENBQXlFOzs7OztJQUV6RSwrQ0FBMEc7Ozs7O0lBRTFHLDhDQUErRTs7Ozs7SUFFL0UsZ0RBQTJHOzs7OztJQUUzRyxnREFBMkU7Ozs7O0lBRTNFLDRDQUE2SDs7Ozs7SUFFN0gsNENBQW1IOztJQUduSCx5Q0FBMkM7O0lBQzNDLCtDQUFvQzs7Ozs7SUFDcEMsOENBQWlDOzs7OztJQUNqQyxpREFBb0Q7Ozs7O0lBRXBELHlEQUFpRDs7Ozs7SUFDakQsK0NBQXFDOzs7OztJQUNyQyxzREFBMkM7Ozs7O0lBRS9CLHNDQUE4QiIsInNvdXJjZXNDb250ZW50IjpbIi8qXG4gKiDCqSAyMDE3IFN0cmF0aW8gQmlnIERhdGEgSW5jLiwgU3VjdXJzYWwgZW4gRXNwYcOxYS5cbiAqXG4gKiBUaGlzIHNvZnR3YXJlIGlzIGxpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAuXG4gKiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZO1xuICogd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS5cbiAqIFNlZSB0aGUgdGVybXMgb2YgdGhlIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy5cbiAqXG4gKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogQXBhY2hlLTIuMC5cbiAqL1xuaW1wb3J0IHsgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksIENoYW5nZURldGVjdG9yUmVmLCBDb21wb25lbnQsIEV2ZW50RW1pdHRlciwgSW5wdXQsIE91dHB1dCwgVGVtcGxhdGVSZWYgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IEpTT05TY2hlbWE0IH0gZnJvbSAnanNvbi1zY2hlbWEnO1xuXG5pbXBvcnQgeyBTdEVnZW8sIFN0UmVxdWlyZWQgfSBmcm9tICcuLi9kZWNvcmF0b3JzL3JlcXVpcmUtZGVjb3JhdG9ycyc7XG5pbXBvcnQgeyBPcmRlciB9IGZyb20gJy4uL3N0LXRhYmxlL3NoYXJlZC9vcmRlcic7XG5pbXBvcnQgeyBTdER5bmFtaWNUYWJsZVV0aWxzIH0gZnJvbSAnLi91dGlscy9zdC1keW5hbWljLXRhYmxlLnV0aWxzJztcbmltcG9ydCB7IFN0RHluYW1pY1RhYmxlQ2xpY2tDZWxsRXZlbnQsIFN0RHluYW1pY1RhYmxlSGVhZGVyLCBTdER5bmFtaWNUYWJsZVVzZXJJbnRlcmZhY2UgfSBmcm9tICcuL3N0LWR5bmFtaWMtdGFibGUubW9kZWwnO1xuaW1wb3J0IHsgU3RUYWJsZUljb25DbGFzc2VzIH0gZnJvbSAnLi4vc3QtdGFibGUvc3QtdGFibGUuaW50ZXJmYWNlJztcblxuLyoqXG4gKiBAZGVzY3JpcHRpb24ge0NvbXBvbmVudH0gW0R5bmFtaWMgVGFibGVdXG4gKlxuICogVGhlIHRhYmxlIGNvbXBvbmVudCBoYXMgYmVlbiBkZXNpZ25lZCB0byBiZSBhYmxlIHRvIGNyZWF0ZSBhIHRhYmxlIGRlZHVjaW5nIGl0cyBjb2x1bW5zIHVzaW5nIGEganNvbiBzY2hlbWFcbiAqXG4gKiAqIEBtb2RlbFxuICpcbiAqICAgW1N0RHluYW1pY1RhYmxlSGVhZGVyXSB7Li9zdC1keW5hbWljLXRhYmxlLm1vZGVsLnRzI1N0RHluYW1pY1RhYmxlSGVhZGVyfVxuICogICBbU3REeW5hbWljVGFibGVVSVNwZWNpZmljYXRpb25dIHsuL3N0LWR5bmFtaWMtdGFibGUubW9kZWwudHMjU3REeW5hbWljVGFibGVVSVNwZWNpZmljYXRpb259XG4gKiAgIFtTdER5bmFtaWNUYWJsZVVzZXJJbnRlcmZhY2VdIHsuL3N0LWR5bmFtaWMtdGFibGUubW9kZWwudHMjU3REeW5hbWljVGFibGVVc2VySW50ZXJmYWNlfVxuICpcbiAqIEBleGFtcGxlXG4gKlxuICoge2h0bWx9XG4gKlxuICogYGBgXG4gKiA8c3QtZHluYW1pYy10YWJsZSBbanNvblNjaGVtYV09XCJqc29uU2NoZW1hXCJcbiAqICAgIFtpdGVtc109XCJzb3J0ZWRVc2Vyc1wiXG4gKiAgICBbc29ydGFibGVdPVwidHJ1ZVwiXG4gKiAgICBbZmlsdGVyYWJsZV09XCJ0cnVlXCJcbiAqICAgIFtoYXNIb3Zlck1lbnVdPVwidHJ1ZVwiXG4gKiAgICBbY3VycmVudE9yZGVyXT1cImN1cnJlbnRPcmRlclwiXG4gKiAgICBbYWN0aXZlSG92ZXJNZW51XT1cImFjdGl2ZUhvdmVyTWVudVBvc2l0aW9uXCJcbiAqICAgIFt0ZW1wbGF0ZUNvbnRlbnRGaWx0ZXJdPVwiZmlsdGVyQ29udGVudFwiXG4gKiAgICAoY2hhbmdlT3JkZXIpPVwib25Tb3J0VGFibGUoJGV2ZW50KVwiXG4gKiAgICAoc2hvd0hvdmVyTWVudSk9XCJvblNob3dIb3Zlck1lbnUoJGV2ZW50KVwiPlxuICogICAgICAgIDxzdC1kcm9wZG93bi1tZW51IHN0LWR5bmFtaWMtdGFibGUtaG92ZXItbWVudVxuICogICAgICAgICAgY2xhc3M9XCJob3Zlci1tZW51XCJcbiAqICAgICAgICAgIFtpdGVtc109XCJyb3dBY3Rpb25zXCJcbiAqICAgICAgICAgIFthY3RpdmVdPVwiYWN0aXZlSG92ZXJNZW51UG9zaXRpb25bM10gIT09IHVuZGVmaW5lZFwiXG4gKiAgICAgICAgICBbdmlzdWFsTW9kZV09XCIxXCI+XG4gKiAgICAgICA8L3N0LWRyb3Bkb3duLW1lbnU+XG4gKiA8L3N0LWR5bmFtaWMtdGFibGU+XG4gKiBgYGBcbiAqXG4gKi9cbkBTdEVnZW8oKVxuQENvbXBvbmVudCh7XG4gICBzZWxlY3RvcjogJ3N0LWR5bmFtaWMtdGFibGUnLFxuICAgdGVtcGxhdGVVcmw6ICcuL3N0LWR5bmFtaWMtdGFibGUuY29tcG9uZW50Lmh0bWwnLFxuICAgc3R5bGVVcmxzOiBbJy4vc3QtZHluYW1pYy10YWJsZS5jb21wb25lbnQuc2NzcyddLFxuICAgY2hhbmdlRGV0ZWN0aW9uOiBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneS5PblB1c2hcbn0pXG5cbmV4cG9ydCBjbGFzcyBTdER5bmFtaWNUYWJsZUNvbXBvbmVudCB7XG4gICAvKiogQElucHV0IHtPYmplY3QoW2tleTogc3RyaW5nXTogYW55KVtdfSBbaXRlbXM9JyddIEl0ZW0gbGlzdCBkaXNwbGF5ZWQgYXMgdGFibGUgcm93cyAqL1xuICAgQElucHV0KCkgQFN0UmVxdWlyZWQoKSBpdGVtczogeyBba2V5OiBzdHJpbmddOiBhbnkgfVtdO1xuICAgLyoqIEBJbnB1dCB7c3RyaW5nfSBbcWFUYWc9JyddIFByZWZpeCB1c2VkIHRvIGdlbmVyYXRlIHRoZSBpZCB2YWx1ZXMgZm9yIHFhIHRlc3RzICovXG4gICBASW5wdXQoKSBxYVRhZzogc3RyaW5nO1xuICAgLyoqIEBJbnB1dCB7Ym9vbGVhbn0gW2hlYWRlcj10cnVlXSBCb29sZWFuIHRvIHNob3cgb3IgaGlkZSB0aGUgaGVhZGVyICovXG4gICBASW5wdXQoKSBoZWFkZXI6IGJvb2xlYW4gPSB0cnVlO1xuICAgLyoqXG4gICAgKiBASW5wdXQge2Jvb2xlYW59IFtzb3J0YWJsZT10cnVlXSBCb29sZWFuIHRvIG1ha2Ugc29ydGFibGUgdGhlIHRhYmxlLCBUbyBlbmFibGUgc29ydGluZyBvZiBjb2x1bW5zIHVzZVxuICAgICogdGhlIG5ldyBcInNvcnRhYmxlXCIgZmllbGQgaW5zaWRlIHN0VGFibGVIZWFkZXIgbW9kZWxcbiAgICAqL1xuICAgQElucHV0KCkgc29ydGFibGU6IGJvb2xlYW4gPSB0cnVlO1xuICAgLyoqXG4gICAgKiBASW5wdXQge2Jvb2xlYW59IFtmaWx0ZXJhYmxlPWZhbHNlXSBCb29sZWFuIHRvIG1ha2UgZmlsdGVyYWJsZSB0aGUgdGFibGUsIFRvIGVuYWJsZSBmaWx0ZXJpbmcgb2YgY29sdW1ucyB1c2VcbiAgICAqIHRoZSBuZXcgXCJmaWx0ZXJhYmxlXCIgZmllbGQgaW5zaWRlIHN0VGFibGVIZWFkZXIgbW9kZWwgKG5lY2Vzc2FyeSBkZWZpbmUgZmlsdGVyQ29uZmlnKS5cbiAgICAqL1xuICAgQElucHV0KCkgZmlsdGVyYWJsZTogYm9vbGVhbiA9IGZhbHNlO1xuICAgLyoqXG4gICAgKiBASW5wdXQge2Jvb2xlYW59IFtzZWxlY3RhYmxlPWZhbHNlXSBCb29sZWFuIHRvIHNob3cgb3IgaGlkZSBhIGNoZWNrYm94ZXMgaW4gdGhlIGZpcnN0IGNlbGwgb2Ygcm93c1xuICAgICovXG4gICBASW5wdXQoKSBzZWxlY3RhYmxlOiBib29sZWFuID0gZmFsc2U7XG4gICAvKipcbiAgICAqIEBJbnB1dCB7Ym9vbGVhbn0gW3NlbGVjdGFibGVBbGw9ZmFsc2VdIEJvb2xlYW4gdG8gc2hvdyBvciBoaWRlIGEgY2hlY2tib3ggaW4gdGhlIGhlYWRlciB0byBzZWxlY3Qgb3JcbiAgICAqICBkZXNlbGVjdCBhbGwgcm93c1xuICAgICovXG4gICBASW5wdXQoKSBzZWxlY3RhYmxlQWxsOiBib29sZWFuID0gZmFsc2U7XG4gICAvKiogQElucHV0IHtib29sZWFuW119IFtzZWxlY3RlZD0nJ10gQm9vbGVhbiBsaXN0IHRvIGluZGljYXRlIGlmIGEgcm93IGlzIHNlbGVjdGVkICovXG4gICBASW5wdXQoKSBzZWxlY3RlZD86IGJvb2xlYW5bXSA9IFtdO1xuICAgLyoqIEBJbnB1dCB7T3JkZXJ9IFtjdXJyZW50T3JkZXI9JyddIEl0IHNwZWNpZmllcyB3aGF0IGlzIHRoZSBjdXJyZW50IG9yZGVyIGFwcGxpZWQgdG8gdGhlIHRhYmxlICovXG4gICBASW5wdXQoKSBjdXJyZW50T3JkZXI6IE9yZGVyO1xuICAgLyoqIEBJbnB1dCB7c3RyaW5nfSBbY3VzdG9tQ2xhc3Nlcz1dIENsYXNzZXMgZm9yIGFkZGluZyBzdHlsZXMgdG8gdGFibGUgdGFnIGZyb20gb3V0c2lkZS4gVGhlc2UgY2FuIGJlOiBzZXBhcmF0ZWQtcm93cyAqL1xuICAgQElucHV0KCkgY3VzdG9tQ2xhc3Nlczogc3RyaW5nO1xuICAgLyoqIEBJbnB1dCB7Ym9vbGVhbn0gW2ZpeGVkSGVhZGVyPWZhbHNlXSBCb29sZWFuIHRvIGZpeCB0aGUgdGFibGUgaGVhZGVyICovXG4gICBASW5wdXQoKSBmaXhlZEhlYWRlcjogYm9vbGVhbiA9IGZhbHNlO1xuICAgLyoqIEBJbnB1dCB7Ym9vbGVhbn0gW3N0aWNreUhvdmVyTWVudT1mYWxzZV0gQm9vbGVhbiB0byBmaXggaG92ZXIgbWVudSBhbHdheXMgdmlzaWJsZSAqL1xuICAgQElucHV0KCkgc3RpY2t5SG92ZXJNZW51OiBib29sZWFuID0gZmFsc2U7XG4gICAvKiogQElucHV0IHtTdFRhYmxlSWNvbkNsYXNzZXN9IFtpY29uQ2xhc3Nlcz0nJ10gTGlzdCBvZiBpY29uIGNsYXNzZXMgKi9cbiAgIEBJbnB1dCgpIGljb25DbGFzc2VzPzogU3RUYWJsZUljb25DbGFzc2VzID0gbmV3IFN0VGFibGVJY29uQ2xhc3NlcygpO1xuICAgLyoqIEBJbnB1dCB7bnVtYmVyfSBbYWN0aXZlSG92ZXJNZW51PV0gUG9zaXRpb24gb2YgdGhlIGN1cnJlbnQgYWN0aXZlIGhvdmVyIG1lbnUgKi9cbiAgIEBJbnB1dCgpIGFjdGl2ZUhvdmVyTWVudT86IG51bWJlcjtcbiAgIC8qKiBASW5wdXQge2Jvb2xlYW59IFtoYXNIb3Zlck1lbnU9XSBJdCBzcGVjaWZpZXMgaWYgYSBtZW51IGhhcyB0byBiZSBkaXNwbGF5ZWQgd2hlbiB1c2VyIHB1dHMgdGhlIG1vdXNlIG92ZXJcbiAgICAqIHRoZSByb3dzLiBSZW1lbWJlciB0byBhZGQgYSBjZWxsIHdpdGggdGhlIHNlbGVjdG9yIHN0LXRhYmxlLXJvdy1ob3ZlciBmb3IgYWRkaW5nIGNvbnRlbnQgdG8gdGhlIG1lbnVcbiAgICAqL1xuICAgQElucHV0KCkgaGFzSG92ZXJNZW51PzogYm9vbGVhbjtcbiAgIC8qKiBASW5wdXQge3N0cmluZ30gW2hvdmVyQnV0dG9uPSdpY29uLWVsbGlwc2lzJ10gSXQgc3BlY2lmaWVzIHRoZSBpY29uIGNsYXNzIG9mIHRoZSBob3ZlciBidXR0b24gZGlzcGxheWVkIHdoZW4gdXNlciBwdXRzIG1vdXNlIG92ZXIgYSByb3dcbiAgICAqL1xuICAgQElucHV0KCkgaG92ZXJCdXR0b246IHN0cmluZyA9ICdpY29uLWVsbGlwc2lzJztcbiAgIC8qKiBASW5wdXQge2Jvb2xlYW59IFtzZWxlY3RlZEFsbD1dIEl0IHNwZWNpZmllcyBpZiBhbGwgcm93cyBhcmUgc2VsZWN0ZWQgKi9cbiAgIEBJbnB1dCgpIHNlbGVjdGVkQWxsPzogYm9vbGVhbjtcbiAgIC8qKiBASW5wdXQge3N0cmluZ30gW2xvY2FsZT1lbi1VU10gTG9jYWxlIHVzZWQgdG8gZm9ybWF0IGRhdGVzICovXG4gICBASW5wdXQoKSBsb2NhbGU6IHN0cmluZyA9ICdlbi1VUyc7XG4gICAvKiogQElucHV0IHtUZW1wbGF0ZVJlZn0gW3RlbXBsYXRlQ29udGVudEZpbHRlcj11bmRlZmluZWRdIFJlZmVyZW5jZSB0byBwYWludCBhIGN1c3RvbSB0ZW1wbGF0ZSBpbnNpZGUgcG9wb3ZlciBjb250ZW50ICovXG4gICBASW5wdXQoKSB0ZW1wbGF0ZUNvbnRlbnRGaWx0ZXI/OiBUZW1wbGF0ZVJlZjxhbnk+O1xuICAgLyoqIEBPdXRwdXQge09yZGVyfSBbY2hhbmdlT3JkZXI9JyddIEV2ZW50IGVtaXR0ZWQgd2l0aCB0aGUgbmV3IG9yZGVyIHdoaWNoIGhhcyB0byBiZSBhcHBsaWVkIHRvIHRoZSB0YWJsZSByb3dzICovXG4gICBAT3V0cHV0KCkgY2hhbmdlT3JkZXI6IEV2ZW50RW1pdHRlcjxPcmRlcj4gPSBuZXcgRXZlbnRFbWl0dGVyPE9yZGVyPigpO1xuICAgLyoqIEBPdXRwdXQge2Jvb2xlYW59IFtzZWxlY3RBbGw9JyddIEV2ZW50IGVtaXR0ZWQgIHdoZW4gdXNlciBpbnRlcmFjdHMgd2l0aCB0aGUgY2hlY2tib3ggdG8gc2VsZWN0IG9yIGRlc2VsZWN0XG4gICAgKiBhbGwgcm93c1xuICAgICovXG4gICBAT3V0cHV0KCkgc2VsZWN0QWxsOiBFdmVudEVtaXR0ZXI8Ym9vbGVhbj4gPSBuZXcgRXZlbnRFbWl0dGVyPGJvb2xlYW4+KCk7XG4gICAvKiogQE91dHB1dCB7RXZlbnRFbWl0dGVyPFN0VGFibGVIZWFkZXJbXT59IFtmaWVsZHM9XSBFdmVudCBlbWl0dGVkIHdoZW4gaGVhZGVyIGZpZWxkcyBhcmUgYmVpbmcgbG9hZGVkICovXG4gICBAT3V0cHV0KCkgdXBkYXRlRmllbGRzOiBFdmVudEVtaXR0ZXI8U3REeW5hbWljVGFibGVIZWFkZXJbXT4gPSBuZXcgRXZlbnRFbWl0dGVyPFN0RHluYW1pY1RhYmxlSGVhZGVyW10+KCk7XG4gICAvKiogQE91dHB1dCB7c3RyaW5nfSBbY2xpY2tGaWx0ZXI9XSBFdmVudCBlbWl0dGVkIHdoZW4gdXNpbmcgZmlsdGVycyBjdXN0b20gdGVtcGxhdGUgICovXG4gICBAT3V0cHV0KCkgY2xpY2tGaWx0ZXI6IEV2ZW50RW1pdHRlcjxTdER5bmFtaWNUYWJsZUhlYWRlcj4gPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG4gICAvKiogQE91dHB1dCB7U3RUYWJsZUhlYWRlcltdfSBbc2VsZWN0RmlsdGVycz1dIEV2ZW50IGVtaXR0ZWQgIHdoZW4gdXNlciBpbnRlcmFjdHMgd2l0aCBmaWx0ZXIgYnV0dG9uIHdpdGhvdXQgYSBjdXN0b20gdGVtcGxhdGUgKi9cbiAgIEBPdXRwdXQoKSBzZWxlY3RGaWx0ZXJzOiBFdmVudEVtaXR0ZXI8U3REeW5hbWljVGFibGVIZWFkZXJbXT4gPSBuZXcgRXZlbnRFbWl0dGVyPFN0RHluYW1pY1RhYmxlSGVhZGVyW10+KCk7XG4gICAvKiogQE91dHB1dCB7RXZlbnRFbWl0dGVyPG51bWJlcn0gW3Nob3dIb3Zlck1lbnU9XSBFdmVudCBlbWl0dGVkIHdoZW4gdXNlciBjbGlja3Mgb24gaG92ZXIgYnV0dG9uIG9mIGEgcm93ICovXG4gICBAT3V0cHV0KCkgc2hvd0hvdmVyTWVudTogRXZlbnRFbWl0dGVyPG51bWJlcj4gPSBuZXcgRXZlbnRFbWl0dGVyPG51bWJlcj4oKTtcbiAgIC8qKiBAT3V0cHV0IHtPYmplY3QoY2hlY2tlZDogYm9vbGVhbiwgcm93OiBudW1iZXIpfSBbc2VsZWN0Um93PV0gRXZlbnQgZW1pdHRlZCB3aGVuIHVzZXIgY2xpY2tzIG9uIGNoZWNrYm94IG9mIGEgcm93ICovXG4gICBAT3V0cHV0KCkgc2VsZWN0Um93OiBFdmVudEVtaXR0ZXI8eyBjaGVja2VkOiBib29sZWFuLCByb3c6IG51bWJlciB9PiA9IG5ldyBFdmVudEVtaXR0ZXI8eyBjaGVja2VkOiBib29sZWFuLCByb3c6IG51bWJlciB9PigpO1xuICAgLyoqIEBPdXRwdXQge1N0RHluYW1pY1RhYmxlQ2xpY2tDZWxsRXZlbnR9IFtjbGlja0NlbGw9XSBFdmVudCBlbWl0dGVkIHdoZW4gdXNlciBjbGlja3Mgb24gYSBjZWxsICovXG4gICBAT3V0cHV0KCkgY2xpY2tDZWxsOiBFdmVudEVtaXR0ZXI8U3REeW5hbWljVGFibGVDbGlja0NlbGxFdmVudD4gPSBuZXcgRXZlbnRFbWl0dGVyPFN0RHluYW1pY1RhYmxlQ2xpY2tDZWxsRXZlbnQ+KCk7XG5cblxuICAgcHVibGljIGZpZWxkczogU3REeW5hbWljVGFibGVIZWFkZXJbXSA9IFtdO1xuICAgcHVibGljIHN0YXR1c0ZpbHRlcjogYm9vbGVhbltdID0gW107XG4gICBwcml2YXRlIF9qc29uU2NoZW1hOiBKU09OU2NoZW1hNDtcbiAgIHByaXZhdGUgX3VpRGVmaW5pdGlvbnM6IFN0RHluYW1pY1RhYmxlVXNlckludGVyZmFjZTtcblxuICAgcHJpdmF0ZSBfdGVtcGxhdGVDb250ZW50RmlsdGVyOiBUZW1wbGF0ZVJlZjxhbnk+O1xuICAgcHJpdmF0ZSBfZmtTZXBhcmF0b3I6IHN0cmluZyA9ICcgLSAnO1xuICAgcHJpdmF0ZSBfYWN0aXZlRmlsdGVyRmllbGRzOiBzdHJpbmdbXSA9IFtdO1xuXG4gICBjb25zdHJ1Y3Rvcihwcml2YXRlIF9jZDogQ2hhbmdlRGV0ZWN0b3JSZWYpIHtcbiAgIH1cblxuICAgLyoqIEBJbnB1dCB7SlNPTlNjaGVtYTR9IFtqc29uU2NoZW1hPV0gSnNvbiBzY2hlbWEgdG8gZGVmaW5lIGl0cyBzdHJ1Y3R1cmUgKi9cbiAgIEBJbnB1dCgpIEBTdFJlcXVpcmVkKClcbiAgIGdldCBqc29uU2NoZW1hKCk6IEpTT05TY2hlbWE0IHtcbiAgICAgIHJldHVybiB0aGlzLl9qc29uU2NoZW1hO1xuICAgfVxuXG4gICBzZXQganNvblNjaGVtYShfanNvblNjaGVtYTogSlNPTlNjaGVtYTQpIHtcbiAgICAgIHRoaXMuX2pzb25TY2hlbWEgPSBfanNvblNjaGVtYTtcbiAgICAgIHRoaXMuX21hbmFnZUZpZWxkc1VwZGF0ZSgpO1xuICAgfVxuXG4gICAvKiogQElucHV0IHtTdER5bmFtaWNUYWJsZVVzZXJJbnRlcmZhY2V9IFt1aURlZmluaXRpb25zPScnXSBVSSBkZWZpbml0aW9uIGZvciBlYWNoIGZpZWxkICovXG4gICBASW5wdXQoKVxuICAgZ2V0IHVpRGVmaW5pdGlvbnMoKTogU3REeW5hbWljVGFibGVVc2VySW50ZXJmYWNlIHtcbiAgICAgIHJldHVybiB0aGlzLl91aURlZmluaXRpb25zO1xuICAgfVxuXG4gICBzZXQgdWlEZWZpbml0aW9ucyhfdWlEZWZpbml0aW9uczogU3REeW5hbWljVGFibGVVc2VySW50ZXJmYWNlKSB7XG4gICAgICB0aGlzLl91aURlZmluaXRpb25zID0gX3VpRGVmaW5pdGlvbnM7XG4gICAgICB0aGlzLl9tYW5hZ2VGaWVsZHNVcGRhdGUoKTtcbiAgIH1cblxuICAgLyoqIEBJbnB1dCB7c3RyaW5nW119IFthY3RpdmVGaWx0ZXJGaWVsZHM9XSBMaXN0IG9mIGN1cnJlbnQgZmlsdGVyZWQgZmllbGRzICAqL1xuICAgQElucHV0KClcbiAgIGdldCBhY3RpdmVGaWx0ZXJGaWVsZHMoKTogc3RyaW5nW10ge1xuICAgICAgcmV0dXJuIHRoaXMuX2FjdGl2ZUZpbHRlckZpZWxkcztcbiAgIH1cblxuICAgc2V0IGFjdGl2ZUZpbHRlckZpZWxkcyhfYWN0aXZlRmlsdGVyRmllbGRzOiBzdHJpbmdbXSkge1xuICAgICAgdGhpcy5fYWN0aXZlRmlsdGVyRmllbGRzID0gX2FjdGl2ZUZpbHRlckZpZWxkcztcbiAgICAgIHRoaXMuX3VwZGF0ZVN0YXR1c0ZpbHRlcnMoKTtcbiAgIH1cblxuICAgcHVibGljIG9uRmlsdGVyQ2xpY2soc2VsZWN0ZWRGaWx0ZXI6IGFueSk6IHZvaWQge1xuICAgICAgdGhpcy5jbGlja0ZpbHRlci5lbWl0KHNlbGVjdGVkRmlsdGVyKTtcbiAgIH1cblxuICAgcHVibGljIG9uQ2hhbmdlT3JkZXIob3JkZXI6IE9yZGVyKTogdm9pZCB7XG4gICAgICBpZiAob3JkZXIpIHtcbiAgICAgICAgIHRoaXMuY2hhbmdlT3JkZXIuZW1pdChvcmRlcik7XG4gICAgICB9XG4gICB9XG5cbiAgIHB1YmxpYyBvblNlbGVjdEFsbChjaGVja2VkOiBib29sZWFuKTogdm9pZCB7XG4gICAgICB0aGlzLnNlbGVjdEFsbC5lbWl0KGNoZWNrZWQpO1xuICAgfVxuXG4gICBwdWJsaWMgb25TZWxlY3RlZEZpbHRlcnMoc2VsZWN0ZWRGaWx0ZXJzOiBTdER5bmFtaWNUYWJsZUhlYWRlcltdKTogdm9pZCB7XG4gICAgICB0aGlzLnNlbGVjdEZpbHRlcnMuZW1pdChzZWxlY3RlZEZpbHRlcnMpO1xuICAgfVxuXG4gICBwdWJsaWMgb25TaG93SG92ZXJNZW51KHJvdzogbnVtYmVyKTogdm9pZCB7XG4gICAgICB0aGlzLnNob3dIb3Zlck1lbnUuZW1pdChyb3cpO1xuICAgfVxuXG4gICBwdWJsaWMgb25MZWF2ZVJvdygpOiB2b2lkIHtcbiAgICAgIHRoaXMuc2hvd0hvdmVyTWVudS5lbWl0KHVuZGVmaW5lZCk7XG4gICB9XG5cbiAgIHB1YmxpYyBvbkNsaWNrQ2VsbCh2YWx1ZTogYW55LCBmaWVsZDogU3REeW5hbWljVGFibGVIZWFkZXIpOiB2b2lkIHtcbiAgICAgIGlmIChmaWVsZC5jbGlja2FibGUpIHtcbiAgICAgICAgIHRoaXMuY2xpY2tDZWxsLmVtaXQoe1xuICAgICAgICAgICAgaGVhZGVyOiBmaWVsZCxcbiAgICAgICAgICAgIHZhbHVlOiB2YWx1ZVxuICAgICAgICAgfSk7XG4gICAgICB9XG4gICB9XG5cbiAgIHB1YmxpYyBnZXRDZWxsQ29udGVudChpdGVtOiB7IFtrZXk6IHN0cmluZ106IGFueSB9LCBmaWVsZDogU3REeW5hbWljVGFibGVIZWFkZXIpOiBzdHJpbmcge1xuICAgICAgaWYgKGZpZWxkLmZrICYmIGZpZWxkLmdyb3VwKSB7XG4gICAgICAgICBjb25zdCBncm91cExhYmVsID0gZmllbGQuZ3JvdXAuc3BsaXQodGhpcy5fZmtTZXBhcmF0b3IpXG4gICAgICAgICAgICAubWFwKF9ncm91cEtleSA9PiBpdGVtW19ncm91cEtleV0pXG4gICAgICAgICAgICAuam9pbih0aGlzLl9ma1NlcGFyYXRvcik7XG4gICAgICAgICByZXR1cm4gZ3JvdXBMYWJlbC5sZW5ndGggPiB0aGlzLl9ma1NlcGFyYXRvci5sZW5ndGggPyBncm91cExhYmVsIDogaXRlbVtmaWVsZC5pZF07XG4gICAgICB9XG4gICAgICBjb25zdCB1aURlZmluaXRpb24gPSB0aGlzLnVpRGVmaW5pdGlvbnMgJiYgdGhpcy51aURlZmluaXRpb25zW2ZpZWxkLmlkXTtcblxuICAgICAgaWYgKHVpRGVmaW5pdGlvbiAmJiB1aURlZmluaXRpb24uZGF0ZUZvcm1hdCkge1xuICAgICAgICAgcmV0dXJuIFN0RHluYW1pY1RhYmxlVXRpbHMuZm9ybWF0RGF0ZSg8c3RyaW5nPiBpdGVtW2ZpZWxkLmlkXSwgdWlEZWZpbml0aW9uLmRhdGVGb3JtYXQsIHRoaXMubG9jYWxlKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBpdGVtW2ZpZWxkLmlkXTtcbiAgIH1cblxuICAgcHVibGljIGdldENlbGxTdHlsZXMoZmllbGQ6IFN0RHluYW1pY1RhYmxlSGVhZGVyKTogYW55IHtcbiAgICAgIGNvbnN0IHVpRGVmaW5pdGlvbiA9IHRoaXMudWlEZWZpbml0aW9ucyAmJiB0aGlzLnVpRGVmaW5pdGlvbnNbZmllbGQuaWRdO1xuICAgICAgcmV0dXJuIHVpRGVmaW5pdGlvbiAmJiB1aURlZmluaXRpb24uc3R5bGVzO1xuICAgfVxuXG4gICBwdWJsaWMgb25TZWxlY3RSb3coY2hlY2tib3hFdmVudDogeyBjaGVja2VkOiBib29sZWFuLCB2YWx1ZTogYW55IH0sIHJvdzogbnVtYmVyKTogdm9pZCB7XG4gICAgICB0aGlzLnNlbGVjdFJvdy5lbWl0KHsgY2hlY2tlZDogY2hlY2tib3hFdmVudC5jaGVja2VkLCByb3c6IHJvdyB9KTtcbiAgIH1cblxuICAgcHJpdmF0ZSBfbWFuYWdlRmllbGRzVXBkYXRlKCk6IHZvaWQge1xuICAgICAgdGhpcy5maWVsZHMgPSBTdER5bmFtaWNUYWJsZVV0aWxzLmdldEhlYWRlckZpZWxkc0Zyb21Kc29uU2NoZW1hKHRoaXMuX2pzb25TY2hlbWEsIHRoaXMuX3VpRGVmaW5pdGlvbnMpO1xuICAgICAgdGhpcy51cGRhdGVGaWVsZHMuZW1pdCh0aGlzLmZpZWxkcyk7XG4gICAgICB0aGlzLl91cGRhdGVTdGF0dXNGaWx0ZXJzKCk7XG4gICAgICB0aGlzLl9jZC5tYXJrRm9yQ2hlY2soKTtcbiAgIH1cblxuICAgcHJpdmF0ZSBfdXBkYXRlU3RhdHVzRmlsdGVycygpOiB2b2lkIHtcbiAgICAgIHRoaXMuc3RhdHVzRmlsdGVyID0gW107XG5cbiAgICAgIGlmICh0aGlzLl9hY3RpdmVGaWx0ZXJGaWVsZHMgJiYgdGhpcy5fYWN0aXZlRmlsdGVyRmllbGRzLmxlbmd0aCAmJiB0aGlzLmZpZWxkcyAmJiB0aGlzLmZpZWxkcy5sZW5ndGgpIHtcbiAgICAgICAgIHRoaXMuX2FjdGl2ZUZpbHRlckZpZWxkcy5mb3JFYWNoKF9maWVsZElkID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHBvc2l0aW9uID0gdGhpcy5maWVsZHMuZmluZEluZGV4KF9maWVsZCA9PiBfZmllbGQuaWQgPT09IF9maWVsZElkKTtcbiAgICAgICAgICAgIGlmIChwb3NpdGlvbiA+IC0xKSB7XG4gICAgICAgICAgICAgICB0aGlzLnN0YXR1c0ZpbHRlcltwb3NpdGlvbl0gPSB0cnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgfSk7XG4gICAgICB9XG4gICB9XG59XG4iXX0=