ngx-doc-viewer2
Version:
Angular document viewer.
217 lines • 30 kB
JavaScript
import { __awaiter } from "tslib";
import { Component, Input, NgZone, Output, ViewChildren } from '@angular/core';
import { DomSanitizer } from '@angular/platform-browser';
import { take } from 'rxjs/operators';
import { timer } from 'rxjs';
import { EventEmitter } from '@angular/core';
export class NgxDocViewerComponent {
constructor(domSanitizer, ngZone) {
this.domSanitizer = domSanitizer;
this.ngZone = ngZone;
this.loaded = new EventEmitter();
this.url = '';
this.queryParams = '';
this.viewerUrl = '';
this.googleCheckInterval = 3000;
this.disableContent = 'none';
this.googleCheckContentLoaded = true;
this.fullUrl = null;
this.externalViewer = false;
this.docHtml = '';
this.configuredViewer = 'google';
this.checkIFrameSubscription = null;
}
ngOnDestroy() {
if (this.checkIFrameSubscription) {
this.checkIFrameSubscription.unsubscribe();
}
}
ngOnChanges(changes) {
return __awaiter(this, void 0, void 0, function* () {
if (changes && changes.viewer && (changes.viewer.isFirstChange || changes.viewer.currentValue !== changes.viewer.previousValue)) {
if (this.viewer !== 'google' && this.viewer !== 'office' &&
this.viewer !== 'mammoth' && this.viewer !== 'pdf' && this.viewer !== 'url') {
console.error(`Unsupported viewer: '${this.viewer}'. Supported viewers: google, office, mammoth and pdf`);
}
if (this.viewer === 'mammoth') {
if (mammoth === null) {
console.error('please install mammoth when using local viewer');
}
}
this.configuredViewer = this.viewer;
}
if (this.disableContent !== 'none' && this.viewer !== 'google') {
}
if ((changes.url && changes.url.currentValue !== changes.url.previousValue) ||
changes.viewer && changes.viewer.currentValue !== changes.viewer.previousValue ||
changes.viewerUrl && changes.viewerUrl.currentValue !== changes.viewerUrl.previousValue) {
if (!changes.viewerUrl) {
this.viewerUrl = null;
}
switch (this.configuredViewer) {
case 'google':
this.viewerUrl = `https://docs.google.com/gview?url=%URL%&embedded=true`;
break;
case 'office': {
this.viewerUrl = `https://view.officeapps.live.com/op/embed.aspx?src=%URL%`;
break;
}
case 'pdf': {
this.viewerUrl = null;
break;
}
}
this.docHtml = '';
this.externalViewer = this.configuredViewer === 'google' || this.configuredViewer === 'office' ||
this.configuredViewer === 'url';
if (this.checkIFrameSubscription) {
this.checkIFrameSubscription.unsubscribe();
}
if (!this.url) {
this.fullUrl = null;
}
else if (this.configuredViewer === 'office' || this.configuredViewer === 'google'
|| this.configuredViewer === 'pdf' || this.configuredViewer === 'url') {
const u = this.url.indexOf('/') ? encodeURIComponent(this.url) : this.url;
let url = this.viewerUrl ? this.viewerUrl.replace('%URL%', u) : this.url;
if (!!this.queryParams && this.configuredViewer !== 'pdf') {
const start = this.queryParams.startsWith('&') ? '' : '&';
url = `${url}${start}${this.queryParams}`;
}
this.fullUrl = this.domSanitizer.bypassSecurityTrustResourceUrl(url);
// see:
// https://stackoverflow.com/questions/40414039/google-docs-viewer-returning-204-responses-no-longer-working-alternatives
// hack to reload iframe if it's not loaded.
// would maybe be better to use view.officeapps.live.com but seems not to work with sas token.
if (this.configuredViewer === 'google' && this.googleCheckContentLoaded) {
this.ngZone.runOutsideAngular(() => {
console.log('NGDOC:>>outside');
// if it's not loaded after the googleIntervalCheck, then open load again.
this.checkIFrameSubscription = timer(500, this.googleCheckInterval)
.pipe(take(Math.round(this.googleCheckInterval === 0 ? 0 : 20000 / this.googleCheckInterval)))
.subscribe(() => {
var _a, _b;
console.log('NGDOC:>>checking again');
const iframe = (_b = (_a = this.iframes) === null || _a === void 0 ? void 0 : _a.first) === null || _b === void 0 ? void 0 : _b.nativeElement;
this.reloadIFrame(iframe);
});
});
}
}
else if (this.configuredViewer === 'mammoth') {
if (!mammoth) {
console.error('Please install mammoth and make sure mammoth.browser.min.js is loaded.');
}
this.docHtml = yield this.getDocxToHtml(this.url);
}
}
});
}
iframeLoaded() {
var _a, _b;
this.loaded.emit(null);
if (this.checkIFrameSubscription) {
const iframe = (_b = (_a = this.iframes) === null || _a === void 0 ? void 0 : _a.first) === null || _b === void 0 ? void 0 : _b.nativeElement;
if (iframe) {
this.loaded.emit(true);
this.checkIFrameSubscription.unsubscribe();
}
}
}
reloadIFrame(iframe) {
if (iframe) {
let src = iframe.src;
iframe.src = iframe.src;
setTimeout(() => {
iframe.src = src;
}, 100);
}
}
getDocxToHtml(url) {
return __awaiter(this, void 0, void 0, function* () {
const arrayBuffer = yield this.fileToArray(url);
const resultObject = yield mammoth.convertToHtml({ arrayBuffer });
return resultObject.value;
});
}
fileToArray(url) {
return new Promise((resolve, reject) => {
try {
const request = new XMLHttpRequest();
request.open('GET', url, true);
request.responseType = 'blob';
request.onload = () => {
const reader = new FileReader();
reader.readAsArrayBuffer(request.response);
reader.onloadend = (e) => {
resolve(reader.result);
};
};
request.send();
}
catch (_a) {
reject(`error while retrieving file ${url}.`);
}
});
}
}
NgxDocViewerComponent.decorators = [
{ type: Component, args: [{
// eslint-disable-next-line @angular-eslint/component-selector
selector: 'ngx-doc-viewer',
template: "<ng-container *ngIf=\"!externalViewer\">\r\n <div *ngIf=\"configuredViewer !== 'pdf'\" [innerHtml]=\"docHtml\"></div>\r\n <object *ngIf=\"fullUrl && configuredViewer === 'pdf'\" [data]=\"fullUrl\"\r\n type=\"application/pdf\" width=\"100%\" height=\"100%\">\r\n <p>Your browser does not support PDFs.\r\n <a [href]=\"fullUrl\">Download the PDF</a>.</p>\r\n </object>\r\n</ng-container>\r\n<ng-container *ngIf=\"externalViewer\">\r\n <iframe (load)=\"iframeLoaded()\" *ngIf=\"fullUrl && disableContent === 'none'\" #iframe id=\"iframe\" frameBorder=\"0\" [src]=\"fullUrl\"></iframe>\r\n <div class=\"container\" *ngIf=\"disableContent !== 'none'\">\r\n <div [class.overlay-full]=\"disableContent === 'all'\"\r\n [class.overlay-popout-google]=\"configuredViewer ==='google' && (disableContent === 'popout' || disableContent === 'popout-hide')\"\r\n [class.overlay-popout-office]=\"configuredViewer ==='office' && (disableContent === 'popout' || disableContent === 'popout-hide')\"\r\n [style.background-color]=\"disableContent === 'popout-hide' ? '#fff': 'transparent'\">\r\n </div>\r\n <iframe (load)=\"iframeLoaded()\" *ngIf=\"fullUrl\" #iframe id=\"iframe\" frameBorder=\"0\" [src]=\"fullUrl\"></iframe>\r\n </div>\r\n</ng-container>",
styles: [`:host {
display: block;
}
.container {
width: 100%;
height: 100%;
position: relative;
}
.overlay-popout-google {
width: 40px;
height: 40px;
right: 26px;
top: 11.5px;
position: absolute;
z-index: 1000;
}
.overlay-popout-office {
width: 100px;
height: 20px;
right: 0;
bottom: 0;
position: absolute;
z-index: 1000;
}
.overlay-full {
width: 100%;
height: 100%;
right: 0;
top: 0;
position: absolute;
z-index: 1000;
}
iframe {
width: 100%;
height: 100%;
}
`]
},] }
];
NgxDocViewerComponent.ctorParameters = () => [
{ type: DomSanitizer },
{ type: NgZone }
];
NgxDocViewerComponent.propDecorators = {
loaded: [{ type: Output }],
url: [{ type: Input }],
queryParams: [{ type: Input }],
viewerUrl: [{ type: Input }],
googleCheckInterval: [{ type: Input }],
disableContent: [{ type: Input }],
googleCheckContentLoaded: [{ type: Input }],
viewer: [{ type: Input }],
iframes: [{ type: ViewChildren, args: ['iframe',] }]
};
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZG9jdW1lbnQtdmlld2VyLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIuLi8uLi8uLi9tb2R1bGVzLyIsInNvdXJjZXMiOlsiZG9jdW1lbnQtdmlld2VyLmNvbXBvbmVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUEsT0FBTyxFQUFFLFNBQVMsRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUF1QyxNQUFNLEVBQUUsWUFBWSxFQUF5QixNQUFNLGVBQWUsQ0FBQztBQUMzSSxPQUFPLEVBQUUsWUFBWSxFQUFtQixNQUFNLDJCQUEyQixDQUFDO0FBQzFFLE9BQU8sRUFBRSxJQUFJLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUN0QyxPQUFPLEVBQTBCLEtBQUssRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUNyRCxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBaUQ3QyxNQUFNLE9BQU8scUJBQXFCO0lBaUI5QixZQUFvQixZQUEwQixFQUFVLE1BQWM7UUFBbEQsaUJBQVksR0FBWixZQUFZLENBQWM7UUFBVSxXQUFNLEdBQU4sTUFBTSxDQUFRO1FBaEI1RCxXQUFNLEdBQXNCLElBQUksWUFBWSxFQUFFLENBQUM7UUFDaEQsUUFBRyxHQUFHLEVBQUUsQ0FBQztRQUNULGdCQUFXLEdBQUcsRUFBRSxDQUFDO1FBQ2pCLGNBQVMsR0FBRyxFQUFFLENBQUM7UUFDZix3QkFBbUIsR0FBRyxJQUFJLENBQUM7UUFDM0IsbUJBQWMsR0FBOEMsTUFBTSxDQUFDO1FBQ25FLDZCQUF3QixHQUFHLElBQUksQ0FBQztRQUlsQyxZQUFPLEdBQW9CLElBQUksQ0FBQztRQUNoQyxtQkFBYyxHQUFHLEtBQUssQ0FBQztRQUN2QixZQUFPLEdBQUcsRUFBRSxDQUFDO1FBQ2IscUJBQWdCLEdBQWUsUUFBUSxDQUFDO1FBQ3ZDLDRCQUF1QixHQUFpQixJQUFJLENBQUM7SUFFcUIsQ0FBQztJQUUzRSxXQUFXO1FBQ1AsSUFBSSxJQUFJLENBQUMsdUJBQXVCLEVBQUU7WUFDOUIsSUFBSSxDQUFDLHVCQUF1QixDQUFDLFdBQVcsRUFBRSxDQUFDO1NBQzlDO0lBQ0wsQ0FBQztJQUVLLFdBQVcsQ0FBQyxPQUFzQjs7WUFDcEMsSUFBSSxPQUFPLElBQUksT0FBTyxDQUFDLE1BQU0sSUFBSSxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsYUFBYSxJQUFJLE9BQU8sQ0FBQyxNQUFNLENBQUMsWUFBWSxLQUFLLE9BQU8sQ0FBQyxNQUFNLENBQUMsYUFBYSxDQUFDLEVBQUU7Z0JBQzdILElBQUksSUFBSSxDQUFDLE1BQU0sS0FBSyxRQUFRLElBQUksSUFBSSxDQUFDLE1BQU0sS0FBSyxRQUFRO29CQUNwRCxJQUFJLENBQUMsTUFBTSxLQUFLLFNBQVMsSUFBSSxJQUFJLENBQUMsTUFBTSxLQUFLLEtBQUssSUFBSSxJQUFJLENBQUMsTUFBTSxLQUFLLEtBQUssRUFBRTtvQkFDN0UsT0FBTyxDQUFDLEtBQUssQ0FBQyx3QkFBd0IsSUFBSSxDQUFDLE1BQU0sdURBQXVELENBQUMsQ0FBQztpQkFDN0c7Z0JBQ0QsSUFBSSxJQUFJLENBQUMsTUFBTSxLQUFLLFNBQVMsRUFBRTtvQkFDM0IsSUFBSSxPQUFPLEtBQUssSUFBSSxFQUFFO3dCQUNsQixPQUFPLENBQUMsS0FBSyxDQUFDLGdEQUFnRCxDQUFDLENBQUM7cUJBQ25FO2lCQUNKO2dCQUNELElBQUksQ0FBQyxnQkFBZ0IsR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDO2FBQ3ZDO1lBQ0QsSUFBSSxJQUFJLENBQUMsY0FBYyxLQUFLLE1BQU0sSUFBSSxJQUFJLENBQUMsTUFBTSxLQUFLLFFBQVEsRUFBRTthQUMvRDtZQUNELElBQUksQ0FBQyxPQUFPLENBQUMsR0FBRyxJQUFJLE9BQU8sQ0FBQyxHQUFHLENBQUMsWUFBWSxLQUFLLE9BQU8sQ0FBQyxHQUFHLENBQUMsYUFBYSxDQUFDO2dCQUN2RSxPQUFPLENBQUMsTUFBTSxJQUFJLE9BQU8sQ0FBQyxNQUFNLENBQUMsWUFBWSxLQUFLLE9BQU8sQ0FBQyxNQUFNLENBQUMsYUFBYTtnQkFDOUUsT0FBTyxDQUFDLFNBQVMsSUFBSSxPQUFPLENBQUMsU0FBUyxDQUFDLFlBQVksS0FBSyxPQUFPLENBQUMsU0FBUyxDQUFDLGFBQWEsRUFBRTtnQkFDekYsSUFBSSxDQUFDLE9BQU8sQ0FBQyxTQUFTLEVBQUU7b0JBQ3BCLElBQUksQ0FBQyxTQUFTLEdBQUcsSUFBSSxDQUFDO2lCQUN6QjtnQkFDRCxRQUFRLElBQUksQ0FBQyxnQkFBZ0IsRUFBRTtvQkFDM0IsS0FBSyxRQUFRO3dCQUNULElBQUksQ0FBQyxTQUFTLEdBQUcsdURBQXVELENBQUM7d0JBQ3pFLE1BQU07b0JBQ1YsS0FBSyxRQUFRLENBQUMsQ0FBQzt3QkFDWCxJQUFJLENBQUMsU0FBUyxHQUFHLDBEQUEwRCxDQUFDO3dCQUM1RSxNQUFNO3FCQUNUO29CQUNELEtBQUssS0FBSyxDQUFDLENBQUM7d0JBQ1IsSUFBSSxDQUFDLFNBQVMsR0FBRyxJQUFJLENBQUM7d0JBQ3RCLE1BQU07cUJBQ1Q7aUJBQ0o7Z0JBQ0QsSUFBSSxDQUFDLE9BQU8sR0FBRyxFQUFFLENBQUM7Z0JBQ2xCLElBQUksQ0FBQyxjQUFjLEdBQUcsSUFBSSxDQUFDLGdCQUFnQixLQUFLLFFBQVEsSUFBSSxJQUFJLENBQUMsZ0JBQWdCLEtBQUssUUFBUTtvQkFDMUYsSUFBSSxDQUFDLGdCQUFnQixLQUFLLEtBQUssQ0FBQztnQkFDcEMsSUFBSSxJQUFJLENBQUMsdUJBQXVCLEVBQUU7b0JBQzlCLElBQUksQ0FBQyx1QkFBdUIsQ0FBQyxXQUFXLEVBQUUsQ0FBQztpQkFDOUM7Z0JBQ0QsSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLEVBQUU7b0JBQ1gsSUFBSSxDQUFDLE9BQU8sR0FBRyxJQUFJLENBQUM7aUJBQ3ZCO3FCQUFNLElBQUksSUFBSSxDQUFDLGdCQUFnQixLQUFLLFFBQVEsSUFBSSxJQUFJLENBQUMsZ0JBQWdCLEtBQUssUUFBUTt1QkFDNUUsSUFBSSxDQUFDLGdCQUFnQixLQUFLLEtBQUssSUFBSSxJQUFJLENBQUMsZ0JBQWdCLEtBQUssS0FBSyxFQUFFO29CQUN2RSxNQUFNLENBQUMsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsa0JBQWtCLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDO29CQUMxRSxJQUFJLEdBQUcsR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLE9BQU8sQ0FBQyxPQUFPLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUM7b0JBQ3pFLElBQUksQ0FBQyxDQUFDLElBQUksQ0FBQyxXQUFXLElBQUksSUFBSSxDQUFDLGdCQUFnQixLQUFLLEtBQUssRUFBRTt3QkFDdkQsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLFdBQVcsQ0FBQyxVQUFVLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDO3dCQUMxRCxHQUFHLEdBQUcsR0FBRyxHQUFHLEdBQUcsS0FBSyxHQUFHLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQztxQkFDN0M7b0JBQ0QsSUFBSSxDQUFDLE9BQU8sR0FBRyxJQUFJLENBQUMsWUFBWSxDQUFDLDhCQUE4QixDQUFDLEdBQUcsQ0FBQyxDQUFDO29CQUNyRSxPQUFPO29CQUNQLHlIQUF5SDtvQkFDekgsNENBQTRDO29CQUM1Qyw4RkFBOEY7b0JBQzlGLElBQUksSUFBSSxDQUFDLGdCQUFnQixLQUFLLFFBQVEsSUFBSSxJQUFJLENBQUMsd0JBQXdCLEVBQUU7d0JBQ3JFLElBQUksQ0FBQyxNQUFNLENBQUMsaUJBQWlCLENBQUMsR0FBRyxFQUFFOzRCQUNqQyxPQUFPLENBQUMsR0FBRyxDQUFDLGlCQUFpQixDQUFDLENBQUM7NEJBQzdCLDBFQUEwRTs0QkFDMUUsSUFBSSxDQUFDLHVCQUF1QixHQUFHLEtBQUssQ0FBQyxHQUFHLEVBQUUsSUFBSSxDQUFDLG1CQUFtQixDQUFDO2lDQUM5RCxJQUFJLENBQ0QsSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLG1CQUFtQixLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDLG1CQUFtQixDQUFDLENBQUMsQ0FBQztpQ0FDM0YsU0FBUyxDQUFDLEdBQUcsRUFBRTs7Z0NBQ2QsT0FBTyxDQUFDLEdBQUcsQ0FBQyx3QkFBd0IsQ0FBQyxDQUFDO2dDQUNwQyxNQUFNLE1BQU0sZUFBRyxJQUFJLENBQUMsT0FBTywwQ0FBRSxLQUFLLDBDQUFFLGFBQWEsQ0FBQztnQ0FDbEQsSUFBSSxDQUFDLFlBQVksQ0FBQyxNQUFNLENBQUMsQ0FBQzs0QkFDOUIsQ0FBQyxDQUFDLENBQUM7d0JBQ1gsQ0FBQyxDQUFDLENBQUM7cUJBQ047aUJBQ0o7cUJBQU0sSUFBSSxJQUFJLENBQUMsZ0JBQWdCLEtBQUssU0FBUyxFQUFFO29CQUM1QyxJQUFJLENBQUMsT0FBTyxFQUFFO3dCQUNWLE9BQU8sQ0FBQyxLQUFLLENBQUMsd0VBQXdFLENBQUMsQ0FBQztxQkFDM0Y7b0JBQ0QsSUFBSSxDQUFDLE9BQU8sR0FBRyxNQUFNLElBQUksQ0FBQyxhQUFhLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDO2lCQUNyRDthQUNKO1FBQ0wsQ0FBQztLQUFBO0lBRUQsWUFBWTs7UUFDUixJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUN2QixJQUFJLElBQUksQ0FBQyx1QkFBdUIsRUFBRTtZQUNoQyxNQUFNLE1BQU0sZUFBRyxJQUFJLENBQUMsT0FBTywwQ0FBRSxLQUFLLDBDQUFFLGFBQWEsQ0FBQztZQUNsRCxJQUFJLE1BQU0sRUFBRTtnQkFDVixJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztnQkFDdkIsSUFBSSxDQUFDLHVCQUF1QixDQUFDLFdBQVcsRUFBRSxDQUFDO2FBQzVDO1NBQ0Y7SUFDTCxDQUFDO0lBRUQsWUFBWSxDQUFDLE1BQXlCO1FBQ2xDLElBQUksTUFBTSxFQUFFO1lBQ1IsSUFBSSxHQUFHLEdBQUcsTUFBTSxDQUFDLEdBQUcsQ0FBQTtZQUNwQixNQUFNLENBQUMsR0FBRyxHQUFHLE1BQU0sQ0FBQyxHQUFHLENBQUM7WUFDeEIsVUFBVSxDQUFDLEdBQUcsRUFBRTtnQkFDZCxNQUFNLENBQUMsR0FBRyxHQUFHLEdBQUcsQ0FBQTtZQUNsQixDQUFDLEVBQUUsR0FBRyxDQUFDLENBQUE7U0FDVjtJQUNMLENBQUM7SUFFYSxhQUFhLENBQUMsR0FBVzs7WUFDbkMsTUFBTSxXQUFXLEdBQUcsTUFBTSxJQUFJLENBQUMsV0FBVyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1lBQ2hELE1BQU0sWUFBWSxHQUFHLE1BQU0sT0FBTyxDQUFDLGFBQWEsQ0FBQyxFQUFFLFdBQVcsRUFBRSxDQUFDLENBQUM7WUFDbEUsT0FBTyxZQUFZLENBQUMsS0FBSyxDQUFDO1FBQzlCLENBQUM7S0FBQTtJQUVPLFdBQVcsQ0FBQyxHQUFXO1FBQzNCLE9BQU8sSUFBSSxPQUFPLENBQWMsQ0FBQyxPQUFPLEVBQUUsTUFBTSxFQUFFLEVBQUU7WUFDaEQsSUFBSTtnQkFDQSxNQUFNLE9BQU8sR0FBRyxJQUFJLGNBQWMsRUFBRSxDQUFDO2dCQUNyQyxPQUFPLENBQUMsSUFBSSxDQUFDLEtBQUssRUFBRSxHQUFHLEVBQUUsSUFBSSxDQUFDLENBQUM7Z0JBQy9CLE9BQU8sQ0FBQyxZQUFZLEdBQUcsTUFBTSxDQUFDO2dCQUM5QixPQUFPLENBQUMsTUFBTSxHQUFHLEdBQUcsRUFBRTtvQkFDbEIsTUFBTSxNQUFNLEdBQUcsSUFBSSxVQUFVLEVBQUUsQ0FBQztvQkFDaEMsTUFBTSxDQUFDLGlCQUFpQixDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUMsQ0FBQztvQkFDM0MsTUFBTSxDQUFDLFNBQVMsR0FBRyxDQUFDLENBQUMsRUFBRSxFQUFFO3dCQUNyQixPQUFPLENBQUMsTUFBTSxDQUFDLE1BQXFCLENBQUMsQ0FBQztvQkFDMUMsQ0FBQyxDQUFDO2dCQUNOLENBQUMsQ0FBQztnQkFDRixPQUFPLENBQUMsSUFBSSxFQUFFLENBQUM7YUFDbEI7WUFBQyxXQUFNO2dCQUNKLE1BQU0sQ0FBQywrQkFBK0IsR0FBRyxHQUFHLENBQUMsQ0FBQzthQUNqRDtRQUNMLENBQUMsQ0FBQyxDQUFDO0lBQ1AsQ0FBQzs7O1lBOUxKLFNBQVMsU0FBQztnQkFDUCw4REFBOEQ7Z0JBQzlELFFBQVEsRUFBRSxnQkFBZ0I7Z0JBQzFCLCt6Q0FBNkM7eUJBQ3BDOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7S0FvQ1I7YUFDSjs7O1lBbkRRLFlBQVk7WUFETSxNQUFNOzs7cUJBc0Q1QixNQUFNO2tCQUNOLEtBQUs7MEJBQ0wsS0FBSzt3QkFDTCxLQUFLO2tDQUNMLEtBQUs7NkJBQ0wsS0FBSzt1Q0FDTCxLQUFLO3FCQUNMLEtBQUs7c0JBQ0wsWUFBWSxTQUFDLFFBQVEiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21wb25lbnQsIElucHV0LCBOZ1pvbmUsIE9uRGVzdHJveSwgT25DaGFuZ2VzLCBTaW1wbGVDaGFuZ2VzLCBPdXRwdXQsIFZpZXdDaGlsZHJlbiwgUXVlcnlMaXN0LCBFbGVtZW50UmVmIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcbmltcG9ydCB7IERvbVNhbml0aXplciwgU2FmZVJlc291cmNlVXJsIH0gZnJvbSAnQGFuZ3VsYXIvcGxhdGZvcm0tYnJvd3Nlcic7XHJcbmltcG9ydCB7IHRha2UgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XHJcbmltcG9ydCB7IFN1YnNjcmlwdGlvbiwgaW50ZXJ2YWwsIHRpbWVyIH0gZnJvbSAncnhqcyc7XHJcbmltcG9ydCB7IEV2ZW50RW1pdHRlciB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5cclxuLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXZhclxyXG5kZWNsYXJlIHZhciBtYW1tb3RoO1xyXG5cclxuLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uYW1pbmctY29udmVudGlvblxyXG5leHBvcnQgdHlwZSB2aWV3ZXJUeXBlID0gJ2dvb2dsZScgfCAnb2ZmaWNlJyB8ICdtYW1tb3RoJyB8ICdwZGYnIHwgJ3VybCc7XHJcbkBDb21wb25lbnQoe1xyXG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEBhbmd1bGFyLWVzbGludC9jb21wb25lbnQtc2VsZWN0b3JcclxuICAgIHNlbGVjdG9yOiAnbmd4LWRvYy12aWV3ZXInLFxyXG4gICAgdGVtcGxhdGVVcmw6ICdkb2N1bWVudC12aWV3ZXIuY29tcG9uZW50Lmh0bWwnLFxyXG4gICAgc3R5bGVzOiBbYDpob3N0IHtcclxuICAgICAgICBkaXNwbGF5OiBibG9jaztcclxuICAgIH1cclxuICAgIC5jb250YWluZXIge1xyXG4gICAgICAgIHdpZHRoOiAxMDAlO1xyXG4gICAgICAgIGhlaWdodDogMTAwJTtcclxuICAgICAgICBwb3NpdGlvbjogcmVsYXRpdmU7XHJcbiAgICB9XHJcbiAgICAub3ZlcmxheS1wb3BvdXQtZ29vZ2xlIHtcclxuICAgICAgICB3aWR0aDogNDBweDtcclxuICAgICAgICBoZWlnaHQ6IDQwcHg7XHJcbiAgICAgICAgcmlnaHQ6IDI2cHg7XHJcbiAgICAgICAgdG9wOiAxMS41cHg7XHJcbiAgICAgICAgcG9zaXRpb246IGFic29sdXRlO1xyXG4gICAgICAgIHotaW5kZXg6IDEwMDA7XHJcbiAgICB9XHJcbiAgICAub3ZlcmxheS1wb3BvdXQtb2ZmaWNlIHtcclxuICAgICAgICB3aWR0aDogMTAwcHg7XHJcbiAgICAgICAgaGVpZ2h0OiAyMHB4O1xyXG4gICAgICAgIHJpZ2h0OiAwO1xyXG4gICAgICAgIGJvdHRvbTogMDtcclxuICAgICAgICBwb3NpdGlvbjogYWJzb2x1dGU7XHJcbiAgICAgICAgei1pbmRleDogMTAwMDtcclxuICAgIH1cclxuICAgIC5vdmVybGF5LWZ1bGwge1xyXG4gICAgICAgIHdpZHRoOiAxMDAlO1xyXG4gICAgICAgIGhlaWdodDogMTAwJTtcclxuICAgICAgICByaWdodDogMDtcclxuICAgICAgICB0b3A6IDA7XHJcbiAgICAgICAgcG9zaXRpb246IGFic29sdXRlO1xyXG4gICAgICAgIHotaW5kZXg6IDEwMDA7XHJcbiAgICB9XHJcbiAgICBpZnJhbWUge1xyXG4gICAgICAgIHdpZHRoOiAxMDAlO1xyXG4gICAgICAgIGhlaWdodDogMTAwJTtcclxuICAgIH1cclxuICAgIGBdXHJcbn0pXHJcbmV4cG9ydCBjbGFzcyBOZ3hEb2NWaWV3ZXJDb21wb25lbnQgaW1wbGVtZW50cyBPbkNoYW5nZXMsIE9uRGVzdHJveSB7XHJcbiAgICBAT3V0cHV0KCkgbG9hZGVkOiBFdmVudEVtaXR0ZXI8YW55PiA9IG5ldyBFdmVudEVtaXR0ZXIoKTtcclxuICAgIEBJbnB1dCgpIHVybCA9ICcnO1xyXG4gICAgQElucHV0KCkgcXVlcnlQYXJhbXMgPSAnJztcclxuICAgIEBJbnB1dCgpIHZpZXdlclVybCA9ICcnO1xyXG4gICAgQElucHV0KCkgZ29vZ2xlQ2hlY2tJbnRlcnZhbCA9IDMwMDA7XHJcbiAgICBASW5wdXQoKSBkaXNhYmxlQ29udGVudDogJ25vbmUnIHwgJ2FsbCcgfCAncG9wb3V0JyB8ICdwb3BvdXQtaGlkZScgPSAnbm9uZSc7XHJcbiAgICBASW5wdXQoKSBnb29nbGVDaGVja0NvbnRlbnRMb2FkZWQgPSB0cnVlO1xyXG4gICAgQElucHV0KCkgdmlld2VyOiB2aWV3ZXJUeXBlO1xyXG4gICAgQFZpZXdDaGlsZHJlbignaWZyYW1lJykgaWZyYW1lczogUXVlcnlMaXN0PEVsZW1lbnRSZWY+O1xyXG5cclxuICAgIHB1YmxpYyBmdWxsVXJsOiBTYWZlUmVzb3VyY2VVcmwgPSBudWxsO1xyXG4gICAgcHVibGljIGV4dGVybmFsVmlld2VyID0gZmFsc2U7XHJcbiAgICBwdWJsaWMgZG9jSHRtbCA9ICcnO1xyXG4gICAgcHVibGljIGNvbmZpZ3VyZWRWaWV3ZXI6IHZpZXdlclR5cGUgPSAnZ29vZ2xlJztcclxuICAgIHByaXZhdGUgY2hlY2tJRnJhbWVTdWJzY3JpcHRpb246IFN1YnNjcmlwdGlvbiA9IG51bGw7XHJcblxyXG4gICAgY29uc3RydWN0b3IocHJpdmF0ZSBkb21TYW5pdGl6ZXI6IERvbVNhbml0aXplciwgcHJpdmF0ZSBuZ1pvbmU6IE5nWm9uZSkgeyB9XHJcblxyXG4gICAgbmdPbkRlc3Ryb3koKTogdm9pZCB7XHJcbiAgICAgICAgaWYgKHRoaXMuY2hlY2tJRnJhbWVTdWJzY3JpcHRpb24pIHtcclxuICAgICAgICAgICAgdGhpcy5jaGVja0lGcmFtZVN1YnNjcmlwdGlvbi51bnN1YnNjcmliZSgpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBhc3luYyBuZ09uQ2hhbmdlcyhjaGFuZ2VzOiBTaW1wbGVDaGFuZ2VzKTogUHJvbWlzZTx2b2lkPiB7XHJcbiAgICAgICAgaWYgKGNoYW5nZXMgJiYgY2hhbmdlcy52aWV3ZXIgJiYgKGNoYW5nZXMudmlld2VyLmlzRmlyc3RDaGFuZ2UgfHwgY2hhbmdlcy52aWV3ZXIuY3VycmVudFZhbHVlICE9PSBjaGFuZ2VzLnZpZXdlci5wcmV2aW91c1ZhbHVlKSkge1xyXG4gICAgICAgICAgICBpZiAodGhpcy52aWV3ZXIgIT09ICdnb29nbGUnICYmIHRoaXMudmlld2VyICE9PSAnb2ZmaWNlJyAmJlxyXG4gICAgICAgICAgICAgICAgdGhpcy52aWV3ZXIgIT09ICdtYW1tb3RoJyAmJiB0aGlzLnZpZXdlciAhPT0gJ3BkZicgJiYgdGhpcy52aWV3ZXIgIT09ICd1cmwnKSB7XHJcbiAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKGBVbnN1cHBvcnRlZCB2aWV3ZXI6ICcke3RoaXMudmlld2VyfScuIFN1cHBvcnRlZCB2aWV3ZXJzOiBnb29nbGUsIG9mZmljZSwgbWFtbW90aCBhbmQgcGRmYCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgaWYgKHRoaXMudmlld2VyID09PSAnbWFtbW90aCcpIHtcclxuICAgICAgICAgICAgICAgIGlmIChtYW1tb3RoID09PSBudWxsKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcigncGxlYXNlIGluc3RhbGwgbWFtbW90aCB3aGVuIHVzaW5nIGxvY2FsIHZpZXdlcicpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHRoaXMuY29uZmlndXJlZFZpZXdlciA9IHRoaXMudmlld2VyO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAodGhpcy5kaXNhYmxlQ29udGVudCAhPT0gJ25vbmUnICYmIHRoaXMudmlld2VyICE9PSAnZ29vZ2xlJykge1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAoKGNoYW5nZXMudXJsICYmIGNoYW5nZXMudXJsLmN1cnJlbnRWYWx1ZSAhPT0gY2hhbmdlcy51cmwucHJldmlvdXNWYWx1ZSkgfHxcclxuICAgICAgICAgICAgY2hhbmdlcy52aWV3ZXIgJiYgY2hhbmdlcy52aWV3ZXIuY3VycmVudFZhbHVlICE9PSBjaGFuZ2VzLnZpZXdlci5wcmV2aW91c1ZhbHVlIHx8XHJcbiAgICAgICAgICAgIGNoYW5nZXMudmlld2VyVXJsICYmIGNoYW5nZXMudmlld2VyVXJsLmN1cnJlbnRWYWx1ZSAhPT0gY2hhbmdlcy52aWV3ZXJVcmwucHJldmlvdXNWYWx1ZSkge1xyXG4gICAgICAgICAgICBpZiAoIWNoYW5nZXMudmlld2VyVXJsKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLnZpZXdlclVybCA9IG51bGw7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgc3dpdGNoICh0aGlzLmNvbmZpZ3VyZWRWaWV3ZXIpIHtcclxuICAgICAgICAgICAgICAgIGNhc2UgJ2dvb2dsZSc6XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy52aWV3ZXJVcmwgPSBgaHR0cHM6Ly9kb2NzLmdvb2dsZS5jb20vZ3ZpZXc/dXJsPSVVUkwlJmVtYmVkZGVkPXRydWVgO1xyXG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgY2FzZSAnb2ZmaWNlJzoge1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMudmlld2VyVXJsID0gYGh0dHBzOi8vdmlldy5vZmZpY2VhcHBzLmxpdmUuY29tL29wL2VtYmVkLmFzcHg/c3JjPSVVUkwlYDtcclxuICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGNhc2UgJ3BkZic6IHtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLnZpZXdlclVybCA9IG51bGw7XHJcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgdGhpcy5kb2NIdG1sID0gJyc7XHJcbiAgICAgICAgICAgIHRoaXMuZXh0ZXJuYWxWaWV3ZXIgPSB0aGlzLmNvbmZpZ3VyZWRWaWV3ZXIgPT09ICdnb29nbGUnIHx8IHRoaXMuY29uZmlndXJlZFZpZXdlciA9PT0gJ29mZmljZScgfHxcclxuICAgICAgICAgICAgICAgIHRoaXMuY29uZmlndXJlZFZpZXdlciA9PT0gJ3VybCc7XHJcbiAgICAgICAgICAgIGlmICh0aGlzLmNoZWNrSUZyYW1lU3Vic2NyaXB0aW9uKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmNoZWNrSUZyYW1lU3Vic2NyaXB0aW9uLnVuc3Vic2NyaWJlKCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgaWYgKCF0aGlzLnVybCkge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5mdWxsVXJsID0gbnVsbDtcclxuICAgICAgICAgICAgfSBlbHNlIGlmICh0aGlzLmNvbmZpZ3VyZWRWaWV3ZXIgPT09ICdvZmZpY2UnIHx8IHRoaXMuY29uZmlndXJlZFZpZXdlciA9PT0gJ2dvb2dsZSdcclxuICAgICAgICAgICAgICAgIHx8IHRoaXMuY29uZmlndXJlZFZpZXdlciA9PT0gJ3BkZicgfHwgdGhpcy5jb25maWd1cmVkVmlld2VyID09PSAndXJsJykge1xyXG4gICAgICAgICAgICAgICAgY29uc3QgdSA9IHRoaXMudXJsLmluZGV4T2YoJy8nKSA/IGVuY29kZVVSSUNvbXBvbmVudCh0aGlzLnVybCkgOiB0aGlzLnVybDtcclxuICAgICAgICAgICAgICAgIGxldCB1cmwgPSB0aGlzLnZpZXdlclVybCA/IHRoaXMudmlld2VyVXJsLnJlcGxhY2UoJyVVUkwlJywgdSkgOiB0aGlzLnVybDtcclxuICAgICAgICAgICAgICAgIGlmICghIXRoaXMucXVlcnlQYXJhbXMgJiYgdGhpcy5jb25maWd1cmVkVmlld2VyICE9PSAncGRmJykge1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0YXJ0ID0gdGhpcy5xdWVyeVBhcmFtcy5zdGFydHNXaXRoKCcmJykgPyAnJyA6ICcmJztcclxuICAgICAgICAgICAgICAgICAgICB1cmwgPSBgJHt1cmx9JHtzdGFydH0ke3RoaXMucXVlcnlQYXJhbXN9YDtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIHRoaXMuZnVsbFVybCA9IHRoaXMuZG9tU2FuaXRpemVyLmJ5cGFzc1NlY3VyaXR5VHJ1c3RSZXNvdXJjZVVybCh1cmwpO1xyXG4gICAgICAgICAgICAgICAgLy8gc2VlOlxyXG4gICAgICAgICAgICAgICAgLy8gaHR0cHM6Ly9zdGFja292ZXJmbG93LmNvbS9xdWVzdGlvbnMvNDA0MTQwMzkvZ29vZ2xlLWRvY3Mtdmlld2VyLXJldHVybmluZy0yMDQtcmVzcG9uc2VzLW5vLWxvbmdlci13b3JraW5nLWFsdGVybmF0aXZlc1xyXG4gICAgICAgICAgICAgICAgLy8gaGFjayB0byByZWxvYWQgaWZyYW1lIGlmIGl0J3Mgbm90IGxvYWRlZC5cclxuICAgICAgICAgICAgICAgIC8vIHdvdWxkIG1heWJlIGJlIGJldHRlciB0byB1c2Ugdmlldy5vZmZpY2VhcHBzLmxpdmUuY29tIGJ1dCBzZWVtcyBub3QgdG8gd29yayB3aXRoIHNhcyB0b2tlbi5cclxuICAgICAgICAgICAgICAgIGlmICh0aGlzLmNvbmZpZ3VyZWRWaWV3ZXIgPT09ICdnb29nbGUnICYmIHRoaXMuZ29vZ2xlQ2hlY2tDb250ZW50TG9hZGVkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5uZ1pvbmUucnVuT3V0c2lkZUFuZ3VsYXIoKCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5sb2coJ05HRE9DOj4+b3V0c2lkZScpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBpZiBpdCdzIG5vdCBsb2FkZWQgYWZ0ZXIgdGhlIGdvb2dsZUludGVydmFsQ2hlY2ssIHRoZW4gb3BlbiBsb2FkIGFnYWluLlxyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmNoZWNrSUZyYW1lU3Vic2NyaXB0aW9uID0gdGltZXIoNTAwLCB0aGlzLmdvb2dsZUNoZWNrSW50ZXJ2YWwpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAucGlwZShcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0YWtlKE1hdGgucm91bmQodGhpcy5nb29nbGVDaGVja0ludGVydmFsID09PSAwID8gMCA6IDIwMDAwIC8gdGhpcy5nb29nbGVDaGVja0ludGVydmFsKSkpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAuc3Vic2NyaWJlKCgpID0+IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5sb2coJ05HRE9DOj4+Y2hlY2tpbmcgYWdhaW4nKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBpZnJhbWUgPSB0aGlzLmlmcmFtZXM/LmZpcnN0Py5uYXRpdmVFbGVtZW50O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucmVsb2FkSUZyYW1lKGlmcmFtZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfSBlbHNlIGlmICh0aGlzLmNvbmZpZ3VyZWRWaWV3ZXIgPT09ICdtYW1tb3RoJykge1xyXG4gICAgICAgICAgICAgICAgaWYgKCFtYW1tb3RoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcignUGxlYXNlIGluc3RhbGwgbWFtbW90aCBhbmQgbWFrZSBzdXJlIG1hbW1vdGguYnJvd3Nlci5taW4uanMgaXMgbG9hZGVkLicpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgdGhpcy5kb2NIdG1sID0gYXdhaXQgdGhpcy5nZXREb2N4VG9IdG1sKHRoaXMudXJsKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBpZnJhbWVMb2FkZWQoKSB7XHJcbiAgICAgICAgdGhpcy5sb2FkZWQuZW1pdChudWxsKTtcclxuICAgICAgICBpZiAodGhpcy5jaGVja0lGcmFtZVN1YnNjcmlwdGlvbikge1xyXG4gICAgICAgICAgY29uc3QgaWZyYW1lID0gdGhpcy5pZnJhbWVzPy5maXJzdD8ubmF0aXZlRWxlbWVudDtcclxuICAgICAgICAgIGlmIChpZnJhbWUpIHtcclxuICAgICAgICAgICAgdGhpcy5sb2FkZWQuZW1pdCh0cnVlKTtcclxuICAgICAgICAgICAgdGhpcy5jaGVja0lGcmFtZVN1YnNjcmlwdGlvbi51bnN1YnNjcmliZSgpO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICByZWxvYWRJRnJhbWUoaWZyYW1lOiBIVE1MSUZyYW1lRWxlbWVudCkge1xyXG4gICAgICAgIGlmIChpZnJhbWUpIHtcclxuICAgICAgICAgICAgbGV0IHNyYyA9IGlmcmFtZS5zcmNcclxuICAgICAgICAgICAgaWZyYW1lLnNyYyA9IGlmcmFtZS5zcmM7XHJcbiAgICAgICAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xyXG4gICAgICAgICAgICAgIGlmcmFtZS5zcmMgPSBzcmNcclxuICAgICAgICAgICAgfSwgMTAwKVxyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIGFzeW5jIGdldERvY3hUb0h0bWwodXJsOiBzdHJpbmcpIHtcclxuICAgICAgICBjb25zdCBhcnJheUJ1ZmZlciA9IGF3YWl0IHRoaXMuZmlsZVRvQXJyYXkodXJsKTtcclxuICAgICAgICBjb25zdCByZXN1bHRPYmplY3QgPSBhd2FpdCBtYW1tb3RoLmNvbnZlcnRUb0h0bWwoeyBhcnJheUJ1ZmZlciB9KTtcclxuICAgICAgICByZXR1cm4gcmVzdWx0T2JqZWN0LnZhbHVlO1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgZmlsZVRvQXJyYXkodXJsOiBzdHJpbmcpOiBQcm9taXNlPEFycmF5QnVmZmVyPiB7XHJcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlPEFycmF5QnVmZmVyPigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XHJcbiAgICAgICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgICAgICBjb25zdCByZXF1ZXN0ID0gbmV3IFhNTEh0dHBSZXF1ZXN0KCk7XHJcbiAgICAgICAgICAgICAgICByZXF1ZXN0Lm9wZW4oJ0dFVCcsIHVybCwgdHJ1ZSk7XHJcbiAgICAgICAgICAgICAgICByZXF1ZXN0LnJlc3BvbnNlVHlwZSA9ICdibG9iJztcclxuICAgICAgICAgICAgICAgIHJlcXVlc3Qub25sb2FkID0gKCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHJlYWRlciA9IG5ldyBGaWxlUmVhZGVyKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgcmVhZGVyLnJlYWRBc0FycmF5QnVmZmVyKHJlcXVlc3QucmVzcG9uc2UpO1xyXG4gICAgICAgICAgICAgICAgICAgIHJlYWRlci5vbmxvYWRlbmQgPSAoZSkgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKHJlYWRlci5yZXN1bHQgYXMgQXJyYXlCdWZmZXIpO1xyXG4gICAgICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgICAgcmVxdWVzdC5zZW5kKCk7XHJcbiAgICAgICAgICAgIH0gY2F0Y2gge1xyXG4gICAgICAgICAgICAgICAgcmVqZWN0KGBlcnJvciB3aGlsZSByZXRyaWV2aW5nIGZpbGUgJHt1cmx9LmApO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcbn1cclxuIl19