UNPKG

@ux-aspects/ux-aspects

Version:

Open source user interface framework for building modern, responsive, mobile big data applications

156 lines 20.7 kB
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=