UNPKG

@ui-tool/core

Version:
278 lines 42.1 kB
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, ComponentFactoryResolver, Input, ViewChild, ViewContainerRef } from '@angular/core'; import { BANNER_BUILDER, BANNER_SERVICE, WINDOW } from '../../constants/injectors/injectors'; import { of, Subscription, throwError } from 'rxjs'; import { NavigationCancel, NavigationEnd, NavigationError, NavigationStart, Router, RouterEvent } from '@angular/router'; import { filter, map, mergeMap, retryWhen, switchMap, tap } from 'rxjs/operators'; import { findLastIndex } from 'lodash-es'; import * as i0 from "@angular/core"; export class BannerComponent { //#endregion //#region Constructor constructor(injector) { this.injector = injector; this.id = ''; this.queryMode = 'pop'; this.preserveMode = 'navigate-start-clear'; this.container = null; this._destroyBannerTimer = null; this._displayingRequest = null; this._displayRequests = []; // Service reflection. this.bannerService = this.injector.get(BANNER_SERVICE); this.componentFactoryResolver = this.injector.get(ComponentFactoryResolver); this.router = this.injector.get(Router); this.windowService = this.injector.get(WINDOW); this.bannerBuilders = this.injector.get(BANNER_BUILDER); this.changeDetectorRef = this.injector.get(ChangeDetectorRef); this._subscription = new Subscription(); } //#endregion //#region Methods ngAfterViewInit() { const id = this.id; // Subscription about banner display requested. const displayBannerSubscription = this.bannerService .addedRequestEvent .subscribe(request => { // Container is invalid. if (!this.container) { return; } // Add the request into list. this._displayRequests.push(request); // No banner has been displayed before. if (!this._displayingRequest) { this.bannerService.displayNextBanner(id); } }); this._subscription.add(displayBannerSubscription); // Subscription which raises when next banner display is requested. const nextBannerDisplayRequestSubscription = this.bannerService .nextBannerDisplayRequested .pipe(switchMap(request => { // Invalid container. if (request.containerId && request.containerId !== id) { return of(void (0)); } if (!request.containerId) { return of(void (0)); } // Get the next settings. const nextRequest = this.queryMode === 'pop' ? this.popRequest(request.containerId) : this.dequeueRequest(request.containerId); if (!nextRequest) { // Clear the host view. if (this.container) { this.container.clear(); this._displayingRequest = null; } return of(void (0)); } return this.displayBannerAsync(nextRequest) .pipe(map(_ => void (0))); })) .subscribe(() => { this.changeDetectorRef.markForCheck(); }); this._subscription.add(nextBannerDisplayRequestSubscription); // Listen to navigation event. const navigationEventSubscription = this.router .events .pipe(filter(e => e instanceof RouterEvent), filter(e => (e instanceof NavigationCancel) || (e instanceof NavigationEnd) || (e instanceof NavigationError))) .subscribe(e => { if (!this.container) { return; } if (((e instanceof NavigationCancel) || (e instanceof NavigationEnd) || (e instanceof NavigationError)) && this.preserveMode === 'navigate-end-clear') { this.container.clear(); this.changeDetectorRef.markForCheck(); } if ((e instanceof NavigationStart) && this.preserveMode === 'navigate-start-clear') { this.container.clear(); this.changeDetectorRef.markForCheck(); } }); this._subscription.add(navigationEventSubscription); // Hook delete display banner request. this.hookDeleteRequestEvent(); } // Called when component is destroyed. ngOnDestroy() { this._subscription?.unsubscribe(); // Clear the previous timeout. if (this._destroyBannerTimer) { this.windowService.clearTimeout(this._destroyBannerTimer); } } //#endregion //#region Internal methods hookDeleteRequestEvent() { const deleteRequestSubscription = this.bannerService .deleteRequestEvent .subscribe(deleteRequest => { // Container is invalid. if (!this.container) { return; } let index = 0; while (index < this._displayRequests.length) { // Container is invalid. if (deleteRequest.containerId && deleteRequest.containerId !== this.id) { index++; continue; } // Request id is invalid. if (deleteRequest.id && deleteRequest.id !== this._displayingRequest?.id) { index++; continue; } this._displayRequests.splice(index, 1); } if (!this.ableToDeleteDisplayingRequest(deleteRequest)) { return; } this.container.clear(); this._displayingRequest = null; this.changeDetectorRef.markForCheck(); }); this._subscription.add(deleteRequestSubscription); } // Display banner by handling request. displayBannerAsync(bannerDisplayRequest) { // Invalid request. if (!bannerDisplayRequest) { return of(void (0)); } // Request does not belong to the current container. if (bannerDisplayRequest.containerId && this.id && bannerDisplayRequest.containerId !== this.id) { return of(void (0)); } const settings = bannerDisplayRequest.settings; if (!settings) { return of(void (0)); } // Clear the previous timeout. if (this._destroyBannerTimer) { this.windowService.clearTimeout(this._destroyBannerTimer); } let itemIndex = 0; const builders = this.bannerBuilders; const isNotAbleToBuildException = 'IS_NOT_ABLE_TO_BE_BUILT'; const noBuilderAvailableException = 'NO_BUILDER_AVAILABLE'; const maxRetriesExceeded = 'MAX_RETRIES_EXCEEDED'; return of(void (0)) .pipe(tap(_ => { if (!builders) { throw noBuilderAvailableException; } if (itemIndex > builders.length - 1) { throw maxRetriesExceeded; } }), mergeMap(_ => builders[itemIndex].canBuildAsync(bannerDisplayRequest.settings)), mergeMap(ableToBuild => { if (!ableToBuild) { return throwError(isNotAbleToBuildException); } return builders[itemIndex].buildAsync(bannerDisplayRequest.settings) .pipe(tap((componentRef) => { if (!this.container) { return; } // Update the request. this._displayingRequest = bannerDisplayRequest; const hookDisposeRequest = componentRef.instance .disposeRequestingEvent .subscribe((_) => { this.bannerService.displayNextBanner(this.id); }); componentRef.onDestroy(() => { if (hookDisposeRequest && !hookDisposeRequest.closed) { hookDisposeRequest.unsubscribe(); } // Mark no request to be displayed. this._displayingRequest = null; }); // Detect changes. componentRef.changeDetectorRef.detectChanges(); this.container.clear(); this.container.insert(componentRef.hostView); if (settings.timeout && settings.timeout.duration && settings.timeout.action) { this._destroyBannerTimer = this.windowService .setTimeout(() => { // Do action on timeout. if (settings && settings.timeout) { settings.timeout.action(); } }, settings.timeout.duration); } }), map(_ => void (0))); }), retryWhen(exceptionObservable => { return exceptionObservable .pipe(tap(exception => { if (exception !== isNotAbleToBuildException) { throw exception; } itemIndex++; })); })); //#endregion } // Whether displaying request is removable or not. ableToDeleteDisplayingRequest(deleteRequest) { if (deleteRequest.containerId && deleteRequest.containerId !== this.id) { return false; } if (deleteRequest.id && deleteRequest.id !== this._displayingRequest?.id) { return false; } return true; } // Dequeue request. dequeueRequest(containerId) { if (!this._displayRequests || !this._displayRequests.length) { return null; } // Get first match item in the messages list. const itemIndex = this._displayRequests.findIndex(x => x.containerId === containerId); if (itemIndex < 0) { return null; } const item = this._displayRequests[itemIndex]; this._displayRequests.splice(itemIndex, 1); return item; } // Pop request. popRequest(containerId) { if (!this._displayRequests || !this._displayRequests.length) { return null; } // Find the last index of item. const lastIndex = findLastIndex(this._displayRequests, x => x.containerId === containerId); if (lastIndex < 0) { return null; } const item = this._displayRequests[lastIndex]; this._displayRequests.splice(lastIndex, 1); return item; } } BannerComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: BannerComponent, deps: [{ token: i0.Injector }], target: i0.ɵɵFactoryTarget.Component }); BannerComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.11", type: BannerComponent, selector: "cms-banner", inputs: { id: "id", queryMode: ["query-mode", "queryMode"], preserveMode: ["preserve-mode", "preserveMode"] }, viewQueries: [{ propertyName: "container", first: true, predicate: ["container"], descendants: true, read: ViewContainerRef }], ngImport: i0, template: "<ng-template #container></ng-template>\n", changeDetection: i0.ChangeDetectionStrategy.OnPush }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: BannerComponent, decorators: [{ type: Component, args: [{ selector: 'cms-banner', changeDetection: ChangeDetectionStrategy.OnPush, template: "<ng-template #container></ng-template>\n" }] }], ctorParameters: function () { return [{ type: i0.Injector }]; }, propDecorators: { id: [{ type: Input }], queryMode: [{ type: Input, args: ['query-mode'] }], preserveMode: [{ type: Input, args: ['preserve-mode'] }], container: [{ type: ViewChild, args: ['container', { read: ViewContainerRef }] }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmFubmVyLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uL2xpYnMvY29yZS9zcmMvbW9kdWxlcy9iYW5uZXIvYmFubmVyLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uLy4uLy4uL2xpYnMvY29yZS9zcmMvbW9kdWxlcy9iYW5uZXIvYmFubmVyLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFFTCx1QkFBdUIsRUFDdkIsaUJBQWlCLEVBQ2pCLFNBQVMsRUFDVCx3QkFBd0IsRUFHeEIsS0FBSyxFQUVMLFNBQVMsRUFDVCxnQkFBZ0IsRUFDakIsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUFDLGNBQWMsRUFBRSxjQUFjLEVBQUUsTUFBTSxFQUFDLE1BQU0scUNBQXFDLENBQUM7QUFDM0YsT0FBTyxFQUFhLEVBQUUsRUFBRSxZQUFZLEVBQUUsVUFBVSxFQUFDLE1BQU0sTUFBTSxDQUFDO0FBQzlELE9BQU8sRUFBQyxnQkFBZ0IsRUFBRSxhQUFhLEVBQUUsZUFBZSxFQUFFLGVBQWUsRUFBRSxNQUFNLEVBQUUsV0FBVyxFQUFDLE1BQU0saUJBQWlCLENBQUM7QUFDdkgsT0FBTyxFQUFDLE1BQU0sRUFBRSxHQUFHLEVBQUUsUUFBUSxFQUFFLFNBQVMsRUFBRSxTQUFTLEVBQUUsR0FBRyxFQUFDLE1BQU0sZ0JBQWdCLENBQUM7QUFFaEYsT0FBTyxFQUFDLGFBQWEsRUFBQyxNQUFNLFdBQVcsQ0FBQzs7QUFheEMsTUFBTSxPQUFPLGVBQWU7SUEyRDFCLFlBQVk7SUFFWixxQkFBcUI7SUFFckIsWUFBNkIsUUFBa0I7UUFBbEIsYUFBUSxHQUFSLFFBQVEsQ0FBVTtRQUM3QyxJQUFJLENBQUMsRUFBRSxHQUFHLEVBQUUsQ0FBQztRQUNiLElBQUksQ0FBQyxTQUFTLEdBQUcsS0FBSyxDQUFDO1FBQ3ZCLElBQUksQ0FBQyxZQUFZLEdBQUcsc0JBQXNCLENB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LElBQUksRUFBRSxnQkFBZ0IsRUFBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gIEFmdGVyVmlld0luaXQsXG4gIENoYW5nZURldGVjdGlvblN0cmF0ZWd5LFxuICBDaGFuZ2VEZXRlY3RvclJlZixcbiAgQ29tcG9uZW50LFxuICBDb21wb25lbnRGYWN0b3J5UmVzb2x2ZXIsXG4gIENvbXBvbmVudFJlZixcbiAgSW5qZWN0b3IsXG4gIElucHV0LFxuICBPbkRlc3Ryb3ksXG4gIFZpZXdDaGlsZCxcbiAgVmlld0NvbnRhaW5lclJlZlxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7QkFOTkVSX0JVSUxERVIsIEJBTk5FUl9TRVJWSUNFLCBXSU5ET1d9IGZyb20gJy4uLy4uL2NvbnN0YW50cy9pbmplY3RvcnMvaW5qZWN0b3JzJztcbmltcG9ydCB7T2JzZXJ2YWJsZSwgb2YsIFN1YnNjcmlwdGlvbiwgdGhyb3dFcnJvcn0gZnJvbSAncnhqcyc7XG5pbXBvcnQge05hdmlnYXRpb25DYW5jZWwsIE5hdmlnYXRpb25FbmQsIE5hdmlnYXRpb25FcnJvciwgTmF2aWdhdGlvblN0YXJ0LCBSb3V0ZXIsIFJvdXRlckV2ZW50fSBmcm9tICdAYW5ndWxhci9yb3V0ZXInO1xuaW1wb3J0IHtmaWx0ZXIsIG1hcCwgbWVyZ2VNYXAsIHJldHJ5V2hlbiwgc3dpdGNoTWFwLCB0YXB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcbmltcG9ydCB7QkFOTkVSX1BSRVNFUlZFX01PREUsIEJBTk5FUl9RVUVSWV9NT0RFfSBmcm9tICcuLi8uLi9jb25zdGFudHMvZGF0YS10eXBlLmNvbnN0YW50JztcbmltcG9ydCB7ZmluZExhc3RJbmRleH0gZnJvbSAnbG9kYXNoLWVzJztcbmltcG9ydCB7SUJhbm5lckNvbnRlbnRCdWlsZGVyfSBmcm9tICcuLi8uLi9zZXJ2aWNlcy9pbnRlcmZhY2VzL2Jhbm5lcnMvYmFubmVyLWNvbnRlbnQtYnVpbGRlci5pbnRlcmZhY2UnO1xuaW1wb3J0IHtCYW5uZXJTZXJ2aWNlfSBmcm9tICcuLi8uLi9zZXJ2aWNlcy9pbXBsZW1lbnRhdGlvbnMvYmFubmVycy9iYW5uZXIuc2VydmljZSc7XG5pbXBvcnQge0lEaXNwbGF5QmFubmVyUmVxdWVzdH0gZnJvbSAnLi4vLi4vbW9kZWxzL2ludGVyZmFjZXMvYmFubmVycy9hZGQtYmFubmVyLWNvbnRlbnQtcmVxdWVzdC5pbnRlcmZhY2UnO1xuaW1wb3J0IHtJQmFubmVyQ29udGVudENvbXBvbmVudH0gZnJvbSAnLi4vLi4vbW9kZWxzL2ludGVyZmFjZXMvYmFubmVycy9iYW5uZXItY29udGVudC1jb21wb25lbnQuaW50ZXJmYWNlJztcbmltcG9ydCB7SURlbGV0ZUJhbm5lclJlcXVlc3R9IGZyb20gJy4uLy4uL21vZGVscy9pbnRlcmZhY2VzL2Jhbm5lcnMvZGVsZXRlLWJhbm5lci1jb250ZW50LXJlcXVlc3QuaW50ZXJmYWNlJztcblxuQENvbXBvbmVudCh7XG4gIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTpjb21wb25lbnQtc2VsZWN0b3JcbiAgc2VsZWN0b3I6ICdjbXMtYmFubmVyJyxcbiAgdGVtcGxhdGVVcmw6ICdiYW5uZXIuY29tcG9uZW50Lmh0bWwnLFxuICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaFxufSlcbmV4cG9ydCBjbGFzcyBCYW5uZXJDb21wb25lbnQgaW1wbGVtZW50cyBBZnRlclZpZXdJbml0LCBPbkRlc3Ryb3kge1xuXG4gIC8vI3JlZ2lvbiBQcm9wZXJ0aWVzXG5cbiAgLy8gVW5pcXVlIGlkIG9mIGEgYmFubmVyIGNvbnRhaW5lci5cbiAgQElucHV0KClcbiAgcHVibGljIGlkOiBzdHJpbmc7XG5cbiAgLy8gSG93IGJhbm5lciBpcyBxdWVyaWVkIGZvciBiZWluZyBkaXNwbGF5ZWQuXG4gIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTpuby1pbnB1dC1yZW5hbWVcbiAgQElucHV0KCdxdWVyeS1tb2RlJylcbiAgcHVibGljIHF1ZXJ5TW9kZTogQkFOTkVSX1FVRVJZX01PREU7XG5cbiAgLy8gSG93IGJhbm5lciBwcmVzZXJ2ZSBtZXNzYWdlLlxuICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6bm8taW5wdXQtcmVuYW1lXG4gIEBJbnB1dCgncHJlc2VydmUtbW9kZScpXG4gIHB1YmxpYyBwcmVzZXJ2ZU1vZGU6IEJBTk5FUl9QUkVTRVJWRV9NT0RFO1xuXG4gIC8vIEdldCB0aGUgYmFubmVyIGNvbnRhaW5lciBhcmVhLlxuICBAVmlld0NoaWxkKCdjb250YWluZXInLCB7cmVhZDogVmlld0NvbnRhaW5lclJlZn0pXG4gIHB1YmxpYyBjb250YWluZXI6IFZpZXdDb250YWluZXJSZWYgfCBudWxsO1xuXG4gIC8vIFJlcXVlc3Qgd2hpY2ggaXMgY3VycmVudGx5IGFwcGxpZWQgdG8gdGhlIGJhbm5lciBjb250YWluZXIuXG4gIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTp2YXJpYWJsZS1uYW1lXG4gIHByaXZhdGUgX2Rpc3BsYXlpbmdSZXF1ZXN0OiBJRGlzcGxheUJhbm5lclJlcXVlc3QgfCBudWxsO1xuXG4gIC8vIEJhY2tncm91bmQgdGFzayB3aGljaCBpcyBmb3IgZGVzdHJveWluZyBjdXJyZW50bHkgZGlzcGxheWVkIGJhbm5lci5cbiAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOnZhcmlhYmxlLW5hbWVcbiAgcHJpdmF0ZSBfZGVzdHJveUJhbm5lclRpbWVyOiBudW1iZXIgfCBudWxsO1xuXG4gIC8vIExpc3Qgb2YgcmVxdWVzdCBhYm91dCBiYW5uZXIgZGlzcGxheS5cbiAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOnZhcmlhYmxlLW5hbWVcbiAgcHJpdmF0ZSByZWFkb25seSBfZGlzcGxheVJlcXVlc3RzOiBJRGlzcGxheUJhbm5lclJlcXVlc3RbXTtcblxuICAvLyBTdWJzY3JpcHRpb24gd2F0Y2ggbGlzdC5cbiAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOnZhcmlhYmxlLW5hbWVcbiAgcHJpdmF0ZSByZWFkb25seSBfc3Vic2NyaXB0aW9uOiBTdWJzY3JpcHRpb247XG5cbiAgLy8jZW5kcmVnaW9uXG5cbiAgLy8jcmVnaW9uIFNlcnZpY2VzXG5cbiAgLy8gU2VydmljZSBmb3IgaGFuZGxpbmcgYmFubmVyIGJ1c2luZXNzLlxuICBwcm90ZWN0ZWQgcmVhZG9ubHkgYmFubmVyU2VydmljZTogQmFubmVyU2VydmljZTtcblxuICAvLyBDb21wb25lbnQgZmFjdG9yeSByZXNvbHZlci5cbiAgcHJvdGVjdGVkIHJlYWRvbmx5IGNvbXBvbmVudEZhY3RvcnlSZXNvbHZlcjogQ29tcG9uZW50RmFjdG9yeVJlc29sdmVyO1xuXG4gIC8vIFJvdXRlciBzZXJ2aWNlLlxuICBwcm90ZWN0ZWQgcmVhZG9ubHkgcm91dGVyOiBSb3V0ZXI7XG5cbiAgLy8gV2luZG93IHNlcnZpY2UuXG4gIHByb3RlY3RlZCByZWFkb25seSB3aW5kb3dTZXJ2aWNlOiBXaW5kb3c7XG5cbiAgLy8gQmFubmVyIGJ1aWxkZXIuXG4gIHByb3RlY3RlZCByZWFkb25seSBiYW5uZXJCdWlsZGVyczogSUJhbm5lckNvbnRlbnRCdWlsZGVyW107XG5cbiAgcHJvdGVjdGVkIHJlYWRvbmx5IGNoYW5nZURldGVjdG9yUmVmOiBDaGFuZ2VEZXRlY3RvclJlZjtcblxuICAvLyNlbmRyZWdpb25cblxuICAvLyNyZWdpb24gQ29uc3RydWN0b3JcblxuICBwdWJsaWMgY29uc3RydWN0b3IocHJvdGVjdGVkIGluamVjdG9yOiBJbmplY3Rvcikge1xuICAgIHRoaXMuaWQgPSAnJztcbiAgICB0aGlzLnF1ZXJ5TW9kZSA9ICdwb3AnO1xuICAgIHRoaXMucHJlc2VydmVNb2RlID0gJ25hdmlnYXRlLXN0YXJ0LWNsZWFyJztcbiAgICB0aGlzLmNvbnRhaW5lciA9IG51bGw7XG4gICAgdGhpcy5fZGVzdHJveUJhbm5lclRpbWVyID0gbnVsbDtcbiAgICB0aGlzLl9kaXNwbGF5aW5nUmVxdWVzdCA9IG51bGw7XG4gICAgdGhpcy5fZGlzcGxheVJlcXVlc3RzID0gW107XG5cbiAgICAvLyBTZXJ2aWNlIHJlZmxlY3Rpb24uXG4gICAgdGhpcy5iYW5uZXJTZXJ2aWNlID0gdGhpcy5pbmplY3Rvci5nZXQoQkFOTkVSX1NFUlZJQ0UpIGFzIGFueSBhcyBCYW5uZXJTZXJ2aWNlO1xuICAgIHRoaXMuY29tcG9uZW50RmFjdG9yeVJlc29sdmVyID0gdGhpcy5pbmplY3Rvci5nZXQoQ29tcG9uZW50RmFjdG9yeVJlc29sdmVyKTtcbiAgICB0aGlzLnJvdXRlciA9IHRoaXMuaW5qZWN0b3IuZ2V0KFJvdXRlcik7XG4gICAgdGhpcy53aW5kb3dTZXJ2aWNlID0gdGhpcy5pbmplY3Rvci5nZXQoV0lORE9XKSBhcyBXaW5kb3c7XG4gICAgdGhpcy5iYW5uZXJCdWlsZGVycyA9IHRoaXMuaW5qZWN0b3IuZ2V0KEJBTk5FUl9CVUlMREVSKSBhcyBhbnkgYXMgSUJhbm5lckNvbnRlbnRCdWlsZGVyW107XG4gICAgdGhpcy5jaGFuZ2VEZXRlY3RvclJlZiA9IHRoaXMuaW5qZWN0b3IuZ2V0KENoYW5nZURldGVjdG9yUmVmKTtcbiAgICB0aGlzLl9zdWJzY3JpcHRpb24gPSBuZXcgU3Vic2NyaXB0aW9uKCk7XG4gIH1cblxuICAvLyNlbmRyZWdpb25cblxuICAvLyNyZWdpb24gTWV0aG9kc1xuXG4gIHB1YmxpYyBuZ0FmdGVyVmlld0luaXQoKTogdm9pZCB7XG5cbiAgICBjb25zdCBpZCA9IHRoaXMuaWQ7XG5cbiAgICAvLyBTdWJzY3JpcHRpb24gYWJvdXQgYmFubmVyIGRpc3BsYXkgcmVxdWVzdGVkLlxuICAgIGNvbnN0IGRpc3BsYXlCYW5uZXJTdWJzY3JpcHRpb24gPSB0aGlzLmJhbm5lclNlcnZpY2VcbiAgICAgIC5hZGRlZFJlcXVlc3RFdmVudFxuICAgICAgLnN1YnNjcmliZShyZXF1ZXN0ID0+IHtcblxuICAgICAgICAvLyBDb250YWluZXIgaXMgaW52YWxpZC5cbiAgICAgICAgaWYgKCF0aGlzLmNvbnRhaW5lcikge1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIEFkZCB0aGUgcmVxdWVzdCBpbnRvIGxpc3QuXG4gICAgICAgIHRoaXMuX2Rpc3BsYXlSZXF1ZXN0cy5wdXNoKHJlcXVlc3QpO1xuXG4gICAgICAgIC8vIE5vIGJhbm5lciBoYXMgYmVlbiBkaXNwbGF5ZWQgYmVmb3JlLlxuICAgICAgICBpZiAoIXRoaXMuX2Rpc3BsYXlpbmdSZXF1ZXN0KSB7XG4gICAgICAgICAgdGhpcy5iYW5uZXJTZXJ2aWNlLmRpc3BsYXlOZXh0QmFubmVyKGlkKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgdGhpcy5fc3Vic2NyaXB0aW9uLmFkZChkaXNwbGF5QmFubmVyU3Vic2NyaXB0aW9uKTtcblxuICAgIC8vIFN1YnNjcmlwdGlvbiB3aGljaCByYWlzZXMgd2hlbiBuZXh0IGJhbm5lciBkaXNwbGF5IGlzIHJlcXVlc3RlZC5cbiAgICBjb25zdCBuZXh0QmFubmVyRGlzcGxheVJlcXVlc3RTdWJzY3JpcHRpb24gPSB0aGlzLmJhbm5lclNlcnZpY2VcbiAgICAgIC5uZXh0QmFubmVyRGlzcGxheVJlcXVlc3RlZFxuICAgICAgLnBpcGUoXG4gICAgICAgIHN3aXRjaE1hcChyZXF1ZXN0ID0+IHtcblxuICAgICAgICAgIC8vIEludmFsaWQgY29udGFpbmVyLlxuICAgICAgICAgIGlmIChyZXF1ZXN0LmNvbnRhaW5lcklkICYmIHJlcXVlc3QuY29udGFpbmVySWQgIT09IGlkKSB7XG4gICAgICAgICAgICByZXR1cm4gb2Yodm9pZCAoMCkpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGlmICghcmVxdWVzdC5jb250YWluZXJJZCkge1xuICAgICAgICAgICAgcmV0dXJuIG9mKHZvaWQgKDApKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICAvLyBHZXQgdGhlIG5leHQgc2V0dGluZ3MuXG4gICAgICAgICAgY29uc3QgbmV4dFJlcXVlc3QgPSB0aGlzLnF1ZXJ5TW9kZSA9PT0gJ3BvcCcgPyB0aGlzLnBvcFJlcXVlc3QocmVxdWVzdC5jb250YWluZXJJZClcbiAgICAgICAgICAgIDogdGhpcy5kZXF1ZXVlUmVxdWVzdChyZXF1ZXN0LmNvbnRhaW5lcklkKTtcblxuICAgICAgICAgIGlmICghbmV4dFJlcXVlc3QpIHtcbiAgICAgICAgICAgIC8vIENsZWFyIHRoZSBob3N0IHZpZXcuXG4gICAgICAgICAgICBpZiAodGhpcy5jb250YWluZXIpIHtcbiAgICAgICAgICAgICAgdGhpcy5jb250YWluZXIuY2xlYXIoKTtcbiAgICAgICAgICAgICAgdGhpcy5fZGlzcGxheWluZ1JlcXVlc3QgPSBudWxsO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXR1cm4gb2Yodm9pZCAoMCkpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHJldHVybiB0aGlzLmRpc3BsYXlCYW5uZXJBc3luYyhuZXh0UmVxdWVzdClcbiAgICAgICAgICAgIC5waXBlKFxuICAgICAgICAgICAgICBtYXAoXyA9PiB2b2lkICgwKSlcbiAgICAgICAgICAgICk7XG4gICAgICAgIH0pXG4gICAgICApXG4gICAgICAuc3Vic2NyaWJlKCgpID0+IHtcbiAgICAgICAgdGhpcy5jaGFuZ2VEZXRlY3RvclJlZi5tYXJrRm9yQ2hlY2soKTtcbiAgICAgIH0pO1xuXG4gICAgdGhpcy5fc3Vic2NyaXB0aW9uLmFkZChuZXh0QmFubmVyRGlzcGxheVJlcXVlc3RTdWJzY3JpcHRpb24pO1xuXG4gICAgLy8gTGlzdGVuIHRvIG5hdmlnYXRpb24gZXZlbnQuXG4gICAgY29uc3QgbmF2aWdhdGlvbkV2ZW50U3Vic2NyaXB0aW9uID0gdGhpcy5yb3V0ZXJcbiAgICAgIC5ldmVudHNcbiAgICAgIC5waXBlKFxuICAgICAgICBmaWx0ZXIoZSA9PiBlIGluc3RhbmNlb2YgUm91dGVyRXZlbnQpLFxuICAgICAgICBmaWx0ZXIoZSA9PiAoZSBpbnN0YW5jZW9mIE5hdmlnYXRpb25DYW5jZWwpIHx8IChlIGluc3RhbmNlb2YgTmF2aWdhdGlvbkVuZCkgfHwgKGUgaW5zdGFuY2VvZiBOYXZpZ2F0aW9uRXJyb3IpKVxuICAgICAgKVxuICAgICAgLnN1YnNjcmliZShlID0+IHtcblxuICAgICAgICBpZiAoIXRoaXMuY29udGFpbmVyKSB7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCgoZSBpbnN0YW5jZW9mIE5hdmlnYXRpb25DYW5jZWwpIHx8IChlIGluc3RhbmNlb2YgTmF2aWdhdGlvbkVuZCkgfHwgKGUgaW5zdGFuY2VvZiBOYXZpZ2F0aW9uRXJyb3IpKVxuICAgICAgICAgICYmIHRoaXMucHJlc2VydmVNb2RlID09PSAnbmF2aWdhdGUtZW5kLWNsZWFyJykge1xuICAgICAgICAgIHRoaXMuY29udGFpbmVyLmNsZWFyKCk7XG4gICAgICAgICAgdGhpcy5jaGFuZ2VEZXRlY3RvclJlZi5tYXJrRm9yQ2hlY2soKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICgoZSBpbnN0YW5jZW9mIE5hdmlnYXRpb25TdGFydClcbiAgICAgICAgICAmJiB0aGlzLnByZXNlcnZlTW9kZSA9PT0gJ25hdmlnYXRlLXN0YXJ0LWNsZWFyJykge1xuICAgICAgICAgIHRoaXMuY29udGFpbmVyLmNsZWFyKCk7XG4gICAgICAgICAgdGhpcy5jaGFuZ2VEZXRlY3RvclJlZi5tYXJrRm9yQ2hlY2soKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgdGhpcy5fc3Vic2NyaXB0aW9uLmFkZChuYXZpZ2F0aW9uRXZlbnRTdWJzY3JpcHRpb24pO1xuXG4gICAgLy8gSG9vayBkZWxldGUgZGlzcGxheSBiYW5uZXIgcmVxdWVzdC5cbiAgICB0aGlzLmhvb2tEZWxldGVSZXF1ZXN0RXZlbnQoKTtcbiAgfVxuXG4gIC8vIENhbGxlZCB3aGVuIGNvbXBvbmVudCBpcyBkZXN0cm95ZWQuXG4gIHB1YmxpYyBuZ09uRGVzdHJveSgpOiB2b2lkIHtcbiAgICB0aGlzLl9zdWJzY3JpcHRpb24/LnVuc3Vic2NyaWJlKCk7XG5cbiAgICAvLyBDbGVhciB0aGUgcHJldmlvdXMgdGltZW91dC5cbiAgICBpZiAodGhpcy5fZGVzdHJveUJhbm5lclRpbWVyKSB7XG4gICAgICB0aGlzLndpbmRvd1NlcnZpY2UuY2xlYXJUaW1lb3V0KHRoaXMuX2Rlc3Ryb3lCYW5uZXJUaW1lcik7XG4gICAgfVxuICB9XG5cbiAgLy8jZW5kcmVnaW9uXG5cbiAgLy8jcmVnaW9uIEludGVybmFsIG1ldGhvZHNcblxuICBwcm90ZWN0ZWQgaG9va0RlbGV0ZVJlcXVlc3RFdmVudCgpOiB2b2lkIHtcbiAgICBjb25zdCBkZWxldGVSZXF1ZXN0U3Vic2NyaXB0aW9uID0gdGhpcy5iYW5uZXJTZXJ2aWNlXG4gICAgICAuZGVsZXRlUmVxdWVzdEV2ZW50XG4gICAgICAuc3Vic2NyaWJlKGRlbGV0ZVJlcXVlc3QgPT4ge1xuXG4gICAgICAgIC8vIENvbnRhaW5lciBpcyBpbnZhbGlkLlxuICAgICAgICBpZiAoIXRoaXMuY29udGFpbmVyKSB7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgbGV0IGluZGV4ID0gMDtcblxuICAgICAgICB3aGlsZSAoaW5kZXggPCB0aGlzLl9kaXNwbGF5UmVxdWVzdHMubGVuZ3RoKSB7XG5cbiAgICAgICAgICAvLyBDb250YWluZXIgaXMgaW52YWxpZC5cbiAgICAgICAgICBpZiAoZGVsZXRlUmVxdWVzdC5jb250YWluZXJJZCAmJiBkZWxldGVSZXF1ZXN0LmNvbnRhaW5lcklkICE9PSB0aGlzLmlkKSB7XG4gICAgICAgICAgICBpbmRleCsrO1xuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgLy8gUmVxdWVzdCBpZCBpcyBpbnZhbGlkLlxuICAgICAgICAgIGlmIChkZWxldGVSZXF1ZXN0LmlkICYmIGRlbGV0ZVJlcXVlc3QuaWQgIT09IHRoaXMuX2Rpc3BsYXlpbmdSZXF1ZXN0Py5pZCkge1xuICAgICAgICAgICAgaW5kZXgrKztcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHRoaXMuX2Rpc3BsYXlSZXF1ZXN0cy5zcGxpY2UoaW5kZXgsIDEpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCF0aGlzLmFibGVUb0RlbGV0ZURpc3BsYXlpbmdSZXF1ZXN0KGRlbGV0ZVJlcXVlc3QpKSB7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5jb250YWluZXIuY2xlYXIoKTtcbiAgICAgICAgdGhpcy5fZGlzcGxheWluZ1JlcXVlc3QgPSBudWxsO1xuICAgICAgICB0aGlzLmNoYW5nZURldGVjdG9yUmVmLm1hcmtGb3JDaGVjaygpO1xuICAgICAgfSk7XG4gICAgdGhpcy5fc3Vic2NyaXB0aW9uLmFkZChkZWxldGVSZXF1ZXN0U3Vic2NyaXB0aW9uKTtcbiAgfVxuXG4gIC8vIERpc3BsYXkgYmFubmVyIGJ5IGhhbmRsaW5nIHJlcXVlc3QuXG4gIHByb3RlY3RlZCBkaXNwbGF5QmFubmVyQXN5bmMoYmFubmVyRGlzcGxheVJlcXVlc3Q6IElEaXNwbGF5QmFubmVyUmVxdWVzdCk6IE9ic2VydmFibGU8dm9pZD4ge1xuXG4gICAgLy8gSW52YWxpZCByZXF1ZXN0LlxuICAgIGlmICghYmFubmVyRGlzcGxheVJlcXVlc3QpIHtcbiAgICAgIHJldHVybiBvZih2b2lkICgwKSk7XG4gICAgfVxuXG4gICAgLy8gUmVxdWVzdCBkb2VzIG5vdCBiZWxvbmcgdG8gdGhlIGN1cnJlbnQgY29udGFpbmVyLlxuICAgIGlmIChiYW5uZXJEaXNwbGF5UmVxdWVzdC5jb250YWluZXJJZCAmJiB0aGlzLmlkXG4gICAgICAmJiBiYW5uZXJEaXNwbGF5UmVxdWVzdC5jb250YWluZXJJZCAhPT0gdGhpcy5pZCkge1xuICAgICAgcmV0dXJuIG9mKHZvaWQgKDApKTtcbiAgICB9XG5cbiAgICBjb25zdCBzZXR0aW5ncyA9IGJhbm5lckRpc3BsYXlSZXF1ZXN0LnNldHRpbmdzO1xuICAgIGlmICghc2V0dGluZ3MpIHtcbiAgICAgIHJldHVybiBvZih2b2lkICgwKSk7XG4gICAgfVxuXG4gICAgLy8gQ2xlYXIgdGhlIHByZXZpb3VzIHRpbWVvdXQuXG4gICAgaWYgKHRoaXMuX2Rlc3Ryb3lCYW5uZXJUaW1lcikge1xuICAgICAgdGhpcy53aW5kb3dTZXJ2aWNlLmNsZWFyVGltZW91dCh0aGlzLl9kZXN0cm95QmFubmVyVGltZXIpO1xuICAgIH1cblxuICAgIGxldCBpdGVtSW5kZXggPSAwO1xuICAgIGNvbnN0IGJ1aWxkZXJzID0gdGhpcy5iYW5uZXJCdWlsZGVycztcbiAgICBjb25zdCBpc05vdEFibGVUb0J1aWxkRXhjZXB0aW9uID0gJ0lTX05PVF9BQkxFX1RPX0JFX0JVSUxUJztcbiAgICBjb25zdCBub0J1aWxkZXJBdmFpbGFibGVFeGNlcHRpb24gPSAnTk9fQlVJTERFUl9BVkFJTEFCTEUnO1xuICAgIGNvbnN0IG1heFJldHJpZXNFeGNlZWRlZCA9ICdNQVhfUkVUUklFU19FWENFRURFRCc7XG5cbiAgICByZXR1cm4gb2Yodm9pZCAoMCkpXG4gICAgICAucGlwZShcbiAgICAgICAgdGFwKF8gPT4ge1xuICAgICAgICAgIGlmICghYnVpbGRlcnMpIHtcbiAgICAgICAgICAgIHRocm93IG5vQnVpbGRlckF2YWlsYWJsZUV4Y2VwdGlvbjtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAoaXRlbUluZGV4ID4gYnVpbGRlcnMubGVuZ3RoIC0gMSkge1xuICAgICAgICAgICAgdGhyb3cgbWF4UmV0cmllc0V4Y2VlZGVkO1xuICAgICAgICAgIH1cbiAgICAgICAgfSksXG4gICAgICAgIG1lcmdlTWFwKF8gPT4gYnVpbGRlcnNbaXRlbUluZGV4XS5jYW5CdWlsZEFzeW5jKGJhbm5lckRpc3BsYXlSZXF1ZXN0LnNldHRpbmdzKSksXG4gICAgICAgIG1lcmdlTWFwKGFibGVUb0J1aWxkID0+IHtcbiAgICAgICAgICBpZiAoIWFibGVUb0J1aWxkKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhyb3dFcnJvcihpc05vdEFibGVUb0J1aWxkRXhjZXB0aW9uKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICByZXR1cm4gYnVpbGRlcnNbaXRlbUluZGV4XS5idWlsZEFzeW5jKGJhbm5lckRpc3BsYXlSZXF1ZXN0LnNldHRpbmdzKVxuICAgICAgICAgICAgLnBpcGUoXG4gICAgICAgICAgICAgIHRhcCgoY29tcG9uZW50UmVmOiBDb21wb25lbnRSZWY8SUJhbm5lckNvbnRlbnRDb21wb25lbnQ+KSA9PiB7XG5cbiAgICAgICAgICAgICAgICBpZiAoIXRoaXMuY29udGFpbmVyKSB7XG4gICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgLy8gVXBkYXRlIHRoZSByZXF1ZXN0LlxuICAgICAgICAgICAgICAgIHRoaXMuX2Rpc3BsYXlpbmdSZXF1ZXN0ID0gYmFubmVyRGlzcGxheVJlcXVlc3Q7XG5cbiAgICAgICAgICAgICAgICBjb25zdCBob29rRGlzcG9zZVJlcXVlc3QgPSBjb21wb25lbnRSZWYuaW5zdGFuY2VcbiAgICAgICAgICAgICAgICAgIC5kaXNwb3NlUmVxdWVzdGluZ0V2ZW50XG4gICAgICAgICAgICAgICAgICAuc3Vic2NyaWJlKChfOiBhbnkpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5iYW5uZXJTZXJ2aWNlLmRpc3BsYXlOZXh0QmFubmVyKHRoaXMuaWQpO1xuICAgICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgICAgICBjb21wb25lbnRSZWYub25EZXN0cm95KCgpID0+IHtcbiAgICAgICAgICAgICAgICAgIGlmIChob29rRGlzcG9zZVJlcXVlc3QgJiYgIWhvb2tEaXNwb3NlUmVxdWVzdC5jbG9zZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgaG9va0Rpc3Bvc2VSZXF1ZXN0LnVuc3Vic2NyaWJlKCk7XG4gICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgIC8vIE1hcmsgbm8gcmVxdWVzdCB0byBiZSBkaXNwbGF5ZWQuXG4gICAgICAgICAgICAgICAgICB0aGlzLl9kaXNwbGF5aW5nUmVxdWVzdCA9IG51bGw7XG4gICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgICAgICAvLyBEZXRlY3QgY2hhbmdlcy5cbiAgICAgICAgICAgICAgICBjb21wb25lbnRSZWYuY2hhbmdlRGV0ZWN0b3JSZWYuZGV0ZWN0Q2hhbmdlcygpO1xuXG4gICAgICAgICAgICAgICAgdGhpcy5jb250YWluZXIuY2xlYXIoKTtcbiAgICAgICAgICAgICAgICB0aGlzLmNvbnRhaW5lci5pbnNlcnQoY29tcG9uZW50UmVmLmhvc3RWaWV3KTtcblxuICAgICAgICAgICAgICAgIGlmIChzZXR0aW5ncy50aW1lb3V0ICYmIHNldHRpbmdzLnRpbWVvdXQuZHVyYXRpb24gJiYgc2V0dGluZ3MudGltZW91dC5hY3Rpb24pIHtcbiAgICAgICAgICAgICAgICAgIHRoaXMuX2Rlc3Ryb3lCYW5uZXJUaW1lciA9IHRoaXMud2luZG93U2VydmljZVxuICAgICAgICAgICAgICAgICAgICAuc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgLy8gRG8gYWN0aW9uIG9uIHRpbWVvdXQuXG4gICAgICAgICAgICAgICAgICAgICAgaWYgKHNldHRpbmdzICYmIHNldHRpbmdzLnRpbWVvdXQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHNldHRpbmdzLnRpbWVvdXQuYWN0aW9uKCk7XG4gICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9LCBzZXR0aW5ncy50aW1lb3V0LmR1cmF0aW9uKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgICBtYXAoXyA9PiB2b2lkICgwKSlcbiAgICAgICAgICAgICk7XG4gICAgICAgIH0pLFxuICAgICAgICByZXRyeVdoZW4oZXhjZXB0aW9uT2JzZXJ2YWJsZSA9PiB7XG4gICAgICAgICAgcmV0dXJuIGV4Y2VwdGlvbk9ic2VydmFibGVcbiAgICAgICAgICAgIC5waXBlKFxuICAgICAgICAgICAgICB0YXAoZXhjZXB0aW9uID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoZXhjZXB0aW9uICE9PSBpc05vdEFibGVUb0J1aWxkRXhjZXB0aW9uKSB7XG4gICAgICAgICAgICAgICAgICB0aHJvdyBleGNlcHRpb247XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgaXRlbUluZGV4Kys7XG4gICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICApO1xuICAgICAgICB9KVxuICAgICAgKTtcblxuICAgIC8vI2VuZHJlZ2lvblxuICB9XG5cbiAgLy8gV2hldGhlciBkaXNwbGF5aW5nIHJlcXVlc3QgaXMgcmVtb3ZhYmxlIG9yIG5vdC5cbiAgcHJvdGVjdGVkIGFibGVUb0RlbGV0ZURpc3BsYXlpbmdSZXF1ZXN0KGRlbGV0ZVJlcXVlc3Q6IElEZWxldGVCYW5uZXJSZXF1ZXN0KTogYm9vbGVhbiB7XG5cbiAgICBpZiAoZGVsZXRlUmVxdWVzdC5jb250YWluZXJJZCAmJiBkZWxldGVSZXF1ZXN0LmNvbnRhaW5lcklkICE9PSB0aGlzLmlkKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgaWYgKGRlbGV0ZVJlcXVlc3QuaWQgJiYgZGVsZXRlUmVxdWVzdC5pZCAhPT0gdGhpcy5fZGlzcGxheWluZ1JlcXVlc3Q/LmlkKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICAvLyBEZXF1ZXVlIHJlcXVlc3QuXG4gIHByb3RlY3RlZCBkZXF1ZXVlUmVxdWVzdChjb250YWluZXJJZDogc3RyaW5nKTogSURpc3BsYXlCYW5uZXJSZXF1ZXN0IHwgbnVsbCB7XG4gICAgaWYgKCF0aGlzLl9kaXNwbGF5UmVxdWVzdHMgfHwgIXRoaXMuX2Rpc3BsYXlSZXF1ZXN0cy5sZW5ndGgpIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIC8vIEdldCBmaXJzdCBtYXRjaCBpdGVtIGluIHRoZSBtZXNzYWdlcyBsaXN0LlxuICAgIGNvbnN0IGl0ZW1JbmRleCA9IHRoaXMuX2Rpc3BsYXlSZXF1ZXN0cy5maW5kSW5kZXgoeCA9PiB4LmNvbnRhaW5lcklkID09PSBjb250YWluZXJJZCk7XG4gICAgaWYgKGl0ZW1JbmRleCA8IDApIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIGNvbnN0IGl0ZW0gPSB0aGlzLl9kaXNwbGF5UmVxdWVzdHNbaXRlbUluZGV4XTtcbiAgICB0aGlzLl9kaXNwbGF5UmVxdWVzdHMuc3BsaWNlKGl0ZW1JbmRleCwgMSk7XG4gICAgcmV0dXJuIGl0ZW07XG4gIH1cblxuICAvLyBQb3AgcmVxdWVzdC5cbiAgcHJvdGVjdGVkIHBvcFJlcXVlc3QoY29udGFpbmVySWQ6IHN0cmluZyk6IElEaXNwbGF5QmFubmVyUmVxdWVzdCB8IG51bGwge1xuICAgIGlmICghdGhpcy5fZGlzcGxheVJlcXVlc3RzIHx8ICF0aGlzLl9kaXNwbGF5UmVxdWVzdHMubGVuZ3RoKSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG5cbiAgICAvLyBGaW5kIHRoZSBsYXN0IGluZGV4IG9mIGl0ZW0uXG4gICAgY29uc3QgbGFzdEluZGV4ID0gZmluZExhc3RJbmRleCh0aGlzLl9kaXNwbGF5UmVxdWVzdHMsIHggPT4geC5jb250YWluZXJJZCA9PT0gY29udGFpbmVySWQpO1xuICAgIGlmIChsYXN0SW5kZXggPCAwKSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG5cbiAgICBjb25zdCBpdGVtID0gdGhpcy5fZGlzcGxheVJlcXVlc3RzW2xhc3RJbmRleF07XG4gICAgdGhpcy5fZGlzcGxheVJlcXVlc3RzLnNwbGljZShsYXN0SW5kZXgsIDEpO1xuICAgIHJldHVybiBpdGVtO1xuICB9XG5cbiAgLy8jZW5kcmVnaW9uXG59XG4iLCI8bmctdGVtcGxhdGUgI2NvbnRhaW5lcj48L25nLXRlbXBsYXRlPlxuIl19