UNPKG

@hxui/angular

Version:

This README includes the steps that are necessary to import the HxUi-angular into a project or to contribute with development.

510 lines (509 loc) 57.2 kB
/** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ import * as tslib_1 from "tslib"; import { Component, Input, Output, EventEmitter } from '@angular/core'; import { ITabularConfig } from './tabular-config.interface'; import { ActionConfigRouteType } from './actions-config.interface'; import { TabularSortByService, SortByDirection } from './tabular-sort-by.service'; import { TabularConfig } from './tabular.config'; import { TabularSize } from './tabular-size.enum'; import { TabularColumnTypes } from './tabular-column.interface'; import { Context } from '../enums'; import * as _ from 'lodash'; var TabularComponent = /** @class */ (function () { function TabularComponent(conf, sortByService) { var _this = this; this.conf = conf; this.sortByService = sortByService; /** * Event fired when refresh is called. * Host should refresh data of input. */ this.refresh = new EventEmitter(); /** * Event fired when a row is clicked. */ this.rowClick = new EventEmitter(); this.oldRows = []; this.pagedItems = []; this.TabularColumnTypes = TabularColumnTypes; this.TabularSize = TabularSize; this.ActionConfigRouteType = ActionConfigRouteType; this.selectAll = false; this.Context = Context; this.SortByDirection = SortByDirection; this.toggleSelectAll = function ($event) { for (var /** @type {?} */ i = 0; i < _this.rows.length; i++) { _this.rows[i].checked = _this.selectAll; } }; this.toggleIndividualSelect = function ($event) { var /** @type {?} */ count = 0; for (var /** @type {?} */ i = 0; i < _this.rows.length; i++) { if (_this.rows[i].checked) { count++; } } _this.selectAll = (_this.rows.length === count); }; Object.assign(this, conf); } Object.defineProperty(TabularComponent.prototype, "config", { get: /** * Tabular configuration * IPaginationInstance, ISearchConfig * @return {?} */ function () { return this._config; }, set: /** * @param {?} c * @return {?} */ function (c) { if (!c.sortBy) { c.sortBy = []; } this._config = c; }, enumerable: true, configurable: true }); Object.defineProperty(TabularComponent.prototype, "callback", { get: /** * The function to call when a action item is clicked * * @return {?} */ function () { return this._callback; }, set: /** * @param {?} Fn * @return {?} */ function (Fn) { this._callback = Fn; }, enumerable: true, configurable: true }); Object.defineProperty(TabularComponent.prototype, "searchTerm", { get: /** * Search term is used in the simple search pipe * Array of objects: *ngFor="#row of rows | simpleSearch : 'the search term'" * @return {?} */ function () { return this._searchTerm; }, set: /** * @param {?} term * @return {?} */ function (term) { this._searchTerm = term; }, enumerable: true, configurable: true }); /** * @return {?} */ TabularComponent.prototype.ngOnInit = /** * @return {?} */ function () { }; /** * @return {?} */ TabularComponent.prototype.ngDoCheck = /** * @return {?} */ function () { if (!_.isEqual(this.rows, this.oldRows)) { this.oldRows = _.cloneDeep(this.rows); this.orderByData(); } }; /** * Calls the parsed callback with optional arguments */ /** * Calls the parsed callback with optional arguments * @param {?} event * @param {?} cb * @return {?} */ TabularComponent.prototype.executeCallback = /** * Calls the parsed callback with optional arguments * @param {?} event * @param {?} cb * @return {?} */ function (event, cb) { event.stopPropagation(); if (cb.length) { if (cb.length === 1) { // if callback has no arguments cb[0](); } else { // if callback has 1 or more arguments var /** @type {?} */ args = []; for (var /** @type {?} */ i = 1; i < cb.length; i++) { args.push(cb[i]); } cb[0].apply(this, args); } } }; /** * @param {?=} $event * @return {?} */ TabularComponent.prototype.setPage = /** * @param {?=} $event * @return {?} */ function ($event) { if ($event === void 0) { $event = { page: this.config.pagination.currentPage, itemsPerPage: this.config.pagination.itemsPerPage }; } this.config.pagination.currentPage = $event.page; // calculate start and end page item indexes var /** @type {?} */ startIndex = (this.config.pagination.currentPage - 1) * this.config.pagination.itemsPerPage; var /** @type {?} */ endIndex = Math.min(startIndex + this.config.pagination.itemsPerPage - 1, this.totalItemCount - 1); this.pagedItems = this.rows.slice(startIndex, endIndex + 1); }; /** * Get the action tooltip if it exists */ /** * Get the action tooltip if it exists * @param {?} action * @return {?} */ TabularComponent.prototype.getActionTooltip = /** * Get the action tooltip if it exists * @param {?} action * @return {?} */ function (action) { return (action && action.disabledConfig) ? action.disabledConfig.tooltip : ''; }; /** * @param {?} action * @return {?} */ TabularComponent.prototype.getActionDisabledState = /** * @param {?} action * @return {?} */ function (action) { return (action && action.disabledConfig) ? action.disabledConfig.disabled : false; }; /** * Handles the column header click event for sorting. * Sort order is Descending, Ascending followed by None. */ /** * Handles the column header click event for sorting. * Sort order is Descending, Ascending followed by None. * @param {?} key * @param {?} type * @return {?} */ TabularComponent.prototype.onSortClickHandler = /** * Handles the column header click event for sorting. * Sort order is Descending, Ascending followed by None. * @param {?} key * @param {?} type * @return {?} */ function (key, type) { var /** @type {?} */ findPropInSortList = this.config.sortBy.filter(function (prop) { return (prop.property === key); }); if (findPropInSortList.length) { var /** @type {?} */ prop_1 = findPropInSortList[0]; var /** @type {?} */ index = this.config.sortBy.findIndex(function (x) { return x === prop_1; }); if (prop_1.direction === SortByDirection.None) { prop_1.direction = SortByDirection.Descending; } else if (prop_1.direction === SortByDirection.Descending) { prop_1.direction = SortByDirection.Ascending; } else if (prop_1.direction === SortByDirection.Ascending) { if (index > -1) { this.config.sortBy.splice(index, 1); } } } else { this.config.sortBy.push({ property: key, direction: SortByDirection.Descending, type: type }); } this.orderByData(); return false; }; /** * @param {?} key * @param {?} direction * @return {?} */ TabularComponent.prototype.isColumnSorted = /** * @param {?} key * @param {?} direction * @return {?} */ function (key, direction) { var /** @type {?} */ findPropInSortList = this.config.sortBy.filter(function (prop) { return (prop.property === key && prop.direction === direction); }); return (findPropInSortList.length > 0); }; /** * Handles the row click event. */ /** * Handles the row click event. * @param {?} $event * @param {?} data * @return {?} */ TabularComponent.prototype.onRowClickHandler = /** * Handles the row click event. * @param {?} $event * @param {?} data * @return {?} */ function ($event, data) { var /** @type {?} */ el = $event.target; if (this.config.clickableRows) { if (el.parentElement.tagName === 'BUTTON' || el.tagName === 'BUTTON' || el.parentElement.classList.contains('hx-checkbox-control')) { return; } this.rowClick.emit(data); } }; /** * @return {?} */ TabularComponent.prototype.orderByData = /** * @return {?} */ function () { if (this.config.sortBy.length > 0) { this.rows = tslib_1.__spread(this.rows); // Required as array-sort-by mutates the original array this.sortByService.sortBy(this.rows, this.config.sortBy); } this.setPage(); }; Object.defineProperty(TabularComponent.prototype, "totalItemCount", { get: /** * @return {?} */ function () { return this.rows.length; }, enumerable: true, configurable: true }); /** * Helper to determine if tabular instance is in small mode */ /** * Helper to determine if tabular instance is in small mode * @return {?} */ TabularComponent.prototype.isSmall = /** * Helper to determine if tabular instance is in small mode * @return {?} */ function () { return (this.config.size === TabularSize.Small); }; /** * @param {?} colData * @return {?} */ TabularComponent.prototype.hasValidBadgeTypeParams = /** * @param {?} colData * @return {?} */ function (colData) { if (colData) { if (typeof colData.label !== 'undefined') { return true; } else { console.error('Record for column type badge is invalid, make sure you have the right type. ITabularColumnTypeBadge', { columnValue: colData }); } } return false; }; /** * @param {?} colData * @return {?} */ TabularComponent.prototype.hasValidIconTypeParams = /** * @param {?} colData * @return {?} */ function (colData) { var /** @type {?} */ hasError = false; if (colData) { if (typeof colData.icon !== 'undefined') { if (typeof colData.tooltip.config !== 'undefined' && typeof colData.tooltip.content !== 'undefined') { if (typeof colData.tooltip.config.context !== 'undefined' || typeof colData.tooltip.config.placement !== 'undefined') { return true; } else { hasError = true; } } else { hasError = true; } } else { hasError = true; } } if (hasError) { console.error('Record for column type icon is invalid, make sure you have the right type. ITabularColumnTypeIcon', { columnValue: colData }); } return false; }; /** * @param {?} colData * @return {?} */ TabularComponent.prototype.getTooltipContext = /** * @param {?} colData * @return {?} */ function (colData) { return (!this.hasValidIconTypeParams(colData)) ? colData.tooltip.config.context : Context.None; }; /** * @param {?} action * @return {?} */ TabularComponent.prototype.hasChildren = /** * @param {?} action * @return {?} */ function (action) { return (action.children && action.children.length > 0); }; /** * @param {?} index * @param {?} action * @return {?} */ TabularComponent.prototype.trackByFn = /** * @param {?} index * @param {?} action * @return {?} */ function (index, action) { return index; // or action.id }; TabularComponent.decorators = [ { type: Component, args: [{ selector: 'hxa-tabular', template: "<table class=\"tabular hx-table is-striped\" [class.is-hover]=\"config.clickableRows\" [class.is-narrow]=\"config.size === TabularSize.Small\">\n <thead>\n <tr>\n <th *ngFor=\"let col of columns\" class=\"{{col.cssClass}} tabular__{{col.label}}\" [ngClass]=\"{'tabular__checkboxes': col.dataType === TabularColumnTypes.Checkbox, 'tabular__sortable': col.sortable}\">\n\n <!-- sortable column -->\n <a class=\"tabular__sorter\" href=\"#\" *ngIf=\"col.sortable && col.dataType != TabularColumnTypes.Checkbox\" (click)=\"onSortClickHandler(col.id, col.dataType)\">{{col.label}} <i class=\"hx-icon icon-arrow-up is-small\" [class.icon-arrow-up]=\"isColumnSorted(col.id, SortByDirection.Ascending)\" [class.icon-arrow-down]=\"isColumnSorted(col.id, SortByDirection.Descending)\" *ngIf=\"isColumnSorted(col.id, SortByDirection.Descending) || isColumnSorted(col.id, SortByDirection.Ascending)\"></i></a>\n\n <!-- non sortable column -->\n <span *ngIf=\"!col.sortable && col.dataType !== TabularColumnTypes.Checkbox\">{{col.label}}</span>\n\n <!-- checkbox column -->\n <div *ngIf=\"col.dataType === TabularColumnTypes.Checkbox\" class=\"hx-checkbox-control\">\n <input id=\"selectAll\" name=\"selectAll\" type=\"checkbox\" class=\"hx-checkbox\" (change)=\"toggleSelectAll($event)\" title=\"Select All\" [(ngModel)]=\"selectAll\" />\n <label for=\"selectAll\" class=\"hx-label\"></label>\n </div>\n </th>\n </tr>\n </thead>\n\n <tbody>\n <!--<tr *ngFor=\"let row of rows | paginate: config.pagination | simpleSearch: searchTerm\">-->\n <tr *ngFor=\"let row of pagedItems\"\n (click)=\"onRowClickHandler($event, row)\"\n [class.is-selected]=\"row.selected\"\n [class.is-danger]=\"row.context && row.context === Context.Danger\"\n [class.is-warning]=\"row.context && row.context === Context.Warning\"\n [class.is-info]=\"row.context && row.context === Context.Info\"\n [class.is-success]=\"row.context && row.context === Context.Success\"\n [class.has-stripe-danger]=\"row.stripeContext && row.stripeContext === Context.Danger\"\n [class.has-stripe-warning]=\"row.stripeContext && row.stripeContext === Context.Warning\"\n [class.has-stripe-info]=\"row.stripeContext && row.stripeContext === Context.Info\"\n [class.has-stripe-success]=\"row.stripeContext && row.stripeContext === Context.Success\"\n [ngClass]=\"[row.cssClass? row.cssClass : '']\"\n [attr.title]=\"row.title ? row.title : ''\">\n <td *ngFor=\"let col of columns\" class=\"{{col.cssClass}} tabular__{{col.label}}\" [ngClass]=\"{'tabular__checkboxes': col.dataType === TabularColumnTypes.Checkbox}\">\n\n <!-- checkbox type -->\n <div *ngIf=\"col.dataType === TabularColumnTypes.Checkbox\" class=\"hx-checkbox-control\">\n <input id=\"checkbox-{{row.id}}\" name=\"{{col.label}}-checkbox\" type=\"checkbox\" class=\"hx-checkbox\" title=\"{{col.label}}\" (change)=\"toggleIndividualSelect($event)\" [(ngModel)]=\"row.checked\" />\n <label for=\"checkbox-{{row.id}}\" class=\"hx-label\"></label>\n </div>\n\n <!-- string type | number type -->\n <span *ngIf=\"col.dataType === TabularColumnTypes.String || col.dataType === TabularColumnTypes.Number\" title=\"{{row[col.id]}}\">{{row[col.id]}}</span>\n\n <!-- icon type -->\n <i *ngIf=\"col.dataType === TabularColumnTypes.Icon && hasValidIconTypeParams(row[col.id])\" title=\"\" class=\"hx-icon {{row[col.id].icon}}\" [hxTooltip]=\"row[col.id].tooltip.content\" placement=\"{{row[col.id].tooltip.config.placement}}\" [context]=\"row[col.id].tooltip.config.context\"></i>\n\n <!-- date type -->\n <span *ngIf=\"col.dataType === TabularColumnTypes.Date\">{{row[col.id] | date:'d/M/yy'}}</span>\n\n <!-- status type -->\n <span *ngIf=\"col.dataType === TabularColumnTypes.Status\" class=\"hx-icon\" [ngClass]=\"{'is-primary':row[col.id],'is-danger':!row[col.id], 'icon-check-empty': row[col.id], 'icon-close-empty':!row[col.id]}\" ></span>\n\n <!-- badge type -->\n <span *ngIf=\"col.dataType === TabularColumnTypes.Badge && hasValidBadgeTypeParams(row[col.id])\" class=\"hx-badge is-small {{row[col.id].cssClass}}\"><span class=\"hx-badge-content\">{{row[col.id].label}}</span></span>\n\n <!-- date time type -->\n <span *ngIf=\"col.dataType === TabularColumnTypes.DateTime\">{{row[col.id] | date:'d/M/yy h:mm a'}}</span>\n\n <!-- actions type -->\n <div *ngIf=\"col.dataType === TabularColumnTypes.Actions\" class=\"hx-dropdown tabularActions\">\n\n\n <div class=\"tabularActions__action\">\n\n <ng-container *ngFor=\"let action of row[col.id];trackBy: trackByFn\">\n\n <!-- single action -->\n <button type=\"button\" class=\"hx-button is-flat\" [class.is-small]=\"config.size === TabularSize.Small\"\n *ngIf=\"!getActionDisabledState(action) && action.routeType === ActionConfigRouteType.Route && !hasChildren(action)\"\n [routerLink]=\"action.route\"\n class=\"hx-button is-flat {{action.css}}\"\n title=\"{{action.label}}\"><span class=\"hx-icon {{action.icon}}\"></span></button>\n <button type=\"button\" class=\"hx-button is-flat\" [class.is-small]=\"config.size === TabularSize.Small\"\n *ngIf=\"!getActionDisabledState(action) && action.routeType === ActionConfigRouteType.Callback && !hasChildren(action)\"\n (click)='executeCallback($event,action.callback)'\n class=\"hx-button is-flat {{action.css}}\"><span class=\"hx-icon {{action.icon}}\"></span></button>\n\n <!-- action with children -->\n <div class=\"hx-dropdown\" hxDropdown [isRight]=\"true\" *ngIf=\"hasChildren(action)\">\n\n <button class=\"hx-button is-flat hx-button-dropdown\" [class.is-small]=\"config.size === TabularSize.Small\" hxDropdownToggle type=\"button\">\n <i class=\"icon {{action.icon}}\"></i>\n </button>\n\n <div class=\"hx-dropdown-menu\" *hxDropdownMenu>\n\n <ng-container *ngFor=\"let childAction of action.children;trackBy: trackByFn\">\n <a *ngIf=\"!getActionDisabledState(childAction) && childAction.routeType === ActionConfigRouteType.Route\"\n [routerLink]=\"childAction.route\"\n class=\"hx-dropdown-item {{childAction.css}}\">{{childAction.label}}</a>\n <a *ngIf=\"!getActionDisabledState(childAction) && childAction.routeType === ActionConfigRouteType.Callback\"\n (click)='executeCallback($event,childAction.callback)'\n class=\"hx-dropdown-item {{childAction.css}}\">{{childAction.label}}</a>\n </ng-container>\n\n </div>\n\n </div>\n\n </ng-container>\n\n </div>\n </div>\n\n </td>\n </tr>\n </tbody>\n</table>\n\n<hx-pagination [directionLinks]=\"true\" [boundaryLinks]=\"true\" [rotate]=\"false\" [maxSize]=\"10\"\n [totalItems]=\"totalItemCount\" [itemsPerPage]=\"config.pagination.itemsPerPage\"\n [(ngModel)]=\"config.pagination.currentPage\" (pageChanged)=\"setPage($event)\" *ngIf=\"totalItemCount > config.pagination.itemsPerPage\"></hx-pagination>\n", styles: [ '.tabular__sortable {}', '.tabular__sorter {cursor:pointer; display:flex; align-items: center;}', '.tabular__sorter .hx-icon {margin-left:.1rem;}', '.tabular__checkboxes{width:2%;}', '.tabular__checkboxes .hx-checkbox-control{display:flex;}', '.tabularActions__action button.hx-button{ width: 1rem;}', '.tabularActions__action {display:flex;}' ] },] }, ]; /** @nocollapse */ TabularComponent.ctorParameters = function () { return [ { type: TabularConfig, }, { type: TabularSortByService, }, ]; }; TabularComponent.propDecorators = { "columns": [{ type: Input },], "rows": [{ type: Input },], "config": [{ type: Input },], "callback": [{ type: Input },], "searchTerm": [{ type: Input },], "refresh": [{ type: Output },], "rowClick": [{ type: Output },], }; return TabularComponent; }()); export { TabularComponent }; function TabularComponent_tsickle_Closure_declarations() { /** @type {!Array<{type: !Function, args: (undefined|!Array<?>)}>} */ TabularComponent.decorators; /** * @nocollapse * @type {function(): !Array<(null|{type: ?, decorators: (undefined|!Array<{type: !Function, args: (undefined|!Array<?>)}>)})>} */ TabularComponent.ctorParameters; /** @type {!Object<string,!Array<{type: !Function, args: (undefined|!Array<?>)}>>} */ TabularComponent.propDecorators; /** * Collection of column models * @type {?} */ TabularComponent.prototype.columns; /** * Collection of data rows * @type {?} */ TabularComponent.prototype.rows; /** * Event fired when refresh is called. * Host should refresh data of input. * @type {?} */ TabularComponent.prototype.refresh; /** * Event fired when a row is clicked. * @type {?} */ TabularComponent.prototype.rowClick; /** @type {?} */ TabularComponent.prototype.oldRows; /** @type {?} */ TabularComponent.prototype.pagedItems; /** @type {?} */ TabularComponent.prototype.TabularColumnTypes; /** @type {?} */ TabularComponent.prototype.TabularSize; /** @type {?} */ TabularComponent.prototype.ActionConfigRouteType; /** @type {?} */ TabularComponent.prototype.selectAll; /** @type {?} */ TabularComponent.prototype.Context; /** @type {?} */ TabularComponent.prototype.SortByDirection; /** @type {?} */ TabularComponent.prototype._callback; /** @type {?} */ TabularComponent.prototype._config; /** @type {?} */ TabularComponent.prototype._searchTerm; /** @type {?} */ TabularComponent.prototype.toggleSelectAll; /** @type {?} */ TabularComponent.prototype.toggleIndividualSelect; /** @type {?} */ TabularComponent.prototype.conf; /** @type {?} */ TabularComponent.prototype.sortByService; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGFidWxhci5jb21wb25lbnQuanMiLCJzb3VyY2VSb290Ijoibmc6Ly9AaHh1aS9hbmd1bGFyLyIsInNvdXJjZXMiOlsibGliL3RhYnVsYXIvdGFidWxhci5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFBQSxPQUFPLEVBQ0wsU0FBUyxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUUsWUFBWSxFQUN2QyxNQUFNLGVBQWUsQ0FBQztBQUV2QixPQUFPLEVBQUMsY0FBYyxFQUFDLE1BQU0sNEJBQTRCLENBQUM7QUFDMUQsT0FBTyxFQUFDLHFCQUFxQixFQUFpQixNQUFNLDRCQUE0QixDQUFDO0FBQ2pGLE9BQU8sRUFBQyxvQkFBb0IsRUFBRSxlQUFlLEVBQWtCLE1BQU0sMkJBQTJCLENBQUM7QUFDakcsT0FBTyxFQUFDLGFBQWEsRUFBQyxNQUFNLGtCQUFrQixDQUFDO0FBQy9DLE9BQU8sRUFBQyxXQUFXLEVBQUMsTUFBTSxxQkFBcUIsQ0FBQztBQUNoRCxPQUFPLEVBQWtELGtCQUFrQixFQUFDLE1BQU0sNEJBQTRCLENBQUM7QUFFL0csT0FBTyxFQUFDLE9BQU8sRUFBQyxNQUFNLFVBQVUsQ0FBQztBQUNqQyxPQUFPLEtBQUssQ0FBQyxNQUFNLFFBQVEsQ0FBQzs7SUE4TXpCLDBCQUNTLE1BQ0E7UUFGVCxpQkFLQTtRQUpTLFNBQUksR0FBSixJQUFJO1FBQ0osa0JBQWEsR0FBYixhQUFhOzs7Ozt1QkF0Qm9CLElBQUksWUFBWSxFQUFXOzs7O3dCQUs5QixJQUFJLFlBQVksRUFBTzt1QkFFL0IsRUFBRTswQkFDUCxFQUFFO2tDQUNELGtCQUFrQjsyQkFDekIsV0FBVztxQ0FDRCxxQkFBcUI7eUJBQ2pDLEtBQUs7dUJBQ1AsT0FBTzsrQkFDQyxlQUFlOytCQTJDckIsVUFBQyxNQUFNO1lBQ3hCLEdBQUcsQ0FBQyxDQUFDLHFCQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLEtBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFF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TSxDQUFDLFFBQVEsSUFBSSxNQUFNLENBQUMsUUFBUSxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUMsQ0FBQztLQUN4RDs7Ozs7O0lBRUQsb0NBQVM7Ozs7O0lBQVQsVUFBVSxLQUFLLEVBQUUsTUFBTTtRQUNyQixNQUFNLENBQUMsS0FBSyxDQUFDO0tBQ2Q7O2dCQXRaRixTQUFTLFNBQUM7b0JBQ1QsUUFBUSxFQUFFLGFBQWE7b0JBQ3ZCLFFBQVEsRUFBRSwwc09BbUhYO29CQUNDLE1BQU0sRUFBRTt3QkFDTix1QkFBdUI7d0JBQ3ZCLHVFQUF1RTt3QkFDdkUsZ0RBQWdEO3dCQUNoRCxpQ0FBaUM7d0JBQ2pDLDBEQUEwRDt3QkFDMUQseURBQXlEO3dCQUN6RCx5Q0FBeUM7cUJBQzFDO2lCQUNGOzs7O2dCQXRJTyxhQUFhO2dCQURiLG9CQUFvQjs7OzRCQStJekIsS0FBSzt5QkFNSixLQUFLOzJCQU1OLEtBQUs7NkJBWUwsS0FBSzsrQkFhTCxLQUFLOzRCQVlMLE1BQU07NkJBS04sTUFBTTs7MkJBM01UOztTQWdKYSxnQkFBZ0IiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xyXG4gIENvbXBvbmVudCwgSW5wdXQsIE91dHB1dCwgRXZlbnRFbWl0dGVyLCBPbkluaXQsIERvQ2hlY2ssIE9uQ2hhbmdlcywgU2ltcGxlQ2hhbmdlc1xyXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5pbXBvcnQge1RhYnVsYXJDb2x1bW59IGZyb20gJy4vdGFidWxhcic7XHJcbmltcG9ydCB7SVRhYnVsYXJDb25maWd9IGZyb20gJy4vdGFidWxhci1jb25maWcuaW50ZXJmYWNlJztcclxuaW1wb3J0IHtBY3Rpb25Db25maWdSb3V0ZVR5cGUsIElBY3Rpb25zQ29uZmlnfSBmcm9tICcuL2FjdGlvbnMtY29uZmlnLmludGVyZmFjZSc7XHJcbmltcG9ydCB7VGFidWxhclNvcnRCeVNlcnZpY2UsIFNvcnRCeURpcmVjdGlvbiwgSVNvcnRCeVByb3BlcnR5fSBmcm9tICcuL3RhYnVsYXItc29ydC1ieS5zZXJ2aWNlJztcclxuaW1wb3J0IHtUYWJ1bGFyQ29uZmlnfSBmcm9tICcuL3RhYnVsYXIuY29uZmlnJztcclxuaW1wb3J0IHtUYWJ1bGFyU2l6ZX0gZnJvbSAnLi90YWJ1bGFyLXNpemUuZW51bSc7XHJcbmltcG9ydCB7SVRhYnVsYXJDb2x1bW5CYWRnZVR5cGUsIElUYWJ1bGFyQ29sdW1uSWNvblR5cGUsIFRhYnVsYXJDb2x1bW5UeXBlc30gZnJvbSAnLi90YWJ1bGFyLWNvbHVtbi5pbnRlcmZhY2UnO1xyXG5pbXBvcnQge0lUYWJ1bGFyUm93fSBmcm9tICcuL3RhYnVsYXItcm93LmludGVyZmFjZSc7XHJcbmltcG9ydCB7Q29udGV4dH0gZnJvbSAnLi4vZW51bXMnO1xyXG5pbXBvcnQgKiBhcyBfIGZyb20gJ2xvZGFzaCc7XHJcblxyXG5AQ29tcG9uZW50KHtcclxuICBzZWxlY3RvcjogJ2h4YS10YWJ1bGFyJyxcclxuICB0ZW1wbGF0ZTogYDx0YWJsZSBjbGFzcz1cInRhYnVsYXIgaHgtdGFibGUgaXMtc3RyaXBlZFwiIFtjbGFzcy5pcy1ob3Zlcl09XCJjb25maWcuY2xpY2thYmxlUm93c1wiIFtjbGFzcy5pcy1uYXJyb3ddPVwiY29uZmlnLnNpemUgPT09IFRhYnVsYXJTaXplLlNtYWxsXCI+XHJcbiAgPHRoZWFkPlxyXG4gIDx0cj5cclxuICAgIDx0aCAqbmdGb3I9XCJsZXQgY29sIG9mIGNvbHVtbnNcIiBjbGFzcz1cInt7Y29sLmNzc0NsYXNzfX0gdGFidWxhcl9fe3tjb2wubGFiZWx9fVwiIFtuZ0NsYXNzXT1cInsndGFidWxhcl9fY2hlY2tib3hlcyc6IGNvbC5kYXRhVHlwZSA9PT0gVGFidWxhckNvbHVtblR5cGVzLkNoZWNrYm94LCAndGFidWxhcl9fc29ydGFibGUnOiBjb2wuc29ydGFibGV9XCI+XHJcblxyXG4gICAgICA8IS0tIHNvcnRhYmxlIGNvbHVtbiAtLT5cclxuICAgICAgPGEgY2xhc3M9XCJ0YWJ1bGFyX19zb3J0ZXJcIiBocmVmPVwiI1wiICpuZ0lmPVwiY29sLnNvcnRhYmxlICYmIGNvbC5kYXRhVHlwZSAhPSBUYWJ1bGFyQ29sdW1uVHlwZXMuQ2hlY2tib3hcIiAoY2xpY2spPVwib25Tb3J0Q2xpY2tIYW5kbGVyKGNvbC5pZCwgY29sLmRhdGFUeXBlKVwiPnt7Y29sLmxhYmVsfX0gPGkgY2xhc3M9XCJoeC1pY29uIGljb24tYXJyb3ctdXAgaXMtc21hbGxcIiBbY2xhc3MuaWNvbi1hcnJvdy11cF09XCJpc0NvbHVtblNvcnRlZChjb2wuaWQsIFNvcnRCeURpcmVjdGlvbi5Bc2NlbmRpbmcpXCIgW2NsYXNzLmljb24tYXJyb3ctZG93bl09XCJpc0NvbHVtblNvcnRlZChjb2wuaWQsIFNvcnRCeURpcmVjdGlvbi5EZXNjZW5kaW5nKVwiICpuZ0lmPVwiaXNDb2x1bW5Tb3J0ZWQoY29sLmlkLCBTb3J0QnlEaXJlY3Rpb24uRGVzY2VuZGluZykgfHwgaXNDb2x1bW5Tb3J0ZWQoY29sLmlkLCBTb3J0QnlEaXJlY3Rpb24uQXNjZW5kaW5nKVwiPjwvaT48L2E+XHJcblxyXG4gICAgICA8IS0tIG5vbiBzb3J0YWJsZSBjb2x1bW4gLS0+XHJcbiAgICAgIDxzcGFuICpuZ0lmPVwiIWNvbC5zb3J0YWJsZSAmJiBjb2wuZGF0YVR5cGUgIT09IFRhYnVsYXJDb2x1bW5UeXBlcy5DaGVja2JveFwiPnt7Y29sLmxhYmVsfX08L3NwYW4+XHJcblxyXG4gICAgICA8IS0tIGNoZWNrYm94IGNvbHVtbiAtLT5cclxuICAgICAgPGRpdiAqbmdJZj1cImNvbC5kYXRhVHlwZSA9PT0gVGFidWxhckNvbHVtblR5cGVzLkNoZWNrYm94XCIgY2xhc3M9XCJoeC1jaGVja2JveC1jb250cm9sXCI+XHJcbiAgICAgICAgPGlucHV0IGlkPVwic2VsZWN0QWxsXCIgbmFtZT1cInNlbGVjdEFsbFwiIHR5cGU9XCJjaGVja2JveFwiIGNsYXNzPVwiaHgtY2hlY2tib3hcIiAoY2hhbmdlKT1cInRvZ2dsZVNlbGVjdEFsbCgkZXZlbnQpXCIgdGl0bGU9XCJTZWxlY3QgQWxsXCIgWyhuZ01vZGVsKV09XCJzZWxlY3RBbGxcIiAvPlxyXG4gICAgICAgIDxsYWJlbCBmb3I9XCJzZWxlY3RBbGxcIiBjbGFzcz1cImh4LWxhYmVsXCI+PC9sYWJlbD5cclxuICAgICAgPC9kaXY+XHJcbiAgICA8L3RoPlxyXG4gIDwvdHI+XHJcbiAgPC90aGVhZD5cclxuXHJcbiAgPHRib2R5PlxyXG4gIDwhLS08dHIgKm5nRm9yPVwibGV0IHJvdyBvZiByb3dzIHwgcGFnaW5hdGU6IGNvbmZpZy5wYWdpbmF0aW9uIHwgc2ltcGxlU2VhcmNoOiBzZWFyY2hUZXJtXCI+LS0+XHJcbiAgPHRyICpuZ0Zvcj1cImxldCByb3cgb2YgcGFnZWRJdGVtc1wiXHJcbiAgICAgIChjbGljayk9XCJvblJvd0NsaWNrSGFuZGxlcigkZXZlbnQsIHJvdylcIlxyXG4gICAgICBbY2xhc3MuaXMtc2VsZWN0ZWRdPVwicm93LnNlbGVjdGVkXCJcclxuICAgICAgW2NsYXNzLmlzLWRhbmdlcl09XCJyb3cuY29udGV4dCAmJiByb3cuY29udGV4dCA9PT0gQ29udGV4dC5EYW5nZXJcIlxyXG4gICAgICBbY2xhc3MuaXMtd2FybmluZ109XCJyb3cuY29udGV4dCAmJiByb3cuY29udGV4dCA9PT0gQ29udGV4dC5XYXJuaW5nXCJcclxuICAgICAgW2NsYXNzLmlzLWluZm9dPVwicm93LmNvbnRleHQgJiYgcm93LmNvbnRleHQgPT09IENvbnRleHQuSW5mb1wiXHJcbiAgICAgIFtjbGFzcy5pcy1zdWNjZXNzXT1cInJvdy5jb250ZXh0ICYmIHJvdy5jb250ZXh0ID09PSBDb250ZXh0LlN1Y2Nlc3NcIlxyXG4gICAgICBbY2xhc3MuaGFzLXN0cmlwZS1kYW5nZXJdPVwicm93LnN0cmlwZUNvbnRleHQgJiYgcm93LnN0cmlwZUNvbnRleHQgPT09IENvbnRleHQuRGFuZ2VyXCJcclxuICAgICAgW2NsYXNzLmhhcy1zdHJpcGUtd2FybmluZ109XCJyb3cuc3RyaXBlQ29udGV4dCAmJiByb3cuc3RyaXBlQ29udGV4dCA9PT0gQ29udGV4dC5XYXJuaW5nXCJcclxuICAgICAgW2NsYXNzLmhhcy1zdHJpcGUtaW5mb109XCJyb3cuc3RyaXBlQ29udGV4dCAmJiByb3cuc3RyaXBlQ29udGV4dCA9PT0gQ29udGV4dC5JbmZvXCJcclxuICAgICAgW2NsYXNzLmhhcy1zdHJpcGUtc3VjY2Vzc109XCJyb3cuc3RyaXBlQ29udGV4dCAmJiByb3cuc3RyaXBlQ29udGV4dCA9PT0gQ29udGV4dC5TdWNjZXNzXCJcclxuICAgICAgW25nQ2xhc3NdPVwiW3Jvdy5jc3NDbGFzcz8gcm93LmNzc0NsYXNzIDogJyddXCJcclxuICAgICAgW2F0dHIudGl0bGVdPVwicm93LnRpdGxlID8gcm93LnRpdGxlIDogJydcIj5cclxuICAgIDx0ZCAqbmdGb3I9XCJsZXQgY29sIG9mIGNvbHVtbnNcIiBjbGFzcz1cInt7Y29sLmNzc0NsYXNzfX0gdGFidWxhcl9fe3tjb2wubGFiZWx9fVwiIFtuZ0NsYXNzXT1cInsndGFidWxhcl9fY2hlY2tib3hlcyc6IGNvbC5kYXRhVHlwZSA9PT0gVGFidWxhckNvbHVtblR5cGVzLkNoZWNrYm94fVwiPlxyXG5cclxuICAgICAgPCEtLSBjaGVja2JveCB0eXBlIC0tPlxyXG4gICAgICA8ZGl2ICpuZ0lmPVwiY29sLmRhdGFUeXBlID09PSBUYWJ1bGFyQ29sdW1uVHlwZXMuQ2hlY2tib3hcIiBjbGFzcz1cImh4LWNoZWNrYm94LWNvbnRyb2xcIj5cclxuICAgICAgICA8aW5wdXQgaWQ9XCJjaGVja2JveC17e3Jvdy5pZH19XCIgbmFtZT1cInt7Y29sLmxhYmVsfX0tY2hlY2tib3hcIiB0eXBlPVwiY2hlY2tib3hcIiBjbGFzcz1cImh4LWNoZWNrYm94XCIgdGl0bGU9XCJ7e2NvbC5sYWJlbH19XCIgKGNoYW5nZSk9XCJ0b2dnbGVJbmRpdmlkdWFsU2VsZWN0KCRldmVudClcIiBbKG5nTW9kZWwpXT1cInJvdy5jaGVja2VkXCIgLz5cclxuICAgICAgICA8bGFiZWwgZm9yPVwiY2hlY2tib3gte3tyb3cuaWR9fVwiIGNsYXNzPVwiaHgtbGFiZWxcIj48L2xhYmVsPlxyXG4gICAgICA8L2Rpdj5cclxuXHJcbiAgICAgIDwhLS0gc3RyaW5nIHR5cGUgfCBudW1iZXIgdHlwZSAtLT5cclxuICAgICAgPHNwYW4gKm5nSWY9XCJjb2wuZGF0YVR5cGUgPT09IFRhYnVsYXJDb2x1bW5UeXBlcy5TdHJpbmcgfHwgY29sLmRhdGFUeXBlID09PSBUYWJ1bGFyQ29sdW1uVHlwZXMuTnVtYmVyXCIgdGl0bGU9XCJ7e3Jvd1tjb2wuaWRdfX1cIj57e3Jvd1tjb2wuaWRdfX08L3NwYW4+XHJcblxyXG4gICAgICA8IS0tIGljb24gdHlwZSAtLT5cclxuICAgICAgPGkgKm5nSWY9XCJjb2wuZGF0YVR5cGUgPT09IFRhYnVsYXJDb2x1bW5UeXBlcy5JY29uICYmIGhhc1ZhbGlkSWNvblR5cGVQYXJhbXMocm93W2NvbC5pZF0pXCIgdGl0bGU9XCJcIiBjbGFzcz1cImh4LWljb24ge3tyb3dbY29sLmlkXS5pY29ufX1cIiBbaHhUb29sdGlwXT1cInJvd1tjb2wuaWRdLnRvb2x0aXAuY29udGVudFwiIHBsYWNlbWVudD1cInt7cm93W2NvbC5pZF0udG9vbHRpcC5jb25maWcucGxhY2VtZW50fX1cIiBbY29udGV4dF09XCJyb3dbY29sLmlkXS50b29sdGlwLmNvbmZpZy5jb250ZXh0XCI+PC9pPlxyXG5cclxuICAgICAgPCEtLSBkYXRlIHR5cGUgLS0+XHJcbiAgICAgIDxzcGFuICpuZ0lmPVwiY29sLmRhdGFUeXBlID09PSBUYWJ1bGFyQ29sdW1uVHlwZXMuRGF0ZVwiPnt7cm93W2NvbC5pZF0gfCBkYXRlOidkL00veXknfX08L3NwYW4+XHJcblxyXG4gICAgICA8IS0tIHN0YXR1cyB0eXBlIC0tPlxyXG4gICAgICA8c3BhbiAqbmdJZj1cImNvbC5kYXRhVHlwZSA9PT0gVGFidWxhckNvbHVtblR5cGVzLlN0YXR1c1wiIGNsYXNzPVwiaHgtaWNvblwiIFtuZ0NsYXNzXT1cInsnaXMtcHJpbWFyeSc6cm93W2NvbC5pZF0sJ2lzLWRhbmdlcic6IXJvd1tjb2wuaWRdLCAnaWNvbi1jaGVjay1lbXB0eSc6IHJvd1tjb2wuaWRdLCAnaWNvbi1jbG9zZS1lbXB0eSc6IXJvd1tjb2wuaWRdfVwiID48L3NwYW4+XHJcblxyXG4gICAgICA8IS0tIGJhZGdlIHR5cGUgLS0+XHJcbiAgICAgIDxzcGFuICpuZ0lmPVwiY29sLmRhdGFUeXBlID09PSBUYWJ1bGFyQ29sdW1uVHlwZXMuQmFkZ2UgJiYgaGFzVmFsaWRCYWRnZVR5cGVQYXJhbXMocm93W2NvbC5pZF0pXCIgY2xhc3M9XCJoeC1iYWRnZSBpcy1zbWFsbCB7e3Jvd1tjb2wuaWRdLmNzc0NsYXNzfX1cIj48c3BhbiBjbGFzcz1cImh4LWJhZGdlLWNvbnRlbnRcIj57e3Jvd1tjb2wuaWRdLmxhYmVsfX08L3NwYW4+PC9zcGFuPlxyXG5cclxuICAgICAgPCEtLSBkYXRlIHRpbWUgdHlwZSAtLT5cclxuICAgICAgPHNwYW4gKm5nSWY9XCJjb2wuZGF0YVR5cGUgPT09IFRhYnVsYXJDb2x1bW5UeXBlcy5EYXRlVGltZVwiPnt7cm93W2NvbC5pZF0gfCBkYXRlOidkL00veXkgaDptbSBhJ319PC9zcGFuPlxyXG5cclxuICAgICAgPCEtLSBhY3Rpb25zIHR5cGUgLS0+XHJcbiAgICAgIDxkaXYgKm5nSWY9XCJjb2wuZGF0YVR5cGUgPT09IFRhYnVsYXJDb2x1bW5UeXBlcy5BY3Rpb25zXCIgY2xhc3M9XCJoeC1kcm9wZG93biB0YWJ1bGFyQWN0aW9uc1wiPlxyXG5cclxuXHJcbiAgICAgICAgPGRpdiBjbGFzcz1cInRhYnVsYXJBY3Rpb25zX19hY3Rpb25cIj5cclxuXHJcbiAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0Zvcj1cImxldCBhY3Rpb24gb2Ygcm93W2NvbC5pZF07dHJhY2tCeTogdHJhY2tCeUZuXCI+XHJcblxyXG4gICAgICAgICAgICA8IS0tIHNpbmdsZSBhY3Rpb24gLS0+XHJcbiAgICAgICAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIGNsYXNzPVwiaHgtYnV0dG9uIGlzLWZsYXRcIiBbY2xhc3MuaXMtc21hbGxdPVwiY29uZmlnLnNpemUgPT09IFRhYnVsYXJTaXplLlNtYWxsXCJcclxuICAgICAgICAgICAgICAgICAgICAqbmdJZj1cIiFnZXRBY3Rpb25EaXNhYmxlZFN0YXRlKGFjdGlvbikgJiYgYWN0aW9uLnJvdXRlVHlwZSA9PT0gQWN0aW9uQ29uZmlnUm91dGVUeXBlLlJvdXRlICYmICFoYXNDaGlsZHJlbihhY3Rpb24pXCJcclxuICAgICAgICAgICAgICAgICAgICBbcm91dGVyTGlua109XCJhY3Rpb24ucm91dGVcIlxyXG4gICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiaHgtYnV0dG9uIGlzLWZsYXQge3thY3Rpb24uY3NzfX1cIlxyXG4gICAgICAgICAgICAgICAgICAgIHRpdGxlPVwie3thY3Rpb24ubGFiZWx9fVwiPjxzcGFuIGNsYXNzPVwiaHgtaWNvbiB7e2FjdGlvbi5pY29ufX1cIj48L3NwYW4+PC9idXR0b24+XHJcbiAgICAgICAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIGNsYXNzPVwiaHgtYnV0dG9uIGlzLWZsYXRcIiBbY2xhc3MuaXMtc21hbGxdPVwiY29uZmlnLnNpemUgPT09IFRhYnVsYXJTaXplLlNtYWxsXCJcclxuICAgICAgICAgICAgICAgICAgICAqbmdJZj1cIiFnZXRBY3Rpb25EaXNhYmxlZFN0YXRlKGFjdGlvbikgJiYgYWN0aW9uLnJvdXRlVHlwZSA9PT0gQWN0aW9uQ29uZmlnUm91dGVUeXBlLkNhbGxiYWNrICYmICFoYXNDaGlsZHJlbihhY3Rpb24pXCJcclxuICAgICAgICAgICAgICAgICAgIChjbGljayk9J2V4ZWN1dGVDYWxsYmFjaygkZXZlbnQsYWN0aW9uLmNhbGxiYWNrKSdcclxuICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiaHgtYnV0dG9uIGlzLWZsYXQge3thY3Rpb24uY3NzfX1cIj48c3BhbiBjbGFzcz1cImh4LWljb24ge3thY3Rpb24uaWNvbn19XCI+PC9zcGFuPjwvYnV0dG9uPlxyXG5cclxuICAgICAgICAgICAgPCEtLSBhY3Rpb24gd2l0aCBjaGlsZHJlbiAtLT5cclxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImh4LWRyb3Bkb3duXCIgaHhEcm9wZG93biBbaXNSaWdodF09XCJ0cnVlXCIgKm5nSWY9XCJoYXNDaGlsZHJlbihhY3Rpb24pXCI+XHJcblxyXG4gICAgICAgICAgICAgIDxidXR0b24gY2xhc3M9XCJoeC1idXR0b24gaXMtZmxhdCBoeC1idXR0b24tZHJvcGRvd25cIiBbY2xhc3MuaXMtc21hbGxdPVwiY29uZmlnLnNpemUgPT09IFRhYnVsYXJTaXplLlNtYWxsXCIgaHhEcm9wZG93blRvZ2dsZSB0eXBlPVwiYnV0dG9uXCI+XHJcbiAgICAgICAgICAgICAgICA8aSBjbGFzcz1cImljb24ge3thY3Rpb24uaWNvbn19XCI+PC9pPlxyXG4gICAgICAgICAgICAgIDwvYnV0dG9uPlxyXG5cclxuICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiaHgtZHJvcGRvd24tbWVudVwiICpoeERyb3Bkb3duTWVudT5cclxuXHJcbiAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0Zvcj1cImxldCBjaGlsZEFjdGlvbiBvZiBhY3Rpb24uY2hpbGRyZW47dHJhY2tCeTogdHJhY2tCeUZuXCI+XHJcbiAgICAgICAgICAgICAgICAgIDxhICpuZ0lmPVwiIWdldEFjdGlvbkRpc2FibGVkU3RhdGUoY2hpbGRBY3Rpb24pICYmIGNoaWxkQWN0aW9uLnJvdXRlVHlwZSA9PT0gQWN0aW9uQ29uZmlnUm91dGVUeXBlLlJvdXRlXCJcclxuICAgICAgICAgICAgICAgICAgICAgW3JvdXRlckxpbmtdPVwiY2hpbGRBY3Rpb24ucm91dGVcIlxyXG4gICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImh4LWRyb3Bkb3duLWl0ZW0ge3tjaGlsZEFjdGlvbi5jc3N9fVwiPnt7Y2hpbGRBY3Rpb24ubGFiZWx9fTwvYT5cclxuICAgICAgICAgICAgICAgICAgPGEgKm5nSWY9XCIhZ2V0QWN0aW9uRGlzYWJsZWRTdGF0ZShjaGlsZEFjdGlvbikgJiYgY2hpbGRBY3Rpb24ucm91dGVUeXBlID09PSBBY3Rpb25Db25maWdSb3V0ZVR5cGUuQ2FsbGJhY2tcIlxyXG4gICAgICAgICAgICAgICAgICAgICAoY2xpY2spPSdleGVjdXRlQ2FsbGJhY2soJGV2ZW50LGNoaWxkQWN0aW9uLmNhbGxiYWNrKSdcclxuICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJoeC1kcm9wZG93bi1pdGVtIHt7Y2hpbGRBY3Rpb24uY3NzfX1cIj57e2NoaWxkQWN0aW9uLmxhYmVsfX08L2E+XHJcbiAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cclxuXHJcbiAgICAgICAgICAgICAgPC9kaXY+XHJcblxyXG4gICAgICAgICAgICA8L2Rpdj5cclxuXHJcbiAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cclxuXHJcbiAgICAgICAgPC9kaXY+XHJcbiAgICAgIDwvZGl2PlxyXG5cclxuICAgIDwvdGQ+XHJcbiAgPC90cj5cclxuICA8L3Rib2R5PlxyXG48L3RhYmxlPlxyXG5cclxuPGh4LXBhZ2luYXRpb24gW2RpcmVjdGlvbkxpbmtzXT1cInRydWVcIiBbYm91bmRhcnlMaW5rc109XCJ0cnVlXCIgW3JvdGF0ZV09XCJmYWxzZVwiIFttYXhTaXplXT1cIjEwXCJcclxuICAgICAgICAgICAgICAgW3RvdGFsSXRlbXNdPVwidG90YWxJdGVtQ291bnRcIiBbaXRlbXNQZXJQYWdlXT1cImNvbmZpZy5wYWdpbmF0aW9uLml0ZW1zUGVyUGFnZVwiXHJcbiAgICAgICAgICAgICAgIFsobmdNb2RlbCldPVwiY29uZmlnLnBhZ2luYXRpb24uY3VycmVudFBhZ2VcIiAocGFnZUNoYW5nZWQpPVwic2V0UGFnZSgkZXZlbnQpXCIgKm5nSWY9XCJ0b3RhbEl0ZW1Db3VudCA+IGNvbmZpZy5wYWdpbmF0aW9uLml0ZW1zUGVyUGFnZVwiPjwvaHgtcGFnaW5hdGlvbj5cclxuYCxcclxuICBzdHlsZXM6IFtcclxuICAgICcudGFidWxhcl9fc29ydGFibGUge30nLFxyXG4gICAgJy50YWJ1bGFyX19zb3J0ZXIge2N1cnNvcjpwb2ludGVyOyBkaXNwbGF5OmZsZXg7IGFsaWduLWl0ZW1zOiBjZW50ZXI7fScsXHJcbiAgICAnLnRhYnVsYXJfX3NvcnRlciAuaHgtaWNvbiB7bWFyZ2luLWxlZnQ6LjFyZW07fScsXHJcbiAgICAnLnRhYnVsYXJfX2NoZWNrYm94ZXN7d2lkdGg6MiU7fScsXHJcbiAgICAnLnRhYnVsYXJfX2NoZWNrYm94ZXMgLmh4LWNoZWNrYm94LWNvbnRyb2x7ZGlzcGxheTpmbGV4O30nLFxyXG4gICAgJy50YWJ1bGFyQWN0aW9uc19fYWN0aW9uIGJ1dHRvbi5oeC1idXR0b257IHdpZHRoOiAxcmVtO30nLFxyXG4gICAgJy50YWJ1bGFyQWN0aW9uc19fYWN0aW9uIHtkaXNwbGF5OmZsZXg7fSdcclxuICBdXHJcbn0pXHJcblxyXG5cclxuZXhwb3J0IGNsYXNzIFRhYnVsYXJDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQsIERvQ2hlY2sge1xyXG5cclxuICAvKipcclxuICAgKiBDb2xsZWN0aW9uIG9mIGNvbHVtbiBtb2RlbHNcclxuICAgKi9cclxuICBASW5wdXQoKSBjb2x1bW5zOiBUYWJ1bGFyQ29sdW1uW107XHJcblxyXG4gIC8qKlxyXG4gICAqIENvbGxlY3Rpb24gb2YgZGF0YSByb3dzXHJcbiAgICovXHJcbiAgLy8gdG9kbyAtIHRoaXMgaXMgbm90IHN0cmljdC4gc2hvdWxkIGl0IGJlIHdoZW4gaXQncyBkeW5hbWljPy5cclxuICAgQElucHV0KCkgcm93czogSVRhYnVsYXJSb3dbXTtcclxuXHJcbiAgLyoqXHJcbiAgICogVGFidWxhciBjb25maWd1cmF0aW9uXHJcbiAgICogSVBhZ2luYXRpb25JbnN0YW5jZSwgSVNlYXJjaENvbmZpZ1xyXG4gICAqL1xyXG4gIEBJbnB1dCgpXHJcbiAgcHVibGljIGdldCBjb25maWcoKTogSVRhYnVsYXJDb25maWcgIHtcclxuICAgIHJldHVybiB0aGlzLl9jb25maWc7XHJcbiAgfVxyXG4gIHB1YmxpYyBzZXQgY29uZmlnKGM6IElUYWJ1bGFyQ29uZmlnKSAge1xyXG4gICAgaWYgKCFjLnNvcnRCeSkge1xyXG4gICAgICBjLnNvcnRCeSA9IFtdO1xyXG4gICAgfVxyXG4gICAgdGhpcy5fY29uZmlnID0gYztcclxuICB9XHJcblxyXG4gIC8qKiBUaGUgZnVuY3Rpb24gdG8gY2FsbCB3aGVuIGEgYWN0aW9uIGl0ZW0gaXMgY2xpY2tlZCAqKi9cclxuICBASW5wdXQoKVxyXG4gIHB1YmxpYyBnZXQgY2FsbGJhY2soKTogRnVuY3Rpb257XHJcbiAgICByZXR1cm4gdGhpcy5fY2FsbGJhY2s7XHJcbiAgfVxyXG4gIHB1YmxpYyBzZXQgY2FsbGJhY2soRm46IEZ1bmN0aW9uKXtcclxuICAgIHRoaXMuX2NhbGxiYWNrID0gRm47XHJcbiAgfVxyXG5cclxuXHJcbiAgLyoqXHJcbiAgICogU2VhcmNoIHRlcm0gaXMgdXNlZCBpbiB0aGUgc2ltcGxlIHNlYXJjaCBwaXBlXHJcbiAgICogQXJyYXkgb2Ygb2JqZWN0czogKm5nRm9yPVwiI3JvdyBvZiByb3dzIHwgc2ltcGxlU2VhcmNoIDogJ3RoZSBzZWFyY2ggdGVybSdcIlxyXG4gICAqL1xyXG4gIEBJbnB1dCgpXHJcbiAgcHVibGljIGdldCBzZWFyY2hUZXJtKCk6IHN0cmluZ3tcclxuICAgIHJldHVybiB0aGlzLl9zZWFyY2hUZXJtO1xyXG4gIH1cclxuICBwdWJsaWMgc2V0IHNlYXJjaFRlcm0odGVybTogc3RyaW5nKXtcclxuICAgIHRoaXMuX3NlYXJjaFRlcm0gPSB0ZXJtO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogRXZlbnQgZmlyZWQgd2hlbiByZWZyZXNoIGlzIGNhbGxlZC5cclxuICAgKiBIb3N0IHNob3VsZCByZWZyZXNoIGRhdGEgb2YgaW5wdXQuXHJcbiAgICovXHJcbiAgQE91dHB1dCgpIHJlZnJlc2g6IEV2ZW50RW1pdHRlcjxib29sZWFuPiA9IG5ldyBFdmVudEVtaXR0ZXI8Ym9vbGVhbj4oKTtcclxuXHJcbiAgLyoqXHJcbiAgICogRXZlbnQgZmlyZWQgd2hlbiBhIHJvdyBpcyBjbGlja2VkLlxyXG4gICAqL1xyXG4gIEBPdXRwdXQoKSByb3dDbGljazogRXZlbnRFbWl0dGVyPGFueT4gPSBuZXcgRXZlbnRFbWl0dGVyPGFueT4oKTtcclxuXHJcbiAgcHVibGljIG9sZFJvd3M6IElUYWJ1bGFyUm93W10gPSBbXTtcclxuICBwdWJsaWMgcGFnZWRJdGVtczogYW55W10gPSBbXTtcclxuICBwdWJsaWMgVGFidWxhckNvbHVtblR5cGVzID0gVGFidWxhckNvbHVtblR5cGVzO1xyXG4gIHB1YmxpYyBUYWJ1bGFyU2l6ZSA9IFRhYnVsYXJTaXplO1xyXG4gIHB1YmxpYyBBY3Rpb25Db25maWdSb3V0ZVR5cGUgPSBBY3Rpb25Db25maWdSb3V0ZVR5cGU7XHJcbiAgcHVibGljIHNlbGVjdEFsbCA9IGZhbHNlO1xyXG4gIHB1YmxpYyBDb250ZXh0ID0gQ29udGV4dDtcclxuICBwdWJsaWMgU29ydEJ5RGlyZWN0aW9uID0gU29ydEJ5RGlyZWN0aW9uO1xyXG4gIHByb3RlY3RlZCBfY2FsbGJhY2s6IEZ1bmN0aW9uO1xyXG4gIHByb3RlY3RlZCBfY29uZmlnOiBJVGFidWxhckNvbmZpZztcclxuICBwcm90ZWN0ZWQgX3NlYXJjaFRlcm06IHN0cmluZztcclxuXHJcblxyXG4gICBjb25zdHJ1Y3RvcihcclxuICAgIHByaXZhdGUgY29uZjogVGFidWxhckNvbmZpZyxcclxuICAgIHByaXZhdGUgc29ydEJ5U2VydmljZTogVGFidWxhclNvcnRCeVNlcnZpY2VcclxuICApIHtcclxuICAgIE9iamVjdC5hc3NpZ24odGhpcywgY29uZik7XHJcbiAgfVxyXG5cclxuICBuZ09uSW5pdCgpIHtcclxuXHJcbiAgfVxyXG5cclxuICBuZ0RvQ2hlY2soKSB7XHJcbiAgICBpZiAoIV8uaXNFcXVhbCh0aGlzLnJvd3MsIHRoaXMub2xkUm93cykpIHtcclxuICAgICAgdGhpcy5vbGRSb3dzID0gXy5jbG9uZURlZXAodGhpcy5yb3dzKTtcclxuICAgICAgdGhpcy5vcmRlckJ5RGF0YSgpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogQ2FsbHMgdGhlIHBhcnNlZCBjYWxsYmFjayB3aXRoIG9wdGlvbmFsIGFyZ3VtZW50c1xyXG4gICAqL1xyXG4gICBleGVjdXRlQ2FsbGJhY2soZXZlbnQ6IEV2ZW50LCBjYjogYW55W10pIHtcclxuICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xyXG4gICAgaWYgKGNiLmxlbmd0aCkge1xyXG4gICAgICBpZiAoY2IubGVuZ3RoID09PSAxKSB7IC8vIGlmIGNhbGxiYWNrIGhhcyBubyBhcmd1bWVudHNcclxuICAgICAgICBjYlswXSgpO1xyXG4gICAgICB9IGVsc2UgeyAvLyBpZiBjYWxsYmFjayBoYXMgMSBvciBtb3JlIGFyZ3VtZW50c1xyXG4gICAgICAgIGNvbnN0IGFyZ3M6IGFueVtdID0gW107XHJcbiAgICAgICAgZm9yIChsZXQgaSA9IDE7IGkgPCBjYi5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgYXJncy5wdXNoKGNiW2ldKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgY2JbMF0uYXBwbHkodGhpcywgYXJncyk7XHJcbiAgICAgIH1cclxuICAgIH1cclxuICB9XHJcblxyXG5cclxuICAgdG9nZ2xlU2VsZWN0QWxsID0gKCRldmVudCkgPT4ge1xyXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0a