@linid-dm/directory-manager-client-core
Version:
Core package by providing a set of angular components for the Directory Manager app.
332 lines • 79.6 kB
JavaScript
import { __decorate } from "tslib";
import { DOCUMENT } from '@angular/common';
import { ChangeDetectionStrategy, Component, EventEmitter, Inject, Input, Output, ViewChild, } from '@angular/core';
import { Validators } from '@angular/forms';
import { Select, ofActionSuccessful } from '@ngxs/store';
import { Subject, debounceTime, distinctUntilChanged, filter, fromEvent, merge, pairwise, startWith, take, takeUntil, tap, } from 'rxjs';
import { Data, UiState, finalizeWithValue, getAdvancedSearchChipsFromFormData, setFormFieldDataValue, } from '../../shared';
import * as i0 from "@angular/core";
import * as i1 from "@angular/forms";
import * as i2 from "@ngxs/store";
import * as i3 from "../../shared";
import * as i4 from "@angular/cdk/overlay";
import * as i5 from "@angular/common";
import * as i6 from "@angular/flex-layout/flex";
import * as i7 from "@angular/flex-layout/extended";
import * as i8 from "@angular/material/button";
import * as i9 from "@angular/material/chips";
import * as i10 from "@angular/material/form-field";
import * as i11 from "@angular/material/icon";
import * as i12 from "@angular/material/input";
import * as i13 from "@angular/material/menu";
import * as i14 from "@angular/material/tooltip";
import * as i15 from "../../shared/directives/disable-control.directive";
import * as i16 from "../generic-form/generic-form.component";
var ESearchMode;
(function (ESearchMode) {
ESearchMode["ADVANCED"] = "advanced";
ESearchMode["SIMPLE"] = "simple";
})(ESearchMode || (ESearchMode = {}));
var EOverlayClickMode;
(function (EOverlayClickMode) {
EOverlayClickMode["ENABLE"] = "enable";
EOverlayClickMode["DISABLE"] = "disable";
})(EOverlayClickMode || (EOverlayClickMode = {}));
export class AdvancedSearchComponent {
set searchFormValue(value) {
if (value === '' && this._searchFormValue !== '') {
this.searchForm.reset();
}
this._searchFormValue = value ?? '';
if (this.resetBtnClicked) {
this.resetBtnClicked = false;
}
}
get searchFormValue() {
return this._searchFormValue;
}
set selectedResourceRootTypeId(val) {
this._selectedResourceRootTypeId = val;
if (!!this.searchForm) {
this.searchForm.setValue({ search: this.searchFormValue });
}
}
get selectedResourceRootTypeId() {
return this._selectedResourceRootTypeId;
}
set advancedSearchChips(chips) {
this._advancedSearchChips = chips ?? [];
if (!this._isSearchSuccess) {
this.setFormFieldsWithChips();
}
else {
this._isSearchSuccess = false;
}
if (this.resetBtnClicked) {
this.resetBtnClicked = false;
}
this.removingChips = this.removingChips.filter((id) => chips.map((chip) => chip.modelRef).includes(id));
}
get advancedSearchChips() {
return this._advancedSearchChips;
}
set resourceTypeConfig(config) {
this._resourceTypeConfig = config;
this.formFields = [];
this._resourceTypeConfig.attributes.forEach((attribute) => {
if (attribute.props.isSearchable) {
this.formFields.push({
...attribute,
dataValue: null,
});
}
});
}
get resourceTypeConfig() {
return this._resourceTypeConfig;
}
constructor(_el, _fb, _actions$, _store$, _renderer, document, _interactionsService, _overlayContainer, _envService) {
this._el = _el;
this._fb = _fb;
this._actions$ = _actions$;
this._store$ = _store$;
this._renderer = _renderer;
this.document = document;
this._interactionsService = _interactionsService;
this._overlayContainer = _overlayContainer;
this._envService = _envService;
this._advancedSearchChips = [];
this.evtUpdateDataArray = new EventEmitter();
this.resetBtnClicked = false;
this.removingChips = [];
this.formFields = [];
this.isGenericFormEnable = true;
this._onDestroy$ = new Subject();
this._searchFormValue = '';
this._isSearchSuccess = false;
this.elementRef = this._el;
}
ngOnInit() {
this.searchForm = this._fb.group({
search: [this.searchFormValue ?? '', Validators.minLength(3)],
});
this.searchForm
.get('search')
.valueChanges.pipe(takeUntil(this._onDestroy$), debounceTime(600), startWith(this.searchForm.get('search').value), tap((value) => {
if (this.searchFormValue !== '' &&
value === this.searchFormValue &&
!this.resetBtnClicked) {
this._interactionsService.cancelRequest();
this._store$.dispatch(new Data.StopFilteringResources());
}
}), distinctUntilChanged((prev, curr) => prev === curr ||
(this.searchFormValue !== '' && this.searchFormValue === curr)), pairwise(), filter(([prev, curr]) => {
const isClearingSearchWithKeyboard = prev !== null &&
curr !== null &&
prev.length > curr.length &&
curr.length <= 2;
if (isClearingSearchWithKeyboard) {
this.resetSearch();
}
return curr !== null && curr.length > 2;
}), tap(([_prev, curr]) => {
this._store$.dispatch(new Data.FilterResources({
actionOnSuccess: new Data.SetSearchFormValue({
searchForm: curr,
dataTypeId: this.selectedResourceRootTypeId,
}),
filterPayload: curr,
}));
}))
.subscribe();
let advancedSearchMenuWasOpened = false;
this.resizeObservable$ = fromEvent(window, 'resize');
this.resizeObservable$
.pipe(takeUntil(this._onDestroy$), tap((_) => {
if (!advancedSearchMenuWasOpened && this.menuTrigger) {
advancedSearchMenuWasOpened = this.menuTrigger.menuOpen;
}
}), tap((_) => {
if (this.menuTrigger) {
this.menuTrigger.closeMenu();
}
}), debounceTime(300), tap((_) => {
if (advancedSearchMenuWasOpened && this.menuTrigger) {
this.menuTrigger.openMenu();
advancedSearchMenuWasOpened = false;
}
}))
.subscribe();
}
ngOnDestroy() {
this._onDestroy$.next();
this._onDestroy$.complete();
}
onResetSearchBtnClick() {
this.resetBtnClicked = true;
this.searchForm.disable({ emitEvent: false });
this.resetSearch();
}
resetSearch() {
if (this.searchFormValue !== '' || this.advancedSearchChips?.length > 0) {
const searchMode = this.searchFormValue !== '' ? ESearchMode.SIMPLE : ESearchMode.ADVANCED;
const payload = searchMode === ESearchMode.SIMPLE
? {
actionOnSuccess: new Data.ResetSearchFormValue({
dataTypeId: this.selectedResourceRootTypeId,
}),
filterPayload: '',
}
: {
actionOnSuccess: new Data.ResetAdvancedSearchChips({
dataTypeId: this.selectedResourceRootTypeId,
}),
filterPayload: [],
};
this._store$.dispatch(new Data.FilterResources(payload));
}
else {
this._interactionsService.cancelRequest();
this._store$.dispatch(new Data.StopFilteringResources());
this.searchForm.reset();
this.searchForm.enable({ emitEvent: false });
if (this.resetBtnClicked) {
this.resetBtnClicked = false;
}
}
}
onSubmit() {
this._actions$
.pipe(ofActionSuccessful(Data.FetchResourcesSuccess, Data.FetchResourcesError), take(1), takeUntil(merge(this._onDestroy$, this._interactionsService.cancelRequest$)), finalizeWithValue((action) => {
this.menuTrigger.closeMenu();
this._switchClickOnOverlay(EOverlayClickMode.ENABLE);
this.isGenericFormEnable = true;
if (action instanceof Data.FetchResourcesError || !action) {
this.setFormFieldsWithChips();
}
else if (action instanceof Data.FetchResourcesSuccess) {
this._isSearchSuccess = true;
}
}))
.subscribe();
const updatedChips = getAdvancedSearchChipsFromFormData(this.formFields);
this.isGenericFormEnable = false;
this._switchClickOnOverlay(EOverlayClickMode.DISABLE);
this._store$.dispatch(new Data.FilterResources({
actionOnSuccess: new Data.SetAdvancedSearchChips({
advancedSearchChips: updatedChips,
dataTypeId: this.selectedResourceRootTypeId,
}),
filterPayload: updatedChips,
}));
}
removeChip(chip) {
const index = this.advancedSearchChips.indexOf(chip);
if (index >= 0) {
const chipModelRef = chip.associatedFieldId ?? chip.modelRef;
this.removingChips.push(chipModelRef);
const remainingFormFields = this.formFields.filter((formData) => formData.modelRef !== chipModelRef && !!formData.dataValue);
if (remainingFormFields.length > 0) {
this._store$.dispatch(new Data.FilterResources({
actionOnSuccess: new Data.RemoveAdvancedSearchChip({
modelRef: chipModelRef,
dataTypeId: this.selectedResourceRootTypeId,
}),
filterPayload: getAdvancedSearchChipsFromFormData(remainingFormFields),
}));
}
else {
this.resetSearch();
}
}
}
setMenuPanelPosition() {
setTimeout(() => {
if (this.searchFormField &&
this.menuTriggerBtn &&
this.menu &&
this.menu.panelId) {
const panelLeftOffset = this.searchFormField._elementRef.nativeElement.getBoundingClientRect()
.left;
const panelTopOffset = this.menuTriggerBtn._elementRef.nativeElement.getBoundingClientRect()
.bottom;
const menuPanel = this.document.getElementById(this.menu.panelId).parentElement;
this._renderer.setStyle(menuPanel, 'top', '0px');
this._renderer.setStyle(menuPanel, 'left', '0px');
this._renderer.setStyle(menuPanel, 'margin-top', panelTopOffset + 'px');
this._renderer.setStyle(menuPanel, 'margin-left', panelLeftOffset + 'px');
}
}, 1);
}
setFormFieldsWithChips() {
const chipIdIndexMap = new Map(this.advancedSearchChips.map((chip, index) => [
chip.associatedFieldId ?? chip.modelRef,
index,
]));
this.formFields.forEach((formData) => {
if (chipIdIndexMap.has(formData.modelRef)) {
setFormFieldDataValue(formData, this.advancedSearchChips[chipIdIndexMap.get(formData.modelRef)].value, this._envService.ui.displayDateFormat);
}
else {
formData.dataValue = null;
}
});
}
_switchClickOnOverlay(mode) {
const overlayContainer = this._overlayContainer.getContainerElement();
switch (mode) {
case EOverlayClickMode.ENABLE:
overlayContainer.classList.remove('disable-overlay');
overlayContainer.style.pointerEvents = 'none';
overlayContainer.onclick = null;
break;
case EOverlayClickMode.DISABLE:
overlayContainer.classList.add('disable-overlay');
overlayContainer.style.pointerEvents = 'auto';
overlayContainer.onclick = (event) => event.stopPropagation();
break;
default:
break;
}
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.4", ngImport: i0, type: AdvancedSearchComponent, deps: [{ token: i0.ElementRef }, { token: i1.FormBuilder }, { token: i2.Actions }, { token: i2.Store }, { token: i0.Renderer2 }, { token: DOCUMENT }, { token: i3.InteractionsService }, { token: i4.OverlayContainer }, { token: i3.EnvService }], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.4", type: AdvancedSearchComponent, selector: "dm-advanced-search", inputs: { searchFormValue: "searchFormValue", selectedResourceRootTypeId: "selectedResourceRootTypeId", advancedSearchChips: "advancedSearchChips", resourceTypeConfig: "resourceTypeConfig", isLargeScreen: "isLargeScreen" }, outputs: { evtUpdateDataArray: "evtUpdateDataArray" }, viewQueries: [{ propertyName: "menu", first: true, predicate: ["advancedSearchMenu"], descendants: true }, { propertyName: "matHint", first: true, predicate: ["matHint"], descendants: true }, { propertyName: "searchFormField", first: true, predicate: ["searchFormField"], descendants: true }, { propertyName: "menuTriggerBtn", first: true, predicate: ["menuTriggerBtn"], descendants: true }, { 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<form [formGroup]=\"searchForm\" class=\"search-form\">\n <div fxLayout=\"row\" fxLayoutAlign=\"start center\">\n <mat-form-field\n *ngIf=\"\n advancedSearchAccessibility$ | async as advancedSearchAccessibility\n \"\n fxFlex\n color=\"accent\"\n appearance=\"fill\"\n class=\"search-form-field\"\n #searchFormField\n >\n <mat-label>\n <mat-icon aria-hidden=\"true\">search</mat-icon>\n {{ advancedSearchAccessibility.label }}\n </mat-label>\n <mat-chip-grid #chipList>\n <mat-chip-row\n *ngFor=\"let chip of advancedSearchChips\"\n color=\"accent\"\n [matTooltip]=\"chip.displayedContent\"\n [matTooltipDisabled]=\"isLargeScreen\"\n [disabled]=\"resetBtnClicked || removingChips.includes(chip.modelRef)\"\n (removed)=\"removeChip(chip)\"\n >\n {{ chip.displayedContent }}\n <button\n matChipRemove\n (keydown.enter)=\"removeChip(chip)\"\n aria-hidden=\"true\"\n >\n <mat-icon tabindex=\"0\">cancel</mat-icon>\n </button>\n </mat-chip-row>\n <input\n disableControl\n type=\"text\"\n #searchInput\n matInput\n formControlName=\"search\"\n minlength=\"3\"\n [matChipInputFor]=\"chipList\"\n [disableControl]=\"\n advancedSearchChips.length > 0 ||\n (menuTrigger && menuTrigger.menuOpen) ||\n resetBtnClicked\n \"\n class=\"search-input\"\n />\n </mat-chip-grid>\n <mat-hint\n #matHint\n *ngIf=\"\n searchInput?.value?.length < 3 && advancedSearchChips.length === 0;\n else advancedSearchActivated\n \"\n >\n {{ advancedSearchAccessibility.hint }}\n </mat-hint>\n <ng-template #advancedSearchActivated>\n <mat-hint #matHint *ngIf=\"advancedSearchChips.length > 0\">\n {{ advancedSearchAccessibility.activatedSearchHint }}\n </mat-hint>\n </ng-template>\n <div matSuffix class=\"div-search-suffix-btn\">\n <button\n *ngIf=\"\n searchInput?.value?.length > 0 || advancedSearchChips?.length > 0\n \"\n [disabled]=\"resetBtnClicked\"\n mat-icon-button\n type=\"button\"\n [attr.aria-label]=\"advancedSearchAccessibility.clearSearch\"\n (click)=\"onResetSearchBtnClick()\"\n class=\"clear-input-btn\"\n [matTooltip]=\"advancedSearchAccessibility.clearSearch\"\n >\n <mat-icon aria-hidden=\"true\"> clear </mat-icon>\n </button>\n <button\n #menuTriggerBtn\n #menuTrigger=\"matMenuTrigger\"\n type=\"button\"\n mat-icon-button\n [attr.aria-label]=\"\n advancedSearchAccessibility.displayAdvancedSearchMenu\n \"\n [matMenuTriggerFor]=\"advancedSearchMenu\"\n [disabled]=\"\n searchInput?.value.length > 0 ||\n resetBtnClicked ||\n removingChips.length > 0\n \"\n (menuOpened)=\"setMenuPanelPosition()\"\n (click)=\"$event.stopPropagation()\"\n class=\"toggle-advanced-search-menu-btn\"\n [matTooltip]=\"advancedSearchAccessibility.displayAdvancedSearchMenu\"\n >\n <mat-icon\n [ngClass]=\"{\n 'toggle-advanced-search-menu-icon': menuTrigger.menuOpen\n }\"\n aria-hidden=\"true\"\n >\n arrow_drop_down\n </mat-icon>\n </button>\n <mat-menu\n #advancedSearchMenu=\"matMenu\"\n backdropClass=\"advanced-search-menu\"\n >\n <ng-template matMenuContent>\n <div\n class=\"advanced-search-menu-content\"\n (click)=\"$event.stopPropagation()\"\n >\n <dm-generic-form\n [enableCheckoutForm]=\"isGenericFormEnable\"\n [formData]=\"formFields\"\n [crudAction]=\"'search'\"\n (submitForm)=\"onSubmit()\"\n ></dm-generic-form>\n </div>\n </ng-template>\n </mat-menu>\n </div>\n </mat-form-field>\n </div>\n</form>\n", styles: ["@charset \"UTF-8\";.div-search-suffix-btn{display:flex;margin-left:8px}.mdc-icon-button:hover{background-color:#e0e0e0}.advanced-search-menu-content{padding:0 20px 20px;min-width:350px}.mat-chip.mat-standard-chip{overflow:hidden}.mat-mdc-chip-grid{padding-top:3px}.mat-mdc-form-field-hint{color:#0009}\n"], dependencies: [{ kind: "directive", type: i5.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i5.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.MinLengthValidator, selector: "[minlength][formControlName],[minlength][formControl],[minlength][ngModel]", inputs: ["minlength"] }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: i6.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: i6.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: i6.DefaultFlexDirective, selector: " [fxFlex], [fxFlex.xs], [fxFlex.sm], [fxFlex.md], [fxFlex.lg], [fxFlex.xl], [fxFlex.lt-sm], [fxFlex.lt-md], [fxFlex.lt-lg], [fxFlex.lt-xl], [fxFlex.gt-xs], [fxFlex.gt-sm], [fxFlex.gt-md], [fxFlex.gt-lg]", inputs: ["fxFlex", "fxFlex.xs", "fxFlex.sm", "fxFlex.md", "fxFlex.lg", "fxFlex.xl", "fxFlex.lt-sm", "fxFlex.lt-md", "fxFlex.lt-lg", "fxFlex.lt-xl", "fxFlex.gt-xs", "fxFlex.gt-sm", "fxFlex.gt-md", "fxFlex.gt-lg"] }, { kind: "directive", type: i7.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: i8.MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "component", type: i9.MatChipGrid, selector: "mat-chip-grid", inputs: ["disabled", "placeholder", "required", "value", "errorStateMatcher"], outputs: ["change", "valueChange"] }, { kind: "directive", type: i9.MatChipInput, selector: "input[matChipInputFor]", inputs: ["matChipInputFor", "matChipInputAddOnBlur", "matChipInputSeparatorKeyCodes", "placeholder", "id", "disabled"], outputs: ["matChipInputTokenEnd"], exportAs: ["matChipInput", "matChipInputFor"] }, { kind: "directive", type: i9.MatChipRemove, selector: "[matChipRemove]" }, { kind: "component", type: i9.MatChipRow, selector: "mat-chip-row, [mat-chip-row], mat-basic-chip-row, [mat-basic-chip-row]", inputs: ["editable"], outputs: ["edited"] }, { kind: "component", type: i10.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i10.MatLabel, selector: "mat-label" }, { kind: "directive", type: i10.MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "directive", type: i10.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "component", type: i11.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: i12.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "component", type: i13.MatMenu, selector: "mat-menu", inputs: ["backdropClass", "aria-label", "aria-labelledby", "aria-describedby", "xPosition", "yPosition", "overlapTrigger", "hasBackdrop", "class", "classList"], outputs: ["closed", "close"], exportAs: ["matMenu"] }, { kind: "directive", type: i13.MatMenuContent, selector: "ng-template[matMenuContent]" }, { kind: "directive", type: i13.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }, { kind: "directive", type: i14.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "directive", type: i15.DisableControlDirective, selector: "[disableControl]", inputs: ["disableControl"] }, { kind: "component", type: i16.GenericFormComponent, selector: "dm-generic-form", inputs: ["autocompleteOff", "isDisplayingDefaultFormBtns", "crudAction", "endpoint", "entryId", "formData", "scimProperties", "authorizeDisableOnRequest", "isInModal", "enableCheckoutForm"], outputs: ["clickOnCancelBtn", "clickOnSubmitBtn", "addSucceeded", "addFailed", "updateSucceeded", "updateFailed", "submitForm"] }, { kind: "pipe", type: i5.AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
}
__decorate([
Select(UiState.getAdvancedSearchAccessibility)
], AdvancedSearchComponent.prototype, "advancedSearchAccessibility$", void 0);
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.4", ngImport: i0, type: AdvancedSearchComponent, decorators: [{
type: Component,
args: [{ selector: 'dm-advanced-search', changeDetection: ChangeDetectionStrategy.OnPush, 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<form [formGroup]=\"searchForm\" class=\"search-form\">\n <div fxLayout=\"row\" fxLayoutAlign=\"start center\">\n <mat-form-field\n *ngIf=\"\n advancedSearchAccessibility$ | async as advancedSearchAccessibility\n \"\n fxFlex\n color=\"accent\"\n appearance=\"fill\"\n class=\"search-form-field\"\n #searchFormField\n >\n <mat-label>\n <mat-icon aria-hidden=\"true\">search</mat-icon>\n {{ advancedSearchAccessibility.label }}\n </mat-label>\n <mat-chip-grid #chipList>\n <mat-chip-row\n *ngFor=\"let chip of advancedSearchChips\"\n color=\"accent\"\n [matTooltip]=\"chip.displayedContent\"\n [matTooltipDisabled]=\"isLargeScreen\"\n [disabled]=\"resetBtnClicked || removingChips.includes(chip.modelRef)\"\n (removed)=\"removeChip(chip)\"\n >\n {{ chip.displayedContent }}\n <button\n matChipRemove\n (keydown.enter)=\"removeChip(chip)\"\n aria-hidden=\"true\"\n >\n <mat-icon tabindex=\"0\">cancel</mat-icon>\n </button>\n </mat-chip-row>\n <input\n disableControl\n type=\"text\"\n #searchInput\n matInput\n formControlName=\"search\"\n minlength=\"3\"\n [matChipInputFor]=\"chipList\"\n [disableControl]=\"\n advancedSearchChips.length > 0 ||\n (menuTrigger && menuTrigger.menuOpen) ||\n resetBtnClicked\n \"\n class=\"search-input\"\n />\n </mat-chip-grid>\n <mat-hint\n #matHint\n *ngIf=\"\n searchInput?.value?.length < 3 && advancedSearchChips.length === 0;\n else advancedSearchActivated\n \"\n >\n {{ advancedSearchAccessibility.hint }}\n </mat-hint>\n <ng-template #advancedSearchActivated>\n <mat-hint #matHint *ngIf=\"advancedSearchChips.length > 0\">\n {{ advancedSearchAccessibility.activatedSearchHint }}\n </mat-hint>\n </ng-template>\n <div matSuffix class=\"div-search-suffix-btn\">\n <button\n *ngIf=\"\n searchInput?.value?.length > 0 || advancedSearchChips?.length > 0\n \"\n [disabled]=\"resetBtnClicked\"\n mat-icon-button\n type=\"button\"\n [attr.aria-label]=\"advancedSearchAccessibility.clearSearch\"\n (click)=\"onResetSearchBtnClick()\"\n class=\"clear-input-btn\"\n [matTooltip]=\"advancedSearchAccessibility.clearSearch\"\n >\n <mat-icon aria-hidden=\"true\"> clear </mat-icon>\n </button>\n <button\n #menuTriggerBtn\n #menuTrigger=\"matMenuTrigger\"\n type=\"button\"\n mat-icon-button\n [attr.aria-label]=\"\n advancedSearchAccessibility.displayAdvancedSearchMenu\n \"\n [matMenuTriggerFor]=\"advancedSearchMenu\"\n [disabled]=\"\n searchInput?.value.length > 0 ||\n resetBtnClicked ||\n removingChips.length > 0\n \"\n (menuOpened)=\"setMenuPanelPosition()\"\n (click)=\"$event.stopPropagation()\"\n class=\"toggle-advanced-search-menu-btn\"\n [matTooltip]=\"advancedSearchAccessibility.displayAdvancedSearchMenu\"\n >\n <mat-icon\n [ngClass]=\"{\n 'toggle-advanced-search-menu-icon': menuTrigger.menuOpen\n }\"\n aria-hidden=\"true\"\n >\n arrow_drop_down\n </mat-icon>\n </button>\n <mat-menu\n #advancedSearchMenu=\"matMenu\"\n backdropClass=\"advanced-search-menu\"\n >\n <ng-template matMenuContent>\n <div\n class=\"advanced-search-menu-content\"\n (click)=\"$event.stopPropagation()\"\n >\n <dm-generic-form\n [enableCheckoutForm]=\"isGenericFormEnable\"\n [formData]=\"formFields\"\n [crudAction]=\"'search'\"\n (submitForm)=\"onSubmit()\"\n ></dm-generic-form>\n </div>\n </ng-template>\n </mat-menu>\n </div>\n </mat-form-field>\n </div>\n</form>\n", styles: ["@charset \"UTF-8\";.div-search-suffix-btn{display:flex;margin-left:8px}.mdc-icon-button:hover{background-color:#e0e0e0}.advanced-search-menu-content{padding:0 20px 20px;min-width:350px}.mat-chip.mat-standard-chip{overflow:hidden}.mat-mdc-chip-grid{padding-top:3px}.mat-mdc-form-field-hint{color:#0009}\n"] }]
}], ctorParameters: () => [{ type: i0.ElementRef }, { type: i1.FormBuilder }, { type: i2.Actions }, { type: i2.Store }, { type: i0.Renderer2 }, { type: Document, decorators: [{
type: Inject,
args: [DOCUMENT]
}] }, { type: i3.InteractionsService }, { type: i4.OverlayContainer }, { type: i3.EnvService }], propDecorators: { advancedSearchAccessibility$: [], searchFormValue: [{
type: Input
}], selectedResourceRootTypeId: [{
type: Input
}], advancedSearchChips: [{
type: Input
}], resourceTypeConfig: [{
type: Input
}], isLargeScreen: [{
type: Input
}], evtUpdateDataArray: [{
type: Output
}], menu: [{
type: ViewChild,
args: ['advancedSearchMenu']
}], matHint: [{
type: ViewChild,
args: ['matHint']
}], searchFormField: [{
type: ViewChild,
args: ['searchFormField']
}], menuTriggerBtn: [{
type: ViewChild,
args: ['menuTriggerBtn']
}], menuTrigger: [{
type: ViewChild,
args: ['menuTrigger', { static: false }]
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWR2YW5jZWQtc2VhcmNoLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uLy4uL3BhY2thZ2VzL2xpYnMvY2xpZW50LWNvcmUvc3JjL2xpYi9mZWF0dXJlL2FkdmFuY2VkLXNlYXJjaC9hZHZhbmNlZC1zZWFyY2guY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vcGFja2FnZXMvbGlicy9jbGllbnQtY29yZS9zcmMvbGliL2ZlYXR1cmUvYWR2YW5jZWQtc2VhcmNoL2FkdmFuY2VkLXNlYXJjaC5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBbUNBLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUMzQyxPQUFPLEVBQ0wsdUJBQXVCLEVBQ3ZCLFNBQVMsRUFFVCxZQUFZLEVBQ1osTUFBTSxFQUNOLEtBQUssRUFHTCxNQUFNLEVBRU4sU0FBUyxHQUNWLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFBMEIsVUFBVSxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFJcEUsT0FBTyxFQUFXLE1BQU0sRUFBUyxrQkFBa0IsRUFBRSxNQUFNLGFBQWEsQ0FBQztBQUN6RSxPQUFPLEVBRUwsT0FBTyxFQUNQLFlBQVksRUFDWixvQkFBb0IsRUFDcEIsTUFBTSxFQUNOLFNBQVMsRUFDVCxLQUFLLEVBQ0wsUUFBUSxFQUNSLFNBQVMsRUFDVCxJQUFJLEVBQ0osU0FBUyxFQUNULEdBQUcsR0FDSixNQUFNLE1BQU0sQ0FBQztBQUNkLE9BQU8sRUFDTCxJQUFJLEVBU0osT0FBTyxFQUNQLGlCQUFpQixFQUNqQixrQ0FBa0MsRUFDbEMscUJBQXFCLEdBQ3RCLE1BQU0sY0FBYyxDQUFDOzs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFFdEIsSUFBSyxXQUdKO0FBSEQsV0FBSyxXQUFXO0lBQ2Qsb0NBQXFCLENBQUE7SUFDckIsZ0NBQWlCLENBQUE7QUFDbkIsQ0FB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LFNBQVM7dUJBQUMsU0FBUztnQkFFVSxlQUFlO3NCQUE1QyxTQUFTO3VCQUFDLGlCQUFpQjtnQkFDQyxjQUFjO3NCQUExQyxTQUFTO3VCQUFDLGdCQUFnQjtnQkFDa0IsV0FBVztzQkFBdkQsU0FBUzt1QkFBQyxhQUFhLEVBQUUsRUFBRSxNQUFNLEVBQUUsS0FBSyxFQUFFIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBDb3B5cmlnaHQgKEMpIDIwMjAtMjAyNCBMaW5hZ29yYVxuICpcbiAqIFRoaXMgcHJvZ3JhbSBpcyBmcmVlIHNvZnR3YXJlOiB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0IHVuZGVyXG4gKiB0aGUgdGVybXMgb2YgdGhlIEdOVSBBZmZlcm8gR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWVcbiAqIFNvZnR3YXJlIEZvdW5kYXRpb24sIGVpdGhlciB2ZXJzaW9uIDMgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55XG4gKiBsYXRlciB2ZXJzaW9uLCBwcm92aWRlZCB5b3UgY29tcGx5IHdpdGggdGhlIEFkZGl0aW9uYWwgVGVybXMgYXBwbGljYWJsZSBmb3JcbiAqIExpbklEIERpcmVjdG9yeSBNYW5hZ2VyIHNvZnR3YXJlIGJ5IExJTkFHT1JBIHB1cnN1YW50IHRvIFNlY3Rpb24gNyBvZiB0aGUgR05VXG4gKiBBZmZlcm8gR2VuZXJhbCBQdWJsaWMgTGljZW5zZSwgc3Vic2VjdGlvbnMgKGIpLCAoYyksIGFuZCAoZSksIHB1cnN1YW50IHRvXG4gKiB3aGljaCB0aGVzZSBBcHByb3ByaWF0ZSBMZWdhbCBOb3RpY2VzIG11c3Qgbm90YWJseSAoaSkgcmV0YWluIHRoZSBkaXNwbGF5IG9mXG4gKiB0aGUgXCJMaW5JROKEolwiIHRyYWRlbWFyay9sb2dvIGF0IHRoZSB0b3Agb2YgdGhlIGludGVyZmFjZSB3aW5kb3csIHRoZSBkaXNwbGF5XG4gKiBvZiB0aGUg4oCcWW91IGFyZSB1c2luZyB0aGUgT3BlbiBTb3VyY2UgYW5kIGZyZWUgdmVyc2lvbiBvZiBMaW5JROKEoiwgcG93ZXJlZCBieVxuICogTGluYWdvcmEgwqkgMjAwOeKAkzIwMTMuIENvbnRyaWJ1dGUgdG8gTGluSUQgUiZEIGJ5IHN1YnNjcmliaW5nIHRvIGFuIEVudGVycHJpc2VcbiAqIG9mZmVyIeKAnSBpbmZvYm94IGFuZCBpbiB0aGUgZS1tYWlscyBzZW50IHdpdGggdGhlIFByb2dyYW0sIG5vdGljZSBhcHBlbmRlZCB0b1xuICogYW55IHR5cGUgb2Ygb3V0Ym91bmQgbWVzc2FnZXMgKGUuZy4gZS1tYWlsIGFuZCBtZWV0aW5nIHJlcXVlc3RzKSBhcyB3ZWxsIGFzXG4gKiBpbiB0aGUgTGluSUQgRGlyZWN0b3J5IE1hbmFnZXIgdXNlciBpbnRlcmZhY2UsIChpaSkgcmV0YWluIGFsbCBoeXBlcnRleHRcbiAqIGxpbmtzIGJldHdlZW4gTGluSUQgRGlyZWN0b3J5IE1hbmFnZXIgYW5kIGh0dHBzOi8vbGluaWQub3JnLywgYXMgd2VsbCBhc1xuICogYmV0d2VlbiBMSU5BR09SQSBhbmQgTElOQUdPUkEuY29tLCBhbmQgKGlpaSkgcmVmcmFpbiBmcm9tIGluZnJpbmdpbmcgTElOQUdPUkFcbiAqIGludGVsbGVjdHVhbCBwcm9wZXJ0eSByaWdodHMgb3ZlciBpdHMgdHJhZGVtYXJrcyBhbmQgY29tbWVyY2lhbCBicmFuZHMuIE90aGVyXG4gKiBBZGRpdGlvbmFsIFRlcm1zIGFwcGx5LCBzZWUgPGh0dHA6Ly93d3cubGluYWdvcmEuY29tL2xpY2Vuc2VzLz4gZm9yIG1vcmVcbiAqIGRldGFpbHMuXG4gKlxuICogVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dCBXSVRIT1VUXG4gKiBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTU1xuICogRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiBTZWUgdGhlIEdOVSBBZmZlcm8gR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZVxuICogZGV0YWlscy5cbiAqXG4gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgQWZmZXJvIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYW5kXG4gKiBpdHMgYXBwbGljYWJsZSBBZGRpdGlvbmFsIFRlcm1zIGZvciBMaW5JRCBEaXJlY3RvcnkgTWFuYWdlciBhbG9uZyB3aXRoIHRoaXNcbiAqIHByb2dyYW0uIElmIG5vdCwgc2VlIDxodHRwOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvPiBmb3IgdGhlIEdOVSBBZmZlcm9cbiAqIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAzIGFuZCA8aHR0cDovL3d3dy5saW5hZ29yYS5jb20vbGljZW5zZXMvPiBmb3JcbiAqIHRoZSBBZGRpdGlvbmFsIFRlcm1zIGFwcGxpY2FibGUgdG8gdGhlIExpbklEIERpcmVjdG9yeSBNYW5hZ2VyIHNvZnR3YXJlLlxuICovXG5cbmltcG9ydCB7IE92ZXJsYXlDb250YWluZXIgfSBmcm9tICdAYW5ndWxhci9jZGsvb3ZlcmxheSc7XG5pbXBvcnQgeyBET0NVTUVOVCB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XG5pbXBvcnQge1xuICBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneSxcbiAgQ29tcG9uZW50LFxuICBFbGVtZW50UmVmLFxuICBFdmVudEVtaXR0ZXIsXG4gIEluamVjdCxcbiAgSW5wdXQsXG4gIE9uRGVzdHJveSxcbiAgT25Jbml0LFxuICBPdXRwdXQsXG4gIFJlbmRlcmVyMixcbiAgVmlld0NoaWxkLFxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IEZvcm1CdWlsZGVyLCBGb3JtR3JvdXAsIFZhbGlkYXRvcnMgfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XG5pbXBvcnQgeyBNYXRCdXR0b24gfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9idXR0b24nO1xuaW1wb3J0IHsgTWF0Rm9ybUZpZWxkIH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvZm9ybS1maWVsZCc7XG5pbXBvcnQgeyBNYXRNZW51LCBNYXRNZW51VHJpZ2dlciB9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL21lbnUnO1xuaW1wb3J0IHsgQWN0aW9ucywgU2VsZWN0LCBTdG9yZSwgb2ZBY3Rpb25TdWNjZXNzZnVsIH0gZnJvbSAnQG5neHMvc3RvcmUnO1xuaW1wb3J0IHtcbiAgT2JzZXJ2YWJsZSxcbiAgU3ViamVjdCxcbiAgZGVib3VuY2VUaW1lLFxuICBkaXN0aW5jdFVudGlsQ2hhbmdlZCxcbiAgZmlsdGVyLFxuICBmcm9tRXZlbnQsXG4gIG1lcmdlLFxuICBwYWlyd2lzZSxcbiAgc3RhcnRXaXRoLFxuICB0YWtlLFxuICB0YWtlVW50aWwsXG4gIHRhcCxcbn0gZnJvbSAncnhqcyc7XG5pbXBvcnQge1xuICBEYXRhLFxuICBFbnZTZXJ2aWNlLFxuICBJQWR2YW5jZWRTZWFyY2hBY2Nlc3NpYmlsaXR5LFxuICBJQWR2YW5jZWRTZWFyY2hDaGlwLFxuICBJQXR0cmlidXRlLFxuICBJQ29uZmlnLFxuICBJRGF0YSxcbiAgSUZvcm1EYXRhLFxuICBJbnRlcmFjdGlvbnNTZXJ2aWNlLFxuICBVaVN0YXRlLFxuICBmaW5hbGl6ZVdpdGhWYWx1ZSxcbiAgZ2V0QWR2YW5jZWRTZWFyY2hDaGlwc0Zyb21Gb3JtRGF0YSxcbiAgc2V0Rm9ybUZpZWxkRGF0YVZhbHVlLFxufSBmcm9tICcuLi8uLi9zaGFyZWQnO1xuXG5lbnVtIEVTZWFyY2hNb2RlIHtcbiAgQURWQU5DRUQgPSAnYWR2YW5jZWQnLFxuICBTSU1QTEUgPSAnc2ltcGxlJyxcbn1cblxuZW51bSBFT3ZlcmxheUNsaWNrTW9kZSB7XG4gIEVOQUJMRSA9ICdlbmFibGUnLFxuICBESVNBQkxFID0gJ2Rpc2FibGUnLFxufVxuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdkbS1hZHZhbmNlZC1zZWFyY2gnLFxuICB0ZW1wbGF0ZVVybDogJy4vYWR2YW5jZWQtc2VhcmNoLmNvbXBvbmVudC5odG1sJyxcbiAgc3R5bGVVcmxzOiBbJy4vYWR2YW5jZWQtc2VhcmNoLmNvbXBvbmVudC5zY3NzJ10sXG4gIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoLFxufSlcbmV4cG9ydCBjbGFzcyBBZHZhbmNlZFNlYXJjaENvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCwgT25EZXN0cm95IHtcbiAgQFNlbGVjdChVaVN0YXRlLmdldEFkdmFuY2VkU2VhcmNoQWNjZXNzaWJpbGl0eSlcbiAgYWR2YW5jZWRTZWFyY2hBY2Nlc3NpYmlsaXR5JDogT2JzZXJ2YWJsZTxJQWR2YW5jZWRTZWFyY2hBY2Nlc3NpYmlsaXR5PjtcblxuICBASW5wdXQoKSBzZXQgc2VhcmNoRm9ybVZhbHVlKHZhbHVlOiBzdHJpbmcpIHtcbiAgICBpZiAodmFsdWUgPT09ICcnICYmIHRoaXMuX3NlYXJjaEZvcm1WYWx1ZSAhPT0gJycpIHtcbiAgICAgIHRoaXMuc2VhcmNoRm9ybS5yZXNldCgpO1xuICAgIH1cbiAgICB0aGlzLl9zZWFyY2hGb3JtVmFsdWUgPSB2YWx1ZSA/PyAnJztcbiAgICBpZiAodGhpcy5yZXNldEJ0bkNsaWNrZWQpIHtcbiAgICAgIHRoaXMucmVzZXRCdG5DbGlja2VkID0gZmFsc2U7XG4gICAgfVxuICB9XG5cbiAgZ2V0IHNlYXJjaEZvcm1WYWx1ZSgpOiBzdHJpbmcge1xuICAgIHJldHVybiB0aGlzLl9zZWFyY2hGb3JtVmFsdWU7XG4gIH1cblxuICBwcml2YXRlIF9zZWxlY3RlZFJlc291cmNlUm9vdFR5cGVJZDogc3RyaW5nO1xuICBASW5wdXQoKSBzZXQgc2VsZWN0ZWRSZXNvdXJjZVJvb3RUeXBlSWQodmFsOiBzdHJpbmcpIHtcbiAgICB0aGlzLl9zZWxlY3RlZFJlc291cmNlUm9vdFR5cGVJZCA9IHZhbDtcbiAgICBpZiAoISF0aGlzLnNlYXJjaEZvcm0pIHtcbiAgICAgIHRoaXMuc2VhcmNoRm9ybS5zZXRWYWx1ZSh7IHNlYXJjaDogdGhpcy5zZWFyY2hGb3JtVmFsdWUgfSk7XG4gICAgfVxuICB9XG5cbiAgZ2V0IHNlbGVjdGVkUmVzb3VyY2VSb290VHlwZUlkKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHRoaXMuX3NlbGVjdGVkUmVzb3VyY2VSb290VHlwZUlkO1xuICB9XG5cbiAgcHJpdmF0ZSBfYWR2YW5jZWRTZWFyY2hDaGlwczogSUFkdmFuY2VkU2VhcmNoQ2hpcFtdID0gW107XG4gIEBJbnB1dCgpIHNldCBhZHZhbmNlZFNlYXJjaENoaXBzKGNoaXBzOiBJQWR2YW5jZWRTZWFyY2hDaGlwW10pIHtcbiAgICB0aGlzLl9hZHZhbmNlZFNlYXJjaENoaXBzID0gY2hpcHMgPz8gW107XG4gICAgaWYgKCF0aGlzLl9pc1NlYXJjaFN1Y2Nlc3MpIHtcbiAgICAgIHRoaXMuc2V0Rm9ybUZpZWxkc1dpdGhDaGlwcygpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLl9pc1NlYXJjaFN1Y2Nlc3MgPSBmYWxzZTtcbiAgICB9XG4gICAgaWYgKHRoaXMucmVzZXRCdG5DbGlja2VkKSB7XG4gICAgICB0aGlzLnJlc2V0QnRuQ2xpY2tlZCA9IGZhbHNlO1xuICAgIH1cbiAgICB0aGlzLnJlbW92aW5nQ2hpcHMgPSB0aGlzLnJlbW92aW5nQ2hpcHMuZmlsdGVyKChpZDogc3RyaW5nKSA9PlxuICAgICAgY2hpcHMubWFwKChjaGlwOiBJQWR2YW5jZWRTZWFyY2hDaGlwKSA9PiBjaGlwLm1vZGVsUmVmKS5pbmNsdWRlcyhpZClcbiAgICApO1xuICB9XG5cbiAgZ2V0IGFkdmFuY2VkU2VhcmNoQ2hpcHMoKTogSUFkdmFuY2VkU2VhcmNoQ2hpcFtdIHtcbiAgICByZXR1cm4gdGhpcy5fYWR2YW5jZWRTZWFyY2hDaGlwcztcbiAgfVxuXG4gIHByaXZhdGUgX3Jlc291cmNlVHlwZUNvbmZpZzogSUNvbmZpZztcbiAgQElucHV0KCkgc2V0IHJlc291cmNlVHlwZUNvbmZpZyhjb25maWc6IElDb25maWcpIHtcbiAgICB0aGlzLl9yZXNvdXJjZVR5cGVDb25maWcgPSBjb25maWc7XG4gICAgdGhpcy5mb3JtRmllbGRzID0gW107XG4gICAgdGhpcy5fcmVzb3VyY2VUeXBlQ29uZmlnLmF0dHJpYnV0ZXMuZm9yRWFjaCgoYXR0cmlidXRlOiBJQXR0cmlidXRlKSA9PiB7XG4gICAgICBpZiAoYXR0cmlidXRlLnByb3BzLmlzU2VhcmNoYWJsZSkge1xuICAgICAgICB0aGlzLmZvcm1GaWVsZHMucHVzaCh7XG4gICAgICAgICAgLi4uYXR0cmlidXRlLFxuICAgICAgICAgIGRhdGFWYWx1ZTogbnVsbCxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICBnZXQgcmVzb3VyY2VUeXBlQ29uZmlnKCk6IElDb25maWcge1xuICAgIHJldHVybiB0aGlzLl9yZXNvdXJjZVR5cGVDb25maWc7XG4gIH1cbiAgQElucHV0KCkgaXNMYXJnZVNjcmVlbjogYm9vbGVhbjtcblxuICBAT3V0cHV0KCkgZXZ0VXBkYXRlRGF0YUFycmF5ID0gbmV3IEV2ZW50RW1pdHRlcjx2b2lkIHwgSURhdGE+KCk7XG5cbiAgQFZpZXdDaGlsZCgnYWR2YW5jZWRTZWFyY2hNZW51JykgbWVudTogTWF0TWVudTtcblxuICBAVmlld0NoaWxkKCdtYXRIaW50JykgbWF0SGludDogRWxlbWVudFJlZjtcblxuICBAVmlld0NoaWxkKCdzZWFyY2hGb3JtRmllbGQnKSBzZWFyY2hGb3JtRmllbGQ6IE1hdEZvcm1GaWVsZDtcbiAgQFZpZXdDaGlsZCgnbWVudVRyaWdnZXJCdG4nKSBtZW51VHJpZ2dlckJ0bjogTWF0QnV0dG9uO1xuICBAVmlld0NoaWxkKCdtZW51VHJpZ2dlcicsIHsgc3RhdGljOiBmYWxzZSB9KSBtZW51VHJpZ2dlcjogTWF0TWVudVRyaWdnZXI7XG5cbiAgcHVibGljIGVsZW1lbnRSZWY6IEVsZW1lbnRSZWY7XG5cbiAgcHVibGljIHNlYXJjaEZvcm06IEZvcm1Hcm91cDtcblxuICBwdWJsaWMgcmVzaXplT2JzZXJ2YWJsZSQ6IE9ic2VydmFibGU8RXZlbnQ+O1xuXG4gIHB1YmxpYyByZXNldEJ0bkNsaWNrZWQgPSBmYWxzZTtcblxuICBwdWJsaWMgcmVtb3ZpbmdDaGlwczogc3RyaW5nW10gPSBbXTtcbiAgcHVibGljIGZvcm1GaWVsZHM6IElGb3JtRGF0YVtdID0gW107XG5cbiAgcHVibGljIGlzR2VuZXJpY0Zvcm1FbmFibGUgPSB0cnVlO1xuXG4gIHByaXZhdGUgX29uRGVzdHJveSQgPSBuZXcgU3ViamVjdDx2b2lkPigpO1xuXG4gIHByaXZhdGUgX3NlYXJjaEZvcm1WYWx1ZSA9ICcnO1xuXG4gIHByaXZhdGUgX2lzU2VhcmNoU3VjY2VzcyA9IGZhbHNlO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgX2VsOiBFbGVtZW50UmVmLFxuICAgIHByaXZhdGUgX2ZiOiBGb3JtQnVpbGRlcixcbiAgICBwcml2YXRlIF9hY3Rpb25zJDogQWN0aW9ucyxcbiAgICBwcml2YXRlIF9zdG9yZSQ6IFN0b3JlLFxuICAgIHByaXZhdGUgX3JlbmRlcmVyOiBSZW5kZXJlcjIsXG4gICAgQEluamVjdChET0NVTUVOVCkgcHJpdmF0ZSBkb2N1bWVudDogRG9jdW1lbnQsXG4gICAgcHJpdmF0ZSBfaW50ZXJhY3Rpb25zU2VydmljZTogSW50ZXJhY3Rpb25zU2VydmljZSxcbiAgICBwcml2YXRlIF9vdmVybGF5Q29udGFpbmVyOiBPdmVybGF5Q29udGFpbmVyLFxuICAgIHByaXZhdGUgX2VudlNlcnZpY2U6IEVudlNlcnZpY2VcbiAgKSB7XG4gICAgdGhpcy5lbGVtZW50UmVmID0gdGhpcy5fZWw7XG4gIH1cblxuICBuZ09uSW5pdCgpOiB2b2lkIHtcbiAgICB0aGlzLnNlYXJjaEZvcm0gPSB0aGlzLl9mYi5ncm91cCh7XG4gICAgICBzZWFyY2g6IFt0aGlzLnNlYXJjaEZvcm1WYWx1ZSA/PyAnJywgVmFsaWRhdG9ycy5taW5MZW5ndGgoMyldLFxuICAgIH0pO1xuXG4gICAgdGhpcy5zZWFyY2hGb3JtXG4gICAgICAuZ2V0KCdzZWFyY2gnKVxuICAgICAgLnZhbHVlQ2hhbmdlcy5waXBlKFxuICAgICAgICB0YWtlVW50aWwodGhpcy5fb25EZXN0cm95JCksXG4gICAgICAgIGRlYm91bmNlVGltZSg2MDApLFxuICAgICAgICBzdGFydFdpdGgodGhpcy5zZWFyY2hGb3JtLmdldCgnc2VhcmNoJykudmFsdWUpLFxuICAgICAgICB0YXAoKHZhbHVlOiBzdHJpbmcpID0+IHtcbiAgICAgICAgICBpZiAoXG4gICAgICAgICAgICB0aGlzLnNlYXJjaEZvcm1WYWx1ZSAhPT0gJycgJiZcbiAgICAgICAgICAgIHZhbHVlID09PSB0aGlzLnNlYXJjaEZvcm1WYWx1ZSAmJlxuICAgICAgICAgICAgIXRoaXMucmVzZXRCdG5DbGlja2VkXG4gICAgICAgICAgKSB7XG4gICAgICAgICAgICB0aGlzLl9pbnRlcmFjdGlvbnNTZXJ2aWNlLmNhbmNlbFJlcXVlc3QoKTtcbiAgICAgICAgICAgIHRoaXMuX3N0b3JlJC5kaXNwYXRjaChuZXcgRGF0YS5TdG9wRmlsdGVyaW5nUmVzb3VyY2VzKCkpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSksXG4gICAgICAgIGRpc3RpbmN0VW50aWxDaGFuZ2VkKFxuICAgICAgICAgIChwcmV2LCBjdXJyKSA9PlxuICAgICAgICAgICAgcHJldiA9PT0gY3VyciB8fFxuICAgICAgICAgICAgKHRoaXMuc2VhcmNoRm9ybVZhbHVlICE9PSAnJyAmJiB0aGlzLnNlYXJjaEZvcm1WYWx1ZSA9PT0gY3VycilcbiAgICAgICAgKSxcbiAgICAgICAgcGFpcndpc2UoKSxcbiAgICAgICAgZmlsdGVyKChbcHJldiwgY3Vycl0pID0+IHtcbiAgICAgICAgICBjb25zdCBpc0NsZWFyaW5nU2VhcmNoV2l0aEtleWJvYXJkID1cbiAgICAgICAgICAgIHByZXYgIT09IG51bGwgJiZcbiAgICAgICAgICAgIGN1cnIgIT09IG51bGwgJiZcbiAgICAgICAgICAgIHByZXYubGVuZ3RoID4gY3Vyci5sZW5ndGggJiZcbiAgICAgICAgICAgIGN1cnIubGVuZ3RoIDw9IDI7XG4gICAgICAgICAgaWYgKGlzQ2xlYXJpbmdTZWFyY2hXaXRoS2V5Ym9hcmQpIHtcbiAgICAgICAgICAgIHRoaXMucmVzZXRTZWFyY2goKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIGN1cnIgIT09IG51bGwgJiYgY3Vyci5sZW5ndGggPiAyO1xuICAgICAgICB9KSxcbiAgICAgICAgdGFwKChbX3ByZXYsIGN1cnJdKSA9PiB7XG4gICAgICAgICAgdGhpcy5fc3RvcmUkLmRpc3BhdGNoKFxuICAgICAgICAgICAgbmV3IERhdGEuRmlsdGVyUmVzb3VyY2VzKHtcbiAgICAgICAgICAgICAgYWN0aW9uT25TdWNjZXNzOiBuZXcgRGF0YS5TZXRTZWFyY2hGb3JtVmFsdWUoe1xuICAgICAgICAgICAgICAgIHNlYXJjaEZvcm06IGN1cnIsXG4gICAgICAgICAgICAgICAgZGF0YVR5cGVJZDogdGhpcy5zZWxlY3RlZFJlc291cmNlUm9vdFR5cGVJZCxcbiAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICAgIGZpbHRlclBheWxvYWQ6IGN1cnIsXG4gICAgICAgICAgICB9KVxuICAgICAgICAgICk7XG4gICAgICAgIH0pXG4gICAgICApXG4gICAgICAuc3Vic2NyaWJlKCk7XG5cbiAgICBsZXQgYWR2YW5jZWRTZWFyY2hNZW51V2FzT3BlbmVkID0gZmFsc2U7XG5cbiAgICB0aGlzLnJlc2l6ZU9ic2VydmFibGUkID0gZnJvbUV2ZW50KHdpbmRvdywgJ3Jlc2l6ZScpO1xuICAgIHRoaXMucmVzaXplT2JzZXJ2YWJsZSRcbiAgICAgIC5waXBlKFxuICAgICAgICB0YWtlVW50aWwodGhpcy5fb25EZXN0cm95JCksXG4gICAgICAgIHRhcCgoXykgPT4ge1xuICAgICAgICAgIGlmICghYWR2YW5jZWRTZWFyY2hNZW51V2FzT3BlbmVkICYmIHRoaXMubWVudVRyaWdnZXIpIHtcbiAgICAgICAgICAgIGFkdmFuY2VkU2VhcmNoTWVudVdhc09wZW5lZCA9IHRoaXMubWVudVRyaWdnZXIubWVudU9wZW47XG4gICAgICAgICAgfVxuICAgICAgICB9KSxcbiAgICAgICAgdGFwKChfKSA9PiB7XG4gICAgICAgICAgaWYgKHRoaXMubWVudVRyaWdnZXIpIHtcbiAgICAgICAgICAgIHRoaXMubWVudVRyaWdnZXIuY2xvc2VNZW51KCk7XG4gICAgICAgICAgfVxuICAgICAgICB9KSxcbiAgICAgICAgZGVib3VuY2VUaW1lKDMwMCksXG4gICAgICAgIHRhcCgoXykgPT4ge1xuICAgICAgICAgIGlmIChhZHZhbmNlZFNlYXJjaE1lbnVXYXNPcGVuZWQgJiYgdGhpcy5tZW51VHJpZ2dlcikge1xuICAgICAgICAgICAgdGhpcy5tZW51VHJpZ2dlci5vcGVuTWVudSgpO1xuICAgICAgICAgICAgYWR2YW5jZWRTZWFyY2hNZW51V2FzT3BlbmVkID0gZmFsc2U7XG4gICAgICAgICAgfVxuICAgICAgICB9KVxuICAgICAgKVxuICAgICAgLnN1YnNjcmliZSgpO1xuICB9XG5cbiAgbmdPbkRlc3Ryb3koKTogdm9pZCB7XG4gICAgdGhpcy5fb25EZXN0cm95JC5uZXh0KCk7XG4gICAgdGhpcy5fb25EZXN0cm95JC5jb21wbGV0ZSgpO1xuICB9XG5cbiAgb25SZXNldFNlYXJjaEJ0bkNsaWNrKCk6IHZvaWQge1xuICAgIHRoaXMucmVzZXRCdG5DbGlja2VkID0gdHJ1ZTtcbiAgICB0aGlzLnNlYXJjaEZvcm0uZGlzYWJsZSh7IGVtaXRFdmVudDogZmFsc2UgfSk7XG4gICAgdGhpcy5yZXNldFNlYXJjaCgpO1xuICB9XG5cbiAgcmVzZXRTZWFyY2goKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuc2VhcmNoRm9ybVZhbHVlICE9PSAnJyB8fCB0aGlzLmFkdmFuY2VkU2VhcmNoQ2hpcHM/Lmxlbmd0aCA+IDApIHtcbiAgICAgIGNvbnN0IHNlYXJjaE1vZGU6IEVTZWFyY2hNb2RlID1cbiAgICAgICAgdGhpcy5zZWFyY2hGb3JtVmFsdWUgIT09ICcnID8gRVNlYXJjaE1vZGUuU0lNUExFIDogRVNlYXJjaE1vZGUuQURWQU5DRUQ7XG4gICAgICBjb25zdCBwYXlsb2FkOiB7XG4gICAgICAgIGFjdGlvbk9uU3VjY2VzczogYW55O1xuICAgICAgICBmaWx0ZXJQYXlsb2FkOiBzdHJpbmcgfCBJQWR2YW5jZWRTZWFyY2hDaGlwW107XG4gICAgICB9ID1cbiAgICAgICAgc2VhcmNoTW9kZSA9PT0gRVNlYXJjaE1vZGUuU0lNUExFXG4gICAgICAgICAgPyB7XG4gICAgICAgICAgICAgIGFjdGlvbk9uU3VjY2VzczogbmV3IERhdGEuUmVzZXRTZWFyY2hGb3JtVmFsdWUoe1xuICAgICAgICAgICAgICAgIGRhdGFUeXBlSWQ6IHRoaXMuc2VsZWN0ZWRSZXNvdXJjZVJvb3RUeXBlSWQsXG4gICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgICBmaWx0ZXJQYXlsb2FkOiAnJyxcbiAgICAgICAgICAgIH1cbiAgICAgICAgICA6IHtcbiAgICAgICAgICAgICAgYWN0aW9uT25TdWNjZXNzOiBuZXcgRGF0YS5SZXNldEFkdmFuY2VkU2VhcmNoQ2hpcHMoe1xuICAgICAgICAgICAgICAgIGRhdGFUeXBlSWQ6IHRoaXMuc2VsZWN0ZWRSZXNvdXJjZVJvb3RUeXBlSWQsXG4gICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgICBmaWx0ZXJQYXlsb2FkOiBbXSBhcyBJQWR2YW5jZWRTZWFyY2hDaGlwW10sXG4gICAgICAgICAgICB9O1xuICAgICAgdGhpcy5fc3RvcmUkLmRpc3BhdGNoKG5ldyBEYXRhLkZpbHRlclJlc291cmNlcyhwYXlsb2FkKSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuX2ludGVyYWN0aW9uc1NlcnZpY2UuY2FuY2VsUmVxdWVzdCgpO1xuICAgICAgdGhpcy5fc3RvcmUkLmRpc3BhdGNoKG5ldyBEYXRhLlN0b3BGaWx0ZXJpbmdSZXNvdXJjZXMoKSk7XG4gICAgICB0aGlzLnNlYXJjaEZvcm0ucmVzZXQoKTtcbiAgICAgIHRoaXMuc2VhcmNoRm9ybS5lbmFibGUoeyBlbWl0RXZlbnQ6IGZhbHNlIH0pO1xuICAgICAgaWYgKHRoaXMucmVzZXRCdG5DbGlja2VkKSB7XG4gICAgICAgIHRoaXMucmVzZXRCdG5DbGlja2VkID0gZmFsc2U7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgb25TdWJtaXQoKTogdm9pZCB7XG4gICAgdGhpcy5fYWN0aW9ucyRcbiAgICAgIC5waXBlKFxuICAgICAgICBvZkFjdGlvblN1Y2Nlc3NmdWwoXG4gICAgICAgICAgRGF0YS5GZXRjaFJlc291cmNlc1N1Y2Nlc3MsXG4gICAgICAgICAgRGF0YS5GZXRjaFJlc291cmNlc0Vycm9yXG4gICAgICAgICksXG4gICAgICAgIHRha2UoMSksXG4gICAgICAgIHRha2VVbnRpbChcbiAgICAgICAgICBtZXJnZSh0aGlzLl9vbkRlc3Ryb3kkLCB0aGlzLl9pbnRlcmFjdGlvbnNTZXJ2aWNlLmNhbmNlbFJlcXVlc3QkKVxuICAgICAgICApLFxuICAgICAgICBmaW5hbGl6ZVdpdGhWYWx1ZShcbiAgICAgICAgICAoYWN0aW9uOiBEYXRhLkZldGNoUmVzb3VyY2VzU3VjY2VzcyB8IERhdGEuRmV0Y2hSZXNvdXJjZXNFcnJvcikgPT4ge1xuICAgICAgICAgICAgdGhpcy5tZW51VHJpZ2dlci5jbG9zZU1lbnUoKTtcbiAgICAgICAgICAgIHRoaXMuX3N3aXRjaENsaWNrT25PdmVybGF5KEVPdmVybGF5Q2xpY2tNb2RlLkVOQUJMRSk7XG4gICAgICAgICAgICB0aGlzLmlzR2VuZXJpY0Zvcm1FbmFibGUgPSB0cnVlO1xuXG4gICAgICAgICAgICBpZiAoYWN0aW9uIGluc3RhbmNlb2YgRGF0YS5GZXRjaFJlc291cmNlc0Vycm9yIHx8ICFhY3Rpb24pIHtcbiAgICAgICAgICAgICAgdGhpcy5zZXRGb3JtRmllbGRzV2l0aENoaXBzKCk7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKGFjdGlvbiBpbnN0YW5jZW9mIERhdGEuRmV0Y2hSZXNvdXJjZXNTdWNjZXNzKSB7XG4gICAgICAgICAgICAgIHRoaXMuX2lzU2VhcmNoU3VjY2VzcyA9IHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICApXG4gICAgICApXG4gICAgICAuc3Vic2NyaWJlKCk7XG5cbiAgICBjb25zdCB1cGRhdGVkQ2hpcHM6IElBZHZhbmNlZFNlYXJjaENoaXBbXSA9XG4gICAgICBnZXRBZHZhbmNlZFNlYXJjaENoaXBzRnJvbUZvcm1EYXRhKHRoaXMuZm9ybUZpZWxkcyk7XG5cbiAgICB0aGlzLmlzR2VuZXJpY0Zvcm1FbmFibGUgPSBmYWxzZTtcbiAgICB0aGlzLl9zd2l0Y2hDbGlja09uT3ZlcmxheShFT3ZlcmxheUNsaWNrTW9kZS5ESVNBQkxFKTtcblxuICAgIHRoaXMuX3N0b3JlJC5kaXNwYXRjaChcbiAgICAgIG5ldyBEYXRhLkZpbHRlclJlc291cmNlcyh7XG4gICAgICAgIGFjdGlvbk9uU3VjY2VzczogbmV3IERhdGEuU2V0QWR2YW5jZWRTZWFyY2hDaGlwcyh7XG4gICAgICAgICAgYWR2YW5jZWRTZWFyY2hDaGlwczogdXBkYXRlZENoaXBzLFxuICAgICAgICAgIGRhdGFUeXBlSWQ6IHRoaXMuc2VsZWN0ZWRSZXNvdXJjZVJvb3RUeXBlSWQsXG4gICAgICAgIH0pLFxuICAgICAgICBmaWx0ZXJQYXlsb2FkOiB1cGRhdGVkQ2hpcHMsXG4gICAgICB9KVxuICAgICk7XG4gIH1cblxuICByZW1vdmVDaGlwKGNoaXA6IElBZHZhbmNlZFNlYXJjaENoaXApOiB2b2lkIHtcbiAgICBjb25zdCBpbmRleCA9IHRoaXMuYWR2YW5jZWRTZWFyY2hDaGlwcy5pbmRleE9mKGNoaXApO1xuXG4gICAgaWYgKGluZGV4ID49IDApIHtcbiAgICAgIGNvbnN0IGNoaXBNb2RlbFJlZjogc3RyaW5nID0gY2hpcC5hc3NvY2lhdGVkRmllbGRJZCA/PyBjaGlwLm1vZGVsUmVmO1xuICAgICAgdGhpcy5yZW1vdmluZ0NoaXBzLnB1c2goY2hpcE1vZGVsUmVmKTtcbiAgICAgIGNvbnN0IHJlbWFpbmluZ0Zvcm1GaWVsZHM6IElGb3JtRGF0YVtdID0gdGhpcy5mb3JtRmllbGRzLmZpbHRlcihcbiAgICAgICAgKGZvcm1EYXRhOiBJRm9ybURhdGEpID0+XG4gICAgICAgICAgZm9ybURhdGEubW9kZWxSZWYgIT09IGNoaXBNb2RlbFJlZiAmJiAhIWZvcm1EYXRhLmRhdGFWYWx1ZVxuICAgICAgKTtcbiAgICAgIGlmIChyZW1haW5pbmdGb3JtRmllbGRzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgdGhpcy5fc3RvcmUkLmRpc3BhdGNoKFxuICAgICAgICAgIG5ldyBEYXRhLkZpbHRlclJlc291cmNlcyh7XG4gICAgICAgICAgICBhY3Rpb25PblN1Y2Nlc3M6IG5ldyBEYXRhLlJlbW92ZUFkdmFuY2VkU2VhcmNoQ2hpcCh7XG4gICAgICAgICAgICAgIG1vZGVsUmVmOiBjaGlwTW9kZWxSZWYsXG4gICAgICAgICAgICAgIGRhdGFUeXBlSWQ6IHRoaXMuc2VsZWN0ZWRSZXNvdXJjZVJvb3RUeXBlSWQsXG4gICAgICAgICAgICB9KSxcbiAgICAgICAgICAgIGZpbHRlclBheWxvYWQ6XG4gICAgICAgICAgICAgIGdldEFkdmFuY2VkU2VhcmNoQ2hpcHNGcm9tRm9ybURhdGEocmVtYWluaW5nRm9ybUZpZWxkcyksXG4gICAgICAgICAgfSlcbiAgICAgICAgKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMucmVzZXRTZWFyY2goKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBzZXRNZW51UGFuZWxQb3NpdGlvbigpOiB2b2lkIHtcbiAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgIGlmIChcbiAgICAgICAgdGhpcy5zZWFyY2hGb3JtRmllbGQgJiZcbiAgICAgICAgdGhpcy5tZW51VHJpZ2dlckJ0biAmJlxuICAgICAgICB0aGlzLm1lbnUgJiZcbiAgICAgICAgdGhpcy5tZW51LnBhbmVsSWRcbiAgICAgICkge1xuICAgICAgICBjb25zdCBwYW5lbExlZnRPZmZzZXQ6IG51bWJlciA9XG4gICAgICAgICAgdGhpcy5zZWFyY2hGb3JtRmllbGQuX2VsZW1lbnRSZWYubmF0aXZlRWxlbWVudC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKVxuICAgICAgICAgICAgLmxlZnQ7XG4gICAgICAgIGNvbnN0IHBhbmVsVG9wT2Zmc2V0OiBudW1iZXIgPVxuICAgICAgICAgIHRoaXMubWVudVRyaWdnZXJCdG4uX2VsZW1lbnRSZWYubmF0aXZlRWxlbWVudC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKVxuICAgICAgICAgICAgLmJvdHRvbTtcbiAgICAgICAgY29uc3QgbWVudVBhbmVsOiBIVE1MRWxlbWVudCA9IHRoaXMuZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoXG4gICAgICAgICAgdGhpcy5tZW51LnBhbmVsSWRcbiAgICAgICAgKS5wYXJlbnRFbGVtZW50O1xuICAgICAgICB0aGlzLl9yZW5kZXJlci5zZXRTdHlsZShtZW51UGFuZWwsICd0b3AnLCAnMHB4Jyk7XG4gICAgICAgIHRoaXMuX3JlbmRlcmVyLnNldFN0eWxlKG1lbnVQYW5lbCwgJ2xlZnQnLCAnMHB4Jyk7XG4gICAgICAgIHRoaXMuX3JlbmRlcmVyLnNldFN0eWxlKG1lbnVQYW5lbCwgJ21hcmdpbi10b3AnLCBwYW5lbFRvcE9mZnNldCArICdweCcpO1xuICAgICAgICB0aGlzLl9yZW5kZXJlci5zZXRTdHlsZShcbiAgICAgICAgICBtZW51UGFuZWwsXG4gICAgICAgICAgJ21hcmdpbi1sZWZ0JyxcbiAgICAgICAgICBwYW5lbExlZnRPZmZzZXQgKyAncHgnXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfSwgMSk7XG4gIH1cblxuICBzZXRGb3JtRmllbGRzV2l0aENoaXBzKCk6IHZvaWQge1xuICAgIGNvbnN0IGNoaXBJZEluZGV4TWFwOiBNYXA8c3RyaW5nLCBudW1iZXI+ID0gbmV3IE1hcChcbiAgICAgIHRoaXMuYWR2YW5jZWRTZWFyY2hDaGlwcy5tYXAoKGNoaXA6IElBZHZhbmNlZFNlYXJjaENoaXAsIGluZGV4KSA9PiBbXG4gICAgICAgIGNoaXAuYXNzb2NpYXRlZEZpZWxkSWQgPz8gY2hpcC5tb2RlbFJlZixcbiAgICAgICAgaW5kZXgsXG4gICAgICBdKVxuICAgICk7XG4gICAgdGhpcy5mb3JtRmllbGRzLmZvckVhY2goKGZvcm1EYXRhOiBJRm9ybURhdGEpID0+IHtcbiAgICAgIGlmIChjaGlwSWRJbmRleE1hcC5oYXMoZm9ybURhdGEubW9kZWxSZWYpKSB7XG4gICAgICAgIHNldEZvcm1GaWVsZERhdGFWYWx1ZShcbiAgICAgICAgICBmb3JtRGF0YSxcbiAgICAgICAgICB0aGlzLmFkdmFuY2VkU2VhcmNoQ2hpcHNbY2hpcElkSW5kZXhNYXAuZ2V0KGZvcm1EYXRhLm1vZGVsUmVmKV0udmFsdWUsXG4gICAgICAgICAgdGhpcy5fZW52U2VydmljZS51aS5kaXNwbGF5RGF0ZUZvcm1hdFxuICAgICAgICApO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZm9ybURhdGEuZGF0YVZhbHVlID0gbnVsbDtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgX3N3aXRjaENsaWNrT25PdmVybGF5KG1vZGU6IEVPdmVybGF5Q2xpY2tNb2RlKTogdm9pZCB7XG4gICAgY29uc3Qgb3ZlcmxheUNvbnRhaW5lcjogSFRNTEVsZW1lbnQgPVxuICAgICAgdGhpcy5fb3ZlcmxheUNvbnRhaW5lci5nZXRDb250YWluZXJFbGVtZW50KCk7XG4gICAgc3dpdGNoIChtb2RlKSB7XG4gICAgICBjYXNlIEVPdmVybGF5Q2xpY2tNb2RlLkVOQUJMRTpcbiAgICAgICAgb3ZlcmxheUNvbnRhaW5lci5jbGFzc0xpc3QucmVtb3ZlKCdkaXNhYmxlLW92ZXJsYXknKTtcbiAgICAgICAgb3ZlcmxheUNvbnRhaW5lci5zdHlsZS5wb2ludGVyRXZlbnRzID0gJ25vbmUnO1xuICAgICAgICBvdmVybGF5Q29udGFpbmVyLm9uY2xpY2sgPSBudWxsO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgRU92ZXJsYXlDbGlja01vZGUuRElTQUJMRTpcbiAgICAgICAgb3ZlcmxheUNvbnRhaW5lci5jbGFzc0xpc3QuYWRkKCdkaXNhYmxlLW92ZXJsYXknKTtcbiAgICAgICAgb3ZlcmxheUNvbnRhaW5lci5zdHlsZS5wb2ludGVyRXZlbnRzID0gJ2F1dG8nO1xuICAgICAgICBvdmVybGF5Q29udGFpbmVyLm9uY2xpY2sgPSAoZXZlbnQpID0+IGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgICAgICBicmVhaztcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxufVxuIiwiPCEtLSBDb3B5cmlnaHQgKEMpIDIwMjAtMjAyNCBMaW5hZ29yYVxuXG5UaGlzIHByb2dyYW0gaXMgZnJlZSBzb2Z0d2FyZTogeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeSBpdCB1bmRlclxudGhlIHRlcm1zIG9mIHRoZSBHTlUgQWZmZXJvIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlXG5Tb2Z0d2FyZSBGb3VuZGF0aW9uLCBlaXRoZXIgdmVyc2lvbiAzIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueVxubGF0ZXIgdmVyc2lvbiwgcHJvdmlkZWQgeW91IGNvbXBseSB3aXRoIHRoZSBBZGRpdGlvbmFsIFRlcm1zIGFwcGxpY2FibGUgZm9yXG5MaW5JRCBEaXJlY3RvcnkgTWFuYWdlciBzb2Z0d2FyZSBieSBMSU5BR09SQSBwdXJzdWFudCB0byBTZWN0aW9uIDcgb2YgdGhlIEdOVVxuQWZmZXJvIEdlbmVyYWwgUHVibGljIExpY2Vuc2UsIHN1YnNlY3Rpb25zIChiKSwgKGMpLCBhbmQgKGUpLCBwdXJzdWFudCB0b1xud2hpY2ggdGhlc2UgQXBwcm9wcmlhdGUgTGVnYWwgTm90aWNlcyBtdXN0IG5vdGFibHkgKGkpIHJldGFpbiB0aGUgZGlzcGxheSBvZlxudGhlIFwiTGluSUTihKJcIiB0cmFkZW1hcmsvbG9nbyBhdCB0aGUgdG9wIG9mIHRoZSBpbnRlcmZhY2Ugd2luZG93LCB0aGUgZGlzcGxheVxub2YgdGhlIOKAnFlvdSBhcmUgdXNpbmcgdGhlIE9wZW4gU291cmNlIGFuZCBmcmVlIHZlcnNpb24gb2YgTGluSUTihKIsIHBvd2VyZWQgYnlcbkxpbmFnb3JhIMKpIDIwMDnigJMyMDEzLiBDb250cmlidXRlIHRvIExpbklEIFImRCBieSBzdWJzY3JpYmluZyB0byBhbiBFbnRlcnByaXNlXG5vZmZlciHigJ0gaW5mb2JveCBhbmQgaW4gdGhlIGUtbWFpbHMgc2VudCB3aXRoIHRoZSBQcm9ncmFtLCBub3RpY2UgYXBwZW5kZWQgdG9cbmFueSB0eXBlIG9mIG91dGJvdW5kIG1lc3NhZ2VzIChlLmcuIGUtbWFpbCBhbmQgbWVldGluZyByZXF1ZXN0cykgYXMgd2VsbCBhc1xuaW4gdGhlIExpbklEIERpcmVjdG9yeSBNYW5hZ2VyIHVzZXIgaW50ZXJmYWNlLCAoaWkpIHJldGFpbiBhbGwgaHlwZXJ0ZXh0XG5saW5rcyBiZXR3ZWVuIExpbklEIERpcmVjdG9yeSBNYW5hZ2VyIGFuZCBodHRwczovL2xpbmlkLm9yZy8sIGFzIHdlbGwgYXNcbmJldHdlZW4gTElOQUdPUkEgYW5kIExJTkFHT1JBLmNvbSwgYW5kIChpaWkpIHJlZnJhaW4gZnJvbSBpbmZyaW5naW5nIExJTkFHT1JBXG5pbnRlbGxlY3R1YWwgcHJvcGVydHkgcmlnaHRzIG92ZXIgaXRzIHRyYWRlbWFya3MgYW5kIGNvbW1lcmNpYWwgYnJhbmRzLiBPdGhlclxuQWRkaXRpb25hbCBUZXJtcyBhcHBseSwgc2VlIDxodHRwOi8vd3d3LmxpbmFnb3JhLmNvbS9saWNlbnNlcy8+IGZvciBtb3JlXG5kZXRhaWxzLlxuXG5UaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVRcbkFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTXG5GT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuIFNlZSB0aGUgR05VIEFmZmVybyBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlXG5kZXRhaWxzLlxuXG5Zb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgQWZmZXJvIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYW5kXG5pdHMgYXBwbGljYWJsZSBBZGRpdGlvbmFsIFRlcm1zIGZvciBMaW5JRCBEaXJlY3RvcnkgTWFuYWdlciBhbG9uZyB3aXRoIHRoaXNcbnByb2dyYW0uIElmIG5vdCwgc2VlIDxodHRwOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvPiBmb3IgdGhlIEdOVSBBZmZlcm9cbkdlbmVyYWwgUHVibGljIExpY2Vuc2UgdmVyc2lvbiAzIGFuZCA8aHR0cDovL3d3dy5saW5hZ29yYS5jb20vbGljZW5zZXMvPiBmb3JcbnRoZSBBZGRpdGlvbmFsIFRlcm1zIGFwcGxpY2FibGUgdG8gdGhlIExpbklEIERpcmVjdG9yeSBNYW5hZ2VyIHNvZnR3YXJlLiAtLT5cblxuPGZvcm0gW2Zvcm1Hcm91cF09XCJzZWFyY2hGb3JtXCIgY2xhc3M9XCJzZWFyY2gtZm9ybVwiPlxuICA8ZGl2IGZ4TGF5b3V0PVwicm93XCIgZnhMYXlvdXRBbGlnbj1cInN0YXJ0IGNlbnRlclwiPlxuICAgIDxtYXQtZm9ybS1maWVsZFxuICAgICAgKm5nSWY9XCJcbiAgICAgICAgYWR2YW5jZWRTZWFyY2hBY2Nlc3NpYmlsaXR5JCB8IGFzeW5jIGFzIGFkdmFuY2VkU2VhcmNoQWNjZXNzaWJpbGl0eVxuICAgICAgXCJcbiAgICAgIGZ4RmxleFxuICAgICAgY29sb3I9XCJhY2NlbnRcIlxuICAgICAgYXBwZWFyYW5jZT1cImZpbGxcIlxuICAgICAgY2xhc3M9XCJzZWFyY2gtZm9ybS1maWVsZFwiXG4gICAgICAjc2VhcmNoRm9ybUZpZWxkXG4gICAgPlxuICAgICAgPG1hdC1sYWJlbD5cbiAgICAgICAgPG1hdC1pY29uIGFyaWEtaGlkZGVuPVwidHJ1ZVwiPnNlYXJjaDwvbWF0LWljb24+XG4gICAgICAgIHt7IGFkdmFuY2VkU2VhcmNoQWNjZXNzaWJpbGl0eS5sYWJlbCB9fVxuICAgICAgPC9tYXQtbGFiZWw+XG4gICAgICA8bWF0LWNoaXAtZ3JpZCAjY2hpcExpc3Q+XG4gICAgICAgIDxtYXQtY2hpcC1yb3dcbiAgICAgICAgICAqbmdGb3I9XCJsZXQgY2hpcCBvZiBhZHZhbmNlZFNlYXJjaENoaXBzXCJcbiAgICAgICAgICBjb2xvcj1cImFjY2VudFwiXG4gICAgICAgICAgW21hdFRvb2x0aXBdPVwiY2hpcC5kaXNwbGF5ZWRDb250ZW50XCJcbiAgICAgICAgICBbbWF0VG9vbHRpcERpc2FibGVkXT1cImlzTGFyZ2VTY3JlZW5cIlxuICAgICAgICAgIFtkaXNhYmxlZF09XCJyZXNldEJ0bkNsaWNrZWQgfHwgcmVtb3ZpbmdDaGlwcy5pbmNsdWRlcyhjaGlwLm1vZGVsUmVmKVwiXG4gICAgICAgICAgKHJlbW92ZWQpPVwicmVtb3ZlQ2hpcChjaGlwKVwiXG4gICAgICAgID5cbiAgICAgICAgICB7eyBjaGlwLmRpc3BsYXllZENvbnRlbnQgfX1cbiAgICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgICBtYXRDaGlwUmVtb3ZlXG4gICAgICAgICAgICAoa2V5ZG93bi5lbnRlcik9XCJyZW1vdmVDaGlwKGNoaXApXCJcbiAgICAgICAgICAgIGFyaWEtaGlkZGVuPVwidHJ1ZVwiXG4gICAgICAgICAgPlxuICAgICAgICAgICAgPG1hdC1pY29uIHRhYmluZGV4PVwiMFwiPmNhbmNlbDwvbWF0LWljb24+XG4gICAgICAgICAgPC9idXR0b24+XG4gICAgICAgIDwvbWF0LWNoaXAtcm93PlxuICAgICAgICA8aW5wdXRcbiAgICAgICAgICBkaXNhYmxlQ29udHJvbFxuICAgICAgICAgIHR5cGU9XCJ0ZXh0XCJcbiAgICAgICAgICAjc2VhcmNoSW5wdXRcbiAgICAgICAgICBtYXRJbnB1dFxuICAgICAgICAgIGZvcm1Db250cm9sTmFtZT1cInNlYXJjaFwiXG4gICAgICAgICAgbWlubGVuZ3RoPVwiM1wiXG4gICAgICAgICAgW21hdENoaXBJbnB1dEZvcl09XCJjaGlwTGlzdFwiXG4gICAgICAgICAgW2Rpc2FibGVDb250cm9sXT1cIlxuICAgICAgICAgICAgYWR2YW5jZWRTZWFyY2hDaGlwcy5sZW5ndGggPiAwIHx8XG4gICAgICAgICAgICAobWVudVRyaWdnZXIgJiYgbWVudVRyaWdnZXIubWVudU9wZW4pIHx8XG4gICAgICAgICAgICByZXNldEJ0bkNsaWNrZWRcbiAgICAgICAgICBcIlxuICAgICAgICAgIGNsYXNzPVwic2VhcmNoLWlucHV0XCJcbiAgICAgICAgLz5cbiAgICAgIDwvbWF0LWNoaXAtZ3JpZD5cbiAgICAgIDxtYXQtaGludFxuICAgICAgICAjbWF0SGludFxuICAgICAgICAqbmdJZj1cIlxuICAgICAgICAgIHNlYXJjaElucHV0Py52YWx1ZT8ubGVuZ3RoIDwgMyAmJiBhZHZhbmNlZFNlYXJjaENoaXBzLmxlbmd0aCA9PT0gMDtcbiAgICAgICAgICBlbHNlIGFkdmFuY2VkU2VhcmNoQWN0aXZhdGVkXG4gICAgICAgIFwiXG4gICAgICA+XG4gICAgICAgIHt7IGFkdmFuY2VkU2VhcmNoQWNjZXNzaWJpbGl0eS5oaW50IH19XG4gICAgICA8L21hdC1oaW50PlxuICAgICAgPG5nLXRlbXBsYXRlICNhZHZhbmNlZFNlYXJjaEFjdGl2YXRlZD5cbiAgICAgICAgPG1hdC1oaW50ICNtYXRIaW50ICpuZ0lmPVwiYWR2YW5jZWRTZWFyY2hDaGlwcy5sZW5ndGggPiAwXCI+XG4gICAgICAgICAge3sgYWR2YW5jZWRTZWFyY2hBY2Nlc3NpYmlsaXR5LmFjdGl2YXRlZFNlYXJjaEhpbnQgfX1cbiAgICAgICAgPC9tYXQtaGludD5cbiAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICA8ZGl2IG1hdFN1ZmZpeCBjbGFzcz1cImRpdi1zZWFyY2gtc3VmZml4LWJ0blwiPlxuICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgKm5nSWY9XCJcbiAgICAgICAgICAgIHNlYXJjaElucHV0Py52YWx1ZT8ubGVuZ3RoID4gMCB8fCBhZHZhbmNlZFNlYXJjaENoaXBzPy5sZW5ndGggPiAwXG4gICAgICAgICAgXCJcbiAgICAgICAgICBbZGlzYWJsZWRdPVwicmVzZXRCdG5DbGlja2VkXCJcbiAgICAgICAgICBtYXQtaWNvbi1idXR0b25cbiAgICAgICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICAgICBbYXR0ci5hcmlhLWxhYmVsXT1cImFkdmFuY2VkU2VhcmNoQWNjZXNzaWJpbGl0eS5jbGVhclNlYXJjaFwiXG4gICAgICAgICAgKGNsaWNrKT1cIm9uUmVzZXRTZWFyY2hCdG5DbGljaygpXCJcbiAgICAgICAgICBjbGFzcz1cImNsZWFyLWlucHV0LWJ0blwiXG4gICAgICAgICAgW21hdFRvb2x0aXBdPVwiYWR2YW5jZWRTZWFyY2hBY2Nlc3NpYmlsaXR5LmNsZWFyU2VhcmNoXCJcbiAgICAgICAgPlxuICAgICAgICAgIDxtYXQtaWNvbiBhcmlhLWhpZGRlbj1cInRydWVcIj4gY2xlYXIgPC9tYXQtaWNvbj5cbiAgICAgICAgPC9idXR0b24+XG4gICAgICAgIDxidXR0b25cbiAgICAgICAgICAjbWVudVRyaWdnZXJCdG5cbiAgICAgICAgICAjbWVudVRyaWdnZXI9XCJtYXRNZW51VHJpZ2dlclwiXG4gICAgICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgICAgbWF0LWljb24tYnV0dG9uXG4gICAgICAgICAgW2F0dHIuYXJpYS1sYWJlbF09XCJcbiAgICAgICAgICAgIGFkdmFuY2VkU2VhcmNoQWNjZXNzaWJpbGl0eS5kaXNwbGF5QWR2YW5jZWRTZWFyY2hNZW51XG4gICAgICAgICAgXCJcbiAgICAgICAgICBbbWF0TWVudVRyaWdnZXJGb3JdPVwiYWR2YW5jZWRTZWFyY2hNZW51XCJcbiAgICAgICAgICBbZGlzYWJsZWRdPVwiXG4gICAgICAgICAgICBzZWFyY2hJbnB1dD8udmFsdWUubGVuZ3RoID4gMCB8fFxuICAgICAgICAgICAgcmVzZXRCdG5DbGlja2VkIHx8XG4gICAgICAgICAgICByZW1vdmluZ0NoaXBzLmxlbmd0aCA+IDBcbiAgICAgICAgICBcIlxuICAgICAgICAgIChtZW51T3BlbmVkKT1cInNldE1lbnVQYW5lbFBvc2l0aW9uKClcIlxuICAgICAgICAgIChjbGljayk9XCIkZXZlbnQuc3RvcFByb3BhZ2F0aW9uKClcIlxuICAgICAgICAgIGNsYXNzPVwidG9nZ2xlLWFkdmFuY2VkLXNlYXJjaC1tZW51LWJ0blwiXG4gICAgICAgICAgW21hdFRvb2x0aXBdPVwiYWR2YW5jZWRTZWFyY2hBY2Nlc3NpYmlsaXR5LmRpc3BsYXlBZHZhbmNlZFNlYXJjaE1lbnVcIlxuICAgICAgICA+XG4gICAgICAgICAgPG1hdC1pY29uXG4gICAgICAgICAgICBbbmdDbGFzc109XCJ7XG4gICAgICAgICAgICAgICd0b2dnbGUtYWR2YW5jZWQtc2VhcmNoLW1lbnUtaWNvbic6IG1lbnVUcmlnZ2VyLm1lbnVPcGVuXG4gICAgICAgICAgICB9XCJcbiAgICAgICAgICAgIGFyaWEtaGlkZGVuPVwidHJ1ZVwiXG4gICAgICAgICAgPlxuICAgICAgICAgICAgYXJyb3dfZHJvcF9kb3duXG4gICAgICAgICAgPC9tYXQtaWNvbj5cbiAgICAgICAgPC9idXR0b24+XG4gICAgICAgIDxtYXQtbWVudVxuICAgICAgICAgICNhZHZhbmNlZFNlYXJjaE1lbnU9XCJtYXRNZW51XCJcbiAgICAgICAgICBiYWNrZHJvcENsYXNzPVwiYWR2YW5jZWQtc2VhcmNoLW1lbnVcIlxuICAgICAgICA+XG4gICAgICAgICAgPG5nLXRlbXBsYXRlIG1hdE1lbnVDb250ZW50PlxuICAgICAgICAgICAgPGRpdlxuICAgICAgICAgICAgICBjbGFzcz1cImFkdmFuY2VkLXNlYXJjaC1tZW51LWNvbnRlbnRcIlxuICAgICAgICAgICAgICAoY2xpY2spPVwiJGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpXCJcbiAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgPGRtLWdlbmVyaWMtZm9ybVxuICAgICAgICAgICAgICAgIFtlbmFibGVDaGVja291dEZvcm1dPVwiaXNHZW5lcmljRm9ybUVuYWJsZVwiXG4gICAgICAgICAgICAgICAgW2Zvcm1EYXRhXT1cImZvcm1GaWVsZHNcIlxuICAgICAgICAgICAgICAgIFtjcnVkQWN0aW9uXT1cIidzZWFyY2gnXCJcbiAgICAgICAgICAgICAgICAoc3VibWl0Rm9ybSk9XCJvblN1Ym1pdCgpXCJcbiAgICAgICAgICAgICAgPjwvZG0tZ2VuZXJpYy1mb3JtPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgPC9tYXQtbWVudT5cbiAgICAgIDwvZGl2PlxuICAgIDwvbWF0LWZvcm0tZmllbGQ+XG4gIDwvZGl2PlxuPC9mb3JtPlxuIl19