UNPKG

@clr/angular

Version:

Angular components for Clarity

366 lines 46.6 kB
/* * 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 { Injectable } from '@angular/core'; import { Subject } from 'rxjs'; import { debounceTime } from 'rxjs/operators'; import { SelectionType } from '../enums/selection-type'; import * as i0 from "@angular/core"; import * as i1 from "./items"; import * as i2 from "./filters"; let nbSelection = 0; export class Selection { constructor(_items, _filters) { this._items = _items; this._filters = _filters; this.preserveSelection = false; /** * Shift key state, for use in range selection. */ this.shiftPressed = false; /** @deprecated since 2.0, remove in 3.0 */ this.rowSelectionMode = false; this.prevSelectionRefs = []; // Refs of selected items this.lockedRefs = []; // Ref of locked items this.valueCollector = new Subject(); this._selectionType = SelectionType.None; /** * The Observable that lets other classes subscribe to selection changes */ this._change = new Subject(); /** * Subscriptions to the other providers changes. */ this.subscriptions = []; this.id = 'clr-dg-selection' + nbSelection++; this.subscriptions.push(this._filters.change.subscribe(() => { if (!this._selectable || this.preserveSelection) { return; } this.clearSelection(); })); this.subscriptions.push(this._items.allChanges.subscribe(updatedItems => { // Reset the lockedRefs; const updateLockedRef = []; switch (this.selectionType) { case SelectionType.None: { break; } case SelectionType.Single: { let newSingle; let selectionUpdated = false; // if the currentSingle has been set before data was loaded, we look up and save the ref from current data set if (this.currentSingle && !this.prevSingleSelectionRef) { if (this._items.canTrackBy()) { this.prevSingleSelectionRef = this._items.trackBy(this.currentSingle); } } updatedItems.forEach((item, index) => { const ref = this._items.trackBy(item, index); // If one of the updated items is the previously selectedSingle, set it as the new one if (this.prevSingleSelectionRef === ref) { newSingle = item; selectionUpdated = true; } if (this.lockedRefs.indexOf(ref) > -1) { updateLockedRef.push(ref); } }); // If we're using smart datagrids, we expect all items to be present in the updatedItems array. // Therefore, we should delete the currentSingle if it used to be defined but doesn't exist anymore. // No explicit "delete" is required, since newSingle would be undefined at this point. // Marking it as selectionUpdated here will set currentSingle to undefined below in the setTimeout. if (this._items.smart && !newSingle) { selectionUpdated = true; } // TODO: Discussed this with Eudes and this is fine for now. // But we need to figure out a different pattern for the // child triggering the parent change detection problem. // Using setTimeout for now to fix this. setTimeout(() => { if (selectionUpdated) { this.currentSingle = newSingle; } }, 0); break; } case SelectionType.Multi: { let leftOver = this.current.slice(); let selectionUpdated = false; // if the current has been set before data was loaded, we look up and save the ref from current data set if (this.current.length > 0 && this.prevSelectionRefs.length !== this.current.length) { if (this._items.canTrackBy()) { this.prevSelectionRefs = []; this.current.forEach(item => { this.prevSelectionRefs.push(this._items.trackBy(item)); }); } } // Duplicate loop, when the issue is issue#2342 is revisited keep in mind that // we need to go over every updated item and check to see if there are valid to be // locked or not and update it. When only add items that are found in the lockedRefs back. // // The both loops below that goes over updatedItems could be combined into one. updatedItems.forEach((item, index) => { const ref = this._items.trackBy(item, index); if (this.lockedRefs.indexOf(ref) > -1) { updateLockedRef.push(ref); } }); // TODO: revisit this when we work on https://github.com/vmware/clarity/issues/2342 // currently, the selection is cleared when filter is applied, so the logic inside // the if statement below results in broken behavior. if (leftOver.length > 0) { updatedItems.forEach((item, index) => { const ref = this._items.trackBy(item, index); // Look in current selected refs array if item is selected, and update actual value const selectedIndex = this.prevSelectionRefs.indexOf(ref); if (selectedIndex > -1) { leftOver[selectedIndex] = item; selectionUpdated = true; } }); // Filter out any unmatched items if we're using smart datagrids where we expect all items to be // present if (this._items.smart) { leftOver = leftOver.filter(selected => updatedItems.indexOf(selected) > -1); if (this.current.length !== leftOver.length) { selectionUpdated = true; } } // TODO: Discussed this with Eudes and this is fine for now. // But we need to figure out a different pattern for the // child triggering the parent change detection problem. // Using setTimeout for now to fix this. setTimeout(() => { if (selectionUpdated) { this.current = leftOver; } }, 0); } break; } default: { break; } } // Sync locked items this.lockedRefs = updateLockedRef; })); this.subscriptions.push(this.valueCollector.pipe(debounceTime(0)).subscribe(() => this.emitChange())); } get selectionType() { return this._selectionType; } set selectionType(value) { if (value === this.selectionType) { return; } this._selectionType = value; if (value === SelectionType.None) { delete this.current; } else { this.updateCurrent([], false); } } get current() { return this._current; } set current(value) { this.updateCurrent(value, true); } get currentSingle() { return this._currentSingle; } set currentSingle(value) { if (value === this._currentSingle) { return; } this._currentSingle = value; if (this._items.canTrackBy() && value) { this.prevSingleSelectionRef = this._items.trackBy(value); } this.emitChange(); } // We do not want to expose the Subject itself, but the Observable which is read-only get change() { return this._change.asObservable(); } get _selectable() { return this._selectionType === SelectionType.Multi || this._selectionType === SelectionType.Single; } clearSelection() { this._current = []; this.prevSelectionRefs = []; this.prevSingleSelectionRef = null; this._currentSingle = null; this.emitChange(); } /** * Cleans up our subscriptions to other providers */ destroy() { this.subscriptions.forEach(sub => sub.unsubscribe()); } updateCurrent(value, emit) { this._current = value; if (emit) { this.valueCollector.next(value); } } /** * Checks if an item is currently selected */ isSelected(item) { if (this._selectionType === SelectionType.Single) { return this.currentSingle === item; } else if (this._selectionType === SelectionType.Multi) { return this.current.indexOf(item) >= 0; } return false; } /** * Selects or deselects an item */ setSelected(item, selected) { const index = this.current ? this.current.indexOf(item) : -1; switch (this._selectionType) { case SelectionType.None: break; case SelectionType.Single: // in single selection, set currentSingle method should be used break; case SelectionType.Multi: if (index >= 0 && !selected) { this.deselectItem(index); } else if (index < 0 && selected) { this.selectItem(item); } break; default: break; } } /** * Checks if all currently displayed items are selected */ isAllSelected() { if (this._selectionType !== SelectionType.Multi || !this._items.displayed) { return false; } // make sure to exclude the locked items from the list when counting const displayedItems = this._items.displayed.filter(item => { return this.isLocked(item) === false; }); const nbDisplayed = displayedItems.length; if (nbDisplayed < 1) { return false; } const temp = displayedItems.filter(item => this.current.indexOf(item) > -1); return temp.length === displayedItems.length; } /** * Lock and unlock item */ lockItem(item, lock) { if (this.canItBeLocked()) { const ref = this._items.trackBy(item); if (lock === true) { // Add to lockedRef this.lockedRefs.push(ref); } else { // Remove from lockedRef this.lockedRefs = this.lockedRefs.filter(lockedItem => ref !== lockedItem); } } } /** * Check is item locked or not by searching into lockedRefs for entry */ isLocked(item) { /** * The check for selectionType will boost the performance by NOT searching * into the array when there is no need for that. */ if (this.canItBeLocked()) { const ref = this._items.trackBy(item); return this.lockedRefs.indexOf(ref) > -1; } return false; } /** * Selects or deselects all currently displayed items */ toggleAll() { if (this._selectionType === SelectionType.None || this._selectionType === SelectionType.Single) { return; } /** * If every currently displayed item is already selected, we clear them. * If at least one item isn't selected, we select every currently displayed item. */ if (this.isAllSelected()) { this._items.displayed.forEach(item => { const currentIndex = this.current.indexOf(item); if (currentIndex > -1 && this.isLocked(item) === false) { this.deselectItem(currentIndex); } }); } else { this._items.displayed.forEach(item => { if (this.current.indexOf(item) < 0 && this.isLocked(item) === false) { this.selectItem(item); } }); } } /** * Selects an item */ selectItem(item) { this.current = this.current.concat(item); if (this._items.canTrackBy()) { // Push selected ref onto array this.prevSelectionRefs.push(this._items.trackBy(item)); } } /** * Deselects an item */ deselectItem(indexOfItem) { this.current = this.current.slice(0, indexOfItem).concat(this.current.slice(indexOfItem + 1)); if (indexOfItem < this.prevSelectionRefs.length) { // Keep selected refs array in sync const removedItems = this.prevSelectionRefs.splice(indexOfItem, 1); // locked reference is no longer needed (if any) this.lockedRefs = this.lockedRefs.filter(locked => locked !== removedItems[0]); } } /** * Make sure that it could be locked */ canItBeLocked() { return this._selectionType !== SelectionType.None && this._items.canTrackBy(); } emitChange() { if (this._selectionType === SelectionType.Single) { this._change.next(this.currentSingle); } else if (this._selectionType === SelectionType.Multi) { this._change.next(this.current); } } } Selection.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: Selection, deps: [{ token: i1.Items }, { token: i2.FiltersProvider }], target: i0.ɵɵFactoryTarget.Injectable }); Selection.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: Selection }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: Selection, decorators: [{ type: Injectable }], ctorParameters: function () { return [{ type: i1.Items }, { type: i2.FiltersProvider }]; } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VsZWN0aW9uLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvYW5ndWxhci9zcmMvZGF0YS9kYXRhZ3JpZC9wcm92aWRlcnMvc2VsZWN0aW9uLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7O0dBSUc7QUFFSCxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQzNDLE9BQU8sRUFBYyxPQUFPLEVBQWdCLE1BQU0sTUFBTSxDQUFDO0FBQ3pELE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUU5QyxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0seUJBQXlCLENBQUM7Ozs7QUFJeEQsSUFBSSxXQUFXLEdBQUcsQ0FBQyxDQUFDO0FBR3BCLE1BQU0sT0FBTyxTQUFTO0lBMkNwQixZQUFvQixNQUFnQixFQUFVLFFBQTRCO1FBQXRELFdBQU0sR0FBTixNQUFNLENBQVU7UUFBVSxhQUFRLEdBQVIsUUFBUSxDQUFvQjtRQXpDMUUsc0JBQWlCLEdBQUcsS0FBSyxDQUFDO1FBTzFCOztXQUVHO1FBQ0gsaUJBQVksR0FBRyxLQUFLLENBQUM7UUFFckIsMkNBQTJDO1FBQzNDLHFCQUFnQixHQUFHLEtBQUssQ0FBQztRQUVqQixzQkFBaUIsR0FBUSxFQUFFLENBQUMsQ0FBQyx5QkFBeUI7UUFFdEQsZUFBVSxHQUFRLEVBQUUsQ0FBQyxDQUFDLHNCQUFzQjtRQUM1QyxtQkFBYyxHQUFHLElBQUksT0FBTyxFQUFPLENBQUM7UUFDcEMsbUJBQWMsR0FBa0IsYUFBYSxDQUFDLElBQUksQ0FBQztRQVkzRDs7V0FFRztRQUNLLFlBQU8sR0FBRyxJQUFJLE9BQU8sRUFBVyxDQUFDO1FBRXpDOztXQUVHO1FBQ0ssa0JBQWEsR0FBbUIsRUFBRSxDQUFDO1FBR3pDLElBQUksQ0FBQyxFQUFFLEdBQUcsa0JBQWtCLEdBQUcsV0FBVyxFQUFFLENBQUM7UUFFN0MsSUFBSSxDQUFDLGFB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Z2h0cyBSZXNlcnZlZC5cbiAqIFRoaXMgc29mdHdhcmUgaXMgcmVsZWFzZWQgdW5kZXIgTUlUIGxpY2Vuc2UuXG4gKiBUaGUgZnVsbCBsaWNlbnNlIGluZm9ybWF0aW9uIGNhbiBiZSBmb3VuZCBpbiBMSUNFTlNFIGluIHRoZSByb290IGRpcmVjdG9yeSBvZiB0aGlzIHByb2plY3QuXG4gKi9cblxuaW1wb3J0IHsgSW5qZWN0YWJsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgT2JzZXJ2YWJsZSwgU3ViamVjdCwgU3Vic2NyaXB0aW9uIH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBkZWJvdW5jZVRpbWUgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5cbmltcG9ydCB7IFNlbGVjdGlvblR5cGUgfSBmcm9tICcuLi9lbnVtcy9zZWxlY3Rpb24tdHlwZSc7XG5pbXBvcnQgeyBGaWx0ZXJzUHJvdmlkZXIgfSBmcm9tICcuL2ZpbHRlcnMnO1xuaW1wb3J0IHsgSXRlbXMgfSBmcm9tICcuL2l0ZW1zJztcblxubGV0IG5iU2VsZWN0aW9uID0gMDtcblxuQEluamVjdGFibGUoKVxuZXhwb3J0IGNsYXNzIFNlbGVjdGlvbjxUID0gYW55PiB7XG4gIGlkOiBzdHJpbmc7XG4gIHByZXNlcnZlU2VsZWN0aW9uID0gZmFsc2U7XG5cbiAgLyoqXG4gICAqIExhc3Qgc2VsZWN0aW9uLCBmb3IgdXNlIGluIHJhbmdlIHNlbGVjdGlvbi5cbiAgICovXG4gIHJhbmdlU3RhcnQ6IFQ7XG5cbiAgLyoqXG4gICAqIFNoaWZ0IGtleSBzdGF0ZSwgZm9yIHVzZSBpbiByYW5nZSBzZWxlY3Rpb24uXG4gICAqL1xuICBzaGlmdFByZXNzZWQgPSBmYWxzZTtcblxuICAvKiogQGRlcHJlY2F0ZWQgc2luY2UgMi4wLCByZW1vdmUgaW4gMy4wICovXG4gIHJvd1NlbGVjdGlvbk1vZGUgPSBmYWxzZTtcblxuICBwcml2YXRlIHByZXZTZWxlY3Rpb25SZWZzOiBUW10gPSBbXTsgLy8gUmVmcyBvZiBzZWxlY3RlZCBpdGVtc1xuICBwcml2YXRlIHByZXZTaW5nbGVTZWxlY3Rpb25SZWY6IFQ7IC8vIFJlZiBvZiBzaW5nbGUgc2VsZWN0ZWQgaXRlbVxuICBwcml2YXRlIGxvY2tlZFJlZnM6IFRbXSA9IFtdOyAvLyBSZWYgb2YgbG9ja2VkIGl0ZW1zXG4gIHByaXZhdGUgdmFsdWVDb2xsZWN0b3IgPSBuZXcgU3ViamVjdDxUW10+KCk7XG4gIHByaXZhdGUgX3NlbGVjdGlvblR5cGU6IFNlbGVjdGlvblR5cGUgPSBTZWxlY3Rpb25UeXBlLk5vbmU7XG5cbiAgLyoqXG4gICAqIFRoZSBjdXJyZW50IHNlbGVjdGlvblxuICAgKi9cbiAgcHJpdmF0ZSBfY3VycmVudDogVFtdO1xuXG4gIC8qKlxuICAgKiBUaGUgY3VycmVudCBzZWxlY3Rpb24gaW4gc2luZ2xlIHNlbGVjdGlvbiB0eXBlXG4gICAqL1xuICBwcml2YXRlIF9jdXJyZW50U2luZ2xlOiBUO1xuXG4gIC8qKlxuICAgKiBUaGUgT2JzZXJ2YWJsZSB0aGF0IGxldHMgb3RoZXIgY2xhc3NlcyBzdWJzY3JpYmUgdG8gc2VsZWN0aW9uIGNoYW5nZXNcbiAgICovXG4gIHByaXZhdGUgX2NoYW5nZSA9IG5ldyBTdWJqZWN0PFRbXSB8IFQ+KCk7XG5cbiAgLyoqXG4gICAqIFN1YnNjcmlwdGlvbnMgdG8gdGhlIG90aGVyIHByb3ZpZGVycyBjaGFuZ2VzLlxuICAgKi9cbiAgcHJpdmF0ZSBzdWJzY3JpcHRpb25zOiBTdWJzY3JpcHRpb25bXSA9IFtdO1xuXG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgX2l0ZW1zOiBJdGVtczxUPiwgcHJpdmF0ZSBfZmlsdGVyczogRmlsdGVyc1Byb3ZpZGVyPFQ+KSB7XG4gICAgdGhpcy5pZCA9ICdjbHItZGctc2VsZWN0aW9uJyArIG5iU2VsZWN0aW9uKys7XG5cbiAgICB0aGlzLnN1YnNjcmlwdGlvbnMucHVzaChcbiAgICAgIHRoaXMuX2ZpbHRlcnMuY2hhbmdlLnN1YnNjcmliZSgoKSA9PiB7XG4gICAgICAgIGlmICghdGhpcy5fc2VsZWN0YWJsZSB8fCB0aGlzLnByZXNlcnZlU2VsZWN0aW9uKSB7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuY2xlYXJTZWxlY3Rpb24oKTtcbiAgICAgIH0pXG4gICAgKTtcblxuICAgIHRoaXMuc3Vic2NyaXB0aW9ucy5wdXNoKFxuICAgICAgdGhpcy5faXRlbXMuYWxsQ2hhbmdlcy5zdWJzY3JpYmUodXBkYXRlZEl0ZW1zID0+IHtcbiAgICAgICAgLy8gUmVzZXQgdGhlIGxvY2tlZFJlZnM7XG4gICAgICAgIGNvbnN0IHVwZGF0ZUxvY2tlZFJlZjogVFtdID0gW107XG5cbiAgICAgICAgc3dpdGNoICh0aGlzLnNlbGVjdGlvblR5cGUpIHtcbiAgICAgICAgICBjYXNlIFNlbGVjdGlvblR5cGUuTm9uZToge1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgY2FzZSBTZWxlY3Rpb25UeXBlLlNpbmdsZToge1xuICAgICAgICAgICAgbGV0IG5ld1NpbmdsZTogYW55O1xuICAgICAgICAgICAgbGV0IHNlbGVjdGlvblVwZGF0ZWQgPSBmYWxzZTtcblxuICAgICAgICAgICAgLy8gaWYgdGhlIGN1cnJlbnRTaW5nbGUgaGFzIGJlZW4gc2V0IGJlZm9yZSBkYXRhIHdhcyBsb2FkZWQsIHdlIGxvb2sgdXAgYW5kIHNhdmUgdGhlIHJlZiBmcm9tIGN1cnJlbnQgZGF0YSBzZXRcbiAgICAgICAgICAgIGlmICh0aGlzLmN1cnJlbnRTaW5nbGUgJiYgIXRoaXMucHJldlNpbmdsZVNlbGVjdGlvblJlZikge1xuICAgICAgICAgICAgICBpZiAodGhpcy5faXRlbXMuY2FuVHJhY2tCeSgpKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5wcmV2U2luZ2xlU2VsZWN0aW9uUmVmID0gdGhpcy5faXRlbXMudHJhY2tCeSh0aGlzLmN1cnJlbnRTaW5nbGUpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHVwZGF0ZWRJdGVtcy5mb3JFYWNoKChpdGVtLCBpbmRleCkgPT4ge1xuICAgICAgICAgICAgICBjb25zdCByZWYgPSB0aGlzLl9pdGVtcy50cmFja0J5KGl0ZW0sIGluZGV4KTtcbiAgICAgICAgICAgICAgLy8gSWYgb25lIG9mIHRoZSB1cGRhdGVkIGl0ZW1zIGlzIHRoZSBwcmV2aW91c2x5IHNlbGVjdGVkU2luZ2xlLCBzZXQgaXQgYXMgdGhlIG5ldyBvbmVcbiAgICAgICAgICAgICAgaWYgKHRoaXMucHJldlNpbmdsZVNlbGVjdGlvblJlZiA9PT0gcmVmKSB7XG4gICAgICAgICAgICAgICAgbmV3U2luZ2xlID0gaXRlbTtcbiAgICAgICAgICAgICAgICBzZWxlY3Rpb25VcGRhdGVkID0gdHJ1ZTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICBpZiAodGhpcy5sb2NrZWRSZWZzLmluZGV4T2YocmVmKSA+IC0xKSB7XG4gICAgICAgICAgICAgICAgdXBkYXRlTG9ja2VkUmVmLnB1c2gocmVmKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIC8vIElmIHdlJ3JlIHVzaW5nIHNtYXJ0IGRhdGFncmlkcywgd2UgZXhwZWN0IGFsbCBpdGVtcyB0byBiZSBwcmVzZW50IGluIHRoZSB1cGRhdGVkSXRlbXMgYXJyYXkuXG4gICAgICAgICAgICAvLyBUaGVyZWZvcmUsIHdlIHNob3VsZCBkZWxldGUgdGhlIGN1cnJlbnRTaW5nbGUgaWYgaXQgdXNlZCB0byBiZSBkZWZpbmVkIGJ1dCBkb2Vzbid0IGV4aXN0IGFueW1vcmUuXG4gICAgICAgICAgICAvLyBObyBleHBsaWNpdCBcImRlbGV0ZVwiIGlzIHJlcXVpcmVkLCBzaW5jZSBuZXdTaW5nbGUgd291bGQgYmUgdW5kZWZpbmVkIGF0IHRoaXMgcG9pbnQuXG4gICAgICAgICAgICAvLyBNYXJraW5nIGl0IGFzIHNlbGVjdGlvblVwZGF0ZWQgaGVyZSB3aWxsIHNldCBjdXJyZW50U2luZ2xlIHRvIHVuZGVmaW5lZCBiZWxvdyBpbiB0aGUgc2V0VGltZW91dC5cbiAgICAgICAgICAgIGlmICh0aGlzLl9pdGVtcy5zbWFydCAmJiAhbmV3U2luZ2xlKSB7XG4gICAgICAgICAgICAgIHNlbGVjdGlvblVwZGF0ZWQgPSB0cnVlO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBUT0RPOiBEaXNjdXNzZWQgdGhpcyB3aXRoIEV1ZGVzIGFuZCB0aGlzIGlzIGZpbmUgZm9yIG5vdy5cbiAgICAgICAgICAgIC8vIEJ1dCB3ZSBuZWVkIHRvIGZpZ3VyZSBvdXQgYSBkaWZmZXJlbnQgcGF0dGVybiBmb3IgdGhlXG4gICAgICAgICAgICAvLyBjaGlsZCB0cmlnZ2VyaW5nIHRoZSBwYXJlbnQgY2hhbmdlIGRldGVjdGlvbiBwcm9ibGVtLlxuICAgICAgICAgICAgLy8gVXNpbmcgc2V0VGltZW91dCBmb3Igbm93IHRvIGZpeCB0aGlzLlxuICAgICAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgICAgIGlmIChzZWxlY3Rpb25VcGRhdGVkKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5jdXJyZW50U2luZ2xlID0gbmV3U2luZ2xlO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9LCAwKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGNhc2UgU2VsZWN0aW9uVHlwZS5NdWx0aToge1xuICAgICAgICAgICAgbGV0IGxlZnRPdmVyOiBhbnlbXSA9IHRoaXMuY3VycmVudC5zbGljZSgpO1xuICAgICAgICAgICAgbGV0IHNlbGVjdGlvblVwZGF0ZWQgPSBmYWxzZTtcblxuICAgICAgICAgICAgLy8gaWYgdGhlIGN1cnJlbnQgaGFzIGJlZW4gc2V0IGJlZm9yZSBkYXRhIHdhcyBsb2FkZWQsIHdlIGxvb2sgdXAgYW5kIHNhdmUgdGhlIHJlZiBmcm9tIGN1cnJlbnQgZGF0YSBzZXRcbiAgICAgICAgICAgIGlmICh0aGlzLmN1cnJlbnQubGVuZ3RoID4gMCAmJiB0aGlzLnByZXZTZWxlY3Rpb25SZWZzLmxlbmd0aCAhPT0gdGhpcy5jdXJyZW50Lmxlbmd0aCkge1xuICAgICAgICAgICAgICBpZiAodGhpcy5faXRlbXMuY2FuVHJhY2tCeSgpKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5wcmV2U2VsZWN0aW9uUmVmcyA9IFtdO1xuICAgICAgICAgICAgICAgIHRoaXMuY3VycmVudC5mb3JFYWNoKGl0ZW0gPT4ge1xuICAgICAgICAgICAgICAgICAgdGhpcy5wcmV2U2VsZWN0aW9uUmVmcy5wdXNoKHRoaXMuX2l0ZW1zLnRyYWNrQnkoaXRlbSkpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIER1cGxpY2F0ZSBsb29wLCB3aGVuIHRoZSBpc3N1ZSBpcyBpc3N1ZSMyMzQyIGlzIHJldmlzaXRlZCBrZWVwIGluIG1pbmQgdGhhdFxuICAgICAgICAgICAgLy8gd2UgbmVlZCB0byBnbyBvdmVyIGV2ZXJ5IHVwZGF0ZWQgaXRlbSBhbmQgY2hlY2sgdG8gc2VlIGlmIHRoZXJlIGFyZSB2YWxpZCB0byBiZVxuICAgICAgICAgICAgLy8gbG9ja2VkIG9yIG5vdCBhbmQgdXBkYXRlIGl0LiBXaGVuIG9ubHkgYWRkIGl0ZW1zIHRoYXQgYXJlIGZvdW5kIGluIHRoZSBsb2NrZWRSZWZzIGJhY2suXG4gICAgICAgICAgICAvL1xuICAgICAgICAgICAgLy8gVGhlIGJvdGggbG9vcHMgYmVsb3cgdGhhdCBnb2VzIG92ZXIgdXBkYXRlZEl0ZW1zIGNvdWxkIGJlIGNvbWJpbmVkIGludG8gb25lLlxuICAgICAgICAgICAgdXBkYXRlZEl0ZW1zLmZvckVhY2goKGl0ZW0sIGluZGV4KSA9PiB7XG4gICAgICAgICAgICAgIGNvbnN0IHJlZiA9IHRoaXMuX2l0ZW1zLnRyYWNrQnkoaXRlbSwgaW5kZXgpO1xuICAgICAgICAgICAgICBpZiAodGhpcy5sb2NrZWRSZWZzLmluZGV4T2YocmVmKSA+IC0xKSB7XG4gICAgICAgICAgICAgICAgdXBkYXRlTG9ja2VkUmVmLnB1c2gocmVmKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIC8vIFRPRE86IHJldmlzaXQgdGhpcyB3aGVuIHdlIHdvcmsgb24gaHR0cHM6Ly9naXRodWIuY29tL3Ztd2FyZS9jbGFyaXR5L2lzc3Vlcy8yMzQyXG4gICAgICAgICAgICAvLyBjdXJyZW50bHksIHRoZSBzZWxlY3Rpb24gaXMgY2xlYXJlZCB3aGVuIGZpbHRlciBpcyBhcHBsaWVkLCBzbyB0aGUgbG9naWMgaW5zaWRlXG4gICAgICAgICAgICAvLyB0aGUgaWYgc3RhdGVtZW50IGJlbG93IHJlc3VsdHMgaW4gYnJva2VuIGJlaGF2aW9yLlxuICAgICAgICAgICAgaWYgKGxlZnRPdmVyLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgICAgdXBkYXRlZEl0ZW1zLmZvckVhY2goKGl0ZW0sIGluZGV4KSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgcmVmID0gdGhpcy5faXRlbXMudHJhY2tCeShpdGVtLCBpbmRleCk7XG4gICAgICAgICAgICAgICAgLy8gTG9vayBpbiBjdXJyZW50IHNlbGVjdGVkIHJlZnMgYXJyYXkgaWYgaXRlbSBpcyBzZWxlY3RlZCwgYW5kIHVwZGF0ZSBhY3R1YWwgdmFsdWVcbiAgICAgICAgICAgICAgICBjb25zdCBzZWxlY3RlZEluZGV4ID0gdGhpcy5wcmV2U2VsZWN0aW9uUmVmcy5pbmRleE9mKHJlZik7XG4gICAgICAgICAgICAgICAgaWYgKHNlbGVjdGVkSW5kZXggPiAtMSkge1xuICAgICAgICAgICAgICAgICAgbGVmdE92ZXJbc2VsZWN0ZWRJbmRleF0gPSBpdGVtO1xuICAgICAgICAgICAgICAgICAgc2VsZWN0aW9uVXBkYXRlZCA9IHRydWU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgICAvLyBGaWx0ZXIgb3V0IGFueSB1bm1hdGNoZWQgaXRlbXMgaWYgd2UncmUgdXNpbmcgc21hcnQgZGF0YWdyaWRzIHdoZXJlIHdlIGV4cGVjdCBhbGwgaXRlbXMgdG8gYmVcbiAgICAgICAgICAgICAgLy8gcHJlc2VudFxuICAgICAgICAgICAgICBpZiAodGhpcy5faXRlbXMuc21hcnQpIHtcbiAgICAgICAgICAgICAgICBsZWZ0T3ZlciA9IGxlZnRPdmVyLmZpbHRlcihzZWxlY3RlZCA9PiB1cGRhdGVkSXRlbXMuaW5kZXhPZihzZWxlY3RlZCkgPiAtMSk7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuY3VycmVudC5sZW5ndGggIT09IGxlZnRPdmVyLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgICAgc2VsZWN0aW9uVXBkYXRlZCA9IHRydWU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgLy8gVE9ETzogRGlzY3Vzc2VkIHRoaXMgd2l0aCBFdWRlcyBhbmQgdGhpcyBpcyBmaW5lIGZvciBub3cuXG4gICAgICAgICAgICAgIC8vIEJ1dCB3ZSBuZWVkIHRvIGZpZ3VyZSBvdXQgYSBkaWZmZXJlbnQgcGF0dGVybiBmb3IgdGhlXG4gICAgICAgICAgICAgIC8vIGNoaWxkIHRyaWdnZXJpbmcgdGhlIHBhcmVudCBjaGFuZ2UgZGV0ZWN0aW9uIHByb2JsZW0uXG4gICAgICAgICAgICAgIC8vIFVzaW5nIHNldFRpbWVvdXQgZm9yIG5vdyB0byBmaXggdGhpcy5cbiAgICAgICAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKHNlbGVjdGlvblVwZGF0ZWQpIHtcbiAgICAgICAgICAgICAgICAgIHRoaXMuY3VycmVudCA9IGxlZnRPdmVyO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfSwgMCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBkZWZhdWx0OiB7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgLy8gU3luYyBsb2NrZWQgaXRlbXNcbiAgICAgICAgdGhpcy5sb2NrZWRSZWZzID0gdXBkYXRlTG9ja2VkUmVmO1xuICAgICAgfSlcbiAgICApO1xuXG4gICAgdGhpcy5zdWJzY3JpcHRpb25zLnB1c2godGhpcy52YWx1ZUNvbGxlY3Rvci5waXBlKGRlYm91bmNlVGltZSgwKSkuc3Vic2NyaWJlKCgpID0+IHRoaXMuZW1pdENoYW5nZSgpKSk7XG4gIH1cblxuICBnZXQgc2VsZWN0aW9uVHlwZSgpOiBTZWxlY3Rpb25UeXBlIHtcbiAgICByZXR1cm4gdGhpcy5fc2VsZWN0aW9uVHlwZTtcbiAgfVxuICBzZXQgc2VsZWN0aW9uVHlwZSh2YWx1ZTogU2VsZWN0aW9uVHlwZSkge1xuICAgIGlmICh2YWx1ZSA9PT0gdGhpcy5zZWxlY3Rpb25UeXBlKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRoaXMuX3NlbGVjdGlvblR5cGUgPSB2YWx1ZTtcbiAgICBpZiAodmFsdWUgPT09IFNlbGVjdGlvblR5cGUuTm9uZSkge1xuICAgICAgZGVsZXRlIHRoaXMuY3VycmVudDtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy51cGRhdGVDdXJyZW50KFtdLCBmYWxzZSk7XG4gICAgfVxuICB9XG5cbiAgZ2V0IGN1cnJlbnQoKTogVFtdIHtcbiAgICByZXR1cm4gdGhpcy5fY3VycmVudDtcbiAgfVxuICBzZXQgY3VycmVudCh2YWx1ZTogVFtdKSB7XG4gICAgdGhpcy51cGRhdGVDdXJyZW50KHZhbHVlLCB0cnVlKTtcbiAgfVxuXG4gIGdldCBjdXJyZW50U2luZ2xlKCk6IFQge1xuICAgIHJldHVybiB0aGlzLl9jdXJyZW50U2luZ2xlO1xuICB9XG4gIHNldCBjdXJyZW50U2luZ2xlKHZhbHVlOiBUKSB7XG4gICAgaWYgKHZhbHVlID09PSB0aGlzLl9jdXJyZW50U2luZ2xlKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy5fY3VycmVudFNpbmdsZSA9IHZhbHVlO1xuICAgIGlmICh0aGlzLl9pdGVtcy5jYW5UcmFja0J5KCkgJiYgdmFsdWUpIHtcbiAgICAgIHRoaXMucHJldlNpbmdsZVNlbGVjdGlvblJlZiA9IHRoaXMuX2l0ZW1zLnRyYWNrQnkodmFsdWUpO1xuICAgIH1cbiAgICB0aGlzLmVtaXRDaGFuZ2UoKTtcbiAgfVxuXG4gIC8vIFdlIGRvIG5vdCB3YW50IHRvIGV4cG9zZSB0aGUgU3ViamVjdCBpdHNlbGYsIGJ1dCB0aGUgT2JzZXJ2YWJsZSB3aGljaCBpcyByZWFkLW9ubHlcbiAgZ2V0IGNoYW5nZSgpOiBPYnNlcnZhYmxlPFRbXSB8IFQ+IHtcbiAgICByZXR1cm4gdGhpcy5fY2hhbmdlLmFzT2JzZXJ2YWJsZSgpO1xuICB9XG5cbiAgcHJpdmF0ZSBnZXQgX3NlbGVjdGFibGUoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuX3NlbGVjdGlvblR5cGUgPT09IFNlbGVjdGlvblR5cGUuTXVsdGkgfHwgdGhpcy5fc2VsZWN0aW9uVHlwZSA9PT0gU2VsZWN0aW9uVHlwZS5TaW5nbGU7XG4gIH1cblxuICBjbGVhclNlbGVjdGlvbigpOiB2b2lkIHtcbiAgICB0aGlzLl9jdXJyZW50ID0gW107XG4gICAgdGhpcy5wcmV2U2VsZWN0aW9uUmVmcyA9IFtdO1xuICAgIHRoaXMucHJldlNpbmdsZVNlbGVjdGlvblJlZiA9IG51bGw7XG4gICAgdGhpcy5fY3VycmVudFNpbmdsZSA9IG51bGw7XG4gICAgdGhpcy5lbWl0Q2hhbmdlKCk7XG4gIH1cblxuICAvKipcbiAgICogQ2xlYW5zIHVwIG91ciBzdWJzY3JpcHRpb25zIHRvIG90aGVyIHByb3ZpZGVyc1xuICAgKi9cbiAgZGVzdHJveSgpIHtcbiAgICB0aGlzLnN1YnNjcmlwdGlvbnMuZm9yRWFjaChzdWIgPT4gc3ViLnVuc3Vic2NyaWJlKCkpO1xuICB9XG5cbiAgdXBkYXRlQ3VycmVudCh2YWx1ZTogVFtdLCBlbWl0OiBib29sZWFuKSB7XG4gICAgdGhpcy5fY3VycmVudCA9IHZhbHVlO1xuXG4gICAgaWYgKGVtaXQpIHtcbiAgICAgIHRoaXMudmFsdWVDb2xsZWN0b3IubmV4dCh2YWx1ZSk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIENoZWNrcyBpZiBhbiBpdGVtIGlzIGN1cnJlbnRseSBzZWxlY3RlZFxuICAgKi9cbiAgaXNTZWxlY3RlZChpdGVtOiBUKTogYm9vbGVhbiB7XG4gICAgaWYgKHRoaXMuX3NlbGVjdGlvblR5cGUgPT09IFNlbGVjdGlvblR5cGUuU2luZ2xlKSB7XG4gICAgICByZXR1cm4gdGhpcy5jdXJyZW50U2luZ2xlID09PSBpdGVtO1xuICAgIH0gZWxzZSBpZiAodGhpcy5fc2VsZWN0aW9uVHlwZSA9PT0gU2VsZWN0aW9uVHlwZS5NdWx0aSkge1xuICAgICAgcmV0dXJuIHRoaXMuY3VycmVudC5pbmRleE9mKGl0ZW0pID49IDA7XG4gICAgfVxuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTZWxlY3RzIG9yIGRlc2VsZWN0cyBhbiBpdGVtXG4gICAqL1xuICBzZXRTZWxlY3RlZChpdGVtOiBULCBzZWxlY3RlZDogYm9vbGVhbikge1xuICAgIGNvbnN0IGluZGV4ID0gdGhpcy5jdXJyZW50ID8gdGhpcy5jdXJyZW50LmluZGV4T2YoaXRlbSkgOiAtMTtcblxuICAgIHN3aXRjaCAodGhpcy5fc2VsZWN0aW9uVHlwZSkge1xuICAgICAgY2FzZSBTZWxlY3Rpb25UeXBlLk5vbmU6XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSBTZWxlY3Rpb25UeXBlLlNpbmdsZTpcbiAgICAgICAgLy8gaW4gc2luZ2xlIHNlbGVjdGlvbiwgc2V0IGN1cnJlbnRTaW5nbGUgbWV0aG9kIHNob3VsZCBiZSB1c2VkXG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSBTZWxlY3Rpb25UeXBlLk11bHRpOlxuICAgICAgICBpZiAoaW5kZXggPj0gMCAmJiAhc2VsZWN0ZWQpIHtcbiAgICAgICAgICB0aGlzLmRlc2VsZWN0SXRlbShpbmRleCk7XG4gICAgICAgIH0gZWxzZSBpZiAoaW5kZXggPCAwICYmIHNlbGVjdGVkKSB7XG4gICAgICAgICAgdGhpcy5zZWxlY3RJdGVtKGl0ZW0pO1xuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgYnJlYWs7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIENoZWNrcyBpZiBhbGwgY3VycmVudGx5IGRpc3BsYXllZCBpdGVtcyBhcmUgc2VsZWN0ZWRcbiAgICovXG4gIGlzQWxsU2VsZWN0ZWQoKTogYm9vbGVhbiB7XG4gICAgaWYgKHRoaXMuX3NlbGVjdGlvblR5cGUgIT09IFNlbGVjdGlvblR5cGUuTXVsdGkgfHwgIXRoaXMuX2l0ZW1zLmRpc3BsYXllZCkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICAvLyBtYWtlIHN1cmUgdG8gZXhjbHVkZSB0aGUgbG9ja2VkIGl0ZW1zIGZyb20gdGhlIGxpc3Qgd2hlbiBjb3VudGluZ1xuICAgIGNvbnN0IGRpc3BsYXllZEl0ZW1zOiBUW10gPSB0aGlzLl9pdGVtcy5kaXNwbGF5ZWQuZmlsdGVyKGl0ZW0gPT4ge1xuICAgICAgcmV0dXJuIHRoaXMuaXNMb2NrZWQoaXRlbSkgPT09IGZhbHNlO1xuICAgIH0pO1xuXG4gICAgY29uc3QgbmJEaXNwbGF5ZWQgPSBkaXNwbGF5ZWRJdGVtcy5sZW5ndGg7XG4gICAgaWYgKG5iRGlzcGxheWVkIDwgMSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICBjb25zdCB0ZW1wOiBUW10gPSBkaXNwbGF5ZWRJdGVtcy5maWx0ZXIoaXRlbSA9PiB0aGlzLmN1cnJlbnQuaW5kZXhPZihpdGVtKSA+IC0xKTtcbiAgICByZXR1cm4gdGVtcC5sZW5ndGggPT09IGRpc3BsYXllZEl0ZW1zLmxlbmd0aDtcbiAgfVxuXG4gIC8qKlxuICAgKiBMb2NrIGFuZCB1bmxvY2sgaXRlbVxuICAgKi9cbiAgbG9ja0l0ZW0oaXRlbTogVCwgbG9jazogYm9vbGVhbikge1xuICAgIGlmICh0aGlzLmNhbkl0QmVMb2NrZWQoKSkge1xuICAgICAgY29uc3QgcmVmID0gdGhpcy5faXRlbXMudHJhY2tCeShpdGVtKTtcbiAgICAgIGlmIChsb2NrID09PSB0cnVlKSB7XG4gICAgICAgIC8vIEFkZCB0byBsb2NrZWRSZWZcbiAgICAgICAgdGhpcy5sb2NrZWRSZWZzLnB1c2gocmVmKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIFJlbW92ZSBmcm9tIGxvY2tlZFJlZlxuICAgICAgICB0aGlzLmxvY2tlZFJlZnMgPSB0aGlzLmxvY2tlZFJlZnMuZmlsdGVyKGxvY2tlZEl0ZW0gPT4gcmVmICE9PSBsb2NrZWRJdGVtKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQ2hlY2sgaXMgaXRlbSBsb2NrZWQgb3Igbm90IGJ5IHNlYXJjaGluZyBpbnRvIGxvY2tlZFJlZnMgZm9yIGVudHJ5XG4gICAqL1xuICBpc0xvY2tlZChpdGVtOiBUKTogYm9vbGVhbiB7XG4gICAgLyoqXG4gICAgICogVGhlIGNoZWNrIGZvciBzZWxlY3Rpb25UeXBlIHdpbGwgYm9vc3QgdGhlIHBlcmZvcm1hbmNlIGJ5IE5PVCBzZWFyY2hpbmdcbiAgICAgKiBpbnRvIHRoZSBhcnJheSB3aGVuIHRoZXJlIGlzIG5vIG5lZWQgZm9yIHRoYXQuXG4gICAgICovXG4gICAgaWYgKHRoaXMuY2FuSXRCZUxvY2tlZCgpKSB7XG4gICAgICBjb25zdCByZWYgPSB0aGlzLl9pdGVtcy50cmFja0J5KGl0ZW0pO1xuICAgICAgcmV0dXJuIHRoaXMubG9ja2VkUmVmcy5pbmRleE9mKHJlZikgPiAtMTtcbiAgICB9XG5cbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICAvKipcbiAgICogU2VsZWN0cyBvciBkZXNlbGVjdHMgYWxsIGN1cnJlbnRseSBkaXNwbGF5ZWQgaXRlbXNcbiAgICovXG4gIHRvZ2dsZUFsbCgpIHtcbiAgICBpZiAodGhpcy5fc2VsZWN0aW9uVHlwZSA9PT0gU2VsZWN0aW9uVHlwZS5Ob25lIHx8IHRoaXMuX3NlbGVjdGlvblR5cGUgPT09IFNlbGVjdGlvblR5cGUuU2luZ2xlKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIC8qKlxuICAgICAqIElmIGV2ZXJ5IGN1cnJlbnRseSBkaXNwbGF5ZWQgaXRlbSBpcyBhbHJlYWR5IHNlbGVjdGVkLCB3ZSBjbGVhciB0aGVtLlxuICAgICAqIElmIGF0IGxlYXN0IG9uZSBpdGVtIGlzbid0IHNlbGVjdGVkLCB3ZSBzZWxlY3QgZXZlcnkgY3VycmVudGx5IGRpc3BsYXllZCBpdGVtLlxuICAgICAqL1xuICAgIGlmICh0aGlzLmlzQWxsU2VsZWN0ZWQoKSkge1xuICAgICAgdGhpcy5faXRlbXMuZGlzcGxheWVkLmZvckVhY2goaXRlbSA9PiB7XG4gICAgICAgIGNvbnN0IGN1cnJlbnRJbmRleCA9IHRoaXMuY3VycmVudC5pbmRleE9mKGl0ZW0pO1xuICAgICAgICBpZiAoY3VycmVudEluZGV4ID4gLTEgJiYgdGhpcy5pc0xvY2tlZChpdGVtKSA9PT0gZmFsc2UpIHtcbiAgICAgICAgICB0aGlzLmRlc2VsZWN0SXRlbShjdXJyZW50SW5kZXgpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5faXRlbXMuZGlzcGxheWVkLmZvckVhY2goaXRlbSA9PiB7XG4gICAgICAgIGlmICh0aGlzLmN1cnJlbnQuaW5kZXhPZihpdGVtKSA8IDAgJiYgdGhpcy5pc0xvY2tlZChpdGVtKSA9PT0gZmFsc2UpIHtcbiAgICAgICAgICB0aGlzLnNlbGVjdEl0ZW0oaXRlbSk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBTZWxlY3RzIGFuIGl0ZW1cbiAgICovXG4gIHByaXZhdGUgc2VsZWN0SXRlbShpdGVtOiBUKTogdm9pZCB7XG4gICAgdGhpcy5jdXJyZW50ID0gdGhpcy5jdXJyZW50LmNvbmNhdChpdGVtKTtcbiAgICBpZiAodGhpcy5faXRlbXMuY2FuVHJhY2tCeSgpKSB7XG4gICAgICAvLyBQdXNoIHNlbGVjdGVkIHJlZiBvbnRvIGFycmF5XG4gICAgICB0aGlzLnByZXZTZWxlY3Rpb25SZWZzLnB1c2godGhpcy5faXRlbXMudHJhY2tCeShpdGVtKSk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIERlc2VsZWN0cyBhbiBpdGVtXG4gICAqL1xuICBwcml2YXRlIGRlc2VsZWN0SXRlbShpbmRleE9mSXRlbTogbnVtYmVyKTogdm9pZCB7XG4gICAgdGhpcy5jdXJyZW50ID0gdGhpcy5jdXJyZW50LnNsaWNlKDAsIGluZGV4T2ZJdGVtKS5jb25jYXQodGhpcy5jdXJyZW50LnNsaWNlKGluZGV4T2ZJdGVtICsgMSkpO1xuICAgIGlmIChpbmRleE9mSXRlbSA8IHRoaXMucHJldlNlbGVjdGlvblJlZnMubGVuZ3RoKSB7XG4gICAgICAvLyBLZWVwIHNlbGVjdGVkIHJlZnMgYXJyYXkgaW4gc3luY1xuICAgICAgY29uc3QgcmVtb3ZlZEl0ZW1zID0gdGhpcy5wcmV2U2VsZWN0aW9uUmVmcy5zcGxpY2UoaW5kZXhPZkl0ZW0sIDEpO1xuICAgICAgLy8gbG9ja2VkIHJlZmVyZW5jZSBpcyBubyBsb25nZXIgbmVlZGVkIChpZiBhbnkpXG4gICAgICB0aGlzLmxvY2tlZFJlZnMgPSB0aGlzLmxvY2tlZFJlZnMuZmlsdGVyKGxvY2tlZCA9PiBsb2NrZWQgIT09IHJlbW92ZWRJdGVtc1swXSk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIE1ha2Ugc3VyZSB0aGF0IGl0IGNvdWxkIGJlIGxvY2tlZFxuICAgKi9cbiAgcHJpdmF0ZSBjYW5JdEJlTG9ja2VkKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLl9zZWxlY3Rpb25UeXBlICE9PSBTZWxlY3Rpb25UeXBlLk5vbmUgJiYgdGhpcy5faXRlbXMuY2FuVHJhY2tCeSgpO1xuICB9XG5cbiAgcHJpdmF0ZSBlbWl0Q2hhbmdlKCkge1xuICAgIGlmICh0aGlzLl9zZWxlY3Rpb25UeXBlID09PSBTZWxlY3Rpb25UeXBlLlNpbmdsZSkge1xuICAgICAgdGhpcy5fY2hhbmdlLm5leHQodGhpcy5jdXJyZW50U2luZ2xlKTtcbiAgICB9IGVsc2UgaWYgKHRoaXMuX3NlbGVjdGlvblR5cGUgPT09IFNlbGVjdGlvblR5cGUuTXVsdGkpIHtcbiAgICAgIHRoaXMuX2NoYW5nZS5uZXh0KHRoaXMuY3VycmVudCk7XG4gICAgfVxuICB9XG59XG4iXX0=