UNPKG

@wizco/fenixds-ngx

Version:

Componentes fenix design system para Angular.

405 lines 45.3 kB
import { Component, EventEmitter, Input, Output, SkipSelf, } from '@angular/core'; import { HttpClientModule, HttpEventType, } from '@angular/common/http'; import { CommonModule } from '@angular/common'; import * as i0 from "@angular/core"; import * as i1 from "@angular/common/http"; import * as i2 from "@angular/common"; export class UploadComponent { http; /* Texto de descrição do arquivo */ description = '(XX MB de tamanho máximo e é permitido qualquer tipo de arquivos)'; /* config <AngularFileUploaderConfig> configuração do componente principais parâmetros */ config = { uploadAPI: { url: '', method: 'POST', headers: { 'Content-Type': 'text/plain;charset=UTF-8', }, responseType: 'json', withCredentials: false, }, }; /* * Opção de resetar o componente */ resetUpload = false; /* * Evento Resposta da requisição sendo sucesso ou erro */ ApiResponse = new EventEmitter(); /* * Evento javascript puro para retorno do arquivo */ fileSelected = new EventEmitter(); /** * @ignore */ theme = ''; /** * @ignore */ id = 0; /** * @ignore */ hideProgressBar = false; /** * @ignore */ maxSize = 20 * 1024000; // mb to bytes. /** * @ignore */ uploadAPI = ''; /** * @ignore */ method = 'POST'; /** * @ignore */ formatsAllowed = '*'; /** * @ignore */ formatsAllowedText = ''; /** * @ignore */ multiple = false; /** * @ignore */ headers = {}; /** * @ignore */ params = {}; /** * @ignore */ responseType = 'blob'; /** * @ignore */ hideResetBtn = false; /** * @ignore */ hideSelectBtn = false; /** * @ignore */ allowedFiles = []; /** * @ignore */ notAllowedFiles = []; /** * @ignore */ Caption = []; /** * @ignore */ isAllowedFileSingle = true; /** * @ignore */ progressBarShow = false; /** * @ignore */ enableUploadBtn = false; /** * @ignore */ uploadMsg = false; /** * @ignore */ afterUpload = false; /** * @ignore */ uploadStarted = false; /** * @ignore */ uploadMsgText = ''; /** * @ignore */ uploadMsgClass = 'text-success'; /** * @ignore */ uploadPercent = 0; /** * @ignore */ replaceTexts = { selectFileBtn: 'Selecionar Arquivo', resetBtn: 'Resetar', uploadBtn: 'Enviar', dragNDropBox: 'Arraste e solte', attachPinBtn: 'Anexar Arquivo...', afterUploadMsg_success: 'Enviado com sucesso !', afterUploadMsg_error: 'Falha no envio !', sizeLimit: 'Tamanho máximo', }; /** * @ignore */ currentUploads = []; /** * @ignore */ fileNameIndex = true; /** * @ignore */ withCredentials = false; /** * @ignore */ autoUpload = true; /** * @ignore */ idDate = +new Date(); constructor(http) { this.http = http; } /** * @ignore */ ngOnChanges(changes) { // Track changes in Configuration and see if user has even provided Configuration. if (changes.config && this.config) { // Assign User Configurations to Library Properties. this.theme = this.config.theme || ''; this.id = this.config.id || parseInt((this.idDate / 10000).toString().split('.')[1], 10) + Math.floor(Math.random() * 20) * 10000; this.hideProgressBar = this.config.hideProgressBar || false; this.hideResetBtn = this.config.hideResetBtn || false; this.hideSelectBtn = this.config.hideSelectBtn || false; this.maxSize = (this.config.maxSize || 20) * 1024000; // mb to bytes. if (this.config.uploadAPI) { this.uploadAPI = this.config.uploadAPI.url; this.method = this.config.uploadAPI.method || 'POST'; this.formatsAllowed = this.config.formatsAllowed || '*'; this.multiple = this.config.multiple || false; this.headers = this.config.uploadAPI.headers || {}; this.params = this.config.uploadAPI.params || {}; this.responseType = this.config.uploadAPI.responseType || 'json'; this.withCredentials = this.config.uploadAPI.withCredentials || false; } this.formatsAllowedText = this.formatsAllowed === '*' ? '' : '(' + this.formatsAllowed + ')'; this.fileNameIndex = this.config.fileNameIndex === false ? false : true; this.autoUpload = this.config.autoUpload || false; if (this.config.replaceTexts) { this.replaceTexts = { ...this.replaceTexts, ...this.config.replaceTexts, }; } } // Reset when resetUpload value changes from false to true. if (changes.resetUpload) { if (changes.resetUpload.currentValue === true) { this.resetFileUpload(); } } } /* Função resetar componente */ resetFileUpload() { this.allowedFiles = []; this.Caption = []; this.notAllowedFiles = []; this.uploadMsg = false; this.enableUploadBtn = false; } /* Detectar mudança */ onChange(event) { this.fileSelected.emit(event); this.notAllowedFiles = []; const fileExtRegExp = /(?:\.([^.]+))?$/; let fileList; if (this.afterUpload || !this.multiple) { this.allowedFiles = []; this.Caption = []; this.afterUpload = false; } if (event.type === 'drop') { fileList = event.dataTransfer.files; } else { fileList = event.target.files || event.srcElement.files; } // 'forEach' does not exist on 'filelist' that's why this good old 'for' is used. // tslint:disable-next-line: for-of for (let i = 0; i < fileList.length; i++) { const _currentFileExt = fileExtRegExp.exec(fileList[i].name); const currentFileExt = typeof _currentFileExt[1] === 'string' ? _currentFileExt[1].toLowerCase() : ''; const isFormatValid = this.formatsAllowed.includes('*') ? true : this.formatsAllowed.includes(currentFileExt); const isSizeValid = fileList[i].size <= this.maxSize; // Check whether current file format and size is correct as specified in the configurations. if (isFormatValid && isSizeValid) { this.allowedFiles.push(fileList[i]); } else { this.notAllowedFiles.push({ fileName: fileList[i].name, fileSize: this.convertSize(fileList[i].size), errorMsg: !isFormatValid ? 'Invalid format' : 'Invalid size', }); } } // If there's any allowedFiles. if (this.allowedFiles.length > 0) { this.enableUploadBtn = true; // Upload the files directly if theme is attach pin (as upload btn is not there for this theme) or autoUpload is true. if (this.theme === 'attachPin' || this.autoUpload) { this.uploadFiles(); } } else { this.enableUploadBtn = false; } this.uploadMsg = false; this.uploadStarted = false; this.uploadPercent = 0; event.target.value = null; } /* Função para enviar arquivo para servidor */ uploadFiles() { this.progressBarShow = true; this.uploadStarted = true; this.notAllowedFiles = []; let isError = false; this.isAllowedFileSingle = this.allowedFiles.length <= 1; const formData = new FormData(); // Add data to be sent in this request this.allowedFiles.forEach((file, i) => { formData.append(this.Caption[i] || 'file' + (this.fileNameIndex ? i : ''), this.allowedFiles[i]); }); this.http .request(this.method.toUpperCase(), this.uploadAPI, { body: formData, reportProgress: true, observe: 'events', headers: this.headers, params: this.params, responseType: this.responseType, withCredentials: this.withCredentials, }) .subscribe((event) => { // Upload Progress if (event.type === HttpEventType.UploadProgress) { this.enableUploadBtn = false; // button should be disabled if process uploading const currentDone = event.loaded / event.total; this.uploadPercent = Math.round((event.loaded / event.total) * 100); } else if (event.type === HttpEventType.Response) { if (event.status === 200 || event.status === 201) { // Success this.progressBarShow = false; this.enableUploadBtn = false; this.uploadMsg = true; this.afterUpload = true; if (!isError) { this.uploadMsgText = this.replaceTexts.afterUploadMsg_success || 'Successfully Uploaded !'; this.uploadMsgClass = 'text-success lead'; } } else { // Failure isError = true; this.handleErrors(); } this.ApiResponse.emit(event); } else { //console.log('Event Other: ', event); } }, (error) => { // Failure isError = true; this.handleErrors(); this.ApiResponse.emit(error); }); } handleErrors() { this.progressBarShow = false; this.enableUploadBtn = false; this.uploadMsg = true; this.afterUpload = true; this.uploadMsgText = this.replaceTexts.afterUploadMsg_error || 'Error in uploading files'; this.uploadMsgClass = 'text-danger lead'; } removeFile(i, sf_na) { if (sf_na === 'sf') { this.allowedFiles.splice(i, 1); this.Caption.splice(i, 1); } else { this.notAllowedFiles.splice(i, 1); } if (this.allowedFiles.length === 0) { this.enableUploadBtn = false; } } convertSize(fileSize) { return fileSize < 1024000 ? (fileSize / 1024).toFixed(2) + ' KB' : (fileSize / 1024000).toFixed(2) + ' MB'; } attachpinOnclick() { const element = document.getElementById('sel' + this.id); if (element !== null) { element.click(); } } drop(event) { event.stopPropagation(); event.preventDefault(); this.onChange(event); } allowDrop(event) { event.stopPropagation(); event.preventDefault(); event.dataTransfer.dropEffect = 'copy'; } static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: UploadComponent, deps: [{ token: i1.HttpClient, skipSelf: true }], target: i0.ɵɵFactoryTarget.Component }); static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: UploadComponent, isStandalone: true, selector: "wco-file-upload", inputs: { description: "description", config: "config", resetUpload: "resetUpload" }, outputs: { ApiResponse: "apiResponse", fileSelected: "fileSelected" }, usesOnChanges: true, ngImport: i0, template: "<label for=\"sel{{id}}\" class=\"wco-form-upload\" (drop)=\"drop($event)\" (dragover)=\"allowDrop($event)\">\n <div class=\"wco-form-upload__info\">\n <span>Arraste-os aqui ou</span>\n <span>\n <span class=\"material-icons-outlined\">\nupload_file\n</span>\n <span>{{replaceTexts.selectFileBtn}}</span>\n </span>\n </div>\n <span class=\"upload__info\" *ngIf=\"!allowedFiles.length\" >{{description}}</span>\n <ng-container *ngIf=\"allowedFiles.length\">\n <span class=\"upload__info\" *ngFor=\"let sf of allowedFiles;let i=index\">\n {{sf.name}} <small>({{convertSize(sf.size)}})</small>\n </span>\n </ng-container>\n <input type=\"file\" id=\"sel{{id}}\" (change)=\"onChange($event)\" style=\"display: none\" title=\"Select file\"\n name=\"files[]\" [accept]=\"formatsAllowed\" [attr.multiple]=\"multiple ? '' : null\" />\n</label>", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: HttpClientModule }] }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: UploadComponent, decorators: [{ type: Component, args: [{ selector: 'wco-file-upload', standalone: true, imports: [CommonModule, HttpClientModule], template: "<label for=\"sel{{id}}\" class=\"wco-form-upload\" (drop)=\"drop($event)\" (dragover)=\"allowDrop($event)\">\n <div class=\"wco-form-upload__info\">\n <span>Arraste-os aqui ou</span>\n <span>\n <span class=\"material-icons-outlined\">\nupload_file\n</span>\n <span>{{replaceTexts.selectFileBtn}}</span>\n </span>\n </div>\n <span class=\"upload__info\" *ngIf=\"!allowedFiles.length\" >{{description}}</span>\n <ng-container *ngIf=\"allowedFiles.length\">\n <span class=\"upload__info\" *ngFor=\"let sf of allowedFiles;let i=index\">\n {{sf.name}} <small>({{convertSize(sf.size)}})</small>\n </span>\n </ng-container>\n <input type=\"file\" id=\"sel{{id}}\" (change)=\"onChange($event)\" style=\"display: none\" title=\"Select file\"\n name=\"files[]\" [accept]=\"formatsAllowed\" [attr.multiple]=\"multiple ? '' : null\" />\n</label>" }] }], ctorParameters: () => [{ type: i1.HttpClient, decorators: [{ type: SkipSelf }] }], propDecorators: { description: [{ type: Input }], config: [{ type: Input }], resetUpload: [{ type: Input }], ApiResponse: [{ type: Output, args: ['apiResponse'] }], fileSelected: [{ type: Output }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXBsb2FkLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL25neC1jb21wb25lbnRzL3NyYy9saWIvdXBsb2FkL3VwbG9hZC5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9uZ3gtY29tcG9uZW50cy9zcmMvbGliL3VwbG9hZC91cGxvYWQuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUNMLFNBQVMsRUFDVCxZQUFZLEVBQ1osS0FBSyxFQUVMLE1BQU0sRUFDTixRQUFRLEdBQ1QsTUFBTSxlQUFlLENBQUM7QUFFdkIsT0FBTyxFQUVMLGdCQUFnQixFQUNoQixhQUFhLEdBR2QsTUFBTSxzQkFBc0IsQ0FBQztBQUU5QixPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0saUJBQWlCLENBQUM7Ozs7QUFjL0MsTUFBTSxPQUFPLGVBQWU7SUErS007SUE5S2hDLG1DQUFtQztJQUMxQixXQUFXLEdBQ2xCLG1FQUFtRSxDQUFDO0lBQ3RFLHlGQUF5RjtJQUNoRixNQUFNLEdBQThCO1FBQzNDLFNBQVMsRUFBRTtZQUNULEdBQUcsRUFBRSxFQUFFO1lBQ1AsTUFBTSxFQUFFLE1BQU07WUFDZCxPQUFPLEVBQUU7Z0JBQ1AsY0FBYyxFQUFFLDBCQUEwQjthQUMzQztZQUNELFlBQVksRUFBRSxNQUFNO1lBQ3BCLGVBQWUsRUFBRSxLQUFLO1NBQ3ZCO0tBQ0YsQ0FBQztJQUVGOztPQUVHO0lBQ00sV0FBVyxHQUFHLEtBQUssQ0FBQztJQUU3Qjs7T0FFRztJQUNvQixXQUFXLEdBQUcsSUFBSSxZQUFZLEVBQUUsQ0FBQztJQUN4RDs7T0FFRztJQUNPLFlBQVksR0FBb0MsSUFBSSxZQUFZLEVBRXZFLENBQUM7SUFFSjs7T0FFRztJQUNILEtBQUssR0FBVyxFQUFFLENBQUM7SUFDbkI7O09BRUc7SUFDSCxFQUFFLEdBQVcsQ0FBQyxDQUFDO0lBQ2Y7O09BRUc7SUFDSCxlQUFlLEdBQVksS0FBSyxDQUFDO0lBQ2pDOztPQUVHO0lBQ0gsT0FBTyxHQUFXLEVBQUUsR0FBRyxPQUFPLENBQUMsQ0FBQyxlQUFlO0lBQy9DOztPQUVHO0lBQ0gsU0FBUyxHQUFXLEVBQUUsQ0FBQztJQUN2Qjs7T0FFRztJQUNILE1BQU0sR0FBVyxNQUFNLENBQUM7SUFDeEI7O09BRUc7SUFDSCxjQUFjLEdBQVcsR0FBRyxDQUFDO0lBQzdCOztPQUVHO0lBQ0gsa0JBQWtCLEdBQVcsRUFBRSxDQUFDO0lBQ2hDOztPQUVHO0lBQ0gsUUFBUSxHQUFZLEtBQUssQ0FBQztJQUMxQjs7T0FFRztJQUNILE9BQU8sR0FBMEQsRUFBRSxDQUFDO0lBQ3BFOztPQUVHO0lBQ0gsTUFBTSxHQUF3RCxFQUFFLENBQUM7SUFDakU7O09BRUc7SUFDSCxZQUFZLEdBQTZDLE1BQU0sQ0FBQztJQUNoRTs7T0FFRztJQUNILFlBQVksR0FBWSxLQUFLLENBQUM7SUFDOUI7O09BRUc7SUFDSCxhQUFhLEdBQVksS0FBSyxDQUFDO0lBQy9COztPQUVHO0lBQ0gsWUFBWSxHQUFXLEVBQUUsQ0FBQztJQUMxQjs7T0FFRztJQUNILGVBQWUsR0FJVCxFQUFFLENBQUM7SUFDVDs7T0FFRztJQUNILE9BQU8sR0FBYSxFQUFFLENBQUM7SUFDdkI7O09BRUc7SUFDSCxtQkFBbUIsR0FBRyxJQUFJLENBQUM7SUFDM0I7O09BRUc7SUFDSCxlQUFlLEdBQUcsS0FBSyxDQUFDO0lBQ3hCOztPQUVHO0lBQ0gsZUFBZSxHQUFHLEtBQUssQ0FBQztJQUN4Qjs7T0FFRztJQUNILFNBQVMsR0FBRyxLQUFLLENBQUM7SUFDbEI7O09BRUc7SUFDSCxXQUFXLEdBQUcsS0FBSyxDQUFDO0lBQ3BCOztPQUVHO0lBQ0gsYUFBYSxHQUFHLEtBQUssQ0FBQztJQUN0Qjs7T0FFRztJQUNILGFBQWEsR0FBVyxFQUFFLENBQUM7SUFDM0I7O09BRUc7SUFDSCxjQUFjLEdBQVcsY0FBYyxDQUFDO0lBQ3hDOztPQUVHO0lBQ0gsYUFBYSxHQUFXLENBQUMsQ0FBQztJQUMxQjs7T0FFRztJQUNILFlBQVksR0FBaUI7UUFDM0IsYUFBYSxFQUFFLG9CQUFvQjtRQUNuQyxRQUFRLEVBQUUsU0FBUztRQUNuQixTQUFTLEVBQUUsUUFBUTtRQUNuQixZQUFZLEVBQUUsaUJBQWlCO1FBQy9CLFlBQVksRUFBRSxtQkFBbUI7UUFDakMsc0JBQXNCLEVBQUUsdUJBQXVCO1FBQy9DLG9CQUFvQixFQUFFLGtCQUFrQjtRQUN4QyxTQUFTLEVBQUUsZ0JBQWdCO0tBQzVCLENBQUM7SUFDRjs7T0FFRztJQUNILGNBQWMsR0FBVSxFQUFFLENBQUM7SUFDM0I7O09BRUc7SUFDSCxhQUFhLEdBQUcsSUFBSSxDQUFDO0lBQ3JCOztPQUVHO0lBQ0gsZUFBZSxHQUFHLEtBQUssQ0FBQztJQUN4Qjs7T0FFRztJQUNILFVBQVUsR0FBRyxJQUFJLENBQUM7SUFDbEI7O09BRUc7SUFDSyxNQUFNLEdBQVcsQ0FBQyxJQUFJLElBQUksRUFBRSxDQUFDO0lBRXJDLFlBQWdDLElBQWdCO1FBQWhCLFNBQUksR0FBSixJQUFJLENBQVk7SUFBRyxDQUFDO0lBRXBEOztPQUVHO0lBQ0gsV0FBVyxDQUFDLE9BQVk7UUFDdEIsa0ZBQWtGO1FBQ2xGLElBQUksT0FBTyxDQUFDLE1BQU0sSUFBSSxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUM7WUFDbEMsb0RBQW9EO1lBQ3BELElBQUksQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxLQUFLLElBQUksRUFBRSxDQUFDO1lBQ3JDLElBQUksQ0FBQyxFQUFFO2dCQUNMLElBQUksQ0FBQyxNQUFNLENBQUMsRUFBRTtvQkFDZCxRQUFRLENBQUMsQ0FBQyxJQUFJLENBQUMsTUFBTSxHQUFHLEtBQUssQ0FBQyxDQUFDLFFBQVEsRUFBRSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUM7d0JBQzFELElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxHQUFHLEVBQUUsQ0FBQyxHQUFHLEtBQUssQ0FBQztZQUMzQyxJQUFJLENBQUMsZUFBZSxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsZUFBZSxJQUFJLEtBQUssQ0FBQztZQUM1RCxJQUFJLENBQUMsWUFBWSxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsWUFBWSxJQUFJLEtBQUssQ0FBQztZQUN0RCxJQUFJLENBQUMsYUFBYSxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsYUFBYSxJQUFJLEtBQUssQ0FBQztZQUN4RCxJQUFJLENBQUMsT0FBTyxHQUFHLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxPQUFPLElBQUksRUFBRSxDQUFDLEdBQUcsT0FBTyxDQUFDLENBQUMsZUFBZTtZQUNyRSxJQUFJLElBQUksQ0FBQyxNQUFNLENBQUMsU0FBUyxFQUFFLENBQUM7Z0JBQzFCLElBQUksQ0FBQyxTQUFTLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDO2dCQUMzQyxJQUFJLENBQUMsTUFBTSxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsU0FBUyxDQUFDLE1BQU0sSUFBSSxNQUFNLENBQUM7Z0JBQ3JELElBQUksQ0FBQyxjQUFjLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxjQUFjLElBQUksR0FBRyxDQUFDO2dCQUN4RCxJQUFJLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsUUFBUSxJQUFJLEtBQUssQ0FBQztnQkFDOUMsSUFBSSxDQUFDLE9BQU8sR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLFNBQVMsQ0FBQyxPQUFPLElBQUksRUFBRSxDQUFDO2dCQUNuRCxJQUFJLENBQUMsTUFBTSxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsU0FBUyxDQUFDLE1BQU0sSUFBSSxFQUFFLENBQUM7Z0JBQ2pELElBQUksQ0FBQyxZQUFZLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxTQUFTLENBQUMsWUFBWSxJQUFJLE1BQU0sQ0FBQztnQkFDakUsSUFBSSxDQUFDLGVBQWUsR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLFNBQVMsQ0FBQyxlQUFlLElBQUksS0FBSyxDQUFDO1lBQ3hFLENBQUM7WUFDRCxJQUFJLENBQUMsa0JBQWtCO2dCQUNyQixJQUFJLENBQUMsY0FBYyxLQUFLLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxHQUFHLEdBQUcsSUFBSSxDQUFDLGNBQWMsR0FBRyxHQUFHLENBQUM7WUFDckUsSUFBSSxDQUFDLGFBQWEsR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLGFBQWEsS0FBSyxLQUFLLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDO1lBQ3hFLElBQUksQ0FBQyxVQUFVLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxVQUFVLElBQUksS0FBSyxDQUFDO1lBQ2xELElBQUksSUFBSSxDQUFDLE1BQU0sQ0FBQyxZQUFZLEVBQUUsQ0FBQztnQkFDN0IsSUFBSSxDQUFDLFlBQVksR0FBRztvQkFDbEIsR0FBRyxJQUFJLENBQUMsWUFBWTtvQkFDcEIsR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLFlBQVk7aUJBQzVCLENBQUM7WUFDSixDQUFDO1FBQ0gsQ0FBQztRQUVELDJEQUEyRDtRQUMzRCxJQUFJLE9BQU8sQ0FBQyxXQUFXLEVBQUUsQ0FBQztZQUN4QixJQUFJLE9BQU8sQ0FBQyxXQUFXLENBQUMsWUFBWSxLQUFLLElBQUksRUFBRSxDQUFDO2dCQUM5QyxJQUFJLENBQUMsZUFBZSxFQUFFLENBQUM7WUFDekIsQ0FBQztRQUNILENBQUM7SUFDSCxDQUFDO0lBRUQsK0JBQStCO0lBQy9CLGVBQWU7UUFDYixJQUFJLENBQUMsWUFBWSxHQUFHLEVBQUUsQ0FBQztRQUN2QixJQUFJLENBQUMsT0FBTyxHQUFHLEVBQUUsQ0FBQztRQUNsQixJQUFJLENBQUMsZUFBZSxHQUFHLEVBQUUsQ0FBQztRQUMxQixJQUFJLENBQUMsU0FBUyxHQUFHLEtBQUssQ0FBQztRQUN2QixJQUFJLENBQUMsZUFBZSxHQUFHLEtBQUssQ0FBQztJQUMvQixDQUFDO0lBRUQsdUJBQXVCO0lBQ3ZCLFFBQVEsQ0FBQyxLQUFVO1FBQ2pCLElBQUksQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQzlCLElBQUksQ0FBQyxlQUFlLEdBQUcsRUFBRSxDQUFDO1FBQzFCLE1BQU0sYUFBYSxHQUFXLGlCQUFpQixDQUFDO1FBQ2hELElBQUksUUFBa0IsQ0FBQztRQUV2QixJQUFJLElBQUksQ0FBQyxXQUFXLElBQUksQ0FBQyxJQUFJLENBQUMsUUFBUSxFQUFFLENBQUM7WUFDdkMsSUFBSSxDQUFDLFlBQVksR0FBRyxFQUFFLENBQUM7WUFDdkIsSUFBSSxDQUFDLE9BQU8sR0FBRyxFQUFFLENBQUM7WUFDbEIsSUFBSSxDQUFDLFdBQVcsR0FBRyxLQUFLLENBQUM7UUFDM0IsQ0FBQztRQUVELElBQUksS0FBSyxDQUFDLElBQUksS0FBSyxNQUFNLEVBQUUsQ0FBQztZQUMxQixRQUFRLEdBQUcsS0FBSyxDQUFDLFlBQVksQ0FBQyxLQUFLLENBQUM7UUFDdEMsQ0FBQzthQUFNLENBQUM7WUFDTixRQUFRLEdBQUcsS0FBSyxDQUFDLE1BQU0sQ0FBQyxLQUFLLElBQUksS0FBSyxDQUFDLFVBQVUsQ0FBQyxLQUFLLENBQUM7UUFDMUQsQ0FBQztRQUVELGlGQUFpRjtRQUNqRixtQ0FBbUM7UUFDbkMsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLFFBQVEsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQztZQUN6QyxNQUFNLGVBQWUsR0FBUSxhQUFhLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUNsRSxNQUFNLGNBQWMsR0FDbEIsT0FBTyxlQUFlLENBQUMsQ0FBQyxDQUFDLEtBQUssUUFBUTtnQkFDcEMsQ0FBQyxDQUFDLGVBQWUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxXQUFXLEVBQUU7Z0JBQ2xDLENBQUMsQ0FBQyxFQUFFLENBQUM7WUFDVCxNQUFNLGFBQWEsR0FBRyxJQUFJLENBQUMsY0FBYyxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUM7Z0JBQ3JELENBQUMsQ0FBQyxJQUFJO2dCQUNOLENBQUMsQ0FBQyxJQUFJLENBQUMsY0FBYyxDQUFDLFFBQVEsQ0FBQyxjQUFjLENBQUMsQ0FBQztZQUVqRCxNQUFNLFdBQVcsR0FBRyxRQUFRLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxJQUFJLElBQUksQ0FBQyxPQUFPLENBQUM7WUFFckQsNEZBQTRGO1lBQzVGLElBQUksYUFBYSxJQUFJLFdBQVcsRUFBRSxDQUFDO2dCQUNqQyxJQUFJLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUN0QyxDQUFDO2lCQUFNLENBQUM7Z0JBQ04sSUFBSSxDQUFDLGVBQWUsQ0FBQyxJQUFJLENBQUM7b0JBQ3hCLFFBQVEsRUFBRSxRQUFRLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSTtvQkFDMUIsUUFBUSxFQUFFLElBQUksQ0FBQyxXQUFXLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQztvQkFDNUMsUUFBUSxFQUFFLENBQUMsYUFBYSxDQUFDLENBQUMsQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDLENBQUMsY0FBYztpQkFDN0QsQ0FBQyxDQUFDO1lBQ0wsQ0FBQztRQUNILENBQUM7UUFFRCwrQkFBK0I7UUFDL0IsSUFBSSxJQUFJLENBQUMsWUFBWSxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUUsQ0FBQztZQUNqQyxJQUFJLENBQUMsZUFBZSxHQUFHLElBQUksQ0FBQztZQUM1QixzSEFBc0g7WUFDdEgsSUFBSSxJQUFJLENBQUMsS0FBSyxLQUFLLFdBQVcsSUFBSSxJQUFJLENBQUMsVUFBVSxFQUFFLENBQUM7Z0JBQ2xELElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQztZQUNyQixDQUFDO1FBQ0gsQ0FBQzthQUFNLENBQUM7WUFDTixJQUFJLENBQUMsZUFBZSxHQUFHLEtBQUssQ0FBQztRQUMvQixDQUFDO1FBRUQsSUFBSSxDQUFDLFNBQVMsR0FBRyxLQUFLLENBQUM7UUFDdkIsSUFBSSxDQUFDLGFBQWEsR0FBRyxLQUFLLENBQUM7UUFDM0IsSUFBSSxDQUFDLGFBQWEsR0FBRyxDQUFDLENBQUM7UUFDdkIsS0FBSyxDQUFDLE1BQU0sQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDO0lBQzVCLENBQUM7SUFFRCw4Q0FBOEM7SUFDOUMsV0FBVztRQUNULElBQUksQ0FBQyxlQUFlLEdBQUcsSUFBSSxDQUFDO1FBQzVCLElBQUksQ0FBQyxhQUFhLEdBQUcsSUFBSSxDQUFDO1FBQzFCLElBQUksQ0FBQyxlQUFlLEdBQUcsRUFBRSxDQUFDO1FBQzFCLElBQUksT0FBTyxHQUFHLEtBQUssQ0FBQztRQUNwQixJQUFJLENBQUMsbUJBQW1CLEdBQUcsSUFBSSxDQUFDLFlBQVksQ0FBQyxNQUFNLElBQUksQ0FBQyxDQUFDO1FBQ3pELE1BQU0sUUFBUSxHQUFHLElBQUksUUFBUSxFQUFFLENBQUM7UUFFaEMsc0NBQXNDO1FBQ3RDLElBQUksQ0FBQyxZQUFZLENBQUMsT0FBTyxDQUFDLENBQUMsSUFBSSxFQUFFLENBQUMsRUFBRSxFQUFFO1lBQ3BDLFFBQVEsQ0FBQyxNQUFNLENBQ2IsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsSUFBSSxNQUFNLEdBQUcsQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUN6RCxJQUFJLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQyxDQUNyQixDQUFDO1FBQ0osQ0FBQyxDQUFDLENBQUM7UUFFSCxJQUFJLENBQUMsSUFBSTthQUNOLE9BQU8sQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLFdBQVcsRUFBRSxFQUFFLElBQUksQ0FBQyxTQUFTLEVBQUU7WUFDbEQsSUFBSSxFQUFFLFFBQVE7WUFDZCxjQUFjLEVBQUUsSUFBSTtZQUNwQixPQUFPLEVBQUUsUUFBUTtZQUNqQixPQUFPLEVBQUUsSUFBSSxDQUFDLE9BQU87WUFDckIsTUFBTSxFQUFFLElBQUksQ0FBQyxNQUFNO1lBQ25CLFlBQVksRUFBRSxJQUFJLENBQUMsWUFBWTtZQUMvQixlQUFlLEVBQUUsSUFBSSxDQUFDLGVBQWU7U0FDdEMsQ0FBQzthQUNELFNBQVMsQ0FDUixDQUFDLEtBQUssRUFBRSxFQUFFO1lBQ1Isa0JBQWtCO1lBQ2xCLElBQUksS0FBSyxDQUFDLElBQUksS0FBSyxhQUFhLENBQUMsY0FBYyxFQUFFLENBQUM7Z0JBQ2hELElBQUksQ0FBQyxlQUFlLEdBQUcsS0FBSyxDQUFDLENBQUMsaURBQWlEO2dCQUMvRSxNQUFNLFdBQVcsR0FBRyxLQUFLLENBQUMsTUFBTSxHQUFHLEtBQUssQ0FBQyxLQUFLLENBQUM7Z0JBQy9DLElBQUksQ0FBQyxhQUFhLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLEtBQUssQ0FBQyxNQUFNLEdBQUcsS0FBSyxDQUFDLEtBQUssQ0FBQyxHQUFHLEdBQUcsQ0FBQyxDQUFDO1lBQ3RFLENBQUM7aUJBQU0sSUFBSSxLQUFLLENBQUMsSUFBSSxLQUFLLGFBQWEsQ0FBQyxRQUFRLEVBQUUsQ0FBQztnQkFDakQsSUFBSSxLQUFLLENBQUMsTUFBTSxLQUFLLEdBQUcsSUFBSSxLQUFLLENBQUMsTUFBTSxLQUFLLEdBQUcsRUFBRSxDQUFDO29CQUNqRCxVQUFVO29CQUNWLElBQUksQ0FBQyxlQUFlLEdBQUcsS0FBSyxDQUFDO29CQUM3QixJQUFJLENBQUMsZUFBZSxHQUFHLEtBQUssQ0FBQztvQkFDN0IsSUFBSSxDQUFDLFNBQVMsR0FBRyxJQUFJLENBQUM7b0JBQ3RCLElBQUksQ0FBQyxXQUFXLEdBQUcsSUFBSSxDQUFDO29CQUN4QixJQUFJLENBQUMsT0FBTyxFQUFFLENBQUM7d0JBQ2IsSUFBSSxDQUFDLGFBQWE7NEJBQ2hCLElBQUksQ0FBQyxZQUFZLENBQUMsc0JBQXNCO2dDQUN4Qyx5QkFBeUIsQ0FBQzt3QkFDNUIsSUFBSSxDQUFDLGNBQWMsR0FBRyxtQkFBbUIsQ0FBQztvQkFDNUMsQ0FBQztnQkFDSCxDQUFDO3FCQUFNLENBQUM7b0JBQ04sVUFBVTtvQkFDVixPQUFPLEdBQUcsSUFBSSxDQUFDO29CQUNmLElBQUksQ0FBQyxZQUFZLEVBQUUsQ0FBQztnQkFDdEIsQ0FBQztnQkFDRCxJQUFJLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUMvQixDQUFDO2lCQUFNLENBQUM7Z0JBQ04sc0NBQXNDO1lBQ3hDLENBQUM7UUFDSCxDQUFDLEVBQ0QsQ0FBQyxLQUFLLEVBQUUsRUFBRTtZQUNSLFVBQVU7WUFDVixPQUFPLEdBQUcsSUFBSSxDQUFDO1lBQ2YsSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFDO1lBQ3BCLElBQUksQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQy9CLENBQUMsQ0FDRixDQUFDO0lBQ04sQ0FBQztJQUVELFlBQVk7UUFDVixJQUFJLENBQUMsZUFBZSxHQUFHLEtBQUssQ0FBQztRQUM3QixJQUFJLENBQUMsZUFBZSxHQUFHLEtBQUssQ0FBQztRQUM3QixJQUFJLENBQUMsU0FBUyxHQUFHLElBQUksQ0FBQztRQUN0QixJQUFJLENBQUMsV0FBVyxHQUFHLElBQUksQ0FBQztRQUN4QixJQUFJLENBQUMsYUFBYTtZQUNoQixJQUFJLENBQUMsWUFBWSxDQUFDLG9CQUFvQixJQUFJLDBCQUEwQixDQUFDO1FBQ3ZFLElBQUksQ0FBQyxjQUFjLEdBQUcsa0JBQWtCLENBQUM7SUFDM0MsQ0FBQztJQUVELFVBQVUsQ0FBQyxDQUFNLEVBQUUsS0FBVTtRQUMzQixJQUFJLEtBQUssS0FBSyxJQUFJLEVBQUUsQ0FBQztZQUNuQixJQUFJLENBQUMsWUFBWSxDQUFDLE1BQU0sQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7WUFDL0IsSUFBSSxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBQzVCLENBQUM7YUFBTSxDQUFDO1lBQ04sSUFBSSxDQUFDLGVBQWUsQ0FBQyxNQUFNLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBQ3BDLENBQUM7UUFFRCxJQUFJLElBQUksQ0FBQyxZQUFZLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBRSxDQUFDO1lBQ25DLElBQUksQ0FBQyxlQUFlLEdBQUcsS0FBSyxDQUFDO1FBQy9CLENBQUM7SUFDSCxDQUFDO0lBRUQsV0FBVyxDQUFDLFFBQWdCO1FBQzFCLE9BQU8sUUFBUSxHQUFHLE9BQU87WUFDdkIsQ0FBQyxDQUFDLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsR0FBRyxLQUFLO1lBQ3RDLENBQUMsQ0FBQyxDQUFDLFFBQVEsR0FBRyxPQUFPLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLEdBQUcsS0FBSyxDQUFDO0lBQzlDLENBQUM7SUFFRCxnQkFBZ0I7UUFDZCxNQUFNLE9BQU8sR0FBRyxRQUFRLENBQUMsY0FBYyxDQUFDLEtBQUssR0FBRyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUM7UUFDekQsSUFBSSxPQUFPLEtBQUssSUFBSSxFQUFFLENBQUM7WUFDckIsT0FBTyxDQUFDLEtBQUssRUFBRSxDQUFDO1FBQ2xCLENBQUM7SUFDSCxDQUFDO0lBRUQsSUFBSSxDQUFDLEtBQVU7UUFDYixLQUFLLENBQUMsZUFBZSxFQUFFLENBQUM7UUFDeEIsS0FBSyxDQUFDLGNBQWMsRUFBRSxDQUFDO1FBQ3ZCLElBQUksQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDdkIsQ0FBQztJQUVELFNBQVMsQ0FBQyxLQUFVO1FBQ2xCLEtBQUssQ0FBQyxlQUFlLEVBQUUsQ0FBQztRQUN4QixLQUFLLENBQUMsY0FBYyxFQUFFLENBQUM7UUFDdkIsS0FBSyxDQUFDLFlBQVksQ0FBQyxVQUFVLEdBQUcsTUFBTSxDQUFDO0lBQ3pDLENBQUM7d0dBdFpVLGVBQWU7NEZBQWYsZUFBZSw2UEMvQjVCLHcyQkFrQlEseUREU0ksWUFBWSwrUEFBRSxnQkFBZ0I7OzRGQUk3QixlQUFlO2tCQVAzQixTQUFTOytCQUNFLGlCQUFpQixjQUNmLElBQUksV0FDUCxDQUFDLFlBQVksRUFBRSxnQkFBZ0IsQ0FBQzs7MEJBbUw1QixRQUFRO3lDQTdLWixXQUFXO3NCQUFuQixLQUFLO2dCQUdHLE1BQU07c0JBQWQsS0FBSztnQkFlRyxXQUFXO3NCQUFuQixLQUFLO2dCQUtpQixXQUFXO3NCQUFqQyxNQUFNO3VCQUFDLGFBQWE7Z0JBSVgsWUFBWTtzQkFBckIsTUFBTSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gIENvbXBvbmVudCxcbiAgRXZlbnRFbWl0dGVyLFxuICBJbnB1dCxcbiAgT25DaGFuZ2VzLFxuICBPdXRwdXQsXG4gIFNraXBTZWxmLFxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcblxuaW1wb3J0IHtcbiAgSHR0cENsaWVudCxcbiAgSHR0cENsaWVudE1vZHVsZSxcbiAgSHR0cEV2ZW50VHlwZSxcbiAgSHR0cEhlYWRlcnMsXG4gIEh0dHBQYXJhbXMsXG59IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbi9odHRwJztcblxuaW1wb3J0IHsgQ29tbW9uTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcbmltcG9ydCB7XG4gIEFuZ3VsYXJGaWxlVXBsb2FkZXJDb25maWcsXG4gIFJlcGxhY2VUZXh0cyxcbiAgVXBsb2FkSW5mb1R5cGVzLFxufSBmcm9tICcuL3VwbG9hZC50eXBlcyc7XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ3djby1maWxlLXVwbG9hZCcsXG4gIHN0YW5kYWxvbmU6IHRydWUsXG4gIGltcG9ydHM6IFtDb21tb25Nb2R1bGUsIEh0dHBDbGllbnRNb2R1bGVdLFxuICB0ZW1wbGF0ZVVybDogJy4vdXBsb2FkLmNvbXBvbmVudC5odG1sJyxcbiAgc3R5bGVVcmxzOiBbJy4vdXBsb2FkLmNvbXBvbmVudC5zY3NzJ10sXG59KVxuZXhwb3J0IGNsYXNzIFVwbG9hZENvbXBvbmVudCBpbXBsZW1lbnRzIE9uQ2hhbmdlcyB7XG4gIC8qIFRleHRvIGRlIGRlc2NyacOnw6NvIGRvIGFycXVpdm8gKi9cbiAgQElucHV0KCkgZGVzY3JpcHRpb246IHN0cmluZyA9XG4gICAgJyhYWCBNQiBkZSB0YW1hbmhvIG3DoXhpbW8gZSDDqSBwZXJtaXRpZG8gcXVhbHF1ZXIgdGlwbyBkZSBhcnF1aXZvcyknO1xuICAvKiBjb25maWcgPEFuZ3VsYXJGaWxlVXBsb2FkZXJDb25maWc+IGNvbmZpZ3VyYcOnw6NvIGRvIGNvbXBvbmVudGUgcHJpbmNpcGFpcyBwYXLDom1ldHJvcyAqL1xuICBASW5wdXQoKSBjb25maWc6IEFuZ3VsYXJGaWxlVXBsb2FkZXJDb25maWcgPSB7XG4gICAgdXBsb2FkQVBJOiB7XG4gICAgICB1cmw6ICcnLFxuICAgICAgbWV0aG9kOiAnUE9TVCcsXG4gICAgICBoZWFkZXJzOiB7XG4gICAgICAgICdDb250ZW50LVR5cGUnOiAndGV4dC9wbGFpbjtjaGFyc2V0PVVURi04JyxcbiAgICAgIH0sXG4gICAgICByZXNwb25zZVR5cGU6ICdqc29uJyxcbiAgICAgIHdpdGhDcmVkZW50aWFsczogZmFsc2UsXG4gICAgfSxcbiAgfTtcblxuICAvKlxuICAgKiBPcMOnw6NvIGRlIHJlc2V0YXIgbyBjb21wb25lbnRlXG4gICAqL1xuICBASW5wdXQoKSByZXNldFVwbG9hZCA9IGZhbHNlO1xuXG4gIC8qXG4gICAqIEV2ZW50byBSZXNwb3N0YSBkYSByZXF1aXNpw6fDo28gc2VuZG8gc3VjZXNzbyBvdSBlcnJvXG4gICAqL1xuICBAT3V0cHV0KCdhcGlSZXNwb25zZScpIEFwaVJlc3BvbnNlID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuICAvKlxuICAgKiBFdmVudG8gamF2YXNjcmlwdCBwdXJvIHBhcmEgcmV0b3JubyBkbyBhcnF1aXZvXG4gICAqL1xuICBAT3V0cHV0KCkgZmlsZVNlbGVjdGVkOiBFdmVudEVtaXR0ZXI8VXBsb2FkSW5mb1R5cGVzW10+ID0gbmV3IEV2ZW50RW1pdHRlcjxcbiAgICBVcGxvYWRJbmZvVHlwZXNbXVxuICA+KCk7XG5cbiAgLyoqXG4gICAqIEBpZ25vcmVcbiAgICovXG4gIHRoZW1lOiBzdHJpbmcgPSAnJztcbiAgLyoqXG4gICAqIEBpZ25vcmVcbiAgICovXG4gIGlkOiBudW1iZXIgPSAwO1xuICAvKipcbiAgICogQGlnbm9yZVxuICAgKi9cbiAgaGlkZVByb2dyZXNzQmFyOiBib29sZWFuID0gZmFsc2U7XG4gIC8qKlxuICAgKiBAaWdub3JlXG4gICAqL1xuICBtYXhTaXplOiBudW1iZXIgPSAyMCAqIDEwMjQwMDA7IC8vIG1iIHRvIGJ5dGVzLlxuICAvKipcbiAgICogQGlnbm9yZVxuICAgKi9cbiAgdXBsb2FkQVBJOiBzdHJpbmcgPSAnJztcbiAgLyoqXG4gICAqIEBpZ25vcmVcbiAgICovXG4gIG1ldGhvZDogc3RyaW5nID0gJ1BPU1QnO1xuICAvKipcbiAgICogQGlnbm9yZVxuICAgKi9cbiAgZm9ybWF0c0FsbG93ZWQ6IHN0cmluZyA9ICcqJztcbiAgLyoqXG4gICAqIEBpZ25vcmVcbiAgICovXG4gIGZvcm1hdHNBbGxvd2VkVGV4dDogc3RyaW5nID0gJyc7XG4gIC8qKlxuICAgKiBAaWdub3JlXG4gICAqL1xuICBtdWx0aXBsZTogYm9vbGVhbiA9IGZhbHNlO1xuICAvKipcbiAgICogQGlnbm9yZVxuICAgKi9cbiAgaGVhZGVyczogSHR0cEhlYWRlcnMgfCB7IFtoZWFkZXI6IHN0cmluZ106IHN0cmluZyB8IHN0cmluZ1tdIH0gPSB7fTtcbiAgLyoqXG4gICAqIEBpZ25vcmVcbiAgICovXG4gIHBhcmFtczogSHR0cFBhcmFtcyB8IHsgW3BhcmFtOiBzdHJpbmddOiBzdHJpbmcgfCBzdHJpbmdbXSB9ID0ge307XG4gIC8qKlxuICAgKiBAaWdub3JlXG4gICAqL1xuICByZXNwb25zZVR5cGU6ICdqc29uJyB8ICdhcnJheWJ1ZmZlcicgfCAnYmxvYicgfCAndGV4dCcgPSAnYmxvYic7XG4gIC8qKlxuICAgKiBAaWdub3JlXG4gICAqL1xuICBoaWRlUmVzZXRCdG46IGJvb2xlYW4gPSBmYWxzZTtcbiAgLyoqXG4gICAqIEBpZ25vcmVcbiAgICovXG4gIGhpZGVTZWxlY3RCdG46IGJvb2xlYW4gPSBmYWxzZTtcbiAgLyoqXG4gICAqIEBpZ25vcmVcbiAgICovXG4gIGFsbG93ZWRGaWxlczogRmlsZVtdID0gW107XG4gIC8qKlxuICAgKiBAaWdub3JlXG4gICAqL1xuICBub3RBbGxvd2VkRmlsZXM6IHtcbiAgICBmaWxlTmFtZTogc3RyaW5nO1xuICAgIGZpbGVTaXplOiBzdHJpbmc7XG4gICAgZXJyb3JNc2c6IHN0cmluZztcbiAgfVtdID0gW107XG4gIC8qKlxuICAgKiBAaWdub3JlXG4gICAqL1xuICBDYXB0aW9uOiBzdHJpbmdbXSA9IFtdO1xuICAvKipcbiAgICogQGlnbm9yZVxuICAgKi9cbiAgaXNBbGxvd2VkRmlsZVNpbmdsZSA9IHRydWU7XG4gIC8qKlxuICAgKiBAaWdub3JlXG4gICAqL1xuICBwcm9ncmVzc0JhclNob3cgPSBmYWxzZTtcbiAgLyoqXG4gICAqIEBpZ25vcmVcbiAgICovXG4gIGVuYWJsZVVwbG9hZEJ0biA9IGZhbHNlO1xuICAvKipcbiAgICogQGlnbm9yZVxuICAgKi9cbiAgdXBsb2FkTXNnID0gZmFsc2U7XG4gIC8qKlxuICAgKiBAaWdub3JlXG4gICAqL1xuICBhZnRlclVwbG9hZCA9IGZhbHNlO1xuICAvKipcbiAgICogQGlnbm9yZVxuICAgKi9cbiAgdXBsb2FkU3RhcnRlZCA9IGZhbHNlO1xuICAvKipcbiAgICogQGlnbm9yZVxuICAgKi9cbiAgdXBsb2FkTXNnVGV4dDogc3RyaW5nID0gJyc7XG4gIC8qKlxuICAgKiBAaWdub3JlXG4gICAqL1xuICB1cGxvYWRNc2dDbGFzczogc3RyaW5nID0gJ3RleHQtc3VjY2Vzcyc7XG4gIC8qKlxuICAgKiBAaWdub3JlXG4gICAqL1xuICB1cGxvYWRQZXJjZW50OiBudW1iZXIgPSAwO1xuICAvKipcbiAgICogQGlnbm9yZVxuICAgKi9cbiAgcmVwbGFjZVRleHRzOiBSZXBsYWNlVGV4dHMgPSB7XG4gICAgc2VsZWN0RmlsZUJ0bjogJ1NlbGVjaW9uYXIgQXJxdWl2bycsXG4gICAgcmVzZXRCdG46ICdSZXNldGFyJyxcbiAgICB1cGxvYWRCdG46ICdFbnZpYXInLFxuICAgIGRyYWdORHJvcEJveDogJ0FycmFzdGUgZSBzb2x0ZScsXG4gICAgYXR0YWNoUGluQnRuOiAnQW5leGFyIEFycXVpdm8uLi4nLFxuICAgIGFmdGVyVXBsb2FkTXNnX3N1Y2Nlc3M6ICdFbnZpYWRvIGNvbSBzdWNlc3NvICEnLFxuICAgIGFmdGVyVXBsb2FkTXNnX2Vycm9yOiAnRmFsaGEgbm8gZW52aW8gIScsXG4gICAgc2l6ZUxpbWl0OiAnVGFtYW5obyBtw6F4aW1vJyxcbiAgfTtcbiAgLyoqXG4gICAqIEBpZ25vcmVcbiAgICovXG4gIGN1cnJlbnRVcGxvYWRzOiBhbnlbXSA9IFtdO1xuICAvKipcbiAgICogQGlnbm9yZVxuICAgKi9cbiAgZmlsZU5hbWVJbmRleCA9IHRydWU7XG4gIC8qKlxuICAgKiBAaWdub3JlXG4gICAqL1xuICB3aXRoQ3JlZGVudGlhbHMgPSBmYWxzZTtcbiAgLyoqXG4gICAqIEBpZ25vcmVcbiAgICovXG4gIGF1dG9VcGxvYWQgPSB0cnVlO1xuICAvKipcbiAgICogQGlnbm9yZVxuICAgKi9cbiAgcHJpdmF0ZSBpZERhdGU6IG51bWJlciA9ICtuZXcgRGF0ZSgpO1xuXG4gIGNvbnN0cnVjdG9yKEBTa2lwU2VsZigpIHByaXZhdGUgaHR0cDogSHR0cENsaWVudCkge31cblxuICAvKipcbiAgICogQGlnbm9yZVxuICAgKi9cbiAgbmdPbkNoYW5nZXMoY2hhbmdlczogYW55KSB7XG4gICAgLy8gVHJhY2sgY2hhbmdlcyBpbiBDb25maWd1cmF0aW9uIGFuZCBzZWUgaWYgdXNlciBoYXMgZXZlbiBwcm92aWRlZCBDb25maWd1cmF0aW9uLlxuICAgIGlmIChjaGFuZ2VzLmNvbmZpZyAmJiB0aGlzLmNvbmZpZykge1xuICAgICAgLy8gQXNzaWduIFVzZXIgQ29uZmlndXJhdGlvbnMgdG8gTGlicmFyeSBQcm9wZXJ0aWVzLlxuICAgICAgdGhpcy50aGVtZSA9IHRoaXMuY29uZmlnLnRoZW1lIHx8ICcnO1xuICAgICAgdGhpcy5pZCA9XG4gICAgICAgIHRoaXMuY29uZmlnLmlkIHx8XG4gICAgICAgIHBhcnNlSW50KCh0aGlzLmlkRGF0ZSAvIDEwMDAwKS50b1N0cmluZygpLnNwbGl0KCcuJylbMV0sIDEwKSArXG4gICAgICAgICAgTWF0aC5mbG9vcihNYXRoLnJhbmRvbSgpICogMjApICogMTAwMDA7XG4gICAgICB0aGlzLmhpZGVQcm9ncmVzc0JhciA9IHRoaXMuY29uZmlnLmhpZGVQcm9ncmVzc0JhciB8fCBmYWxzZTtcbiAgICAgIHRoaXMuaGlkZVJlc2V0QnRuID0gdGhpcy5jb25maWcuaGlkZVJlc2V0QnRuIHx8IGZhbHNlO1xuICAgICAgdGhpcy5oaWRlU2VsZWN0QnRuID0gdGhpcy5jb25maWcuaGlkZVNlbGVjdEJ0biB8fCBmYWxzZTtcbiAgICAgIHRoaXMubWF4U2l6ZSA9ICh0aGlzLmNvbmZpZy5tYXhTaXplIHx8IDIwKSAqIDEwMjQwMDA7IC8vIG1iIHRvIGJ5dGVzLlxuICAgICAgaWYgKHRoaXMuY29uZmlnLnVwbG9hZEFQSSkge1xuICAgICAgICB0aGlzLnVwbG9hZEFQSSA9IHRoaXMuY29uZmlnLnVwbG9hZEFQSS51cmw7XG4gICAgICAgIHRoaXMubWV0aG9kID0gdGhpcy5jb25maWcudXBsb2FkQVBJLm1ldGhvZCB8fCAnUE9TVCc7XG4gICAgICAgIHRoaXMuZm9ybWF0c0FsbG93ZWQgPSB0aGlzLmNvbmZpZy5mb3JtYXRzQWxsb3dlZCB8fCAnKic7XG4gICAgICAgIHRoaXMubXVsdGlwbGUgPSB0aGlzLmNvbmZpZy5tdWx0aXBsZSB8fCBmYWxzZTtcbiAgICAgICAgdGhpcy5oZWFkZXJzID0gdGhpcy5jb25maWcudXBsb2FkQVBJLmhlYWRlcnMgfHwge307XG4gICAgICAgIHRoaXMucGFyYW1zID0gdGhpcy5jb25maWcudXBsb2FkQVBJLnBhcmFtcyB8fCB7fTtcbiAgICAgICAgdGhpcy5yZXNwb25zZVR5cGUgPSB0aGlzLmNvbmZpZy51cGxvYWRBUEkucmVzcG9uc2VUeXBlIHx8ICdqc29uJztcbiAgICAgICAgdGhpcy53aXRoQ3JlZGVudGlhbHMgPSB0aGlzLmNvbmZpZy51cGxvYWRBUEkud2l0aENyZWRlbnRpYWxzIHx8IGZhbHNlO1xuICAgICAgfVxuICAgICAgdGhpcy5mb3JtYXRzQWxsb3dlZFRleHQgPVxuICAgICAgICB0aGlzLmZvcm1hdHNBbGxvd2VkID09PSAnKicgPyAnJyA6ICcoJyArIHRoaXMuZm9ybWF0c0FsbG93ZWQgKyAnKSc7XG4gICAgICB0aGlzLmZpbGVOYW1lSW5kZXggPSB0aGlzLmNvbmZpZy5maWxlTmFtZUluZGV4ID09PSBmYWxzZSA/IGZhbHNlIDogdHJ1ZTtcbiAgICAgIHRoaXMuYXV0b1VwbG9hZCA9IHRoaXMuY29uZmlnLmF1dG9VcGxvYWQgfHwgZmFsc2U7XG4gICAgICBpZiAodGhpcy5jb25maWcucmVwbGFjZVRleHRzKSB7XG4gICAgICAgIHRoaXMucmVwbGFjZVRleHRzID0ge1xuICAgICAgICAgIC4uLnRoaXMucmVwbGFjZVRleHRzLFxuICAgICAgICAgIC4uLnRoaXMuY29uZmlnLnJlcGxhY2VUZXh0cyxcbiAgICAgICAgfTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBSZXNldCB3aGVuIHJlc2V0VXBsb2FkIHZhbHVlIGNoYW5nZXMgZnJvbSBmYWxzZSB0byB0cnVlLlxuICAgIGlmIChjaGFuZ2VzLnJlc2V0VXBsb2FkKSB7XG4gICAgICBpZiAoY2hhbmdlcy5yZXNldFVwbG9hZC5jdXJyZW50VmFsdWUgPT09IHRydWUpIHtcbiAgICAgICAgdGhpcy5yZXNldEZpbGVVcGxvYWQoKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvKiBGdW7Dp8OjbyByZXNldGFyIGNvbXBvbmVudGUgKi9cbiAgcmVzZXRGaWxlVXBsb2FkKCkge1xuICAgIHRoaXMuYWxsb3dlZEZpbGVzID0gW107XG4gICAgdGhpcy5DYXB0aW9uID0gW107XG4gICAgdGhpcy5ub3RBbGxvd2VkRmlsZXMgPSBbXTtcbiAgICB0aGlzLnVwbG9hZE1zZyA9IGZhbHNlO1xuICAgIHRoaXMuZW5hYmxlVXBsb2FkQnRuID0gZmFsc2U7XG4gIH1cblxuICAvKiBEZXRlY3RhciBtdWRhbsOnYSAgKi9cbiAgb25DaGFuZ2UoZXZlbnQ6IGFueSkge1xuICAgIHRoaXMuZmlsZVNlbGVjdGVkLmVtaXQoZXZlbnQpO1xuICAgIHRoaXMubm90QWxsb3dlZEZpbGVzID0gW107XG4gICAgY29uc3QgZmlsZUV4dFJlZ0V4cDogUmVnRXhwID0gLyg/OlxcLihbXi5dKykpPyQvO1xuICAgIGxldCBmaWxlTGlzdDogRmlsZUxpc3Q7XG5cbiAgICBpZiAodGhpcy5hZnRlclVwbG9hZCB8fCAhdGhpcy5tdWx0aXBsZSkge1xuICAgICAgdGhpcy5hbGxvd2VkRmlsZXMgPSBbXTtcbiAgICAgIHRoaXMuQ2FwdGlvbiA9IFtdO1xuICAgICAgdGhpcy5hZnRlclVwbG9hZCA9IGZhbHNlO1xuICAgIH1cblxuICAgIGlmIChldmVudC50eXBlID09PSAnZHJvcCcpIHtcbiAgICAgIGZpbGVMaXN0ID0gZXZlbnQuZGF0YVRyYW5zZmVyLmZpbGVzO1xuICAgIH0gZWxzZSB7XG4gICAgICBmaWxlTGlzdCA9IGV2ZW50LnRhcmdldC5maWxlcyB8fCBldmVudC5zcmNFbGVtZW50LmZpbGVzO1xuICAgIH1cblxuICAgIC8vICdmb3JFYWNoJyBkb2VzIG5vdCBleGlzdCBvbiAnZmlsZWxpc3QnIHRoYXQncyB3aHkgdGhpcyBnb29kIG9sZCAnZm9yJyBpcyB1c2VkLlxuICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTogZm9yLW9mXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBmaWxlTGlzdC5sZW5ndGg7IGkrKykge1xuICAgICAgY29uc3QgX2N1cnJlbnRGaWxlRXh0OiBhbnkgPSBmaWxlRXh0UmVnRXhwLmV4ZWMoZmlsZUxpc3RbaV0ubmFtZSk7XG4gICAgICBjb25zdCBjdXJyZW50RmlsZUV4dCA9XG4gICAgICAgIHR5cGVvZiBfY3VycmVudEZpbGVFeHRbMV0gPT09ICdzdHJpbmcnXG4gICAgICAgICAgPyBfY3VycmVudEZpbGVFeHRbMV0udG9Mb3dlckNhc2UoKVxuICAgICAgICAgIDogJyc7XG4gICAgICBjb25zdCBpc0Zvcm1hdFZhbGlkID0gdGhpcy5mb3JtYXRzQWxsb3dlZC5pbmNsdWRlcygnKicpXG4gICAgICAgID8gdHJ1ZVxuICAgICAgICA6IHRoaXMuZm9ybWF0c0FsbG93ZWQuaW5jbHVkZXMoY3VycmVudEZpbGVFeHQpO1xuXG4gICAgICBjb25zdCBpc1NpemVWYWxpZCA9IGZpbGVMaXN0W2ldLnNpemUgPD0gdGhpcy5tYXhTaXplO1xuXG4gICAgICAvLyBDaGVjayB3aGV0aGVyIGN1cnJlbnQgZmlsZSBmb3JtYXQgYW5kIHNpemUgaXMgY29ycmVjdCBhcyBzcGVjaWZpZWQgaW4gdGhlIGNvbmZpZ3VyYXRpb25zLlxuICAgICAgaWYgKGlzRm9ybWF0VmFsaWQgJiYgaXNTaXplVmFsaWQpIHtcbiAgICAgICAgdGhpcy5hbGxvd2VkRmlsZXMucHVzaChmaWxlTGlzdFtpXSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLm5vdEFsbG93ZWRGaWxlcy5wdXNoKHtcbiAgICAgICAgICBmaWxlTmFtZTogZmlsZUxpc3RbaV0ubmFtZSxcbiAgICAgICAgICBmaWxlU2l6ZTogdGhpcy5jb252ZXJ0U2l6ZShmaWxlTGlzdFtpXS5zaXplKSxcbiAgICAgICAgICBlcnJvck1zZzogIWlzRm9ybWF0VmFsaWQgPyAnSW52YWxpZCBmb3JtYXQnIDogJ0ludmFsaWQgc2l6ZScsXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIElmIHRoZXJlJ3MgYW55IGFsbG93ZWRGaWxlcy5cbiAgICBpZiAodGhpcy5hbGxvd2VkRmlsZXMubGVuZ3RoID4gMCkge1xuICAgICAgdGhpcy5lbmFibGVVcGxvYWRCdG4gPSB0cnVlO1xuICAgICAgLy8gVXBsb2FkIHRoZSBmaWxlcyBkaXJlY3RseSBpZiB0aGVtZSBpcyBhdHRhY2ggcGluIChhcyB1cGxvYWQgYnRuIGlzIG5vdCB0aGVyZSBmb3IgdGhpcyB0aGVtZSkgb3IgYXV0b1VwbG9hZCBpcyB0cnVlLlxuICAgICAgaWYgKHRoaXMudGhlbWUgPT09ICdhdHRhY2hQaW4nIHx8IHRoaXMuYXV0b1VwbG9hZCkge1xuICAgICAgICB0aGlzLnVwbG9hZEZpbGVzKCk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuZW5hYmxlVXBsb2FkQnRuID0gZmFsc2U7XG4gICAgfVxuXG4gICAgdGhpcy51cGxvYWRNc2cgPSBmYWxzZTtcbiAgICB0aGlzLnVwbG9hZFN0YXJ0ZWQgPSBmYWxzZTtcbiAgICB0aGlzLnVwbG9hZFBlcmNlbnQgPSAwO1xuICAgIGV2ZW50LnRhcmdldC52YWx1ZSA9IG51bGw7XG4gIH1cblxuICAvKiBGdW7Dp8OjbyBwYXJhIGVudmlhciBhcnF1aXZvIHBhcmEgc2Vydmlkb3IgKi9cbiAgdXBsb2FkRmlsZXMoKSB7XG4gICAgdGhpcy5wcm9ncmVzc0JhclNob3cgPSB0cnVlO1xuICAgIHRoaXMudXBsb2FkU3RhcnRlZCA9IHRydWU7XG4gICAgdGhpcy5ub3RBbGxvd2VkRmlsZXMgPSBbXTtcbiAgICBsZXQgaXNFcnJvciA9IGZhbHNlO1xuICAgIHRoaXMuaXNBbGxvd2VkRmlsZVNpbmdsZSA9IHRoaXMuYWxsb3dlZEZpbGVzLmxlbmd0aCA8PSAxO1xuICAgIGNvbnN0IGZvcm1EYXRhID0gbmV3IEZvcm1EYXRhKCk7XG5cbiAgICAvLyBBZGQgZGF0YSB0byBiZSBzZW50IGluIHRoaXMgcmVxdWVzdFxuICAgIHRoaXMuYWxsb3dlZEZpbGVzLmZvckVhY2goKGZpbGUsIGkpID0+IHtcbiAgICAgIGZvcm1EYXRhLmFwcGVuZChcbiAgICAgICAgdGhpcy5DYXB0aW9uW2ldIHx8ICdmaWxlJyArICh0aGlzLmZpbGVOYW1lSW5kZXggPyBpIDogJycpLFxuICAgICAgICB0aGlzLmFsbG93ZWRGaWxlc1tpXVxuICAgICAgKTtcbiAgICB9KTtcblxuICAgIHRoaXMuaHR0cFxuICAgICAgLnJlcXVlc3QodGhpcy5tZXRob2QudG9VcHBlckNhc2UoKSwgdGhpcy51cGxvYWRBUEksIHtcbiAgICAgICAgYm9keTogZm9ybURhdGEsXG4gICAgICAgIHJlcG9ydFByb2dyZXNzOiB0cnVlLFxuICAgICAgICBvYnNlcnZlOiAnZXZlbnRzJyxcbiAgICAgICAgaGVhZGVyczogdGhpcy5oZWFkZXJzLFxuICAgICAgICBwYXJhbXM6IHRoaXMucGFyYW1zLFxuICAgICAgICByZXNwb25zZVR5cGU6IHRoaXMucmVzcG9uc2VUeXBlLFxuICAgICAgICB3aXRoQ3JlZGVudGlhbHM6IHRoaXMud2l0aENyZWRlbnRpYWxzLFxuICAgICAgfSlcbiAgICAgIC5zdWJzY3JpYmUoXG4gICAgICAgIChldmVudCkgPT4ge1xuICAgICAgICAgIC8vIFVwbG9hZCBQcm9ncmVzc1xuICAgICAgICAgIGlmIChldmVudC50eXBlID09PSBIdHRwRXZlbnRUeXBlLlVwbG9hZFByb2dyZXNzKSB7XG4gICAgICAgICAgICB0aGlzLmVuYWJsZVVwbG9hZEJ0biA9IGZhbHNlOyAvLyBidXR0b24gc2hvdWxkIGJlIGRpc2FibGVkIGlmIHByb2Nlc3MgdXBsb2FkaW5nXG4gICAgICAgICAgICBjb25zdCBjdXJyZW50RG9uZSA9IGV2ZW50LmxvYWRlZCAvIGV2ZW50LnRvdGFsO1xuICAgICAgICAgICAgdGhpcy51cGxvYWRQZXJjZW50ID0gTWF0aC5yb3VuZCgoZXZlbnQubG9hZGVkIC8gZXZlbnQudG90YWwpICogMTAwKTtcbiAgICAgICAgICB9IGVsc2UgaWYgKGV2ZW50LnR5cGUgPT09IEh0dHBFdmVudFR5cGUuUmVzcG9uc2UpIHtcbiAgICAgICAgICAgIGlmIChldmVudC5zdGF0dXMgPT09IDIwMCB8fCBldmVudC5zdGF0dXMgPT09IDIwMSkge1xuICAgICAgICAgICAgICAvLyBTdWNjZXNzXG4gICAgICAgICAgICAgIHRoaXMucHJvZ3Jlc3NCYXJTaG93ID0gZmFsc2U7XG4gICAgICAgICAgICAgIHRoaXMuZW5hYmxlVXBsb2FkQnRuID0gZmFsc2U7XG4gICAgICAgICAgICAgIHRoaXMudXBsb2FkTXNnID0gdHJ1ZTtcbiAgICAgICAgICAgICAgdGhpcy5hZnRlclVwbG9hZCA9IHRydWU7XG4gICAgICAgICAgICAgIGlmICghaXNFcnJvcikge1xuICAgICAgICAgICAgICAgIHRoaXMudXBsb2FkTXNnVGV4dCA9XG4gICAgICAgICAgICAgICAgICB0aGlzLnJlcGxhY2VUZXh0cy5hZnRlclVwbG9hZE1zZ19zdWNjZXNzIHx8XG4gICAgICAgICAgICAgICAgICAnU3VjY2Vzc2Z1bGx5IFVwbG9hZGVkICEnO1xuICAgICAgICAgICAgICAgIHRoaXMudXBsb2FkTXNnQ2xhc3MgPSAndGV4dC1zdWNjZXNzIGxlYWQnO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAvLyBGYWlsdXJlXG4gICAgICAgICAgICAgIGlzRXJyb3IgPSB0cnVlO1xuICAgICAgICAgICAgICB0aGlzLmhhbmRsZUVycm9ycygpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5BcGlSZXNwb25zZS5lbWl0KGV2ZW50KTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgLy9jb25zb2xlLmxvZygnRXZlbnQgT3RoZXI6ICcsIGV2ZW50KTtcbiAgICAgICAgICB9XG4gICAgICAgIH0sXG4gICAgICAgIChlcnJvcikgPT4ge1xuICAgICAgICAgIC8vIEZhaWx1cmVcbiAgICAgICAgICBpc0Vycm9yID0gdHJ1ZTtcbiAgICAgICAgICB0aGlzLmhhbmRsZUVycm9ycygpO1xuICAgICAgICAgIHRoaXMuQXBpUmVzcG9uc2UuZW1pdChlcnJvcik7XG4gICAgICAgIH1cbiAgICAgICk7XG4gIH1cblxuICBoYW5kbGVFcnJvcnMoKSB7XG4gICAgdGhpcy5wcm9ncmVzc0JhclNob3cgPSBmYWxzZTtcbiAgICB0aGlzLmVuYWJsZVVwbG9hZEJ0biA9IGZhbHNlO1xuICAgIHRoaXMudXBsb2FkTXNnID0gdHJ1ZTtcbiAgICB0aGlzLmFmdGVyVXBsb2FkID0gdHJ1ZTtcbiAgICB0aGlzLnVwbG9hZE1zZ1RleHQgPVxuICAgICAgdGhpcy5yZXBsYWNlVGV4dHMuYWZ0ZXJVcGxvYWRNc2dfZXJyb3IgfHwgJ0Vycm9yIGluIHVwbG9hZGluZyBmaWxlcyc7XG4gICAgdGhpcy51cGxvYWRNc2dDbGFzcyA9ICd0ZXh0LWRhbmdlciBsZWFkJztcbiAgfVxuXG4gIHJlbW92ZUZpbGUoaTogYW55LCBzZl9uYTogYW55KSB7XG4gICAgaWYgKHNmX25hID09PSAnc2YnKSB7XG4gICAgICB0aGlzLmFsbG93ZWRGaWxlcy5zcGxpY2UoaSwgMSk7XG4gICAgICB0aGlzLkNhcHRpb24uc3BsaWNlKGksIDEpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLm5vdEFsbG93ZWRGaWxlcy5zcGxpY2UoaSwgMSk7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuYWxsb3dlZEZpbGVzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgdGhpcy5lbmFibGVVcGxvYWRCdG4gPSBmYWxzZTtcbiAgICB9XG4gIH1cblxuICBjb252ZXJ0U2l6ZShmaWxlU2l6ZTogbnVtYmVyKTogc3RyaW5nIHtcbiAgICByZXR1cm4gZmlsZVNpemUgPCAxMDI0MDAwXG4gICAgICA/IChmaWxlU2l6ZSAvIDEwMjQpLnRvRml4ZWQoMikgKyAnIEtCJ1xuICAgICAgOiAoZmlsZVNpemUgLyAxMDI0MDAwKS50b0ZpeGVkKDIpICsgJyBNQic7XG4gIH1cblxuICBhdHRhY2hwaW5PbmNsaWNrKCkge1xuICAgIGNvbnN0IGVsZW1lbnQgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnc2VsJyArIHRoaXMuaWQpO1xuICAgIGlmIChlbGVtZW50ICE9PSBudWxsKSB7XG4gICAgICBlbGVtZW50LmNsaWNrKCk7XG4gICAgfVxuICB9XG5cbiAgZHJvcChldmVudDogYW55KSB7XG4gICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICB0aGlzLm9uQ2hhbmdlKGV2ZW50KTtcbiAgfVxuXG4gIGFsbG93RHJvcChldmVudDogYW55KSB7XG4gICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICBldmVudC5kYXRhVHJhbnNmZXIuZHJvcEVmZmVjdCA9ICdjb3B5JztcbiAgfVxufVxuIiwiPGxhYmVsIGZvcj1cInNlbHt7aWR9fVwiIGNsYXNzPVwid2NvLWZvcm0tdXBsb2FkXCIgKGRyb3ApPVwiZHJvcCgkZXZlbnQpXCIgKGRyYWdvdmVyKT1cImFsbG93RHJvcCgkZXZlbnQpXCI+XG4gIDxkaXYgY2xhc3M9XCJ3Y28tZm9ybS11cGxvYWRfX2luZm9cIj5cbiAgICA8c3Bhbj5BcnJhc3RlLW9zIGFxdWkgb3U8L3NwYW4+XG4gICAgPHNwYW4+XG4gICAgICA8c3BhbiBjbGFzcz1cIm1hdGVyaWFsLWljb25zLW91dGxpbmVkXCI+XG51cGxvYWRfZmlsZVxuPC9zcGFuPlxuICAgICAgPHNwYW4+e3tyZXBsYWNlVGV4dHMuc2VsZWN0RmlsZUJ0bn19PC9zcGFuPlxuICAgIDwvc3Bhbj5cbiAgPC9kaXY+XG4gIDxzcGFuIGNsYXNzPVwidXBsb2FkX19pbmZvXCIgKm5nSWY9XCIhYWxsb3dlZEZpbGVzLmxlbmd0aFwiID57e2Rlc2NyaXB0aW9ufX08L3NwYW4+XG4gIDxuZy1jb250YWluZXIgKm5nSWY9XCJhbGxvd2VkRmlsZXMubGVuZ3RoXCI+XG4gICAgPHNwYW4gY2xhc3M9XCJ1cGxvYWRfX2luZm9cIiAqbmdGb3I9XCJsZXQgc2Ygb2YgYWxsb3dlZEZpbGVzO2xldCBpPWluZGV4XCI+XG4gICAgICB7e3NmLm5hbWV9fSA8c21hbGw+KHt7Y29udmVydFNpemUoc2Yuc2l6ZSl9fSk8L3NtYWxsPlxuICAgIDwvc3Bhbj5cbiAgPC9uZy1jb250YWluZXI+XG4gIDxpbnB1dCB0eXBlPVwiZmlsZVwiIGlkPVwic2Vse3tpZH19XCIgKGNoYW5nZSk9XCJvbkNoYW5nZSgkZXZlbnQpXCIgc3R5bGU9XCJkaXNwbGF5OiBub25lXCIgdGl0bGU9XCJTZWxlY3QgZmlsZVwiXG4gIG5hbWU9XCJmaWxlc1tdXCIgW2FjY2VwdF09XCJmb3JtYXRzQWxsb3dlZFwiIFthdHRyLm11bHRpcGxlXT1cIm11bHRpcGxlID8gJycgOiBudWxsXCIgLz5cbjwvbGFiZWw+Il19