@ux-aspects/ux-aspects
Version:
Open source user interface framework for building modern, responsive, mobile big data applications
131 lines • 21.1 kB
JavaScript
import { ContentChildren, Directive, ElementRef, inject, Input, QueryList } from '@angular/core';
import { Subject } from 'rxjs';
import { filter, takeUntil } from 'rxjs/operators';
import { TabbableListItemDirective } from './tabbable-list-item.directive';
import { TabbableListService } from './tabbable-list.service';
import * as i0 from "@angular/core";
export class TabbableListDirective {
/** Enabling handling of hierarchical lists via use of the `TabbableListItemDirective.parent` property. */
set hierarchy(value) { this._tabbableList.hierarchy = value; }
/** Prevent keyboard interaction when alt modifier key is pressed */
set allowAltModifier(value) { this._tabbableList.allowAltModifier = value; }
/** Prevent keyboard interaction when ctrl modifier key is pressed */
set allowCtrlModifier(value) { this._tabbableList.allowCtrlModifier = value; }
/** Focus the first or last item when Home or End keys are pressed */
set allowBoundaryKeys(value) { this._tabbableList.allowBoundaryKeys = value; }
get focusKeyManager() {
return this._tabbableList.focusKeyManager;
}
constructor() {
/** Access the tabbable list service */
this._tabbableList = inject(TabbableListService);
/** Access the native dom element */
this.elementRef = inject(ElementRef);
/** Determine whether the up/down arrows should be used or the left/right arrows */
this.direction = 'vertical';
/** Indicate whether or not focus should loop back to the first element after the last */
this.wrap = true;
/** Indicate whether or not the first item should receive focus on show - useful for modals and popovers */
this.focusOnShow = false;
/** Indicate whether or not focus should be returned to the previous element (only applicable when using focusOnShow) */
this.returnFocus = false;
/** Unsubscribe from all observables automatically on destroy */
this._onDestroy = new Subject();
// store a reference to the container element
this._tabbableList.containerRef = this.elementRef.nativeElement;
}
ngAfterContentInit() {
// store the currently focused element
this._focusedElement = document.activeElement;
this._orderedItems = new QueryList();
if (this._tabbableList.hierarchy) {
// Sort items in a hierarchy
this._orderedItems.reset(this._tabbableList.sortItemsByHierarchy(this.items));
// Ensure that the child items remain sorted
this.items.changes.pipe(takeUntil(this._onDestroy)).subscribe(() => {
this._orderedItems.reset(this._tabbableList.sortItemsByHierarchy(this.items));
this._orderedItems.notifyOnChanges();
});
}
else {
// Items are already in order
this._orderedItems = this.items;
// Ensure we reselect a selected item after the querylist has changed
this.items.changes.pipe(filter(() => this._tabbableList.shouldFocusOnChange && this._tabbableList.isFocused), takeUntil(this._onDestroy))
.subscribe((items) => {
// check if an item is currently focused
const activeItem = this._tabbableList.focusKeyManager.activeItem;
// restore the selected item if there was one and it is still visible
if (activeItem) {
// find the matching index
const index = items.toArray().findIndex(item => item.key === activeItem.key);
// if the item is still in the list we want to focus it
if (index > -1) {
// however we are refocusing an item that was focused so we dont want to scroll into view again as this can prevent wheel scrolling
this._tabbableList.shouldScrollInView = false;
// refocus the item again
this._tabbableList.activateItemAtIndex(index, !this._tabbableList.isFocused);
// re-enable scrolling into view
this._tabbableList.shouldScrollInView = true;
}
}
});
}
// Set up the focus monitoring
this._tabbableList.initialize(this._orderedItems, this.direction, this.wrap);
// focus the first element if specified
if (this.focusOnShow) {
this._tabbableList.focusKeyManager.setFirstItemActive();
}
}
ngOnDestroy() {
if (this.returnFocus && this._focusedElement instanceof HTMLElement) {
setTimeout(() => this._focusedElement.focus());
}
this._onDestroy.next();
this._onDestroy.complete();
}
setFirstItemTabbable() {
if (!this._tabbableList.isAnyItemTabbable()) {
this._tabbableList.setFirstItemTabbable();
}
}
focus() {
if (this._tabbableList.focusKeyManager && this._tabbableList.focusKeyManager.activeItem) {
this._tabbableList.focusKeyManager.activeItem.focus();
}
}
focusTabbableItem() {
this._tabbableList.focusTabbableItem();
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.12", ngImport: i0, type: TabbableListDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.2.12", type: TabbableListDirective, selector: "[uxTabbableList]", inputs: { direction: "direction", wrap: "wrap", focusOnShow: "focusOnShow", returnFocus: "returnFocus", hierarchy: "hierarchy", allowAltModifier: "allowAltModifier", allowCtrlModifier: "allowCtrlModifier", allowBoundaryKeys: "allowBoundaryKeys" }, providers: [TabbableListService], queries: [{ propertyName: "items", predicate: TabbableListItemDirective, descendants: true }], exportAs: ["ux-tabbable-list"], ngImport: i0 }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.12", ngImport: i0, type: TabbableListDirective, decorators: [{
type: Directive,
args: [{
selector: '[uxTabbableList]',
exportAs: 'ux-tabbable-list',
providers: [TabbableListService]
}]
}], ctorParameters: () => [], propDecorators: { direction: [{
type: Input
}], wrap: [{
type: Input
}], focusOnShow: [{
type: Input
}], returnFocus: [{
type: Input
}], hierarchy: [{
type: Input
}], allowAltModifier: [{
type: Input
}], allowCtrlModifier: [{
type: Input
}], allowBoundaryKeys: [{
type: Input
}], items: [{
type: ContentChildren,
args: [TabbableListItemDirective, { descendants: true }]
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGFiYmFibGUtbGlzdC5kaXJlY3RpdmUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9zcmMvZGlyZWN0aXZlcy9hY2Nlc3NpYmlsaXR5L3RhYmJhYmxlLWxpc3QvdGFiYmFibGUtbGlzdC5kaXJlY3RpdmUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQ0EsT0FBTyxFQUFvQixlQUFlLEVBQUUsU0FBUyxFQUFFLFVBQVUsRUFBRSxNQUFNLEVBQUUsS0FBSyxFQUFhLFNBQVMsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUM5SCxPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQy9CLE9BQU8sRUFBRSxNQUFNLEVBQUUsU0FBUyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDbkQsT0FBTyxFQUFFLHlCQUF5QixFQUFFLE1BQU0sZ0NBQWdDLENBQUM7QUFDM0UsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0seUJBQXlCLENBQUM7O0FBTzlELE1BQU0sT0FBTyxxQkFBcUI7SUFrQjlCLDBHQUEwRztJQUMxRyxJQUFhLFNBQVMsQ0FBQyxLQUFjLElBQUksSUFBSSxDQUFDLGFBQWEsQ0FBQyxTQUFTLEdBQUcsS0FBSyxDQUFDLENBQUMsQ0FBQztJQUVoRixvRUFBb0U7SUFDcEUsSUFBYSxnQkFBZ0IsQ0FBQyxLQUFjLElBQUksSUFBSSxDQUFDLGFBQWEsQ0FBQyxnQkFBZ0IsR0FBRyxLQUFLLENBQUMsQ0FBQyxDQUFDO0lBRTlGLHFFQUFxRTtJQUNyRSxJQUFhLGlCQUFpQixDQUFDLEtBQWMsSUFBSSxJQUFJLENBQUMsYUFBYSxDQUFDLGlCQUFpQixHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUM7SUFFaEcscUVBQXFFO0lBQ3JFLElBQWEsaUJBQWlCLENBQUMsS0FBYyxJQUFJLElBQUksQ0FBQyxhQUFhLENBQUMsaUJBQWlCLEdBQUcsS0FBSyxDQUFDLENBQUMsQ0FBQztJQWNoRyxJQUFJLGVBQWU7UUFDZixP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QUM7SUFFRCxpQkFBaUI7UUFDYixJQUFJLENBQUMsYUFBYSxDQUFDLGlCQUFpQixFQUFFLENBQUM7SUFDM0MsQ0FBQzsrR0F0SVEscUJBQXFCO21HQUFyQixxQkFBcUIsbVNBRm5CLENBQUMsbUJBQW1CLENBQUMsZ0RBaUNmLHlCQUF5Qjs7NEZBL0JqQyxxQkFBcUI7a0JBTGpDLFNBQVM7bUJBQUM7b0JBQ1AsUUFBUSxFQUFFLGtCQUFrQjtvQkFDNUIsUUFBUSxFQUFFLGtCQUFrQjtvQkFDNUIsU0FBUyxFQUFFLENBQUMsbUJBQW1CLENBQUM7aUJBQ25DO3dEQVFZLFNBQVM7c0JBQWpCLEtBQUs7Z0JBR0csSUFBSTtzQkFBWixLQUFLO2dCQUdHLFdBQVc7c0JBQW5CLEtBQUs7Z0JBR0csV0FBVztzQkFBbkIsS0FBSztnQkFHTyxTQUFTO3NCQUFyQixLQUFLO2dCQUdPLGdCQUFnQjtzQkFBNUIsS0FBSztnQkFHTyxpQkFBaUI7c0JBQTdCLEtBQUs7Z0JBR08saUJBQWlCO3NCQUE3QixLQUFLO2dCQUc2RCxLQUFLO3NCQUF2RSxlQUFlO3VCQUFDLHlCQUF5QixFQUFFLEVBQUUsV0FBVyxFQUFFLElBQUksRUFBRSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEZvY3VzS2V5TWFuYWdlciB9IGZyb20gJ0Bhbmd1bGFyL2Nkay9hMTF5JztcbmltcG9ydCB7IEFmdGVyQ29udGVudEluaXQsIENvbnRlbnRDaGlsZHJlbiwgRGlyZWN0aXZlLCBFbGVtZW50UmVmLCBpbmplY3QsIElucHV0LCBPbkRlc3Ryb3ksIFF1ZXJ5TGlzdCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgU3ViamVjdCB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgZmlsdGVyLCB0YWtlVW50aWwgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5pbXBvcnQgeyBUYWJiYWJsZUxpc3RJdGVtRGlyZWN0aXZlIH0gZnJvbSAnLi90YWJiYWJsZS1saXN0LWl0ZW0uZGlyZWN0aXZlJztcbmltcG9ydCB7IFRhYmJhYmxlTGlzdFNlcnZpY2UgfSBmcm9tICcuL3RhYmJhYmxlLWxpc3Quc2VydmljZSc7XG5cbkBEaXJlY3RpdmUoe1xuICAgIHNlbGVjdG9yOiAnW3V4VGFiYmFibGVMaXN0XScsXG4gICAgZXhwb3J0QXM6ICd1eC10YWJiYWJsZS1saXN0JyxcbiAgICBwcm92aWRlcnM6IFtUYWJiYWJsZUxpc3RTZXJ2aWNlXVxufSlcbmV4cG9ydCBjbGFzcyBUYWJiYWJsZUxpc3REaXJlY3RpdmUgaW1wbGVtZW50cyBBZnRlckNvbnRlbnRJbml0LCBPbkRlc3Ryb3kge1xuICAgIC8qKiBBY2Nlc3MgdGhlIHRhYmJhYmxlIGxpc3Qgc2VydmljZSAqL1xuICAgIHByaXZhdGUgcmVhZG9ubHkgX3RhYmJhYmxlTGlzdCA9IGluamVjdChUYWJiYWJsZUxpc3RTZXJ2aWNlKTtcbiAgICAvKiogQWNjZXNzIHRoZSBuYXRpdmUgZG9tIGVsZW1lbnQgKi9cbiAgICByZWFkb25seSBlbGVtZW50UmVmID0gaW5qZWN0KEVsZW1lbnRSZWYpO1xuXG4gICAgLyoqIERldGVybWluZSB3aGV0aGVyIHRoZSB1cC9kb3duIGFycm93cyBzaG91bGQgYmUgdXNlZCBvciB0aGUgbGVmdC9yaWdodCBhcnJvd3MgKi9cbiAgICBASW5wdXQoKSBkaXJlY3Rpb246ICdob3Jpem9udGFsJyB8ICd2ZXJ0aWNhbCcgPSAndmVydGljYWwnO1xuXG4gICAgLyoqIEluZGljYXRlIHdoZXRoZXIgb3Igbm90IGZvY3VzIHNob3VsZCBsb29wIGJhY2sgdG8gdGhlIGZpcnN0IGVsZW1lbnQgYWZ0ZXIgdGhlIGxhc3QgKi9cbiAgICBASW5wdXQoKSB3cmFwOiBib29sZWFuID0gdHJ1ZTtcblxuICAgIC8qKiBJbmRpY2F0ZSB3aGV0aGVyIG9yIG5vdCB0aGUgZmlyc3QgaXRlbSBzaG91bGQgcmVjZWl2ZSBmb2N1cyBvbiBzaG93IC0gdXNlZnVsIGZvciBtb2RhbHMgYW5kIHBvcG92ZXJzICovXG4gICAgQElucHV0KCkgZm9jdXNPblNob3c6IGJvb2xlYW4gPSBmYWxzZTtcblxuICAgIC8qKiBJbmRpY2F0ZSB3aGV0aGVyIG9yIG5vdCBmb2N1cyBzaG91bGQgYmUgcmV0dXJuZWQgdG8gdGhlIHByZXZpb3VzIGVsZW1lbnQgKG9ubHkgYXBwbGljYWJsZSB3aGVuIHVzaW5nIGZvY3VzT25TaG93KSAqL1xuICAgIEBJbnB1dCgpIHJldHVybkZvY3VzOiBib29sZWFuID0gZmFsc2U7XG5cbiAgICAvKiogRW5hYmxpbmcgaGFuZGxpbmcgb2YgaGllcmFyY2hpY2FsIGxpc3RzIHZpYSB1c2Ugb2YgdGhlIGBUYWJiYWJsZUxpc3RJdGVtRGlyZWN0aXZlLnBhcmVudGAgcHJvcGVydHkuICovXG4gICAgQElucHV0KCkgc2V0IGhpZXJhcmNoeSh2YWx1ZTogYm9vbGVhbikgeyB0aGlzLl90YWJiYWJsZUxpc3QuaGllcmFyY2h5ID0gdmFsdWU7IH1cblxuICAgIC8qKiBQcmV2ZW50IGtleWJvYXJkIGludGVyYWN0aW9uIHdoZW4gYWx0IG1vZGlmaWVyIGtleSBpcyBwcmVzc2VkICovXG4gICAgQElucHV0KCkgc2V0IGFsbG93QWx0TW9kaWZpZXIodmFsdWU6IGJvb2xlYW4pIHsgdGhpcy5fdGFiYmFibGVMaXN0LmFsbG93QWx0TW9kaWZpZXIgPSB2YWx1ZTsgfVxuXG4gICAgLyoqIFByZXZlbnQga2V5Ym9hcmQgaW50ZXJhY3Rpb24gd2hlbiBjdHJsIG1vZGlmaWVyIGtleSBpcyBwcmVzc2VkICovXG4gICAgQElucHV0KCkgc2V0IGFsbG93Q3RybE1vZGlmaWVyKHZhbHVlOiBib29sZWFuKSB7IHRoaXMuX3RhYmJhYmxlTGlzdC5hbGxvd0N0cmxNb2RpZmllciA9IHZhbHVlOyB9XG5cbiAgICAvKiogRm9jdXMgdGhlIGZpcnN0IG9yIGxhc3QgaXRlbSB3aGVuIEhvbWUgb3IgRW5kIGtleXMgYXJlIHByZXNzZWQgKi9cbiAgICBASW5wdXQoKSBzZXQgYWxsb3dCb3VuZGFyeUtleXModmFsdWU6IGJvb2xlYW4pIHsgdGhpcy5fdGFiYmFibGVMaXN0LmFsbG93Qm91bmRhcnlLZXlzID0gdmFsdWU7IH1cblxuICAgIC8qKiBGaW5kIGFsbCB0YWJiYWJsZSBsaXN0IGl0ZW1zICovXG4gICAgQENvbnRlbnRDaGlsZHJlbihUYWJiYWJsZUxpc3RJdGVtRGlyZWN0aXZlLCB7IGRlc2NlbmRhbnRzOiB0cnVlIH0pIGl0ZW1zOiBRdWVyeUxpc3Q8VGFiYmFibGVMaXN0SXRlbURpcmVjdGl2ZT47XG5cbiAgICAvKiogU3RvcmUgdGhlIGN1cnJlbnRseSBmb2N1c2VkIEhUTUwgZWxlbWVudCAqL1xuICAgIHByaXZhdGUgX2ZvY3VzZWRFbGVtZW50OiBIVE1MRWxlbWVudDtcblxuICAgIC8qKiBTdG9yZSB0aGUgaXRlbXMgaW4gYSBzcGVjaWZpYyBvcmRlciAqL1xuICAgIHByaXZhdGUgX29yZGVyZWRJdGVtczogUXVlcnlMaXN0PFRhYmJhYmxlTGlzdEl0ZW1EaXJlY3RpdmU+O1xuXG4gICAgLyoqIFVuc3Vic2NyaWJlIGZyb20gYWxsIG9ic2VydmFibGVzIGF1dG9tYXRpY2FsbHkgb24gZGVzdHJveSAqL1xuICAgIHByaXZhdGUgcmVhZG9ubHkgX29uRGVzdHJveSA9IG5ldyBTdWJqZWN0PHZvaWQ+KCk7XG5cbiAgICBnZXQgZm9jdXNLZXlNYW5hZ2VyKCk6IEZvY3VzS2V5TWFuYWdlcjxUYWJiYWJsZUxpc3RJdGVtRGlyZWN0aXZlPiB7XG4gICAgICAgIHJldHVybiB0aGlzLl90YWJiYWJsZUxpc3QuZm9jdXNLZXlNYW5hZ2VyO1xuICAgIH1cblxuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICAvLyBzdG9yZSBhIHJlZmVyZW5jZSB0byB0aGUgY29udGFpbmVyIGVsZW1lbnRcbiAgICAgICAgdGhpcy5fdGFiYmFibGVMaXN0LmNvbnRhaW5lclJlZiA9IHRoaXMuZWxlbWVudFJlZi5uYXRpdmVFbGVtZW50O1xuICAgIH1cblxuICAgIG5nQWZ0ZXJDb250ZW50SW5pdCgpOiB2b2lkIHtcblxuICAgICAgICAvLyBzdG9yZSB0aGUgY3VycmVudGx5IGZvY3VzZWQgZWxlbWVudFxuICAgICAgICB0aGlzLl9mb2N1c2VkRWxlbWVudCA9IGRvY3VtZW50LmFjdGl2ZUVsZW1lbnQgYXMgSFRNTEVsZW1lbnQ7XG4gICAgICAgIHRoaXMuX29yZGVyZWRJdGVtcyA9IG5ldyBRdWVyeUxpc3Q8VGFiYmFibGVMaXN0SXRlbURpcmVjdGl2ZT4oKTtcblxuICAgICAgICBpZiAodGhpcy5fdGFiYmFibGVMaXN0LmhpZXJhcmNoeSkge1xuXG4gICAgICAgICAgICAvLyBTb3J0IGl0ZW1zIGluIGEgaGllcmFyY2h5XG4gICAgICAgICAgICB0aGlzLl9vcmRlcmVkSXRlbXMucmVzZXQodGhpcy5fdGFiYmFibGVMaXN0LnNvcnRJdGVtc0J5SGllcmFyY2h5KHRoaXMuaXRlbXMpKTtcblxuICAgICAgICAgICAgLy8gRW5zdXJlIHRoYXQgdGhlIGNoaWxkIGl0ZW1zIHJlbWFpbiBzb3J0ZWRcbiAgICAgICAgICAgIHRoaXMuaXRlbXMuY2hhbmdlcy5waXBlKHRha2VVbnRpbCh0aGlzLl9vbkRlc3Ryb3kpKS5zdWJzY3JpYmUoKCkgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMuX29yZGVyZWRJdGVtcy5yZXNldCh0aGlzLl90YWJiYWJsZUxpc3Quc29ydEl0ZW1zQnlIaWVyYXJjaHkodGhpcy5pdGVtcykpO1xuICAgICAgICAgICAgICAgIHRoaXMuX29yZGVyZWRJdGVtcy5ub3RpZnlPbkNoYW5nZXMoKTtcbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgIH0gZWxzZSB7XG5cbiAgICAgICAgICAgIC8vIEl0ZW1zIGFyZSBhbHJlYWR5IGluIG9yZGVyXG4gICAgICAgICAgICB0aGlzLl9vcmRlcmVkSXRlbXMgPSB0aGlzLml0ZW1zO1xuXG4gICAgICAgICAgICAvLyBFbnN1cmUgd2UgcmVzZWxlY3QgYSBzZWxlY3RlZCBpdGVtIGFmdGVyIHRoZSBxdWVyeWxpc3QgaGFzIGNoYW5nZWRcbiAgICAgICAgICAgIHRoaXMuaXRlbXMuY2hhbmdlcy5waXBlKGZpbHRlcigoKSA9PiB0aGlzLl90YWJiYWJsZUxpc3Quc2hvdWxkRm9jdXNPbkNoYW5nZSAmJiB0aGlzLl90YWJiYWJsZUxpc3QuaXNGb2N1c2VkKSwgdGFrZVVudGlsKHRoaXMuX29uRGVzdHJveSkpXG4gICAgICAgICAgICAgICAgLnN1YnNjcmliZSgoaXRlbXM6IFF1ZXJ5TGlzdDxUYWJiYWJsZUxpc3RJdGVtRGlyZWN0aXZlPikgPT4ge1xuXG4gICAgICAgICAgICAgICAgICAgIC8vIGNoZWNrIGlmIGFuIGl0ZW0gaXMgY3VycmVudGx5IGZvY3VzZWRcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgYWN0aXZlSXRlbSA9IHRoaXMuX3RhYmJhYmxlTGlzdC5mb2N1c0tleU1hbmFnZXIuYWN0aXZlSXRlbTtcblxuICAgICAgICAgICAgICAgICAgICAvLyByZXN0b3JlIHRoZSBzZWxlY3RlZCBpdGVtIGlmIHRoZXJlIHdhcyBvbmUgYW5kIGl0IGlzIHN0aWxsIHZpc2libGVcbiAgICAgICAgICAgICAgICAgICAgaWYgKGFjdGl2ZUl0ZW0pIHtcblxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gZmluZCB0aGUgbWF0Y2hpbmcgaW5kZXhcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGluZGV4ID0gaXRlbXMudG9BcnJheSgpLmZpbmRJbmRleChpdGVtID0+IGl0ZW0ua2V5ID09PSBhY3RpdmVJdGVtLmtleSk7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGlmIHRoZSBpdGVtIGlzIHN0aWxsIGluIHRoZSBsaXN0IHdlIHdhbnQgdG8gZm9jdXMgaXRcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpbmRleCA+IC0xKSB7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBob3dldmVyIHdlIGFyZSByZWZvY3VzaW5nIGFuIGl0ZW0gdGhhdCB3YXMgZm9jdXNlZCBzbyB3ZSBkb250IHdhbnQgdG8gc2Nyb2xsIGludG8gdmlldyBhZ2FpbiBhcyB0aGlzIGNhbiBwcmV2ZW50IHdoZWVsIHNjcm9sbGluZ1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX3RhYmJhYmxlTGlzdC5zaG91bGRTY3JvbGxJblZpZXcgPSBmYWxzZTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHJlZm9jdXMgdGhlIGl0ZW0gYWdhaW5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl90YWJiYWJsZUxpc3QuYWN0aXZhdGVJdGVtQXRJbmRleChpbmRleCwgIXRoaXMuX3RhYmJhYmxlTGlzdC5pc0ZvY3VzZWQpO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gcmUtZW5hYmxlIHNjcm9sbGluZyBpbnRvIHZpZXdcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl90YWJiYWJsZUxpc3Quc2hvdWxkU2Nyb2xsSW5WaWV3ID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gU2V0IHVwIHRoZSBmb2N1cyBtb25pdG9yaW5nXG4gICAgICAgIHRoaXMuX3RhYmJhYmxlTGlzdC5pbml0aWFsaXplKHRoaXMuX29yZGVyZWRJdGVtcywgdGhpcy5kaXJlY3Rpb24sIHRoaXMud3JhcCk7XG5cbiAgICAgICAgLy8gZm9jdXMgdGhlIGZpcnN0IGVsZW1lbnQgaWYgc3BlY2lmaWVkXG4gICAgICAgIGlmICh0aGlzLmZvY3VzT25TaG93KSB7XG4gICAgICAgICAgICB0aGlzLl90YWJiYWJsZUxpc3QuZm9jdXNLZXlNYW5hZ2VyLnNldEZpcnN0SXRlbUFjdGl2ZSgpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgbmdPbkRlc3Ryb3koKTogdm9pZCB7XG4gICAgICAgIGlmICh0aGlzLnJldHVybkZvY3VzICYmIHRoaXMuX2ZvY3VzZWRFbGVtZW50IGluc3RhbmNlb2YgSFRNTEVsZW1lbnQpIHtcbiAgICAgICAgICAgIHNldFRpbWVvdXQoKCkgPT4gdGhpcy5fZm9jdXNlZEVsZW1lbnQuZm9jdXMoKSk7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLl9vbkRlc3Ryb3kubmV4dCgpO1xuICAgICAgICB0aGlzLl9vbkRlc3Ryb3kuY29tcGxldGUoKTtcbiAgICB9XG5cbiAgICBzZXRGaXJzdEl0ZW1UYWJiYWJsZSgpOiB2b2lkIHtcbiAgICAgICAgaWYgKCF0aGlzLl90YWJiYWJsZUxpc3QuaXNBbnlJdGVtVGFiYmFibGUoKSkge1xuICAgICAgICAgICAgdGhpcy5fdGFiYmFibGVMaXN0LnNldEZpcnN0SXRlbVRhYmJhYmxlKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBmb2N1cygpOiB2b2lkIHtcbiAgICAgICAgaWYgKHRoaXMuX3RhYmJhYmxlTGlzdC5mb2N1c0tleU1hbmFnZXIgJiYgdGhpcy5fdGFiYmFibGVMaXN0LmZvY3VzS2V5TWFuYWdlci5hY3RpdmVJdGVtKSB7XG4gICAgICAgICAgICB0aGlzLl90YWJiYWJsZUxpc3QuZm9jdXNLZXlNYW5hZ2VyLmFjdGl2ZUl0ZW0uZm9jdXMoKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGZvY3VzVGFiYmFibGVJdGVtKCk6IHZvaWQge1xuICAgICAgICB0aGlzLl90YWJiYWJsZUxpc3QuZm9jdXNUYWJiYWJsZUl0ZW0oKTtcbiAgICB9XG59XG4iXX0=