ontimize-web-ngx
Version:
Ontimize Web framework using Angular 15
195 lines • 42.2 kB
JavaScript
import { __decorate, __metadata } from "tslib";
import { animate, state, style, transition, trigger } from '@angular/animations';
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, ElementRef, EventEmitter, Injector, ViewEncapsulation } from '@angular/core';
import { NavigationEnd, Router } from '@angular/router';
import { Subscription } from 'rxjs';
import { BooleanInputConverter, NumberInputConverter } from '../../../decorators/input-converter';
import { AppMenuService } from '../../../services/app-menu.service';
import { PermissionsService } from '../../../services/permissions/permissions.service';
import { OTranslateService } from '../../../services/translate/o-translate.service';
import { PermissionsUtils } from '../../../util/permissions';
import { Util } from '../../../util/util';
import { OAppSidenavBase } from '../o-app-sidenav-base.class';
import { OAppLayoutBase } from '../../../layouts/app-layout/o-app-layout-base.class';
import * as i0 from "@angular/core";
import * as i1 from "@angular/common";
import * as i2 from "@angular/flex-layout/flex";
import * as i3 from "@angular/material/button";
import * as i4 from "@angular/material/icon";
import * as i5 from "@angular/material/tooltip";
import * as i6 from "../menu-item/o-app-sidenav-menu-item.component";
import * as i7 from "../../../pipes/o-translate.pipe";
export const DEFAULT_INPUTS_O_APP_SIDENAV_MENU_GROUP = [
'menuGroup : menu-group',
'sidenavOpened : sidenav-opened',
'level'
];
export const DEFAULT_OUTPUTS_O_APP_SIDENAV_MENU_GROUP = [
'onItemClick'
];
export class OAppSidenavMenuGroupComponent {
constructor(injector, elRef, cd) {
this.injector = injector;
this.elRef = elRef;
this.cd = cd;
this.onItemClick = new EventEmitter();
this.onClickEvent = new EventEmitter();
this.sidenavSubscription = new Subscription();
this.sidenavOpened = true;
this.level = 1;
this.translateService = this.injector.get(OTranslateService);
this.appMenuService = this.injector.get(AppMenuService);
this.permissionsService = this.injector.get(PermissionsService);
this.sidenav = this.injector.get(OAppSidenavBase);
this.router = this.injector.get(Router);
this.oAppLayoutComponent = this.injector.get(OAppLayoutBase);
this.routerSubscription = this.router.events.subscribe((event) => {
if (event instanceof NavigationEnd && this.appMenuService.isRouteItem(this.menuGroup)) {
this.active = this.appMenuService.isItemActive(this.menuGroup);
this.cd.detectChanges();
}
});
}
ngOnInit() {
this.parsePermissions();
}
get shouldShowTooltip() {
switch (this.oAppLayoutComponent.tooltipDisplayMode) {
case 'always':
return true;
case 'never':
return false;
case 'only-collapsed':
return !this.sidenavOpened;
case 'only-expanded':
return this.sidenavOpened;
default:
return false;
}
}
ngAfterViewInit() {
if (this.menuGroup.id === 'user-info' && this.sidenav) {
const self = this;
this.sidenavSubscription.add(this.sidenav.onSidenavOpenedChange.subscribe((opened) => {
self.disabled = ((!opened && Util.isDefined(opened)) || (Util.isDefined(self.permissions) && self.permissions && self.permissions.enabled === false));
self.updateContentExpansion();
self.cd.markForCheck();
}));
}
this.updateContentExpansion();
}
ngOnDestroy() {
if (this.sidenavSubscription) {
this.sidenavSubscription.unsubscribe();
}
if (this.routerSubscription) {
this.routerSubscription.unsubscribe();
}
}
parsePermissions() {
this.permissions = this.permissionsService.getMenuPermissions(this.menuGroup.id);
if (!Util.isDefined(this.permissions)) {
return;
}
this.hidden = this.permissions.visible === false;
this.disabled = this.permissions.enabled === false;
if (this.disabled) {
this.mutationObserver = PermissionsUtils.registerDisabledChangesInDom(this.elRef.nativeElement, {
checkStringValue: true
});
}
}
onClick() {
if (this.disabled) {
return;
}
if (this.appMenuService.isMenuGroup(this.menuGroup) ||
this.appMenuService.isMenuGroupRoute(this.menuGroup) && (!this.menuGroup.opened)) {
this.toggle();
}
this.navigate();
}
toggle(event) {
if (event) {
event.stopPropagation();
event.preventDefault();
}
this.menuGroup.opened = !this.menuGroup.opened;
this.appMenuService.onClick.next({
idMenu: this.menuGroup.id,
opened: this.menuGroup.opened
});
this.updateContentExpansion();
}
navigate() {
if (this.appMenuService.isMenuGroupRoute(this.menuGroup)) {
const route = this.menuGroup.route;
if (this.router.url !== route) {
this.router.navigate([route]);
}
}
}
updateContentExpansion() {
let isOpened = this.menuGroup && this.menuGroup.opened;
if (this.menuGroup.id === 'user-info') {
isOpened = (this.sidenav && this.sidenav.sidenav && this.sidenav.sidenav.opened) && isOpened;
}
this.contentExpansion = isOpened ? 'expanded' : 'collapsed';
}
get contentExpansion() {
return this._contentExpansion;
}
set contentExpansion(val) {
this._contentExpansion = val;
this.cd.detectChanges();
}
get tooltip() {
let result = this.translateService.get(this.menuGroup.name);
if (Util.isDefined(this.menuGroup.tooltip)) {
result += ': ' + this.translateService.get(this.menuGroup.tooltip);
}
return result;
}
onMenuItemClick(e) {
this.onItemClick.emit(e);
}
getClass() {
let className = 'o-app-sidenav-menu-group o-app-sidenav-menu-group-level-' + this.level;
if (this.menuGroup.class) {
className += ' ' + this.menuGroup.class;
}
return className;
}
}
OAppSidenavMenuGroupComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: OAppSidenavMenuGroupComponent, deps: [{ token: i0.Injector }, { token: i0.ElementRef }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
OAppSidenavMenuGroupComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: OAppSidenavMenuGroupComponent, selector: "o-app-sidenav-menu-group", inputs: { menuGroup: ["menu-group", "menuGroup"], sidenavOpened: ["sidenav-opened", "sidenavOpened"], level: "level" }, outputs: { onItemClick: "onItemClick" }, host: { properties: { "class": "getClass()", "attr.disabled": "disabled" } }, ngImport: i0, template: "<ng-container *ngIf=\"!hidden\">\n <ng-container *ngIf=\"shouldShowTooltip; else noTooltip\">\n <a mat-button mat-button class=\"o-app-sidenav-item o-app-sidenav-menugroup\" [class.opened]=\"menuGroup.opened\" (click)=\"onClick()\"\n [class.o-app-sidenav-viewer-sidenav-item-selected]=\"active\" [matTooltip]=\"tooltip\" matTooltipClass=\"menugroup-tooltip\"\n matTooltipPosition=\"right\" [matTooltipShowDelay]=\"sidenavOpened?500:0\">\n <ng-container *ngTemplateOutlet=\"contentButton\"></ng-container>\n </a>\n </ng-container>\n\n\n <div class=\"o-app-sidenav-menugroup-items-container\">\n <ul [@contentExpansion]=\"contentExpansion\" class=\"o-app-sidenav-menugroup-ul\">\n <ng-container *ngFor=\"let menuItem of menuGroup.items\">\n <ng-container *ngIf=\"appMenuService.isVisible(menuItem)\">\n <o-app-sidenav-menu-item [sidenav-opened]=\"sidenavOpened\" *ngIf=\"!menuItem.items; else menuGroup\" [disabled]=\"disabled\"\n [menu-item]=\"menuItem\" [menu-item-type]=\"appMenuService.getMenuItemType(menuItem)\" (onClick)=\"onMenuItemClick($event)\">\n </o-app-sidenav-menu-item>\n <ng-template #menuGroup>\n <o-app-sidenav-menu-group [menu-group]=\"menuItem\" [sidenav-opened]=\"sidenavOpened\" [level]=\"level + 1\"\n *ngIf=\"appMenuService.getMenuItemType(menuItem) === 'group'\" (onItemClick)=\"onMenuItemClick($event)\">\n </o-app-sidenav-menu-group>\n </ng-template>\n </ng-container>\n </ng-container>\n </ul>\n </div>\n</ng-container>\n\n<ng-template #noTooltip>\n <a mat-button mat-button class=\"o-app-sidenav-item o-app-sidenav-menugroup\" [class.opened]=\"menuGroup.opened\" (click)=\"onClick()\"\n [class.o-app-sidenav-viewer-sidenav-item-selected]=\"active\">\n <ng-container *ngTemplateOutlet=\"contentButton\"></ng-container>\n </a>\n</ng-template>\n\n<ng-template #contentButton>\n <div fxLayout=\"row\" fxLayoutAlign=\"start center\" fxFill>\n <ng-container *ngIf=\"sidenavOpened\">\n <mat-icon *ngIf=\"menuGroup.svgIcon\" [svgIcon]=\"menuGroup.svgIcon\"></mat-icon>\n <mat-icon *ngIf=\"menuGroup.icon\">{{ menuGroup.icon }}</mat-icon>\n <span class=\"o-app-sidenav-menugroup-title\">{{ menuGroup.name | oTranslate }}</span>\n <span class=\"fill-remaining\"></span>\n <ng-container *ngIf=\"appMenuService.isMenuGroupRoute(menuGroup) && menuGroup.opened; else arrowMenuGroupTemplate\">\n <mat-icon [id]=\"'arrow_icon_' + menuGroup.id\" class=\"o-app-sidenav-menugroup-arrow\" svgIcon=\"ontimize:keyboard_arrow_right\"\n (click)=\"toggle($event)\"\n (keydown)=\"toggle($event)\"></mat-icon>\n </ng-container>\n <ng-template #arrowMenuGroupTemplate>\n <mat-icon [id]=\"'arrow_icon_' + menuGroup.id\" class=\"o-app-sidenav-menugroup-arrow\" svgIcon=\"ontimize:keyboard_arrow_right\"></mat-icon>\n </ng-template>\n </ng-container>\n <ng-container *ngIf=\"!sidenavOpened\">\n <mat-icon *ngIf=\"menuGroup.svgIcon\" [svgIcon]=\"menuGroup.svgIcon\"></mat-icon> <mat-icon *ngIf=\"menuGroup.icon\">{{ menuGroup.icon }}</mat-icon>\n </ng-container>\n </div>\n</ng-template>\n", styles: [".o-app-sidenav-menu-group .o-app-sidenav-menugroup.mat-mdc-button{min-width:0}.o-app-sidenav-menu-group[disabled=true] .o-app-sidenav-menugroup{cursor:default}.o-app-sidenav-menu-group .mat-mdc-tooltip.menugroup-tooltip{margin-left:28px}\n"], dependencies: [{ kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i2.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: i2.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: i2.FlexFillDirective, selector: "[fxFill], [fxFlexFill]" }, { kind: "component", type: i3.MatAnchor, selector: "a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button]", inputs: ["disabled", "disableRipple", "color", "tabIndex"], exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i4.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: i5.MatTooltip, selector: "[matTooltip]", exportAs: ["matTooltip"] }, { kind: "component", type: OAppSidenavMenuGroupComponent, selector: "o-app-sidenav-menu-group", inputs: ["menu-group", "sidenav-opened", "level"], outputs: ["onItemClick"] }, { kind: "component", type: i6.OAppSidenavMenuItemComponent, selector: "o-app-sidenav-menu-item", inputs: ["menu-item", "menu-item-type", "sidenav-opened", "disabled"], outputs: ["onClick"] }, { kind: "pipe", type: i7.OTranslatePipe, name: "oTranslate" }], animations: [
trigger('contentExpansion', [
state('collapsed', style({ height: '0px' })),
state('expanded', style({ height: '*' })),
transition('collapsed => expanded', animate('200ms ease-in')),
transition('expanded => collapsed', animate('200ms ease-out'))
])
], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
__decorate([
BooleanInputConverter(),
__metadata("design:type", Boolean)
], OAppSidenavMenuGroupComponent.prototype, "sidenavOpened", void 0);
__decorate([
NumberInputConverter(),
__metadata("design:type", Number)
], OAppSidenavMenuGroupComponent.prototype, "level", void 0);
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: OAppSidenavMenuGroupComponent, decorators: [{
type: Component,
args: [{ selector: 'o-app-sidenav-menu-group', inputs: DEFAULT_INPUTS_O_APP_SIDENAV_MENU_GROUP, outputs: DEFAULT_OUTPUTS_O_APP_SIDENAV_MENU_GROUP, encapsulation: ViewEncapsulation.None, animations: [
trigger('contentExpansion', [
state('collapsed', style({ height: '0px' })),
state('expanded', style({ height: '*' })),
transition('collapsed => expanded', animate('200ms ease-in')),
transition('expanded => collapsed', animate('200ms ease-out'))
])
], changeDetection: ChangeDetectionStrategy.OnPush, host: {
'[class]': 'getClass()',
'[attr.disabled]': 'disabled'
}, template: "<ng-container *ngIf=\"!hidden\">\n <ng-container *ngIf=\"shouldShowTooltip; else noTooltip\">\n <a mat-button mat-button class=\"o-app-sidenav-item o-app-sidenav-menugroup\" [class.opened]=\"menuGroup.opened\" (click)=\"onClick()\"\n [class.o-app-sidenav-viewer-sidenav-item-selected]=\"active\" [matTooltip]=\"tooltip\" matTooltipClass=\"menugroup-tooltip\"\n matTooltipPosition=\"right\" [matTooltipShowDelay]=\"sidenavOpened?500:0\">\n <ng-container *ngTemplateOutlet=\"contentButton\"></ng-container>\n </a>\n </ng-container>\n\n\n <div class=\"o-app-sidenav-menugroup-items-container\">\n <ul [@contentExpansion]=\"contentExpansion\" class=\"o-app-sidenav-menugroup-ul\">\n <ng-container *ngFor=\"let menuItem of menuGroup.items\">\n <ng-container *ngIf=\"appMenuService.isVisible(menuItem)\">\n <o-app-sidenav-menu-item [sidenav-opened]=\"sidenavOpened\" *ngIf=\"!menuItem.items; else menuGroup\" [disabled]=\"disabled\"\n [menu-item]=\"menuItem\" [menu-item-type]=\"appMenuService.getMenuItemType(menuItem)\" (onClick)=\"onMenuItemClick($event)\">\n </o-app-sidenav-menu-item>\n <ng-template #menuGroup>\n <o-app-sidenav-menu-group [menu-group]=\"menuItem\" [sidenav-opened]=\"sidenavOpened\" [level]=\"level + 1\"\n *ngIf=\"appMenuService.getMenuItemType(menuItem) === 'group'\" (onItemClick)=\"onMenuItemClick($event)\">\n </o-app-sidenav-menu-group>\n </ng-template>\n </ng-container>\n </ng-container>\n </ul>\n </div>\n</ng-container>\n\n<ng-template #noTooltip>\n <a mat-button mat-button class=\"o-app-sidenav-item o-app-sidenav-menugroup\" [class.opened]=\"menuGroup.opened\" (click)=\"onClick()\"\n [class.o-app-sidenav-viewer-sidenav-item-selected]=\"active\">\n <ng-container *ngTemplateOutlet=\"contentButton\"></ng-container>\n </a>\n</ng-template>\n\n<ng-template #contentButton>\n <div fxLayout=\"row\" fxLayoutAlign=\"start center\" fxFill>\n <ng-container *ngIf=\"sidenavOpened\">\n <mat-icon *ngIf=\"menuGroup.svgIcon\" [svgIcon]=\"menuGroup.svgIcon\"></mat-icon>\n <mat-icon *ngIf=\"menuGroup.icon\">{{ menuGroup.icon }}</mat-icon>\n <span class=\"o-app-sidenav-menugroup-title\">{{ menuGroup.name | oTranslate }}</span>\n <span class=\"fill-remaining\"></span>\n <ng-container *ngIf=\"appMenuService.isMenuGroupRoute(menuGroup) && menuGroup.opened; else arrowMenuGroupTemplate\">\n <mat-icon [id]=\"'arrow_icon_' + menuGroup.id\" class=\"o-app-sidenav-menugroup-arrow\" svgIcon=\"ontimize:keyboard_arrow_right\"\n (click)=\"toggle($event)\"\n (keydown)=\"toggle($event)\"></mat-icon>\n </ng-container>\n <ng-template #arrowMenuGroupTemplate>\n <mat-icon [id]=\"'arrow_icon_' + menuGroup.id\" class=\"o-app-sidenav-menugroup-arrow\" svgIcon=\"ontimize:keyboard_arrow_right\"></mat-icon>\n </ng-template>\n </ng-container>\n <ng-container *ngIf=\"!sidenavOpened\">\n <mat-icon *ngIf=\"menuGroup.svgIcon\" [svgIcon]=\"menuGroup.svgIcon\"></mat-icon> <mat-icon *ngIf=\"menuGroup.icon\">{{ menuGroup.icon }}</mat-icon>\n </ng-container>\n </div>\n</ng-template>\n", styles: [".o-app-sidenav-menu-group .o-app-sidenav-menugroup.mat-mdc-button{min-width:0}.o-app-sidenav-menu-group[disabled=true] .o-app-sidenav-menugroup{cursor:default}.o-app-sidenav-menu-group .mat-mdc-tooltip.menugroup-tooltip{margin-left:28px}\n"] }]
}], ctorParameters: function () { return [{ type: i0.Injector }, { type: i0.ElementRef }, { type: i0.ChangeDetectorRef }]; }, propDecorators: { sidenavOpened: [], level: [] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiby1hcHAtc2lkZW5hdi1tZW51LWdyb3VwLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL29udGltaXplLXdlYi1uZ3gvc3JjL2xpYi9jb21wb25lbnRzL2FwcC1zaWRlbmF2L21lbnUtZ3JvdXAvby1hcHAtc2lkZW5hdi1tZW51LWdyb3VwLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL29udGltaXplLXdlYi1uZ3gvc3JjL2xpYi9jb21wb25lbnRzL2FwcC1zaWRlbmF2L21lbnUtZ3JvdXAvby1hcHAtc2lkZW5hdi1tZW51LWdyb3VwLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQSxPQUFPLEVBQUUsT0FBTyxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsVUFBVSxFQUFFLE9BQU8sRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBQ2pGLE9BQU8sRUFFTCx1QkFBdUIsRUFDdkIsaUJBQWlCLEVBQ2pCLFNBQVMsRUFDVCxVQUFVLEVBQ1YsWUFBWSxFQUNaLFFBQVEsRUFJUixpQkFBaUIsRUFDbEIsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUN4RCxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBRXBDLE9BQU8sRUFBRSxxQkFBcUIsRUFBRSxvQkFBb0IsRUFBRSxNQUFNLHFDQUFxQyxDQUFDO0FBRWxHLE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSxvQ0FBb0MsQ0FBQztBQUNwRSxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSxtREFBbUQsQ0FBQztBQUN2RixPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxpREFBaUQsQ0FBQztBQUVwRixPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQztBQUM3RCxPQUFPLEVB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QUNFLDBCQUEwQixVQUM1Qix1Q0FBdUMsV0FDdEMsd0NBQXdDLGlCQUdsQyxpQkFBaUIsQ0FBQyxJQUFJLGNBQ3pCO3dCQUNWLE9BQU8sQ0FBQyxrQkFBa0IsRUFBRTs0QkFDMUIsS0FBSyxDQUFDLFdBQVcsRUFBRSxLQUFLLENBQUMsRUFBRSxNQUFNLEVBQUUsS0FBSyxFQUFFLENBQUMsQ0FBQzs0QkFDNUMsS0FBSyxDQUFDLFVBQVUsRUFBRSxLQUFLLENBQUMsRUFBRSxNQUFNLEVBQUUsR0FBRyxFQUFFLENBQUMsQ0FBQzs0QkFDekMsVUFBVSxDQUFDLHVCQUF1QixFQUFFLE9BQU8sQ0FBQyxlQUFlLENBQUMsQ0FBQzs0QkFDN0QsVUFBVSxDQUFDLHVCQUF1QixFQUFFLE9BQU8sQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO3lCQUMvRCxDQUFDO3FCQUNILG1CQUNnQix1QkFBdUIsQ0FBQyxNQUFNLFFBQ3pDO3dCQUNKLFNBQVMsRUFBRSxZQUFZO3dCQUN2QixpQkFBaUIsRUFBRSxVQUFVO3FCQUM5Qjt3SkFtQkQsYUFBYSxNQUdiLEtBQUsiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBhbmltYXRlLCBzdGF0ZSwgc3R5bGUsIHRyYW5zaXRpb24sIHRyaWdnZXIgfSBmcm9tICdAYW5ndWxhci9hbmltYXRpb25zJztcbmltcG9ydCB7XG4gIEFmdGVyVmlld0luaXQsXG4gIENoYW5nZURldGVjdGlvblN0cmF0ZWd5LFxuICBDaGFuZ2VEZXRlY3RvclJlZixcbiAgQ29tcG9uZW50LFxuICBFbGVtZW50UmVmLFxuICBFdmVudEVtaXR0ZXIsXG4gIEluamVjdG9yLFxuICBPbkRlc3Ryb3ksXG4gIE9uSW5pdCxcbiAgVHlwZSxcbiAgVmlld0VuY2Fwc3VsYXRpb25cbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBOYXZpZ2F0aW9uRW5kLCBSb3V0ZXIgfSBmcm9tICdAYW5ndWxhci9yb3V0ZXInO1xuaW1wb3J0IHsgU3Vic2NyaXB0aW9uIH0gZnJvbSAncnhqcyc7XG5cbmltcG9ydCB7IEJvb2xlYW5JbnB1dENvbnZlcnRlciwgTnVtYmVySW5wdXRDb252ZXJ0ZXIgfSBmcm9tICcuLi8uLi8uLi9kZWNvcmF0b3JzL2lucHV0LWNvbnZlcnRlcic7XG5pbXBvcnQgeyBNZW51R3JvdXAsIE1lbnVHcm91cFJvdXRlIH0gZnJvbSAnLi4vLi4vLi4vaW50ZXJmYWNlcy9hcHAtbWVudS5pbnRlcmZhY2UnO1xuaW1wb3J0IHsgQXBwTWVudVNlcnZpY2UgfSBmcm9tICcuLi8uLi8uLi9zZXJ2aWNlcy9hcHAtbWVudS5zZXJ2aWNlJztcbmltcG9ydCB7IFBlcm1pc3Npb25zU2VydmljZSB9IGZyb20gJy4uLy4uLy4uL3NlcnZpY2VzL3Blcm1pc3Npb25zL3Blcm1pc3Npb25zLnNlcnZpY2UnO1xuaW1wb3J0IHsgT1RyYW5zbGF0ZVNlcnZpY2UgfSBmcm9tICcuLi8uLi8uLi9zZXJ2aWNlcy90cmFuc2xhdGUvby10cmFuc2xhdGUuc2VydmljZSc7XG5pbXBvcnQgeyBPUGVybWlzc2lvbnMgfSBmcm9tICcuLi8uLi8uLi90eXBlcy9vLXBlcm1pc3Npb25zLnR5cGUnO1xuaW1wb3J0IHsgUGVybWlzc2lvbnNVdGlscyB9IGZyb20gJy4uLy4uLy4uL3V0aWwvcGVybWlzc2lvbnMnO1xuaW1wb3J0IHsgVXRpbCB9IGZyb20gJy4uLy4uLy4uL3V0aWwvdXRpbCc7XG5pbXBvcnQgeyBPQXBwU2lkZW5hdkJhc2UgfSBmcm9tICcuLi9vLWFwcC1zaWRlbmF2LWJhc2UuY2xhc3MnO1xuaW1wb3J0IHsgT0FwcExheW91dEJhc2UgfSBmcm9tICcuLi8uLi8uLi9sYXlvdXRzL2FwcC1sYXlvdXQvby1hcHAtbGF5b3V0LWJhc2UuY2xhc3MnO1xuXG5leHBvcnQgY29uc3QgREVGQVVMVF9JTlBVVFNfT19BUFBfU0lERU5BVl9NRU5VX0dST1VQID0gW1xuICAnbWVudUdyb3VwIDogbWVudS1ncm91cCcsXG4gICdzaWRlbmF2T3BlbmVkIDogc2lkZW5hdi1vcGVuZWQnLFxuICAnbGV2ZWwnXG5dO1xuXG5leHBvcnQgY29uc3QgREVGQVVMVF9PVVRQVVRTX09fQVBQX1NJREVOQVZfTUVOVV9HUk9VUCA9IFtcbiAgJ29uSXRlbUNsaWNrJ1xuXTtcblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnby1hcHAtc2lkZW5hdi1tZW51LWdyb3VwJyxcbiAgaW5wdXRzOiBERUZBVUxUX0lOUFVUU19PX0FQUF9TSURFTkFWX01FTlVfR1JPVVAsXG4gIG91dHB1dHM6IERFRkFVTFRfT1VUUFVUU19PX0FQUF9TSURFTkFWX01FTlVfR1JPVVAsXG4gIHRlbXBsYXRlVXJsOiAnLi9vLWFwcC1zaWRlbmF2LW1lbnUtZ3JvdXAuY29tcG9uZW50Lmh0bWwnLFxuICBzdHlsZVVybHM6IFsnLi9vLWFwcC1zaWRlbmF2LW1lbnUtZ3JvdXAuY29tcG9uZW50LnNjc3MnXSxcbiAgZW5jYXBzdWxhdGlvbjogVmlld0VuY2Fwc3VsYXRpb24uTm9uZSxcbiAgYW5pbWF0aW9uczogW1xuICAgIHRyaWdnZXIoJ2NvbnRlbnRFeHBhbnNpb24nLCBbXG4gICAgICBzdGF0ZSgnY29sbGFwc2VkJywgc3R5bGUoeyBoZWlnaHQ6ICcwcHgnIH0pKSxcbiAgICAgIHN0YXRlKCdleHBhbmRlZCcsIHN0eWxlKHsgaGVpZ2h0OiAnKicgfSkpLFxuICAgICAgdHJhbnNpdGlvbignY29sbGFwc2VkID0+IGV4cGFuZGVkJywgYW5pbWF0ZSgnMjAwbXMgZWFzZS1pbicpKSxcbiAgICAgIHRyYW5zaXRpb24oJ2V4cGFuZGVkID0+IGNvbGxhcHNlZCcsIGFuaW1hdGUoJzIwMG1zIGVhc2Utb3V0JykpXG4gICAgXSlcbiAgXSxcbiAgY2hhbmdlRGV0ZWN0aW9uOiBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneS5PblB1c2gsXG4gIGhvc3Q6IHtcbiAgICAnW2NsYXNzXSc6ICdnZXRDbGFzcygpJyxcbiAgICAnW2F0dHIuZGlzYWJsZWRdJzogJ2Rpc2FibGVkJ1xuICB9XG59KVxuZXhwb3J0IGNsYXNzIE9BcHBTaWRlbmF2TWVudUdyb3VwQ29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0LCBBZnRlclZpZXdJbml0LCBPbkRlc3Ryb3kge1xuXG4gIHB1YmxpYyBvbkl0ZW1DbGljazogRXZlbnRFbWl0dGVyPGFueT4gPSBuZXcgRXZlbnRFbWl0dGVyPGFueT4oKTtcbiAgcHVibGljIG9uQ2xpY2tFdmVudDogRXZlbnRFbWl0dGVyPGFueT4gPSBuZXcgRXZlbnRFbWl0dGVyPGFueT4oKTtcblxuICBwcm90ZWN0ZWQgdHJhbnNsYXRlU2VydmljZTogT1RyYW5zbGF0ZVNlcnZpY2U7XG4gIHByb3RlY3RlZCBwZXJtaXNzaW9uc1NlcnZpY2U6IFBlcm1pc3Npb25zU2VydmljZTtcblxuICBwdWJsaWMgYXBwTWVudVNlcnZpY2U6IEFwcE1lbnVTZXJ2aWNlO1xuICBwdWJsaWMgc2lkZW5hdjogT0FwcFNpZGVuYXZCYXNlO1xuICBwcm90ZWN0ZWQgc2lkZW5hdlN1YnNjcmlwdGlvbjogU3Vic2NyaXB0aW9uID0gbmV3IFN1YnNjcmlwdGlvbigpO1xuICBwcm90ZWN0ZWQgcGVybWlzc2lvbnM6IE9QZXJtaXNzaW9ucztcbiAgcHJvdGVjdGVkIG11dGF0aW9uT2JzZXJ2ZXI6IE11dGF0aW9uT2JzZXJ2ZXI7XG5cbiAgcHVibGljIG1lbnVHcm91cDogKE1lbnVHcm91cCB8IE1lbnVHcm91cFJvdXRlKTtcblxuICBAQm9vbGVhbklucHV0Q29udmVydGVyKClcbiAgc2lkZW5hdk9wZW5lZDogYm9vbGVhbiA9IHRydWU7XG5cbiAgQE51bWJlcklucHV0Q29udmVydGVyKClcbiAgbGV2ZWw6IG51bWJlciA9IDE7XG5cbiAgaGlkZGVuOiBib29sZWFuO1xuICBkaXNhYmxlZDogYm9vbGVhbjtcbiAgcHJvdGVjdGVkIF9jb250ZW50RXhwYW5zaW9uO1xuICBwcm90ZWN0ZWQgcm91dGVyOiBSb3V0ZXI7XG4gIHJvdXRlclN1YnNjcmlwdGlvbjogU3Vic2NyaXB0aW9uO1xuICBhY3RpdmU6IGJvb2xlYW47XG4gIG9BcHBMYXlvdXRDb21wb25lbnQ6IE9BcHBMYXlvdXRCYXNlO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHByb3RlY3RlZCBpbmplY3RvcjogSW5qZWN0b3IsXG4gICAgcHJvdGVjdGVkIGVsUmVmOiBFbGVtZW50UmVmLFxuICAgIHByb3RlY3RlZCBjZDogQ2hhbmdlRGV0ZWN0b3JSZWZcbiAgKSB7XG4gICAgdGhpcy50cmFuc2xhdGVTZXJ2aWNlID0gdGhpcy5pbmplY3Rvci5nZXQoT1RyYW5zbGF0ZVNlcnZpY2UpO1xuICAgIHRoaXMuYXBwTWVudVNlcnZpY2UgPSB0aGlzLmluamVjdG9yLmdldChBcHBNZW51U2VydmljZSk7XG4gICAgdGhpcy5wZXJtaXNzaW9uc1NlcnZpY2UgPSB0aGlzLmluamVjdG9yLmdldChQZXJtaXNzaW9uc1NlcnZpY2UpO1xuICAgIHRoaXMuc2lkZW5hdiA9IHRoaXMuaW5qZWN0b3IuZ2V0KE9BcHBTaWRlbmF2QmFzZSk7XG4gICAgdGhpcy5yb3V0ZXIgPSB0aGlzLmluamVjdG9yLmdldDxSb3V0ZXI+KFJvdXRlciBhcyBUeXBlPFJvdXRlcj4pO1xuICAgIHRoaXMub0FwcExheW91dENvbXBvbmVudCA9IHRoaXMuaW5qZWN0b3IuZ2V0PE9BcHBMYXlvdXRCYXNlPihPQXBwTGF5b3V0QmFzZSBhcyBUeXBlPE9BcHBMYXlvdXRCYXNlPik7XG4gICAgdGhpcy5yb3V0ZXJTdWJzY3JpcHRpb24gPSB0aGlzLnJvdXRlci5ldmVudHMuc3Vic2NyaWJlKChldmVudCkgPT4ge1xuICAgICAgaWYgKGV2ZW50IGluc3RhbmNlb2YgTmF2aWdhdGlvbkVuZCAmJiB0aGlzLmFwcE1lbnVTZXJ2aWNlLmlzUm91dGVJdGVtKHRoaXMubWVudUdyb3VwKSkge1xuICAgICAgICB0aGlzLmFjdGl2ZSA9IHRoaXMuYXBwTWVudVNlcnZpY2UuaXNJdGVtQWN0aXZlKHRoaXMubWVudUdyb3VwIGFzIE1lbnVHcm91cFJvdXRlKTtcbiAgICAgICAgdGhpcy5jZC5kZXRlY3RDaGFuZ2VzKCk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICBuZ09uSW5pdCgpIHtcbiAgICB0aGlzLnBhcnNlUGVybWlzc2lvbnMoKTtcbiAgfVxuXG4gIGdldCBzaG91bGRTaG93VG9vbHRpcCgpIHtcbiAgICBzd2l0Y2ggKHRoaXMub0FwcExheW91dENvbXBvbmVudC50b29sdGlwRGlzcGxheU1vZGUpIHtcbiAgICAgIGNhc2UgJ2Fsd2F5cyc6XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgY2FzZSAnbmV2ZXInOlxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICBjYXNlICdvbmx5LWNvbGxhcHNlZCc6XG4gICAgICAgIHJldHVybiAhdGhpcy5zaWRlbmF2T3BlbmVkO1xuICAgICAgY2FzZSAnb25seS1leHBhbmRlZCc6XG4gICAgICAgIHJldHVybiB0aGlzLnNpZGVuYXZPcGVuZWQ7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9XG5cbiAgbmdBZnRlclZpZXdJbml0KCkge1xuICAgIGlmICh0aGlzLm1lbnVHcm91cC5pZCA9PT0gJ3VzZXItaW5mbycgJiYgdGhpcy5zaWRlbmF2KSB7XG4gICAgICBjb25zdCBzZWxmID0gdGhpcztcbiAgICAgIHRoaXMuc2lkZW5hdlN1YnNjcmlwdGlvbi5hZGQodGhpcy5zaWRlbmF2Lm9uU2lkZW5hdk9wZW5lZENoYW5nZS5zdWJzY3JpYmUoKG9wZW5lZCkgPT4ge1xuICAgICAgICBzZWxmLmRpc2FibGVkID0gKCghb3BlbmVkICYmIFV0aWwuaXNEZWZpbmVkKG9wZW5lZCkpIHx8IChVdGlsLmlzRGVmaW5lZChzZWxmLnBlcm1pc3Npb25zKSAmJiBzZWxmLnBlcm1pc3Npb25zICYmIHNlbGYucGVybWlzc2lvbnMuZW5hYmxlZCA9PT0gZmFsc2UpKTtcbiAgICAgICAgc2VsZi51cGRhdGVDb250ZW50RXhwYW5zaW9uKCk7XG4gICAgICAgIHNlbGYuY2QubWFya0ZvckNoZWNrKCk7XG4gICAgICB9KSk7XG4gICAgfVxuICAgIHRoaXMudXBkYXRlQ29udGVudEV4cGFuc2lvbigpO1xuICB9XG5cbiAgbmdPbkRlc3Ryb3koKSB7XG4gICAgaWYgKHRoaXMuc2lkZW5hdlN1YnNjcmlwdGlvbikge1xuICAgICAgdGhpcy5zaWRlbmF2U3Vic2NyaXB0aW9uLnVuc3Vic2NyaWJlKCk7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMucm91dGVyU3Vic2NyaXB0aW9uKSB7XG4gICAgICB0aGlzLnJvdXRlclN1YnNjcmlwdGlvbi51bnN1YnNjcmliZSgpO1xuICAgIH1cbiAgfVxuXG4gIHByb3RlY3RlZCBwYXJzZVBlcm1pc3Npb25zKCkge1xuICAgIC8vIGlmIG9hdHRyIGluIGZvcm0sIGl0IGNhbiBoYXZlIHBlcm1pc3Npb25zXG4gICAgdGhpcy5wZXJtaXNzaW9ucyA9IHRoaXMucGVybWlzc2lvbnNTZXJ2aWNlLmdldE1lbnVQZXJtaXNzaW9ucyh0aGlzLm1lbnVHcm91cC5pZCk7XG4gICAgaWYgKCFVdGlsLmlzRGVmaW5lZCh0aGlzLnBlcm1pc3Npb25zKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLmhpZGRlbiA9IHRoaXMucGVybWlzc2lvbnMudmlzaWJsZSA9PT0gZmFsc2U7XG4gICAgdGhpcy5kaXNhYmxlZCA9IHRoaXMucGVybWlzc2lvbnMuZW5hYmxlZCA9PT0gZmFsc2U7XG5cbiAgICBpZiAodGhpcy5kaXNhYmxlZCkge1xuICAgICAgdGhpcy5tdXRhdGlvbk9ic2VydmVyID0gUGVybWlzc2lvbnNVdGlscy5yZWdpc3RlckRpc2FibGVkQ2hhbmdlc0luRG9tKHRoaXMuZWxSZWYubmF0aXZlRWxlbWVudCwge1xuICAgICAgICBjaGVja1N0cmluZ1ZhbHVlOiB0cnVlXG4gICAgICB9KTtcbiAgICB9XG4gIH1cblxuICBvbkNsaWNrKCkge1xuICAgIGlmICh0aGlzLmRpc2FibGVkKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmICh0aGlzLmFwcE1lbnVTZXJ2aWNlLmlzTWVudUdyb3VwKHRoaXMubWVudUdyb3VwKSB8fFxuICAgICAgdGhpcy5hcHBNZW51U2VydmljZS5pc01lbnVHcm91cFJvdXRlKHRoaXMubWVudUdyb3VwKSAmJiAoIXRoaXMubWVudUdyb3VwLm9wZW5lZCkpIHtcbiAgICAgIHRoaXMudG9nZ2xlKCk7XG4gICAgfVxuICAgIHRoaXMubmF2aWdhdGUoKTtcbiAgfVxuXG4gIHRvZ2dsZShldmVudD86IEV2ZW50KTogdm9pZCB7XG4gICAgaWYgKGV2ZW50KSB7XG4gICAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgfVxuICAgIHRoaXMubWVudUdyb3VwLm9wZW5lZCA9ICF0aGlzLm1lbnVHcm91cC5vcGVuZWQ7XG4gICAgdGhpcy5hcHBNZW51U2VydmljZS5vbkNsaWNrLm5leHQoe1xuICAgICAgaWRNZW51OiB0aGlzLm1lbnVHcm91cC5pZCxcbiAgICAgIG9wZW5lZDogdGhpcy5tZW51R3JvdXAub3BlbmVkXG4gICAgfSk7XG4gICAgdGhpcy51cGRhdGVDb250ZW50RXhwYW5zaW9uKCk7XG4gIH1cblxuICBuYXZpZ2F0ZSgpIHtcbiAgICBpZiAodGhpcy5hcHBNZW51U2VydmljZS5pc01lbnVHcm91cFJvdXRlKHRoaXMubWVudUdyb3VwKSkge1xuICAgICAgY29uc3Qgcm91dGUgPSAodGhpcy5tZW51R3JvdXAgYXMgTWVudUdyb3VwUm91dGUpLnJvdXRlO1xuICAgICAgaWYgKHRoaXMucm91dGVyLnVybCAhPT0gcm91dGUpIHtcbiAgICAgICAgdGhpcy5yb3V0ZXIubmF2aWdhdGUoW3JvdXRlXSk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgdXBkYXRlQ29udGVudEV4cGFuc2lvbigpIHtcbiAgICBsZXQgaXNPcGVuZWQgPSB0aGlzLm1lbnVHcm91cCAmJiB0aGlzLm1lbnVHcm91cC5vcGVuZWQ7XG4gICAgaWYgKHRoaXMubWVudUdyb3VwLmlkID09PSAndXNlci1pbmZvJykge1xuICAgICAgaXNPcGVuZWQgPSAodGhpcy5zaWRlbmF2ICYmIHRoaXMuc2lkZW5hdi5zaWRlbmF2ICYmIHRoaXMuc2lkZW5hdi5zaWRlbmF2Lm9wZW5lZCkgJiYgaXNPcGVuZWQ7XG4gICAgfVxuICAgIHRoaXMuY29udGVudEV4cGFuc2lvbiA9IGlzT3BlbmVkID8gJ2V4cGFuZGVkJyA6ICdjb2xsYXBzZWQnO1xuICB9XG5cbiAgZ2V0IGNvbnRlbnRFeHBhbnNpb24oKTogc3RyaW5nIHtcbiAgICByZXR1cm4gdGhpcy5fY29udGVudEV4cGFuc2lvbjtcbiAgfVxuXG4gIHNldCBjb250ZW50RXhwYW5zaW9uKHZhbDogc3RyaW5nKSB7XG4gICAgdGhpcy5fY29udGVudEV4cGFuc2lvbiA9IHZhbDtcbiAgICB0aGlzLmNkLmRldGVjdENoYW5nZXMoKTtcbiAgfVxuXG4gIGdldCB0b29sdGlwKCkge1xuICAgIGxldCByZXN1bHQgPSB0aGlzLnRyYW5zbGF0ZVNlcnZpY2UuZ2V0KHRoaXMubWVudUdyb3VwLm5hbWUpO1xuICAgIGlmIChVdGlsLmlzRGVmaW5lZCh0aGlzLm1lbnVHcm91cC50b29sdGlwKSkge1xuICAgICAgcmVzdWx0ICs9ICc6ICcgKyB0aGlzLnRyYW5zbGF0ZVNlcnZpY2UuZ2V0KHRoaXMubWVudUdyb3VwLnRvb2x0aXApO1xuICAgIH1cbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgb25NZW51SXRlbUNsaWNrKGU6IEV2ZW50KTogdm9pZCB7XG4gICAgdGhpcy5vbkl0ZW1DbGljay5lbWl0KGUpO1xuICB9XG5cbiAgZ2V0Q2xhc3MoKSB7XG4gICAgbGV0IGNsYXNzTmFtZSA9ICdvLWFwcC1zaWRlbmF2LW1lbnUtZ3JvdXAgby1hcHAtc2lkZW5hdi1tZW51LWdyb3VwLWxldmVsLScgKyB0aGlzLmxldmVsO1xuICAgIGlmICh0aGlzLm1lbnVHcm91cC5jbGFzcykge1xuICAgICAgY2xhc3NOYW1lICs9ICcgJyArIHRoaXMubWVudUdyb3VwLmNsYXNzO1xuICAgIH1cbiAgICByZXR1cm4gY2xhc3NOYW1lO1xuICB9XG5cbn1cbiIsIjxuZy1jb250YWluZXIgKm5nSWY9XCIhaGlkZGVuXCI+XG4gIDxuZy1jb250YWluZXIgKm5nSWY9XCJzaG91bGRTaG93VG9vbHRpcDsgZWxzZSBub1Rvb2x0aXBcIj5cbiAgICA8YSBtYXQtYnV0dG9uIG1hdC1idXR0b24gY2xhc3M9XCJvLWFwcC1zaWRlbmF2LWl0ZW0gby1hcHAtc2lkZW5hdi1tZW51Z3JvdXBcIiBbY2xhc3Mub3BlbmVkXT1cIm1lbnVHcm91cC5vcGVuZWRcIiAoY2xpY2spPVwib25DbGljaygpXCJcbiAgICAgIFtjbGFzcy5vLWFwcC1zaWRlbmF2LXZpZXdlci1zaWRlbmF2LWl0ZW0tc2VsZWN0ZWRdPVwiYWN0aXZlXCIgW21hdFRvb2x0aXBdPVwidG9vbHRpcFwiIG1hdFRvb2x0aXBDbGFzcz1cIm1lbnVncm91cC10b29sdGlwXCJcbiAgICAgIG1hdFRvb2x0aXBQb3NpdGlvbj1cInJpZ2h0XCIgW21hdFRvb2x0aXBTaG93RGVsYXldPVwic2lkZW5hdk9wZW5lZD81MDA6MFwiPlxuICAgICAgPG5nLWNvbnRhaW5lciAqbmdUZW1wbGF0ZU91dGxldD1cImNvbnRlbnRCdXR0b25cIj48L25nLWNvbnRhaW5lcj5cbiAgICA8L2E+XG4gIDwvbmctY29udGFpbmVyPlxuXG5cbiAgPGRpdiBjbGFzcz1cIm8tYXBwLXNpZGVuYXYtbWVudWdyb3VwLWl0ZW1zLWNvbnRhaW5lclwiPlxuICAgIDx1bCBbQGNvbnRlbnRFeHBhbnNpb25dPVwiY29udGVudEV4cGFuc2lvblwiIGNsYXNzPVwiby1hcHAtc2lkZW5hdi1tZW51Z3JvdXAtdWxcIj5cbiAgICAgIDxuZy1jb250YWluZXIgKm5nRm9yPVwibGV0IG1lbnVJdGVtIG9mIG1lbnVHcm91cC5pdGVtc1wiPlxuICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiYXBwTWVudVNlcnZpY2UuaXNWaXNpYmxlKG1lbnVJdGVtKVwiPlxuICAgICAgICAgIDxvLWFwcC1zaWRlbmF2LW1lbnUtaXRlbSBbc2lkZW5hdi1vcGVuZWRdPVwic2lkZW5hdk9wZW5lZFwiICpuZ0lmPVwiIW1lbnVJdGVtLml0ZW1zOyBlbHNlIG1lbnVHcm91cFwiIFtkaXNhYmxlZF09XCJkaXNhYmxlZFwiXG4gICAgICAgICAgICBbbWVudS1pdGVtXT1cIm1lbnVJdGVtXCIgW21lbnUtaXRlbS10eXBlXT1cImFwcE1lbnVTZXJ2aWNlLmdldE1lbnVJdGVtVHlwZShtZW51SXRlbSlcIiAob25DbGljayk9XCJvbk1lbnVJdGVtQ2xpY2soJGV2ZW50KVwiPlxuICAgICAgICAgIDwvby1hcHAtc2lkZW5hdi1tZW51LWl0ZW0+XG4gICAgICAgICAgPG5nLXRlbXBsYXRlICNtZW51R3JvdXA+XG4gICAgICAgICAgICA8by1hcHAtc2lkZW5hdi1tZW51LWdyb3VwIFttZW51LWdyb3VwXT1cIm1lbnVJdGVtXCIgW3NpZGVuYXYtb3BlbmVkXT1cInNpZGVuYXZPcGVuZWRcIiBbbGV2ZWxdPVwibGV2ZWwgKyAxXCJcbiAgICAgICAgICAgICAgKm5nSWY9XCJhcHBNZW51U2VydmljZS5nZXRNZW51SXRlbVR5cGUobWVudUl0ZW0pID09PSAnZ3JvdXAnXCIgKG9uSXRlbUNsaWNrKT1cIm9uTWVudUl0ZW1DbGljaygkZXZlbnQpXCI+XG4gICAgICAgICAgICA8L28tYXBwLXNpZGVuYXYtbWVudS1ncm91cD5cbiAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgIDwvbmctY29udGFpbmVyPlxuICAgIDwvdWw+XG4gIDwvZGl2PlxuPC9uZy1jb250YWluZXI+XG5cbjxuZy10ZW1wbGF0ZSAjbm9Ub29sdGlwPlxuICA8YSBtYXQtYnV0dG9uIG1hdC1idXR0b24gY2xhc3M9XCJvLWFwcC1zaWRlbmF2LWl0ZW0gby1hcHAtc2lkZW5hdi1tZW51Z3JvdXBcIiBbY2xhc3Mub3BlbmVkXT1cIm1lbnVHcm91cC5vcGVuZWRcIiAoY2xpY2spPVwib25DbGljaygpXCJcbiAgICBbY2xhc3Muby1hcHAtc2lkZW5hdi12aWV3ZXItc2lkZW5hdi1pdGVtLXNlbGVjdGVkXT1cImFjdGl2ZVwiPlxuICAgIDxuZy1jb250YWluZXIgKm5nVGVtcGxhdGVPdXRsZXQ9XCJjb250ZW50QnV0dG9uXCI+PC9uZy1jb250YWluZXI+XG4gIDwvYT5cbjwvbmctdGVtcGxhdGU+XG5cbjxuZy10ZW1wbGF0ZSAjY29udGVudEJ1dHRvbj5cbiAgPGRpdiBmeExheW91dD1cInJvd1wiIGZ4TGF5b3V0QWxpZ249XCJzdGFydCBjZW50ZXJcIiBmeEZpbGw+XG4gICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cInNpZGVuYXZPcGVuZWRcIj5cbiAgICAgIDxtYXQtaWNvbiAqbmdJZj1cIm1lbnVHcm91cC5zdmdJY29uXCIgW3N2Z0ljb25dPVwibWVudUdyb3VwLnN2Z0ljb25cIj48L21hdC1pY29uPlxuICAgICAgPG1hdC1pY29uICpuZ0lmPVwibWVudUdyb3VwLmljb25cIj57eyBtZW51R3JvdXAuaWNvbiB9fTwvbWF0LWljb24+XG4gICAgICA8c3BhbiBjbGFzcz1cIm8tYXBwLXNpZGVuYXYtbWVudWdyb3VwLXRpdGxlXCI+e3sgbWVudUdyb3VwLm5hbWUgfCBvVHJhbnNsYXRlIH19PC9zcGFuPlxuICAgICAgPHNwYW4gY2xhc3M9XCJmaWxsLXJlbWFpbmluZ1wiPjwvc3Bhbj5cbiAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJhcHBNZW51U2VydmljZS5pc01lbnVHcm91cFJvdXRlKG1lbnVHcm91cCkgJiYgbWVudUdyb3VwLm9wZW5lZDsgZWxzZSBhcnJvd01lbnVHcm91cFRlbXBsYXRlXCI+XG4gICAgICAgIDxtYXQtaWNvbiBbaWRdPVwiJ2Fycm93X2ljb25fJyArIG1lbnVHcm91cC5pZFwiIGNsYXNzPVwiby1hcHAtc2lkZW5hdi1tZW51Z3JvdXAtYXJyb3dcIiBzdmdJY29uPVwib250aW1pemU6a2V5Ym9hcmRfYXJyb3dfcmlnaHRcIlxuICAgICAgICAoY2xpY2spPVwidG9nZ2xlKCRldmVudClcIlxuICAgICAgICAoa2V5ZG93bik9XCJ0b2dnbGUoJGV2ZW50KVwiPjwvbWF0LWljb24+XG4gICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgIDxuZy10ZW1wbGF0ZSAjYXJyb3dNZW51R3JvdXBUZW1wbGF0ZT5cbiAgICAgICAgPG1hdC1pY29uIFtpZF09XCInYXJyb3dfaWNvbl8nICsgbWVudUdyb3VwLmlkXCIgY2xhc3M9XCJvLWFwcC1zaWRlbmF2LW1lbnVncm91cC1hcnJvd1wiIHN2Z0ljb249XCJvbnRpbWl6ZTprZXlib2FyZF9hcnJvd19yaWdodFwiPjwvbWF0LWljb24+XG4gICAgICA8L25nLXRlbXBsYXRlPlxuICAgIDwvbmctY29udGFpbmVyPlxuICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCIhc2lkZW5hdk9wZW5lZFwiPlxuICAgICAgPG1hdC1pY29uICpuZ0lmPVwibWVudUdyb3VwLnN2Z0ljb25cIiBbc3ZnSWNvbl09XCJtZW51R3JvdXAuc3ZnSWNvblwiPjwvbWF0LWljb24+IDxtYXQtaWNvbiAqbmdJZj1cIm1lbnVHcm91cC5pY29uXCI+e3sgbWVudUdyb3VwLmljb24gfX08L21hdC1pY29uPlxuICAgIDwvbmctY29udGFpbmVyPlxuICA8L2Rpdj5cbjwvbmctdGVtcGxhdGU+XG4iXX0=