UNPKG

@dicdikshaorg/video-player-mobile-v9

Version:

Contains Video player library components powered by angular. These components are designed to be used in sunbird consumption platforms *(mobile app, web portal, offline desktop app)* to drive reusability, maintainability hence reducing the redundant devel

439 lines 47.6 kB
/** * @fileoverview added by tsickle * Generated from: lib/sunbird-video-player.component.ts * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ import { ChangeDetectorRef, Component, EventEmitter, Input, Output, HostListener, ElementRef, ViewChild, Renderer2 } from '@angular/core'; import { ErrorService, errorCode, errorMessage } from '@dicdikshaorg/player-sdk-v9'; import { ViewerService } from './services/viewer.service'; import { SunbirdVideoPlayerService } from './sunbird-video-player.service'; export class SunbirdVideoPlayerComponent { /** * @param {?} videoPlayerService * @param {?} viewerService * @param {?} cdr * @param {?} renderer2 * @param {?} errorService */ constructor(videoPlayerService, viewerService, cdr, renderer2, errorService) { this.videoPlayerService = videoPlayerService; this.viewerService = viewerService; this.cdr = cdr; this.renderer2 = renderer2; this.errorService = errorService; this.telemetryEvent = new EventEmitter(); this.viewState = 'player'; this.showControls = true; this.sideMenuConfig = { showShare: true, showDownload: true, showReplay: true, showExit: true }; this.isPaused = false; this.showQumlPlayer = false; this.QumlPlayerConfig = {}; this.isFullScreen = false; this.raiseInternetDisconnectionError = (/** * @return {?} */ () => { /** @type {?} */ const code = errorCode.internetConnectivity; /** @type {?} */ const message = errorMessage.internetConnectivity; /** @type {?} */ const stacktrace = `${code}: ${message}`; this.viewerService.raiseExceptionLog(code, message, stacktrace, this.traceId); }); this.playerEvent = this.viewerService.playerEvent; this.viewerService.playerEvent.subscribe((/** * @param {?} event * @return {?} */ event => { if (event.type === 'pause') { this.isPaused = true; this.showControls = true; } if (event.type === 'play') { this.isPaused = false; } if (event.type === 'loadstart') { this.viewerService.raiseStartEvent(event); } if (event.type === 'ended') { this.viewerService.endPageSeen = true; this.viewerService.raiseEndEvent(); this.viewState = 'end'; } if (event.type === 'error') { // tslint:disable-next-line:one-variable-per-declaration /** @type {?} */ let code = errorCode.contentLoadFails; /** @type {?} */ let message = errorMessage.contentLoadFails; if (this.viewerService.isAvailableLocally) { code = errorCode.contentLoadFails; message = errorMessage.contentLoadFails; } if (code === errorCode.contentLoadFails) { this.showContentError = true; } this.viewerService.raiseExceptionLog(code, message, event, this.traceId); } // tslint:disable-next-line:max-line-length /** @type {?} */ const events = [{ type: 'volumechange', telemetryEvent: 'VOLUME_CHANGE' }, { type: 'seeking', telemetryEvent: 'DRAG' }, { type: 'fullscreen', telemetryEvent: 'FULLSCREEN' }, { type: 'ratechange', telemetryEvent: 'RATE_CHANGE' }]; events.forEach((/** * @param {?} data * @return {?} */ data => { if (event.type === data.type) { this.viewerService.raiseHeartBeatEvent(data.telemetryEvent); } })); })); } /** * @param {?} event * @return {?} */ onTelemetryEvent(event) { this.telemetryEvent.emit(event.detail); } /** * @return {?} */ ngOnInit() { if (typeof this.playerConfig === 'string') { try { this.playerConfig = JSON.parse(this.playerConfig); } catch (error) { console.error('Invalid playerConfig: ', error); } } setInterval((/** * @return {?} */ () => { if (!this.isPaused) { this.showControls = false; } }), 5000); /* tslint:disable:no-string-literal */ this.nextContent = this.playerConfig.config.nextContent; this.traceId = this.playerConfig.config['traceId']; this.sideMenuConfig = Object.assign(Object.assign({}, this.sideMenuConfig), this.playerConfig.config.sideMenu); this.videoPlayerService.initialize(this.playerConfig); this.viewerService.initialize(this.playerConfig); window.addEventListener('offline', this.raiseInternetDisconnectionError, true); this.QumlPlayerConfig.config = this.playerConfig.config; this.QumlPlayerConfig.config.sideMenu.enable = false; this.QumlPlayerConfig.context = this.playerConfig.context; this.setTelemetryObjectRollup(this.playerConfig.metadata.identifier); } /** * @param {?} changes * @return {?} */ ngOnChanges(changes) { if (changes.action) { if (!this.showQumlPlayer) { this.playerAction = this.action; } } } /** * @return {?} */ ngAfterViewInit() { /** @type {?} */ const videoPlayerElement = this.videoPlayerRef.nativeElement; this.unlistenMouseMove = this.renderer2.listen(videoPlayerElement, 'mousemove', (/** * @return {?} */ () => { this.showControls = true; })); this.unlistenTouchStart = this.renderer2.listen(videoPlayerElement, 'touchstart', (/** * @return {?} */ () => { this.showControls = true; })); /** @type {?} */ const contentCompabilityLevel = this.playerConfig.metadata['compatibilityLevel']; if (contentCompabilityLevel) { /** @type {?} */ const checkContentCompatible = this.errorService.checkContentCompatibility(contentCompabilityLevel); if (!checkContentCompatible['isCompitable']) { // tslint:disable-next-line:max-line-length this.viewerService.raiseExceptionLog(errorCode.contentCompatibility, errorMessage.contentCompatibility, checkContentCompatible['error']['message'], this.traceId); } } } /** * @param {?} event * @return {?} */ sideBarEvents(event) { this.playerEvent.emit(event); // capturing this event from app code itself // if (event.type === 'DOWNLOAD') { // this.downloadVideo(); // } /** @type {?} */ const events = ['SHARE', 'DOWNLOAD_MENU', 'EXIT', 'CLOSE_MENU', 'OPEN_MENU', 'DOWNLOAD_POPUP_CANCEL', 'DOWNLOAD_POPUP_CLOSE']; events.forEach((/** * @param {?} data * @return {?} */ data => { if (event.type === data) { this.viewerService.raiseHeartBeatEvent(data); } if (event.type === 'EXIT') { this.viewerService.sidebarMenuEvent.emit('CLOSE_MENU'); } })); } /** * @param {?} id * @return {?} */ setTelemetryObjectRollup(id) { if (this.QumlPlayerConfig.context) { /** @type {?} */ const hasObjectRollup = this.QumlPlayerConfig && this.QumlPlayerConfig.context && this.QumlPlayerConfig.context.objectRollup; if (!hasObjectRollup) { this.QumlPlayerConfig.context.objectRollup = {}; } /** @type {?} */ const levels = Object.keys(this.QumlPlayerConfig.context.objectRollup); this.QumlPlayerConfig.context.objectRollup[`l${levels.length + 1}`] = id; } } /** * @param {?} event * @return {?} */ playContent(event) { this.viewerService.raiseHeartBeatEvent(event.type); } /** * @param {?} event * @return {?} */ replayContent(event) { this.playerEvent.emit(event); this.viewState = 'player'; this.viewerService.isEndEventRaised = false; this.viewerService.raiseHeartBeatEvent('REPLAY'); } /** * @param {?} event * @return {?} */ exitContent(event) { this.playerEvent.emit(event); this.viewerService.raiseHeartBeatEvent('EXIT'); } /** * @return {?} */ downloadVideo() { /** @type {?} */ const a = document.createElement('a'); a.href = this.viewerService.artifactUrl; a.download = this.viewerService.contentName; a.target = '_blank'; document.body.appendChild(a); a.click(); a.remove(); this.viewerService.raiseHeartBeatEvent('DOWNLOAD'); } /** * @param {?} event * @return {?} */ qumlPlayerEvents(event) { if (event.eid === 'QUML_SUMMARY') { this.showQumlPlayer = false; /** @type {?} */ const score = parseInt(event.edata.extra.find((/** * @param {?} p * @return {?} */ p => p.id === 'score'))['value'], 10); this.viewerService.interceptionResponses[this.currentInterceptionTime] = { score, isSkipped: false }; /** @type {?} */ const interceptPointElement = document.querySelector(`[data-marker-time="${this.currentInterceptionTime}"]`); if (interceptPointElement) { interceptPointElement['style'].background = 'green'; } this.videoInstance.play(); this.videoInstance.controls(true); this.viewerService.raiseImpressionEvent('video'); // if currently video is not in full screen and was previously full screen then set it back to full screen again if (!document.fullscreenElement && this.isFullScreen) { if (document.getElementsByClassName('video-js')[0]) { document.getElementsByClassName('video-js')[0].requestFullscreen() .catch((/** * @param {?} err * @return {?} */ (err) => console.error(err))); } } } } /** * @param {?} __0 * @return {?} */ questionSetData({ response, time, identifier }) { this.QumlPlayerConfig.metadata = response; this.QumlPlayerConfig.metadata['showStartPage'] = 'No'; this.QumlPlayerConfig.metadata['showEndPage'] = 'No'; this.currentInterceptionTime = time; this.currentInterceptionUIId = identifier; if (document.fullscreenElement) { this.isFullScreen = true; document.exitFullscreen() .catch((/** * @param {?} err * @return {?} */ (err) => console.error(err))); } else { this.isFullScreen = false; } this.showQumlPlayer = true; this.viewerService.raiseImpressionEvent('interactive-question-set', { id: identifier, type: 'QuestionSet' }); this.viewerService.raiseHeartBeatEvent('VIDEO_MARKER_SELECTED', { identifier, // Question set id, type: 'QuestionSet', // Type of interaction interceptedAt: time // Time when the interception happened }); } /** * @param {?} event * @return {?} */ playerInstance(event) { this.videoInstance = event; } /** * @return {?} */ ngOnDestroy() { this.viewerService.raiseEndEvent(); this.unlistenTouchStart(); this.unlistenMouseMove(); this.viewerService.isEndEventRaised = false; window.removeEventListener('offline', this.raiseInternetDisconnectionError, true); } } SunbirdVideoPlayerComponent.decorators = [ { type: Component, args: [{ selector: 'sunbird-video-player', template: "<div class=\"sunbird-video-player-container\" #videoPlayer [ngClass]=\"showQumlPlayer ? 'videoPlayerHide': 'videoPlayerShow'\">\n <sb-player-side-menu-icon class=\"sb-player-side-menu-icon notVisible\" tabindex=\"0\" (sidebarMenuEvent)=\"sideBarEvents($event)\"\n\n *ngIf=\"viewState ==='player'\" [ngClass]=\"{'isVisible': showControls}\"></sb-player-side-menu-icon>\n <video-player *ngIf=\"viewState === 'player'\" (questionSetData)=\"questionSetData($event)\" (playerInstance)=\"playerInstance($event)\" [config]=\"playerConfig.config\" [action]=\"playerAction\" [playVideoFromTimestamp]=\"playVideoFromTimestamp\">\n </video-player>\n <sb-player-sidebar *ngIf=\"viewState ==='player'\"\n [title]=\"viewerService.contentName\"\n (sidebarEvent)=\"sideBarEvents($event)\" [config]=\"sideMenuConfig\"></sb-player-sidebar>\n <sb-player-end-page \n [contentName]=\"viewerService.contentName\" \n [outcomeLabel]=\"viewerService.showScore ? 'Score: ': ''\" \n [outcome]=\"viewerService.showScore ? viewerService.scoreObtained + ((viewerService.maxScore && viewerService.maxScore > 0) ? '/' + viewerService.maxScore : '') : ''\"\n [nextContent]=\"nextContent\" [userName]=\"viewerService.userName\" \n [showExit]=\"sideMenuConfig.showExit\"\n [timeSpentLabel]=\"viewerService.timeSpent\" tabindex=\"0\" (playNextContent)=\"playContent($event)\" \n (exitContent)=\"exitContent($event)\" (replayContent)=\"replayContent($event)\"\n *ngIf=\"viewState === 'end'\"></sb-player-end-page>\n <sb-player-contenterror *ngIf=\"showContentError\"></sb-player-contenterror>\n</div>\n\n<div class=\"sunbird-video-player-container\" *ngIf=\"showQumlPlayer\" #qumlPlayer>\n <quml-main-player [playerConfig]=\"QumlPlayerConfig\" (playerEvent)=\"qumlPlayerEvents($event)\"></quml-main-player>\n</div>", styles: [".sunbird-video-player-container{width:100%;height:100%;overflow:hidden;position:relative}.videoPlayerHide{display:none}.videoPlayerShow{display:block}pdf-menu{position:absolute;top:0;left:0;z-index:99}.BtmNotVisible,.notVisible{transition:1s ease-in-out;position:absolute;width:100%}.notVisible{top:-10rem}.notVisible.isVisible{top:0}.BtmNotVisible{bottom:-10rem}.BtmNotVisible.isVisible{bottom:0}::ng-deep .sunbird-video-player-container .sb-player-side-menu-icon input[type=checkbox]:checked~#overlay-button span{background:0 0!important}::ng-deep .sunbird-video-player-container .sb-player-side-menu-icon input[type=checkbox]:checked~#overlay-button span:after,::ng-deep .sunbird-video-player-container .sb-player-side-menu-icon input[type=checkbox]:checked~#overlay-button span:before,::ng-deep .sunbird-video-player-container .sb-player-side-menu-icon input[type=checkbox]:checked~#overlay-button:hover span:after,::ng-deep .sunbird-video-player-container .sb-player-side-menu-icon input[type=checkbox]:checked~#overlay-button:hover span:before{background-color:rgba(255,255,255,.7)!important}::ng-deep .sunbird-video-player-container .sb-player-side-menu-icon label{background:rgba(51,51,51,.5)}::ng-deep .sunbird-video-player-container .sb-player-side-menu-icon label span,::ng-deep .sunbird-video-player-container .sb-player-side-menu-icon label span:after,::ng-deep .sunbird-video-player-container .sb-player-side-menu-icon label span:before{background-color:rgba(255,255,255,.7)!important}::ng-deep .sunbird-pdf-player{overflow:hidden}::ng-deep .pdfViewer .page{background:0 0!important;-o-border-image:none!important;border-image:none!important;border:0!important}::ng-deep #toolbarContainer{background:0 0!important;height:auto!important}::ng-deep #viewerContainer{position:relative!important;height:calc(100% - 3rem)}::ng-deep .body,::ng-deep .html,::ng-deep .pdf-viewer button,::ng-deep .pdf-viewer input,::ng-deep .pdf-viewer select{font-size:inherit!important}::ng-deep .findbar,::ng-deep .secondaryToolbar,::ng-deep html[dir=ltr] #toolbarContainer,::ng-deep html[dir=rtl] #toolbarContainer{box-shadow:none!important}::ng-deep .zoom{min-height:inherit!important}::ng-deep html[dir=rtl] .sb-pdf-reading-status{left:auto;right:1rem}.sb-pdf-reading-status{color:var(--gray-800);font-size:.75rem;position:absolute;left:1rem;bottom:1rem;display:flex;align-items:center;background:var(--white);border-radius:.5rem;padding:.25em .5rem;z-index:5;line-height:normal}.sb-pdf-reading-status span{background:var(--gray-800);width:.25rem;height:.25rem;display:block;margin:0 .5rem;border-radius:50%}.sbt-pdf-footer{background:var(--white);position:absolute;bottom:0;width:100%;height:3rem;display:flex;align-items:center;justify-content:flex-end;padding:.75rem .5rem}@media all and (orientation:landscape){::ng-deep .visible-only-potrait{display:none}}@media all and (orientation:portrait){::ng-deep #viewerContainer{height:calc(100% - 6rem)!important}::ng-deep .visible-only-landscape{display:none}::ng-deep .visible-only-potrait{display:block}::ng-deep .file-download__popup{height:15.125rem}::ng-deep .pdf-endpage{display:block!important;position:relative}::ng-deep .pdf-endpage__left-panel{margin-top:6rem}::ng-deep .pdf-endpage__right-panel .title-section{position:absolute;top:0;left:0;right:0}}@media all and (max-width:640px){.visible-only-landscape{display:none}.visible-only-potrait{display:block}}@media all and (min-width:640px){.visible-only-landscape{display:block}.visible-only-potrait{display:none}}"] }] } ]; /** @nocollapse */ SunbirdVideoPlayerComponent.ctorParameters = () => [ { type: SunbirdVideoPlayerService }, { type: ViewerService }, { type: ChangeDetectorRef }, { type: Renderer2 }, { type: ErrorService } ]; SunbirdVideoPlayerComponent.propDecorators = { playerConfig: [{ type: Input }], action: [{ type: Input }], playerEvent: [{ type: Output }], telemetryEvent: [{ type: Output }], videoPlayerRef: [{ type: ViewChild, args: ['videoPlayer', { static: true },] }], playVideoFromTimestamp: [{ type: Input }], onTelemetryEvent: [{ type: HostListener, args: ['document:TelemetryEvent', ['$event'],] }], ngOnDestroy: [{ type: HostListener, args: ['window:beforeunload',] }] }; if (false) { /** @type {?} */ SunbirdVideoPlayerComponent.prototype.playerConfig; /** @type {?} */ SunbirdVideoPlayerComponent.prototype.action; /** @type {?} */ SunbirdVideoPlayerComponent.prototype.playerEvent; /** @type {?} */ SunbirdVideoPlayerComponent.prototype.telemetryEvent; /** @type {?} */ SunbirdVideoPlayerComponent.prototype.videoPlayerRef; /** @type {?} */ SunbirdVideoPlayerComponent.prototype.playVideoFromTimestamp; /** @type {?} */ SunbirdVideoPlayerComponent.prototype.viewState; /** @type {?} */ SunbirdVideoPlayerComponent.prototype.traceId; /** @type {?} */ SunbirdVideoPlayerComponent.prototype.nextContent; /** @type {?} */ SunbirdVideoPlayerComponent.prototype.showContentError; /** @type {?} */ SunbirdVideoPlayerComponent.prototype.showControls; /** @type {?} */ SunbirdVideoPlayerComponent.prototype.sideMenuConfig; /** * @type {?} * @private */ SunbirdVideoPlayerComponent.prototype.unlistenTouchStart; /** * @type {?} * @private */ SunbirdVideoPlayerComponent.prototype.unlistenMouseMove; /** @type {?} */ SunbirdVideoPlayerComponent.prototype.isPaused; /** @type {?} */ SunbirdVideoPlayerComponent.prototype.showQumlPlayer; /** @type {?} */ SunbirdVideoPlayerComponent.prototype.QumlPlayerConfig; /** @type {?} */ SunbirdVideoPlayerComponent.prototype.videoInstance; /** @type {?} */ SunbirdVideoPlayerComponent.prototype.currentInterceptionTime; /** @type {?} */ SunbirdVideoPlayerComponent.prototype.currentInterceptionUIId; /** @type {?} */ SunbirdVideoPlayerComponent.prototype.isFullScreen; /** @type {?} */ SunbirdVideoPlayerComponent.prototype.playerAction; /** @type {?} */ SunbirdVideoPlayerComponent.prototype.raiseInternetDisconnectionError; /** @type {?} */ SunbirdVideoPlayerComponent.prototype.videoPlayerService; /** @type {?} */ SunbirdVideoPlayerComponent.prototype.viewerService; /** @type {?} */ SunbirdVideoPlayerComponent.prototype.cdr; /** * @type {?} * @private */ SunbirdVideoPlayerComponent.prototype.renderer2; /** @type {?} */ SunbirdVideoPlayerComponent.prototype.errorService; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3VuYmlyZC12aWRlby1wbGF5ZXIuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6Im5nOi8vQGRpY2Rpa3NoYW9yZy92aWRlby1wbGF5ZXItbW9iaWxlLXY5LyIsInNvdXJjZXMiOlsibGliL3N1bmJpcmQtdmlkZW8tcGxheWVyLmNvbXBvbmVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7OztBQUNBLE9BQU8sRUFDTCxpQkFBaUIsRUFBRSxTQUFTLEVBQUUsWUFBWSxFQUFFLEtBQUssRUFBVSxNQUFNLEVBQ2pFLFlBQVksRUFBRSxVQUFVLEVBQUUsU0FBUyxFQUFpQixTQUFTLEVBQzlELE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFBRSxZQUFZLEVBQUcsU0FBUyxFQUFHLFlBQVksRUFBaUIsTUFBTSw2QkFBNkIsQ0FBQztBQUlyRyxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sMkJBQTJCLENBQUM7QUFDMUQsT0FBTyxFQUFFLHlCQUF5QixFQUFFLE1BQU0sZ0NBQWdDLENBQUM7QUFNM0UsTUFBTSxPQUFPLDJCQUEyQjs7Ozs7Ozs7SUE4QnRDLFlBQ1Msa0JBQTZDLEVBQzdDLGFBQTRCLEVBQzVCLEdBQXNCLEVBQ3JCLFNBQW9CLEVBQ3JCLFlBQTBCO1FBSjFCLHVCQUFrQixHQUFsQixrQkFBa0IsQ0FBMkI7UUFDN0Msa0JBQWEsR0FBYixhQUFhLENBQWU7UUFDNUIsUUFBRyxHQUFILEdBQUcsQ0FBbUI7UUFDckIsY0FBUyxHQUFULFNBQVMsQ0FBVztRQUNyQixpQkFBWSxHQUFaLFlBQVksQ0FBYztRQTlCekIsbUJBQWMsR0FBc0IsSUFBSSxZQUFZLEVBQU8sQ0FBQztRQUd0RSxjQUFTLEdBQUcsUUFBUSxDQUFDO1FBSXJCLGlCQUFZLEdBQUcsSUFBSSxDQUFDO1FBQ3BCLG1CQUFjLEdBQUc7WUFDZixTQUFTLEVBQUUsSUFBSTtZQUNmLFlBQVksRUFBRSxJQUFJO1lBQ2xCLFVBQVUsRUFBRSxJQUFJO1lBQ2hCLFFBQVEsRUFBRSxJQUFJO1NBQ2YsQ0FBQztRQUdGLGFBQVEsR0FBRyxLQUFLLENBQUM7UUFDakIsbUJBQWMsR0FBRyxLQUFLLENBQUM7UUFDdkIscUJBQWdCLEdBQVEsRUFBRSxDQUFDO1FBSTNCLGlCQUFZLEdBQUcsS0FBSyxDQUFDO1FBNkZyQixvQ0FBK0I7OztRQUFHLEdBQUcsRUFBRTs7a0JBQy9CLElBQUksR0FBRyxTQUFTLENBQUMsb0JBQW9COztrQkFDckMsT0FBTyxHQUFHLFlBQVksQ0FBQyxvQkFBb0I7O2tCQUMzQyxVQUFVLEdBQUcsR0FBRyxJQUFJLEtBQUssT0FBTyxFQUFFO1lBQ3hDLElBQUksQ0FBQyxhQUFhLENBQUMsaUJBQWlCLENBQUMsSUFBSSxFQUFFLE9BQU8sRUFBRSxVQUFVLEVBQUUsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQ2hGLENBQUMsRUFBQTtRQXhGQyxJQUFJLENBQUMsV0FBVyxHQUFHLElBQUksQ0FBQyxhQUFhLENBQUMsV0FBVyxDQUFDO1FBQ2xELElBQUksQ0FBQyxhQUFhLENBQUMsV0FBVyxDQUFDLFNBQVM7Ozs7UUFBQyxLQUFLLENBQUMsRUFBRTtZQUMvQyxJQUFJLEtBQUssQ0FBQyxJQUFJLEtBQUssT0FBTyxFQUFFO2dCQUMxQixJQUFJLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQztnQkFDckIsSUFBSSxDQUFDLFlBQVksR0FBRyxJQUFJLENBQUM7YUFDMUI7WUFDRCxJQUFJLEtBQUssQ0FBQyxJQUFJLEtBQUssTUFBTSxFQUFFO2dCQUN6QixJQUFJLENBQUMsUUFBUSxHQUFHLEtBQUssQ0FBQzthQUN2QjtZQUNELElBQUksS0FBSyxDQUFDLElBQUksS0FBSyxXQUFXLEVBQUU7Z0JBQzlCLElBQUksQ0FBQyxhQUFhLENBQUMsZUFBZSxDQUFDLEtBQUssQ0FBQyxDQUFDO2FBQzNDO1lBQ0QsSUFBSSxLQUFLLENBQUMsSUFBSSxLQUFLLE9BQU8sRUFBRTtnQkFDMUIsSUFBSSxDQUFDLGFBQWEsQ0FBQyxXQUFXLEdBQUcsSUFBSSxDQUFDO2dCQUN0QyxJQUFJLENBQUMsYUFBYSxDQUFDLGFBQWEsRUFBRSxDQUFDO2dCQUNuQyxJQUFJLENBQUMsU0FBUyxHQUFHLEtBQUssQ0FBQzthQUN4QjtZQUNELElBQUksS0FBSyxDQUFDLElBQUksS0FBSyxPQUFPLEVBQUU7OztvQkFFdEIsSUFBSSxHQUFHLFNBQVMsQ0FBQyxnQkFBZ0I7O29CQUNuQyxPQUFPLEdBQUcsWUFBWSxDQUFDLGdCQUFnQjtnQkFDekMsSUFBSSxJQUFJLENBQUMsYUFBYSxDQUFDLGtCQUFrQixFQUFFO29CQUN2QyxJQUFJLEdBQUcsU0FBUyxDQUFDLGdCQUFnQixDQUFDO29CQUNsQyxPQUFPLEdBQUcsWUFBWSxDQUFDLGdCQUFnQixDQUFDO2lCQUMzQztnQkFDRCxJQUFJLElBQUksS0FBSyxTQUFTLENBQUMsZ0JBQWdCLEVBQUU7b0JBQ3ZDLElBQUksQ0FBQyxnQkFBZ0IsR0FBRyxJQUFJLENBQUM7aUJBQzlCO2dCQUNELElBQUksQ0FBQyxhQUFhLENBQUMsaUJBQWlCLENBQUMsSUFBSSxFQUFFLE9BQU8sRUFBRSxLQUFLLEVBQUUsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDO2FBRTFFOzs7a0JBRUssTUFBTSxHQUFHLENBQUMsRUFBRSxJQUFJLEVBQUUsY0FBYyxFQUFFLGNBQWMsRUFBRSxlQUFlLEVBQUUsRUFBRSxFQUFFLElBQUksRUFBRSxTQUFTLEVBQUUsY0FBYyxFQUFFLE1BQU0sRUFBRSxFQUFFLEVBQUUsSUFBSSxFQUFFLFlBQVksRUFBRSxjQUFjLEVBQUUsWUFBWSxFQUFFO2dCQUM1SyxFQUFFLElBQUksRUFBRSxZQUFZLEVBQUUsY0FBYyxFQUFFLGFBQWEsRUFBRSxDQUFDO1lBQ3RELE1BQU0sQ0FBQyxPQUFPOzs7O1lBQUMsSUFBSSxDQUFDLEVBQUU7Z0JBQ3BCLElBQUksS0FBSyxDQUFDLElBQUksS0FBSyxJQUFJLENBQUMsSUFBSSxFQUFFO29CQUM1QixJQUFJLENBQUMsYUFBYSxDQUFDLG1CQUFtQixDQUFDLElBQUksQ0FBQyxjQUFjLENBQUMsQ0FBQztpQkFDN0Q7WUFDSCxDQUFDLEVBQUMsQ0FBQztRQUNMLENBQUMsRUFBQyxDQUFDO0lBQ0wsQ0FBQzs7Ozs7SUFHRCxnQkFBZ0IsQ0FBQyxLQUFLO1FBQ3BCLElBQUksQ0FBQyxjQUFjLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsQ0FBQztJQUN6QyxDQUFDOzs7O0lBRUQsUUFBUTtRQUNOLElBQUksT0FBTyxJQUFJLENBQUMsWUFBWSxLQUFLLFFBQVEsRUFBRTtZQUN6QyxJQUFJO2dCQUNGLElBQUksQ0FBQyxZQUFZLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLENBQUM7YUFDbkQ7WUFBQyxPQUFPLEtBQUssRUFBRTtnQkFDZCxPQUFPLENBQUMsS0FBSyxDQUFDLHdCQUF3QixFQUFFLEtBQUssQ0FBQyxDQUFDO2FBQ2hEO1NBQ0Y7UUFFRCxXQUFXOzs7UUFBQyxHQUFHLEVBQUU7WUFDZixJQUFJLENBQUMsSUFBSSxDQUFDLFFBQVEsRUFBRTtnQkFDbEIsSUFBSSxDQUFDLFlBQVksR0FBRyxLQUFLLENBQUM7YUFDM0I7UUFDSCxDQUFDLEdBQUUsSUFBSSxDQUFDLENBQUM7UUFFVCxzQ0FBc0M7UUFDdEMsSUFBSSxDQUFDLFdBQVcsR0FBRyxJQUFJLENBQUMsWUFBWSxDQUFDLE1BQU0sQ0FBQyxXQUFXLENBQUM7UUFDeEQsSUFBSSxDQUFDLE9BQU8sR0FBRyxJQUFJLENBQUMsWUFBWSxDQUFDLE1BQU0sQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUNuRCxJQUFJLENBQUMsY0FBYyxtQ0FBUSxJQUFJLENBQUMsY0FBYyxHQUFLLElBQUksQ0FBQyxZQUFZLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBRSxDQUFDO1FBQ3ZGLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxDQUFDO1FBQ3RELElBQUksQ0FBQyxhQUFhLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsQ0FBQztRQUNqRCxNQUFNLENBQUMsZ0JBQWdCLENBQUMsU0FBUyxFQUFFLElBQUksQ0FBQywrQkFBK0IsRUFBRyxJQUFJLENBQUMsQ0FBQztRQUNoRixJQUFJLENBQUMsZ0JBQWdCLENBQUMsTUFBTSxHQUFHLElBQUksQ0FBQyxZQUFZLENBQUMsTUFBTSxDQUFDO1FBQ3hELElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLE1BQU0sR0FBRyxLQUFLLENBQUM7UUFDckQsSUFBSSxDQUFDLGdCQUFnQixDQUFDLE9BQU8sR0FBRyxJQUFJLENBQUMsWUFBWSxDQUFDLE9BQU8sQ0FBQztRQUMxRCxJQUFJLENBQUMsd0JBQXdCLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxRQUFRLENBQUMsVUFBVSxDQUFDLENBQUM7SUFDdkUsQ0FBQzs7Ozs7SUFFRCxXQUFXLENBQUMsT0FBc0I7UUFDaEMsSUFBSSxPQUFPLENBQUMsTUFBTSxFQUFFO1lBQ2xCLElBQUksQ0FBQyxJQUFJLENBQUMsY0FBYyxFQUFFO2dCQUN4QixJQUFJLENBQUMsWUFBWSxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUM7YUFDakM7U0FDRjtJQUNILENBQUM7Ozs7SUFTRCxlQUFlOztjQUNQLGtCQUFrQixHQUFHLElBQUksQ0FBQyxjQUFjLENBQUMsYUFBYTtRQUM1RCxJQUFJLENBQUMsaUJBQWlCLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsa0JBQWtCLEVBQUUsV0FBVzs7O1FBQUUsR0FBRyxFQUFFO1lBQ25GLElBQUksQ0FBQyxZQUFZLEdBQUcsSUFBSSxDQUFDO1FBQzNCLENBQUMsRUFBQyxDQUFDO1FBRUgsSUFBSSxDQUFDLGtCQUFrQixHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLGtCQUFrQixFQUFFLFlBQVk7OztRQUFFLEdBQUcsRUFBRTtZQUNyRixJQUFJLENBQUMsWUFBWSxHQUFHLElBQUksQ0FBQztRQUMzQixDQUFDLEVBQUMsQ0FBQzs7Y0FFRyx1QkFBdUIsR0FBRyxJQUFJLENBQUMsWUFBWSxDQUFDLFFBQVEsQ0FBQyxvQkFBb0IsQ0FBQztRQUNoRixJQUFJLHVCQUF1QixFQUFFOztrQkFDckIsc0JBQXNCLEdBQUcsSUFBSSxDQUFDLFlBQVksQ0FBQyx5QkFBeUIsQ0FBQyx1QkFBdUIsQ0FBQztZQUNuRyxJQUFJLENBQUMsc0JBQXNCLENBQUMsY0FBYyxDQUFDLEVBQUU7Z0JBQzNDLDJDQUEyQztnQkFDM0MsSUFBSSxDQUFDLGFBQWEsQ0FBQyxpQkFBaUIsQ0FBQyxTQUFTLENBQUMsb0JBQW9CLEVBQUUsWUFBWSxDQUFDLG9CQUFvQixFQUFFLHNCQUFzQixDQUFDLE9BQU8sQ0FBQyxDQUFDLFNBQVMsQ0FBQyxFQUFFLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQzthQUNuSztTQUNGO0lBQ0gsQ0FBQzs7Ozs7SUFFRCxhQUFhLENBQUMsS0FBb0I7UUFDaEMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7Ozs7OztjQUt2QixNQUFNLEdBQUcsQ0FBQyxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sRUFBRSxZQUFZLEVBQUUsV0FBVyxFQUFFLHVCQUF1QixFQUFFLHNCQUFzQixDQUFDO1FBQzdILE1BQU0sQ0FBQyxPQUFPOzs7O1FBQUMsSUFBSSxDQUFDLEVBQUU7WUFDcEIsSUFBSSxLQUFLLENBQUMsSUFBSSxLQUFLLElBQUksRUFBRTtnQkFDdkIsSUFBSSxDQUFDLGFBQWEsQ0FBQyxtQkFBbUIsQ0FBQyxJQUFJLENBQUMsQ0FBQzthQUM5QztZQUNELElBQUksS0FBSyxDQUFDLElBQUksS0FBSyxNQUFNLEVBQUU7Z0JBQ3pCLElBQUksQ0FBQyxhQUFhLENBQUMsZ0JBQWdCLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxDQUFDO2FBQ3hEO1FBQ0gsQ0FBQyxFQUFDLENBQUM7SUFDTCxDQUFDOzs7OztJQUVELHdCQUF3QixDQUFDLEVBQUU7UUFDekIsSUFBSSxJQUFJLENBQUMsZ0JBQWdCLENBQUMsT0FBTyxFQUFFOztrQkFDM0IsZUFBZSxHQUFHLElBQUksQ0FBQyxnQkFBZ0IsSUFBSSxJQUFJLENBQUMsZ0JBQWdCLENBQUMsT0FBTyxJQUFJLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxPQUFPLENBQUMsWUFBWTtZQUM1SCxJQUFJLENBQUMsZUFBZSxFQUFFO2dCQUNwQixJQUFJLENBQUMsZ0JBQWdCLENBQUMsT0FBTyxDQUFDLFlBQVksR0FBRyxFQUFFLENBQUM7YUFDakQ7O2tCQUNLLE1BQU0sR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxPQUFPLENBQUMsWUFBWSxDQUFDO1lBQ3RFLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxPQUFPLENBQUMsWUFBWSxDQUFDLElBQUksTUFBTSxDQUFDLE1BQU0sR0FBSSxDQUFDLEVBQUUsQ0FBQyxHQUFHLEVBQUUsQ0FBQztTQUMzRTtJQUNILENBQUM7Ozs7O0lBRUQsV0FBVyxDQUFDLEtBQUs7UUFDZixJQUFJLENBQUMsYUFBYSxDQUFDLG1CQUFtQixDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUNyRCxDQUFDOzs7OztJQUVELGFBQWEsQ0FBQyxLQUFLO1FBQ2pCLElBQUksQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQzdCLElBQUksQ0FBQyxTQUFTLEdBQUcsUUFBUSxDQUFDO1FBQzFCLElBQUksQ0FBQyxhQUFhLENBQUMsZ0JBQWdCLEdBQUcsS0FBSyxDQUFDO1FBQzVDLElBQUksQ0FBQyxhQUFhLENBQUMsbUJBQW1CLENBQUMsUUFBUSxDQUFDLENBQUM7SUFDbkQsQ0FBQzs7Ozs7SUFFRCxXQUFXLENBQUMsS0FBSztRQUNmLElBQUksQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQzdCLElBQUksQ0FBQyxhQUFhLENBQUMsbUJBQW1CLENBQUMsTUFBTSxDQUFDLENBQUM7SUFDakQsQ0FBQzs7OztJQUVELGFBQWE7O2NBQ0wsQ0FBQyxHQUFHLFFBQVEsQ0FBQyxhQUFhLENBQUMsR0FBRyxDQUFDO1FBQ3JDLENBQUMsQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDLGFBQWEsQ0FBQyxXQUFXLENBQUM7UUFDeEMsQ0FBQyxDQUFDLFFBQVEsR0FBRyxJQUFJLENBQUMsYUFBYSxDQUFDLFdBQVcsQ0FBQztRQUM1QyxDQUFDLENBQUMsTUFBTSxHQUFHLFFBQVEsQ0FBQztRQUNwQixRQUFRLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUM3QixDQUFDLENBQUMsS0FBSyxFQUFFLENBQUM7UUFDVixDQUFDLENBQUMsTUFBTSxFQUFFLENBQUM7UUFDWCxJQUFJLENBQUMsYUFBYSxDQUFDLG1CQUFtQixDQUFDLFVBQVUsQ0FBQyxDQUFDO0lBQ3JELENBQUM7Ozs7O0lBRUQsZ0JBQWdCLENBQUMsS0FBSztRQUNwQixJQUFJLEtBQUssQ0FBQyxHQUFHLEtBQUssY0FBYyxFQUFFO1lBQ2hDLElBQUksQ0FBQyxjQUFjLEdBQUcsS0FBSyxDQUFDOztrQkFDdEIsS0FBSyxHQUFHLFFBQVEsQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxJQUFJOzs7O1lBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxLQUFLLE9BQU8sRUFBQyxDQUFDLE9BQU8sQ0FBQyxFQUFFLEVBQUUsQ0FBQztZQUNsRixJQUFJLENBQUMsYUFBYSxDQUFDLHFCQUFxQixDQUFDLElBQUksQ0FBQyx1QkFBdUIsQ0FBQyxHQUFHO2dCQUN2RSxLQUFLO2dCQUNMLFNBQVMsRUFBRSxLQUFLO2FBQ2pCLENBQUM7O2tCQUNJLHFCQUFxQixHQUFHLFFBQVEsQ0FBQyxhQUFhLENBQUMsc0JBQXNCLElBQUksQ0FBQyx1QkFBdUIsSUFBSSxDQUFDO1lBQzVHLElBQUkscUJBQXFCLEVBQUU7Z0JBQ3pCLHFCQUFxQixDQUFDLE9BQU8sQ0FBQyxDQUFDLFVBQVUsR0FBRyxPQUFPLENBQUM7YUFDckQ7WUFDRCxJQUFJLENBQUMsYUFBYSxDQUFDLElBQUksRUFBRSxDQUFDO1lBQzFCLElBQUksQ0FBQyxhQUFhLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFDO1lBQ2xDLElBQUksQ0FBQyxhQUFhLENBQUMsb0JBQW9CLENBQUMsT0FBTyxDQUFDLENBQUM7WUFDakQsZ0hBQWdIO1lBQ2hILElBQUksQ0FBQyxRQUFRLENBQUMsaUJBQWlCLElBQUksSUFBSSxDQUFDLFlBQVksRUFBRTtnQkFDcEQsSUFBSSxRQUFRLENBQUMsc0JBQXNCLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUU7b0JBQ2xELFFBQVEsQ0FBQyxzQkFBc0IsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxpQkFBaUIsRUFBRTt5QkFDakUsS0FBSzs7OztvQkFBQyxDQUFDLEdBQUcsRUFBRSxFQUFFLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsRUFBQyxDQUFDO2lCQUNyQzthQUNGO1NBQ0Y7SUFDSCxDQUFDOzs7OztJQUVELGVBQWUsQ0FBQyxFQUFDLFFBQVEsRUFBRSxJQUFJLEVBQUUsVUFBVSxFQUFDO1FBQzFDLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxRQUFRLEdBQUcsUUFBUSxDQUFDO1FBQzFDLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxRQUFRLENBQUMsZUFBZSxDQUFDLEdBQUcsSUFBSSxDQUFDO1FBQ3ZELElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxRQUFRLENBQUMsYUFBYSxDQUFDLEdBQUcsSUFBSSxDQUFDO1FBQ3JELElBQUksQ0FBQyx1QkFBdUIsR0FBRyxJQUFJLENBQUM7UUFDcEMsSUFBSSxDQUFDLHVCQUF1QixHQUFHLFVBQVUsQ0FBQztRQUMxQyxJQUFJLFFBQVEsQ0FBQyxpQkFBaUIsRUFBRTtZQUM5QixJQUFJLENBQUMsWUFBWSxHQUFHLElBQUksQ0FBQztZQUN6QixRQUFRLENBQUMsY0FBYyxFQUFFO2lCQUN4QixLQUFLOzs7O1lBQUMsQ0FBQyxHQUFHLEVBQUUsRUFBRSxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLEVBQUMsQ0FBQztTQUNyQzthQUFNO1lBQ0wsSUFBSSxDQUFDLFlBQVksR0FBRyxLQUFLLENBQUM7U0FDM0I7UUFDRCxJQUFJLENBQUMsY0FBYyxHQUFHLElBQUksQ0FBQztRQUMzQixJQUFJLENBQUMsYUFBYSxDQUFDLG9CQUFvQixDQUFDLDBCQUEwQixFQUFFLEVBQUUsRUFBRSxFQUFFLFVBQVUsRUFBRSxJQUFJLEVBQUUsYUFBYSxFQUFFLENBQUMsQ0FBQztRQUM3RyxJQUFJLENBQUMsYUFBYSxDQUFDLG1CQUFtQixDQUFDLHVCQUF1QixFQUFFO1lBQzlELFVBQVU7O1lBQ1YsSUFBSSxFQUFFLGFBQWE7O1lBQ25CLGFBQWEsRUFBRSxJQUFJLENBQUMsc0NBQXNDO1NBQzNELENBQUMsQ0FBQztJQUNMLENBQUM7Ozs7O0lBRUQsY0FBYyxDQUFDLEtBQUs7UUFDbEIsSUFBSSxDQUFDLGFBQWEsR0FBRyxLQUFLLENBQUM7SUFDN0IsQ0FBQzs7OztJQUdELFdBQVc7UUFDVCxJQUFJLENBQUMsYUFBYSxDQUFDLGFBQWEsRUFBRSxDQUFDO1FBQ25DLElBQUksQ0FBQyxrQkFBa0IsRUFBRSxDQUFDO1FBQzFCLElBQUksQ0FBQyxpQkFBaUIsRUFBRSxDQUFDO1FBQ3pCLElBQUksQ0FBQyxhQUFhLENBQUMsZ0JBQWdCLEdBQUcsS0FBSyxDQUFDO1FBQzVDLE1BQU0sQ0FBQyxtQkFBbUIsQ0FBQyxTQUFTLEVBQUUsSUFBSSxDQUFDLCtCQUErQixFQUFHLElBQUksQ0FBQyxDQUFDO0lBQ3JGLENBQUM7OztZQXpRRixTQUFTLFNBQUM7Z0JBQ1QsUUFBUSxFQUFFLHNCQUFzQjtnQkFDaEMsbTNEQUFvRDs7YUFFckQ7Ozs7WUFMUSx5QkFBeUI7WUFEekIsYUFBYTtZQVBwQixpQkFBaUI7WUFDbUMsU0FBUztZQUV0RCxZQUFZOzs7MkJBYWxCLEtBQUs7cUJBQ0wsS0FBSzswQkFDTCxNQUFNOzZCQUNOLE1BQU07NkJBQ04sU0FBUyxTQUFDLGFBQWEsRUFBRSxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUU7cUNBQ3pDLEtBQUs7K0JBd0VMLFlBQVksU0FBQyx5QkFBeUIsRUFBRSxDQUFDLFFBQVEsQ0FBQzswQkE4S2xELFlBQVksU0FBQyxxQkFBcUI7Ozs7SUEzUG5DLG1EQUFvQzs7SUFDcEMsNkNBQTBCOztJQUMxQixrREFBNEM7O0lBQzVDLHFEQUFzRTs7SUFDdEUscURBQXVFOztJQUN2RSw2REFBNEM7O0lBQzVDLGdEQUFxQjs7SUFDckIsOENBQXVCOztJQUN2QixrREFBd0I7O0lBQ3hCLHVEQUEwQjs7SUFDMUIsbURBQW9COztJQUNwQixxREFLRTs7Ozs7SUFDRix5REFBdUM7Ozs7O0lBQ3ZDLHdEQUFzQzs7SUFDdEMsK0NBQWlCOztJQUNqQixxREFBdUI7O0lBQ3ZCLHVEQUEyQjs7SUFDM0Isb0RBQW1COztJQUNuQiw4REFBd0I7O0lBQ3hCLDhEQUF3Qjs7SUFDeEIsbURBQXFCOztJQUNyQixtREFBc0I7O0lBNEZ0QixzRUFLQzs7SUE5RkMseURBQW9EOztJQUNwRCxvREFBbUM7O0lBQ25DLDBDQUE2Qjs7Ozs7SUFDN0IsZ0RBQTRCOztJQUM1QixtREFBaUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBUaHJvd1N0bXQgfSBmcm9tICdAYW5ndWxhci9jb21waWxlcic7XG5pbXBvcnQge1xuICBDaGFuZ2VEZXRlY3RvclJlZiwgQ29tcG9uZW50LCBFdmVudEVtaXR0ZXIsIElucHV0LCBPbkluaXQsIE91dHB1dCwgT25DaGFuZ2VzLCBTaW1wbGVDaGFuZ2VzLFxuICBIb3N0TGlzdGVuZXIsIEVsZW1lbnRSZWYsIFZpZXdDaGlsZCwgQWZ0ZXJWaWV3SW5pdCwgUmVuZGVyZXIyLCBPbkRlc3Ryb3lcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBFcnJvclNlcnZpY2UgLCBlcnJvckNvZGUgLCBlcnJvck1lc3NhZ2UsIElTaWRlQmFyRXZlbnQgfSBmcm9tICdAZGljZGlrc2hhb3JnL3BsYXllci1zZGstdjknO1xuXG5pbXBvcnQgeyBQbGF5ZXJDb25maWcgfSBmcm9tICcuL3BsYXllckludGVyZmFjZXMnO1xuaW1wb3J0IHsgSUFjdGlvbiB9IGZyb20gJy4vcGxheWVySW50ZXJmYWNlcyc7XG5pbXBvcnQgeyBWaWV3ZXJTZXJ2aWNlIH0gZnJvbSAnLi9zZXJ2aWNlcy92aWV3ZXIuc2VydmljZSc7XG5pbXBvcnQgeyBTdW5iaXJkVmlkZW9QbGF5ZXJTZXJ2aWNlIH0gZnJvbSAnLi9zdW5iaXJkLXZpZGVvLXBsYXllci5zZXJ2aWNlJztcbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ3N1bmJpcmQtdmlkZW8tcGxheWVyJyxcbiAgdGVtcGxhdGVVcmw6ICcuL3N1bmJpcmQtdmlkZW8tcGxheWVyLmNvbXBvbmVudC5odG1sJyxcbiAgc3R5bGVVcmxzOiBbJy4vc3VuYmlyZC12aWRlby1wbGF5ZXIuY29tcG9uZW50LnNjc3MnXVxufSlcbmV4cG9ydCBjbGFzcyBTdW5iaXJkVmlkZW9QbGF5ZXJDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQsIEFmdGVyVmlld0luaXQsIE9uRGVzdHJveSwgT25DaGFuZ2VzIHtcblxuICBASW5wdXQoKSBwbGF5ZXJDb25maWc6IFBsYXllckNvbmZpZztcbiAgQElucHV0KCkgYWN0aW9uPzogSUFjdGlvbjtcbiAgQE91dHB1dCgpIHBsYXllckV2ZW50OiBFdmVudEVtaXR0ZXI8b2JqZWN0PjtcbiAgQE91dHB1dCgpIHRlbGVtZXRyeUV2ZW50OiBFdmVudEVtaXR0ZXI8YW55PiA9IG5ldyBFdmVudEVtaXR0ZXI8YW55PigpO1xuICBAVmlld0NoaWxkKCd2aWRlb1BsYXllcicsIHsgc3RhdGljOiB0cnVlIH0pIHZpZGVvUGxheWVyUmVmOiBFbGVtZW50UmVmOyBcbiAgQElucHV0KCkgcHVibGljIHBsYXlWaWRlb0Zyb21UaW1lc3RhbXA6IGFueTtcbiAgdmlld1N0YXRlID0gJ3BsYXllcic7XG4gIHB1YmxpYyB0cmFjZUlkOiBzdHJpbmc7XG4gIHB1YmxpYyBuZXh0Q29udGVudDogYW55O1xuICBzaG93Q29udGVudEVycm9yOiBib29sZWFuO1xuICBzaG93Q29udHJvbHMgPSB0cnVlO1xuICBzaWRlTWVudUNvbmZpZyA9IHtcbiAgICBzaG93U2hhcmU6IHRydWUsXG4gICAgc2hvd0Rvd25sb2FkOiB0cnVlLFxuICAgIHNob3dSZXBsYXk6IHRydWUsXG4gICAgc2hvd0V4aXQ6IHRydWVcbiAgfTtcbiAgcHJpdmF0ZSB1bmxpc3RlblRvdWNoU3RhcnQ6ICgpID0+IHZvaWQ7XG4gIHByaXZhdGUgdW5saXN0ZW5Nb3VzZU1vdmU6ICgpID0+IHZvaWQ7XG4gIGlzUGF1c2VkID0gZmFsc2U7XG4gIHNob3dRdW1sUGxheWVyID0gZmFsc2U7XG4gIFF1bWxQbGF5ZXJDb25maWc6IGFueSA9IHt9O1xuICB2aWRlb0luc3RhbmNlOiBhbnk7XG4gIGN1cnJlbnRJbnRlcmNlcHRpb25UaW1lO1xuICBjdXJyZW50SW50ZXJjZXB0aW9uVUlJZDtcbiAgaXNGdWxsU2NyZWVuID0gZmFsc2U7XG4gIHBsYXllckFjdGlvbjogSUFjdGlvbjtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBwdWJsaWMgdmlkZW9QbGF5ZXJTZXJ2aWNlOiBTdW5iaXJkVmlkZW9QbGF5ZXJTZXJ2aWNlLFxuICAgIHB1YmxpYyB2aWV3ZXJTZXJ2aWNlOiBWaWV3ZXJTZXJ2aWNlLFxuICAgIHB1YmxpYyBjZHI6IENoYW5nZURldGVjdG9yUmVmLFxuICAgIHByaXZhdGUgcmVuZGVyZXIyOiBSZW5kZXJlcjIsXG4gICAgcHVibGljIGVycm9yU2VydmljZTogRXJyb3JTZXJ2aWNlXG4gICkge1xuICAgIHRoaXMucGxheWVyRXZlbnQgPSB0aGlzLnZpZXdlclNlcnZpY2UucGxheWVyRXZlbnQ7XG4gICAgdGhpcy52aWV3ZXJTZXJ2aWNlLnBsYXllckV2ZW50LnN1YnNjcmliZShldmVudCA9PiB7XG4gICAgICBpZiAoZXZlbnQudHlwZSA9PT0gJ3BhdXNlJykge1xuICAgICAgICB0aGlzLmlzUGF1c2VkID0gdHJ1ZTtcbiAgICAgICAgdGhpcy5zaG93Q29udHJvbHMgPSB0cnVlO1xuICAgICAgfVxuICAgICAgaWYgKGV2ZW50LnR5cGUgPT09ICdwbGF5Jykge1xuICAgICAgICB0aGlzLmlzUGF1c2VkID0gZmFsc2U7XG4gICAgICB9XG4gICAgICBpZiAoZXZlbnQudHlwZSA9PT0gJ2xvYWRzdGFydCcpIHtcbiAgICAgICAgdGhpcy52aWV3ZXJTZXJ2aWNlLnJhaXNlU3RhcnRFdmVudChldmVudCk7XG4gICAgICB9XG4gICAgICBpZiAoZXZlbnQudHlwZSA9PT0gJ2VuZGVkJykge1xuICAgICAgICB0aGlzLnZpZXdlclNlcnZpY2UuZW5kUGFnZVNlZW4gPSB0cnVlO1xuICAgICAgICB0aGlzLnZpZXdlclNlcnZpY2UucmFpc2VFbmRFdmVudCgpO1xuICAgICAgICB0aGlzLnZpZXdTdGF0ZSA9ICdlbmQnO1xuICAgICAgfVxuICAgICAgaWYgKGV2ZW50LnR5cGUgPT09ICdlcnJvcicpIHtcbiAgICAgICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOm9uZS12YXJpYWJsZS1wZXItZGVjbGFyYXRpb25cbiAgICAgICAgbGV0IGNvZGUgPSBlcnJvckNvZGUuY29udGVudExvYWRGYWlscyxcbiAgICAgICAgICBtZXNzYWdlID0gZXJyb3JNZXNzYWdlLmNvbnRlbnRMb2FkRmFpbHM7XG4gICAgICAgIGlmICh0aGlzLnZpZXdlclNlcnZpY2UuaXNBdmFpbGFibGVMb2NhbGx5KSB7XG4gICAgICAgICAgICBjb2RlID0gZXJyb3JDb2RlLmNvbnRlbnRMb2FkRmFpbHM7XG4gICAgICAgICAgICBtZXNzYWdlID0gZXJyb3JNZXNzYWdlLmNvbnRlbnRMb2FkRmFpbHM7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGNvZGUgPT09IGVycm9yQ29kZS5jb250ZW50TG9hZEZhaWxzKSB7XG4gICAgICAgICAgdGhpcy5zaG93Q29udGVudEVycm9yID0gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnZpZXdlclNlcnZpY2UucmFpc2VFeGNlcHRpb25Mb2coY29kZSwgbWVzc2FnZSwgZXZlbnQsIHRoaXMudHJhY2VJZCk7XG5cbiAgICAgIH1cbiAgICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTptYXgtbGluZS1sZW5ndGhcbiAgICAgIGNvbnN0IGV2ZW50cyA9IFt7IHR5cGU6ICd2b2x1bWVjaGFuZ2UnLCB0ZWxlbWV0cnlFdmVudDogJ1ZPTFVNRV9DSEFOR0UnIH0sIHsgdHlwZTogJ3NlZWtpbmcnLCB0ZWxlbWV0cnlFdmVudDogJ0RSQUcnIH0sIHsgdHlwZTogJ2Z1bGxzY3JlZW4nLCB0ZWxlbWV0cnlFdmVudDogJ0ZVTExTQ1JFRU4nIH0sXG4gICAgICB7IHR5cGU6ICdyYXRlY2hhbmdlJywgdGVsZW1ldHJ5RXZlbnQ6ICdSQVRFX0NIQU5HRScgfV07XG4gICAgICBldmVudHMuZm9yRWFjaChkYXRhID0+IHtcbiAgICAgICAgaWYgKGV2ZW50LnR5cGUgPT09IGRhdGEudHlwZSkge1xuICAgICAgICAgIHRoaXMudmlld2VyU2VydmljZS5yYWlzZUhlYXJ0QmVhdEV2ZW50KGRhdGEudGVsZW1ldHJ5RXZlbnQpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfVxuXG4gIEBIb3N0TGlzdGVuZXIoJ2RvY3VtZW50OlRlbGVtZXRyeUV2ZW50JywgWyckZXZlbnQnXSlcbiAgb25UZWxlbWV0cnlFdmVudChldmVudCkge1xuICAgIHRoaXMudGVsZW1ldHJ5RXZlbnQuZW1pdChldmVudC5kZXRhaWwpO1xuICB9XG5cbiAgbmdPbkluaXQoKSB7XG4gICAgaWYgKHR5cGVvZiB0aGlzLnBsYXllckNvbmZpZyA9PT0gJ3N0cmluZycpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIHRoaXMucGxheWVyQ29uZmlnID0gSlNPTi5wYXJzZSh0aGlzLnBsYXllckNvbmZpZyk7XG4gICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICBjb25zb2xlLmVycm9yKCdJbnZhbGlkIHBsYXllckNvbmZpZzogJywgZXJyb3IpO1xuICAgICAgfVxuICAgIH1cblxuICAgIHNldEludGVydmFsKCgpID0+IHtcbiAgICAgIGlmICghdGhpcy5pc1BhdXNlZCkge1xuICAgICAgICB0aGlzLnNob3dDb250cm9scyA9IGZhbHNlO1xuICAgICAgfVxuICAgIH0sIDUwMDApO1xuXG4gICAgLyogdHNsaW50OmRpc2FibGU6bm8tc3RyaW5nLWxpdGVyYWwgKi9cbiAgICB0aGlzLm5leHRDb250ZW50ID0gdGhpcy5wbGF5ZXJDb25maWcuY29uZmlnLm5leHRDb250ZW50O1xuICAgIHRoaXMudHJhY2VJZCA9IHRoaXMucGxheWVyQ29uZmlnLmNvbmZpZ1sndHJhY2VJZCddO1xuICAgIHRoaXMuc2lkZU1lbnVDb25maWcgPSB7IC4uLnRoaXMuc2lkZU1lbnVDb25maWcsIC4uLnRoaXMucGxheWVyQ29uZmlnLmNvbmZpZy5zaWRlTWVudSB9O1xuICAgIHRoaXMudmlkZW9QbGF5ZXJTZXJ2aWNlLmluaXRpYWxpemUodGhpcy5wbGF5ZXJDb25maWcpO1xuICAgIHRoaXMudmlld2VyU2VydmljZS5pbml0aWFsaXplKHRoaXMucGxheWVyQ29uZmlnKTtcbiAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcignb2ZmbGluZScsIHRoaXMucmFpc2VJbnRlcm5ldERpc2Nvbm5lY3Rpb25FcnJvciAsIHRydWUpO1xuICAgIHRoaXMuUXVtbFBsYXllckNvbmZpZy5jb25maWcgPSB0aGlzLnBsYXllckNvbmZpZy5jb25maWc7XG4gICAgdGhpcy5RdW1sUGxheWVyQ29uZmlnLmNvbmZpZy5zaWRlTWVudS5lbmFibGUgPSBmYWxzZTtcbiAgICB0aGlzLlF1bWxQbGF5ZXJDb25maWcuY29udGV4dCA9IHRoaXMucGxheWVyQ29uZmlnLmNvbnRleHQ7XG4gICAgdGhpcy5zZXRUZWxlbWV0cnlPYmplY3RSb2xsdXAodGhpcy5wbGF5ZXJDb25maWcubWV0YWRhdGEuaWRlbnRpZmllcik7XG4gIH1cblxuICBuZ09uQ2hhbmdlcyhjaGFuZ2VzOiBTaW1wbGVDaGFuZ2VzKTogdm9pZCB7XG4gICAgaWYgKGNoYW5nZXMuYWN0aW9uKSB7XG4gICAgICBpZiAoIXRoaXMuc2hvd1F1bWxQbGF5ZXIpIHtcbiAgICAgICAgdGhpcy5wbGF5ZXJBY3Rpb24gPSB0aGlzLmFjdGlvbjtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICByYWlzZUludGVybmV0RGlzY29ubmVjdGlvbkVycm9yID0gKCkgPT4ge1xuICAgIGNvbnN0IGNvZGUgPSBlcnJvckNvZGUuaW50ZXJuZXRDb25uZWN0aXZpdHk7XG4gICAgY29uc3QgbWVzc2FnZSA9IGVycm9yTWVzc2FnZS5pbnRlcm5ldENvbm5lY3Rpdml0eTtcbiAgICBjb25zdCBzdGFja3RyYWNlID0gYCR7Y29kZX06ICR7bWVzc2FnZX1gO1xuICAgIHRoaXMudmlld2VyU2VydmljZS5yYWlzZUV4Y2VwdGlvbkxvZyhjb2RlLCBtZXNzYWdlLCBzdGFja3RyYWNlLCB0aGlzLnRyYWNlSWQpO1xuICB9XG5cbiAgbmdBZnRlclZpZXdJbml0KCkge1xuICAgIGNvbnN0IHZpZGVvUGxheWVyRWxlbWVudCA9IHRoaXMudmlkZW9QbGF5ZXJSZWYubmF0aXZlRWxlbWVudDtcbiAgICB0aGlzLnVubGlzdGVuTW91c2VNb3ZlID0gdGhpcy5yZW5kZXJlcjIubGlzdGVuKHZpZGVvUGxheWVyRWxlbWVudCwgJ21vdXNlbW92ZScsICgpID0+IHtcbiAgICAgIHRoaXMuc2hvd0NvbnRyb2xzID0gdHJ1ZTtcbiAgICB9KTtcblxuICAgIHRoaXMudW5saXN0ZW5Ub3VjaFN0YXJ0ID0gdGhpcy5yZW5kZXJlcjIubGlzdGVuKHZpZGVvUGxheWVyRWxlbWVudCwgJ3RvdWNoc3RhcnQnLCAoKSA9PiB7XG4gICAgICB0aGlzLnNob3dDb250cm9scyA9IHRydWU7XG4gICAgfSk7XG5cbiAgICBjb25zdCBjb250ZW50Q29tcGFiaWxpdHlMZXZlbCA9IHRoaXMucGxheWVyQ29uZmlnLm1ldGFkYXRhWydjb21wYXRpYmlsaXR5TGV2ZWwnXTtcbiAgICBpZiAoY29udGVudENvbXBhYmlsaXR5TGV2ZWwpIHtcbiAgICAgIGNvbnN0IGNoZWNrQ29udGVudENvbXBhdGlibGUgPSB0aGlzLmVycm9yU2VydmljZS5jaGVja0NvbnRlbnRDb21wYXRpYmlsaXR5KGNvbnRlbnRDb21wYWJpbGl0eUxldmVsKTtcbiAgICAgIGlmICghY2hlY2tDb250ZW50Q29tcGF0aWJsZVsnaXNDb21waXRhYmxlJ10pIHtcbiAgICAgICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOm1heC1saW5lLWxlbmd0aFxuICAgICAgICB0aGlzLnZpZXdlclNlcnZpY2UucmFpc2VFeGNlcHRpb25Mb2coZXJyb3JDb2RlLmNvbnRlbnRDb21wYXRpYmlsaXR5LCBlcnJvck1lc3NhZ2UuY29udGVudENvbXBhdGliaWxpdHksIGNoZWNrQ29udGVudENvbXBhdGlibGVbJ2Vycm9yJ11bJ21lc3NhZ2UnXSwgdGhpcy50cmFjZUlkKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBzaWRlQmFyRXZlbnRzKGV2ZW50OiBJU2lkZUJhckV2ZW50KSB7XG4gICAgdGhpcy5wbGF5ZXJFdmVudC5lbWl0KGV2ZW50KTtcbiAgICAvLyBjYXB0dXJpbmcgdGhpcyBldmVudCBmcm9tIGFwcCBjb2RlIGl0c2VsZlxuICAgIC8vIGlmIChldmVudC50eXBlID09PSAnRE9XTkxPQUQnKSB7XG4gICAgLy8gICB0aGlzLmRvd25sb2FkVmlkZW8oKTtcbiAgICAvLyB9XG4gICAgY29uc3QgZXZlbnRzID0gWydTSEFSRScsICdET1dOTE9BRF9NRU5VJywgJ0VYSVQnLCAnQ0xPU0VfTUVOVScsICdPUEVOX01FTlUnLCAnRE9XTkxPQURfUE9QVVBfQ0FOQ0VMJywgJ0RPV05MT0FEX1BPUFVQX0NMT1NFJ107XG4gICAgZXZlbnRzLmZvckVhY2goZGF0YSA9PiB7XG4gICAgICBpZiAoZXZlbnQudHlwZSA9PT0gZGF0YSkge1xuICAgICAgICB0aGlzLnZpZXdlclNlcnZpY2UucmFpc2VIZWFydEJlYXRFdmVudChkYXRhKTtcbiAgICAgIH1cbiAgICAgIGlmIChldmVudC50eXBlID09PSAnRVhJVCcpIHtcbiAgICAgICAgdGhpcy52aWV3ZXJTZXJ2aWNlLnNpZGViYXJNZW51RXZlbnQuZW1pdCgnQ0xPU0VfTUVOVScpO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgc2V0VGVsZW1ldHJ5T2JqZWN0Um9sbHVwKGlkKSB7XG4gICAgaWYgKHRoaXMuUXVtbFBsYXllckNvbmZpZy5jb250ZXh0KSB7XG4gICAgICBjb25zdCBoYXNPYmplY3RSb2xsdXAgPSB0aGlzLlF1bWxQbGF5ZXJDb25maWcgJiYgdGhpcy5RdW1sUGxheWVyQ29uZmlnLmNvbnRleHQgJiYgdGhpcy5RdW1sUGxheWVyQ29uZmlnLmNvbnRleHQub2JqZWN0Um9sbHVwO1xuICAgICAgaWYgKCFoYXNPYmplY3RSb2xsdXApIHtcbiAgICAgICAgdGhpcy5RdW1sUGxheWVyQ29uZmlnLmNvbnRleHQub2JqZWN0Um9sbHVwID0ge307XG4gICAgICB9XG4gICAgICBjb25zdCBsZXZlbHMgPSBPYmplY3Qua2V5cyh0aGlzLlF1bWxQbGF5ZXJDb25maWcuY29udGV4dC5vYmplY3RSb2xsdXApO1xuICAgICAgdGhpcy5RdW1sUGxheWVyQ29uZmlnLmNvbnRleHQub2JqZWN0Um9sbHVwW2BsJHtsZXZlbHMubGVuZ3RoICsgIDF9YF0gPSBpZDtcbiAgICB9XG4gIH1cblxuICBwbGF5Q29udGVudChldmVudCkge1xuICAgIHRoaXMudmlld2VyU2VydmljZS5yYWlzZUhlYXJ0QmVhdEV2ZW50KGV2ZW50LnR5cGUpO1xuICB9XG5cbiAgcmVwbGF5Q29udGVudChldmVudCkge1xuICAgIHRoaXMucGxheWVyRXZlbnQuZW1pdChldmVudCk7XG4gICAgdGhpcy52aWV3U3RhdGUgPSAncGxheWVyJztcbiAgICB0aGlzLnZpZXdlclNlcnZpY2UuaXNFbmRFdmVudFJhaXNlZCA9IGZhbHNlO1xuICAgIHRoaXMudmlld2VyU2VydmljZS5yYWlzZUhlYXJ0QmVhdEV2ZW50KCdSRVBMQVknKTtcbiAgfVxuXG4gIGV4aXRDb250ZW50KGV2ZW50KSB7XG4gICAgdGhpcy5wbGF5ZXJFdmVudC5lbWl0KGV2ZW50KTtcbiAgICB0aGlzLnZpZXdlclNlcnZpY2UucmFpc2VIZWFydEJlYXRFdmVudCgnRVhJVCcpO1xuICB9XG5cbiAgZG93bmxvYWRWaWRlbygpIHtcbiAgICBjb25zdCBhID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnYScpO1xuICAgIGEuaHJlZiA9IHRoaXMudmlld2VyU2VydmljZS5hcnRpZmFjdFVybDtcbiAgICBhLmRvd25sb2FkID0gdGhpcy52aWV3ZXJTZXJ2aWNlLmNvbnRlbnROYW1lO1xuICAgIGEudGFyZ2V0ID0gJ19ibGFuayc7XG4gICAgZG9jdW1lbnQuYm9keS5hcHBlbmRDaGlsZChhKTtcbiAgICBhLmNsaWNrKCk7XG4gICAgYS5yZW1vdmUoKTtcbiAgICB0aGlzLnZpZXdlclNlcnZpY2UucmFpc2VIZWFydEJlYXRFdmVudCgnRE9XTkxPQUQnKTtcbiAgfVxuXG4gIHF1bWxQbGF5ZXJFdmVudHMoZXZlbnQpIHtcbiAgICBpZiAoZXZlbnQuZWlkID09PSAnUVVNTF9TVU1NQVJZJykge1xuICAgICAgdGhpcy5zaG93UXVtbFBsYXllciA9IGZhbHNlO1xuICAgICAgY29uc3Qgc2NvcmUgPSBwYXJzZUludChldmVudC5lZGF0YS5leHRyYS5maW5kKHAgPT4gcC5pZCA9PT0gJ3Njb3JlJylbJ3ZhbHVlJ10sIDEwKTtcbiAgICAgIHRoaXMudmlld2VyU2VydmljZS5pbnRlcmNlcHRpb25SZXNwb25zZXNbdGhpcy5jdXJyZW50SW50ZXJjZXB0aW9uVGltZV0gPSB7XG4gICAgICAgIHNjb3JlLFxuICAgICAgICBpc1NraXBwZWQ6IGZhbHNlXG4gICAgICB9O1xuICAgICAgY29uc3QgaW50ZXJjZXB0UG9pbnRFbGVtZW50ID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcihgW2RhdGEtbWFya2VyLXRpbWU9XCIke3RoaXMuY3VycmVudEludGVyY2VwdGlvblRpbWV9XCJdYCk7XG4gICAgICBpZiAoaW50ZXJjZXB0UG9pbnRFbGVtZW50KSB7XG4gICAgICAgIGludGVyY2VwdFBvaW50RWxlbWVudFsnc3R5bGUnXS5iYWNrZ3JvdW5kID0gJ2dyZWVuJztcbiAgICAgIH1cbiAgICAgIHRoaXMudmlkZW9JbnN0YW5jZS5wbGF5KCk7XG4gICAgICB0aGlzLnZpZGVvSW5zdGFuY2UuY29udHJvbHModHJ1ZSk7XG4gICAgICB0aGlzLnZpZXdlclNlcnZpY2UucmFpc2VJbXByZXNzaW9uRXZlbnQoJ3ZpZGVvJyk7XG4gICAgICAvLyBpZiBjdXJyZW50bHkgdmlkZW8gaXMgbm90IGluIGZ1bGwgc2NyZWVuIGFuZCB3YXMgcHJldmlvdXNseSBmdWxsIHNjcmVlbiB0aGVuIHNldCBpdCBiYWNrIHRvIGZ1bGwgc2NyZWVuIGFnYWluXG4gICAgICBpZiAoIWRvY3VtZW50LmZ1bGxzY3JlZW5FbGVtZW50ICYmIHRoaXMuaXNGdWxsU2NyZWVuKSB7XG4gICAgICAgIGlmIChkb2N1bWVudC5nZXRFbGVtZW50c0J5Q2xhc3NOYW1lKCd2aWRlby1qcycpWzBdKSB7XG4gICAgICAgICAgZG9jdW1lbnQuZ2V0RWxlbWVudHNCeUNsYXNzTmFtZSgndmlkZW8tanMnKVswXS5yZXF1ZXN0RnVsbHNjcmVlbigpXG4gICAgICAgICAgLmNhdGNoKChlcnIpID0+IGNvbnNvbGUuZXJyb3IoZXJyKSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBxdWVzdGlvblNldERhdGEoe3Jlc3BvbnNlLCB0aW1lLCBpZGVudGlmaWVyfSkge1xuICAgIHRoaXMuUXVtbFBsYXllckNvbmZpZy5tZXRhZGF0YSA9IHJlc3BvbnNlO1xuICAgIHRoaXMuUXVtbFBsYXllckNvbmZpZy5tZXRhZGF0YVsnc2hvd1N0YXJ0UGFnZSddID0gJ05vJztcbiAgICB0aGlzLlF1bWxQbGF5ZXJDb25maWcubWV0YWRhdGFbJ3Nob3dFbmRQYWdlJ10gPSAnTm8nO1xuICAgIHRoaXMuY3VycmVudEludGVyY2VwdGlvblRpbWUgPSB0aW1lO1xuICAgIHRoaXMuY3VycmVudEludGVyY2VwdGlvblVJSWQgPSBpZGVudGlmaWVyO1xuICAgIGlmIChkb2N1bWVudC5mdWxsc2NyZWVuRWxlbWVudCkge1xuICAgICAgdGhpcy5pc0Z1bGxTY3JlZW4gPSB0cnVlO1xuICAgICAgZG9jdW1lbnQuZXhpdEZ1bGxzY3JlZW4oKVxuICAgICAgLmNhdGNoKChlcnIpID0+IGNvbnNvbGUuZXJyb3IoZXJyKSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuaXNGdWxsU2NyZWVuID0gZmFsc2U7XG4gICAgfVxuICAgIHRoaXMuc2hvd1F1bWxQbGF5ZXIgPSB0cnVlO1xuICAgIHRoaXMudmlld2VyU2VydmljZS5yYWlzZUltcHJlc3Npb25FdmVudCgnaW50ZXJhY3RpdmUtcXVlc3Rpb24tc2V0JywgeyBpZDogaWRlbnRpZmllciwgdHlwZTogJ1F1ZXN0aW9uU2V0JyB9KTtcbiAgICB0aGlzLnZpZXdlclNlcnZpY2UucmFpc2VIZWFydEJlYXRFdmVudCgnVklERU9fTUFSS0VSX1NFTEVDVEVEJywge1xuICAgICAgaWRlbnRpZmllciwgLy8gUXVlc3Rpb24gc2V0IGlkLFxuICAgICAgdHlwZTogJ1F1ZXN0aW9uU2V0JywgLy8gVHlwZSBvZiBpbnRlcmFjdGlvblxuICAgICAgaW50ZXJjZXB0ZWRBdDogdGltZSAvLyBUaW1lIHdoZW4gdGhlIGludGVyY2VwdGlvbiBoYXBwZW5lZFxuICAgIH0pO1xuICB9XG5cbiAgcGxheWVySW5zdGFuY2UoZXZlbnQpIHtcbiAgICB0aGlzLnZpZGVvSW5zdGFuY2UgPSBldmVudDtcbiAgfVxuXG4gIEBIb3N0TGlzdGVuZXIoJ3dpbmRvdzpiZWZvcmV1bmxvYWQnKVxuICBuZ09uRGVzdHJveSgpIHtcbiAgICB0aGlzLnZpZXdlclNlcnZpY2UucmFpc2VFbmRFdmVudCgpO1xuICAgIHRoaXMudW5saXN0ZW5Ub3VjaFN0YXJ0KCk7XG4gICAgdGhpcy51bmxpc3Rlbk1vdXNlTW92ZSgpO1xuICAgIHRoaXMudmlld2VyU2VydmljZS5pc0VuZEV2ZW50UmFpc2VkID0gZmFsc2U7XG4gICAgd2luZG93LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ29mZmxpbmUnLCB0aGlzLnJhaXNlSW50ZXJuZXREaXNjb25uZWN0aW9uRXJyb3IgLCB0cnVlKTtcbiAgfVxufVxuIl19