@ux-aspects/ux-aspects
Version:
Open source user interface framework for building modern, responsive, mobile big data applications
156 lines • 20.7 kB
JavaScript
import { ChangeDetectorRef, ContentChildren, Directive, EventEmitter, HostBinding, inject, Input, Output } from '@angular/core';
import { Subject } from 'rxjs';
import { debounceTime, takeUntil } from 'rxjs/operators';
import { SelectionItemDirective } from './selection-item.directive';
import { SelectionService } from './selection.service';
import * as i0 from "@angular/core";
export class SelectionDirective {
/** Defines the items that should be selected. */
set uxSelection(items) {
this._lastSelection = items;
this._selectionService.selectOnly(...items);
}
/** Can be used to enabled/disable selection behavior. */
set disabled(disabled) {
this._selectionService.setDisabled(disabled);
}
/**
* Defines the selection behavior. Alternatively, custom selection behavior can be defined by defining a
* class which extends SelectionStrategy, and providing an instance of the custom class to this property.
* See below for details of the SelectionStrategy class.
*/
set mode(mode) {
this._selectionService.setStrategy(mode);
}
/**
* Can be used to enable/disable click selection on items. This can be used to manually control the selection of an item,
* for example, binding the selection state to a checkbox.
*/
set clickSelection(isClickEnabled) {
this._selectionService.isClickEnabled = isClickEnabled;
}
/** Can be used to enable/disable keyboard navigation on items. Use this if you wish to provide custom keyboard controls for selection. */
set keyboardSelection(isKeyboardEnabled) {
this._selectionService.isKeyboardEnabled = isKeyboardEnabled;
}
/**
* The full set of selection items.
* Only needed if the full set of `uxSelectionItem`s is not available, e.g. within a virtual scroll container.
*/
set selectionItems(value) {
this._hasExplicitDataset = !!value;
if (value) {
this._selectionService.dataset = value;
}
}
constructor() {
this._selectionService = inject(SelectionService);
this._cdRef = inject(ChangeDetectorRef);
/** The tabstop of the selection outer element */
this.tabindex = null;
/** This event will be triggered when there is a change to the selected items. It will contain an array of the currently selected items. */
this.uxSelectionChange = new EventEmitter();
/** Unsubscribe from all observables on component destroy */
this._onDestroy = new Subject();
/** Store the previous selection so we don't emit more than we have to */
this._lastSelection = [];
/** Whether a value has been provided to the `selectionItems` input. */
this._hasExplicitDataset = false;
this._selectionService.selection$.pipe(debounceTime(0), takeUntil(this._onDestroy)).subscribe(items => {
if (this.isSelectionChanged(items)) {
this.uxSelectionChange.emit(items);
}
// store the most recent selection
this._lastSelection = [...items];
});
}
ngAfterContentInit() {
// provide the initial list of selection items
this.update();
// if the list changes then inform the service
this.items.changes.pipe(takeUntil(this._onDestroy)).subscribe(() => this.update());
}
ngOnDestroy() {
this._onDestroy.next();
this._onDestroy.complete();
}
/**
* Update the dataset to reflect the latest selection items
*/
update() {
// Capture the set of data items from the ContentChildren, unless an explicit value has been provided.
if (!this._hasExplicitDataset) {
this._selectionService.dataset = this.items.map(item => item.uxSelectionItem);
}
// Make sure that a tab target has been defined so that the component can be tabbed to.
if (this._selectionService.focus$.getValue() === null && this._selectionService.dataset.length > 0) {
this._selectionService.focus$.next(this._selectionService.dataset[0]);
}
// The above could trigger a change in the computed tabindex for selection items
this._cdRef.detectChanges();
}
/**
* Select all the items in the list
*/
selectAll() {
if (this._selectionService.isEnabled) {
this._selectionService.strategy.selectAll();
}
}
/**
* Deselect all currently selected items
*/
deselectAll() {
if (this._selectionService.isEnabled) {
this._selectionService.strategy.deselectAll();
}
}
/**
* Determine if the previous selection is the same as the current selection
*/
isSelectionChanged(selection) {
// fast, efficient check, if length is different they must have changed
if (!this._lastSelection && selection || this._lastSelection.length !== selection.length) {
return true;
}
// if both arrays have 0 items then they have not changed
if (this._lastSelection.length === 0 && selection.length === 0) {
return false;
}
// otherwise do a check on each item
return !this._lastSelection.every(item => selection.indexOf(item) !== -1);
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.12", ngImport: i0, type: SelectionDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.2.12", type: SelectionDirective, selector: "[uxSelection]", inputs: { uxSelection: "uxSelection", disabled: "disabled", mode: "mode", clickSelection: "clickSelection", keyboardSelection: "keyboardSelection", selectionItems: "selectionItems", tabindex: "tabindex" }, outputs: { uxSelectionChange: "uxSelectionChange" }, host: { properties: { "attr.tabindex": "this.tabindex" } }, providers: [SelectionService], queries: [{ propertyName: "items", predicate: SelectionItemDirective }], exportAs: ["ux-selection"], ngImport: i0 }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.12", ngImport: i0, type: SelectionDirective, decorators: [{
type: Directive,
args: [{
selector: '[uxSelection]',
exportAs: 'ux-selection',
providers: [SelectionService]
}]
}], ctorParameters: () => [], propDecorators: { uxSelection: [{
type: Input
}], disabled: [{
type: Input
}], mode: [{
type: Input
}], clickSelection: [{
type: Input
}], keyboardSelection: [{
type: Input
}], selectionItems: [{
type: Input
}], tabindex: [{
type: Input
}, {
type: HostBinding,
args: ['attr.tabindex']
}], uxSelectionChange: [{
type: Output
}], items: [{
type: ContentChildren,
args: [SelectionItemDirective]
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VsZWN0aW9uLmRpcmVjdGl2ZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3NyYy9kaXJlY3RpdmVzL3NlbGVjdGlvbi9zZWxlY3Rpb24uZGlyZWN0aXZlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBb0IsaUJBQWlCLEVBQUUsZUFBZSxFQUFFLFNBQVMsRUFBRSxZQUFZLEVBQUUsV0FBVyxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQWEsTUFBTSxFQUFhLE1BQU0sZUFBZSxDQUFDO0FBQ3hLLE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDL0IsT0FBTyxFQUFFLFlBQVksRUFBRSxTQUFTLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUN6RCxPQUFPLEVBQUUsc0JBQXNCLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUNwRSxPQUFPLEVBQWlCLGdCQUFnQixFQUFFLE1BQU0scUJBQXFCLENBQUM7O0FBUXRFLE1BQU0sT0FBTyxrQkFBa0I7SUFLM0IsaURBQWlEO0lBQ2pELElBQWEsV0FBVyxDQUFDLEtBQWtDO1FBQ3ZELElBQUksQ0FBQyxjQUFjLEdBQUcsS0FBSyxDQUFDO1FBQzVCLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxVQUFVLENBQUMsR0FBRyxLQUFLLENBQUMsQ0FBQztJQUNoRCxDQUFDO0lBRUQseURBQXlEO0lBQ3pELElBQWEsUUFBUSxDQUFDLFFBQWlCO1FBQ25DLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxXQUFXLENBQUMsUUFBUSxDQUFDLENBQUM7SUFDakQsQ0FBQztJQUVEOzs7O09BSUc7SUFDSCxJQUFhLElBQUksQ0FBQyxJQUEwQztRQUN4RCxJQUFJLENBQUMsaUJBQWlCLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQzdDLENBQUM7SUFFRDs7O09BR0c7SUFDSCxJQUFhLGNBQWMsQ0FBQyxjQUF1QjtRQUMvQyxJQUFJLENBQUMsaUJBQWlCLENBQUMs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QixTQUFTLEVBQUUsQ0FBQyxnQkFBZ0IsQ0FBQztpQkFDaEM7d0RBT2dCLFdBQVc7c0JBQXZCLEtBQUs7Z0JBTU8sUUFBUTtzQkFBcEIsS0FBSztnQkFTTyxJQUFJO3NCQUFoQixLQUFLO2dCQVFPLGNBQWM7c0JBQTFCLEtBQUs7Z0JBS08saUJBQWlCO3NCQUE3QixLQUFLO2dCQVFPLGNBQWM7c0JBQTFCLEtBQUs7Z0JBUWlDLFFBQVE7c0JBQTlDLEtBQUs7O3NCQUFJLFdBQVc7dUJBQUMsZUFBZTtnQkFHM0IsaUJBQWlCO3NCQUExQixNQUFNO2dCQUdrQyxLQUFLO3NCQUE3QyxlQUFlO3VCQUFDLHNCQUFzQiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEFmdGVyQ29udGVudEluaXQsIENoYW5nZURldGVjdG9yUmVmLCBDb250ZW50Q2hpbGRyZW4sIERpcmVjdGl2ZSwgRXZlbnRFbWl0dGVyLCBIb3N0QmluZGluZywgaW5qZWN0LCBJbnB1dCwgT25EZXN0cm95LCBPdXRwdXQsIFF1ZXJ5TGlzdCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgU3ViamVjdCB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgZGVib3VuY2VUaW1lLCB0YWtlVW50aWwgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5pbXBvcnQgeyBTZWxlY3Rpb25JdGVtRGlyZWN0aXZlIH0gZnJvbSAnLi9zZWxlY3Rpb24taXRlbS5kaXJlY3RpdmUnO1xuaW1wb3J0IHsgU2VsZWN0aW9uTW9kZSwgU2VsZWN0aW9uU2VydmljZSB9IGZyb20gJy4vc2VsZWN0aW9uLnNlcnZpY2UnO1xuaW1wb3J0IHsgU2VsZWN0aW9uU3RyYXRlZ3kgfSBmcm9tICcuL3N0cmF0ZWdpZXMvc2VsZWN0aW9uLnN0cmF0ZWd5JztcblxuQERpcmVjdGl2ZSh7XG4gICAgc2VsZWN0b3I6ICdbdXhTZWxlY3Rpb25dJyxcbiAgICBleHBvcnRBczogJ3V4LXNlbGVjdGlvbicsXG4gICAgcHJvdmlkZXJzOiBbU2VsZWN0aW9uU2VydmljZV1cbn0pXG5leHBvcnQgY2xhc3MgU2VsZWN0aW9uRGlyZWN0aXZlPFQ+IGltcGxlbWVudHMgQWZ0ZXJDb250ZW50SW5pdCwgT25EZXN0cm95IHtcbiAgICByZWFkb25seSBfc2VsZWN0aW9uU2VydmljZSA9IGluamVjdDxTZWxlY3Rpb25TZXJ2aWNlPFQ+PihTZWxlY3Rpb25TZXJ2aWNlKTtcblxuICAgIHJlYWRvbmx5IF9jZFJlZiA9IGluamVjdChDaGFuZ2VEZXRlY3RvclJlZik7XG5cbiAgICAvKiogRGVmaW5lcyB0aGUgaXRlbXMgdGhhdCBzaG91bGQgYmUgc2VsZWN0ZWQuICovXG4gICAgQElucHV0KCkgc2V0IHV4U2VsZWN0aW9uKGl0ZW1zOiBBcnJheTxUPiB8IFJlYWRvbmx5QXJyYXk8VD4pIHtcbiAgICAgICAgdGhpcy5fbGFzdFNlbGVjdGlvbiA9IGl0ZW1zO1xuICAgICAgICB0aGlzLl9zZWxlY3Rpb25TZXJ2aWNlLnNlbGVjdE9ubHkoLi4uaXRlbXMpO1xuICAgIH1cblxuICAgIC8qKiBDYW4gYmUgdXNlZCB0byBlbmFibGVkL2Rpc2FibGUgc2VsZWN0aW9uIGJlaGF2aW9yLiAqL1xuICAgIEBJbnB1dCgpIHNldCBkaXNhYmxlZChkaXNhYmxlZDogYm9vbGVhbikge1xuICAgICAgICB0aGlzLl9zZWxlY3Rpb25TZXJ2aWNlLnNldERpc2FibGVkKGRpc2FibGVkKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBEZWZpbmVzIHRoZSBzZWxlY3Rpb24gYmVoYXZpb3IuIEFsdGVybmF0aXZlbHksIGN1c3RvbSBzZWxlY3Rpb24gYmVoYXZpb3IgY2FuIGJlIGRlZmluZWQgYnkgZGVmaW5pbmcgYVxuICAgICAqIGNsYXNzIHdoaWNoIGV4dGVuZHMgU2VsZWN0aW9uU3RyYXRlZ3ksIGFuZCBwcm92aWRpbmcgYW4gaW5zdGFuY2Ugb2YgdGhlIGN1c3RvbSBjbGFzcyB0byB0aGlzIHByb3BlcnR5LlxuICAgICAqIFNlZSBiZWxvdyBmb3IgZGV0YWlscyBvZiB0aGUgU2VsZWN0aW9uU3RyYXRlZ3kgY2xhc3MuXG4gICAgICovXG4gICAgQElucHV0KCkgc2V0IG1vZGUobW9kZTogU2VsZWN0aW9uTW9kZSB8IFNlbGVjdGlvblN0cmF0ZWd5PFQ+KSB7XG4gICAgICAgIHRoaXMuX3NlbGVjdGlvblNlcnZpY2Uuc2V0U3RyYXRlZ3kobW9kZSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2FuIGJlIHVzZWQgdG8gZW5hYmxlL2Rpc2FibGUgY2xpY2sgc2VsZWN0aW9uIG9uIGl0ZW1zLiBUaGlzIGNhbiBiZSB1c2VkIHRvIG1hbnVhbGx5IGNvbnRyb2wgdGhlIHNlbGVjdGlvbiBvZiBhbiBpdGVtLFxuICAgICAqIGZvciBleGFtcGxlLCBiaW5kaW5nIHRoZSBzZWxlY3Rpb24gc3RhdGUgdG8gYSBjaGVja2JveC5cbiAgICAgKi9cbiAgICBASW5wdXQoKSBzZXQgY2xpY2tTZWxlY3Rpb24oaXNDbGlja0VuYWJsZWQ6IGJvb2xlYW4pIHtcbiAgICAgICAgdGhpcy5fc2VsZWN0aW9uU2VydmljZS5pc0NsaWNrRW5hYmxlZCA9IGlzQ2xpY2tFbmFibGVkO1xuICAgIH1cblxuICAgIC8qKiBDYW4gYmUgdXNlZCB0byBlbmFibGUvZGlzYWJsZSBrZXlib2FyZCBuYXZpZ2F0aW9uIG9uIGl0ZW1zLiBVc2UgdGhpcyBpZiB5b3Ugd2lzaCB0byBwcm92aWRlIGN1c3RvbSBrZXlib2FyZCBjb250cm9scyBmb3Igc2VsZWN0aW9uLiAqL1xuICAgIEBJbnB1dCgpIHNldCBrZXlib2FyZFNlbGVjdGlvbihpc0tleWJvYXJkRW5hYmxlZDogYm9vbGVhbikge1xuICAgICAgICB0aGlzLl9zZWxlY3Rpb25TZXJ2aWNlLmlzS2V5Ym9hcmRFbmFibGVkID0gaXNLZXlib2FyZEVuYWJsZWQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVGhlIGZ1bGwgc2V0IG9mIHNlbGVjdGlvbiBpdGVtcy5cbiAgICAgKiBPbmx5IG5lZWRlZCBpZiB0aGUgZnVsbCBzZXQgb2YgYHV4U2VsZWN0aW9uSXRlbWBzIGlzIG5vdCBhdmFpbGFibGUsIGUuZy4gd2l0aGluIGEgdmlydHVhbCBzY3JvbGwgY29udGFpbmVyLlxuICAgICAqL1xuICAgIEBJbnB1dCgpIHNldCBzZWxlY3Rpb25JdGVtcyh2YWx1ZTogVFtdKSB7XG4gICAgICAgIHRoaXMuX2hhc0V4cGxpY2l0RGF0YXNldCA9ICEhdmFsdWU7XG4gICAgICAgIGlmICh2YWx1ZSkge1xuICAgICAgICAgICAgdGhpcy5fc2VsZWN0aW9uU2VydmljZS5kYXRhc2V0ID0gdmFsdWU7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKiogVGhlIHRhYnN0b3Agb2YgdGhlIHNlbGVjdGlvbiBvdXRlciBlbGVtZW50ICovXG4gICAgQElucHV0KCkgQEhvc3RCaW5kaW5nKCdhdHRyLnRhYmluZGV4JykgdGFiaW5kZXg6IHN0cmluZyB8IG51bWJlciA9IG51bGw7XG5cbiAgICAvKiogVGhpcyBldmVudCB3aWxsIGJlIHRyaWdnZXJlZCB3aGVuIHRoZXJlIGlzIGEgY2hhbmdlIHRvIHRoZSBzZWxlY3RlZCBpdGVtcy4gSXQgd2lsbCBjb250YWluIGFuIGFycmF5IG9mIHRoZSBjdXJyZW50bHkgc2VsZWN0ZWQgaXRlbXMuICovXG4gICAgQE91dHB1dCgpIHV4U2VsZWN0aW9uQ2hhbmdlID0gbmV3IEV2ZW50RW1pdHRlcjxUW10+KCk7XG5cbiAgICAvKiogQWNjZXNzIGFsbCBpdGVtcyB3aXRoaW4gdGhlIGxpc3QgKi9cbiAgICBAQ29udGVudENoaWxkcmVuKFNlbGVjdGlvbkl0ZW1EaXJlY3RpdmUpIGl0ZW1zOiBRdWVyeUxpc3Q8U2VsZWN0aW9uSXRlbURpcmVjdGl2ZTxUPj47XG5cbiAgICAvKiogVW5zdWJzY3JpYmUgZnJvbSBhbGwgb2JzZXJ2YWJsZXMgb24gY29tcG9uZW50IGRlc3Ryb3kgKi9cbiAgICBwcml2YXRlIHJlYWRvbmx5IF9vbkRlc3Ryb3kgPSBuZXcgU3ViamVjdDx2b2lkPigpO1xuXG4gICAgLyoqIFN0b3JlIHRoZSBwcmV2aW91cyBzZWxlY3Rpb24gc28gd2UgZG9uJ3QgZW1pdCBtb3JlIHRoYW4gd2UgaGF2ZSB0byAqL1xuICAgIHByaXZhdGUgX2xhc3RTZWxlY3Rpb246IFJlYWRvbmx5QXJyYXk8VD4gPSBbXTtcblxuICAgIC8qKiBXaGV0aGVyIGEgdmFsdWUgaGFzIGJlZW4gcHJvdmlkZWQgdG8gdGhlIGBzZWxlY3Rpb25JdGVtc2AgaW5wdXQuICovXG4gICAgcHJpdmF0ZSBfaGFzRXhwbGljaXREYXRhc2V0OiBib29sZWFuID0gZmFsc2U7XG5cbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgdGhpcy5fc2VsZWN0aW9uU2VydmljZS5zZWxlY3Rpb24kLnBpcGUoZGVib3VuY2VUaW1lKDApLCB0YWtlVW50aWwodGhpcy5fb25EZXN0cm95KSkuc3Vic2NyaWJlKGl0ZW1zID0+IHtcbiAgICAgICAgICAgIGlmICh0aGlzLmlzU2VsZWN0aW9uQ2hhbmdlZChpdGVtcykpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnV4U2VsZWN0aW9uQ2hhbmdlLmVtaXQoaXRlbXMpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBzdG9yZSB0aGUgbW9zdCByZWNlbnQgc2VsZWN0aW9uXG4gICAgICAgICAgICB0aGlzLl9sYXN0U2VsZWN0aW9uID0gWy4uLml0ZW1zXTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgbmdBZnRlckNvbnRlbnRJbml0KCk6IHZvaWQge1xuICAgICAgICAvLyBwcm92aWRlIHRoZSBpbml0aWFsIGxpc3Qgb2Ygc2VsZWN0aW9uIGl0ZW1zXG4gICAgICAgIHRoaXMudXBkYXRlKCk7XG5cbiAgICAgICAgLy8gaWYgdGhlIGxpc3QgY2hhbmdlcyB0aGVuIGluZm9ybSB0aGUgc2VydmljZVxuICAgICAgICB0aGlzLml0ZW1zLmNoYW5nZXMucGlwZSh0YWtlVW50aWwodGhpcy5fb25EZXN0cm95KSkuc3Vic2NyaWJlKCgpID0+IHRoaXMudXBkYXRlKCkpO1xuICAgIH1cblxuICAgIG5nT25EZXN0cm95KCk6IHZvaWQge1xuICAgICAgICB0aGlzLl9vbkRlc3Ryb3kubmV4dCgpO1xuICAgICAgICB0aGlzLl9vbkRlc3Ryb3kuY29tcGxldGUoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBVcGRhdGUgdGhlIGRhdGFzZXQgdG8gcmVmbGVjdCB0aGUgbGF0ZXN0IHNlbGVjdGlvbiBpdGVtc1xuICAgICAqL1xuICAgIHVwZGF0ZSgpOiB2b2lkIHtcblxuICAgICAgICAvLyBDYXB0dXJlIHRoZSBzZXQgb2YgZGF0YSBpdGVtcyBmcm9tIHRoZSBDb250ZW50Q2hpbGRyZW4sIHVubGVzcyBhbiBleHBsaWNpdCB2YWx1ZSBoYXMgYmVlbiBwcm92aWRlZC5cbiAgICAgICAgaWYgKCF0aGlzLl9oYXNFeHBsaWNpdERhdGFzZXQpIHtcbiAgICAgICAgICAgIHRoaXMuX3NlbGVjdGlvblNlcnZpY2UuZGF0YXNldCA9IHRoaXMuaXRlbXMubWFwKGl0ZW0gPT4gaXRlbS51eFNlbGVjdGlvbkl0ZW0pO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gTWFrZSBzdXJlIHRoYXQgYSB0YWIgdGFyZ2V0IGhhcyBiZWVuIGRlZmluZWQgc28gdGhhdCB0aGUgY29tcG9uZW50IGNhbiBiZSB0YWJiZWQgdG8uXG4gICAgICAgIGlmICh0aGlzLl9zZWxlY3Rpb25TZXJ2aWNlLmZvY3VzJC5nZXRWYWx1ZSgpID09PSBudWxsICYmIHRoaXMuX3NlbGVjdGlvblNlcnZpY2UuZGF0YXNldC5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICB0aGlzLl9zZWxlY3Rpb25TZXJ2aWNlLmZvY3VzJC5uZXh0KHRoaXMuX3NlbGVjdGlvblNlcnZpY2UuZGF0YXNldFswXSk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBUaGUgYWJvdmUgY291bGQgdHJpZ2dlciBhIGNoYW5nZSBpbiB0aGUgY29tcHV0ZWQgdGFiaW5kZXggZm9yIHNlbGVjdGlvbiBpdGVtc1xuICAgICAgICB0aGlzLl9jZFJlZi5kZXRlY3RDaGFuZ2VzKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2VsZWN0IGFsbCB0aGUgaXRlbXMgaW4gdGhlIGxpc3RcbiAgICAgKi9cbiAgICBzZWxlY3RBbGwoKTogdm9pZCB7XG4gICAgICAgIGlmICh0aGlzLl9zZWxlY3Rpb25TZXJ2aWNlLmlzRW5hYmxlZCkge1xuICAgICAgICAgICAgdGhpcy5fc2VsZWN0aW9uU2VydmljZS5zdHJhdGVneS5zZWxlY3RBbGwoKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIERlc2VsZWN0IGFsbCBjdXJyZW50bHkgc2VsZWN0ZWQgaXRlbXNcbiAgICAgKi9cbiAgICBkZXNlbGVjdEFsbCgpOiB2b2lkIHtcbiAgICAgICAgaWYgKHRoaXMuX3NlbGVjdGlvblNlcnZpY2UuaXNFbmFibGVkKSB7XG4gICAgICAgICAgICB0aGlzLl9zZWxlY3Rpb25TZXJ2aWNlLnN0cmF0ZWd5LmRlc2VsZWN0QWxsKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBEZXRlcm1pbmUgaWYgdGhlIHByZXZpb3VzIHNlbGVjdGlvbiBpcyB0aGUgc2FtZSBhcyB0aGUgY3VycmVudCBzZWxlY3Rpb25cbiAgICAgKi9cbiAgICBwcml2YXRlIGlzU2VsZWN0aW9uQ2hhbmdlZChzZWxlY3Rpb246IFRbXSk6IGJvb2xlYW4ge1xuXG4gICAgICAgIC8vIGZhc3QsIGVmZmljaWVudCBjaGVjaywgaWYgbGVuZ3RoIGlzIGRpZmZlcmVudCB0aGV5IG11c3QgaGF2ZSBjaGFuZ2VkXG4gICAgICAgIGlmICghdGhpcy5fbGFzdFNlbGVjdGlvbiAmJiBzZWxlY3Rpb24gfHwgdGhpcy5fbGFzdFNlbGVjdGlvbi5sZW5ndGggIT09IHNlbGVjdGlvbi5sZW5ndGgpIHtcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gaWYgYm90aCBhcnJheXMgaGF2ZSAwIGl0ZW1zIHRoZW4gdGhleSBoYXZlIG5vdCBjaGFuZ2VkXG4gICAgICAgIGlmICh0aGlzLl9sYXN0U2VsZWN0aW9uLmxlbmd0aCA9PT0gMCAmJiBzZWxlY3Rpb24ubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBvdGhlcndpc2UgZG8gYSBjaGVjayBvbiBlYWNoIGl0ZW1cbiAgICAgICAgcmV0dXJuICF0aGlzLl9sYXN0U2VsZWN0aW9uLmV2ZXJ5KGl0ZW0gPT4gc2VsZWN0aW9uLmluZGV4T2YoaXRlbSkgIT09IC0xKTtcbiAgICB9XG59XG4iXX0=