@clr/angular
Version:
Angular components for Clarity
203 lines • 22.9 kB
JavaScript
/*
* Copyright (c) 2016-2023 VMware, Inc. All Rights Reserved.
* This software is released under MIT license.
* The full license information can be found in LICENSE in the root directory of this project.
*/
import { Component, ElementRef, ViewChild } from '@angular/core';
import { uniqueIdFactory } from '../../utils/id-generator/id-generator.service';
import { ClrAlignment } from '../../utils/popover/enums/alignment.enum';
import { ClrAxis } from '../../utils/popover/enums/axis.enum';
import { ClrSide } from '../../utils/popover/enums/side.enum';
import { ClrPopoverHostDirective } from '../../utils/popover/popover-host.directive';
import { columnToggleTrackByFn } from './datagrid-column-toggle-trackby';
import { DatagridColumnChanges } from './enums/column-changes.enum';
import * as i0 from "@angular/core";
import * as i1 from "../../utils/i18n/common-strings.service";
import * as i2 from "./providers/columns.service";
import * as i3 from "../../utils/popover/providers/popover-toggle.service";
import * as i4 from "../../utils/popover/popover-host.directive";
import * as i5 from "@angular/common";
import * as i6 from "../../utils/cdk/cdk-trap-focus.module";
import * as i7 from "../../icon/icon";
import * as i8 from "../../forms/common/label";
import * as i9 from "../../forms/checkbox/checkbox";
import * as i10 from "../../forms/checkbox/checkbox-wrapper";
import * as i11 from "@angular/forms";
import * as i12 from "../../utils/popover/popover-anchor";
import * as i13 from "../../utils/popover/popover-close-button";
import * as i14 from "../../utils/popover/popover-open-close-button";
import * as i15 from "../../utils/popover/popover-content";
import * as i16 from "./datagrid-items-trackby";
import * as i17 from "./datagrid-column-toggle-button";
export class ClrDatagridColumnToggle {
constructor(commonStrings, columnsService, popoverToggleService) {
this.commonStrings = commonStrings;
this.columnsService = columnsService;
this.popoverId = uniqueIdFactory();
// Smart Popover
this.smartPosition = {
axis: ClrAxis.VERTICAL,
side: ClrSide.BEFORE,
anchor: ClrAlignment.START,
content: ClrAlignment.START,
};
// Without tracking the checkboxes get rerendered on model update, which leads
// to loss of focus after checkbox toggle.
this.trackByFn = columnToggleTrackByFn;
this.subscription = popoverToggleService.openChange.subscribe(change => (this.openState = change));
}
get allColumnsVisible() {
return this._allColumnsVisible;
}
set allColumnsVisible(value) {
this._allColumnsVisible = value;
}
get hideableColumnStates() {
const hideables = this.columnsService.columns.filter(column => column.value.hideable);
return hideables.map(column => column.value);
}
get hasOnlyOneVisibleColumn() {
const nbNonHideableColumns = this.columnsService.columns.length - this.hideableColumnStates.length;
// this should only return true when there is no non-hideable columns.
return (nbNonHideableColumns === 0 && this.hideableColumnStates.filter(columnState => !columnState.hidden).length === 1);
}
ngOnDestroy() {
this.subscription.unsubscribe();
}
toggleColumnState(columnState, event) {
const columnToToggle = this.columnsService.columns.filter(column => column.value === columnState)[0];
this.columnsService.emitStateChange(columnToToggle, {
hidden: event,
changes: [DatagridColumnChanges.HIDDEN],
});
}
toggleSwitchPanel() {
this.openState = !this.openState;
}
allColumnsSelected() {
this.allSelectedElement.nativeElement.focus();
}
}
ClrDatagridColumnToggle.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrDatagridColumnToggle, deps: [{ token: i1.ClrCommonStringsService }, { token: i2.ColumnsService }, { token: i3.ClrPopoverToggleService }], target: i0.ɵɵFactoryTarget.Component });
ClrDatagridColumnToggle.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.2", type: ClrDatagridColumnToggle, selector: "clr-dg-column-toggle", host: { properties: { "class.column-switch-wrapper": "true", "class.active": "openState" } }, viewQueries: [{ propertyName: "allSelectedElement", first: true, predicate: ["allSelected"], descendants: true, read: ElementRef }], hostDirectives: [{ directive: i4.ClrPopoverHostDirective }], ngImport: i0, template: `
<button
role="button"
type="button"
class="btn btn-sm column-toggle--action"
clrPopoverAnchor
clrPopoverOpenCloseButton
[attr.aria-controls]="popoverId"
[attr.aria-owns]="popoverId"
[attr.aria-expanded]="openState"
>
{{ commonStrings.keys.pickColumns }}
</button>
<div
class="column-switch"
role="dialog"
[attr.aria-label]="commonStrings.keys.showColumnsMenuDescription"
[id]="popoverId"
cdkTrapFocus
*clrPopoverContent="openState; at: smartPosition; outsideClickToClose: true; scrollToClose: true"
>
<div class="switch-header">
<div class="clr-sr-only" tabindex="-1" #allSelected>{{ commonStrings.keys.allColumnsSelected }}</div>
<h2>{{ commonStrings.keys.showColumns }}</h2>
<button
class="btn btn-sm btn-link toggle-switch-close-button"
clrPopoverCloseButton
type="button"
[attr.aria-label]="commonStrings.keys.close"
>
<cds-icon shape="window-close" aria-hidden="true" [attr.title]="commonStrings.keys.close"></cds-icon>
<span class="clr-sr-only">{{ commonStrings.keys.close }}</span>
</button>
</div>
<ul class="switch-content list-unstyled">
<li *ngFor="let columnState of hideableColumnStates; trackBy: trackByFn">
<clr-checkbox-wrapper>
<input
clrCheckbox
type="checkbox"
[disabled]="hasOnlyOneVisibleColumn && !columnState.hidden"
[ngModel]="!columnState.hidden"
(ngModelChange)="toggleColumnState(columnState, !$event)"
/>
<label>
<ng-template [ngTemplateOutlet]="columnState.titleTemplateRef"></ng-template>
</label>
</clr-checkbox-wrapper>
</li>
</ul>
<div class="switch-footer">
<clr-dg-column-toggle-button (clrAllSelected)="allColumnsSelected()"></clr-dg-column-toggle-button>
</div>
</div>
`, isInline: true, dependencies: [{ kind: "directive", type: i5.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i5.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i6.CdkTrapFocusModule_CdkTrapFocus, selector: "[cdkTrapFocus]" }, { kind: "directive", type: i7.CdsIconCustomTag, selector: "cds-icon" }, { kind: "directive", type: i8.ClrLabel, selector: "label", inputs: ["for"] }, { kind: "directive", type: i9.ClrCheckbox, selector: "[clrCheckbox],[clrToggle]" }, { kind: "component", type: i10.ClrCheckboxWrapper, selector: "clr-checkbox-wrapper,clr-toggle-wrapper" }, { kind: "directive", type: i11.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i11.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i11.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i12.ClrPopoverAnchor, selector: "[clrPopoverAnchor]" }, { kind: "directive", type: i13.ClrPopoverCloseButton, selector: "[clrPopoverCloseButton]", outputs: ["clrPopoverOnCloseChange"] }, { kind: "directive", type: i14.ClrPopoverOpenCloseButton, selector: "[clrPopoverOpenCloseButton]", outputs: ["clrPopoverOpenCloseChange"] }, { kind: "directive", type: i15.ClrPopoverContent, selector: "[clrPopoverContent]", inputs: ["clrPopoverContent", "clrPopoverContentAt", "clrPopoverContentOutsideClickToClose", "clrPopoverContentScrollToClose"] }, { kind: "directive", type: i16.ClrDatagridItemsTrackBy, selector: "[ngForTrackBy]", inputs: ["ngForTrackBy"] }, { kind: "component", type: i17.ClrDatagridColumnToggleButton, selector: "clr-dg-column-toggle-button", outputs: ["clrAllSelected"] }] });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: ClrDatagridColumnToggle, decorators: [{
type: Component,
args: [{
selector: 'clr-dg-column-toggle',
template: `
<button
role="button"
type="button"
class="btn btn-sm column-toggle--action"
clrPopoverAnchor
clrPopoverOpenCloseButton
[attr.aria-controls]="popoverId"
[attr.aria-owns]="popoverId"
[attr.aria-expanded]="openState"
>
{{ commonStrings.keys.pickColumns }}
</button>
<div
class="column-switch"
role="dialog"
[attr.aria-label]="commonStrings.keys.showColumnsMenuDescription"
[id]="popoverId"
cdkTrapFocus
*clrPopoverContent="openState; at: smartPosition; outsideClickToClose: true; scrollToClose: true"
>
<div class="switch-header">
<div class="clr-sr-only" tabindex="-1" #allSelected>{{ commonStrings.keys.allColumnsSelected }}</div>
<h2>{{ commonStrings.keys.showColumns }}</h2>
<button
class="btn btn-sm btn-link toggle-switch-close-button"
clrPopoverCloseButton
type="button"
[attr.aria-label]="commonStrings.keys.close"
>
<cds-icon shape="window-close" aria-hidden="true" [attr.title]="commonStrings.keys.close"></cds-icon>
<span class="clr-sr-only">{{ commonStrings.keys.close }}</span>
</button>
</div>
<ul class="switch-content list-unstyled">
<li *ngFor="let columnState of hideableColumnStates; trackBy: trackByFn">
<clr-checkbox-wrapper>
<input
clrCheckbox
type="checkbox"
[disabled]="hasOnlyOneVisibleColumn && !columnState.hidden"
[ngModel]="!columnState.hidden"
(ngModelChange)="toggleColumnState(columnState, !$event)"
/>
<label>
<ng-template [ngTemplateOutlet]="columnState.titleTemplateRef"></ng-template>
</label>
</clr-checkbox-wrapper>
</li>
</ul>
<div class="switch-footer">
<clr-dg-column-toggle-button (clrAllSelected)="allColumnsSelected()"></clr-dg-column-toggle-button>
</div>
</div>
`,
host: { '[class.column-switch-wrapper]': 'true', '[class.active]': 'openState' },
hostDirectives: [ClrPopoverHostDirective],
}]
}], ctorParameters: function () { return [{ type: i1.ClrCommonStringsService }, { type: i2.ColumnsService }, { type: i3.ClrPopoverToggleService }]; }, propDecorators: { allSelectedElement: [{
type: ViewChild,
args: ['allSelected', { read: ElementRef }]
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGF0YWdyaWQtY29sdW1uLXRvZ2dsZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2FuZ3VsYXIvc3JjL2RhdGEvZGF0YWdyaWQvZGF0YWdyaWQtY29sdW1uLXRvZ2dsZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7OztHQUlHO0FBRUgsT0FBTyxFQUFFLFNBQVMsRUFBRSxVQUFVLEVBQWEsU0FBUyxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBSTVFLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSwrQ0FBK0MsQ0FBQztBQUNoRixPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sMENBQTBDLENBQUM7QUFDeEUsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLHFDQUFxQyxDQUFDO0FBQzlELE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSxxQ0FBcUMsQ0FBQztBQUU5RCxPQUFPLEVBQUUsdUJBQXVCLEVBQUUsTUFBTSw0Q0FBNEMsQ0FBQztBQUVyRixPQUFPLEVBQUUscUJBQXFCLEVBQUUsTUFBTSxrQ0FBa0MsQ0FBQztBQUN6RSxPQUFPLEVBQUUscUJBQXFCLEVBQUUsTUFBTSw2QkFBNkIsQ0FBQzs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQWdFcEUsTUFBTSxPQUFPLHVCQUF1QjtJQXFCbEMsWUFDUyxhQUFzQyxFQUNyQyxjQUE4QixFQUN0QyxvQkFBNkM7UUFGdEMsa0JBQWEsR0FBYixhQUFhLENBQXlCO1FBQ3JDLG1CQUFjLEdBQWQsY0FBYyxDQUFnQjtRQXRCeEMsY0FBUyxHQUFHLGVBQWUsRUFBRSxDQUFDO1FBRzlCLGdCQUFnQjtRQUNoQixrQkFBYSxHQUF1QjtZQUNsQyxJQUFJLEVBQUUsT0FBTyxDQUFDLFFBQVE7WUFDdEIsSUFBSSxFQUFFLE9BQU8sQ0FBQyxNQUFNO1lBQ3BCLE1BQU0sRUFBRSxZQUFZLENBQUMsS0FBSztZQUMxQixPQUFPLEVBQUUsWUFBWSxDQUFDLEtBQUs7U0FDNUIsQ0FBQztRQUVG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LCBJbmMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKiBUaGlzIHNvZnR3YXJlIGlzIHJlbGVhc2VkIHVuZGVyIE1JVCBsaWNlbnNlLlxuICogVGhlIGZ1bGwgbGljZW5zZSBpbmZvcm1hdGlvbiBjYW4gYmUgZm91bmQgaW4gTElDRU5TRSBpbiB0aGUgcm9vdCBkaXJlY3Rvcnkgb2YgdGhpcyBwcm9qZWN0LlxuICovXG5cbmltcG9ydCB7IENvbXBvbmVudCwgRWxlbWVudFJlZiwgT25EZXN0cm95LCBWaWV3Q2hpbGQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IFN1YnNjcmlwdGlvbiB9IGZyb20gJ3J4anMnO1xuXG5pbXBvcnQgeyBDbHJDb21tb25TdHJpbmdzU2VydmljZSB9IGZyb20gJy4uLy4uL3V0aWxzL2kxOG4vY29tbW9uLXN0cmluZ3Muc2VydmljZSc7XG5pbXBvcnQgeyB1bmlxdWVJZEZhY3RvcnkgfSBmcm9tICcuLi8uLi91dGlscy9pZC1nZW5lcmF0b3IvaWQtZ2VuZXJhdG9yLnNlcnZpY2UnO1xuaW1wb3J0IHsgQ2xyQWxpZ25tZW50IH0gZnJvbSAnLi4vLi4vdXRpbHMvcG9wb3Zlci9lbnVtcy9hbGlnbm1lbnQuZW51bSc7XG5pbXBvcnQgeyBDbHJBeGlzIH0gZnJvbSAnLi4vLi4vdXRpbHMvcG9wb3Zlci9lbnVtcy9heGlzLmVudW0nO1xuaW1wb3J0IHsgQ2xyU2lkZSB9IGZyb20gJy4uLy4uL3V0aWxzL3BvcG92ZXIvZW51bXMvc2lkZS5lbnVtJztcbmltcG9ydCB7IENsclBvcG92ZXJQb3NpdGlvbiB9IGZyb20gJy4uLy4uL3V0aWxzL3BvcG92ZXIvaW50ZXJmYWNlcy9wb3BvdmVyLXBvc2l0aW9uLmludGVyZmFjZSc7XG5pbXBvcnQgeyBDbHJQb3BvdmVySG9zdERpcmVjdGl2ZSB9IGZyb20gJy4uLy4uL3V0aWxzL3BvcG92ZXIvcG9wb3Zlci1ob3N0LmRpcmVjdGl2ZSc7XG5pbXBvcnQgeyBDbHJQb3BvdmVyVG9nZ2xlU2VydmljZSB9IGZyb20gJy4uLy4uL3V0aWxzL3BvcG92ZXIvcHJvdmlkZXJzL3BvcG92ZXItdG9nZ2xlLnNlcnZpY2UnO1xuaW1wb3J0IHsgY29sdW1uVG9nZ2xlVHJhY2tCeUZuIH0gZnJvbSAnLi9kYXRhZ3JpZC1jb2x1bW4tdG9nZ2xlLXRyYWNrYnknO1xuaW1wb3J0IHsgRGF0YWdyaWRDb2x1bW5DaGFuZ2VzIH0gZnJvbSAnLi9lbnVtcy9jb2x1bW4tY2hhbmdlcy5lbnVtJztcbmltcG9ydCB7IENvbHVtblN0YXRlIH0gZnJvbSAnLi9pbnRlcmZhY2VzL2NvbHVtbi1zdGF0ZS5pbnRlcmZhY2UnO1xuaW1wb3J0IHsgQ29sdW1uc1NlcnZpY2UgfSBmcm9tICcuL3Byb3ZpZGVycy9jb2x1bW5zLnNlcnZpY2UnO1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdjbHItZGctY29sdW1uLXRvZ2dsZScsXG4gIHRlbXBsYXRlOiBgXG4gICAgPGJ1dHRvblxuICAgICAgcm9sZT1cImJ1dHRvblwiXG4gICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgIGNsYXNzPVwiYnRuIGJ0bi1zbSBjb2x1bW4tdG9nZ2xlLS1hY3Rpb25cIlxuICAgICAgY2xyUG9wb3ZlckFuY2hvclxuICAgICAgY2xyUG9wb3Zlck9wZW5DbG9zZUJ1dHRvblxuICAgICAgW2F0dHIuYXJpYS1jb250cm9sc109XCJwb3BvdmVySWRcIlxuICAgICAgW2F0dHIuYXJpYS1vd25zXT1cInBvcG92ZXJJZFwiXG4gICAgICBbYXR0ci5hcmlhLWV4cGFuZGVkXT1cIm9wZW5TdGF0ZVwiXG4gICAgPlxuICAgICAge3sgY29tbW9uU3RyaW5ncy5rZXlzLnBpY2tDb2x1bW5zIH19XG4gICAgPC9idXR0b24+XG4gICAgPGRpdlxuICAgICAgY2xhc3M9XCJjb2x1bW4tc3dpdGNoXCJcbiAgICAgIHJvbGU9XCJkaWFsb2dcIlxuICAgICAgW2F0dHIuYXJpYS1sYWJlbF09XCJjb21tb25TdHJpbmdzLmtleXMuc2hvd0NvbHVtbnNNZW51RGVzY3JpcHRpb25cIlxuICAgICAgW2lkXT1cInBvcG92ZXJJZFwiXG4gICAgICBjZGtUcmFwRm9jdXNcbiAgICAgICpjbHJQb3BvdmVyQ29udGVudD1cIm9wZW5TdGF0ZTsgYXQ6IHNtYXJ0UG9zaXRpb247IG91dHNpZGVDbGlja1RvQ2xvc2U6IHRydWU7IHNjcm9sbFRvQ2xvc2U6IHRydWVcIlxuICAgID5cbiAgICAgIDxkaXYgY2xhc3M9XCJzd2l0Y2gtaGVhZGVyXCI+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJjbHItc3Itb25seVwiIHRhYmluZGV4PVwiLTFcIiAjYWxsU2VsZWN0ZWQ+e3sgY29tbW9uU3RyaW5ncy5rZXlzLmFsbENvbHVtbnNTZWxlY3RlZCB9fTwvZGl2PlxuICAgICAgICA8aDI+e3sgY29tbW9uU3RyaW5ncy5rZXlzLnNob3dDb2x1bW5zIH19PC9oMj5cbiAgICAgICAgPGJ1dHRvblxuICAgICAgICAgIGNsYXNzPVwiYnRuIGJ0bi1zbSBidG4tbGluayB0b2dnbGUtc3dpdGNoLWNsb3NlLWJ1dHRvblwiXG4gICAgICAgICAgY2xyUG9wb3ZlckNsb3NlQnV0dG9uXG4gICAgICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgICAgW2F0dHIuYXJpYS1sYWJlbF09XCJjb21tb25TdHJpbmdzLmtleXMuY2xvc2VcIlxuICAgICAgICA+XG4gICAgICAgICAgPGNkcy1pY29uIHNoYXBlPVwid2luZG93LWNsb3NlXCIgYXJpYS1oaWRkZW49XCJ0cnVlXCIgW2F0dHIudGl0bGVdPVwiY29tbW9uU3RyaW5ncy5rZXlzLmNsb3NlXCI+PC9jZHMtaWNvbj5cbiAgICAgICAgICA8c3BhbiBjbGFzcz1cImNsci1zci1vbmx5XCI+e3sgY29tbW9uU3RyaW5ncy5rZXlzLmNsb3NlIH19PC9zcGFuPlxuICAgICAgICA8L2J1dHRvbj5cbiAgICAgIDwvZGl2PlxuICAgICAgPHVsIGNsYXNzPVwic3dpdGNoLWNvbnRlbnQgbGlzdC11bnN0eWxlZFwiPlxuICAgICAgICA8bGkgKm5nRm9yPVwibGV0IGNvbHVtblN0YXRlIG9mIGhpZGVhYmxlQ29sdW1uU3RhdGVzOyB0cmFja0J5OiB0cmFja0J5Rm5cIj5cbiAgICAgICAgICA8Y2xyLWNoZWNrYm94LXdyYXBwZXI+XG4gICAgICAgICAgICA8aW5wdXRcbiAgICAgICAgICAgICAgY2xyQ2hlY2tib3hcbiAgICAgICAgICAgICAgdHlwZT1cImNoZWNrYm94XCJcbiAgICAgICAgICAgICAgW2Rpc2FibGVkXT1cImhhc09ubHlPbmVWaXNpYmxlQ29sdW1uICYmICFjb2x1bW5TdGF0ZS5oaWRkZW5cIlxuICAgICAgICAgICAgICBbbmdNb2RlbF09XCIhY29sdW1uU3RhdGUuaGlkZGVuXCJcbiAgICAgICAgICAgICAgKG5nTW9kZWxDaGFuZ2UpPVwidG9nZ2xlQ29sdW1uU3RhdGUoY29sdW1uU3RhdGUsICEkZXZlbnQpXCJcbiAgICAgICAgICAgIC8+XG4gICAgICAgICAgICA8bGFiZWw+XG4gICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSBbbmdUZW1wbGF0ZU91dGxldF09XCJjb2x1bW5TdGF0ZS50aXRsZVRlbXBsYXRlUmVmXCI+PC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgICAgIDwvbGFiZWw+XG4gICAgICAgICAgPC9jbHItY2hlY2tib3gtd3JhcHBlcj5cbiAgICAgICAgPC9saT5cbiAgICAgIDwvdWw+XG4gICAgICA8ZGl2IGNsYXNzPVwic3dpdGNoLWZvb3RlclwiPlxuICAgICAgICA8Y2xyLWRnLWNvbHVtbi10b2dnbGUtYnV0dG9uIChjbHJBbGxTZWxlY3RlZCk9XCJhbGxDb2x1bW5zU2VsZWN0ZWQoKVwiPjwvY2xyLWRnLWNvbHVtbi10b2dnbGUtYnV0dG9uPlxuICAgICAgPC9kaXY+XG4gICAgPC9kaXY+XG4gIGAsXG4gIGhvc3Q6IHsgJ1tjbGFzcy5jb2x1bW4tc3dpdGNoLXdyYXBwZXJdJzogJ3RydWUnLCAnW2NsYXNzLmFjdGl2ZV0nOiAnb3BlblN0YXRlJyB9LFxuICBob3N0RGlyZWN0aXZlczogW0NsclBvcG92ZXJIb3N0RGlyZWN0aXZlXSxcbn0pXG5leHBvcnQgY2xhc3MgQ2xyRGF0YWdyaWRDb2x1bW5Ub2dnbGUgaW1wbGVtZW50cyBPbkRlc3Ryb3kge1xuICBwb3BvdmVySWQgPSB1bmlxdWVJZEZhY3RvcnkoKTtcbiAgb3BlblN0YXRlOiBib29sZWFuO1xuXG4gIC8vIFNtYXJ0IFBvcG92ZXJcbiAgc21hcnRQb3NpdGlvbjogQ2xyUG9wb3ZlclBvc2l0aW9uID0ge1xuICAgIGF4aXM6IENsckF4aXMuVkVSVElDQUwsXG4gICAgc2lkZTogQ2xyU2lkZS5CRUZPUkUsXG4gICAgYW5jaG9yOiBDbHJBbGlnbm1lbnQuU1RBUlQsXG4gICAgY29udGVudDogQ2xyQWxpZ25tZW50LlNUQVJULFxuICB9O1xuXG4gIC8vIFdpdGhvdXQgdHJhY2tpbmcgdGhlIGNoZWNrYm94ZXMgZ2V0IHJlcmVuZGVyZWQgb24gbW9kZWwgdXBkYXRlLCB3aGljaCBsZWFkc1xuICAvLyB0byBsb3NzIG9mIGZvY3VzIGFmdGVyIGNoZWNrYm94IHRvZ2dsZS5cbiAgcmVhZG9ubHkgdHJhY2tCeUZuID0gY29sdW1uVG9nZ2xlVHJhY2tCeUZuO1xuXG4gIHByaXZhdGUgX2FsbENvbHVtbnNWaXNpYmxlOiBib29sZWFuO1xuICBwcml2YXRlIHN1YnNjcmlwdGlvbjogU3Vic2NyaXB0aW9uO1xuXG4gIEBWaWV3Q2hpbGQoJ2FsbFNlbGVjdGVkJywgeyByZWFkOiBFbGVtZW50UmVmIH0pIHByaXZhdGUgYWxsU2VsZWN0ZWRFbGVtZW50OiBFbGVtZW50UmVmPEhUTUxFbGVtZW50PjtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBwdWJsaWMgY29tbW9uU3RyaW5nczogQ2xyQ29tbW9uU3RyaW5nc1NlcnZpY2UsXG4gICAgcHJpdmF0ZSBjb2x1bW5zU2VydmljZTogQ29sdW1uc1NlcnZpY2UsXG4gICAgcG9wb3ZlclRvZ2dsZVNlcnZpY2U6IENsclBvcG92ZXJUb2dnbGVTZXJ2aWNlXG4gICkge1xuICAgIHRoaXMuc3Vic2NyaXB0aW9uID0gcG9wb3ZlclRvZ2dsZVNlcnZpY2Uub3BlbkNoYW5nZS5zdWJzY3JpYmUoY2hhbmdlID0+ICh0aGlzLm9wZW5TdGF0ZSA9IGNoYW5nZSkpO1xuICB9XG5cbiAgZ2V0IGFsbENvbHVtbnNWaXNpYmxlKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLl9hbGxDb2x1bW5zVmlzaWJsZTtcbiAgfVxuICBzZXQgYWxsQ29sdW1uc1Zpc2libGUodmFsdWU6IGJvb2xlYW4pIHtcbiAgICB0aGlzLl9hbGxDb2x1bW5zVmlzaWJsZSA9IHZhbHVlO1xuICB9XG5cbiAgZ2V0IGhpZGVhYmxlQ29sdW1uU3RhdGVzKCk6IENvbHVtblN0YXRlW10ge1xuICAgIGNvbnN0IGhpZGVhYmxlcyA9IHRoaXMuY29sdW1uc1NlcnZpY2UuY29sdW1ucy5maWx0ZXIoY29sdW1uID0+IGNvbHVtbi52YWx1ZS5oaWRlYWJsZSk7XG4gICAgcmV0dXJuIGhpZGVhYmxlcy5tYXAoY29sdW1uID0+IGNvbHVtbi52YWx1ZSk7XG4gIH1cblxuICBnZXQgaGFzT25seU9uZVZpc2libGVDb2x1bW4oKTogYm9vbGVhbiB7XG4gICAgY29uc3QgbmJOb25IaWRlYWJsZUNvbHVtbnMgPSB0aGlzLmNvbHVtbnNTZXJ2aWNlLmNvbHVtbnMubGVuZ3RoIC0gdGhpcy5oaWRlYWJsZUNvbHVtblN0YXRlcy5sZW5ndGg7XG4gICAgLy8gdGhpcyBzaG91bGQgb25seSByZXR1cm4gdHJ1ZSB3aGVuIHRoZXJlIGlzIG5vIG5vbi1oaWRlYWJsZSBjb2x1bW5zLlxuICAgIHJldHVybiAoXG4gICAgICBuYk5vbkhpZGVhYmxlQ29sdW1ucyA9PT0gMCAmJiB0aGlzLmhpZGVhYmxlQ29sdW1uU3RhdGVzLmZpbHRlcihjb2x1bW5TdGF0ZSA9PiAhY29sdW1uU3RhdGUuaGlkZGVuKS5sZW5ndGggPT09IDFcbiAgICApO1xuICB9XG5cbiAgbmdPbkRlc3Ryb3koKSB7XG4gICAgdGhpcy5zdWJzY3JpcHRpb24udW5zdWJzY3JpYmUoKTtcbiAgfVxuXG4gIHRvZ2dsZUNvbHVtblN0YXRlKGNvbHVtblN0YXRlOiBDb2x1bW5TdGF0ZSwgZXZlbnQ6IGJvb2xlYW4pIHtcbiAgICBjb25zdCBjb2x1bW5Ub1RvZ2dsZSA9IHRoaXMuY29sdW1uc1NlcnZpY2UuY29sdW1ucy5maWx0ZXIoY29sdW1uID0+IGNvbHVtbi52YWx1ZSA9PT0gY29sdW1uU3RhdGUpWzBdO1xuICAgIHRoaXMuY29sdW1uc1NlcnZpY2UuZW1pdFN0YXRlQ2hhbmdlKGNvbHVtblRvVG9nZ2xlLCB7XG4gICAgICBoaWRkZW46IGV2ZW50LFxuICAgICAgY2hhbmdlczogW0RhdGFncmlkQ29sdW1uQ2hhbmdlcy5ISURERU5dLFxuICAgIH0pO1xuICB9XG5cbiAgdG9nZ2xlU3dpdGNoUGFuZWwoKSB7XG4gICAgdGhpcy5vcGVuU3RhdGUgPSAhdGhpcy5vcGVuU3RhdGU7XG4gIH1cblxuICBhbGxDb2x1bW5zU2VsZWN0ZWQoKSB7XG4gICAgdGhpcy5hbGxTZWxlY3RlZEVsZW1lbnQubmF0aXZlRWxlbWVudC5mb2N1cygpO1xuICB9XG59XG4iXX0=