right-angled
Version:
Lightweight and easy to use angular data grids. Integrates with your markup and styles rather than generating its own.
225 lines • 37.5 kB
JavaScript
import { Directive, EventEmitter, HostBinding, HostListener, Input, Optional, Output, Self, SkipSelf } from '@angular/core';
import { animationFrameScheduler, EMPTY, scheduled, Subject } from 'rxjs';
import { debounce } from 'rxjs/operators';
import { RTSelectionEventsHelper } from './providers/selection-events-helper';
import { RTSelectionService } from './providers/selection.service';
import * as i0 from "@angular/core";
import * as i1 from "./providers/selection.service";
import * as i2 from "./providers/selection-events-helper";
export class SelectionAreaDirective {
set preventEventsDefaults(value) {
this.selectionEventsHelper.preventEventsDefaults = value;
}
set stopEventsPropagation(value) {
this.selectionEventsHelper.stopEventsPropagation = value;
}
set horizontal(value) {
this.selectionEventsHelper.horizontal = value;
}
set multiple(value) {
this.selectionEventsHelper.multiple = value;
}
set toggleOnly(value) {
this.selectionEventsHelper.toggleOnly = value;
}
set trackBy(value) {
if (typeof value !== 'function') {
throw new Error('trackBy parameter value must be a function');
}
this.selectionService.trackByFn = value;
}
constructor(parentSelectionArea, selectionService, selectionEventsHelper) {
this.parentSelectionArea = parentSelectionArea;
this.selectionService = selectionService;
this.selectionEventsHelper = selectionEventsHelper;
this.selectableItems = [];
this.childSelectionCheckboxes = [];
this.childSelectionAreas = new Set();
this.selectablesChangedSubject = new Subject();
this.childSelectionAreasChangedSubject = new Subject();
this.tabIndex = 0;
this.autoSelectFirst = false;
this.itemSelected = new EventEmitter();
this.itemDeselected = new EventEmitter();
this.selectionChanged = new EventEmitter();
this.selectionService.areaEventsEmitter = this;
this.selectionEventsHelper = selectionEventsHelper;
}
ngOnInit() {
this.selectablesChangedSubscription = this.selectablesChangedSubject.pipe(debounce(() => scheduled(EMPTY, animationFrameScheduler))).subscribe(items => this.buildSelectionSource(items));
this.childSelectionAreasChangedSubscription = this.childSelectionAreasChangedSubject.pipe(debounce(() => scheduled(EMPTY, animationFrameScheduler))).subscribe(items => this.buildSelectionServicesList(items));
}
ngAfterViewInit() {
this.parentSelectionArea?.registerChildSelectionArea(this);
}
ngOnDestroy() {
this.selectionService.deselectAll();
this.selectionService.destroy();
this.parentSelectionArea?.unregisterChildSelectionArea(this);
this.selectablesChangedSubscription?.unsubscribe();
this.childSelectionAreasChangedSubscription?.unsubscribe();
}
ngOnChanges(changes) {
if (false === this.selectionService.hasSelections() && changes.autoSelectFirst && changes.autoSelectFirst.currentValue === true) {
this.selectionService.selectIndex(0, false);
}
if (changes.multiple && changes.multiple.currentValue === false) {
const selectedIndexes = this.selectionService.getSelectedIndexes();
if (selectedIndexes.length > 1) {
selectedIndexes.splice(0, 1);
selectedIndexes.forEach(index => {
this.selectionService.deselectIndex(index);
});
}
}
}
keyDownHandler(ctrlKeyPressed, shiftKeyPressed, keyCode, preventDefaultFn, stopPropagationFn, executionContext) {
if (this.selectionEventsHelper.keyboardHandler(ctrlKeyPressed, shiftKeyPressed, keyCode)) {
if (this.selectionEventsHelper.preventEventsDefaults && preventDefaultFn) {
preventDefaultFn.call(executionContext);
}
if (this.selectionEventsHelper.stopEventsPropagation && stopPropagationFn) {
stopPropagationFn.call(executionContext);
}
}
}
//#region callbacks for DOM descendants
registerSelectable(selectable, elementRef) {
const element = elementRef.nativeElement;
let i = 0;
for (; i < this.selectableItems.length; i++) {
if (this.selectableItems[i].element.compareDocumentPosition(element) & document.DOCUMENT_POSITION_PRECEDING) {
this.selectableItems.splice(i, 0, { element, selectable });
break;
}
}
if (i === this.selectableItems.length) {
this.selectableItems.push({ element, selectable });
}
this.selectablesChangedSubject.next(this.selectableItems.map(x => x.selectable));
}
unregisterSelectable(selectable) {
const idx = this.selectableItems.findIndex(x => x.selectable === selectable);
if (idx >= 0) {
this.selectableItems.splice(idx, 1);
}
this.selectablesChangedSubject.next(this.selectableItems.map(x => x.selectable));
}
registerSelectionCheckbox(checkbox, elementRef) {
const element = elementRef.nativeElement;
let i = 0;
for (; i < this.childSelectionCheckboxes.length; i++) {
if (this.childSelectionCheckboxes[i].element.compareDocumentPosition(element) & document.DOCUMENT_POSITION_PRECEDING) {
this.childSelectionCheckboxes.splice(i, 0, { element, selectable: checkbox });
break;
}
}
if (i === this.childSelectionCheckboxes.length) {
this.childSelectionCheckboxes.push({ element, selectable: checkbox });
}
this.selectablesChangedSubject.next(this.childSelectionCheckboxes.map(x => x.selectable));
}
unregisterSelectionCheckbox(checkbox) {
const idx = this.childSelectionCheckboxes.findIndex(x => x.selectable === checkbox);
if (idx >= 0) {
this.childSelectionCheckboxes.splice(idx, 1);
}
this.selectablesChangedSubject.next(this.childSelectionCheckboxes.map(x => x.selectable));
}
registerChildSelectionArea(selectionArea) {
if (!this.childSelectionAreas.has(selectionArea)) {
this.childSelectionAreas.add(selectionArea);
this.childSelectionAreasChangedSubject.next(this.childSelectionAreas);
}
}
unregisterChildSelectionArea(selectionArea) {
if (this.childSelectionAreas.has(selectionArea)) {
this.childSelectionAreas.delete(selectionArea);
this.childSelectionAreasChangedSubject.next(this.childSelectionAreas);
}
}
//#endregion
ngAfterContentInit() {
if (this.selectableItems.length > 0) {
this.buildSelectionSource(this.selectableItems.map(item => item.selectable));
}
if (this.childSelectionCheckboxes.length > 0) {
this.buildSelectionSource(this.childSelectionCheckboxes.map(item => item.selectable));
}
this.buildSelectionServicesList(this.childSelectionAreas);
}
buildSelectionSource(items) {
let index = 0;
this.selectionService.eventEmitters = items.map(item => {
if (item.index !== null && item.index !== index) {
this.selectionService.deselectIndex(item.index);
}
item.index = index++;
return item;
});
this.selectionService.items = items.map(item => item.item);
if (this.selectionService.items.length > 0) {
setTimeout(() => {
// since we've modify collection on first render,
// to prevent error 'Expression has changed after it was checked' we've do selection after render
if (this.selectionService.items.length > 0) {
this.selectionService.checkSelection();
// repeats first element selection since checking can deselect all elements
if (false === this.selectionService.hasSelections() && this.autoSelectFirst) {
this.selectionService.selectIndex(0, false);
}
}
}, 0);
}
}
buildSelectionServicesList(items) {
this.selectionService.childSelectionServices = Array.from(items)
.filter(area => area !== this)
.map(area => area.selectionService);
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: SelectionAreaDirective, deps: [{ token: SelectionAreaDirective, optional: true, skipSelf: true }, { token: i1.RTSelectionService, self: true }, { token: i2.RTSelectionEventsHelper, self: true }], target: i0.ɵɵFactoryTarget.Directive }); }
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.12", type: SelectionAreaDirective, selector: "[rtSelectionArea]", inputs: { preventEventsDefaults: "preventEventsDefaults", stopEventsPropagation: "stopEventsPropagation", horizontal: "horizontal", multiple: "multiple", toggleOnly: "toggleOnly", autoSelectFirst: "autoSelectFirst", trackBy: "trackBy" }, outputs: { itemSelected: "itemSelected", itemDeselected: "itemDeselected", selectionChanged: "selectionChanged" }, host: { listeners: { "keydown": "keyDownHandler($event.ctrlKey,$event.shiftKey,$event.keyCode,$event.preventDefault,$event.stopPropagation,$event)" }, properties: { "tabIndex": "this.tabIndex" } }, providers: [RTSelectionService, RTSelectionEventsHelper], exportAs: ["rtSelectionArea"], usesOnChanges: true, ngImport: i0 }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: SelectionAreaDirective, decorators: [{
type: Directive,
args: [{
exportAs: 'rtSelectionArea',
providers: [RTSelectionService, RTSelectionEventsHelper],
selector: '[rtSelectionArea]'
}]
}], ctorParameters: function () { return [{ type: SelectionAreaDirective, decorators: [{
type: SkipSelf
}, {
type: Optional
}] }, { type: i1.RTSelectionService, decorators: [{
type: Self
}] }, { type: i2.RTSelectionEventsHelper, decorators: [{
type: Self
}] }]; }, propDecorators: { tabIndex: [{
type: HostBinding,
args: ['tabIndex']
}], preventEventsDefaults: [{
type: Input
}], stopEventsPropagation: [{
type: Input
}], horizontal: [{
type: Input
}], multiple: [{
type: Input
}], toggleOnly: [{
type: Input
}], autoSelectFirst: [{
type: Input
}], trackBy: [{
type: Input
}], itemSelected: [{
type: Output
}], itemDeselected: [{
type: Output
}], selectionChanged: [{
type: Output
}], keyDownHandler: [{
type: HostListener,
args: ['keydown', ['$event.ctrlKey', '$event.shiftKey', '$event.keyCode', '$event.preventDefault', '$event.stopPropagation', '$event']]
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VsZWN0aW9uLWFyZWEuZGlyZWN0aXZlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvcmlnaHQtYW5nbGVkL3NyYy9saWIvc2VsZWN0aW9uL3NlbGVjdGlvbi1hcmVhLmRpcmVjdGl2ZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBR0gsU0FBUyxFQUVULFlBQVksRUFDWixXQUFXLEVBQ1gsWUFBWSxFQUNaLEtBQUssRUFJTCxRQUFRLEVBQ1IsTUFBTSxFQUNOLElBQUksRUFFSixRQUFRLEVBQ1gsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUFFLHVCQUF1QixFQUFFLEtBQUssRUFBRSxTQUFTLEVBQUUsT0FBTyxFQUFnQixNQUFNLE1BQU0sQ0FBQztBQUN4RixPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFHMUMsT0FBTyxFQUFFLHVCQUF1QixFQUFFLE1BQU0scUNBQXFDLENBQUM7QUFDOUUsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sK0JBQStCLENBQUM7Ozs7QUFjbkUsTUFBTSxPQUFPLHNCQUFzQjtJQVkvQixJQUNXLHFCQUFxQixDQUFDLEtBQWM7UUFDM0MsSUFBSSxDQUFDLHFCQUFxQixDQUFDLHFCQUFxQixHQUFHLEtBQUssQ0FBQztJQUM3RCxDQUFDO0lBRUQsSUFDVyxxQkFBcUIsQ0FBQyxLQUFjO1FBQzNDLElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxxQkFBcUIsR0FBRyxLQUFLLENBQUM7SUFDN0QsQ0FBQztJQUVELElBQ1csVUFBVSxDQUFDLEtBQWM7UUFDaEMsSUFBSSxDQUFDLHFCQUFxQixDQUFDLFVBQVUsR0FBRyxLQUFLLENBQUM7SUFDbEQsQ0FBQztJQUVELElBQ1csUUFBUSxDQUFDLEtBQWM7UUFDOUIsSUFBSSxDQUFDLHFCQUFxQixDQUFDLFFBQVEsR0FBRyxLQUFLLENBQUM7SUFDaEQsQ0FBQztJQUVELElBQ1csVUFBVSxD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Q29udGVudCI6WyJpbXBvcnQge1xyXG4gICAgQWZ0ZXJDb250ZW50SW5pdCxcclxuICAgIEFmdGVyVmlld0luaXQsXHJcbiAgICBEaXJlY3RpdmUsXHJcbiAgICBFbGVtZW50UmVmLFxyXG4gICAgRXZlbnRFbWl0dGVyLFxyXG4gICAgSG9zdEJpbmRpbmcsXHJcbiAgICBIb3N0TGlzdGVuZXIsXHJcbiAgICBJbnB1dCxcclxuICAgIE9uQ2hhbmdlcyxcclxuICAgIE9uRGVzdHJveSxcclxuICAgIE9uSW5pdCxcclxuICAgIE9wdGlvbmFsLFxyXG4gICAgT3V0cHV0LFxyXG4gICAgU2VsZixcclxuICAgIFNpbXBsZUNoYW5nZSxcclxuICAgIFNraXBTZWxmXHJcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcbmltcG9ydCB7IGFuaW1hdGlvbkZyYW1lU2NoZWR1bGVyLCBFTVBUWSwgc2NoZWR1bGVkLCBTdWJqZWN0LCBTdWJzY3JpcHRpb24gfSBmcm9tICdyeGpzJztcclxuaW1wb3J0IHsgZGVib3VuY2UgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XHJcblxyXG5pbXBvcnQgeyBTZWxlY3Rpb25FdmVudHNFbWl0dGVyLCBSVFNlbGVjdGlvbkV2ZW50IH0gZnJvbSAnLi9wcm92aWRlcnMvc2VsZWN0aW9uLWV2ZW50cy1lbWl0dGVyJztcclxuaW1wb3J0IHsgUlRTZWxlY3Rpb25FdmVudHNIZWxwZXIgfSBmcm9tICcuL3Byb3ZpZGVycy9zZWxlY3Rpb24tZXZlbnRzLWhlbHBlcic7XHJcbmltcG9ydCB7IFJUU2VsZWN0aW9uU2VydmljZSB9IGZyb20gJy4vcHJvdmlkZXJzL3NlbGVjdGlvbi5zZXJ2aWNlJztcclxuaW1wb3J0IHsgU2VsZWN0YWJsZURpcmVjdGl2ZSB9IGZyb20gJy4vc2VsZWN0YWJsZS5kaXJlY3RpdmUnO1xyXG5pbXBvcnQgeyBTZWxlY3Rpb25DaGVja2JveEZvckRpcmVjdGl2ZSB9IGZyb20gJy4vc2VsZWN0aW9uLWNoZWNrYm94LWZvci5kaXJlY3RpdmUnO1xyXG5cclxuaW50ZXJmYWNlIFNlbGVjdGFibGVFbGVtZW50IHtcclxuICAgIHNlbGVjdGFibGU6IFNlbGVjdGFibGVEaXJlY3RpdmUgfCBTZWxlY3Rpb25DaGVja2JveEZvckRpcmVjdGl2ZTtcclxuICAgIGVsZW1lbnQ6IEhUTUxFbGVtZW50O1xyXG59XHJcblxyXG5ARGlyZWN0aXZlKHtcclxuICAgIGV4cG9ydEFzOiAncnRTZWxlY3Rpb25BcmVhJyxcclxuICAgIHByb3ZpZGVyczogW1JUU2VsZWN0aW9uU2VydmljZSwgUlRTZWxlY3Rpb25FdmVudHNIZWxwZXJdLFxyXG4gICAgc2VsZWN0b3I6ICdbcnRTZWxlY3Rpb25BcmVhXSdcclxufSlcclxuZXhwb3J0IGNsYXNzIFNlbGVjdGlvbkFyZWFEaXJlY3RpdmUgaW1wbGVtZW50cyBTZWxlY3Rpb25FdmVudHNFbWl0dGVyLCBBZnRlckNvbnRlbnRJbml0LCBPbkNoYW5nZXMsIE9uSW5pdCwgQWZ0ZXJWaWV3SW5pdCwgT25EZXN0cm95IHtcclxuICAgIHByaXZhdGUgc2VsZWN0YWJsZUl0ZW1zOiBTZWxlY3RhYmxlRWxlbWVudFtdID0gW107XHJcbiAgICBwcml2YXRlIGNoaWxkU2VsZWN0aW9uQ2hlY2tib3hlczogU2VsZWN0YWJsZUVsZW1lbnRbXSA9IFtdO1xyXG4gICAgcHJpdmF0ZSBjaGlsZFNlbGVjdGlvbkFyZWFzID0gbmV3IFNldDxTZWxlY3Rpb25BcmVhRGlyZWN0aXZlPigpO1xyXG4gICAgcHJpdmF0ZSBzZWxlY3RhYmxlc0NoYW5nZWRTdWJzY3JpcHRpb246IFN1YnNjcmlwdGlvbjtcclxuICAgIHByaXZhdGUgc2VsZWN0YWJsZXNDaGFuZ2VkU3ViamVjdCA9IG5ldyBTdWJqZWN0PChTZWxlY3RhYmxlRGlyZWN0aXZlIHwgU2VsZWN0aW9uQ2hlY2tib3hGb3JEaXJlY3RpdmUpW10+KCk7XHJcbiAgICBwcml2YXRlIGNoaWxkU2VsZWN0aW9uQXJlYXNDaGFuZ2VkU3Vic2NyaXB0aW9uOiBTdWJzY3JpcHRpb247XHJcbiAgICBwcml2YXRlIGNoaWxkU2VsZWN0aW9uQXJlYXNDaGFuZ2VkU3ViamVjdCA9IG5ldyBTdWJqZWN0PFNldDxTZWxlY3Rpb25BcmVhRGlyZWN0aXZlPj4oKTtcclxuXHJcbiAgICBASG9zdEJpbmRpbmcoJ3RhYkluZGV4JylcclxuICAgIHB1YmxpYyB0YWJJbmRleCA9IDA7XHJcblxyXG4gICAgQElucHV0KClcclxuICAgIHB1YmxpYyBzZXQgcHJldmVudEV2ZW50c0RlZmF1bHRzKHZhbHVlOiBib29sZWFuKSB7XHJcbiAgICAgICAgdGhpcy5zZWxlY3Rpb25FdmVudHNIZWxwZXIucHJldmVudEV2ZW50c0RlZmF1bHRzID0gdmFsdWU7XHJcbiAgICB9XHJcblxyXG4gICAgQElucHV0KClcclxuICAgIHB1YmxpYyBzZXQgc3RvcEV2ZW50c1Byb3BhZ2F0aW9uKHZhbHVlOiBib29sZWFuKSB7XHJcbiAgICAgICAgdGhpcy5zZWxlY3Rpb25FdmVudHNIZWxwZXIuc3RvcEV2ZW50c1Byb3BhZ2F0aW9uID0gdmFsdWU7XHJcbiAgICB9XHJcblxyXG4gICAgQElucHV0KClcclxuICAgIHB1YmxpYyBzZXQgaG9yaXpvbnRhbCh2YWx1ZTogYm9vbGVhbikge1xyXG4gICAgICAgIHRoaXMuc2VsZWN0aW9uRXZlbnRzSGVscGVyLmhvcml6b250YWwgPSB2YWx1ZTtcclxuICAgIH1cclxuXHJcbiAgICBASW5wdXQoKVxyXG4gICAgcHVibGljIHNldCBtdWx0aXBsZSh2YWx1ZTogYm9vbGVhbikge1xyXG4gICAgICAgIHRoaXMuc2VsZWN0aW9uRXZlbnRzSGVscGVyLm11bHRpcGxlID0gdmFsdWU7XHJcbiAgICB9XHJcblxyXG4gICAgQElucHV0KClcclxuICAgIHB1YmxpYyBzZXQgdG9nZ2xlT25seSh2YWx1ZTogYm9vbGVhbikge1xyXG4gICAgICAgIHRoaXMuc2VsZWN0aW9uRXZlbnRzSGVscGVyLnRvZ2dsZU9ubHkgPSB2YWx1ZTtcclxuICAgIH1cclxuXHJcbiAgICBASW5wdXQoKVxyXG4gICAgcHVibGljIGF1dG9TZWxlY3RGaXJzdCA9IGZhbHNlO1xyXG5cclxuICAgIEBJbnB1dCgpXHJcbiAgICBwdWJsaWMgc2V0IHRyYWNrQnkodmFsdWU6IChpbmRleDogbnVtYmVyLCBpdGVtOiBhbnkpID0+IGFueSkge1xyXG4gICAgICAgIGlmICh0eXBlb2YgdmFsdWUgIT09ICdmdW5jdGlvbicpIHtcclxuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCd0cmFja0J5IHBhcmFtZXRlciB2YWx1ZSBtdXN0IGJlIGEgZnVuY3Rpb24nKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgdGhpcy5zZWxlY3Rpb25TZXJ2aWNlLnRyYWNrQnlGbiA9IHZhbHVlO1xyXG4gICAgfVxyXG5cclxuICAgIEBPdXRwdXQoKVxyXG4gICAgcHVibGljIHJlYWRvbmx5IGl0ZW1TZWxlY3RlZDogRXZlbnRFbWl0dGVyPFJUU2VsZWN0aW9uRXZlbnQ+ID0gbmV3IEV2ZW50RW1pdHRlcjxSVFNlbGVjdGlvbkV2ZW50PigpO1xyXG5cclxuICAgIEBPdXRwdXQoKVxyXG4gICAgcHVibGljIHJlYWRvbmx5IGl0ZW1EZXNlbGVjdGVkOiBFdmVudEVtaXR0ZXI8UlRTZWxlY3Rpb25FdmVudD4gPSBuZXcgRXZlbnRFbWl0dGVyPFJUU2VsZWN0aW9uRXZlbnQ+KCk7XHJcblxyXG4gICAgQE91dHB1dCgpXHJcbiAgICBwdWJsaWMgcmVhZG9ubHkgc2VsZWN0aW9uQ2hhbmdlZDogRXZlbnRFbWl0dGVyPFJUU2VsZWN0aW9uRXZlbnQ+ID0gbmV3IEV2ZW50RW1pdHRlcjxSVFNlbGVjdGlvbkV2ZW50PigpO1xyXG5cclxuICAgIGNvbnN0cnVjdG9yKFxyXG4gICAgICAgIEBTa2lwU2VsZigpIEBPcHRpb25hbCgpIHByaXZhdGUgcGFyZW50U2VsZWN0aW9uQXJlYTogU2VsZWN0aW9uQXJlYURpcmVjdGl2ZSxcclxuICAgICAgICBAU2VsZigpIHB1YmxpYyBzZWxlY3Rpb25TZXJ2aWNlOiBSVFNlbGVjdGlvblNlcnZpY2UsXHJcbiAgICAgICAgQFNlbGYoKSBwdWJsaWMgc2VsZWN0aW9uRXZlbnRzSGVscGVyOiBSVFNlbGVjdGlvbkV2ZW50c0hlbHBlcikge1xyXG4gICAgICAgIHRoaXMuc2VsZWN0aW9uU2VydmljZS5hcmVhRXZlbnRzRW1pdHRlciA9IHRoaXM7XHJcbiAgICAgICAgdGhpcy5zZWxlY3Rpb25FdmVudHNIZWxwZXIgPSBzZWxlY3Rpb25FdmVudHNIZWxwZXI7XHJcbiAgICB9XHJcblxyXG4gICAgbmdPbkluaXQoKSB7XHJcbiAgICAgICAgdGhpcy5zZWxlY3RhYmxlc0NoYW5nZWRTdWJzY3JpcHRpb24gPSB0aGlzLnNlbGVjdGFibGVzQ2hhbmdlZFN1YmplY3QucGlwZShcclxuICAgICAgICAgICAgZGVib3VuY2UoKCkgPT4gc2NoZWR1bGVkKEVNUFRZLCBhbmltYXRpb25GcmFtZVNjaGVkdWxlcikpXHJcbiAgICAgICAgKS5zdWJzY3JpYmUoaXRlbXMgPT4gdGhpcy5idWlsZFNlbGVjdGlvblNvdXJjZShpdGVtcykpO1xyXG5cclxuICAgICAgICB0aGlzLmNoaWxkU2VsZWN0aW9uQXJlYXNDaGFuZ2VkU3Vic2NyaXB0aW9uID0gdGhpcy5jaGlsZFNlbGVjdGlvbkFyZWFzQ2hhbmdlZFN1YmplY3QucGlwZShcclxuICAgICAgICAgICAgZGVib3VuY2UoKCkgPT4gc2NoZWR1bGVkKEVNUFRZLCBhbmltYXRpb25GcmFtZVNjaGVkdWxlcikpXHJcbiAgICAgICAgKS5zdWJzY3JpYmUoaXRlbXMgPT4gdGhpcy5idWlsZFNlbGVjdGlvblNlcnZpY2VzTGlzdChpdGVtcykpO1xyXG4gICAgfVxyXG5cclxuICAgIG5nQWZ0ZXJWaWV3SW5pdCgpIHtcclxuICAgICAgICB0aGlzLnBhcmVudFNlbGVjdGlvbkFyZWE/LnJlZ2lzdGVyQ2hpbGRTZWxlY3Rpb25BcmVhKHRoaXMpO1xyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyBuZ09uRGVzdHJveSgpOiB2b2lkIHtcclxuICAgICAgICB0aGlzLnNlbGVjdGlvblNlcnZpY2UuZGVzZWxlY3RBbGwoKTtcclxuICAgICAgICB0aGlzLnNlbGVjdGlvblNlcnZpY2UuZGVzdHJveSgpO1xyXG4gICAgICAgIHRoaXMucGFyZW50U2VsZWN0aW9uQXJlYT8udW5yZWdpc3RlckNoaWxkU2VsZWN0aW9uQXJlYSh0aGlzKTtcclxuICAgICAgICB0aGlzLnNlbGVjdGFibGVzQ2hhbmdlZFN1YnNjcmlwdGlvbj8udW5zdWJzY3JpYmUoKTtcclxuICAgICAgICB0aGlzLmNoaWxkU2VsZWN0aW9uQXJlYXNDaGFuZ2VkU3Vic2NyaXB0aW9uPy51bnN1YnNjcmliZSgpO1xyXG4gICAgfVxyXG4gICAgcHVibGljIG5nT25DaGFuZ2VzKGNoYW5nZXM6IHsgbXVsdGlwbGU/OiBTaW1wbGVDaGFuZ2U7IGF1dG9TZWxlY3RGaXJzdD86IFNpbXBsZUNoYW5nZSB9KTogdm9pZCB7XHJcbiAgICAgICAgaWYgKGZhbHNlID09PSB0aGlzLnNlbGVjdGlvblNlcnZpY2UuaGFzU2VsZWN0aW9ucygpICYmIGNoYW5nZXMuYXV0b1NlbGVjdEZpcnN0ICYmIGNoYW5nZXMuYXV0b1NlbGVjdEZpcnN0LmN1cnJlbnRWYWx1ZSA9PT0gdHJ1ZSkge1xyXG4gICAgICAgICAgICB0aGlzLnNlbGVjdGlvblNlcnZpY2Uuc2VsZWN0SW5kZXgoMCwgZmFsc2UpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAoY2hhbmdlcy5tdWx0aXBsZSAmJiBjaGFuZ2VzLm11bHRpcGxlLmN1cnJlbnRWYWx1ZSA9PT0gZmFsc2UpIHtcclxuICAgICAgICAgICAgY29uc3Qgc2VsZWN0ZWRJbmRleGVzID0gdGhpcy5zZWxlY3Rpb25TZXJ2aWNlLmdldFNlbGVjdGVkSW5kZXhlcygpO1xyXG4gICAgICAgICAgICBpZiAoc2VsZWN0ZWRJbmRleGVzLmxlbmd0aCA+IDEpIHtcclxuICAgICAgICAgICAgICAgIHNlbGVjdGVkSW5kZXhlcy5zcGxpY2UoMCwgMSk7XHJcbiAgICAgICAgICAgICAgICBzZWxlY3RlZEluZGV4ZXMuZm9yRWFjaChpbmRleCA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5zZWxlY3Rpb25TZXJ2aWNlLmRlc2VsZWN0SW5kZXgoaW5kZXgpO1xyXG4gICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgQEhvc3RMaXN0ZW5lcigna2V5ZG93bicsIFsnJGV2ZW50LmN0cmxLZXknLCAnJGV2ZW50LnNoaWZ0S2V5JywgJyRldmVudC5rZXlDb2RlJywgJyRldmVudC5wcmV2ZW50RGVmYXVsdCcsICckZXZlbnQuc3RvcFByb3BhZ2F0aW9uJywgJyRldmVudCddKVxyXG4gICAgcHVibGljIGtleURvd25IYW5kbGVyKFxyXG4gICAgICAgIGN0cmxLZXlQcmVzc2VkOiBib29sZWFuLFxyXG4gICAgICAgIHNoaWZ0S2V5UHJlc3NlZDogYm9vbGVhbixcclxuICAgICAgICBrZXlDb2RlOiBudW1iZXIsXHJcbiAgICAgICAgcHJldmVudERlZmF1bHRGbjogKCkgPT4gdm9pZCxcclxuICAgICAgICBzdG9wUHJvcGFnYXRpb25GbjogKCkgPT4gdm9pZCxcclxuICAgICAgICBleGVjdXRpb25Db250ZXh0OiBhbnlcclxuICAgICk6IHZvaWQge1xyXG4gICAgICAgIGlmICh0aGlzLnNlbGVjdGlvbkV2ZW50c0hlbHBlci5rZXlib2FyZEhhbmRsZXIoY3RybEtleVByZXNzZWQsIHNoaWZ0S2V5UHJlc3NlZCwga2V5Q29kZSkpIHtcclxuICAgICAgICAgICAgaWYgKHRoaXMuc2VsZWN0aW9uRXZlbnRzSGVscGVyLnByZXZlbnRFdmVudHNEZWZhdWx0cyAmJiBwcmV2ZW50RGVmYXVsdEZuKSB7XHJcbiAgICAgICAgICAgICAgICBwcmV2ZW50RGVmYXVsdEZuLmNhbGwoZXhlY3V0aW9uQ29udGV4dCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgaWYgKHRoaXMuc2VsZWN0aW9uRXZlbnRzSGVscGVyLnN0b3BFdmVudHNQcm9wYWdhdGlvbiAmJiBzdG9wUHJvcGFnYXRpb25Gbikge1xyXG4gICAgICAgICAgICAgICAgc3RvcFByb3BhZ2F0aW9uRm4uY2FsbChleGVjdXRpb25Db250ZXh0KTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIC8vI3JlZ2lvbiBjYWxsYmFja3MgZm9yIERPTSBkZXNjZW5kYW50c1xyXG4gICAgcHVibGljIHJlZ2lzdGVyU2VsZWN0YWJsZShzZWxlY3RhYmxlOiBTZWxlY3RhYmxlRGlyZWN0aXZlLCBlbGVtZW50UmVmOiBFbGVtZW50UmVmKTogdm9pZCB7XHJcbiAgICAgICAgY29uc3QgZWxlbWVudCA9IGVsZW1lbnRSZWYubmF0aXZlRWxlbWVudCBhcyBIVE1MRWxlbWVudDtcclxuICAgICAgICBsZXQgaSA9IDA7XHJcbiAgICAgICAgZm9yICg7IGkgPCB0aGlzLnNlbGVjdGFibGVJdGVtcy5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICBpZiAodGhpcy5zZWxlY3RhYmxlSXRlbXNbaV0uZWxlbWVudC5jb21wYXJlRG9jdW1lbnRQb3NpdGlvbihlbGVtZW50KSAmIGRvY3VtZW50LkRPQ1VNRU5UX1BPU0lUSU9OX1BSRUNFRElORykge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5zZWxlY3RhYmxlSXRlbXMuc3BsaWNlKGksIDAsIHsgZWxlbWVudCwgc2VsZWN0YWJsZSB9KTtcclxuICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmIChpID09PSB0aGlzLnNlbGVjdGFibGVJdGVtcy5sZW5ndGgpIHtcclxuICAgICAgICAgICAgdGhpcy5zZWxlY3RhYmxlSXRlbXMucHVzaCh7ZWxlbWVudCwgc2VsZWN0YWJsZX0pO1xyXG4gICAgICAgIH1cclxuICAgICAgICB0aGlzLnNlbGVjdGFibGVzQ2hhbmdlZFN1YmplY3QubmV4dCh0aGlzLnNlbGVjdGFibGVJdGVtcy5tYXAoeCA9PiB4LnNlbGVjdGFibGUpKTtcclxuICAgIH1cclxuICAgIHB1YmxpYyB1bnJlZ2lzdGVyU2VsZWN0YWJsZShzZWxlY3RhYmxlOiBTZWxlY3RhYmxlRGlyZWN0aXZlKTogdm9pZCB7XHJcbiAgICAgICAgY29uc3QgaWR4ID0gdGhpcy5zZWxlY3RhYmxlSXRlbXMuZmluZEluZGV4KHggPT4geC5zZWxlY3RhYmxlID09PSBzZWxlY3RhYmxlKTtcclxuICAgICAgICBpZiAoaWR4ID49IDApIHtcclxuICAgICAgICAgICAgdGhpcy5zZWxlY3RhYmxlSXRlbXMuc3BsaWNlKGlkeCwgMSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHRoaXMuc2VsZWN0YWJsZXNDaGFuZ2VkU3ViamVjdC5uZXh0KHRoaXMuc2VsZWN0YWJsZUl0ZW1zLm1hcCh4ID0+IHguc2VsZWN0YWJsZSkpO1xyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyByZWdpc3RlclNlbGVjdGlvbkNoZWNrYm94KGNoZWNrYm94OiBTZWxlY3Rpb25DaGVja2JveEZvckRpcmVjdGl2ZSwgZWxlbWVudFJlZjogRWxlbWVudFJlZik6IHZvaWQge1xyXG4gICAgICAgIGNvbnN0IGVsZW1lbnQgPSBlbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQgYXMgSFRNTEVsZW1lbnQ7XHJcbiAgICAgICAgbGV0IGkgPSAwO1xyXG4gICAgICAgIGZvciAoOyBpIDwgdGhpcy5jaGlsZFNlbGVjdGlvbkNoZWNrYm94ZXMubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICAgICAgaWYgKHRoaXMuY2hpbGRTZWxlY3Rpb25DaGVja2JveGVzW2ldLmVsZW1lbnQuY29tcGFyZURvY3VtZW50UG9zaXRpb24oZWxlbWVudCkgJiBkb2N1bWVudC5ET0NVTUVOVF9QT1NJVElPTl9QUkVDRURJTkcpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMuY2hpbGRTZWxlY3Rpb25DaGVja2JveGVzLnNwbGljZShpLCAwLCB7IGVsZW1lbnQsIHNlbGVjdGFibGU6IGNoZWNrYm94IH0pO1xyXG4gICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKGkgPT09IHRoaXMuY2hpbGRTZWxlY3Rpb25DaGVja2JveGVzLmxlbmd0aCkge1xyXG4gICAgICAgICAgICB0aGlzLmNoaWxkU2VsZWN0aW9uQ2hlY2tib3hlcy5wdXNoKHtlbGVtZW50LCBzZWxlY3RhYmxlOiBjaGVja2JveH0pO1xyXG4gICAgICAgIH1cclxuICAgICAgICB0aGlzLnNlbGVjdGFibGVzQ2hhbmdlZFN1YmplY3QubmV4dCh0aGlzLmNoaWxkU2VsZWN0aW9uQ2hlY2tib3hlcy5tYXAoeCA9PiB4LnNlbGVjdGFibGUpKTtcclxuICAgIH1cclxuICAgIHB1YmxpYyB1bnJlZ2lzdGVyU2VsZWN0aW9uQ2hlY2tib3goY2hlY2tib3g6IFNlbGVjdGlvbkNoZWNrYm94Rm9yRGlyZWN0aXZlKTogdm9pZCB7XHJcbiAgICAgICAgY29uc3QgaWR4ID0gdGhpcy5jaGlsZFNlbGVjdGlvbkNoZWNrYm94ZXMuZmluZEluZGV4KHggPT4geC5zZWxlY3RhYmxlID09PSBjaGVja2JveCk7XHJcbiAgICAgICAgaWYgKGlkeCA+PSAwKSB7XHJcbiAgICAgICAgICAgIHRoaXMuY2hpbGRTZWxlY3Rpb25DaGVja2JveGVzLnNwbGljZShpZHgsIDEpO1xyXG4gICAgICAgIH1cclxuICAgICAgICB0aGlzLnNlbGVjdGFibGVzQ2hhbmdlZFN1YmplY3QubmV4dCh0aGlzLmNoaWxkU2VsZWN0aW9uQ2hlY2tib3hlcy5tYXAoeCA9PiB4LnNlbGVjdGFibGUpKTtcclxuICAgIH1cclxuXHJcbiAgICBwdWJsaWMgcmVnaXN0ZXJDaGlsZFNlbGVjdGlvbkFyZWEoc2VsZWN0aW9uQXJlYTogU2VsZWN0aW9uQXJlYURpcmVjdGl2ZSk6IHZvaWQge1xyXG4gICAgICAgIGlmICghdGhpcy5jaGlsZFNlbGVjdGlvbkFyZWFzLmhhcyhzZWxlY3Rpb25BcmVhKSkge1xyXG4gICAgICAgICAgICB0aGlzLmNoaWxkU2VsZWN0aW9uQXJlYXMuYWRkKHNlbGVjdGlvbkFyZWEpO1xyXG4gICAgICAgICAgICB0aGlzLmNoaWxkU2VsZWN0aW9uQXJlYXNDaGFuZ2VkU3ViamVjdC5uZXh0KHRoaXMuY2hpbGRTZWxlY3Rpb25BcmVhcyk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgcHVibGljIHVucmVnaXN0ZXJDaGlsZFNlbGVjdGlvbkFyZWEoc2VsZWN0aW9uQXJlYTogU2VsZWN0aW9uQXJlYURpcmVjdGl2ZSk6IHZvaWQge1xyXG4gICAgICAgIGlmICh0aGlzLmNoaWxkU2VsZWN0aW9uQXJlYXMuaGFzKHNlbGVjdGlvbkFyZWEpKSB7XHJcbiAgICAgICAgICAgIHRoaXMuY2hpbGRTZWxlY3Rpb25BcmVhcy5kZWxldGUoc2VsZWN0aW9uQXJlYSk7XHJcbiAgICAgICAgICAgIHRoaXMuY2hpbGRTZWxlY3Rpb25BcmVhc0NoYW5nZWRTdWJqZWN0Lm5leHQodGhpcy5jaGlsZFNlbGVjdGlvbkFyZWFzKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICAvLyNlbmRyZWdpb25cclxuXHJcbiAgICBwdWJsaWMgbmdBZnRlckNvbnRlbnRJbml0KCk6IHZvaWQge1xyXG4gICAgICAgIGlmICh0aGlzLnNlbGVjdGFibGVJdGVtcy5sZW5ndGggPiAwKSB7XHJcbiAgICAgICAgICAgIHRoaXMuYnVpbGRTZWxlY3Rpb25Tb3VyY2UodGhpcy5zZWxlY3RhYmxlSXRlbXMubWFwKGl0ZW0gPT4gaXRlbS5zZWxlY3RhYmxlKSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmICh0aGlzLmNoaWxkU2VsZWN0aW9uQ2hlY2tib3hlcy5sZW5ndGggPiAwKSB7XHJcbiAgICAgICAgICAgIHRoaXMuYnVpbGRTZWxlY3Rpb25Tb3VyY2UodGhpcy5jaGlsZFNlbGVjdGlvbkNoZWNrYm94ZXMubWFwKGl0ZW0gPT4gaXRlbS5zZWxlY3RhYmxlKSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHRoaXMuYnVpbGRTZWxlY3Rpb25TZXJ2aWNlc0xpc3QodGhpcy5jaGlsZFNlbGVjdGlvbkFyZWFzKTtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIGJ1aWxkU2VsZWN0aW9uU291cmNlKGl0ZW1zOiAoU2VsZWN0YWJsZURpcmVjdGl2ZSB8IFNlbGVjdGlvbkNoZWNrYm94Rm9yRGlyZWN0aXZlKVtdKTogdm9pZCB7XHJcbiAgICAgICAgbGV0IGluZGV4ID0gMDtcclxuICAgICAgICB0aGlzLnNlbGVjdGlvblNlcnZpY2UuZXZlbnRFbWl0dGVycyA9IGl0ZW1zLm1hcChpdGVtID0+IHtcclxuICAgICAgICAgICAgaWYgKGl0ZW0uaW5kZXggIT09IG51bGwgJiYgaXRlbS5pbmRleCAhPT0gaW5kZXgpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMuc2VsZWN0aW9uU2VydmljZS5kZXNlbGVjdEluZGV4KGl0ZW0uaW5kZXgpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGl0ZW0uaW5kZXggPSBpbmRleCsrO1xyXG4gICAgICAgICAgICByZXR1cm4gaXRlbTtcclxuICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgdGhpcy5zZWxlY3Rpb25TZXJ2aWNlLml0ZW1zID0gaXRlbXMubWFwKGl0ZW0gPT4gaXRlbS5pdGVtKTtcclxuICAgICAgICBpZiAodGhpcy5zZWxlY3Rpb25TZXJ2aWNlLml0ZW1zLmxlbmd0aCA+IDApIHtcclxuICAgICAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAvLyBzaW5jZSB3ZSd2ZSBtb2RpZnkgY29sbGVjdGlvbiBvbiBmaXJzdCByZW5kZXIsXHJcbiAgICAgICAgICAgICAgICAvLyB0byBwcmV2ZW50IGVycm9yICdFeHByZXNzaW9uIGhhcyBjaGFuZ2VkIGFmdGVyIGl0IHdhcyBjaGVja2VkJyB3ZSd2ZSBkbyBzZWxlY3Rpb24gYWZ0ZXIgcmVuZGVyXHJcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5zZWxlY3Rpb25TZXJ2aWNlLml0ZW1zLmxlbmd0aCA+IDApIHtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLnNlbGVjdGlvblNlcnZpY2UuY2hlY2tTZWxlY3Rpb24oKTtcclxuICAgICAgICAgICAgICAgICAgICAvLyByZXBlYXRzIGZpcnN0IGVsZW1lbnQgc2VsZWN0aW9uIHNpbmNlIGNoZWNraW5nIGNhbiBkZXNlbGVjdCBhbGwgZWxlbWVudHNcclxuICAgICAgICAgICAgICAgICAgICBpZiAoZmFsc2UgPT09IHRoaXMuc2VsZWN0aW9uU2VydmljZS5oYXNTZWxlY3Rpb25zKCkgJiYgdGhpcy5hdXRvU2VsZWN0Rmlyc3QpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zZWxlY3Rpb25TZXJ2aWNlLnNlbGVjdEluZGV4KDAsIGZhbHNlKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH0sIDApO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIHByaXZhdGUgYnVpbGRTZWxlY3Rpb25TZXJ2aWNlc0xpc3QoaXRlbXM6IFNldDxTZWxlY3Rpb25BcmVhRGlyZWN0aXZlPik6IHZvaWQge1xyXG4gICAgICAgIHRoaXMuc2VsZWN0aW9uU2VydmljZS5jaGlsZFNlbGVjdGlvblNlcnZpY2VzID0gQXJyYXkuZnJvbShpdGVtcylcclxuICAgICAgICAgICAgLmZpbHRlcihhcmVhID0+IGFyZWEgIT09IHRoaXMpXHJcbiAgICAgICAgICAgIC5tYXAoYXJlYSA9PiBhcmVhLnNlbGVjdGlvblNlcnZpY2UpO1xyXG4gICAgfVxyXG59XHJcbiJdfQ==