UNPKG

@alfresco/adf-content-services

Version:
140 lines 44.4 kB
/*! * @license * Copyright © 2005-2025 Hyland Software, Inc. and its affiliates. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import { Component, DestroyRef, EventEmitter, inject, Input, Output, ViewEncapsulation } from '@angular/core'; import { NodesApiService } from '../common/services/nodes-api.service'; import { zip } from 'rxjs'; import { concatMap, map, tap } from 'rxjs/operators'; import { AspectListService } from './services/aspect-list.service'; import { MatCheckboxModule } from '@angular/material/checkbox'; import { CommonModule } from '@angular/common'; import { MatExpansionModule } from '@angular/material/expansion'; import { MatTableModule } from '@angular/material/table'; import { TranslateModule } from '@ngx-translate/core'; import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import * as i0 from "@angular/core"; import * as i1 from "./services/aspect-list.service"; import * as i2 from "../common/services/nodes-api.service"; import * as i3 from "@angular/common"; import * as i4 from "@angular/material/expansion"; import * as i5 from "@angular/material/checkbox"; import * as i6 from "@angular/material/table"; import * as i7 from "@ngx-translate/core"; import * as i8 from "@angular/material/progress-spinner"; export class AspectListComponent { constructor(aspectListService, nodeApiService) { this.aspectListService = aspectListService; this.nodeApiService = nodeApiService; /** Node Id of the node that we want to update */ this.nodeId = ''; /** List of aspects' ids which should not be displayed. */ this.excludedAspects = []; /** Emitted every time the user select a new aspect */ this.valueChanged = new EventEmitter(); /** Emitted every time the number of selected aspects changes */ this.updateCounter = new EventEmitter(); this.propertyColumns = ['name', 'title', 'dataType']; this.aspects$ = null; this.nodeAspects = []; this.nodeAspectStatus = []; this.notDisplayedAspects = []; this.hasEqualAspect = true; this.isPanelOpen = []; this.destroyRef = inject(DestroyRef); } ngOnInit() { let aspects$; if (this.nodeId) { const node$ = this.nodeApiService.getNode(this.nodeId); const customAspect$ = this.aspectListService .getCustomAspects(this.aspectListService.getVisibleAspects()) .pipe(map((customAspects) => customAspects.flatMap((customAspect) => customAspect.entry.id))); aspects$ = zip(node$, customAspect$).pipe(tap(([node, customAspects]) => { this.nodeAspects = node.aspectNames.filter((aspect) => this.aspectListService.getVisibleAspects().includes(aspect) || customAspects.includes(aspect)); this.nodeAspectStatus = [...this.nodeAspects]; this.notDisplayedAspects = node.aspectNames.filter((aspect) => !this.aspectListService.getVisibleAspects().includes(aspect) && !customAspects.includes(aspect)); this.valueChanged.emit([...this.nodeAspects, ...this.notDisplayedAspects]); this.updateCounter.emit(this.nodeAspects.length); }), concatMap(() => this.aspectListService.getAspects()), takeUntilDestroyed(this.destroyRef)); } else { aspects$ = this.aspectListService.getAspects().pipe(takeUntilDestroyed(this.destroyRef)); } this.aspects$ = aspects$.pipe(map((aspects) => aspects.filter((aspect) => !this.excludedAspects.includes(aspect.entry.id)))); } onCheckBoxClick(event) { event.stopImmediatePropagation(); } onChange(change, prefixedName) { if (change.checked) { this.nodeAspects.push(prefixedName); } else { this.nodeAspects.splice(this.nodeAspects.indexOf(prefixedName), 1); } this.updateEqualityOfAspectList(); this.valueChanged.emit([...this.nodeAspects, ...this.notDisplayedAspects]); this.updateCounter.emit(this.nodeAspects.length); } reset() { if (this.nodeAspectStatus && this.nodeAspectStatus.length > 0) { this.nodeAspects.splice(0, this.nodeAspects.length, ...this.nodeAspectStatus); this.hasEqualAspect = true; this.valueChanged.emit([...this.nodeAspects, ...this.notDisplayedAspects]); this.updateCounter.emit(this.nodeAspects.length); } else { this.clear(); } } clear() { this.nodeAspects = []; this.updateEqualityOfAspectList(); this.valueChanged.emit([...this.nodeAspects, ...this.notDisplayedAspects]); this.updateCounter.emit(this.nodeAspects.length); } getId(aspect) { return aspect?.entry?.title ? aspect?.entry?.title : aspect?.entry?.id.replace(':', '-'); } getTitle(aspect) { return aspect?.entry?.title ? aspect?.entry?.title : aspect?.entry?.id; } updateEqualityOfAspectList() { if (this.nodeAspectStatus.length !== this.nodeAspects.length) { this.hasEqualAspect = false; } else { this.hasEqualAspect = this.nodeAspects.every((aspect) => this.nodeAspectStatus.includes(aspect)); } } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: AspectListComponent, deps: [{ token: i1.AspectListService }, { token: i2.NodesApiService }], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.1.3", type: AspectListComponent, isStandalone: true, selector: "adf-aspect-list", inputs: { nodeId: "nodeId", excludedAspects: "excludedAspects" }, outputs: { valueChanged: "valueChanged", updateCounter: "updateCounter" }, ngImport: i0, template: "<div id=\"aspect-list-container\" class=\"adf-aspect-list-container\" *ngIf=\"aspects$ | async as aspects; else loading\">\n <mat-accordion class=\"adf-accordion-aspect-list\">\n <div class=\"adf-accordion-aspect-list-item\"\n *ngFor=\"let aspect of aspects; let colIndex = index\"\n [ngClass]=\"{'adf-hover' : !isPanelOpen[colIndex]}\">\n <mat-checkbox class=\"adf-aspect-list-check-button\" [id]=\"'aspect-list-'+colIndex+'-check'\"\n [checked]=\"nodeAspects?.includes(aspect?.entry?.id)\"\n (click)=\"onCheckBoxClick($event)\"\n [aria-label]=\"getTitle(aspect)\"\n (change)=\"onChange($event, aspect?.entry?.id)\"/>\n <mat-expansion-panel\n [id]=\"'aspect-list-'+getId(aspect)\"\n class=\"adf-accordion-aspect-list-expansion-panel\"\n (opened)=\"isPanelOpen[colIndex] = true\"\n (afterCollapse)=\"isPanelOpen[colIndex] = false\"\n >\n <mat-expansion-panel-header class='adf-accordion-aspect-list-expansion-panel-header'\n [id]=\"'aspect-list-'+(getId(aspect))+'header'\">\n <mat-panel-title class=\"adf-accordion-aspect-list-expansion-panel-header-title\">\n {{getTitle(aspect)}}\n </mat-panel-title>\n <mat-panel-description\n class=\"adf-accordion-aspect-list-expansion-panel-header-description\"\n [id]=\"'aspect-list-'+colIndex+'-title'\"\n [title]=\"getTitle(aspect)\">\n {{getTitle(aspect)}}\n </mat-panel-description>\n </mat-expansion-panel-header>\n <p class=\"adf-property-paragraph\" [id]=\"'aspect-list-'+colIndex+'-description'\"> {{aspect?.entry?.description}}</p>\n\n <table mat-table [dataSource]=\"aspect?.entry?.properties\" *ngIf=\"aspect?.entry?.properties?.length > 0\" class=\"adf-aspect-property-table\" [id]=\"'aspect-list-'+colIndex+'-properties-table'\">\n <ng-container matColumnDef=\"name\">\n <th class=\"adf-aspect-property-table-column-name\" mat-header-cell *matHeaderCellDef> {{'ADF-ASPECT-LIST.PROPERTY_NAME' | translate}} </th>\n <td class=\"adf-aspect-property-table-column-name adf-aspect-property-table-cell\" mat-cell *matCellDef=\"let property\"> {{property.id}} </td>\n </ng-container>\n <ng-container matColumnDef=\"title\">\n <th class=\"adf-aspect-property-table-column-title\" mat-header-cell *matHeaderCellDef> {{'ADF-ASPECT-LIST.DESCRIPTION' | translate}} </th>\n <td class=\"adf-aspect-property-table-column-title adf-aspect-property-table-cell\" mat-cell *matCellDef=\"let property\"> {{property.title}} </td>\n </ng-container>\n <ng-container matColumnDef=\"dataType\">\n <th class=\"adf-aspect-property-table-column-data-type\" mat-header-cell *matHeaderCellDef> {{'ADF-ASPECT-LIST.DATA_TYPE' | translate}} </th>\n <td class=\"adf-aspect-property-table-column-data-type adf-aspect-property-table-cell\" mat-cell *matCellDef=\"let property\"> {{property.dataType}} </td>\n </ng-container>\n <tr mat-header-row *matHeaderRowDef=\"propertyColumns\"></tr>\n <tr mat-row *matRowDef=\"let row; columns: propertyColumns;\"></tr>\n </table>\n </mat-expansion-panel>\n </div>\n </mat-accordion>\n</div>\n\n<ng-template #loading>\n <div class=\"adf-aspect-list-spinner\">\n <mat-progress-spinner mode=\"indeterminate\" id=\"adf-aspect-spinner\" />\n </div>\n</ng-template>\n", styles: [".adf-aspect-list-spinner,.adf-aspect-list-container{padding-top:3px;box-sizing:border-box}.adf-aspect-list-spinner{display:flex;align-items:center;justify-content:center;min-height:calc(65vh - 212px)}.adf-aspect-list-container{max-height:calc(65vh - 212px);overflow:auto;border:1px solid var(--adf-theme-foreground-text-color-007)}.adf-aspect-list-container .adf-aspect-list-check-button{margin-right:5px;height:48px;align-items:center;display:flex}.adf-aspect-list-container .adf-accordion-aspect-list-item{padding-left:14px;display:flex;box-shadow:0 2px 2px -1px var(--adf-theme-foreground-text-color-007)}.adf-aspect-list-container .adf-accordion-aspect-list-item.adf-hover:hover{background-color:var(--adf-theme-background-hover-color)}.adf-aspect-list-container .adf-accordion-aspect-list-expansion-panel{margin:0;width:100%;box-shadow:none;background:border-box}.adf-aspect-list-container .adf-accordion-aspect-list-expansion-panel .mdc-checkbox__background{height:16px;width:16px}.adf-aspect-list-container .adf-accordion-aspect-list-expansion-panel-header{font-size:smaller;padding-left:0;height:48px}.adf-aspect-list-container .adf-accordion-aspect-list-expansion-panel-header-title{color:var(--theme-secondary-text)}.adf-aspect-list-container .adf-accordion-aspect-list-expansion-panel-header-description{justify-content:flex-start;align-items:center;flex:1 1 0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.adf-aspect-property-table{width:100%}.adf-aspect-property-table .adf-aspect-property-table-column-name,.adf-aspect-property-table .adf-aspect-property-table-column-title,.adf-aspect-property-table .adf-aspect-property-table-column-data-type{font-size:12px;color:var(--adf-theme-foreground-text-color-054)}.adf-aspect-property-table .adf-aspect-property-table-column-name{width:15%;padding-left:24px;padding-right:0}.adf-aspect-property-table .adf-aspect-property-table-column-title{width:65%;padding:0}.adf-aspect-property-table .adf-aspect-property-table-column-data-type{width:20%;padding-right:24px;padding-left:10px}.adf-accordion-aspect-list .adf-accordion-aspect-list-item .adf-accordion-aspect-list-expansion-panel .adf-accordion-aspect-list-expansion-panel-header:hover,.adf-accordion-aspect-list .adf-accordion-aspect-list-item .adf-accordion-aspect-list-expansion-panel .adf-accordion-aspect-list-expansion-panel-header:focus{background:none}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i3.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "pipe", type: i3.AsyncPipe, name: "async" }, { kind: "ngmodule", type: MatExpansionModule }, { kind: "directive", type: i4.MatAccordion, selector: "mat-accordion", inputs: ["hideToggle", "displayMode", "togglePosition"], exportAs: ["matAccordion"] }, { kind: "component", type: i4.MatExpansionPanel, selector: "mat-expansion-panel", inputs: ["hideToggle", "togglePosition"], outputs: ["afterExpand", "afterCollapse"], exportAs: ["matExpansionPanel"] }, { kind: "component", type: i4.MatExpansionPanelHeader, selector: "mat-expansion-panel-header", inputs: ["expandedHeight", "collapsedHeight", "tabIndex"] }, { kind: "directive", type: i4.MatExpansionPanelTitle, selector: "mat-panel-title" }, { kind: "directive", type: i4.MatExpansionPanelDescription, selector: "mat-panel-description" }, { kind: "ngmodule", type: MatCheckboxModule }, { kind: "component", type: i5.MatCheckbox, selector: "mat-checkbox", inputs: ["aria-label", "aria-labelledby", "aria-describedby", "id", "required", "labelPosition", "name", "value", "disableRipple", "tabIndex", "color", "checked", "disabled", "indeterminate"], outputs: ["change", "indeterminateChange"], exportAs: ["matCheckbox"] }, { kind: "ngmodule", type: MatTableModule }, { kind: "component", type: i6.MatTable, selector: "mat-table, table[mat-table]", exportAs: ["matTable"] }, { kind: "directive", type: i6.MatHeaderCellDef, selector: "[matHeaderCellDef]" }, { kind: "directive", type: i6.MatHeaderRowDef, selector: "[matHeaderRowDef]", inputs: ["matHeaderRowDef", "matHeaderRowDefSticky"] }, { kind: "directive", type: i6.MatColumnDef, selector: "[matColumnDef]", inputs: ["sticky", "matColumnDef"] }, { kind: "directive", type: i6.MatCellDef, selector: "[matCellDef]" }, { kind: "directive", type: i6.MatRowDef, selector: "[matRowDef]", inputs: ["matRowDefColumns", "matRowDefWhen"] }, { kind: "directive", type: i6.MatHeaderCell, selector: "mat-header-cell, th[mat-header-cell]" }, { kind: "directive", type: i6.MatCell, selector: "mat-cell, td[mat-cell]" }, { kind: "component", type: i6.MatHeaderRow, selector: "mat-header-row, tr[mat-header-row]", exportAs: ["matHeaderRow"] }, { kind: "component", type: i6.MatRow, selector: "mat-row, tr[mat-row]", exportAs: ["matRow"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i7.TranslatePipe, name: "translate" }, { kind: "ngmodule", type: MatProgressSpinnerModule }, { kind: "component", type: i8.MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "mode", "value", "diameter", "strokeWidth"], exportAs: ["matProgressSpinner"] }], encapsulation: i0.ViewEncapsulation.None }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.1.3", ngImport: i0, type: AspectListComponent, decorators: [{ type: Component, args: [{ selector: 'adf-aspect-list', standalone: true, imports: [CommonModule, MatExpansionModule, MatCheckboxModule, MatTableModule, TranslateModule, MatProgressSpinnerModule], encapsulation: ViewEncapsulation.None, template: "<div id=\"aspect-list-container\" class=\"adf-aspect-list-container\" *ngIf=\"aspects$ | async as aspects; else loading\">\n <mat-accordion class=\"adf-accordion-aspect-list\">\n <div class=\"adf-accordion-aspect-list-item\"\n *ngFor=\"let aspect of aspects; let colIndex = index\"\n [ngClass]=\"{'adf-hover' : !isPanelOpen[colIndex]}\">\n <mat-checkbox class=\"adf-aspect-list-check-button\" [id]=\"'aspect-list-'+colIndex+'-check'\"\n [checked]=\"nodeAspects?.includes(aspect?.entry?.id)\"\n (click)=\"onCheckBoxClick($event)\"\n [aria-label]=\"getTitle(aspect)\"\n (change)=\"onChange($event, aspect?.entry?.id)\"/>\n <mat-expansion-panel\n [id]=\"'aspect-list-'+getId(aspect)\"\n class=\"adf-accordion-aspect-list-expansion-panel\"\n (opened)=\"isPanelOpen[colIndex] = true\"\n (afterCollapse)=\"isPanelOpen[colIndex] = false\"\n >\n <mat-expansion-panel-header class='adf-accordion-aspect-list-expansion-panel-header'\n [id]=\"'aspect-list-'+(getId(aspect))+'header'\">\n <mat-panel-title class=\"adf-accordion-aspect-list-expansion-panel-header-title\">\n {{getTitle(aspect)}}\n </mat-panel-title>\n <mat-panel-description\n class=\"adf-accordion-aspect-list-expansion-panel-header-description\"\n [id]=\"'aspect-list-'+colIndex+'-title'\"\n [title]=\"getTitle(aspect)\">\n {{getTitle(aspect)}}\n </mat-panel-description>\n </mat-expansion-panel-header>\n <p class=\"adf-property-paragraph\" [id]=\"'aspect-list-'+colIndex+'-description'\"> {{aspect?.entry?.description}}</p>\n\n <table mat-table [dataSource]=\"aspect?.entry?.properties\" *ngIf=\"aspect?.entry?.properties?.length > 0\" class=\"adf-aspect-property-table\" [id]=\"'aspect-list-'+colIndex+'-properties-table'\">\n <ng-container matColumnDef=\"name\">\n <th class=\"adf-aspect-property-table-column-name\" mat-header-cell *matHeaderCellDef> {{'ADF-ASPECT-LIST.PROPERTY_NAME' | translate}} </th>\n <td class=\"adf-aspect-property-table-column-name adf-aspect-property-table-cell\" mat-cell *matCellDef=\"let property\"> {{property.id}} </td>\n </ng-container>\n <ng-container matColumnDef=\"title\">\n <th class=\"adf-aspect-property-table-column-title\" mat-header-cell *matHeaderCellDef> {{'ADF-ASPECT-LIST.DESCRIPTION' | translate}} </th>\n <td class=\"adf-aspect-property-table-column-title adf-aspect-property-table-cell\" mat-cell *matCellDef=\"let property\"> {{property.title}} </td>\n </ng-container>\n <ng-container matColumnDef=\"dataType\">\n <th class=\"adf-aspect-property-table-column-data-type\" mat-header-cell *matHeaderCellDef> {{'ADF-ASPECT-LIST.DATA_TYPE' | translate}} </th>\n <td class=\"adf-aspect-property-table-column-data-type adf-aspect-property-table-cell\" mat-cell *matCellDef=\"let property\"> {{property.dataType}} </td>\n </ng-container>\n <tr mat-header-row *matHeaderRowDef=\"propertyColumns\"></tr>\n <tr mat-row *matRowDef=\"let row; columns: propertyColumns;\"></tr>\n </table>\n </mat-expansion-panel>\n </div>\n </mat-accordion>\n</div>\n\n<ng-template #loading>\n <div class=\"adf-aspect-list-spinner\">\n <mat-progress-spinner mode=\"indeterminate\" id=\"adf-aspect-spinner\" />\n </div>\n</ng-template>\n", styles: [".adf-aspect-list-spinner,.adf-aspect-list-container{padding-top:3px;box-sizing:border-box}.adf-aspect-list-spinner{display:flex;align-items:center;justify-content:center;min-height:calc(65vh - 212px)}.adf-aspect-list-container{max-height:calc(65vh - 212px);overflow:auto;border:1px solid var(--adf-theme-foreground-text-color-007)}.adf-aspect-list-container .adf-aspect-list-check-button{margin-right:5px;height:48px;align-items:center;display:flex}.adf-aspect-list-container .adf-accordion-aspect-list-item{padding-left:14px;display:flex;box-shadow:0 2px 2px -1px var(--adf-theme-foreground-text-color-007)}.adf-aspect-list-container .adf-accordion-aspect-list-item.adf-hover:hover{background-color:var(--adf-theme-background-hover-color)}.adf-aspect-list-container .adf-accordion-aspect-list-expansion-panel{margin:0;width:100%;box-shadow:none;background:border-box}.adf-aspect-list-container .adf-accordion-aspect-list-expansion-panel .mdc-checkbox__background{height:16px;width:16px}.adf-aspect-list-container .adf-accordion-aspect-list-expansion-panel-header{font-size:smaller;padding-left:0;height:48px}.adf-aspect-list-container .adf-accordion-aspect-list-expansion-panel-header-title{color:var(--theme-secondary-text)}.adf-aspect-list-container .adf-accordion-aspect-list-expansion-panel-header-description{justify-content:flex-start;align-items:center;flex:1 1 0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.adf-aspect-property-table{width:100%}.adf-aspect-property-table .adf-aspect-property-table-column-name,.adf-aspect-property-table .adf-aspect-property-table-column-title,.adf-aspect-property-table .adf-aspect-property-table-column-data-type{font-size:12px;color:var(--adf-theme-foreground-text-color-054)}.adf-aspect-property-table .adf-aspect-property-table-column-name{width:15%;padding-left:24px;padding-right:0}.adf-aspect-property-table .adf-aspect-property-table-column-title{width:65%;padding:0}.adf-aspect-property-table .adf-aspect-property-table-column-data-type{width:20%;padding-right:24px;padding-left:10px}.adf-accordion-aspect-list .adf-accordion-aspect-list-item .adf-accordion-aspect-list-expansion-panel .adf-accordion-aspect-list-expansion-panel-header:hover,.adf-accordion-aspect-list .adf-accordion-aspect-list-item .adf-accordion-aspect-list-expansion-panel .adf-accordion-aspect-list-expansion-panel-header:focus{background:none}\n"] }] }], ctorParameters: () => [{ type: i1.AspectListService }, { type: i2.NodesApiService }], propDecorators: { nodeId: [{ type: Input, args: [{ required: true }] }], excludedAspects: [{ type: Input }], valueChanged: [{ type: Output }], updateCounter: [{ type: Output }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXNwZWN0LWxpc3QuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vbGliL2NvbnRlbnQtc2VydmljZXMvc3JjL2xpYi9hc3BlY3QtbGlzdC9hc3BlY3QtbGlzdC5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi8uLi9saWIvY29udGVudC1zZXJ2aWNlcy9zcmMvbGliL2FzcGVjdC1saXN0L2FzcGVjdC1saXN0LmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7Ozs7Ozs7Ozs7R0FlRztBQUVILE9BQU8sRUFBRSxTQUFTLEVBQUUsVUFBVSxFQUFFLFlBQVksRUFBRSxNQUFNLEVBQUUsS0FBSyxFQUFVLE1BQU0sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUN0SCxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sc0NBQXNDLENBQUM7QUFDdkUsT0FBTyxFQUFjLEdBQUcsRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUN2QyxPQUFPLEVBQUUsU0FBUyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUNyRCxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxnQ0FBZ0MsQ0FBQztBQUNuRSxPQUFPLEVBQXFCLGlCQUFpQixFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFFbEYsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQy9DLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLDZCQUE2QixDQUFDO0FBQ2pFLE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUN6RCxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDdEQsT0FBTyxFQUFFLHdCQUF3QixFQUFFLE1BQU0sb0NBQW9DLENBQUM7QUFDOUUsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sNEJBQTRCLENBQUM7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Ii8qIVxuICogQGxpY2Vuc2VcbiAqIENvcHlyaWdodCDCqSAyMDA1LTIwMjUgSHlsYW5kIFNvZnR3YXJlLCBJbmMuIGFuZCBpdHMgYWZmaWxpYXRlcy4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKi9cblxuaW1wb3J0IHsgQ29tcG9uZW50LCBEZXN0cm95UmVmLCBFdmVudEVtaXR0ZXIsIGluamVjdCwgSW5wdXQsIE9uSW5pdCwgT3V0cHV0LCBWaWV3RW5jYXBzdWxhdGlvbiB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgTm9kZXNBcGlTZXJ2aWNlIH0gZnJvbSAnLi4vY29tbW9uL3NlcnZpY2VzL25vZGVzLWFwaS5zZXJ2aWNlJztcbmltcG9ydCB7IE9ic2VydmFibGUsIHppcCB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgY29uY2F0TWFwLCBtYXAsIHRhcCB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcbmltcG9ydCB7IEFzcGVjdExpc3RTZXJ2aWNlIH0gZnJvbSAnLi9zZXJ2aWNlcy9hc3BlY3QtbGlzdC5zZXJ2aWNlJztcbmltcG9ydCB7IE1hdENoZWNrYm94Q2hhbmdlLCBNYXRDaGVja2JveE1vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL2NoZWNrYm94JztcbmltcG9ydCB7IEFzcGVjdEVudHJ5IH0gZnJvbSAnQGFsZnJlc2NvL2pzLWFwaSc7XG5pbXBvcnQgeyBDb21tb25Nb2R1bGUgfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xuaW1wb3J0IHsgTWF0RXhwYW5zaW9uTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvZXhwYW5zaW9uJztcbmltcG9ydCB7IE1hdFRhYmxlTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvdGFibGUnO1xuaW1wb3J0IHsgVHJhbnNsYXRlTW9kdWxlIH0gZnJvbSAnQG5neC10cmFuc2xhdGUvY29yZSc7XG5pbXBvcnQgeyBNYXRQcm9ncmVzc1NwaW5uZXJNb2R1bGUgfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9wcm9ncmVzcy1zcGlubmVyJztcbmltcG9ydCB7IHRha2VVbnRpbERlc3Ryb3llZCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUvcnhqcy1pbnRlcm9wJztcblxuQENvbXBvbmVudCh7XG4gICAgc2VsZWN0b3I6ICdhZGYtYXNwZWN0LWxpc3QnLFxuICAgIHN0YW5kYWxvbmU6IHRydWUsXG4gICAgaW1wb3J0czogW0NvbW1vbk1vZHVsZSwgTWF0RXhwYW5zaW9uTW9kdWxlLCBNYXRDaGVja2JveE1vZHVsZSwgTWF0VGFibGVNb2R1bGUsIFRyYW5zbGF0ZU1vZHVsZSwgTWF0UHJvZ3Jlc3NTcGlubmVyTW9kdWxlXSxcbiAgICB0ZW1wbGF0ZVVybDogJy4vYXNwZWN0LWxpc3QuY29tcG9uZW50Lmh0bWwnLFxuICAgIHN0eWxlVXJsczogWycuL2FzcGVjdC1saXN0LmNvbXBvbmVudC5zY3NzJ10sXG4gICAgZW5jYXBzdWxhdGlvbjogVmlld0VuY2Fwc3VsYXRpb24uTm9uZVxufSlcbmV4cG9ydCBjbGFzcyBBc3BlY3RMaXN0Q29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0IHtcbiAgICAvKiogTm9kZSBJZCBvZiB0aGUgbm9kZSB0aGF0IHdlIHdhbnQgdG8gdXBkYXRlICovXG4gICAgQElucHV0KHsgcmVxdWlyZWQ6IHRydWUgfSlcbiAgICBub2RlSWQ6IHN0cmluZyA9ICcnO1xuXG4gICAgLyoqIExpc3Qgb2YgYXNwZWN0cycgaWRzIHdoaWNoIHNob3VsZCBub3QgYmUgZGlzcGxheWVkLiAqL1xuICAgIEBJbnB1dCgpXG4gICAgZXhjbHVkZWRBc3BlY3RzPzogc3RyaW5nW10gPSBbXTtcblxuICAgIC8qKiBFbWl0dGVkIGV2ZXJ5IHRpbWUgdGhlIHVzZXIgc2VsZWN0IGEgbmV3IGFzcGVjdCAqL1xuICAgIEBPdXRwdXQoKVxuICAgIHZhbHVlQ2hhbmdlZDogRXZlbnRFbWl0dGVyPHN0cmluZ1tdPiA9IG5ldyBFdmVudEVtaXR0ZXI8c3RyaW5nW10+KCk7XG5cbiAgICAvKiogRW1pdHRlZCBldmVyeSB0aW1lIHRoZSBudW1iZXIgb2Ygc2VsZWN0ZWQgYXNwZWN0cyBjaGFuZ2VzICovXG4gICAgQE91dHB1dCgpXG4gICAgdXBkYXRlQ291bnRlcjogRXZlbnRFbWl0dGVyPG51bWJlcj4gPSBuZXcgRXZlbnRFbWl0dGVyPG51bWJlcj4oKTtcblxuICAgIHByb3BlcnR5Q29sdW1uczogc3RyaW5nW10gPSBbJ25hbWUnLCAndGl0bGUnLCAnZGF0YVR5cGUnXTtcbiAgICBhc3BlY3RzJDogT2JzZXJ2YWJsZTxBc3BlY3RFbnRyeVtdPiA9IG51bGw7XG4gICAgbm9kZUFzcGVjdHM6IHN0cmluZ1tdID0gW107XG4gICAgbm9kZUFzcGVjdFN0YXR1czogc3RyaW5nW10gPSBbXTtcbiAgICBub3REaXNwbGF5ZWRBc3BlY3RzOiBzdHJpbmdbXSA9IFtdO1xuICAgIGhhc0VxdWFsQXNwZWN0OiBib29sZWFuID0gdHJ1ZTtcbiAgICBpc1BhbmVsT3BlbjogYm9vbGVhbltdID0gW107XG5cbiAgICBwcml2YXRlIHJlYWRvbmx5IGRlc3Ryb3lSZWYgPSBpbmplY3QoRGVzdHJveVJlZik7XG5cbiAgICBjb25zdHJ1Y3Rvcihwcml2YXRlIGFzcGVjdExpc3RTZXJ2aWNlOiBBc3BlY3RMaXN0U2VydmljZSwgcHJpdmF0ZSBub2RlQXBpU2VydmljZTogTm9kZXNBcGlTZXJ2aWNlKSB7fVxuXG4gICAgbmdPbkluaXQoKTogdm9pZCB7XG4gICAgICAgIGxldCBhc3BlY3RzJDogT2JzZXJ2YWJsZTxBc3BlY3RFbnRyeVtdPjtcbiAgICAgICAgaWYgKHRoaXMubm9kZUlkKSB7XG4gICAgICAgICAgICBjb25zdCBub2RlJCA9IHRoaXMubm9kZUFwaVNlcnZpY2UuZ2V0Tm9kZSh0aGlzLm5vZGVJZCk7XG4gICAgICAgICAgICBjb25zdCBjdXN0b21Bc3BlY3QkID0gdGhpcy5hc3BlY3RMaXN0U2VydmljZVxuICAgICAgICAgICAgICAgIC5nZXRDdXN0b21Bc3BlY3RzKHRoaXMuYXNwZWN0TGlzdFNlcnZpY2UuZ2V0VmlzaWJsZUFzcGVjdHMoKSlcbiAgICAgICAgICAgICAgICAucGlwZShtYXAoKGN1c3RvbUFzcGVjdHMpID0+IGN1c3RvbUFzcGVjdHMuZmxhdE1hcCgoY3VzdG9tQXNwZWN0KSA9PiBjdXN0b21Bc3BlY3QuZW50cnkuaWQpKSk7XG4gICAgICAgICAgICBhc3BlY3RzJCA9IHppcChub2RlJCwgY3VzdG9tQXNwZWN0JCkucGlwZShcbiAgICAgICAgICAgICAgICB0YXAoKFtub2RlLCBjdXN0b21Bc3BlY3RzXSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLm5vZGVBc3BlY3RzID0gbm9kZS5hc3BlY3ROYW1lcy5maWx0ZXIoXG4gICAgICAgICAgICAgICAgICAgICAgICAoYXNwZWN0KSA9PiB0aGlzLmFzcGVjdExpc3RTZXJ2aWNlLmdldFZpc2libGVBc3BlY3RzKCkuaW5jbHVkZXMoYXNwZWN0KSB8fCBjdXN0b21Bc3BlY3RzLmluY2x1ZGVzKGFzcGVjdClcbiAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5ub2RlQXNwZWN0U3RhdHVzID0gWy4uLnRoaXMubm9kZUFzcGVjdHNdO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLm5vdERpc3BsYXllZEFzcGVjdHMgPSBub2RlLmFzcGVjdE5hbWVzLmZpbHRlcihcbiAgICAgICAgICAgICAgICAgICAgICAgIChhc3BlY3QpID0+ICF0aGlzLmFzcGVjdExpc3RTZXJ2aWNlLmdldFZpc2libGVBc3BlY3RzKCkuaW5jbHVkZXMoYXNwZWN0KSAmJiAhY3VzdG9tQXNwZWN0cy5pbmNsdWRlcyhhc3BlY3QpXG4gICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMudmFsdWVDaGFuZ2VkLmVtaXQoWy4uLnRoaXMubm9kZUFzcGVjdHMsIC4uLnRoaXMubm90RGlzcGxheWVkQXNwZWN0c10pO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnVwZGF0ZUNvdW50ZXIuZW1pdCh0aGlzLm5vZGVBc3BlY3RzLmxlbmd0aCk7XG4gICAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICAgICAgY29uY2F0TWFwKCgpID0+IHRoaXMuYXNwZWN0TGlzdFNlcnZpY2UuZ2V0QXNwZWN0cygpKSxcbiAgICAgICAgICAgICAgICB0YWtlVW50aWxEZXN0cm95ZWQodGhpcy5kZXN0cm95UmVmKVxuICAgICAgICAgICAgKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGFzcGVjdHMkID0gdGhpcy5hc3BlY3RMaXN0U2VydmljZS5nZXRBc3BlY3RzKCkucGlwZSh0YWtlVW50aWxEZXN0cm95ZWQodGhpcy5kZXN0cm95UmVmKSk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5hc3BlY3RzJCA9IGFzcGVjdHMkLnBpcGUobWFwKChhc3BlY3RzKSA9PiBhc3BlY3RzLmZpbHRlcigoYXNwZWN0KSA9PiAhdGhpcy5leGNsdWRlZEFzcGVjdHMuaW5jbHVkZXMoYXNwZWN0LmVudHJ5LmlkKSkpKTtcbiAgICB9XG5cbiAgICBvbkNoZWNrQm94Q2xpY2soZXZlbnQ6IEV2ZW50KSB7XG4gICAgICAgIGV2ZW50LnN0b3BJbW1lZGlhdGVQcm9wYWdhdGlvbigpO1xuICAgIH1cblxuICAgIG9uQ2hhbmdlKGNoYW5nZTogTWF0Q2hlY2tib3hDaGFuZ2UsIHByZWZpeGVkTmFtZTogc3RyaW5nKSB7XG4gICAgICAgIGlmIChjaGFuZ2UuY2hlY2tlZCkge1xuICAgICAgICAgICAgdGhpcy5ub2RlQXNwZWN0cy5wdXNoKHByZWZpeGVkTmFtZSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLm5vZGVBc3BlY3RzLnNwbGljZSh0aGlzLm5vZGVBc3BlY3RzLmluZGV4T2YocHJlZml4ZWROYW1lKSwgMSk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy51cGRhdGVFcXVhbGl0eU9mQXNwZWN0TGlzdCgpO1xuICAgICAgICB0aGlzLnZhbHVlQ2hhbmdlZC5lbWl0KFsuLi50aGlzLm5vZGVBc3BlY3RzLCAuLi50aGlzLm5vdERpc3BsYXllZEFzcGVjdHNdKTtcbiAgICAgICAgdGhpcy51cGRhdGVDb3VudGVyLmVtaXQodGhpcy5ub2RlQXNwZWN0cy5sZW5ndGgpO1xuICAgIH1cblxuICAgIHJlc2V0KCkge1xuICAgICAgICBpZiAodGhpcy5ub2RlQXNwZWN0U3RhdHVzICYmIHRoaXMubm9kZUFzcGVjdFN0YXR1cy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICB0aGlzLm5vZGVBc3BlY3RzLnNwbGljZSgwLCB0aGlzLm5vZGVBc3BlY3RzLmxlbmd0aCwgLi4udGhpcy5ub2RlQXNwZWN0U3RhdHVzKTtcbiAgICAgICAgICAgIHRoaXMuaGFzRXF1YWxBc3BlY3QgPSB0cnVlO1xuICAgICAgICAgICAgdGhpcy52YWx1ZUNoYW5nZWQuZW1pdChbLi4udGhpcy5ub2RlQXNwZWN0cywgLi4udGhpcy5ub3REaXNwbGF5ZWRBc3BlY3RzXSk7XG4gICAgICAgICAgICB0aGlzLnVwZGF0ZUNvdW50ZXIuZW1pdCh0aGlzLm5vZGVBc3BlY3RzLmxlbmd0aCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLmNsZWFyKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBjbGVhcigpIHtcbiAgICAgICAgdGhpcy5ub2RlQXNwZWN0cyA9IFtdO1xuICAgICAgICB0aGlzLnVwZGF0ZUVxdWFsaXR5T2ZBc3BlY3RMaXN0KCk7XG4gICAgICAgIHRoaXMudmFsdWVDaGFuZ2VkLmVtaXQoWy4uLnRoaXMubm9kZUFzcGVjdHMsIC4uLnRoaXMubm90RGlzcGxheWVkQXNwZWN0c10pO1xuICAgICAgICB0aGlzLnVwZGF0ZUNvdW50ZXIuZW1pdCh0aGlzLm5vZGVBc3BlY3RzLmxlbmd0aCk7XG4gICAgfVxuXG4gICAgZ2V0SWQoYXNwZWN0OiBhbnkpOiBzdHJpbmcge1xuICAgICAgICByZXR1cm4gYXNwZWN0Py5lbnRyeT8udGl0bGUgPyBhc3BlY3Q/LmVudHJ5Py50aXRsZSA6IGFzcGVjdD8uZW50cnk/LmlkLnJlcGxhY2UoJzonLCAnLScpO1xuICAgIH1cblxuICAgIGdldFRpdGxlKGFzcGVjdDogYW55KTogc3RyaW5nIHtcbiAgICAgICAgcmV0dXJuIGFzcGVjdD8uZW50cnk/LnRpdGxlID8gYXNwZWN0Py5lbnRyeT8udGl0bGUgOiBhc3BlY3Q/LmVudHJ5Py5pZDtcbiAgICB9XG5cbiAgICBwcml2YXRlIHVwZGF0ZUVxdWFsaXR5T2ZBc3BlY3RMaXN0KCkge1xuICAgICAgICBpZiAodGhpcy5ub2RlQXNwZWN0U3RhdHVzLmxlbmd0aCAhPT0gdGhpcy5ub2RlQXNwZWN0cy5sZW5ndGgpIHtcbiAgICAgICAgICAgIHRoaXMuaGFzRXF1YWxBc3BlY3QgPSBmYWxzZTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuaGFzRXF1YWxBc3BlY3QgPSB0aGlzLm5vZGVBc3BlY3RzLmV2ZXJ5KChhc3BlY3QpID0+IHRoaXMubm9kZUFzcGVjdFN0YXR1cy5pbmNsdWRlcyhhc3BlY3QpKTtcbiAgICAgICAgfVxuICAgIH1cbn1cbiIsIjxkaXYgaWQ9XCJhc3BlY3QtbGlzdC1jb250YWluZXJcIiBjbGFzcz1cImFkZi1hc3BlY3QtbGlzdC1jb250YWluZXJcIiAqbmdJZj1cImFzcGVjdHMkIHwgYXN5bmMgYXMgYXNwZWN0czsgZWxzZSBsb2FkaW5nXCI+XG4gICAgPG1hdC1hY2NvcmRpb24gY2xhc3M9XCJhZGYtYWNjb3JkaW9uLWFzcGVjdC1saXN0XCI+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJhZGYtYWNjb3JkaW9uLWFzcGVjdC1saXN0LWl0ZW1cIlxuICAgICAgICAgICAgICpuZ0Zvcj1cImxldCBhc3BlY3Qgb2YgYXNwZWN0czsgbGV0IGNvbEluZGV4ID0gaW5kZXhcIlxuICAgICAgICAgICAgIFtuZ0NsYXNzXT1cInsnYWRmLWhvdmVyJyA6ICFpc1BhbmVsT3Blbltjb2xJbmRleF19XCI+XG4gICAgICAgICAgICA8bWF0LWNoZWNrYm94IGNsYXNzPVwiYWRmLWFzcGVjdC1saXN0LWNoZWNrLWJ1dHRvblwiIFtpZF09XCInYXNwZWN0LWxpc3QtJytjb2xJbmRleCsnLWNoZWNrJ1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgIFtjaGVja2VkXT1cIm5vZGVBc3BlY3RzPy5pbmNsdWRlcyhhc3BlY3Q/LmVudHJ5Py5pZClcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAoY2xpY2spPVwib25DaGVja0JveENsaWNrKCRldmVudClcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICBbYXJpYS1sYWJlbF09XCJnZXRUaXRsZShhc3BlY3QpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgKGNoYW5nZSk9XCJvbkNoYW5nZSgkZXZlbnQsIGFzcGVjdD8uZW50cnk/LmlkKVwiLz5cbiAgICAgICAgICAgIDxtYXQtZXhwYW5zaW9uLXBhbmVsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbaWRdPVwiJ2FzcGVjdC1saXN0LScrZ2V0SWQoYXNwZWN0KVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImFkZi1hY2NvcmRpb24tYXNwZWN0LWxpc3QtZXhwYW5zaW9uLXBhbmVsXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChvcGVuZWQpPVwiaXNQYW5lbE9wZW5bY29sSW5kZXhdID0gdHJ1ZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoYWZ0ZXJDb2xsYXBzZSk9XCJpc1BhbmVsT3Blbltjb2xJbmRleF0gPSBmYWxzZVwiXG4gICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgPG1hdC1leHBhbnNpb24tcGFuZWwtaGVhZGVyIGNsYXNzPSdhZGYtYWNjb3JkaW9uLWFzcGVjdC1saXN0LWV4cGFuc2lvbi1wYW5lbC1oZWFkZXInXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtpZF09XCInYXNwZWN0LWxpc3QtJysoZ2V0SWQoYXNwZWN0KSkrJ2hlYWRlcidcIj5cbiAgICAgICAgICAgICAgICAgICAgPG1hdC1wYW5lbC10aXRsZSBjbGFzcz1cImFkZi1hY2NvcmRpb24tYXNwZWN0LWxpc3QtZXhwYW5zaW9uLXBhbmVsLWhlYWRlci10aXRsZVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAge3tnZXRUaXRsZShhc3BlY3QpfX1cbiAgICAgICAgICAgICAgICAgICAgPC9tYXQtcGFuZWwtdGl0bGU+XG4gICAgICAgICAgICAgICAgICAgIDxtYXQtcGFuZWwtZGVzY3JpcHRpb25cbiAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiYWRmLWFjY29yZGlvbi1hc3BlY3QtbGlzdC1leHBhbnNpb24tcGFuZWwtaGVhZGVyLWRlc2NyaXB0aW9uXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIFtpZF09XCInYXNwZWN0LWxpc3QtJytjb2xJbmRleCsnLXRpdGxlJ1wiXG4gICAgICAgICAgICAgICAgICAgICAgICBbdGl0bGVdPVwiZ2V0VGl0bGUoYXNwZWN0KVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAge3tnZXRUaXRsZShhc3BlY3QpfX1cbiAgICAgICAgICAgICAgICAgICAgPC9tYXQtcGFuZWwtZGVzY3JpcHRpb24+XG4gICAgICAgICAgICAgICAgPC9tYXQtZXhwYW5zaW9uLXBhbmVsLWhlYWRlcj5cbiAgICAgICAgICAgICAgICA8cCBjbGFzcz1cImFkZi1wcm9wZXJ0eS1wYXJhZ3JhcGhcIiBbaWRdPVwiJ2FzcGVjdC1saXN0LScrY29sSW5kZXgrJy1kZXNjcmlwdGlvbidcIj4ge3thc3BlY3Q/LmVudHJ5Py5kZXNjcmlwdGlvbn19PC9wPlxuXG4gICAgICAgICAgICAgICAgPHRhYmxlIG1hdC10YWJsZSBbZGF0YVNvdXJjZV09XCJhc3BlY3Q/LmVudHJ5Py5wcm9wZXJ0aWVzXCIgKm5nSWY9XCJhc3BlY3Q/LmVudHJ5Py5wcm9wZXJ0aWVzPy5sZW5ndGggPiAwXCIgY2xhc3M9XCJhZGYtYXNwZWN0LXByb3BlcnR5LXRhYmxlXCIgW2lkXT1cIidhc3BlY3QtbGlzdC0nK2NvbEluZGV4KyctcHJvcGVydGllcy10YWJsZSdcIj5cbiAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciBtYXRDb2x1bW5EZWY9XCJuYW1lXCI+XG4gICAgICAgICAgICAgICAgICAgICAgPHRoIGNsYXNzPVwiYWRmLWFzcGVjdC1wcm9wZXJ0eS10YWJsZS1jb2x1bW4tbmFtZVwiIG1hdC1oZWFkZXItY2VsbCAqbWF0SGVhZGVyQ2VsbERlZj4ge3snQURGLUFTUEVDVC1MSVNULlBST1BFUlRZX05BTUUnIHwgdHJhbnNsYXRlfX0gPC90aD5cbiAgICAgICAgICAgICAgICAgICAgICA8dGQgY2xhc3M9XCJhZGYtYXNwZWN0LXByb3BlcnR5LXRhYmxlLWNvbHVtbi1uYW1lIGFkZi1hc3BlY3QtcHJvcGVydHktdGFibGUtY2VsbFwiIG1hdC1jZWxsICptYXRDZWxsRGVmPVwibGV0IHByb3BlcnR5XCI+IHt7cHJvcGVydHkuaWR9fSA8L3RkPlxuICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciBtYXRDb2x1bW5EZWY9XCJ0aXRsZVwiPlxuICAgICAgICAgICAgICAgICAgICAgIDx0aCBjbGFzcz1cImFkZi1hc3BlY3QtcHJvcGVydHktdGFibGUtY29sdW1uLXRpdGxlXCIgbWF0LWhlYWRlci1jZWxsICptYXRIZWFkZXJDZWxsRGVmPiB7eydBREYtQVNQRUNULUxJU1QuREVTQ1JJUFRJT04nIHwgdHJhbnNsYXRlfX0gPC90aD5cbiAgICAgICAgICAgICAgICAgICAgICA8dGQgY2xhc3M9XCJhZGYtYXNwZWN0LXByb3BlcnR5LXRhYmxlLWNvbHVtbi10aXRsZSBhZGYtYXNwZWN0LXByb3BlcnR5LXRhYmxlLWNlbGxcIiBtYXQtY2VsbCAqbWF0Q2VsbERlZj1cImxldCBwcm9wZXJ0eVwiPiB7e3Byb3BlcnR5LnRpdGxlfX0gPC90ZD5cbiAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgbWF0Q29sdW1uRGVmPVwiZGF0YVR5cGVcIj5cbiAgICAgICAgICAgICAgICAgICAgICA8dGggY2xhc3M9XCJhZGYtYXNwZWN0LXByb3BlcnR5LXRhYmxlLWNvbHVtbi1kYXRhLXR5cGVcIiBtYXQtaGVhZGVyLWNlbGwgKm1hdEhlYWRlckNlbGxEZWY+IHt7J0FERi1BU1BFQ1QtTElTVC5EQVRBX1RZUEUnIHwgdHJhbnNsYXRlfX0gPC90aD5cbiAgICAgICAgICAgICAgICAgICAgICA8dGQgY2xhc3M9XCJhZGYtYXNwZWN0LXByb3BlcnR5LXRhYmxlLWNvbHVtbi1kYXRhLXR5cGUgYWRmLWFzcGVjdC1wcm9wZXJ0eS10YWJsZS1jZWxsXCIgbWF0LWNlbGwgKm1hdENlbGxEZWY9XCJsZXQgcHJvcGVydHlcIj4ge3twcm9wZXJ0eS5kYXRhVHlwZX19IDwvdGQ+XG4gICAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgICAgICAgICA8dHIgbWF0LWhlYWRlci1yb3cgKm1hdEhlYWRlclJvd0RlZj1cInByb3BlcnR5Q29sdW1uc1wiPjwvdHI+XG4gICAgICAgICAgICAgICAgICAgIDx0ciBtYXQtcm93ICptYXRSb3dEZWY9XCJsZXQgcm93OyBjb2x1bW5zOiBwcm9wZXJ0eUNvbHVtbnM7XCI+PC90cj5cbiAgICAgICAgICAgICAgICAgIDwvdGFibGU+XG4gICAgICAgICAgICA8L21hdC1leHBhbnNpb24tcGFuZWw+XG4gICAgICAgIDwvZGl2PlxuICAgIDwvbWF0LWFjY29yZGlvbj5cbjwvZGl2PlxuXG48bmctdGVtcGxhdGUgI2xvYWRpbmc+XG4gICAgPGRpdiBjbGFzcz1cImFkZi1hc3BlY3QtbGlzdC1zcGlubmVyXCI+XG4gICAgICAgPG1hdC1wcm9ncmVzcy1zcGlubmVyIG1vZGU9XCJpbmRldGVybWluYXRlXCIgaWQ9XCJhZGYtYXNwZWN0LXNwaW5uZXJcIiAvPlxuICAgIDwvZGl2PlxuPC9uZy10ZW1wbGF0ZT5cbiJdfQ==