@ui-tool/core
Version:
278 lines • 42.1 kB
JavaScript
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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmFubmVyLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uL2xpYnMvY29yZS9zcmMvbW9kdWxlcy9iYW5uZXIvYmFubmVyLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uLy4uLy4uL2xpYnMvY29yZS9zcmMvbW9kdWxlcy9iYW5uZXIvYmFubmVyLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFFTCx1QkFBdUIsRUFDdkIsaUJBQWlCLEVBQ2pCLFNBQVMsRUFDVCx3QkFBd0IsRUFHeEIsS0FBSyxFQUVMLFNBQVMsRUFDVCxnQkFBZ0IsRUFDakIsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUFDLGNBQWMsRUFBRSxjQUFjLEVBQUUsTUFBTSxFQUFDLE1BQU0scUNBQXFDLENBQUM7QUFDM0YsT0FBTyxFQUFhLEVBQUUsRUFBRSxZQUFZLEVBQUUsVUFBVSxFQUFDLE1BQU0sTUFBTSxDQUFDO0FBQzlELE9BQU8sRUFBQyxnQkFBZ0IsRUFBRSxhQUFhLEVBQUUsZUFBZSxFQUFFLGVBQWUsRUFBRSxNQUFNLEVBQUUsV0FBVyxFQUFDLE1BQU0saUJBQWlCLENBQUM7QUFDdkgsT0FBTyxFQUFDLE1BQU0sRUFBRSxHQUFHLEVBQUUsUUFBUSxFQUFFLFNBQVMsRUFBRSxTQUFTLEVBQUUsR0FBRyxFQUFDLE1BQU0sZ0JBQWdCLENBQUM7QUFFaEYsT0FBTyxFQUFDLGFBQWEsRUFBQyxNQUFNLFdBQVcsQ0FBQzs7QUFheEMsTUFBTSxPQUFPLGVBQWU7SUEyRDFCLFlBQVk7SUFFWixxQkFBcUI7SUFFckIsWUFBNkIsUUFBa0I7UUFBbEIsYUFBUSxHQUFSLFFBQVEsQ0FBVTtRQUM3QyxJQUFJLENBQUMsRUFBRSxHQUFHLEVBQUUsQ0FBQztRQUNiLElBQUksQ0FBQyxTQUFTLEdBQUcsS0FBSyxDQUFDO1FBQ3ZCLElBQUksQ0FBQyxZQUFZLEdBQUcsc0JBQXNCLENBQUM7UUFDM0MsSUFBSSxDQUFDLFNBQVMsR0FBRyxJQUFJLENBQUM7UUFDdEIsSUFBSSxDQUFDLG1CQUFtQixHQUFHLElBQUksQ0FBQztRQUNoQyxJQUFJLENBQUMsa0JBQWtCLEdBQUcsSUFBSSxDQUFDO1FBQy9CLElBQUksQ0FBQyxnQkFBZ0IsR0FBRyxFQUFFLENBQUM7UUFFM0Isc0JBQXNCO1FBQ3RCLElBQUksQ0FBQyxhQUFhLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsY0FBYyxDQUF5QixDQUFDO1FBQy9FLElBQUksQ0FBQyx3QkFBd0IsR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyx3QkFBd0IsQ0FBQyxDQUFDO1FBQzVFLElBQUksQ0FBQyxNQUFNLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDeEMsSUFBSSxDQUFDLGFBQWEsR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQVcsQ0FBQztRQUN6RCxJQUFJLENBQUMsY0FBYyxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLGNBQWMsQ0FBbUMsQ0FBQztRQUMxRixJQUFJLENBQUMsaUJBQWlCLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsaUJBQWlCLENBQUMsQ0FBQztRQUM5RCxJQUFJLENBQUMsYUFBYSxHQUFHLElBQUksWUFBWSxFQUFFLENBQUM7SUFDMUMsQ0FBQztJQUVELFlBQVk7SUFFWixpQkFBaUI7SUFFVixlQUFlO1FBRXBCLE1BQU0sRUFBRSxHQUFHLElBQUksQ0FBQyxFQUFFLENBQUM7UUFFbkIsK0NBQStDO1FBQy9DLE1BQU0seUJBQXlCLEdBQUcsSUFBSSxDQUFDLGFBQWE7YUFDakQsaUJBQWlCO2FBQ2pCLFNBQVMsQ0FBQyxPQUFPLENBQUMsRUFBRTtZQUVuQix3QkFBd0I7WUFDeEIsSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLEVBQUU7Z0JBQ25CLE9BQU87YUFDUjtZQUVELDZCQUE2QjtZQUM3QixJQUFJLENBQUMsZ0JBQWdCLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1lBRXBDLHVDQUF1QztZQUN2QyxJQUFJLENBQUMsSUFBSSxDQUFDLGtCQUFrQixFQUFFO2dCQUM1QixJQUFJLENBQUMsYUFBYSxDQUFDLGlCQUFpQixDQUFDLEVBQUUsQ0FBQyxDQUFDO2FBQzFDO1FBQ0gsQ0FBQyxDQUFDLENBQUM7UUFDTCxJQUFJLENBQUMsYUFBYSxDQUFDLEdBQUcsQ0FBQyx5QkFBeUIsQ0FBQyxDQUFDO1FBRWxELG1FQUFtRTtRQUNuRSxNQUFNLG9DQUFvQyxHQUFHLElBQUksQ0FBQyxhQUFhO2FBQzVELDBCQUEwQjthQUMxQixJQUFJLENBQ0gsU0FBUyxDQUFDLE9BQU8sQ0FBQyxFQUFFO1lBRWxCLHFCQUFxQjtZQUNyQixJQUFJLE9BQU8sQ0FBQyxXQUFXLElBQUksT0FBTyxDQUFDLFdBQVcsS0FBSyxFQUFFLEVBQUU7Z0JBQ3JELE9BQU8sRUFBRSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO2FBQ3JCO1lBRUQsSUFBSSxDQUFDLE9BQU8sQ0FBQyxXQUFXLEVBQUU7Z0JBQ3hCLE9BQU8sRUFBRSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO2FBQ3JCO1lBRUQseUJBQXlCO1lBQ3pCLE1BQU0sV0FBVyxHQUFHLElBQUksQ0FBQyxTQUFTLEtBQUssS0FBSyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLE9BQU8sQ0FBQyxXQUFXLENBQUM7Z0JBQ2pGLENBQUMsQ0FBQyxJQUFJLENBQUMsY0FBYyxDQUFDLE9BQU8sQ0FBQyxXQUFXLENBQUMsQ0FBQztZQUU3QyxJQUFJLENBQUMsV0FBVyxFQUFFO2dCQUNoQix1QkFBdUI7Z0JBQ3ZCLElBQUksSUFBSSxDQUFDLFNBQVMsRUFBRTtvQkFDbEIsSUFBSSxDQUFDLFNBQVMsQ0FBQyxLQUFLLEVBQUUsQ0FBQztvQkFDdkIsSUFBSSxDQUFDLGtCQUFrQixHQUFHLElBQUksQ0FBQztpQkFDaEM7Z0JBRUQsT0FBTyxFQUFFLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7YUFDckI7WUFFRCxPQUFPLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxXQUFXLENBQUM7aUJBQ3hDLElBQUksQ0FDSCxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FDbkIsQ0FBQztRQUNOLENBQUMsQ0FBQyxDQUNIO2FBQ0EsU0FBUyxDQUFDLEdBQUcsRUFBRTtZQUNkLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxZQUFZLEVBQUUsQ0FBQztRQUN4QyxDQUFDLENBQUMsQ0FBQztRQUVMLElBQUksQ0FBQyxhQUFhLENBQUMsR0FBRyxDQUFDLG9DQUFvQyxDQUFDLENBQUM7UUFFN0QsOEJBQThCO1FBQzlCLE1BQU0sMkJBQTJCLEdBQUcsSUFBSSxDQUFDLE1BQU07YUFDNUMsTUFBTTthQUNOLElBQUksQ0FDSCxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLFlBQVksV0FBVyxDQUFDLEVBQ3JDLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxZQUFZLGdCQUFnQixDQUFDLElBQUksQ0FBQyxDQUFDLFlBQVksYUFBYSxDQUFDLElBQUksQ0FBQyxDQUFDLFlBQVksZUFBZSxDQUFDLENBQUMsQ0FDL0c7YUFDQSxTQUFTLENBQUMsQ0FBQyxDQUFDLEVBQUU7WUFFYixJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVMsRUFBRTtnQkFDbkIsT0FBTzthQUNSO1lBRUQsSUFBSSxDQUFDLENBQUMsQ0FBQyxZQUFZLGdCQUFnQixDQUFDLElBQUksQ0FBQyxDQUFDLFlBQVksYUFBYSxDQUFDLElBQUksQ0FBQyxDQUFDLFlBQVksZUFBZSxDQUFDLENBQUM7bUJBQ2xHLElBQUksQ0FBQyxZQUFZLEtBQUssb0JBQW9CLEVBQUU7Z0JBQy9DLElBQUksQ0FBQyxTQUFTLENBQUMsS0FBSyxFQUFFLENBQUM7Z0JBQ3ZCLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxZQUFZLEVBQUUsQ0FBQzthQUN2QztZQUVELElBQUksQ0FBQyxDQUFDLFlBQVksZUFBZSxDQUFDO21CQUM3QixJQUFJLENBQUMsWUFBWSxLQUFLLHNCQUFzQixFQUFFO2dCQUNqRCxJQUFJLENBQUMsU0FBUyxDQUFDLEtBQUssRUFBRSxDQUFDO2dCQUN2QixJQUFJLENBQUMsaUJBQWlCLENBQUMsWUFBWSxFQUFFLENBQUM7YUFDdkM7UUFDSCxDQUFDLENBQUMsQ0FBQztRQUNMLElBQUksQ0FBQyxhQUFhLENBQUMsR0FBRyxDQUFDLDJCQUEyQixDQUFDLENBQUM7UUFFcEQsc0NBQXNDO1FBQ3RDLElBQUksQ0FBQyxzQkFBc0IsRUFBRSxDQUFDO0lBQ2hDLENBQUM7SUFFRCxzQ0FBc0M7SUFDL0IsV0FBVztRQUNoQixJQUFJLENBQUMsYUFBYSxFQUFFLFdBQVcsRUFBRSxDQUFDO1FBRWxDLDhCQUE4QjtRQUM5QixJQUFJLElBQUksQ0FBQyxtQkFBbUIsRUFBRTtZQUM1QixJQUFJLENBQUMsYUFBYSxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUMsbUJBQW1CLENBQUMsQ0FBQztTQUMzRDtJQUNILENBQUM7SUFFRCxZQUFZO0lBRVosMEJBQTBCO0lBRWhCLHNCQUFzQjtRQUM5QixNQUFNLHlCQUF5QixHQUFHLElBQUksQ0FBQyxhQUFhO2FBQ2pELGtCQUFrQjthQUNsQixTQUFTLENBQUMsYUFBYSxDQUFDLEVBQUU7WUFFekIsd0JBQXdCO1lBQ3hCLElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUyxFQUFFO2dCQUNuQixPQUFPO2FBQ1I7WUFFRCxJQUFJLEtBQUssR0FBRyxDQUFDLENBQUM7WUFFZCxPQUFPLEtBQUssR0FBRyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsTUFBTSxFQUFFO2dCQUUzQyx3QkFBd0I7Z0JBQ3hCLElBQUksYUFBYSxDQUFDLFdBQVcsSUFBSSxhQUFhLENBQUMsV0FBVyxLQUFLLElBQUksQ0FBQyxFQUFFLEVBQUU7b0JBQ3RFLEtBQUssRUFBRSxDQUFDO29CQUNSLFNBQVM7aUJBQ1Y7Z0JBRUQseUJBQXlCO2dCQUN6QixJQUFJLGFBQWEsQ0FBQyxFQUFFLElBQUksYUFBYSxDQUFDLEVBQUUsS0FBSyxJQUFJLENBQUMsa0JBQWtCLEVBQUUsRUFBRSxFQUFFO29CQUN4RSxLQUFLLEVBQUUsQ0FBQztvQkFDUixTQUFTO2lCQUNWO2dCQUVELElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxNQUFNLENBQUMsS0FBSyxFQUFFLENBQUMsQ0FBQyxDQUFDO2FBQ3hDO1lBRUQsSUFBSSxDQUFDLElBQUksQ0FBQyw2QkFBNkIsQ0FBQyxhQUFhLENBQUMsRUFBRTtnQkFDdEQsT0FBTzthQUNSO1lBRUQsSUFBSSxDQUFDLFNBQVMsQ0FBQyxLQUFLLEVBQUUsQ0FBQztZQUN2QixJQUFJLENBQUMsa0JBQWtCLEdBQUcsSUFBSSxDQUFDO1lBQy9CLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxZQUFZLEVBQUUsQ0FBQztRQUN4QyxDQUFDLENBQUMsQ0FBQztRQUNMLElBQUksQ0FBQyxhQUFhLENBQUMsR0FBRyxDQUFDLHlCQUF5QixDQUFDLENBQUM7SUFDcEQsQ0FBQztJQUVELHNDQUFzQztJQUM1QixrQkFBa0IsQ0FBQyxvQkFBMkM7UUFFdEUsbUJBQW1CO1FBQ25CLElBQUksQ0FBQyxvQkFBb0IsRUFBRTtZQUN6QixPQUFPLEVBQUUsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztTQUNyQjtRQUVELG9EQUFvRDtRQUNwRCxJQUFJLG9CQUFvQixDQUFDLFdBQVcsSUFBSSxJQUFJLENBQUMsRUFBRTtlQUMxQyxvQkFBb0IsQ0FBQyxXQUFXLEtBQUssSUFBSSxDQUFDLEVBQUUsRUFBRTtZQUNqRCxPQUFPLEVBQUUsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztTQUNyQjtRQUVELE1BQU0sUUFBUSxHQUFHLG9CQUFvQixDQUFDLFFBQVEsQ0FBQztRQUMvQyxJQUFJLENBQUMsUUFBUSxFQUFFO1lBQ2IsT0FBTyxFQUFFLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7U0FDckI7UUFFRCw4QkFBOEI7UUFDOUIsSUFBSSxJQUFJLENBQUMsbUJBQW1CLEVBQUU7WUFDNUIsSUFBSSxDQUFDLGFBQWEsQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLG1CQUFtQixDQUFDLENBQUM7U0FDM0Q7UUFFRCxJQUFJLFNBQVMsR0FBRyxDQUFDLENBQUM7UUFDbEIsTUFBTSxRQUFRLEdBQUcsSUFBSSxDQUFDLGNBQWMsQ0FBQztRQUNyQyxNQUFNLHlCQUF5QixHQUFHLHlCQUF5QixDQUFDO1FBQzVELE1BQU0sMkJBQTJCLEdBQUcsc0JBQXNCLENBQUM7UUFDM0QsTUFBTSxrQkFBa0IsR0FBRyxzQkFBc0IsQ0FBQztRQUVsRCxPQUFPLEVBQUUsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7YUFDaEIsSUFBSSxDQUNILEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRTtZQUNOLElBQUksQ0FBQyxRQUFRLEVBQUU7Z0JBQ2IsTUFBTSwyQkFBMkIsQ0FBQzthQUNuQztZQUVELElBQUksU0FBUyxHQUFHLFFBQVEsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFO2dCQUNuQyxNQUFNLGtCQUFrQixDQUFDO2FBQzFCO1FBQ0gsQ0FBQyxDQUFDLEVBQ0YsUUFBUSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsUUFBUSxDQUFDLFNBQVMsQ0FBQyxDQUFDLGFBQWEsQ0FBQyxvQkFBb0IsQ0FBQyxRQUFRLENBQUMsQ0FBQyxFQUMvRSxRQUFRLENBQUMsV0FBVyxDQUFDLEVBQUU7WUFDckIsSUFBSSxDQUFDLFdBQVcsRUFBRTtnQkFDaEIsT0FBTyxVQUFVLENBQUMseUJBQXlCLENBQUMsQ0FBQzthQUM5QztZQUVELE9BQU8sUUFBUSxDQUFDLFNBQVMsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxvQkFBb0IsQ0FBQyxRQUFRLENBQUM7aUJBQ2pFLElBQUksQ0FDSCxHQUFHLENBQUMsQ0FBQyxZQUFtRCxFQUFFLEVBQUU7Z0JBRTFELElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUyxFQUFFO29CQUNuQixPQUFPO2lCQUNSO2dCQUVELHNCQUFzQjtnQkFDdEIsSUFBSSxDQUFDLGtCQUFrQixHQUFHLG9CQUFvQixDQUFDO2dCQUUvQyxNQUFNLGtCQUFrQixHQUFHLFlBQVksQ0FBQyxRQUFRO3FCQUM3QyxzQkFBc0I7cUJBQ3RCLFNBQVMsQ0FBQyxDQUFDLENBQU0sRUFBRSxFQUFFO29CQUNwQixJQUFJLENBQUMsYUFBYSxDQUFDLGlCQUFpQixDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQztnQkFDaEQsQ0FBQyxDQUFDLENBQUM7Z0JBRUwsWUFBWSxDQUFDLFNBQVMsQ0FBQyxHQUFHLEVBQUU7b0JBQzFCLElBQUksa0JBQWtCLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxNQUFNLEVBQUU7d0JBQ3BELGtCQUFrQixDQUFDLFdBQVcsRUFBRSxDQUFDO3FCQUNsQztvQkFFRCxtQ0FBbUM7b0JBQ25DLElBQUksQ0FBQyxrQkFBa0IsR0FBRyxJQUFJLENBQUM7Z0JBQ2pDLENBQUMsQ0FBQyxDQUFDO2dCQUVILGtCQUFrQjtnQkFDbEIsWUFBWSxDQUFDLGlCQUFpQixDQUFDLGFBQWEsRUFBRSxDQUFDO2dCQUUvQyxJQUFJLENBQUMsU0FBUyxDQUFDLEtBQUssRUFBRSxDQUFDO2dCQUN2QixJQUFJLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxZQUFZLENBQUMsUUFBUSxDQUFDLENBQUM7Z0JBRTdDLElBQUksUUFBUSxDQUFDLE9BQU8sSUFBSSxRQUFRLENBQUMsT0FBTyxDQUFDLFFBQVEsSUFBSSxRQUFRLENBQUMsT0FBTyxDQUFDLE1BQU0sRUFBRTtvQkFDNUUsSUFBSSxDQUFDLG1CQUFtQixHQUFHLElBQUksQ0FBQyxhQUFhO3lCQUMxQyxVQUFVLENBQUMsR0FBRyxFQUFFO3dCQUNmLHdCQUF3Qjt3QkFDeEIsSUFBSSxRQUFRLElBQUksUUFBUSxDQUFDLE9BQU8sRUFBRTs0QkFDaEMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxNQUFNLEVBQUUsQ0FBQzt5QkFDM0I7b0JBQ0gsQ0FBQyxFQUFFLFFBQVEsQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDLENBQUM7aUJBQ2pDO1lBQ0gsQ0FBQyxDQUFDLEVBQ0YsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQ25CLENBQUM7UUFDTixDQUFDLENBQUMsRUFDRixTQUFTLENBQUMsbUJBQW1CLENBQUMsRUFBRTtZQUM5QixPQUFPLG1CQUFtQjtpQkFDdkIsSUFBSSxDQUNILEdBQUcsQ0FBQyxTQUFTLENBQUMsRUFBRTtnQkFDZCxJQUFJLFNBQVMsS0FBSyx5QkFBeUIsRUFBRTtvQkFDM0MsTUFBTSxTQUFTLENBQUM7aUJBQ2pCO2dCQUVELFNBQVMsRUFBRSxDQUFDO1lBQ2QsQ0FBQyxDQUFDLENBQ0gsQ0FBQztRQUNOLENBQUMsQ0FBQyxDQUNILENBQUM7UUFFSixZQUFZO0lBQ2QsQ0FBQztJQUVELGtEQUFrRDtJQUN4Qyw2QkFBNkIsQ0FBQyxhQUFtQztRQUV6RSxJQUFJLGFBQWEsQ0FBQyxXQUFXLElBQUksYUFBYSxDQUFDLFdBQVcsS0FBSyxJQUFJLENBQUMsRUFBRSxFQUFFO1lBQ3RFLE9BQU8sS0FBSyxDQUFDO1NBQ2Q7UUFFRCxJQUFJLGFBQWEsQ0FBQyxFQUFFLElBQUksYUFBYSxDQUFDLEVBQUUsS0FBSyxJQUFJLENBQUMsa0JBQWtCLEVBQUUsRUFBRSxFQUFFO1lBQ3hFLE9BQU8sS0FBSyxDQUFDO1NBQ2Q7UUFFRCxPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7SUFFRCxtQkFBbUI7SUFDVCxjQUFjLENBQUMsV0FBbUI7UUFDMUMsSUFBSSxDQUFDLElBQUksQ0FBQyxnQkFBZ0IsSUFBSSxDQUFDLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxNQUFNLEVBQUU7WUFDM0QsT0FBTyxJQUFJLENBQUM7U0FDYjtRQUVELDZDQUE2QztRQUM3QyxNQUFNLFNBQVMsR0FBRyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLFdBQVcsS0FBSyxXQUFXLENBQUMsQ0FBQztRQUN0RixJQUFJLFNBQVMsR0FBRyxDQUFDLEVBQUU7WUFDakIsT0FBTyxJQUFJLENBQUM7U0FDYjtRQUVELE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUM5QyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsTUFBTSxDQUFDLFNBQVMsRUFBRSxDQUFDLENBQUMsQ0FBQztRQUMzQyxPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7SUFFRCxlQUFlO0lBQ0wsVUFBVSxDQUFDLFdBQW1CO1FBQ3RDLElBQUksQ0FBQyxJQUFJLENBQUMsZ0JBQWdCLElBQUksQ0FBQyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsTUFBTSxFQUFFO1lBQzNELE9BQU8sSUFBSSxDQUFDO1NBQ2I7UUFFRCwrQkFBK0I7UUFDL0IsTUFBTSxTQUFTLEdBQUcsYUFBYSxDQUFDLElBQUksQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxXQUFXLEtBQUssV0FBVyxDQUFDLENBQUM7UUFDM0YsSUFBSSxTQUFTLEdBQUcsQ0FBQyxFQUFFO1lBQ2pCLE9BQU8sSUFBSSxDQUFDO1NBQ2I7UUFFRCxNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsU0FBUyxDQUFDLENBQUM7UUFDOUMsSUFBSSxDQUFDLGdCQUFnQixDQUFDLE1BQU0sQ0FBQyxTQUFTLEVBQUUsQ0FBQyxDQUFDLENBQUM7UUFDM0MsT0FBTyxJQUFJLENBQUM7SUFDZCxDQUFDOzs2R0F2WVUsZUFBZTtpR0FBZixlQUFlLG9QQW1CSyxnQkFBZ0IsNkJDbERqRCwwQ0FDQTs0RkQ4QmEsZUFBZTtrQkFOM0IsU0FBUzsrQkFFRSxZQUFZLG1CQUVMLHVCQUF1QixDQUFDLE1BQU07K0ZBUXhDLEVBQUU7c0JBRFIsS0FBSztnQkFNQyxTQUFTO3NCQURmLEtBQUs7dUJBQUMsWUFBWTtnQkFNWixZQUFZO3NCQURsQixLQUFLO3VCQUFDLGVBQWU7Z0JBS2YsU0FBUztzQkFEZixTQUFTO3VCQUFDLFdBQVcsRUFBRSxFQUFDLElBQUksRUFBRSxnQkFBZ0IsRUFBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gIEFmdGVyVmlld0luaXQsXG4gIENoYW5nZURldGVjdGlvblN0cmF0ZWd5LFxuICBDaGFuZ2VEZXRlY3RvclJlZixcbiAgQ29tcG9uZW50LFxuICBDb21wb25lbnRGYWN0b3J5UmVzb2x2ZXIsXG4gIENvbXBvbmVudFJlZixcbiAgSW5qZWN0b3IsXG4gIElucHV0LFxuICBPbkRlc3Ryb3ksXG4gIFZpZXdDaGlsZCxcbiAgVmlld0NvbnRhaW5lclJlZlxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7QkFOTkVSX0JVSUxERVIsIEJBTk5FUl9TRVJWSUNFLCBXSU5ET1d9IGZyb20gJy4uLy4uL2NvbnN0YW50cy9pbmplY3RvcnMvaW5qZWN0b3JzJztcbmltcG9ydCB7T2JzZXJ2YWJsZSwgb2YsIFN1YnNjcmlwdGlvbiwgdGhyb3dFcnJvcn0gZnJvbSAncnhqcyc7XG5pbXBvcnQge05hdmlnYXRpb25DYW5jZWwsIE5hdmlnYXRpb25FbmQsIE5hdmlnYXRpb25FcnJvciwgTmF2aWdhdGlvblN0YXJ0LCBSb3V0ZXIsIFJvdXRlckV2ZW50fSBmcm9tICdAYW5ndWxhci9yb3V0ZXInO1xuaW1wb3J0IHtmaWx0ZXIsIG1hcCwgbWVyZ2VNYXAsIHJldHJ5V2hlbiwgc3dpdGNoTWFwLCB0YXB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcbmltcG9ydCB7QkFOTkVSX1BSRVNFUlZFX01PREUsIEJBTk5FUl9RVUVSWV9NT0RFfSBmcm9tICcuLi8uLi9jb25zdGFudHMvZGF0YS10eXBlLmNvbnN0YW50JztcbmltcG9ydCB7ZmluZExhc3RJbmRleH0gZnJvbSAnbG9kYXNoLWVzJztcbmltcG9ydCB7SUJhbm5lckNvbnRlbnRCdWlsZGVyfSBmcm9tICcuLi8uLi9zZXJ2aWNlcy9pbnRlcmZhY2VzL2Jhbm5lcnMvYmFubmVyLWNvbnRlbnQtYnVpbGRlci5pbnRlcmZhY2UnO1xuaW1wb3J0IHtCYW5uZXJTZXJ2aWNlfSBmcm9tICcuLi8uLi9zZXJ2aWNlcy9pbXBsZW1lbnRhdGlvbnMvYmFubmVycy9iYW5uZXIuc2VydmljZSc7XG5pbXBvcnQge0lEaXNwbGF5QmFubmVyUmVxdWVzdH0gZnJvbSAnLi4vLi4vbW9kZWxzL2ludGVyZmFjZXMvYmFubmVycy9hZGQtYmFubmVyLWNvbnRlbnQtcmVxdWVzdC5pbnRlcmZhY2UnO1xuaW1wb3J0IHtJQmFubmVyQ29udGVudENvbXBvbmVudH0gZnJvbSAnLi4vLi4vbW9kZWxzL2ludGVyZmFjZXMvYmFubmVycy9iYW5uZXItY29udGVudC1jb21wb25lbnQuaW50ZXJmYWNlJztcbmltcG9ydCB7SURlbGV0ZUJhbm5lclJlcXVlc3R9IGZyb20gJy4uLy4uL21vZGVscy9pbnRlcmZhY2VzL2Jhbm5lcnMvZGVsZXRlLWJhbm5lci1jb250ZW50LXJlcXVlc3QuaW50ZXJmYWNlJztcblxuQENvbXBvbmVudCh7XG4gIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTpjb21wb25lbnQtc2VsZWN0b3JcbiAgc2VsZWN0b3I6ICdjbXMtYmFubmVyJyxcbiAgdGVtcGxhdGVVcmw6ICdiYW5uZXIuY29tcG9uZW50Lmh0bWwnLFxuICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaFxufSlcbmV4cG9ydCBjbGFzcyBCYW5uZXJDb21wb25lbnQgaW1wbGVtZW50cyBBZnRlclZpZXdJbml0LCBPbkRlc3Ryb3kge1xuXG4gIC8vI3JlZ2lvbiBQcm9wZXJ0aWVzXG5cbiAgLy8gVW5pcXVlIGlkIG9mIGEgYmFubmVyIGNvbnRhaW5lci5cbiAgQElucHV0KClcbiAgcHVibGljIGlkOiBzdHJpbmc7XG5cbiAgLy8gSG93IGJhbm5lciBpcyBxdWVyaWVkIGZvciBiZWluZyBkaXNwbGF5ZWQuXG4gIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTpuby1pbnB1dC1yZW5hbWVcbiAgQElucHV0KCdxdWVyeS1tb2RlJylcbiAgcHVibGljIHF1ZXJ5TW9kZTogQkFOTkVSX1FVRVJZX01PREU7XG5cbiAgLy8gSG93IGJhbm5lciBwcmVzZXJ2ZSBtZXNzYWdlLlxuICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6bm8taW5wdXQtcmVuYW1lXG4gIEBJbnB1dCgncHJlc2VydmUtbW9kZScpXG4gIHB1YmxpYyBwcmVzZXJ2ZU1vZGU6IEJBTk5FUl9QUkVTRVJWRV9NT0RFO1xuXG4gIC8vIEdldCB0aGUgYmFubmVyIGNvbnRhaW5lciBhcmVhLlxuICBAVmlld0NoaWxkKCdjb250YWluZXInLCB7cmVhZDogVmlld0NvbnRhaW5lclJlZn0pXG4gIHB1YmxpYyBjb250YWluZXI6IFZpZXdDb250YWluZXJSZWYgfCBudWxsO1xuXG4gIC8vIFJlcXVlc3Qgd2hpY2ggaXMgY3VycmVudGx5IGFwcGxpZWQgdG8gdGhlIGJhbm5lciBjb250YWluZXIuXG4gIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTp2YXJpYWJsZS1uYW1lXG4gIHByaXZhdGUgX2Rpc3BsYXlpbmdSZXF1ZXN0OiBJRGlzcGxheUJhbm5lclJlcXVlc3QgfCBudWxsO1xuXG4gIC8vIEJhY2tncm91bmQgdGFzayB3aGljaCBpcyBmb3IgZGVzdHJveWluZyBjdXJyZW50bHkgZGlzcGxheWVkIGJhbm5lci5cbiAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOnZhcmlhYmxlLW5hbWVcbiAgcHJpdmF0ZSBfZGVzdHJveUJhbm5lclRpbWVyOiBudW1iZXIgfCBudWxsO1xuXG4gIC8vIExpc3Qgb2YgcmVxdWVzdCBhYm91dCBiYW5uZXIgZGlzcGxheS5cbiAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOnZhcmlhYmxlLW5hbWVcbiAgcHJpdmF0ZSByZWFkb25seSBfZGlzcGxheVJlcXVlc3RzOiBJRGlzcGxheUJhbm5lclJlcXVlc3RbXTtcblxuICAvLyBTdWJzY3JpcHRpb24gd2F0Y2ggbGlzdC5cbiAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOnZhcmlhYmxlLW5hbWVcbiAgcHJpdmF0ZSByZWFkb25seSBfc3Vic2NyaXB0aW9uOiBTdWJzY3JpcHRpb247XG5cbiAgLy8jZW5kcmVnaW9uXG5cbiAgLy8jcmVnaW9uIFNlcnZpY2VzXG5cbiAgLy8gU2VydmljZSBmb3IgaGFuZGxpbmcgYmFubmVyIGJ1c2luZXNzLlxuICBwcm90ZWN0ZWQgcmVhZG9ubHkgYmFubmVyU2VydmljZTogQmFubmVyU2VydmljZTtcblxuICAvLyBDb21wb25lbnQgZmFjdG9yeSByZXNvbHZlci5cbiAgcHJvdGVjdGVkIHJlYWRvbmx5IGNvbXBvbmVudEZhY3RvcnlSZXNvbHZlcjogQ29tcG9uZW50RmFjdG9yeVJlc29sdmVyO1xuXG4gIC8vIFJvdXRlciBzZXJ2aWNlLlxuICBwcm90ZWN0ZWQgcmVhZG9ubHkgcm91dGVyOiBSb3V0ZXI7XG5cbiAgLy8gV2luZG93IHNlcnZpY2UuXG4gIHByb3RlY3RlZCByZWFkb25seSB3aW5kb3dTZXJ2aWNlOiBXaW5kb3c7XG5cbiAgLy8gQmFubmVyIGJ1aWxkZXIuXG4gIHByb3RlY3RlZCByZWFkb25seSBiYW5uZXJCdWlsZGVyczogSUJhbm5lckNvbnRlbnRCdWlsZGVyW107XG5cbiAgcHJvdGVjdGVkIHJlYWRvbmx5IGNoYW5nZURldGVjdG9yUmVmOiBDaGFuZ2VEZXRlY3RvclJlZjtcblxuICAvLyNlbmRyZWdpb25cblxuICAvLyNyZWdpb24gQ29uc3RydWN0b3JcblxuICBwdWJsaWMgY29uc3RydWN0b3IocHJvdGVjdGVkIGluamVjdG9yOiBJbmplY3Rvcikge1xuICAgIHRoaXMuaWQgPSAnJztcbiAgICB0aGlzLnF1ZXJ5TW9kZSA9ICdwb3AnO1xuICAgIHRoaXMucHJlc2VydmVNb2RlID0gJ25hdmlnYXRlLXN0YXJ0LWNsZWFyJztcbiAgICB0aGlzLmNvbnRhaW5lciA9IG51bGw7XG4gICAgdGhpcy5fZGVzdHJveUJhbm5lclRpbWVyID0gbnVsbDtcbiAgICB0aGlzLl9kaXNwbGF5aW5nUmVxdWVzdCA9IG51bGw7XG4gICAgdGhpcy5fZGlzcGxheVJlcXVlc3RzID0gW107XG5cbiAgICAvLyBTZXJ2aWNlIHJlZmxlY3Rpb24uXG4gICAgdGhpcy5iYW5uZXJTZXJ2aWNlID0gdGhpcy5pbmplY3Rvci5nZXQoQkFOTkVSX1NFUlZJQ0UpIGFzIGFueSBhcyBCYW5uZXJTZXJ2aWNlO1xuICAgIHRoaXMuY29tcG9uZW50RmFjdG9yeVJlc29sdmVyID0gdGhpcy5pbmplY3Rvci5nZXQoQ29tcG9uZW50RmFjdG9yeVJlc29sdmVyKTtcbiAgICB0aGlzLnJvdXRlciA9IHRoaXMuaW5qZWN0b3IuZ2V0KFJvdXRlcik7XG4gICAgdGhpcy53aW5kb3dTZXJ2aWNlID0gdGhpcy5pbmplY3Rvci5nZXQoV0lORE9XKSBhcyBXaW5kb3c7XG4gICAgdGhpcy5iYW5uZXJCdWlsZGVycyA9IHRoaXMuaW5qZWN0b3IuZ2V0KEJBTk5FUl9CVUlMREVSKSBhcyBhbnkgYXMgSUJhbm5lckNvbnRlbnRCdWlsZGVyW107XG4gICAgdGhpcy5jaGFuZ2VEZXRlY3RvclJlZiA9IHRoaXMuaW5qZWN0b3IuZ2V0KENoYW5nZURldGVjdG9yUmVmKTtcbiAgICB0aGlzLl9zdWJzY3JpcHRpb24gPSBuZXcgU3Vic2NyaXB0aW9uKCk7XG4gIH1cblxuICAvLyNlbmRyZWdpb25cblxuICAvLyNyZWdpb24gTWV0aG9kc1xuXG4gIHB1YmxpYyBuZ0FmdGVyVmlld0luaXQoKTogdm9pZCB7XG5cbiAgICBjb25zdCBpZCA9IHRoaXMuaWQ7XG5cbiAgICAvLyBTdWJzY3JpcHRpb24gYWJvdXQgYmFubmVyIGRpc3BsYXkgcmVxdWVzdGVkLlxuICAgIGNvbnN0IGRpc3BsYXlCYW5uZXJTdWJzY3JpcHRpb24gPSB0aGlzLmJhbm5lclNlcnZpY2VcbiAgICAgIC5hZGRlZFJlcXVlc3RFdmVudFxuICAgICAgLnN1YnNjcmliZShyZXF1ZXN0ID0+IHtcblxuICAgICAgICAvLyBDb250YWluZXIgaXMgaW52YWxpZC5cbiAgICAgICAgaWYgKCF0aGlzLmNvbnRhaW5lcikge1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIEFkZCB0aGUgcmVxdWVzdCBpbnRvIGxpc3QuXG4gICAgICAgIHRoaXMuX2Rpc3BsYXlSZXF1ZXN0cy5wdXNoKHJlcXVlc3QpO1xuXG4gICAgICAgIC8vIE5vIGJhbm5lciBoYXMgYmVlbiBkaXNwbGF5ZWQgYmVmb3JlLlxuICAgICAgICBpZiAoIXRoaXMuX2Rpc3BsYXlpbmdSZXF1ZXN0KSB7XG4gICAgICAgICAgdGhpcy5iYW5uZXJTZXJ2aWNlLmRpc3BsYXlOZXh0QmFubmVyKGlkKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgdGhpcy5fc3Vic2NyaXB0aW9uLmFkZChkaXNwbGF5QmFubmVyU3Vic2NyaXB0aW9uKTtcblxuICAgIC8vIFN1YnNjcmlwdGlvbiB3aGljaCByYWlzZXMgd2hlbiBuZXh0IGJhbm5lciBkaXNwbGF5IGlzIHJlcXVlc3RlZC5cbiAgICBjb25zdCBuZXh0QmFubmVyRGlzcGxheVJlcXVlc3RTdWJzY3JpcHRpb24gPSB0aGlzLmJhbm5lclNlcnZpY2VcbiAgICAgIC5uZXh0QmFubmVyRGlzcGxheVJlcXVlc3RlZFxuICAgICAgLnBpcGUoXG4gICAgICAgIHN3aXRjaE1hcChyZXF1ZXN0ID0+IHtcblxuICAgICAgICAgIC8vIEludmFsaWQgY29udGFpbmVyLlxuICAgICAgICAgIGlmIChyZXF1ZXN0LmNvbnRhaW5lcklkICYmIHJlcXVlc3QuY29udGFpbmVySWQgIT09IGlkKSB7XG4gICAgICAgICAgICByZXR1cm4gb2Yodm9pZCAoMCkpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGlmICghcmVxdWVzdC5jb250YWluZXJJZCkge1xuICAgICAgICAgICAgcmV0dXJuIG9mKHZvaWQgKDApKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICAvLyBHZXQgdGhlIG5leHQgc2V0dGluZ3MuXG4gICAgICAgICAgY29uc3QgbmV4dFJlcXVlc3QgPSB0aGlzLnF1ZXJ5TW9kZSA9PT0gJ3BvcCcgPyB0aGlzLnBvcFJlcXVlc3QocmVxdWVzdC5jb250YWluZXJJZClcbiAgICAgICAgICAgIDogdGhpcy5kZXF1ZXVlUmVxdWVzdChyZXF1ZXN0LmNvbnRhaW5lcklkKTtcblxuICAgICAgICAgIGlmICghbmV4dFJlcXVlc3QpIHtcbiAgICAgICAgICAgIC8vIENsZWFyIHRoZSBob3N0IHZpZXcuXG4gICAgICAgICAgICBpZiAodGhpcy5jb250YWluZXIpIHtcbiAgICAgICAgICAgICAgdGhpcy5jb250YWluZXIuY2xlYXIoKTtcbiAgICAgICAgICAgICAgdGhpcy5fZGlzcGxheWluZ1JlcXVlc3QgPSBudWxsO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXR1cm4gb2Yodm9pZCAoMCkpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHJldHVybiB0aGlzLmRpc3BsYXlCYW5uZXJBc3luYyhuZXh0UmVxdWVzdClcbiAgICAgICAgICAgIC5waXBlKFxuICAgICAgICAgICAgICBtYXAoXyA9PiB2b2lkICgwKSlcbiAgICAgICAgICAgICk7XG4gICAgICAgIH0pXG4gICAgICApXG4gICAgICAuc3Vic2NyaWJlKCgpID0+IHtcbiAgICAgICAgdGhpcy5jaGFuZ2VEZXRlY3RvclJlZi5tYXJrRm9yQ2hlY2soKTtcbiAgICAgIH0pO1xuXG4gICAgdGhpcy5fc3Vic2NyaXB0aW9uLmFkZChuZXh0QmFubmVyRGlzcGxheVJlcXVlc3RTdWJzY3JpcHRpb24pO1xuXG4gICAgLy8gTGlzdGVuIHRvIG5hdmlnYXRpb24gZXZlbnQuXG4gICAgY29uc3QgbmF2aWdhdGlvbkV2ZW50U3Vic2NyaXB0aW9uID0gdGhpcy5yb3V0ZXJcbiAgICAgIC5ldmVudHNcbiAgICAgIC5waXBlKFxuICAgICAgICBmaWx0ZXIoZSA9PiBlIGluc3RhbmNlb2YgUm91dGVyRXZlbnQpLFxuICAgICAgICBmaWx0ZXIoZSA9PiAoZSBpbnN0YW5jZW9mIE5hdmlnYXRpb25DYW5jZWwpIHx8IChlIGluc3RhbmNlb2YgTmF2aWdhdGlvbkVuZCkgfHwgKGUgaW5zdGFuY2VvZiBOYXZpZ2F0aW9uRXJyb3IpKVxuICAgICAgKVxuICAgICAgLnN1YnNjcmliZShlID0+IHtcblxuICAgICAgICBpZiAoIXRoaXMuY29udGFpbmVyKSB7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCgoZSBpbnN0YW5jZW9mIE5hdmlnYXRpb25DYW5jZWwpIHx8IChlIGluc3RhbmNlb2YgTmF2aWdhdGlvbkVuZCkgfHwgKGUgaW5zdGFuY2VvZiBOYXZpZ2F0aW9uRXJyb3IpKVxuICAgICAgICAgICYmIHRoaXMucHJlc2VydmVNb2RlID09PSAnbmF2aWdhdGUtZW5kLWNsZWFyJykge1xuICAgICAgICAgIHRoaXMuY29udGFpbmVyLmNsZWFyKCk7XG4gICAgICAgICAgdGhpcy5jaGFuZ2VEZXRlY3RvclJlZi5tYXJrRm9yQ2hlY2soKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICgoZSBpbnN0YW5jZW9mIE5hdmlnYXRpb25TdGFydClcbiAgICAgICAgICAmJiB0aGlzLnByZXNlcnZlTW9kZSA9PT0gJ25hdmlnYXRlLXN0YXJ0LWNsZWFyJykge1xuICAgICAgICAgIHRoaXMuY29udGFpbmVyLmNsZWFyKCk7XG4gICAgICAgICAgdGhpcy5jaGFuZ2VEZXRlY3RvclJlZi5tYXJrRm9yQ2hlY2soKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgdGhpcy5fc3Vic2NyaXB0aW9uLmFkZChuYXZpZ2F0aW9uRXZlbnRTdWJzY3JpcHRpb24pO1xuXG4gICAgLy8gSG9vayBkZWxldGUgZGlzcGxheSBiYW5uZXIgcmVxdWVzdC5cbiAgICB0aGlzLmhvb2tEZWxldGVSZXF1ZXN0RXZlbnQoKTtcbiAgfVxuXG4gIC8vIENhbGxlZCB3aGVuIGNvbXBvbmVudCBpcyBkZXN0cm95ZWQuXG4gIHB1YmxpYyBuZ09uRGVzdHJveSgpOiB2b2lkIHtcbiAgICB0aGlzLl9zdWJzY3JpcHRpb24/LnVuc3Vic2NyaWJlKCk7XG5cbiAgICAvLyBDbGVhciB0aGUgcHJldmlvdXMgdGltZW91dC5cbiAgICBpZiAodGhpcy5fZGVzdHJveUJhbm5lclRpbWVyKSB7XG4gICAgICB0aGlzLndpbmRvd1NlcnZpY2UuY2xlYXJUaW1lb3V0KHRoaXMuX2Rlc3Ryb3lCYW5uZXJUaW1lcik7XG4gICAgfVxuICB9XG5cbiAgLy8jZW5kcmVnaW9uXG5cbiAgLy8jcmVnaW9uIEludGVybmFsIG1ldGhvZHNcblxuICBwcm90ZWN0ZWQgaG9va0RlbGV0ZVJlcXVlc3RFdmVudCgpOiB2b2lkIHtcbiAgICBjb25zdCBkZWxldGVSZXF1ZXN0U3Vic2NyaXB0aW9uID0gdGhpcy5iYW5uZXJTZXJ2aWNlXG4gICAgICAuZGVsZXRlUmVxdWVzdEV2ZW50XG4gICAgICAuc3Vic2NyaWJlKGRlbGV0ZVJlcXVlc3QgPT4ge1xuXG4gICAgICAgIC8vIENvbnRhaW5lciBpcyBpbnZhbGlkLlxuICAgICAgICBpZiAoIXRoaXMuY29udGFpbmVyKSB7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgbGV0IGluZGV4ID0gMDtcblxuICAgICAgICB3aGlsZSAoaW5kZXggPCB0aGlzLl9kaXNwbGF5UmVxdWVzdHMubGVuZ3RoKSB7XG5cbiAgICAgICAgICAvLyBDb250YWluZXIgaXMgaW52YWxpZC5cbiAgICAgICAgICBpZiAoZGVsZXRlUmVxdWVzdC5jb250YWluZXJJZCAmJiBkZWxldGVSZXF1ZXN0LmNvbnRhaW5lcklkICE9PSB0aGlzLmlkKSB7XG4gICAgICAgICAgICBpbmRleCsrO1xuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgLy8gUmVxdWVzdCBpZCBpcyBpbnZhbGlkLlxuICAgICAgICAgIGlmIChkZWxldGVSZXF1ZXN0LmlkICYmIGRlbGV0ZVJlcXVlc3QuaWQgIT09IHRoaXMuX2Rpc3BsYXlpbmdSZXF1ZXN0Py5pZCkge1xuICAgICAgICAgICAgaW5kZXgrKztcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHRoaXMuX2Rpc3BsYXlSZXF1ZXN0cy5zcGxpY2UoaW5kZXgsIDEpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCF0aGlzLmFibGVUb0RlbGV0ZURpc3BsYXlpbmdSZXF1ZXN0KGRlbGV0ZVJlcXVlc3QpKSB7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5jb250YWluZXIuY2xlYXIoKTtcbiAgICAgICAgdGhpcy5fZGlzcGxheWluZ1JlcXVlc3QgPSBudWxsO1xuICAgICAgICB0aGlzLmNoYW5nZURldGVjdG9yUmVmLm1hcmtGb3JDaGVjaygpO1xuICAgICAgfSk7XG4gICAgdGhpcy5fc3Vic2NyaXB0aW9uLmFkZChkZWxldGVSZXF1ZXN0U3Vic2NyaXB0aW9uKTtcbiAgfVxuXG4gIC8vIERpc3BsYXkgYmFubmVyIGJ5IGhhbmRsaW5nIHJlcXVlc3QuXG4gIHByb3RlY3RlZCBkaXNwbGF5QmFubmVyQXN5bmMoYmFubmVyRGlzcGxheVJlcXVlc3Q6IElEaXNwbGF5QmFubmVyUmVxdWVzdCk6IE9ic2VydmFibGU8dm9pZD4ge1xuXG4gICAgLy8gSW52YWxpZCByZXF1ZXN0LlxuICAgIGlmICghYmFubmVyRGlzcGxheVJlcXVlc3QpIHtcbiAgICAgIHJldHVybiBvZih2b2lkICgwKSk7XG4gICAgfVxuXG4gICAgLy8gUmVxdWVzdCBkb2VzIG5vdCBiZWxvbmcgdG8gdGhlIGN1cnJlbnQgY29udGFpbmVyLlxuICAgIGlmIChiYW5uZXJEaXNwbGF5UmVxdWVzdC5jb250YWluZXJJZCAmJiB0aGlzLmlkXG4gICAgICAmJiBiYW5uZXJEaXNwbGF5UmVxdWVzdC5jb250YWluZXJJZCAhPT0gdGhpcy5pZCkge1xuICAgICAgcmV0dXJuIG9mKHZvaWQgKDApKTtcbiAgICB9XG5cbiAgICBjb25zdCBzZXR0aW5ncyA9IGJhbm5lckRpc3BsYXlSZXF1ZXN0LnNldHRpbmdzO1xuICAgIGlmICghc2V0dGluZ3MpIHtcbiAgICAgIHJldHVybiBvZih2b2lkICgwKSk7XG4gICAgfVxuXG4gICAgLy8gQ2xlYXIgdGhlIHByZXZpb3VzIHRpbWVvdXQuXG4gICAgaWYgKHRoaXMuX2Rlc3Ryb3lCYW5uZXJUaW1lcikge1xuICAgICAgdGhpcy53aW5kb3dTZXJ2aWNlLmNsZWFyVGltZW91dCh0aGlzLl9kZXN0cm95QmFubmVyVGltZXIpO1xuICAgIH1cblxuICAgIGxldCBpdGVtSW5kZXggPSAwO1xuICAgIGNvbnN0IGJ1aWxkZXJzID0gdGhpcy5iYW5uZXJCdWlsZGVycztcbiAgICBjb25zdCBpc05vdEFibGVUb0J1aWxkRXhjZXB0aW9uID0gJ0lTX05PVF9BQkxFX1RPX0JFX0JVSUxUJztcbiAgICBjb25zdCBub0J1aWxkZXJBdmFpbGFibGVFeGNlcHRpb24gPSAnTk9fQlVJTERFUl9BVkFJTEFCTEUnO1xuICAgIGNvbnN0IG1heFJldHJpZXNFeGNlZWRlZCA9ICdNQVhfUkVUUklFU19FWENFRURFRCc7XG5cbiAgICByZXR1cm4gb2Yodm9pZCAoMCkpXG4gICAgICAucGlwZShcbiAgICAgICAgdGFwKF8gPT4ge1xuICAgICAgICAgIGlmICghYnVpbGRlcnMpIHtcbiAgICAgICAgICAgIHRocm93IG5vQnVpbGRlckF2YWlsYWJsZUV4Y2VwdGlvbjtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAoaXRlbUluZGV4ID4gYnVpbGRlcnMubGVuZ3RoIC0gMSkge1xuICAgICAgICAgICAgdGhyb3cgbWF4UmV0cmllc0V4Y2VlZGVkO1xuICAgICAgICAgIH1cbiAgICAgICAgfSksXG4gICAgICAgIG1lcmdlTWFwKF8gPT4gYnVpbGRlcnNbaXRlbUluZGV4XS5jYW5CdWlsZEFzeW5jKGJhbm5lckRpc3BsYXlSZXF1ZXN0LnNldHRpbmdzKSksXG4gICAgICAgIG1lcmdlTWFwKGFibGVUb0J1aWxkID0+IHtcbiAgICAgICAgICBpZiAoIWFibGVUb0J1aWxkKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhyb3dFcnJvcihpc05vdEFibGVUb0J1aWxkRXhjZXB0aW9uKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICByZXR1cm4gYnVpbGRlcnNbaXRlbUluZGV4XS5idWlsZEFzeW5jKGJhbm5lckRpc3BsYXlSZXF1ZXN0LnNldHRpbmdzKVxuICAgICAgICAgICAgLnBpcGUoXG4gICAgICAgICAgICAgIHRhcCgoY29tcG9uZW50UmVmOiBDb21wb25lbnRSZWY8SUJhbm5lckNvbnRlbnRDb21wb25lbnQ+KSA9PiB7XG5cbiAgICAgICAgICAgICAgICBpZiAoIXRoaXMuY29udGFpbmVyKSB7XG4gICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgLy8gVXBkYXRlIHRoZSByZXF1ZXN0LlxuICAgICAgICAgICAgICAgIHRoaXMuX2Rpc3BsYXlpbmdSZXF1ZXN0ID0gYmFubmVyRGlzcGxheVJlcXVlc3Q7XG5cbiAgICAgICAgICAgICAgICBjb25zdCBob29rRGlzcG9zZVJlcXVlc3QgPSBjb21wb25lbnRSZWYuaW5zdGFuY2VcbiAgICAgICAgICAgICAgICAgIC5kaXNwb3NlUmVxdWVzdGluZ0V2ZW50XG4gICAgICAgICAgICAgICAgICAuc3Vic2NyaWJlKChfOiBhbnkpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5iYW5uZXJTZXJ2aWNlLmRpc3BsYXlOZXh0QmFubmVyKHRoaXMuaWQpO1xuICAgICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgICAgICBjb21wb25lbnRSZWYub25EZXN0cm95KCgpID0+IHtcbiAgICAgICAgICAgICAgICAgIGlmIChob29rRGlzcG9zZVJlcXVlc3QgJiYgIWhvb2tEaXNwb3NlUmVxdWVzdC5jbG9zZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgaG9va0Rpc3Bvc2VSZXF1ZXN0LnVuc3Vic2NyaWJlKCk7XG4gICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgIC8vIE1hcmsgbm8gcmVxdWVzdCB0byBiZSBkaXNwbGF5ZWQuXG4gICAgICAgICAgICAgICAgICB0aGlzLl9kaXNwbGF5aW5nUmVxdWVzdCA9IG51bGw7XG4gICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgICAgICAvLyBEZXRlY3QgY2hhbmdlcy5cbiAgICAgICAgICAgICAgICBjb21wb25lbnRSZWYuY2hhbmdlRGV0ZWN0b3JSZWYuZGV0ZWN0Q2hhbmdlcygpO1xuXG4gICAgICAgICAgICAgICAgdGhpcy5jb250YWluZXIuY2xlYXIoKTtcbiAgICAgICAgICAgICAgICB0aGlzLmNvbnRhaW5lci5pbnNlcnQoY29tcG9uZW50UmVmLmhvc3RWaWV3KTtcblxuICAgICAgICAgICAgICAgIGlmIChzZXR0aW5ncy50aW1lb3V0ICYmIHNldHRpbmdzLnRpbWVvdXQuZHVyYXRpb24gJiYgc2V0dGluZ3MudGltZW91dC5hY3Rpb24pIHtcbiAgICAgICAgICAgICAgICAgIHRoaXMuX2Rlc3Ryb3lCYW5uZXJUaW1lciA9IHRoaXMud2luZG93U2VydmljZVxuICAgICAgICAgICAgICAgICAgICAuc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgLy8gRG8gYWN0aW9uIG9uIHRpbWVvdXQuXG4gICAgICAgICAgICAgICAgICAgICAgaWYgKHNldHRpbmdzICYmIHNldHRpbmdzLnRpbWVvdXQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHNldHRpbmdzLnRpbWVvdXQuYWN0aW9uKCk7XG4gICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9LCBzZXR0aW5ncy50aW1lb3V0LmR1cmF0aW9uKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgICBtYXAoXyA9PiB2b2lkICgwKSlcbiAgICAgICAgICAgICk7XG4gICAgICAgIH0pLFxuICAgICAgICByZXRyeVdoZW4oZXhjZXB0aW9uT2JzZXJ2YWJsZSA9PiB7XG4gICAgICAgICAgcmV0dXJuIGV4Y2VwdGlvbk9ic2VydmFibGVcbiAgICAgICAgICAgIC5waXBlKFxuICAgICAgICAgICAgICB0YXAoZXhjZXB0aW9uID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoZXhjZXB0aW9uICE9PSBpc05vdEFibGVUb0J1aWxkRXhjZXB0aW9uKSB7XG4gICAgICAgICAgICAgICAgICB0aHJvdyBleGNlcHRpb247XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgaXRlbUluZGV4Kys7XG4gICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICApO1xuICAgICAgICB9KVxuICAgICAgKTtcblxuICAgIC8vI2VuZHJlZ2lvblxuICB9XG5cbiAgLy8gV2hldGhlciBkaXNwbGF5aW5nIHJlcXVlc3QgaXMgcmVtb3ZhYmxlIG9yIG5vdC5cbiAgcHJvdGVjdGVkIGFibGVUb0RlbGV0ZURpc3BsYXlpbmdSZXF1ZXN0KGRlbGV0ZVJlcXVlc3Q6IElEZWxldGVCYW5uZXJSZXF1ZXN0KTogYm9vbGVhbiB7XG5cbiAgICBpZiAoZGVsZXRlUmVxdWVzdC5jb250YWluZXJJZCAmJiBkZWxldGVSZXF1ZXN0LmNvbnRhaW5lcklkICE9PSB0aGlzLmlkKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgaWYgKGRlbGV0ZVJlcXVlc3QuaWQgJiYgZGVsZXRlUmVxdWVzdC5pZCAhPT0gdGhpcy5fZGlzcGxheWluZ1JlcXVlc3Q/LmlkKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICAvLyBEZXF1ZXVlIHJlcXVlc3QuXG4gIHByb3RlY3RlZCBkZXF1ZXVlUmVxdWVzdChjb250YWluZXJJZDogc3RyaW5nKTogSURpc3BsYXlCYW5uZXJSZXF1ZXN0IHwgbnVsbCB7XG4gICAgaWYgKCF0aGlzLl9kaXNwbGF5UmVxdWVzdHMgfHwgIXRoaXMuX2Rpc3BsYXlSZXF1ZXN0cy5sZW5ndGgpIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIC8vIEdldCBmaXJzdCBtYXRjaCBpdGVtIGluIHRoZSBtZXNzYWdlcyBsaXN0LlxuICAgIGNvbnN0IGl0ZW1JbmRleCA9IHRoaXMuX2Rpc3BsYXlSZXF1ZXN0cy5maW5kSW5kZXgoeCA9PiB4LmNvbnRhaW5lcklkID09PSBjb250YWluZXJJZCk7XG4gICAgaWYgKGl0ZW1JbmRleCA8IDApIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIGNvbnN0IGl0ZW0gPSB0aGlzLl9kaXNwbGF5UmVxdWVzdHNbaXRlbUluZGV4XTtcbiAgICB0aGlzLl9kaXNwbGF5UmVxdWVzdHMuc3BsaWNlKGl0ZW1JbmRleCwgMSk7XG4gICAgcmV0dXJuIGl0ZW07XG4gIH1cblxuICAvLyBQb3AgcmVxdWVzdC5cbiAgcHJvdGVjdGVkIHBvcFJlcXVlc3QoY29udGFpbmVySWQ6IHN0cmluZyk6IElEaXNwbGF5QmFubmVyUmVxdWVzdCB8IG51bGwge1xuICAgIGlmICghdGhpcy5fZGlzcGxheVJlcXVlc3RzIHx8ICF0aGlzLl9kaXNwbGF5UmVxdWVzdHMubGVuZ3RoKSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG5cbiAgICAvLyBGaW5kIHRoZSBsYXN0IGluZGV4IG9mIGl0ZW0uXG4gICAgY29uc3QgbGFzdEluZGV4ID0gZmluZExhc3RJbmRleCh0aGlzLl9kaXNwbGF5UmVxdWVzdHMsIHggPT4geC5jb250YWluZXJJZCA9PT0gY29udGFpbmVySWQpO1xuICAgIGlmIChsYXN0SW5kZXggPCAwKSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG5cbiAgICBjb25zdCBpdGVtID0gdGhpcy5fZGlzcGxheVJlcXVlc3RzW2xhc3RJbmRleF07XG4gICAgdGhpcy5fZGlzcGxheVJlcXVlc3RzLnNwbGljZShsYXN0SW5kZXgsIDEpO1xuICAgIHJldHVybiBpdGVtO1xuICB9XG5cbiAgLy8jZW5kcmVnaW9uXG59XG4iLCI8bmctdGVtcGxhdGUgI2NvbnRhaW5lcj48L25nLXRlbXBsYXRlPlxuIl19