@linid-dm/directory-manager-client-core
Version:
Core package by providing a set of angular components for the Directory Manager app.
234 lines • 50.6 kB
JavaScript
/**
* Copyright (C) 2020-2024 Linagora
*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU Affero General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version, provided you comply with the Additional Terms applicable for
* LinID Directory Manager software by LINAGORA pursuant to Section 7 of the GNU
* Affero General Public License, subsections (b), (c), and (e), pursuant to
* which these Appropriate Legal Notices must notably (i) retain the display of
* the "LinID™" trademark/logo at the top of the interface window, the display
* of the “You are using the Open Source and free version of LinID™, powered by
* Linagora © 2009–2013. Contribute to LinID R&D by subscribing to an Enterprise
* offer!” infobox and in the e-mails sent with the Program, notice appended to
* any type of outbound messages (e.g. e-mail and meeting requests) as well as
* in the LinID Directory Manager user interface, (ii) retain all hypertext
* links between LinID Directory Manager and https://linid.org/, as well as
* between LINAGORA and LINAGORA.com, and (iii) refrain from infringing LINAGORA
* intellectual property rights over its trademarks and commercial brands. Other
* Additional Terms apply, see <http://www.linagora.com/licenses/> for more
* details.
*
* 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 GNU Affero General Public License for more
* details.
*
* You should have received a copy of the GNU Affero General Public License and
* its applicable Additional Terms for LinID Directory Manager along with this
* program. If not, see <http://www.gnu.org/licenses/> for the GNU Affero
* General Public License version 3 and <http://www.linagora.com/licenses/> for
* the Additional Terms applicable to the LinID Directory Manager software.
*/
import { trigger } from '@angular/animations';
import { Component, EventEmitter, Input, Output, ViewChild, } from '@angular/core';
import { download, generateCsv, mkConfig } from 'export-to-csv';
import { takeUntil, tap } from 'rxjs';
import { EEllipsisMenuActions, emptyJsTable, fadeIn, getAllElementsToExport, getEditedDataSourceRow, getEditedDataSourceRows, getLabels, getMapIdValue, toJsTable, } from '../../shared';
import { ConfirmDialogComponent } from '../confirm-dialog/confirm-dialog.component';
import * as i0 from "@angular/core";
import * as i1 from "@angular/material/dialog";
import * as i2 from "@angular/common";
import * as i3 from "@angular/flex-layout/flex";
import * as i4 from "@angular/flex-layout/extended";
import * as i5 from "@angular/material/button";
import * as i6 from "@angular/material/icon";
import * as i7 from "@angular/material/menu";
export class EllipsisMenuComponent {
set actions(actions) {
this._actions = actions;
this.ellipsisMenuBtns = toJsTable(getLabels(this.uiComponent, actions, this.options, this.node, this.item));
}
get actions() {
return this._actions;
}
constructor(_dialog) {
this._dialog = _dialog;
this.selectedElementsUiIds = [];
this.isProcessingRequest = false;
this.clickOnAddResourceBtn = new EventEmitter();
this.evtDeleteSelectedElements = new EventEmitter();
this.evtDeleteSelectedElement = new EventEmitter();
this.evtMoveSelectedElements = new EventEmitter();
this.evtEditSelectedElements = new EventEmitter();
this.evtEditSelectedElement = new EventEmitter();
this.evtMoveDataNode = new EventEmitter();
this.ellipsisMenuBtns = emptyJsTable();
}
onClick(dialogAction) {
let confirmDialogData = {};
switch (dialogAction) {
case EEllipsisMenuActions.EXPORT:
this.exportAllElements();
break;
case EEllipsisMenuActions.ADD:
case EEllipsisMenuActions.ADD_CHILDREN:
this.clickOnAddResourceBtn.emit();
break;
case EEllipsisMenuActions.SINGLE_EDIT:
case EEllipsisMenuActions.MULTIPLE_EDIT:
confirmDialogData = {
...confirmDialogData,
mapSelectedElementIdEditableValue: getMapIdValue(this.selectedElementsUiIds, this.dataViewProperties?.getDataSource().data ?? [this.selectedRow], this.updateActionsParams?.edit?.columnId),
};
// falls through
default:
confirmDialogData = {
...confirmDialogData,
selectedElementsUiIds: this.selectedElementsUiIds.map((element) => Object.assign({}, element)),
title: this.ellipsisMenuBtns.byId[dialogAction]?.title ?? null,
cancelButtonText: this.ellipsisMenuBtns.byId[dialogAction]?.dialogCancelBtn ?? null,
confirmButtonText: this.ellipsisMenuBtns.byId[dialogAction]?.dialogConfirmBtn ?? null,
moveToRootButtonText: this.ellipsisMenuBtns.byId[dialogAction]?.dialogMoveToRootBtn ??
null,
moveToAnotherEntryButtonText: this.ellipsisMenuBtns.byId[dialogAction]
?.dialogMoveToAnotherEntryBtn ?? null,
dialogAction,
updateActionsParams: this.updateActionsParams ?? null,
attributeModelRef: this.attributeId ?? null,
triggerElementId: this.node?.ids?.id ?? null,
noSearchResult: this.ellipsisMenuBtns.byId[dialogAction]?.noSearchResult ?? null,
previousStepButtonText: this.ellipsisMenuBtns.byId[dialogAction]?.dialogPreviousStepBtn ??
null,
};
const dialogRef = this._dialog.open(ConfirmDialogComponent, {
restoreFocus: false,
panelClass: 'confirm-dialog-container',
data: confirmDialogData,
});
dialogRef.componentInstance.action$
.pipe(takeUntil(dialogRef.componentInstance.onDestroy$), tap((_) => {
this.menuTrigger.focus();
switch (dialogAction) {
case EEllipsisMenuActions.MOVE_NODE:
this.evtMoveDataNode.emit({
destinationNode: dialogRef.componentInstance.selectedNode,
dialogRef,
});
break;
case EEllipsisMenuActions.SINGLE_REASSIGN:
case EEllipsisMenuActions.MULTIPLE_REASSIGN:
this.evtMoveSelectedElements.emit({
selectedNode: dialogRef.componentInstance.selectedNode,
selectedItem: dialogRef.componentInstance.selectedItem,
selectedElementsUiIds: this.selectedElementsUiIds,
dialogRef,
});
break;
case EEllipsisMenuActions.SINGLE_EDIT:
this.evtEditSelectedElement.emit({
row: getEditedDataSourceRow(this.selectedRow, this.updateActionsParams.edit.columnId, dialogRef.componentInstance.editForm.getRawValue()),
dialogRef,
});
break;
case EEllipsisMenuActions.MULTIPLE_EDIT:
this.evtEditSelectedElements.emit({
rows: getEditedDataSourceRows(this.selectedElementsUiIds, this.dataViewProperties?.getDataSource().data || [
this.selectedRow,
], this.updateActionsParams.edit.columnId, dialogRef.componentInstance.editForm.getRawValue()),
dialogRef,
});
break;
default:
if (this.selectedElementsUiIds?.length === 1) {
this.evtDeleteSelectedElement.emit({
entry: this.selectedElementsUiIds[0],
dialogRef,
});
}
else {
this.evtDeleteSelectedElements.emit({
entries: this.selectedElementsUiIds,
dialogRef,
});
}
break;
}
}))
.subscribe();
break;
}
}
exportAllElements() {
const options = {
fieldSeparator: ';',
quoteStrings: '"',
decimalSeparator: '.',
showLabels: true,
showTitle: false,
title: !!this.ellipsisMenuBtns.byId.export
? this.ellipsisMenuBtns.byId.export.title
: '',
filename: !!this.ellipsisMenuBtns.byId.export
? this.ellipsisMenuBtns.byId.export.title
: '',
useTextFile: false,
useBom: true,
useKeysAsHeaders: true,
};
const exportProperties = {
options,
data: getAllElementsToExport(this.dataViewProperties.getDataSource().filteredData, this.dataViewProperties.getColumns()),
};
const csvConfig = mkConfig(exportProperties.options);
const csv = generateCsv(csvConfig)(exportProperties.data);
download(csvConfig)(csv);
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.4", ngImport: i0, type: EllipsisMenuComponent, deps: [{ token: i1.MatDialog }], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.4", type: EllipsisMenuComponent, selector: "dm-ellipsis-menu", inputs: { dataViewProperties: "dataViewProperties", selectedElementsUiIds: "selectedElementsUiIds", selectedRow: "selectedRow", isProcessingRequest: "isProcessingRequest", uiComponent: "uiComponent", updateActionsParams: "updateActionsParams", options: "options", node: "node", item: "item", attributeId: "attributeId", actions: "actions" }, outputs: { clickOnAddResourceBtn: "clickOnAddResourceBtn", evtDeleteSelectedElements: "evtDeleteSelectedElements", evtDeleteSelectedElement: "evtDeleteSelectedElement", evtMoveSelectedElements: "evtMoveSelectedElements", evtEditSelectedElements: "evtEditSelectedElements", evtEditSelectedElement: "evtEditSelectedElement", evtMoveDataNode: "evtMoveDataNode" }, viewQueries: [{ propertyName: "menuTrigger", first: true, predicate: ["menuTrigger"], descendants: true }], ngImport: i0, template: "<!-- Copyright (C) 2020-2024 Linagora\n\nThis program is free software: you can redistribute it and/or modify it under\nthe terms of the GNU Affero General Public License as published by the Free\nSoftware Foundation, either version 3 of the License, or (at your option) any\nlater version, provided you comply with the Additional Terms applicable for\nLinID Directory Manager software by LINAGORA pursuant to Section 7 of the GNU\nAffero General Public License, subsections (b), (c), and (e), pursuant to\nwhich these Appropriate Legal Notices must notably (i) retain the display of\nthe \"LinID\u2122\" trademark/logo at the top of the interface window, the display\nof the \u201CYou are using the Open Source and free version of LinID\u2122, powered by\nLinagora \u00A9 2009\u20132013. Contribute to LinID R&D by subscribing to an Enterprise\noffer!\u201D infobox and in the e-mails sent with the Program, notice appended to\nany type of outbound messages (e.g. e-mail and meeting requests) as well as\nin the LinID Directory Manager user interface, (ii) retain all hypertext\nlinks between LinID Directory Manager and https://linid.org/, as well as\nbetween LINAGORA and LINAGORA.com, and (iii) refrain from infringing LINAGORA\nintellectual property rights over its trademarks and commercial brands. Other\nAdditional Terms apply, see <http://www.linagora.com/licenses/> for more\ndetails.\n\nThis program is distributed in the hope that it will be useful, but WITHOUT\nANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS\nFOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more\ndetails.\n\nYou should have received a copy of the GNU Affero General Public License and\nits applicable Additional Terms for LinID Directory Manager along with this\nprogram. If not, see <http://www.gnu.org/licenses/> for the GNU Affero\nGeneral Public License version 3 and <http://www.linagora.com/licenses/> for\nthe Additional Terms applicable to the LinID Directory Manager software. -->\n\n<div fxLayout=\"row\" fxLayoutAlign=\"end center\">\n <button\n #menuTrigger=\"matMenuTrigger\"\n mat-icon-button\n aria-label=\"Menu\"\n [class.opened]=\"menuTrigger.menuOpen\"\n [matMenuTriggerFor]=\"menu\"\n class=\"ellipsis-menu-btn\"\n >\n <mat-icon\n aria-hidden=\"true\"\n [ngClass]=\"{\n 'toggle-ellipsis-menu-icon': menuTrigger.menuOpen\n }\"\n >more_vert</mat-icon\n >\n </button>\n <mat-menu #menu=\"matMenu\" backdropClass=\"ellipsis-menu\">\n <ul>\n <li *ngFor=\"let labelId of ellipsisMenuBtns.allIds\">\n <button\n mat-menu-item\n [attr.aria-label]=\"ellipsisMenuBtns.byId[labelId].btnLabel\"\n [disabled]=\"\n ellipsisMenuBtns.byId[labelId].canBeDisabled &&\n (isProcessingRequest || selectedElementsUiIds.length < 1)\n \"\n (click)=\"onClick(labelId)\"\n >\n <mat-icon\n aria-hidden=\"true\"\n [class.mat-menu-icon-disable]=\"\n ellipsisMenuBtns.byId[labelId].canBeDisabled &&\n selectedElementsUiIds.length < 1\n \"\n >\n {{ ellipsisMenuBtns.byId[labelId].icon }}\n </mat-icon>\n <span>{{ ellipsisMenuBtns.byId[labelId].btnLabel }}</span>\n </button>\n </li>\n </ul>\n </mat-menu>\n</div>\n", styles: ["@charset \"UTF-8\";.mat-menu-icon-disable{color:#00000061}.ellipsis-menu-btn{transition:.4s ease-in-out}.ellipsis-menu-btn:hover,.ellipsis-menu-btn:focus{background-color:#00000014}.opened{background-color:#00000014}\n"], dependencies: [{ kind: "directive", type: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i3.DefaultLayoutDirective, selector: " [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]", inputs: ["fxLayout", "fxLayout.xs", "fxLayout.sm", "fxLayout.md", "fxLayout.lg", "fxLayout.xl", "fxLayout.lt-sm", "fxLayout.lt-md", "fxLayout.lt-lg", "fxLayout.lt-xl", "fxLayout.gt-xs", "fxLayout.gt-sm", "fxLayout.gt-md", "fxLayout.gt-lg"] }, { kind: "directive", type: i3.DefaultLayoutAlignDirective, selector: " [fxLayoutAlign], [fxLayoutAlign.xs], [fxLayoutAlign.sm], [fxLayoutAlign.md], [fxLayoutAlign.lg], [fxLayoutAlign.xl], [fxLayoutAlign.lt-sm], [fxLayoutAlign.lt-md], [fxLayoutAlign.lt-lg], [fxLayoutAlign.lt-xl], [fxLayoutAlign.gt-xs], [fxLayoutAlign.gt-sm], [fxLayoutAlign.gt-md], [fxLayoutAlign.gt-lg]", inputs: ["fxLayoutAlign", "fxLayoutAlign.xs", "fxLayoutAlign.sm", "fxLayoutAlign.md", "fxLayoutAlign.lg", "fxLayoutAlign.xl", "fxLayoutAlign.lt-sm", "fxLayoutAlign.lt-md", "fxLayoutAlign.lt-lg", "fxLayoutAlign.lt-xl", "fxLayoutAlign.gt-xs", "fxLayoutAlign.gt-sm", "fxLayoutAlign.gt-md", "fxLayoutAlign.gt-lg"] }, { kind: "directive", type: i4.DefaultClassDirective, selector: " [ngClass], [ngClass.xs], [ngClass.sm], [ngClass.md], [ngClass.lg], [ngClass.xl], [ngClass.lt-sm], [ngClass.lt-md], [ngClass.lt-lg], [ngClass.lt-xl], [ngClass.gt-xs], [ngClass.gt-sm], [ngClass.gt-md], [ngClass.gt-lg]", inputs: ["ngClass", "ngClass.xs", "ngClass.sm", "ngClass.md", "ngClass.lg", "ngClass.xl", "ngClass.lt-sm", "ngClass.lt-md", "ngClass.lt-lg", "ngClass.lt-xl", "ngClass.gt-xs", "ngClass.gt-sm", "ngClass.gt-md", "ngClass.gt-lg"] }, { kind: "component", type: i5.MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "component", type: i6.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i7.MatMenu, selector: "mat-menu", inputs: ["backdropClass", "aria-label", "aria-labelledby", "aria-describedby", "xPosition", "yPosition", "overlapTrigger", "hasBackdrop", "class", "classList"], outputs: ["closed", "close"], exportAs: ["matMenu"] }, { kind: "component", type: i7.MatMenuItem, selector: "[mat-menu-item]", inputs: ["role", "disabled", "disableRipple"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i7.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }], animations: [trigger('fadeIn', fadeIn(':enter'))] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.4", ngImport: i0, type: EllipsisMenuComponent, decorators: [{
type: Component,
args: [{ selector: 'dm-ellipsis-menu', animations: [trigger('fadeIn', fadeIn(':enter'))], template: "<!-- Copyright (C) 2020-2024 Linagora\n\nThis program is free software: you can redistribute it and/or modify it under\nthe terms of the GNU Affero General Public License as published by the Free\nSoftware Foundation, either version 3 of the License, or (at your option) any\nlater version, provided you comply with the Additional Terms applicable for\nLinID Directory Manager software by LINAGORA pursuant to Section 7 of the GNU\nAffero General Public License, subsections (b), (c), and (e), pursuant to\nwhich these Appropriate Legal Notices must notably (i) retain the display of\nthe \"LinID\u2122\" trademark/logo at the top of the interface window, the display\nof the \u201CYou are using the Open Source and free version of LinID\u2122, powered by\nLinagora \u00A9 2009\u20132013. Contribute to LinID R&D by subscribing to an Enterprise\noffer!\u201D infobox and in the e-mails sent with the Program, notice appended to\nany type of outbound messages (e.g. e-mail and meeting requests) as well as\nin the LinID Directory Manager user interface, (ii) retain all hypertext\nlinks between LinID Directory Manager and https://linid.org/, as well as\nbetween LINAGORA and LINAGORA.com, and (iii) refrain from infringing LINAGORA\nintellectual property rights over its trademarks and commercial brands. Other\nAdditional Terms apply, see <http://www.linagora.com/licenses/> for more\ndetails.\n\nThis program is distributed in the hope that it will be useful, but WITHOUT\nANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS\nFOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more\ndetails.\n\nYou should have received a copy of the GNU Affero General Public License and\nits applicable Additional Terms for LinID Directory Manager along with this\nprogram. If not, see <http://www.gnu.org/licenses/> for the GNU Affero\nGeneral Public License version 3 and <http://www.linagora.com/licenses/> for\nthe Additional Terms applicable to the LinID Directory Manager software. -->\n\n<div fxLayout=\"row\" fxLayoutAlign=\"end center\">\n <button\n #menuTrigger=\"matMenuTrigger\"\n mat-icon-button\n aria-label=\"Menu\"\n [class.opened]=\"menuTrigger.menuOpen\"\n [matMenuTriggerFor]=\"menu\"\n class=\"ellipsis-menu-btn\"\n >\n <mat-icon\n aria-hidden=\"true\"\n [ngClass]=\"{\n 'toggle-ellipsis-menu-icon': menuTrigger.menuOpen\n }\"\n >more_vert</mat-icon\n >\n </button>\n <mat-menu #menu=\"matMenu\" backdropClass=\"ellipsis-menu\">\n <ul>\n <li *ngFor=\"let labelId of ellipsisMenuBtns.allIds\">\n <button\n mat-menu-item\n [attr.aria-label]=\"ellipsisMenuBtns.byId[labelId].btnLabel\"\n [disabled]=\"\n ellipsisMenuBtns.byId[labelId].canBeDisabled &&\n (isProcessingRequest || selectedElementsUiIds.length < 1)\n \"\n (click)=\"onClick(labelId)\"\n >\n <mat-icon\n aria-hidden=\"true\"\n [class.mat-menu-icon-disable]=\"\n ellipsisMenuBtns.byId[labelId].canBeDisabled &&\n selectedElementsUiIds.length < 1\n \"\n >\n {{ ellipsisMenuBtns.byId[labelId].icon }}\n </mat-icon>\n <span>{{ ellipsisMenuBtns.byId[labelId].btnLabel }}</span>\n </button>\n </li>\n </ul>\n </mat-menu>\n</div>\n", styles: ["@charset \"UTF-8\";.mat-menu-icon-disable{color:#00000061}.ellipsis-menu-btn{transition:.4s ease-in-out}.ellipsis-menu-btn:hover,.ellipsis-menu-btn:focus{background-color:#00000014}.opened{background-color:#00000014}\n"] }]
}], ctorParameters: () => [{ type: i1.MatDialog }], propDecorators: { dataViewProperties: [{
type: Input
}], selectedElementsUiIds: [{
type: Input
}], selectedRow: [{
type: Input
}], isProcessingRequest: [{
type: Input
}], uiComponent: [{
type: Input
}], updateActionsParams: [{
type: Input
}], options: [{
type: Input
}], node: [{
type: Input
}], item: [{
type: Input
}], attributeId: [{
type: Input
}], actions: [{
type: Input
}], clickOnAddResourceBtn: [{
type: Output
}], evtDeleteSelectedElements: [{
type: Output
}], evtDeleteSelectedElement: [{
type: Output
}], evtMoveSelectedElements: [{
type: Output
}], evtEditSelectedElements: [{
type: Output
}], evtEditSelectedElement: [{
type: Output
}], evtMoveDataNode: [{
type: Output
}], menuTrigger: [{
type: ViewChild,
args: ['menuTrigger']
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZWxsaXBzaXMtbWVudS5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi9wYWNrYWdlcy9saWJzL2NsaWVudC1jb3JlL3NyYy9saWIvZmVhdHVyZS9lbGxpcHNpcy1tZW51L2VsbGlwc2lzLW1lbnUuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vcGFja2FnZXMvbGlicy9jbGllbnQtY29yZS9zcmMvbGliL2ZlYXR1cmUvZWxsaXBzaXMtbWVudS9lbGxpcHNpcy1tZW51LmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQWdDRztBQUVILE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUM5QyxPQUFPLEVBQ0wsU0FBUyxFQUNULFlBQVksRUFDWixLQUFLLEVBQ0wsTUFBTSxFQUNOLFNBQVMsR0FDVixNQUFNLGVBQWUsQ0FBQztBQUd2QixPQUFPLEVBQUUsUUFBUSxFQUFFLFdBQVcsRUFBRSxRQUFRLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDaEUsT0FBTyxFQUFFLFNBQVMsRUFBRSxHQUFHLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDdEMsT0FBTyxFQUVMLG9CQUFvQixFQWtCcEIsWUFBWSxFQUNaLE1BQU0sRUFDTixzQkFBc0IsRUFDdEIsc0JBQXNCLEVBQ3RCLHVCQUF1QixFQUN2QixTQUFTLEVBQ1QsYUFBYSxFQUNiLFNBQVMsR0FDVixNQUFNLGNBQWMsQ0FBQztBQUN0QixPQUFPLEVBQUUsc0JBQXNCLEVBQUUsTUFBTSw0Q0FBNEMsQ0FBQzs7Ozs7Ozs7O0FBUXBGLE1BQU0sT0FBTyxxQkFBcUI7SUFZaEMsSUFBYSxPQUFPLENBQUMsT0FBOEM7UUFDakUsSUFBSSxDQUFDLFFBQVEsR0FBRyxPQUFPLENBQUM7UUFDeEIsSUFBSSxDQUFDLGdCQUFnQixHQUFHLFNB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XG4gKiBDb3B5cmlnaHQgKEMpIDIwMjAtMjAyNCBMaW5hZ29yYVxuICpcbiAqIFRoaXMgcHJvZ3JhbSBpcyBmcmVlIHNvZnR3YXJlOiB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0IHVuZGVyXG4gKiB0aGUgdGVybXMgb2YgdGhlIEdOVSBBZmZlcm8gR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWVcbiAqIFNvZnR3YXJlIEZvdW5kYXRpb24sIGVpdGhlciB2ZXJzaW9uIDMgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55XG4gKiBsYXRlciB2ZXJzaW9uLCBwcm92aWRlZCB5b3UgY29tcGx5IHdpdGggdGhlIEFkZGl0aW9uYWwgVGVybXMgYXBwbGljYWJsZSBmb3JcbiAqIExpbklEIERpcmVjdG9yeSBNYW5hZ2VyIHNvZnR3YXJlIGJ5IExJTkFHT1JBIHB1cnN1YW50IHRvIFNlY3Rpb24gNyBvZiB0aGUgR05VXG4gKiBBZmZlcm8gR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwgc3Vic2VjdGlvbnMgKGIpLCAoYyksIGFuZCAoZSksIHB1cnN1YW50IHRvXG4gKiB3aGljaCB0aGVzZSBBcHByb3ByaWF0ZSBMZWdhbCBOb3RpY2VzIG11c3Qgbm90YWJseSAoaSkgcmV0YWluIHRoZSBkaXNwbGF5IG9mXG4gKiB0aGUgXCJMaW5JROKEolwiIHRyYWRlbWFyay9sb2dvIGF0IHRoZSB0b3Agb2YgdGhlIGludGVyZmFjZSB3aW5kb3csIHRoZSBkaXNwbGF5XG4gKiBvZiB0aGUg4oCcWW91IGFyZSB1c2luZyB0aGUgT3BlbiBTb3VyY2UgYW5kIGZyZWUgdmVyc2lvbiBvZiBMaW5JROKEoiwgcG93ZXJlZCBieVxuICogTGluYWdvcmEgwqkgMjAwOeKAkzIwMTMuIENvbnRyaWJ1dGUgdG8gTGluSUQgUiZEIGJ5IHN1YnNjcmliaW5nIHRvIGFuIEVudGVycHJpc2VcbiAqIG9mZmVyIeKAnSBpbmZvYm94IGFuZCBpbiB0aGUgZS1tYWlscyBzZW50IHdpdGggdGhlIFByb2dyYW0sIG5vdGljZSBhcHBlbmRlZCB0b1xuICogYW55IHR5cGUgb2Ygb3V0Ym91bmQgbWVzc2FnZXMgKGUuZy4gZS1tYWlsIGFuZCBtZWV0aW5nIHJlcXVlc3RzKSBhcyB3ZWxsIGFzXG4gKiBpbiB0aGUgTGluSUQgRGlyZWN0b3J5IE1hbmFnZXIgdXNlciBpbnRlcmZhY2UsIChpaSkgcmV0YWluIGFsbCBoeXBlcnRleHRcbiAqIGxpbmtzIGJldHdlZW4gTGluSUQgRGlyZWN0b3J5IE1hbmFnZXIgYW5kIGh0dHBzOi8vbGluaWQub3JnLywgYXMgd2VsbCBhc1xuICogYmV0d2VlbiBMSU5BR09SQSBhbmQgTElOQUdPUkEuY29tLCBhbmQgKGlpaSkgcmVmcmFpbiBmcm9tIGluZnJpbmdpbmcgTElOQUdPUkFcbiAqIGludGVsbGVjdHVhbCBwcm9wZXJ0eSByaWdodHMgb3ZlciBpdHMgdHJhZGVtYXJrcyBhbmQgY29tbWVyY2lhbCBicmFuZHMuIE90aGVyXG4gKiBBZGRpdGlvbmFsIFRlcm1zIGFwcGx5LCBzZWUgPGh0dHA6Ly93d3cubGluYWdvcmEuY29tL2xpY2Vuc2VzLz4gZm9yIG1vcmVcbiAqIGRldGFpbHMuXG4gKlxuICogVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUXG4gKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTU1xuICogRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiBTZWUgdGhlIEdOVSBBZmZlcm8gR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZVxuICogZGV0YWlscy5cbiAqXG4gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgQWZmZXJvIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYW5kXG4gKiBpdHMgYXBwbGljYWJsZSBBZGRpdGlvbmFsIFRlcm1zIGZvciBMaW5JRCBEaXJlY3RvcnkgTWFuYWdlciBhbG9uZyB3aXRoIHRoaXNcbiAqIHByb2dyYW0uIElmIG5vdCwgc2VlIDxodHRwOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvPiBmb3IgdGhlIEdOVSBBZmZlcm9cbiAqIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAzIGFuZCA8aHR0cDovL3d3dy5saW5hZ29yYS5jb20vbGljZW5zZXMvPiBmb3JcbiAqIHRoZSBBZGRpdGlvbmFsIFRlcm1zIGFwcGxpY2FibGUgdG8gdGhlIExpbklEIERpcmVjdG9yeSBNYW5hZ2VyIHNvZnR3YXJlLlxuICovXG5cbmltcG9ydCB7IHRyaWdnZXIgfSBmcm9tICdAYW5ndWxhci9hbmltYXRpb25zJztcbmltcG9ydCB7XG4gIENvbXBvbmVudCxcbiAgRXZlbnRFbWl0dGVyLFxuICBJbnB1dCxcbiAgT3V0cHV0LFxuICBWaWV3Q2hpbGQsXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgTWF0RGlhbG9nIH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvZGlhbG9nJztcbmltcG9ydCB7IE1hdE1lbnVUcmlnZ2VyIH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvbWVudSc7XG5pbXBvcnQgeyBkb3dubG9hZCwgZ2VuZXJhdGVDc3YsIG1rQ29uZmlnIH0gZnJvbSAnZXhwb3J0LXRvLWNzdic7XG5pbXBvcnQgeyB0YWtlVW50aWwsIHRhcCB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHtcbiAgRGF0YVZpZXdQcm9wZXJ0aWVzLFxuICBFRWxsaXBzaXNNZW51QWN0aW9ucyxcbiAgRVVJQ29tcG9uZW50LFxuICBJQXJyYXlBdHRyaWJ1dGVVcGRhdGVQYXJhbXMsXG4gIElBdHRyaWJ1dGVBY3Rpb25zLFxuICBJRGF0YUl0ZW0sXG4gIElEYXRhTm9kZSxcbiAgSURhdGFTb3VyY2VSb3csXG4gIElEZWxldGVNdWx0aXBsZUVudHJpZXMsXG4gIElEZWxldGVTaW5nbGVFbnRyeSxcbiAgSUVkaXRNdWx0aXBsZURhdGFTb3VyY2VSb3csXG4gIElFZGl0U2luZ2xlRGF0YVNvdXJjZVJvdyxcbiAgSUVsbGlwc2lzQnRuLFxuICBJRWxsaXBzaXNNZW51T3B0aW9ucyxcbiAgSU1vdmVEYXRhTm9kZSxcbiAgSU1vdmVFbGVtZW50cyxcbiAgSVByaW1pdGl2ZUFjdGlvbnMsXG4gIElVaUVudHJ5SWRzLFxuICBKc1RhYmxlLFxuICBlbXB0eUpzVGFibGUsXG4gIGZhZGVJbixcbiAgZ2V0QWxsRWxlbWVudHNUb0V4cG9ydCxcbiAgZ2V0RWRpdGVkRGF0YVNvdXJjZVJvdyxcbiAgZ2V0RWRpdGVkRGF0YVNvdXJjZVJvd3MsXG4gIGdldExhYmVscyxcbiAgZ2V0TWFwSWRWYWx1ZSxcbiAgdG9Kc1RhYmxlLFxufSBmcm9tICcuLi8uLi9zaGFyZWQnO1xuaW1wb3J0IHsgQ29uZmlybURpYWxvZ0NvbXBvbmVudCB9IGZyb20gJy4uL2NvbmZpcm0tZGlhbG9nL2NvbmZpcm0tZGlhbG9nLmNvbXBvbmVudCc7XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ2RtLWVsbGlwc2lzLW1lbnUnLFxuICB0ZW1wbGF0ZVVybDogJy4vZWxsaXBzaXMtbWVudS5jb21wb25lbnQuaHRtbCcsXG4gIHN0eWxlVXJsczogWycuL2VsbGlwc2lzLW1lbnUuY29tcG9uZW50LnNjc3MnXSxcbiAgYW5pbWF0aW9uczogW3RyaWdnZXIoJ2ZhZGVJbicsIGZhZGVJbignOmVudGVyJykpXSxcbn0pXG5leHBvcnQgY2xhc3MgRWxsaXBzaXNNZW51Q29tcG9uZW50IHtcbiAgQElucHV0KCkgZGF0YVZpZXdQcm9wZXJ0aWVzPzogRGF0YVZpZXdQcm9wZXJ0aWVzO1xuICBASW5wdXQoKSBzZWxlY3RlZEVsZW1lbnRzVWlJZHM6IElVaUVudHJ5SWRzW10gPSBbXTtcbiAgQElucHV0KCkgc2VsZWN0ZWRSb3c6IElEYXRhU291cmNlUm93O1xuICBASW5wdXQoKSBpc1Byb2Nlc3NpbmdSZXF1ZXN0ID0gZmFsc2U7XG4gIEBJbnB1dCgpIHVpQ29tcG9uZW50OiBFVUlDb21wb25lbnQ7XG4gIEBJbnB1dCgpIHVwZGF0ZUFjdGlvbnNQYXJhbXM6IElBcnJheUF0dHJpYnV0ZVVwZGF0ZVBhcmFtcztcbiAgQElucHV0KCkgb3B0aW9uczogSUVsbGlwc2lzTWVudU9wdGlvbnM7XG4gIEBJbnB1dCgpIG5vZGU6IElEYXRhTm9kZTtcbiAgQElucHV0KCkgaXRlbTogSURhdGFJdGVtO1xuICBASW5wdXQoKSBhdHRyaWJ1dGVJZDogc3RyaW5nO1xuXG4gIEBJbnB1dCgpIHNldCBhY3Rpb25zKGFjdGlvbnM6IElQcmltaXRpdmVBY3Rpb25zIHwgSUF0dHJpYnV0ZUFjdGlvbnMpIHtcbiAgICB0aGlzLl9hY3Rpb25zID0gYWN0aW9ucztcbiAgICB0aGlzLmVsbGlwc2lzTWVudUJ0bnMgPSB0b0pzVGFibGUoXG4gICAgICBnZXRMYWJlbHModGhpcy51aUNvbXBvbmVudCwgYWN0aW9ucywgdGhpcy5vcHRpb25zLCB0aGlzLm5vZGUsIHRoaXMuaXRlbSlcbiAgICApO1xuICB9XG5cbiAgZ2V0IGFjdGlvbnMoKTogSVByaW1pdGl2ZUFjdGlvbnMgfCBJQXR0cmlidXRlQWN0aW9ucyB7XG4gICAgcmV0dXJuIHRoaXMuX2FjdGlvbnM7XG4gIH1cblxuICBAT3V0cHV0KCkgY2xpY2tPbkFkZFJlc291cmNlQnRuID0gbmV3IEV2ZW50RW1pdHRlcjx2b2lkPigpO1xuICBAT3V0cHV0KCkgZXZ0RGVsZXRlU2VsZWN0ZWRFbGVtZW50cyA9XG4gICAgbmV3IEV2ZW50RW1pdHRlcjxJRGVsZXRlTXVsdGlwbGVFbnRyaWVzPigpO1xuICBAT3V0cHV0KCkgZXZ0RGVsZXRlU2VsZWN0ZWRFbGVtZW50ID0gbmV3IEV2ZW50RW1pdHRlcjxJRGVsZXRlU2luZ2xlRW50cnk+KCk7XG4gIEBPdXRwdXQoKSBldnRNb3ZlU2VsZWN0ZWRFbGVtZW50cyA9IG5ldyBFdmVudEVtaXR0ZXI8SU1vdmVFbGVtZW50cz4oKTtcbiAgQE91dHB1dCgpIGV2dEVkaXRTZWxlY3RlZEVsZW1lbnRzID1cbiAgICBuZXcgRXZlbnRFbWl0dGVyPElFZGl0TXVsdGlwbGVEYXRhU291cmNlUm93PigpO1xuICBAT3V0cHV0KCkgZXZ0RWRpdFNlbGVjdGVkRWxlbWVudCA9XG4gICAgbmV3IEV2ZW50RW1pdHRlcjxJRWRpdFNpbmdsZURhdGFTb3VyY2VSb3c+KCk7XG4gIEBPdXRwdXQoKSBldnRNb3ZlRGF0YU5vZGUgPSBuZXcgRXZlbnRFbWl0dGVyPElNb3ZlRGF0YU5vZGU+KCk7XG5cbiAgQFZpZXdDaGlsZCgnbWVudVRyaWdnZXInKSBtZW51VHJpZ2dlcjogTWF0TWVudVRyaWdnZXI7XG5cbiAgcHJpdmF0ZSBfYWN0aW9uczogSVByaW1pdGl2ZUFjdGlvbnMgfCBJQXR0cmlidXRlQWN0aW9ucztcblxuICBwdWJsaWMgZWxsaXBzaXNNZW51QnRuczogSnNUYWJsZTxJRWxsaXBzaXNCdG4+ID0gZW1wdHlKc1RhYmxlPElFbGxpcHNpc0J0bj4oKTtcblxuICBjb25zdHJ1Y3Rvcihwcml2YXRlIF9kaWFsb2c6IE1hdERpYWxvZykge31cblxuICBvbkNsaWNrKGRpYWxvZ0FjdGlvbjogc3RyaW5nKTogdm9pZCB7XG4gICAgbGV0IGNvbmZpcm1EaWFsb2dEYXRhOiB7IFtpZDogc3RyaW5nXTogYW55IH0gPSB7fTtcbiAgICBzd2l0Y2ggKGRpYWxvZ0FjdGlvbikge1xuICAgICAgY2FzZSBFRWxsaXBzaXNNZW51QWN0aW9ucy5FWFBPUlQ6XG4gICAgICAgIHRoaXMuZXhwb3J0QWxsRWxlbWVudHMoKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIEVFbGxpcHNpc01lbnVBY3Rpb25zLkFERDpcbiAgICAgIGNhc2UgRUVsbGlwc2lzTWVudUFjdGlvbnMuQUREX0NISUxEUkVOOlxuICAgICAgICB0aGlzLmNsaWNrT25BZGRSZXNvdXJjZUJ0bi5lbWl0KCk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSBFRWxsaXBzaXNNZW51QWN0aW9ucy5TSU5HTEVfRURJVDpcbiAgICAgIGNhc2UgRUVsbGlwc2lzTWVudUFjdGlvbnMuTVVMVElQTEVfRURJVDpcbiAgICAgICAgY29uZmlybURpYWxvZ0RhdGEgPSB7XG4gICAgICAgICAgLi4uY29uZmlybURpYWxvZ0RhdGEsXG4gICAgICAgICAgbWFwU2VsZWN0ZWRFbGVtZW50SWRFZGl0YWJsZVZhbHVlOiBnZXRNYXBJZFZhbHVlKFxuICAgICAgICAgICAgdGhpcy5zZWxlY3RlZEVsZW1lbnRzVWlJZHMsXG4gICAgICAgICAgICB0aGlzLmRhdGFWaWV3UHJvcGVydGllcz8uZ2V0RGF0YVNvdXJjZSgpLmRhdGEgPz8gW3RoaXMuc2VsZWN0ZWRSb3ddLFxuICAgICAgICAgICAgdGhpcy51cGRhdGVBY3Rpb25zUGFyYW1zPy5lZGl0Py5jb2x1bW5JZFxuICAgICAgICAgICksXG4gICAgICAgIH07XG4gICAgICAvLyBmYWxscyB0aHJvdWdoXG4gICAgICBkZWZhdWx0OlxuICAgICAgICBjb25maXJtRGlhbG9nRGF0YSA9IHtcbiAgICAgICAgICAuLi5jb25maXJtRGlhbG9nRGF0YSxcbiAgICAgICAgICBzZWxlY3RlZEVsZW1lbnRzVWlJZHM6IHRoaXMuc2VsZWN0ZWRFbGVtZW50c1VpSWRzLm1hcChcbiAgICAgICAgICAgIChlbGVtZW50OiB7IGlkOiBzdHJpbmc7IGxhYmVsOiBzdHJpbmcgfSkgPT5cbiAgICAgICAgICAgICAgT2JqZWN0LmFzc2lnbih7fSwgZWxlbWVudClcbiAgICAgICAgICApLFxuICAgICAgICAgIHRpdGxlOiB0aGlzLmVsbGlwc2lzTWVudUJ0bnMuYnlJZFtkaWFsb2dBY3Rpb25dPy50aXRsZSA/PyBudWxsLFxuICAgICAgICAgIGNhbmNlbEJ1dHRvblRleHQ6XG4gICAgICAgICAgICB0aGlzLmVsbGlwc2lzTWVudUJ0bnMuYnlJZFtkaWFsb2dBY3Rpb25dPy5kaWFsb2dDYW5jZWxCdG4gPz8gbnVsbCxcbiAgICAgICAgICBjb25maXJtQnV0dG9uVGV4dDpcbiAgICAgICAgICAgIHRoaXMuZWxsaXBzaXNNZW51QnRucy5ieUlkW2RpYWxvZ0FjdGlvbl0/LmRpYWxvZ0NvbmZpcm1CdG4gPz8gbnVsbCxcbiAgICAgICAgICBtb3ZlVG9Sb290QnV0dG9uVGV4dDpcbiAgICAgICAgICAgIHRoaXMuZWxsaXBzaXNNZW51QnRucy5ieUlkW2RpYWxvZ0FjdGlvbl0/LmRpYWxvZ01vdmVUb1Jvb3RCdG4gPz9cbiAgICAgICAgICAgIG51bGwsXG4gICAgICAgICAgbW92ZVRvQW5vdGhlckVudHJ5QnV0dG9uVGV4dDpcbiAgICAgICAgICAgIHRoaXMuZWxsaXBzaXNNZW51QnRucy5ieUlkW2RpYWxvZ0FjdGlvbl1cbiAgICAgICAgICAgICAgPy5kaWFsb2dNb3ZlVG9Bbm90aGVyRW50cnlCdG4gPz8gbnVsbCxcbiAgICAgICAgICBkaWFsb2dBY3Rpb24sXG4gICAgICAgICAgdXBkYXRlQWN0aW9uc1BhcmFtczogdGhpcy51cGRhdGVBY3Rpb25zUGFyYW1zID8/IG51bGwsXG4gICAgICAgICAgYXR0cmlidXRlTW9kZWxSZWY6IHRoaXMuYXR0cmlidXRlSWQgPz8gbnVsbCxcbiAgICAgICAgICB0cmlnZ2VyRWxlbWVudElkOiB0aGlzLm5vZGU/Lmlkcz8uaWQgPz8gbnVsbCxcbiAgICAgICAgICBub1NlYXJjaFJlc3VsdDpcbiAgICAgICAgICAgIHRoaXMuZWxsaXBzaXNNZW51QnRucy5ieUlkW2RpYWxvZ0FjdGlvbl0/Lm5vU2VhcmNoUmVzdWx0ID8/IG51bGwsXG4gICAgICAgICAgcHJldmlvdXNTdGVwQnV0dG9uVGV4dDpcbiAgICAgICAgICAgIHRoaXMuZWxsaXBzaXNNZW51QnRucy5ieUlkW2RpYWxvZ0FjdGlvbl0/LmRpYWxvZ1ByZXZpb3VzU3RlcEJ0biA/P1xuICAgICAgICAgICAgbnVsbCxcbiAgICAgICAgfTtcbiAgICAgICAgY29uc3QgZGlhbG9nUmVmID0gdGhpcy5fZGlhbG9nLm9wZW4oQ29uZmlybURpYWxvZ0NvbXBvbmVudCwge1xuICAgICAgICAgIHJlc3RvcmVGb2N1czogZmFsc2UsXG4gICAgICAgICAgcGFuZWxDbGFzczogJ2NvbmZpcm0tZGlhbG9nLWNvbnRhaW5lcicsXG4gICAgICAgICAgZGF0YTogY29uZmlybURpYWxvZ0RhdGEsXG4gICAgICAgIH0pO1xuXG4gICAgICAgIGRpYWxvZ1JlZi5jb21wb25lbnRJbnN0YW5jZS5hY3Rpb24kXG4gICAgICAgICAgLnBpcGUoXG4gICAgICAgICAgICB0YWtlVW50aWwoZGlhbG9nUmVmLmNvbXBvbmVudEluc3RhbmNlLm9uRGVzdHJveSQpLFxuICAgICAgICAgICAgdGFwKChfKSA9PiB7XG4gICAgICAgICAgICAgIHRoaXMubWVudVRyaWdnZXIuZm9jdXMoKTtcbiAgICAgICAgICAgICAgc3dpdGNoIChkaWFsb2dBY3Rpb24pIHtcbiAgICAgICAgICAgICAgICBjYXNlIEVFbGxpcHNpc01lbnVBY3Rpb25zLk1PVkVfTk9ERTpcbiAgICAgICAgICAgICAgICAgIHRoaXMuZXZ0TW92ZURhdGFOb2RlLmVtaXQoe1xuICAgICAgICAgICAgICAgICAgICBkZXN0aW5hdGlvbk5vZGU6IGRpYWxvZ1JlZi5jb21wb25lbnRJbnN0YW5jZS5zZWxlY3RlZE5vZGUsXG4gICAgICAgICAgICAgICAgICAgIGRpYWxvZ1JlZixcbiAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgY2FzZSBFRWxsaXBzaXNNZW51QWN0aW9ucy5TSU5HTEVfUkVBU1NJR046XG4gICAgICAgICAgICAgICAgY2FzZSBFRWxsaXBzaXNNZW51QWN0aW9ucy5NVUxUSVBMRV9SRUFTU0lHTjpcbiAgICAgICAgICAgICAgICAgIHRoaXMuZXZ0TW92ZVNlbGVjdGVkRWxlbWVudHMuZW1pdCh7XG4gICAgICAgICAgICAgICAgICAgIHNlbGVjdGVkTm9kZTogZGlhbG9nUmVmLmNvbXBvbmVudEluc3RhbmNlLnNlbGVjdGVkTm9kZSxcbiAgICAgICAgICAgICAgICAgICAgc2VsZWN0ZWRJdGVtOiBkaWFsb2dSZWYuY29tcG9uZW50SW5zdGFuY2Uuc2VsZWN0ZWRJdGVtLFxuICAgICAgICAgICAgICAgICAgICBzZWxlY3RlZEVsZW1lbnRzVWlJZHM6IHRoaXMuc2VsZWN0ZWRFbGVtZW50c1VpSWRzLFxuICAgICAgICAgICAgICAgICAgICBkaWFsb2dSZWYsXG4gICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIGNhc2UgRUVsbGlwc2lzTWVudUFjdGlvbnMuU0lOR0xFX0VESVQ6XG4gICAgICAgICAgICAgICAgICB0aGlzLmV2dEVkaXRTZWxlY3RlZEVsZW1lbnQuZW1pdCh7XG4gICAgICAgICAgICAgICAgICAgIHJvdzogZ2V0RWRpdGVkRGF0YVNvdXJjZVJvdyhcbiAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNlbGVjdGVkUm93LFxuICAgICAgICAgICAgICAgICAgICAgIHRoaXMudXBkYXRlQWN0aW9uc1BhcmFtcy5lZGl0LmNvbHVtbklkLFxuICAgICAgICAgICAgICAgICAgICAgIGRpYWxvZ1JlZi5jb21wb25lbnRJbnN0YW5jZS5lZGl0Rm9ybS5nZXRSYXdWYWx1ZSgpXG4gICAgICAgICAgICAgICAgICAgICksXG4gICAgICAgICAgICAgICAgICAgIGRpYWxvZ1JlZixcbiAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgY2FzZSBFRWxsaXBzaXNNZW51QWN0aW9ucy5NVUxUSVBMRV9FRElUOlxuICAgICAgICAgICAgICAgICAgdGhpcy5ldnRFZGl0U2VsZWN0ZWRFbGVtZW50cy5lbWl0KHtcbiAgICAgICAgICAgICAgICAgICAgcm93czogZ2V0RWRpdGVkRGF0YVNvdXJjZVJvd3MoXG4gICAgICAgICAgICAgICAgICAgICAgdGhpcy5zZWxlY3RlZEVsZW1lbnRzVWlJZHMsXG4gICAgICAgICAgICAgICAgICAgICAgdGhpcy5kYXRhVmlld1Byb3BlcnRpZXM/LmdldERhdGFTb3VyY2UoKS5kYXRhIHx8IFtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc2VsZWN0ZWRSb3csXG4gICAgICAgICAgICAgICAgICAgICAgXSxcbiAgICAgICAgICAgICAgICAgICAgICB0aGlzLnVwZGF0ZUFjdGlvbnNQYXJhbXMuZWRpdC5jb2x1bW5JZCxcbiAgICAgICAgICAgICAgICAgICAgICBkaWFsb2dSZWYuY29tcG9uZW50SW5zdGFuY2UuZWRpdEZvcm0uZ2V0UmF3VmFsdWUoKVxuICAgICAgICAgICAgICAgICAgICApLFxuICAgICAgICAgICAgICAgICAgICBkaWFsb2dSZWYsXG4gICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgICBpZiAodGhpcy5zZWxlY3RlZEVsZW1lbnRzVWlJZHM/Lmxlbmd0aCA9PT0gMSkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmV2dERlbGV0ZVNlbGVjdGVkRWxlbWVudC5lbWl0KHtcbiAgICAgICAgICAgICAgICAgICAgICBlbnRyeTogdGhpcy5zZWxlY3RlZEVsZW1lbnRzVWlJZHNbMF0sXG4gICAgICAgICAgICAgICAgICAgICAgZGlhbG9nUmVmLFxuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZXZ0RGVsZXRlU2VsZWN0ZWRFbGVtZW50cy5lbWl0KHtcbiAgICAgICAgICAgICAgICAgICAgICBlbnRyaWVzOiB0aGlzLnNlbGVjdGVkRWxlbWVudHNVaUlkcyxcbiAgICAgICAgICAgICAgICAgICAgICBkaWFsb2dSZWYsXG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgKVxuICAgICAgICAgIC5zdWJzY3JpYmUoKTtcbiAgICAgICAgYnJlYWs7XG4gICAgfVxuICB9XG5cbiAgZXhwb3J0QWxsRWxlbWVudHMoKTogdm9pZCB7XG4gICAgY29uc3Qgb3B0aW9ucyA9IHtcbiAgICAgIGZpZWxkU2VwYXJhdG9yOiAnOycsXG4gICAgICBxdW90ZVN0cmluZ3M6ICdcIicsXG4gICAgICBkZWNpbWFsU2VwYXJhdG9yOiAnLicsXG4gICAgICBzaG93TGFiZWxzOiB0cnVlLFxuICAgICAgc2hvd1RpdGxlOiBmYWxzZSxcbiAgICAgIHRpdGxlOiAhIXRoaXMuZWxsaXBzaXNNZW51QnRucy5ieUlkLmV4cG9ydFxuICAgICAgICA/IHRoaXMuZWxsaXBzaXNNZW51QnRucy5ieUlkLmV4cG9ydC50aXRsZVxuICAgICAgICA6ICcnLFxuICAgICAgZmlsZW5hbWU6ICEhdGhpcy5lbGxpcHNpc01lbnVCdG5zLmJ5SWQuZXhwb3J0XG4gICAgICAgID8gdGhpcy5lbGxpcHNpc01lbnVCdG5zLmJ5SWQuZXhwb3J0LnRpdGxlXG4gICAgICAgIDogJycsXG4gICAgICB1c2VUZXh0RmlsZTogZmFsc2UsXG4gICAgICB1c2VCb206IHRydWUsXG4gICAgICB1c2VLZXlzQXNIZWFkZXJzOiB0cnVlLFxuICAgIH07XG4gICAgY29uc3QgZXhwb3J0UHJvcGVydGllczoge1xuICAgICAgb3B0aW9uczogYW55O1xuICAgICAgZGF0YTogeyBbbGFiZWw6IHN0cmluZ106IGFueSB9W107XG4gICAgfSA9IHtcbiAgICAgIG9wdGlvbnMsXG4gICAgICBkYXRhOiBnZXRBbGxFbGVtZW50c1RvRXhwb3J0KFxuICAgICAgICB0aGlzLmRhdGFWaWV3UHJvcGVydGllcy5nZXREYXRhU291cmNlKCkuZmlsdGVyZWREYXRhLFxuICAgICAgICB0aGlzLmRhdGFWaWV3UHJvcGVydGllcy5nZXRDb2x1bW5zKClcbiAgICAgICksXG4gICAgfTtcbiAgICBjb25zdCBjc3ZDb25maWcgPSBta0NvbmZpZyhleHBvcnRQcm9wZXJ0aWVzLm9wdGlvbnMpO1xuICAgIGNvbnN0IGNzdiA9IGdlbmVyYXRlQ3N2KGNzdkNvbmZpZykoZXhwb3J0UHJvcGVydGllcy5kYXRhKTtcbiAgICBkb3dubG9hZChjc3ZDb25maWcpKGNzdik7XG4gIH1cbn1cbiIsIjwhLS0gQ29weXJpZ2h0IChDKSAyMDIwLTIwMjQgTGluYWdvcmFcblxuVGhpcyBwcm9ncmFtIGlzIGZyZWUgc29mdHdhcmU6IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQgdW5kZXJcbnRoZSB0ZXJtcyBvZiB0aGUgR05VIEFmZmVybyBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZVxuU29mdHdhcmUgRm91bmRhdGlvbiwgZWl0aGVyIHZlcnNpb24gMyBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnlcbmxhdGVyIHZlcnNpb24sIHByb3ZpZGVkIHlvdSBjb21wbHkgd2l0aCB0aGUgQWRkaXRpb25hbCBUZXJtcyBhcHBsaWNhYmxlIGZvclxuTGluSUQgRGlyZWN0b3J5IE1hbmFnZXIgc29mdHdhcmUgYnkgTElOQUdPUkEgcHVyc3VhbnQgdG8gU2VjdGlvbiA3IG9mIHRoZSBHTlVcbkFmZmVybyBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlLCBzdWJzZWN0aW9ucyAoYiksIChjKSwgYW5kIChlKSwgcHVyc3VhbnQgdG9cbndoaWNoIHRoZXNlIEFwcHJvcHJpYXRlIExlZ2FsIE5vdGljZXMgbXVzdCBub3RhYmx5IChpKSByZXRhaW4gdGhlIGRpc3BsYXkgb2ZcbnRoZSBcIkxpbklE4oSiXCIgdHJhZGVtYXJrL2xvZ28gYXQgdGhlIHRvcCBvZiB0aGUgaW50ZXJmYWNlIHdpbmRvdywgdGhlIGRpc3BsYXlcbm9mIHRoZSDigJxZb3UgYXJlIHVzaW5nIHRoZSBPcGVuIFNvdXJjZSBhbmQgZnJlZSB2ZXJzaW9uIG9mIExpbklE4oSiLCBwb3dlcmVkIGJ5XG5MaW5hZ29yYSDCqSAyMDA54oCTMjAxMy4gQ29udHJpYnV0ZSB0byBMaW5JRCBSJkQgYnkgc3Vic2NyaWJpbmcgdG8gYW4gRW50ZXJwcmlzZVxub2ZmZXIh4oCdIGluZm9ib3ggYW5kIGluIHRoZSBlLW1haWxzIHNlbnQgd2l0aCB0aGUgUHJvZ3JhbSwgbm90aWNlIGFwcGVuZGVkIHRvXG5hbnkgdHlwZSBvZiBvdXRib3VuZCBtZXNzYWdlcyAoZS5nLiBlLW1haWwgYW5kIG1lZXRpbmcgcmVxdWVzdHMpIGFzIHdlbGwgYXNcbmluIHRoZSBMaW5JRCBEaXJlY3RvcnkgTWFuYWdlciB1c2VyIGludGVyZmFjZSwgKGlpKSByZXRhaW4gYWxsIGh5cGVydGV4dFxubGlua3MgYmV0d2VlbiBMaW5JRCBEaXJlY3RvcnkgTWFuYWdlciBhbmQgaHR0cHM6Ly9saW5pZC5vcmcvLCBhcyB3ZWxsIGFzXG5iZXR3ZWVuIExJTkFHT1JBIGFuZCBMSU5BR09SQS5jb20sIGFuZCAoaWlpKSByZWZyYWluIGZyb20gaW5mcmluZ2luZyBMSU5BR09SQVxuaW50ZWxsZWN0dWFsIHByb3BlcnR5IHJpZ2h0cyBvdmVyIGl0cyB0cmFkZW1hcmtzIGFuZCBjb21tZXJjaWFsIGJyYW5kcy4gT3RoZXJcbkFkZGl0aW9uYWwgVGVybXMgYXBwbHksIHNlZSA8aHR0cDovL3d3dy5saW5hZ29yYS5jb20vbGljZW5zZXMvPiBmb3IgbW9yZVxuZGV0YWlscy5cblxuVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUXG5BTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTU1xuRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiBTZWUgdGhlIEdOVSBBZmZlcm8gR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZVxuZGV0YWlscy5cblxuWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEFmZmVybyBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFuZFxuaXRzIGFwcGxpY2FibGUgQWRkaXRpb25hbCBUZXJtcyBmb3IgTGluSUQgRGlyZWN0b3J5IE1hbmFnZXIgYWxvbmcgd2l0aCB0aGlzXG5wcm9ncmFtLiBJZiBub3QsIHNlZSA8aHR0cDovL3d3dy5nbnUub3JnL2xpY2Vuc2VzLz4gZm9yIHRoZSBHTlUgQWZmZXJvXG5HZW5lcmFsIFB1YmxpYyBMaWNlbnNlIHZlcnNpb24gMyBhbmQgPGh0dHA6Ly93d3cubGluYWdvcmEuY29tL2xpY2Vuc2VzLz4gZm9yXG50aGUgQWRkaXRpb25hbCBUZXJtcyBhcHBsaWNhYmxlIHRvIHRoZSBMaW5JRCBEaXJlY3RvcnkgTWFuYWdlciBzb2Z0d2FyZS4gLS0+XG5cbjxkaXYgZnhMYXlvdXQ9XCJyb3dcIiBmeExheW91dEFsaWduPVwiZW5kIGNlbnRlclwiPlxuICA8YnV0dG9uXG4gICAgI21lbnVUcmlnZ2VyPVwibWF0TWVudVRyaWdnZXJcIlxuICAgIG1hdC1pY29uLWJ1dHRvblxuICAgIGFyaWEtbGFiZWw9XCJNZW51XCJcbiAgICBbY2xhc3Mub3BlbmVkXT1cIm1lbnVUcmlnZ2VyLm1lbnVPcGVuXCJcbiAgICBbbWF0TWVudVRyaWdnZXJGb3JdPVwibWVudVwiXG4gICAgY2xhc3M9XCJlbGxpcHNpcy1tZW51LWJ0blwiXG4gID5cbiAgICA8bWF0LWljb25cbiAgICAgIGFyaWEtaGlkZGVuPVwidHJ1ZVwiXG4gICAgICBbbmdDbGFzc109XCJ7XG4gICAgICAgICd0b2dnbGUtZWxsaXBzaXMtbWVudS1pY29uJzogbWVudVRyaWdnZXIubWVudU9wZW5cbiAgICAgIH1cIlxuICAgICAgPm1vcmVfdmVydDwvbWF0LWljb25cbiAgICA+XG4gIDwvYnV0dG9uPlxuICA8bWF0LW1lbnUgI21lbnU9XCJtYXRNZW51XCIgYmFja2Ryb3BDbGFzcz1cImVsbGlwc2lzLW1lbnVcIj5cbiAgICA8dWw+XG4gICAgICA8bGkgKm5nRm9yPVwibGV0IGxhYmVsSWQgb2YgZWxsaXBzaXNNZW51QnRucy5hbGxJZHNcIj5cbiAgICAgICAgPGJ1dHRvblxuICAgICAgICAgIG1hdC1tZW51LWl0ZW1cbiAgICAgICAgICBbYXR0ci5hcmlhLWxhYmVsXT1cImVsbGlwc2lzTWVudUJ0bnMuYnlJZFtsYWJlbElkXS5idG5MYWJlbFwiXG4gICAgICAgICAgW2Rpc2FibGVkXT1cIlxuICAgICAgICAgICAgZWxsaXBzaXNNZW51QnRucy5ieUlkW2xhYmVsSWRdLmNhbkJlRGlzYWJsZWQgJiZcbiAgICAgICAgICAgIChpc1Byb2Nlc3NpbmdSZXF1ZXN0IHx8IHNlbGVjdGVkRWxlbWVudHNVaUlkcy5sZW5ndGggPCAxKVxuICAgICAgICAgIFwiXG4gICAgICAgICAgKGNsaWNrKT1cIm9uQ2xpY2sobGFiZWxJZClcIlxuICAgICAgICA+XG4gICAgICAgICAgPG1hdC1pY29uXG4gICAgICAgICAgICBhcmlhLWhpZGRlbj1cInRydWVcIlxuICAgICAgICAgICAgW2NsYXNzLm1hdC1tZW51LWljb24tZGlzYWJsZV09XCJcbiAgICAgICAgICAgICAgZWxsaXBzaXNNZW51QnRucy5ieUlkW2xhYmVsSWRdLmNhbkJlRGlzYWJsZWQgJiZcbiAgICAgICAgICAgICAgc2VsZWN0ZWRFbGVtZW50c1VpSWRzLmxlbmd0aCA8IDFcbiAgICAgICAgICAgIFwiXG4gICAgICAgICAgPlxuICAgICAgICAgICAge3sgZWxsaXBzaXNNZW51QnRucy5ieUlkW2xhYmVsSWRdLmljb24gfX1cbiAgICAgICAgICA8L21hdC1pY29uPlxuICAgICAgICAgIDxzcGFuPnt7IGVsbGlwc2lzTWVudUJ0bnMuYnlJZFtsYWJlbElkXS5idG5MYWJlbCB9fTwvc3Bhbj5cbiAgICAgICAgPC9idXR0b24+XG4gICAgICA8L2xpPlxuICAgIDwvdWw+XG4gIDwvbWF0LW1lbnU+XG48L2Rpdj5cbiJdfQ==