ais-uploader
Version:
Simple uploader library for Angular 2+
545 lines • 56.6 kB
JavaScript
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
import * as tslib_1 from "tslib";
import { Component, EventEmitter, Inject, Output, PLATFORM_ID, ViewChild, ViewEncapsulation, } from '@angular/core';
import { isPlatformServer } from '@angular/common';
import { DocumentFileType } from './models/uploader-item';
import { AisUploaderService } from './ais-uploader.service';
import { UploaderTypesPipe } from './pipes/uploader-enum.pipe';
export class AisUploaderComponent {
/**
* @param {?} platformId
* @param {?} uploderService
* @param {?} uploaderEnum
*/
constructor(platformId, uploderService, uploaderEnum) {
this.uploderService = uploderService;
this.uploaderEnum = uploaderEnum;
this.onChange = new EventEmitter();
this.onProgress = new EventEmitter();
this.onError = new EventEmitter();
this._allowedExtensions = [];
if (isPlatformServer(platformId) || typeof ((/** @type {?} */ (window))).MouseEvent === 'function') {
return;
}
/**
* @param {?} event
* @param {?} params
* @return {?}
*/
function CustomEvent(event, params) {
params = params || { bubbles: false, cancelable: false, detail: undefined };
/** @type {?} */
const evt = document.createEvent('CustomEvent');
evt.initCustomEvent(event, params.bubbles, params.cancelable, params.detail);
return evt;
}
CustomEvent.prototype = ((/** @type {?} */ (window))).Event.prototype;
((/** @type {?} */ (window))).CustomEvent = CustomEvent;
}
/**
* @return {?}
*/
ngOnInit() {
this._generateAllowedExtensions();
}
/**
* @return {?}
*/
ngOnDestroy() {
if (this._progressSub$) {
this._progressSub$.unsubscribe();
}
if (this._uploaderSub$) {
this._uploaderSub$.unsubscribe();
}
}
// return file name or arr file names if isMultiple: true
/**
* @return {?}
*/
get fileName() {
if (this.config.isMultiple) {
return this.filesNames;
}
if (!this._file) {
return '';
}
return this._file.name;
}
// return arr file names if isMultiple: true
/**
* @return {?}
*/
get filesNames() {
if (!this._files || !this._files.length) {
return undefined;
}
return this._files.map(file => file.name);
}
// return info message
/**
* @return {?}
*/
get tooltipMessage() {
if (!this.config.supportedFormats.length) {
return `Max. size is ${this.config.maxSize ? this.config.maxSize : 'unlimited'} Mb`;
}
/** @type {?} */
const formats = this.uploaderEnum.transform(this.config.supportedFormats);
return `Supported formats are ${formats || 'All formats'}. Max. size is ${this.config.maxSize ?
this.config.maxSize : 'unlimited'} Mb`;
}
// open selction window
/**
* @return {?}
*/
select() {
/** @type {?} */
let event;
if (typeof ((/** @type {?} */ (window))).MouseEvent === 'function') {
event = new MouseEvent('click', {});
}
else {
event = new CustomEvent('click');
}
this.fileSelector.nativeElement.dispatchEvent(event);
}
// remove file from files arr
/**
* @param {?} i
* @return {?}
*/
delete(i) {
this._files.splice(i, 1);
}
// remove file or all files
/**
* @param {?=} emit
* @return {?}
*/
clear(emit = true) {
this._file = undefined;
this._files = undefined;
this.fileSelector.nativeElement.value = '';
if (emit) {
this.onChange.emit('');
}
}
/**
* @param {?} event
* @return {?}
*/
loadFile(event) {
return tslib_1.__awaiter(this, void 0, void 0, function* () {
if (this.config.isMultiple) {
/** @type {?} */
const _files = event.target.files;
for (const file of _files) {
/** @type {?} */
const isValid = yield this.validate(file);
if (!isValid) {
return;
}
}
this._files = [..._files];
}
else {
/** @type {?} */
const _file = event.target.files[0];
if (!_file) {
return;
}
/** @type {?} */
const isValid = yield this.validate(_file);
if (!isValid) {
return;
}
this._file = _file;
}
if (this.config.isAutoupload) {
try {
/** @type {?} */
const res = yield this.upload();
this.onChange.emit(res);
}
catch (e) {
this.onError.emit(e);
}
return;
}
if (!this.config.isPreviewDisabled) {
this._makePreview();
return;
}
this.onChange.emit(this._file.name);
});
}
// upload to server
/**
* @return {?}
*/
upload() {
if (this._progressSub$) {
this._progressSub$.unsubscribe();
}
this._onLoaderSub();
if (!this.config.isMultiple) {
return new Promise(resolve => {
this._uploaderSub$ = this.uploderService.upload(this._file, this.config).subscribe(res => {
this.onProgress.emit(0);
this.uploadingProgress = 0;
resolve(res);
}, err => {
this.onError.emit('Uploading error');
this.preventUploading();
resolve(undefined);
});
});
}
else {
return new Promise(resolve => {
this._uploaderSub$ = this.uploderService.uploadMultiple(this._files, this.config).subscribe(res => {
this.onProgress.emit(0);
this.uploadingProgress = 0;
resolve(res);
}, err => {
this.onError.emit('Uploading error');
this.preventUploading();
resolve(undefined);
});
});
}
}
// cancel current uploading
/**
* @return {?}
*/
preventUploading() {
if (!this.uploadingProgress) {
return;
}
if (this._progressSub$) {
this._progressSub$.unsubscribe();
}
if (this._uploaderSub$) {
this._uploaderSub$.unsubscribe();
}
this.onProgress.emit(0);
this.uploadingProgress = 0;
this.clear();
}
/**
* @private
* @param {?} file
* @return {?}
*/
validate(file) {
return tslib_1.__awaiter(this, void 0, void 0, function* () {
if (!file || !this.config) {
this.throwError('Uploader error');
return false;
}
if (this.config.maxSize &&
file.size / 1024 / 1024 > this.config.maxSize) {
this.throwError(`File size should be no more than ${this.config.maxSize}Mb`);
return false;
}
if (this.config.supportedFormats.length && file.type &&
!this.config.supportedFormats.includes(file.type)) {
this.throwError(`Unsupported file format`);
return false;
}
if (this.config.supportedFormats.length && !file.type &&
!this._validateFormat(file.name)) {
this.throwError(`Unsupported file format`);
return false;
}
if (this.config.imageResolution) {
/** @type {?} */
let resolution = this.config.imageResolution.split('x');
/** @type {?} */
let img;
if (!resolution || !resolution.length || resolution.length !== 2) {
this.throwError(`Unsupported resolution format`);
return false;
}
resolution = resolution.map(r => Math.ceil(Number(r))).filter(n => !!n);
if (!resolution || !resolution.length || resolution.length !== 2) {
this.throwError(`Unsupported resolution format`);
return false;
}
try {
img = yield this._addImageProcess(file);
}
catch (e) {
console.warn('Resolution property allows only for Images - Error Skipped');
return true;
}
if (img.width !== resolution[0] || img.height !== resolution[1]) {
this.throwError(`Unsupported resolution format! Correct resolution is ${this.config.imageResolution}`);
return false;
}
}
return true;
});
}
/**
* @private
* @param {?} file
* @return {?}
*/
_addImageProcess(file) {
return tslib_1.__awaiter(this, void 0, void 0, function* () {
return new Promise((resolve, reject) => {
// @ts-ignore
/** @type {?} */
const _URL = window.URL || window.webkitURL;
/** @type {?} */
const img = new Image();
/** @type {?} */
const objectUrl = _URL.createObjectURL(file);
img.onload = () => {
_URL.revokeObjectURL(objectUrl);
return resolve({ height: img.height, width: img.width });
};
img.onerror = reject;
img.src = objectUrl;
});
});
}
/**
* @private
* @return {?}
*/
_onLoaderSub() {
this._progressSub$ = this.uploderService.uploadingProgress
.subscribe(progress => {
this.onProgress.emit(progress);
this.uploadingProgress = progress;
});
}
/**
* @private
* @return {?}
*/
_makePreview() {
if (!this.config.isMultiple) {
/** @type {?} */
const reader = new FileReader();
reader.onload = (event) => {
this.onChange.emit(event.target.result);
};
reader.readAsDataURL(this._file);
}
else {
/** @type {?} */
const dataArr = [];
for (let i = 0; i < this._files.length; i++) {
/** @type {?} */
const reader = new FileReader();
reader.onload = (event) => {
dataArr[i] = (event.target.result);
};
reader.readAsDataURL(this._files[i]);
if (i == this._files.length - 1) {
this.onChange.emit(dataArr);
}
}
}
}
/**
* @private
* @param {?} name
* @return {?}
*/
_validateFormat(name) {
if (!this.config.supportedFormats.length) {
return true;
}
/** @type {?} */
const extension = name.split('.').pop().toLowerCase();
return this._allowedExtensions.some(s => s === extension);
}
/**
* @private
* @param {?} message
* @return {?}
*/
throwError(message) {
this.onError.emit(message);
this.fileSelector.nativeElement.value = '';
}
// tslint:disable-next-line:cyclomatic-complexity
/**
* @private
* @return {?}
*/
_generateAllowedExtensions() {
if (!this.config || !this.config.supportedFormats) {
return;
}
for (const format of this.config.supportedFormats) {
switch (format) {
case DocumentFileType.DOC:
this._allowedExtensions.push('doc');
break;
case DocumentFileType.DOCX:
this._allowedExtensions.push('docx');
break;
case DocumentFileType.XLSX:
this._allowedExtensions.push('xlsx');
break;
case DocumentFileType.XLS:
this._allowedExtensions.push('xls');
break;
case DocumentFileType.PDF:
this._allowedExtensions.push('pdf');
break;
case DocumentFileType.TXT:
this._allowedExtensions.push('txt');
break;
case DocumentFileType.PPTX:
this._allowedExtensions.push('pptx');
break;
case DocumentFileType.PPT:
this._allowedExtensions.push('ppt');
break;
case DocumentFileType.AVI:
this._allowedExtensions.push('avi');
break;
case DocumentFileType.FLV:
this._allowedExtensions.push('flv');
break;
case DocumentFileType.MP4:
this._allowedExtensions.push('mp4');
break;
case DocumentFileType.MPEG:
this._allowedExtensions.push('mpeg');
break;
case DocumentFileType.OGG:
this._allowedExtensions.push('ogg');
break;
case DocumentFileType.WEBM:
this._allowedExtensions.push('webm');
break;
case DocumentFileType.JPEG:
this._allowedExtensions.push('jpeg');
break;
case DocumentFileType.JPG:
this._allowedExtensions.push('jpg');
break;
case DocumentFileType.PNG:
this._allowedExtensions.push('png');
break;
case DocumentFileType.TIFF:
this._allowedExtensions.push('tiff');
break;
case DocumentFileType.WBMP:
this._allowedExtensions.push('wbmp');
break;
case DocumentFileType.WEBP:
this._allowedExtensions.push('webp');
break;
case DocumentFileType.SVG:
this._allowedExtensions.push('svg');
break;
case DocumentFileType.GIF:
this._allowedExtensions.push('gif');
break;
case DocumentFileType.CSV:
this._allowedExtensions.push('csv');
break;
case DocumentFileType.MSCSV:
this._allowedExtensions.push('csv');
break;
case DocumentFileType.MOV:
this._allowedExtensions.push('mov');
break;
case DocumentFileType.MP3:
this._allowedExtensions.push('mp3');
break;
case DocumentFileType.WAV:
this._allowedExtensions.push('wav');
break;
case DocumentFileType.XWAV:
this._allowedExtensions.push('wav');
break;
default:
break;
}
}
}
}
AisUploaderComponent.decorators = [
{ type: Component, args: [{
selector: 'ais-uploader',
template: "<input id=\"uploader_lib\" #fileSelector type=\"file\" [accept]=\"config?.supportedFormats | uploaderTypes:true\"\r\n (change)=\"loadFile($event)\">\r\n",
encapsulation: ViewEncapsulation.None,
styles: ["#uploader_lib{display:none}@keyframes blink{0%,100%{box-shadow:0 2px 2px rgba(0,0,0,.24),0 0 2px rgba(0,0,0,.12)}50%{box-shadow:none}}@-webkit-keyframes blink{0%,100%{box-shadow:0 2px 2px rgba(0,0,0,.24),0 0 2px rgba(0,0,0,.12)}50%{box-shadow:0 0 0}}.blink{-webkit-animation:3s linear infinite blink;animation:3s linear infinite blink}"]
}] }
];
/** @nocollapse */
AisUploaderComponent.ctorParameters = () => [
{ type: String, decorators: [{ type: Inject, args: [PLATFORM_ID,] }] },
{ type: AisUploaderService },
{ type: UploaderTypesPipe }
];
AisUploaderComponent.propDecorators = {
onChange: [{ type: Output }],
onProgress: [{ type: Output }],
onError: [{ type: Output }],
fileSelector: [{ type: ViewChild, args: ['fileSelector',] }]
};
if (false) {
/** @type {?} */
AisUploaderComponent.prototype.config;
/** @type {?} */
AisUploaderComponent.prototype.uploadingProgress;
/** @type {?} */
AisUploaderComponent.prototype.onChange;
/** @type {?} */
AisUploaderComponent.prototype.onProgress;
/** @type {?} */
AisUploaderComponent.prototype.onError;
/** @type {?} */
AisUploaderComponent.prototype.fileSelector;
/**
* @type {?}
* @private
*/
AisUploaderComponent.prototype._file;
/**
* @type {?}
* @private
*/
AisUploaderComponent.prototype._files;
/**
* @type {?}
* @private
*/
AisUploaderComponent.prototype._allowedExtensions;
/**
* @type {?}
* @private
*/
AisUploaderComponent.prototype._progressSub$;
/**
* @type {?}
* @private
*/
AisUploaderComponent.prototype._uploaderSub$;
/**
* @type {?}
* @private
*/
AisUploaderComponent.prototype.uploderService;
/**
* @type {?}
* @private
*/
AisUploaderComponent.prototype.uploaderEnum;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWlzLXVwbG9hZGVyLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiJuZzovL2Fpcy11cGxvYWRlci8iLCJzb3VyY2VzIjpbImxpYi9haXMtdXBsb2FkZXIuY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBQUEsT0FBTyxFQUNILFNBQVMsRUFDVCxZQUFZLEVBQ1osTUFBTSxFQUdOLE1BQU0sRUFDTixXQUFXLEVBQ1gsU0FBUyxFQUNULGlCQUFpQixHQUNwQixNQUFNLGVBQWUsQ0FBQztBQUd2QixPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUNuRCxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUMxRCxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUM1RCxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQVEvRCxNQUFNLE9BQU8sb0JBQW9COzs7Ozs7SUFjN0IsWUFDeUIsVUFBa0IsRUFDL0IsY0FBa0MsRUFDbEMsWUFBK0I7UUFEL0IsbUJBQWMsR0FBZCxjQUFjLENBQW9CO1FBQ2xDLGlCQUFZLEdBQVosWUFBWSxDQUFtQjtRQWRqQyxhQUFRLEdBQXNCLElBQUksWUFBWSxFQUFFLENBQUM7UUFDakQsZUFBVSxHQUF5QixJQUFJLFlBQVksRUFBRSxDQUFDO1FBQ3RELFlBQU8sR0FBeUIsSUFBSSxZQUFZLEVBQUUsQ0FBQztRQUtyRCx1QkFBa0IsR0FBYSxFQUFFLENBQUM7UUFTdEMsSUFBSSxnQkFBZ0IsQ0FBQyxVQUFVLENBQUMsSUFBSSxPQUFPLENBQUMsbUJBQUssTUFBTSxFQUFBLENBQUMsQ0FBQyxVQUFVLEtBQUssVUFBVSxFQUFFO1lBQ2hGLE9BQU87U0FDVjs7Ozs7O1FBRUQsU0FBUyxXQUFXLENBQUMsS0FBSyxFQUFFLE1BQU07WUFDOUIsTUFBTSxHQUFHLE1BQU0sSUFBSSxFQUFDLE9BQU8sRUFBRSxLQUFLLEVB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S0FBSyxDQUFDLENBQUM7b0JBQ3BDLE1BQU07Z0JBQ1YsS0FBSyxnQkFBZ0IsQ0FBQyxHQUFHO29CQUNyQixJQUFJLENBQUMsa0JBQWtCLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO29CQUNwQyxNQUFNO2dCQUNWLEtBQUssZ0JBQWdCLENBQUMsR0FBRztvQkFDckIsSUFBSSxDQUFDLGtCQUFrQixDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztvQkFDcEMsTUFBTTtnQkFDVixLQUFLLGdCQUFnQixDQUFDLElBQUk7b0JBQ3RCLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7b0JBQ3BDLE1BQU07Z0JBQ1Y7b0JBQ0ksTUFBTTthQUNiO1NBQ0o7SUFDTCxDQUFDOzs7WUF6WUosU0FBUyxTQUFDO2dCQUNQLFFBQVEsRUFBRSxjQUFjO2dCQUN4QiwwS0FBNEM7Z0JBRTVDLGFBQWEsRUFBRSxpQkFBaUIsQ0FBQyxJQUFJOzthQUN4Qzs7Ozt5Q0FnQlEsTUFBTSxTQUFDLFdBQVc7WUF4QmxCLGtCQUFrQjtZQUNsQixpQkFBaUI7Ozt1QkFXckIsTUFBTTt5QkFDTixNQUFNO3NCQUNOLE1BQU07MkJBRU4sU0FBUyxTQUFDLGNBQWM7Ozs7SUFOekIsc0NBQXVCOztJQUN2QixpREFBMEI7O0lBQzFCLHdDQUEyRDs7SUFDM0QsMENBQWdFOztJQUNoRSx1Q0FBNkQ7O0lBRTdELDRDQUF3Qzs7Ozs7SUFDeEMscUNBQW9COzs7OztJQUNwQixzQ0FBdUI7Ozs7O0lBQ3ZCLGtEQUEwQzs7Ozs7SUFDMUMsNkNBQW9DOzs7OztJQUNwQyw2Q0FBb0M7Ozs7O0lBSWhDLDhDQUEwQzs7Ozs7SUFDMUMsNENBQXVDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcclxuICAgIENvbXBvbmVudCxcclxuICAgIEV2ZW50RW1pdHRlcixcclxuICAgIEluamVjdCxcclxuICAgIE9uRGVzdHJveSxcclxuICAgIE9uSW5pdCxcclxuICAgIE91dHB1dCxcclxuICAgIFBMQVRGT1JNX0lELFxyXG4gICAgVmlld0NoaWxkLFxyXG4gICAgVmlld0VuY2Fwc3VsYXRpb24sXHJcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcbmltcG9ydCB7IFVwbG9hZGVyQ29uZmlnIH0gZnJvbSAnLi9tb2RlbHMvdXBsb2FkZXItY29uZmlnJztcclxuaW1wb3J0IHsgU3Vic2NyaXB0aW9uIH0gZnJvbSAncnhqcyc7XHJcbmltcG9ydCB7IGlzUGxhdGZvcm1TZXJ2ZXIgfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xyXG5pbXBvcnQgeyBEb2N1bWVudEZpbGVUeXBlIH0gZnJvbSAnLi9tb2RlbHMvdXBsb2FkZXItaXRlbSc7XHJcbmltcG9ydCB7IEFpc1VwbG9hZGVyU2VydmljZSB9IGZyb20gJy4vYWlzLXVwbG9hZGVyLnNlcnZpY2UnO1xyXG5pbXBvcnQgeyBVcGxvYWRlclR5cGVzUGlwZSB9IGZyb20gJy4vcGlwZXMvdXBsb2FkZXItZW51bS5waXBlJztcclxuXHJcbkBDb21wb25lbnQoe1xyXG4gICAgc2VsZWN0b3I6ICdhaXMtdXBsb2FkZXInLFxyXG4gICAgdGVtcGxhdGVVcmw6ICcuL2Fpcy11cGxvYWRlci5jb21wb25lbnQuaHRtbCcsXHJcbiAgICBzdHlsZVVybHM6IFsnLi9haXMtdXBsb2FkZXIuY29tcG9uZW50LnNjc3MnXSxcclxuICAgIGVuY2Fwc3VsYXRpb246IFZpZXdFbmNhcHN1bGF0aW9uLk5vbmUsXHJcbn0pXHJcbmV4cG9ydCBjbGFzcyBBaXNVcGxvYWRlckNvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCwgT25EZXN0cm95IHtcclxuICAgIGNvbmZpZzogVXBsb2FkZXJDb25maWc7XHJcbiAgICB1cGxvYWRpbmdQcm9ncmVzczogbnVtYmVyO1xyXG4gICAgQE91dHB1dCgpIG9uQ2hhbmdlOiBFdmVudEVtaXR0ZXI8YW55PiA9IG5ldyBFdmVudEVtaXR0ZXIoKTtcclxuICAgIEBPdXRwdXQoKSBvblByb2dyZXNzOiBFdmVudEVtaXR0ZXI8bnVtYmVyPiA9IG5ldyBFdmVudEVtaXR0ZXIoKTtcclxuICAgIEBPdXRwdXQoKSBvbkVycm9yOiBFdmVudEVtaXR0ZXI8c3RyaW5nPiA9IG5ldyBFdmVudEVtaXR0ZXIoKTtcclxuXHJcbiAgICBAVmlld0NoaWxkKCdmaWxlU2VsZWN0b3InKSBmaWxlU2VsZWN0b3I7XHJcbiAgICBwcml2YXRlIF9maWxlOiBGaWxlO1xyXG4gICAgcHJpdmF0ZSBfZmlsZXM6IEZpbGVbXTtcclxuICAgIHByaXZhdGUgX2FsbG93ZWRFeHRlbnNpb25zOiBzdHJpbmdbXSA9IFtdO1xyXG4gICAgcHJpdmF0ZSBfcHJvZ3Jlc3NTdWIkOiBTdWJzY3JpcHRpb247XHJcbiAgICBwcml2YXRlIF91cGxvYWRlclN1YiQ6IFN1YnNjcmlwdGlvbjtcclxuXHJcbiAgICBjb25zdHJ1Y3RvcihcclxuICAgICAgICBASW5qZWN0KFBMQVRGT1JNX0lEKSBwbGF0Zm9ybUlkOiBzdHJpbmcsXHJcbiAgICAgICAgcHJpdmF0ZSB1cGxvZGVyU2VydmljZTogQWlzVXBsb2FkZXJTZXJ2aWNlLFxyXG4gICAgICAgIHByaXZhdGUgdXBsb2FkZXJFbnVtOiBVcGxvYWRlclR5cGVzUGlwZSxcclxuICAgICkge1xyXG4gICAgICAgIGlmIChpc1BsYXRmb3JtU2VydmVyKHBsYXRmb3JtSWQpIHx8IHR5cGVvZiAoPGFueT53aW5kb3cpLk1vdXNlRXZlbnQgPT09ICdmdW5jdGlvbicpIHtcclxuICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgZnVuY3Rpb24gQ3VzdG9tRXZlbnQoZXZlbnQsIHBhcmFtcyk6IGFueSB7XHJcbiAgICAgICAgICAgIHBhcmFtcyA9IHBhcmFtcyB8fCB7YnViYmxlczogZmFsc2UsIGNhbmNlbGFibGU6IGZhbHNlLCBkZXRhaWw6IHVuZGVmaW5lZH07XHJcbiAgICAgICAgICAgIGNvbnN0IGV2dDogYW55ID0gZG9jdW1lbnQuY3JlYXRlRXZlbnQoJ0N1c3RvbUV2ZW50Jyk7XHJcbiAgICAgICAgICAgIGV2dC5pbml0Q3VzdG9tRXZlbnQoZXZlbnQsIHBhcmFtcy5idWJibGVzLCBwYXJhbXMuY2FuY2VsYWJsZSwgcGFyYW1zLmRldGFpbCk7XHJcbiAgICAgICAgICAgIHJldHVybiBldnQ7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBDdXN0b21FdmVudC5wcm90b3R5cGUgPSAoPGFueT53aW5kb3cpLkV2ZW50LnByb3RvdHlwZTtcclxuICAgICAgICAoPGFueT53aW5kb3cpLkN1c3RvbUV2ZW50ID0gQ3VzdG9tRXZlbnQ7XHJcbiAgICB9XHJcblxyXG4gICAgbmdPbkluaXQoKTogdm9pZCB7XHJcbiAgICAgICAgdGhpcy5fZ2VuZXJhdGVBbGxvd2VkRXh0ZW5zaW9ucygpO1xyXG4gICAgfVxyXG5cclxuICAgIG5nT25EZXN0cm95KCk6IHZvaWQge1xyXG4gICAgICAgIGlmICh0aGlzLl9wcm9ncmVzc1N1YiQpIHtcclxuICAgICAgICAgICAgdGhpcy5fcHJvZ3Jlc3NTdWIkLnVuc3Vic2NyaWJlKCk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmICh0aGlzLl91cGxvYWRlclN1YiQpIHtcclxuICAgICAgICAgICAgdGhpcy5fdXBsb2FkZXJTdWIkLnVuc3Vic2NyaWJlKCk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIC8vIHJldHVybiBmaWxlIG5hbWUgb3IgYXJyIGZpbGUgbmFtZXMgaWYgaXNNdWx0aXBsZTogdHJ1ZVxyXG4gICAgZ2V0IGZpbGVOYW1lKCk6IHN0cmluZyB8IHN0cmluZ1tdIHtcclxuICAgICAgICBpZiAodGhpcy5jb25maWcuaXNNdWx0aXBsZSkge1xyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5maWxlc05hbWVzO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAoIXRoaXMuX2ZpbGUpIHtcclxuICAgICAgICAgICAgcmV0dXJuICcnO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gdGhpcy5fZmlsZS5uYW1lO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIHJldHVybiBhcnIgZmlsZSBuYW1lcyBpZiBpc011bHRpcGxlOiB0cnVlXHJcbiAgICBnZXQgZmlsZXNOYW1lcygpOiBzdHJpbmdbXSB7XHJcbiAgICAgICAgaWYgKCF0aGlzLl9maWxlcyB8fCAhdGhpcy5fZmlsZXMubGVuZ3RoKSB7XHJcbiAgICAgICAgICAgIHJldHVybiB1bmRlZmluZWQ7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiB0aGlzLl9maWxlcy5tYXAoZmlsZSA9PiBmaWxlLm5hbWUpO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIHJldHVybiBpbmZvIG1lc3NhZ2VcclxuICAgIGdldCB0b29sdGlwTWVzc2FnZSgpOiBzdHJpbmcge1xyXG4gICAgICAgIGlmICghdGhpcy5jb25maWcuc3VwcG9ydGVkRm9ybWF0cy5sZW5ndGgpIHtcclxuICAgICAgICAgICAgcmV0dXJuIGBNYXguIHNpemUgaXMgJHt0aGlzLmNvbmZpZy5tYXhTaXplID8gdGhpcy5jb25maWcubWF4U2l6ZSA6ICd1bmxpbWl0ZWQnfSBNYmA7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGNvbnN0IGZvcm1hdHMgPSB0aGlzLnVwbG9hZGVyRW51bS50cmFuc2Zvcm0odGhpcy5jb25maWcuc3VwcG9ydGVkRm9ybWF0cyk7XHJcbiAgICAgICAgcmV0dXJuIGBTdXBwb3J0ZWQgZm9ybWF0cyBhcmUgJHtmb3JtYXRzIHx8ICdBbGwgZm9ybWF0cyd9LiBNYXguIHNpemUgaXMgJHt0aGlzLmNvbmZpZy5tYXhTaXplID9cclxuICAgICAgICAgICAgdGhpcy5jb25maWcubWF4U2l6ZSA6ICd1bmxpbWl0ZWQnfSBNYmA7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gb3BlbiBzZWxjdGlvbiB3aW5kb3dcclxuICAgIHNlbGVjdCgpOiB2b2lkIHtcclxuICAgICAgICBsZXQgZXZlbnQ6IGFueTtcclxuICAgICAgICBpZiAodHlwZW9mICg8YW55PndpbmRvdykuTW91c2VFdmVudCA9PT0gJ2Z1bmN0aW9uJykge1xyXG4gICAgICAgICAgICBldmVudCA9IG5ldyBNb3VzZUV2ZW50KCdjbGljaycsIHt9KTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICBldmVudCA9IG5ldyBDdXN0b21FdmVudCgnY2xpY2snKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgdGhpcy5maWxlU2VsZWN0b3IubmF0aXZlRWxlbWVudC5kaXNwYXRjaEV2ZW50KGV2ZW50KTtcclxuICAgIH1cclxuXHJcbiAgICAvLyByZW1vdmUgZmlsZSBmcm9tIGZpbGVzIGFyclxyXG4gICAgZGVsZXRlKGk6IG51bWJlcik6IHZvaWQge1xyXG4gICAgICAgIHRoaXMuX2ZpbGVzLnNwbGljZShpLCAxKTtcclxuICAgIH1cclxuXHJcbiAgICAvLyByZW1vdmUgZmlsZSBvciBhbGwgZmlsZXNcclxuICAgIGNsZWFyKGVtaXQ6IGJvb2xlYW4gPSB0cnVlKTogdm9pZCB7XHJcbiAgICAgICAgdGhpcy5fZmlsZSA9IHVuZGVmaW5lZDtcclxuICAgICAgICB0aGlzLl9maWxlcyA9IHVuZGVmaW5lZDtcclxuICAgICAgICB0aGlzLmZpbGVTZWxlY3Rvci5uYXRpdmVFbGVtZW50LnZhbHVlID0gJyc7XHJcbiAgICAgICAgaWYgKGVtaXQpIHtcclxuICAgICAgICAgICAgdGhpcy5vbkNoYW5nZS5lbWl0KCcnKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgYXN5bmMgbG9hZEZpbGUoZXZlbnQpOiBQcm9taXNlPGFueT4ge1xyXG4gICAgICAgIGlmICh0aGlzLmNvbmZpZy5pc011bHRpcGxlKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IF9maWxlcyA9IGV2ZW50LnRhcmdldC5maWxlcztcclxuICAgICAgICAgICAgZm9yIChjb25zdCBmaWxlIG9mIF9maWxlcykge1xyXG4gICAgICAgICAgICAgICAgY29uc3QgaXNWYWxpZCA9IGF3YWl0IHRoaXMudmFsaWRhdGUoZmlsZSk7XHJcbiAgICAgICAgICAgICAgICBpZiAoIWlzVmFsaWQpIHtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgdGhpcy5fZmlsZXMgPSBbLi4uX2ZpbGVzXTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICBjb25zdCBfZmlsZSA9IGV2ZW50LnRhcmdldC5maWxlc1swXTtcclxuICAgICAgICAgICAgaWYgKCFfZmlsZSkge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGNvbnN0IGlzVmFsaWQgPSBhd2FpdCB0aGlzLnZhbGlkYXRlKF9maWxlKTtcclxuICAgICAgICAgICAgaWYgKCFpc1ZhbGlkKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgdGhpcy5fZmlsZSA9IF9maWxlO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAodGhpcy5jb25maWcuaXNBdXRvdXBsb2FkKSB7XHJcbiAgICAgICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgICAgICBjb25zdCByZXMgPSBhd2FpdCB0aGlzLnVwbG9hZCgpO1xyXG4gICAgICAgICAgICAgICAgdGhpcy5vbkNoYW5nZS5lbWl0KHJlcyk7XHJcbiAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMub25FcnJvci5lbWl0KGUpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKCF0aGlzLmNvbmZpZy5pc1ByZXZpZXdEaXNhYmxlZCkge1xyXG4gICAgICAgICAgICB0aGlzLl9tYWtlUHJldmlldygpO1xyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHRoaXMub25DaGFuZ2UuZW1pdCh0aGlzLl9maWxlLm5hbWUpO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIHVwbG9hZCB0byBzZXJ2ZXJcclxuICAgIHVwbG9hZCgpOiBQcm9taXNlPGFueT4ge1xyXG4gICAgICAgIGlmICh0aGlzLl9wcm9ncmVzc1N1YiQpIHtcclxuICAgICAgICAgICAgdGhpcy5fcHJvZ3Jlc3NTdWIkLnVuc3Vic2NyaWJlKCk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHRoaXMuX29uTG9hZGVyU3ViKCk7XHJcbiAgICAgICAgaWYgKCF0aGlzLmNvbmZpZy5pc011bHRpcGxlKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBuZXcgUHJvbWlzZShyZXNvbHZlID0+IHtcclxuICAgICAgICAgICAgICAgIHRoaXMuX3VwbG9hZGVyU3ViJCA9IHRoaXMudXBsb2RlclNlcnZpY2UudXBsb2FkKHRoaXMuX2ZpbGUsIHRoaXMuY29uZmlnKS5zdWJzY3JpYmUocmVzID0+IHtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLm9uUHJvZ3Jlc3MuZW1pdCgwKTtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLnVwbG9hZGluZ1Byb2dyZXNzID0gMDtcclxuICAgICAgICAgICAgICAgICAgICByZXNvbHZlKHJlcyk7XHJcbiAgICAgICAgICAgICAgICB9LCBlcnIgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMub25FcnJvci5lbWl0KCdVcGxvYWRpbmcgZXJyb3InKTtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLnByZXZlbnRVcGxvYWRpbmcoKTtcclxuICAgICAgICAgICAgICAgICAgICByZXNvbHZlKHVuZGVmaW5lZCk7XHJcbiAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKHJlc29sdmUgPT4ge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5fdXBsb2FkZXJTdWIkID0gdGhpcy51cGxvZGVyU2VydmljZS51cGxvYWRNdWx0aXBsZSh0aGlzLl9maWxlcywgdGhpcy5jb25maWcpLnN1YnNjcmliZShyZXMgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMub25Qcm9ncmVzcy5lbWl0KDApO1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMudXBsb2FkaW5nUHJvZ3Jlc3MgPSAwO1xyXG4gICAgICAgICAgICAgICAgICAgIHJlc29sdmUocmVzKTtcclxuICAgICAgICAgICAgICAgIH0sIGVyciA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5vbkVycm9yLmVtaXQoJ1VwbG9hZGluZyBlcnJvcicpO1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMucHJldmVudFVwbG9hZGluZygpO1xyXG4gICAgICAgICAgICAgICAgICAgIHJlc29sdmUodW5kZWZpbmVkKTtcclxuICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgLy8gY2FuY2VsIGN1cnJlbnQgdXBsb2FkaW5nXHJcbiAgICBwcmV2ZW50VXBsb2FkaW5nKCk6IHZvaWQge1xyXG4gICAgICAgIGlmICghdGhpcy51cGxvYWRpbmdQcm9ncmVzcykge1xyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmICh0aGlzLl9wcm9ncmVzc1N1YiQpIHtcclxuICAgICAgICAgICAgdGhpcy5fcHJvZ3Jlc3NTdWIkLnVuc3Vic2NyaWJlKCk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmICh0aGlzLl91cGxvYWRlclN1YiQpIHtcclxuICAgICAgICAgICAgdGhpcy5fdXBsb2FkZXJTdWIkLnVuc3Vic2NyaWJlKCk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHRoaXMub25Qcm9ncmVzcy5lbWl0KDApO1xyXG4gICAgICAgIHRoaXMudXBsb2FkaW5nUHJvZ3Jlc3MgPSAwO1xyXG4gICAgICAgIHRoaXMuY2xlYXIoKTtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIGFzeW5jIHZhbGlkYXRlKGZpbGUpOiBQcm9taXNlPGJvb2xlYW4+IHtcclxuICAgICAgICBpZiAoIWZpbGUgfHwgIXRoaXMuY29uZmlnKSB7XHJcbiAgICAgICAgICAgIHRoaXMudGhyb3dFcnJvcignVXBsb2FkZXIgZXJyb3InKTtcclxuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAodGhpcy5jb25maWcubWF4U2l6ZSAmJlxyXG4gICAgICAgICAgICBmaWxlLnNpemUgLyAxMDI0IC8gMTAyNCA+IHRoaXMuY29uZmlnLm1heFNpemUpIHtcclxuICAgICAgICAgICAgdGhpcy50aHJvd0Vycm9yKGBGaWxlIHNpemUgc2hvdWxkIGJlIG5vIG1vcmUgdGhhbiAke3RoaXMuY29uZmlnLm1heFNpemV9TWJgKTtcclxuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAodGhpcy5jb25maWcuc3VwcG9ydGVkRm9ybWF0cy5sZW5ndGggJiYgZmlsZS50eXBlICYmXHJcbiAgICAgICAgICAgICF0aGlzLmNvbmZpZy5zdXBwb3J0ZWRGb3JtYXRzLmluY2x1ZGVzKGZpbGUudHlwZSkpIHtcclxuICAgICAgICAgICAgdGhpcy50aHJvd0Vycm9yKGBVbnN1cHBvcnRlZCBmaWxlIGZvcm1hdGApO1xyXG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmICh0aGlzLmNvbmZpZy5zdXBwb3J0ZWRGb3JtYXRzLmxlbmd0aCAmJiAhZmlsZS50eXBlICYmXHJcbiAgICAgICAgICAgICF0aGlzLl92YWxpZGF0ZUZvcm1hdChmaWxlLm5hbWUpKSB7XHJcbiAgICAgICAgICAgIHRoaXMudGhyb3dFcnJvcihgVW5zdXBwb3J0ZWQgZmlsZSBmb3JtYXRgKTtcclxuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAodGhpcy5jb25maWcuaW1hZ2VSZXNvbHV0aW9uKSB7XHJcbiAgICAgICAgICAgIGxldCByZXNvbHV0aW9uOiBBcnJheTxzdHJpbmcgfCBudW1iZXI+ID0gdGhpcy5jb25maWcuaW1hZ2VSZXNvbHV0aW9uLnNwbGl0KCd4Jyk7XHJcbiAgICAgICAgICAgIGxldCBpbWc7XHJcbiAgICAgICAgICAgIGlmICghcmVzb2x1dGlvbiB8fCAhcmVzb2x1dGlvbi5sZW5ndGggfHwgcmVzb2x1dGlvbi5sZW5ndGggIT09IDIpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMudGhyb3dFcnJvcihgVW5zdXBwb3J0ZWQgcmVzb2x1dGlvbiBmb3JtYXRgKTtcclxuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICByZXNvbHV0aW9uID0gcmVzb2x1dGlvbi5tYXAociA9PiBNYXRoLmNlaWwoTnVtYmVyKHIpKSkuZmlsdGVyKG4gPT4gISFuKTtcclxuICAgICAgICAgICAgaWYgKCFyZXNvbHV0aW9uIHx8ICFyZXNvbHV0aW9uLmxlbmd0aCB8fCByZXNvbHV0aW9uLmxlbmd0aCAhPT0gMikge1xyXG4gICAgICAgICAgICAgICAgdGhpcy50aHJvd0Vycm9yKGBVbnN1cHBvcnRlZCByZXNvbHV0aW9uIGZvcm1hdGApO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgICAgICBpbWcgPSBhd2FpdCB0aGlzLl9hZGRJbWFnZVByb2Nlc3MoZmlsZSk7XHJcbiAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcclxuICAgICAgICAgICAgICAgIGNvbnNvbGUud2FybignUmVzb2x1dGlvbiBwcm9wZXJ0eSBhbGxvd3Mgb25seSBmb3IgSW1hZ2VzIC0gRXJyb3IgU2tpcHBlZCcpO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgaWYgKGltZy53aWR0aCAhPT0gcmVzb2x1dGlvblswXSB8fCBpbWcuaGVpZ2h0ICE9PSByZXNvbHV0aW9uWzFdKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLnRocm93RXJyb3IoYFVuc3VwcG9ydGVkIHJlc29sdXRpb24gZm9ybWF0ISBDb3JyZWN0IHJlc29sdXRpb24gaXMgJHt0aGlzLmNvbmZpZy5pbWFnZVJlc29sdXRpb259YCk7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHRydWU7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBhc3luYyBfYWRkSW1hZ2VQcm9jZXNzKGZpbGUpOiBQcm9taXNlPGFueT4ge1xyXG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XHJcbiAgICAgICAgICAgIC8vIEB0cy1pZ25vcmVcclxuICAgICAgICAgICAgY29uc3QgX1VSTCA9IHdpbmRvdy5VUkwgfHwgd2luZG93LndlYmtpdFVSTDtcclxuICAgICAgICAgICAgY29uc3QgaW1nID0gbmV3IEltYWdlKCk7XHJcbiAgICAgICAgICAgIGNvbnN0IG9iamVjdFVybCA9IF9VUkwuY3JlYXRlT2JqZWN0VVJMKGZpbGUpO1xyXG4gICAgICAgICAgICBpbWcub25sb2FkID0gKCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgX1VSTC5yZXZva2VPYmplY3RVUkwob2JqZWN0VXJsKTtcclxuICAgICAgICAgICAgICAgIHJldHVybiByZXNvbHZlKHtoZWlnaHQ6IGltZy5oZWlnaHQsIHdpZHRoOiBpbWcud2lkdGh9KTtcclxuICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgaW1nLm9uZXJyb3IgPSByZWplY3Q7XHJcbiAgICAgICAgICAgIGltZy5zcmMgPSBvYmplY3RVcmw7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBfb25Mb2FkZXJTdWIoKTogdm9pZCB7XHJcbiAgICAgICAgdGhpcy5fcHJvZ3Jlc3NTdWIkID0gdGhpcy51cGxvZGVyU2VydmljZS51cGxvYWRpbmdQcm9ncmVzc1xyXG4gICAgICAgICAgICAuc3Vic2NyaWJlKHByb2dyZXNzID0+IHtcclxuICAgICAgICAgICAgICAgIHRoaXMub25Qcm9ncmVzcy5lbWl0KHByb2dyZXNzKTtcclxuICAgICAgICAgICAgICAgIHRoaXMudXBsb2FkaW5nUHJvZ3Jlc3MgPSBwcm9ncmVzcztcclxuICAgICAgICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBfbWFrZVByZXZpZXcoKTogdm9pZCB7XHJcbiAgICAgICAgaWYgKCF0aGlzLmNvbmZpZy5pc011bHRpcGxlKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IHJlYWRlciA9IG5ldyBGaWxlUmVhZGVyKCk7XHJcbiAgICAgICAgICAgIHJlYWRlci5vbmxvYWQgPSAoZXZlbnQ6IGFueSkgPT4ge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5vbkNoYW5nZS5lbWl0KGV2ZW50LnRhcmdldC5yZXN1bHQpO1xyXG4gICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICByZWFkZXIucmVhZEFzRGF0YVVSTCh0aGlzLl9maWxlKTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICBjb25zdCBkYXRhQXJyID0gW107XHJcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5fZmlsZXMubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICAgICAgICAgIGNvbnN0IHJlYWRlciA9IG5ldyBGaWxlUmVhZGVyKCk7XHJcbiAgICAgICAgICAgICAgICByZWFkZXIub25sb2FkID0gKGV2ZW50OiBhbnkpID0+IHtcclxuICAgICAgICAgICAgICAgICAgICBkYXRhQXJyW2ldID0gKGV2ZW50LnRhcmdldC5yZXN