UNPKG

ngx-image-upload

Version:
380 lines (377 loc) 41.5 kB
/** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ import * as tslib_1 from "tslib"; import { Component, Input, Output, EventEmitter, ElementRef, ViewChild } from '@angular/core'; import { NgxImageUploadService } from './ngx-image-upload.service'; export class FileHolder { /** * @param {?} src * @param {?} file */ constructor(src, file) { this.src = src; this.file = file; this.pending = false; } } function FileHolder_tsickle_Closure_declarations() { /** @type {?} */ FileHolder.prototype.pending; /** @type {?} */ FileHolder.prototype.serverResponse; /** @type {?} */ FileHolder.prototype.src; /** @type {?} */ FileHolder.prototype.file; } export class NgxImageUploadComponent { /** * @param {?} imageService */ constructor(imageService) { this.imageService = imageService; this.files = []; this.fileCounter = 0; this.fileOver = false; this.showFileTooLargeMessage = false; this.beforeUpload = data => data; this.buttonCaption = '添加图片'; this.disabled = false; this.cssClass = 'img-ul'; this.clearButtonCaption = '清除'; this.dropBoxMessage = '拖拽图片到此处'; this.max = 100; this.preview = true; this.withCredentials = false; this.uploadedFiles = []; this.removed = new EventEmitter(); this.uploadStateChanged = new EventEmitter(); this.uploadFinished = new EventEmitter(); this.previewClicked = new EventEmitter(); this.pendingFilesCounter = 0; this.onFileOver = (isOver) => this.fileOver = isOver; this.countRemainingSlots = () => this.max - this.fileCounter; } /** * @return {?} */ ngOnInit() { if (!this.fileTooLargeMessage) { this.fileTooLargeMessage = '图片太大无法上传.' + (this.maxFileSize ? (' 最大允许 ' + this.maxFileSize / 1024) + 'KiB.' : ''); } this.supportedExtensions = this.supportedExtensions ? this.supportedExtensions.map((ext) => 'image/' + ext) : ['image/*']; } /** * @return {?} */ deleteAll() { this.files.forEach(f => this.removed.emit(f)); this.files = []; this.fileCounter = 0; if (this.inputElement) { this.inputElement.nativeElement.value = ''; } } /** * @param {?} file * @return {?} */ deleteFile(file) { let /** @type {?} */ index = this.files.indexOf(file); this.files.splice(index, 1); this.fileCounter--; if (this.inputElement) { this.inputElement.nativeElement.value = ''; } this.removed.emit(file); } /** * @param {?} file * @return {?} */ previewFileClicked(file) { this.previewClicked.emit(file); } /** * @param {?} changes * @return {?} */ ngOnChanges(changes) { if (changes.uploadedFiles && changes.uploadedFiles.currentValue && changes.uploadedFiles.currentValue.length > 0) { this.processUploadedFiles(); } } /** * @param {?} files * @return {?} */ onFileChange(files) { if (this.disabled) return; // let remainingSlots = 0; let /** @type {?} */ remainingSlots = this.countRemainingSlots(); let /** @type {?} */ filesToUploadNum = files.length > remainingSlots ? remainingSlots : files.length; if (this.url && filesToUploadNum != 0) { this.uploadStateChanged.emit(true); } this.fileCounter += filesToUploadNum; this.showFileTooLargeMessage = false; this.uploadFiles(files, filesToUploadNum); } /** * @param {?} response * @param {?} fileHolder * @return {?} */ onResponse(response, fileHolder) { fileHolder.serverResponse = { status: response.status, response }; fileHolder.pending = false; this.uploadFinished.emit(fileHolder); if (--this.pendingFilesCounter == 0) { this.uploadStateChanged.emit(false); } } /** * @return {?} */ processUploadedFiles() { if (typeof this.uploadedFiles === 'string') { let /** @type {?} */ data = this.uploadedFiles; this.fileCounter = 1; this.max = 1; let /** @type {?} */ fileBlob, /** @type {?} */ file, /** @type {?} */ fileUrl; if (data instanceof Object) { fileUrl = data.url; fileBlob = (data.blob) ? data.blob : new Blob([data]); file = new File([fileBlob], data.fileName); } else { fileUrl = data; fileBlob = new Blob([fileUrl]); file = new File([fileBlob], fileUrl); } this.files = []; this.files.push(new FileHolder(fileUrl, file)); } else { this.max = this.max - Object.keys(this.uploadedFiles).length; for (const /** @type {?} */ i in this.uploadedFiles) { let /** @type {?} */ data = this.uploadedFiles[i]; let /** @type {?} */ fileBlob, /** @type {?} */ file, /** @type {?} */ fileUrl; if (data instanceof Object) { fileUrl = data.url; fileBlob = (data.blob) ? data.blob : new Blob([data]); file = new File([fileBlob], data.fileName); } else { fileUrl = data; fileBlob = new Blob([fileUrl]); file = new File([fileBlob], fileUrl); } this.files.push(new FileHolder(fileUrl, file)); } } } /** * @param {?} files * @param {?} filesToUploadNum * @return {?} */ uploadFiles(files, filesToUploadNum) { return tslib_1.__awaiter(this, void 0, void 0, function* () { for (let /** @type {?} */ i = 0; i < filesToUploadNum; i++) { const /** @type {?} */ file = files[i]; if (this.maxFileSize && file.size > this.maxFileSize) { this.fileCounter--; this.inputElement.nativeElement.value = ''; this.showFileTooLargeMessage = true; continue; } const /** @type {?} */ beforeUploadResult = yield this.beforeUpload({ file, url: this.url, abort: false }); if (beforeUploadResult.abort) { this.fileCounter--; this.inputElement.nativeElement.value = ''; continue; } const /** @type {?} */ img = document.createElement('img'); img.src = window.URL.createObjectURL(beforeUploadResult.file); const /** @type {?} */ reader = new FileReader(); reader.addEventListener('load', (event) => { const /** @type {?} */ fileHolder = new FileHolder(event.target.result, beforeUploadResult.file); this.uploadSingleFile(fileHolder, beforeUploadResult.url, beforeUploadResult.formData); this.files.push(fileHolder); }, false); reader.readAsDataURL(beforeUploadResult.file); } }); } /** * @param {?} fileHolder * @param {?=} url * @param {?=} customForm * @return {?} */ uploadSingleFile(fileHolder, url = this.url, customForm) { if (url) { this.pendingFilesCounter++; fileHolder.pending = true; this.imageService .postImage(url, fileHolder.file, this.headers, this.partName, customForm, this.withCredentials) .subscribe(response => this.onResponse(response, fileHolder), error => { this.onResponse(error, fileHolder); this.deleteFile(fileHolder); }); } else { this.uploadFinished.emit(fileHolder); } } } NgxImageUploadComponent.decorators = [ { type: Component, args: [{ selector: 'ds-ngx-image-upload', template: `<div fileDrop [accept]="supportedExtensions" (fileOver)="onFileOver($event)" (fileDrop)="onFileChange($event)" [ngClass]="cssClass" [ngClass]="{'img-ul-file-is-over': fileOver}" [ngStyle]="style?.layout" > <p class="img-ul-file-too-large" *ngIf="showFileTooLargeMessage" [innerText]="fileTooLargeMessage"></p> <div *ngIf="preview" class="img-ul-container img-ul-hr-inline-group" [ngStyle]="style?.previewPanel"> <!-- img --> <div class="img-ul-image" *ngFor="let file of files" (click)="previewFileClicked(file)" > <!-- [ngStyle]="{'background-image': 'url('+ file.src +')'}" --> <div class="img_div"><img src={{file.src}} class="imgs"></div> <div *ngIf="file.pending" class="img-ul-loading-overlay"> <div class="img-ul-spinning-circle"></div> </div> <div *ngIf="!file.pending" [ngClass]="{'img-ul-disabled': disabled}" class="img-ul-x-mark" (click)="deleteFile(file)"> <span class="img-ul-close"></span> </div> </div> </div> <div class="img-ul-file-upload img-ul-hr-inline-group"> <label *ngIf="fileCounter != max" class="img-ul-upload img-ul-button" [ngStyle]="style?.selectButton" [ngClass]="{'img-ul-disabled': disabled}"> <span [innerText]="buttonCaption"></span> <input type="file" [disabled]="disabled" [accept]="supportedExtensions" multiple (change)="onFileChange(input.files)" #input> </label> </div> </div>`, styles: [`.img-ul{--common-radius:3px;border-radius:var(--common-radius);position:relative;color:#9b9b9b;font-weight:400}.img-ul-x-mark{background-color:#000;border-radius:10px;color:#fff;cursor:pointer;height:20px;opacity:.7;text-align:center;width:20px;position:absolute;top:-8px;right:-10px}.img_div{position:relative;width:120px;height:120px;overflow:hidden}.imgs{max-width:200%;height:auto;position:absolute;top:50%;left:50%;-webkit-transform:translate(-50%,-50%);transform:translate(-50%,-50%);background:#000}.img-ul-file-is-over{border:var(--active-color) solid}.img-ul-hr-inline-group:after{clear:both;content:"";display:table}.img-ul-file-upload{display:inline-block;width:120px;height:120px;margin:10px;color:#000;text-align:center;line-height:120px}.img-ul-drag-box-msg{display:inline-block;font-weight:600;margin-left:12px}label.img-ul-button{border:1px dashed #d0d0d0;font-size:1em!important}label.img-ul-button input[type=file]{display:none;position:fixed;top:-99999px}.img-ul-clear{background-color:red;font-size:1em!important}.img-ul-clear:disabled{background-color:#ff6464;cursor:default}.img-ul-upload{background-color:var(--active-color);width:120px;height:120px}.img-ul-button{border:none;cursor:pointer;display:inline-block;float:left;font-size:1.25em;font-weight:500;text-transform:uppercase}.img-ul-button:active span{display:block;position:relative;top:1px}.img-ul-container{position:relative;display:inline-block}.img-ul-image{box-shadow:0 0 10px 2px #d0d0d0;background:center center/contain no-repeat;display:inline-block;float:left;height:120px;margin:6px;position:relative;width:120px}.img-ul-close{height:20px;opacity:.7;position:relative;width:20px}.img-ul-x-mark:hover .img-ul-close{opacity:1}.img-ul-close:after,.img-ul-close:before{background-color:#fff;border-radius:2px;content:'';height:10px;position:absolute;top:5px;width:2px}.img-ul-close:before{-webkit-transform:rotate(45deg);transform:rotate(45deg)}.img-ul-close:after{-webkit-transform:rotate(-45deg);transform:rotate(-45deg)}.img-ul-x-mark.img-ul-disabled{display:none}.img-ul-loading-overlay{background-color:#000;bottom:0;left:0;opacity:.7;position:absolute;right:0;top:0}.img-ul-spinning-circle{height:30px;width:30px;margin:auto;position:absolute;top:0;left:0;bottom:0;right:0;border-radius:50%;border:3px solid rgba(255,255,255,0);border-top:3px solid #fff;border-right:3px solid #fff;-webkit-animation:2s cubic-bezier(.085,.625,.855,.36) infinite spinner;animation:2s cubic-bezier(.085,.625,.855,.36) infinite spinner}.img-ul-file-too-large{color:red}.img-ul-upload.img-ul-disabled{background-color:#86e9c9;cursor:default}.img-ul-upload.img-ul-disabled:active span{top:0}@-webkit-keyframes spinner{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@keyframes spinner{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}`] },] }, ]; /** @nocollapse */ NgxImageUploadComponent.ctorParameters = () => [ { type: NgxImageUploadService } ]; NgxImageUploadComponent.propDecorators = { beforeUpload: [{ type: Input }], buttonCaption: [{ type: Input }], disabled: [{ type: Input }], cssClass: [{ type: Input, args: ['class',] }], clearButtonCaption: [{ type: Input }], dropBoxMessage: [{ type: Input }], fileTooLargeMessage: [{ type: Input }], headers: [{ type: Input }], max: [{ type: Input }], maxFileSize: [{ type: Input }], preview: [{ type: Input }], partName: [{ type: Input }], style: [{ type: Input }], supportedExtensions: [{ type: Input, args: ['extensions',] }], url: [{ type: Input }], withCredentials: [{ type: Input }], uploadedFiles: [{ type: Input }], removed: [{ type: Output }], uploadStateChanged: [{ type: Output }], uploadFinished: [{ type: Output }], previewClicked: [{ type: Output }], inputElement: [{ type: ViewChild, args: ['input',] }] }; function NgxImageUploadComponent_tsickle_Closure_declarations() { /** @type {?} */ NgxImageUploadComponent.prototype.files; /** @type {?} */ NgxImageUploadComponent.prototype.fileCounter; /** @type {?} */ NgxImageUploadComponent.prototype.fileOver; /** @type {?} */ NgxImageUploadComponent.prototype.showFileTooLargeMessage; /** @type {?} */ NgxImageUploadComponent.prototype.beforeUpload; /** @type {?} */ NgxImageUploadComponent.prototype.buttonCaption; /** @type {?} */ NgxImageUploadComponent.prototype.disabled; /** @type {?} */ NgxImageUploadComponent.prototype.cssClass; /** @type {?} */ NgxImageUploadComponent.prototype.clearButtonCaption; /** @type {?} */ NgxImageUploadComponent.prototype.dropBoxMessage; /** @type {?} */ NgxImageUploadComponent.prototype.fileTooLargeMessage; /** @type {?} */ NgxImageUploadComponent.prototype.headers; /** @type {?} */ NgxImageUploadComponent.prototype.max; /** @type {?} */ NgxImageUploadComponent.prototype.maxFileSize; /** @type {?} */ NgxImageUploadComponent.prototype.preview; /** @type {?} */ NgxImageUploadComponent.prototype.partName; /** @type {?} */ NgxImageUploadComponent.prototype.style; /** @type {?} */ NgxImageUploadComponent.prototype.supportedExtensions; /** @type {?} */ NgxImageUploadComponent.prototype.url; /** @type {?} */ NgxImageUploadComponent.prototype.withCredentials; /** @type {?} */ NgxImageUploadComponent.prototype.uploadedFiles; /** @type {?} */ NgxImageUploadComponent.prototype.removed; /** @type {?} */ NgxImageUploadComponent.prototype.uploadStateChanged; /** @type {?} */ NgxImageUploadComponent.prototype.uploadFinished; /** @type {?} */ NgxImageUploadComponent.prototype.previewClicked; /** @type {?} */ NgxImageUploadComponent.prototype.inputElement; /** @type {?} */ NgxImageUploadComponent.prototype.pendingFilesCounter; /** @type {?} */ NgxImageUploadComponent.prototype.onFileOver; /** @type {?} */ NgxImageUploadComponent.prototype.countRemainingSlots; /** @type {?} */ NgxImageUploadComponent.prototype.imageService; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmd4LWltYWdlLXVwbG9hZC5jb21wb25lbnQuanMiLCJzb3VyY2VSb290Ijoibmc6Ly9uZ3gtaW1hZ2UtdXBsb2FkLyIsInNvdXJjZXMiOlsibGliL25neC1pbWFnZS11cGxvYWQuY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBQUEsT0FBTyxFQUFFLFNBQVMsRUFBcUIsS0FBSyxFQUFFLE1BQU0sRUFBRSxZQUFZLEVBQUUsVUFBVSxFQUFFLFNBQVMsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUdqSCxPQUFPLEVBQUUscUJBQXFCLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUduRSxNQUFNOzs7OztJQUlKLFlBQW1CLEdBQVcsRUFBUyxJQUFVO1FBQTlCLFFBQUcsR0FBSCxHQUFHLENBQVE7UUFBUyxTQUFJLEdBQUosSUFBSSxDQUFNO3VCQUh2QixLQUFLO0tBSTlCO0NBQ0Y7Ozs7Ozs7Ozs7O0FBcURELE1BQU07Ozs7SUFpQ0osWUFBb0IsWUFBbUM7UUFBbkMsaUJBQVksR0FBWixZQUFZLENBQXVCO3FCQS9CakMsRUFBRTsyQkFDRixDQUFDO3dCQUNILEtBQUs7dUNBQ1UsS0FBSzs0QkFFcUQsSUFBSSxDQUFDLEVBQUUsQ0FBQyxJQUFJOzZCQUNoRixNQUFNO3dCQUNYLEtBQUs7d0JBQ0UsUUFBUTtrQ0FDTCxJQUFJOzhCQUNSLFNBQVM7bUJBR3BCLEdBQUc7dUJBRUMsSUFBSTsrQkFLSSxLQUFLOzZCQUMyRCxFQUFFO3VCQUN6RSxJQUFJLFlBQVksRUFBYztrQ0FDbkIsSUFBSSxZQUFZLEVBQVc7OEJBQy9CLElBQUksWUFBWSxFQUFjOzhCQUM5QixJQUFJLFlBQVksRUFBYzttQ0FJbkIsQ0FBQzswQkF5RDFCLENBQUMsTUFBTSxFQUFFLEVBQUUsQ0FBQyxJQUFJLENBQUMsUUFBUSxHQUFHLE1BQU07bUNBRWpCLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxHQUFHLEdBQUcsSUFBSSxDQUFDLFdBQVc7S0F6REg7Ozs7SUFFNUQsUUFB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LEVBQUUsSUFBSSxDQUFDLFFBQVEsRUFBRSxVQUFVLEVBQUUsSUFBSSxDQUFDLGVBQWUsQ0FBQztpQkFDOUYsU0FBUyxDQUNSLFFBQVEsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxRQUFRLEVBQUUsVUFBVSxDQUFDLEVBQ2pELEtBQUssQ0FBQyxFQUFFO2dCQUNOLElBQUksQ0FBQyxVQUFVLENBQUMsS0FBSyxFQUFFLFVBQVUsQ0FBQyxDQUFDO2dCQUNuQyxJQUFJLENBQUMsVUFBVSxDQUFDLFVBQVUsQ0FBQyxDQUFDO2FBQzdCLENBQUMsQ0FBQztTQUNSO1FBQUMsSUFBSSxDQUFDLENBQUM7WUFDTixJQUFJLENBQUMsY0FBYyxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQztTQUN0Qzs7OztZQXhQSixTQUFTLFNBQUM7Z0JBQ1QsUUFBUSxFQUFFLHFCQUFxQjtnQkFDL0IsUUFBUSxFQUFFOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O09BOENMO2dCQUNMLE1BQU0sRUFBRSxDQUFDLDQzRkFBNDNGLENBQUM7YUFDdjRGOzs7O1lBN0RRLHFCQUFxQjs7OzJCQXFFM0IsS0FBSzs0QkFDTCxLQUFLO3VCQUNMLEtBQUs7dUJBQ0wsS0FBSyxTQUFDLE9BQU87aUNBQ2IsS0FBSzs2QkFDTCxLQUFLO2tDQUNMLEtBQUs7c0JBQ0wsS0FBSztrQkFDTCxLQUFLOzBCQUNMLEtBQUs7c0JBQ0wsS0FBSzt1QkFDTCxLQUFLO29CQUNMLEtBQUs7a0NBQ0wsS0FBSyxTQUFDLFlBQVk7a0JBQ2xCLEtBQUs7OEJBQ0wsS0FBSzs0QkFDTCxLQUFLO3NCQUNMLE1BQU07aUNBQ04sTUFBTTs2QkFDTixNQUFNOzZCQUNOLE1BQU07MkJBRU4sU0FBUyxTQUFDLE9BQU8iLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21wb25lbnQsIE9uSW5pdCwgT25DaGFuZ2VzLCBJbnB1dCwgT3V0cHV0LCBFdmVudEVtaXR0ZXIsIEVsZW1lbnRSZWYsIFZpZXdDaGlsZCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuXG5pbXBvcnQgeyBVcGxvYWRNZXRhZGF0YSB9IGZyb20gJy4vYmVmb3JlLXVwbG9hZC5pbnRlcmZhY2UnO1xuaW1wb3J0IHsgTmd4SW1hZ2VVcGxvYWRTZXJ2aWNlIH0gZnJvbSAnLi9uZ3gtaW1hZ2UtdXBsb2FkLnNlcnZpY2UnO1xuaW1wb3J0IHsgU3R5bGUgfSBmcm9tICcuL3N0eWxlJztcblxuZXhwb3J0IGNsYXNzIEZpbGVIb2xkZXIge1xuICBwdWJsaWMgcGVuZGluZzogYm9vbGVhbiA9IGZhbHNlO1xuICBwdWJsaWMgc2VydmVyUmVzcG9uc2U6IHsgc3RhdHVzOiBudW1iZXIsIHJlc3BvbnNlOiBhbnkgfTtcblxuICBjb25zdHJ1Y3RvcihwdWJsaWMgc3JjOiBzdHJpbmcsIHB1YmxpYyBmaWxlOiBGaWxlKSB7XG4gIH1cbn1cblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnZHMtbmd4LWltYWdlLXVwbG9hZCcsXG4gIHRlbXBsYXRlOiBgPGRpdlxuICAgICBmaWxlRHJvcFxuICAgICBbYWNjZXB0XT1cInN1cHBvcnRlZEV4dGVuc2lvbnNcIlxuICAgICAoZmlsZU92ZXIpPVwib25GaWxlT3ZlcigkZXZlbnQpXCJcbiAgICAgKGZpbGVEcm9wKT1cIm9uRmlsZUNoYW5nZSgkZXZlbnQpXCJcbiAgICAgW25nQ2xhc3NdPVwiY3NzQ2xhc3NcIlxuICAgICBbbmdDbGFzc109XCJ7J2ltZy11bC1maWxlLWlzLW92ZXInOiBmaWxlT3Zlcn1cIiAgICAgXG4gICAgIFtuZ1N0eWxlXT1cInN0eWxlPy5sYXlvdXRcIlxuPlxuICA8cCBjbGFzcz1cImltZy11bC1maWxlLXRvby1sYXJnZVwiICpuZ0lmPVwic2hvd0ZpbGVUb29MYXJnZU1lc3NhZ2VcIiBbaW5uZXJUZXh0XT1cImZpbGVUb29MYXJnZU1lc3NhZ2VcIj48L3A+XG5cbiAgPGRpdiAqbmdJZj1cInByZXZpZXdcIiBjbGFzcz1cImltZy11bC1jb250YWluZXIgaW1nLXVsLWhyLWlubGluZS1ncm91cFwiIFtuZ1N0eWxlXT1cInN0eWxlPy5wcmV2aWV3UGFuZWxcIj5cbiAgICA8IS0tIGltZyAtLT5cbiAgICA8ZGl2XG4gICAgICBjbGFzcz1cImltZy11bC1pbWFnZVwiXG4gICAgICAqbmdGb3I9XCJsZXQgZmlsZSBvZiBmaWxlc1wiXG4gICAgICAoY2xpY2spPVwicHJldmlld0ZpbGVDbGlja2VkKGZpbGUpXCJcbiAgICA+XG4gICAgICA8IS0tIFtuZ1N0eWxlXT1cInsnYmFja2dyb3VuZC1pbWFnZSc6ICd1cmwoJysgZmlsZS5zcmMgKycpJ31cIiAtLT5cbiAgICAgIDxkaXYgY2xhc3M9XCJpbWdfZGl2XCI+PGltZyBzcmM9e3tmaWxlLnNyY319IGNsYXNzPVwiaW1nc1wiPjwvZGl2PlxuICAgICAgPGRpdiAqbmdJZj1cImZpbGUucGVuZGluZ1wiIGNsYXNzPVwiaW1nLXVsLWxvYWRpbmctb3ZlcmxheVwiPlxuICAgICAgICA8ZGl2IGNsYXNzPVwiaW1nLXVsLXNwaW5uaW5nLWNpcmNsZVwiPjwvZGl2PlxuICAgICAgPC9kaXY+XG4gICAgICA8ZGl2ICpuZ0lmPVwiIWZpbGUucGVuZGluZ1wiIFxuICAgICAgICBbbmdDbGFzc109XCJ7J2ltZy11bC1kaXNhYmxlZCc6IGRpc2FibGVkfVwiIFxuICAgICAgICBjbGFzcz1cImltZy11bC14LW1hcmtcIiBcbiAgICAgICAgKGNsaWNrKT1cImRlbGV0ZUZpbGUoZmlsZSlcIj5cbiAgICAgICAgPHNwYW4gY2xhc3M9XCJpbWctdWwtY2xvc2VcIj48L3NwYW4+XG4gICAgICA8L2Rpdj5cbiAgICA8L2Rpdj5cbiAgPC9kaXY+XG4gIFxuICA8ZGl2IGNsYXNzPVwiaW1nLXVsLWZpbGUtdXBsb2FkIGltZy11bC1oci1pbmxpbmUtZ3JvdXBcIj4gICAgXG4gICAgPGxhYmVsICpuZ0lmPVwiZmlsZUNvdW50ZXIgIT0gbWF4XCJcbiAgICAgIGNsYXNzPVwiaW1nLXVsLXVwbG9hZCBpbWctdWwtYnV0dG9uXCIgXG4gICAgICBbbmdTdHlsZV09XCJzdHlsZT8uc2VsZWN0QnV0dG9uXCJcbiAgICAgIFtuZ0NsYXNzXT1cInsnaW1nLXVsLWRpc2FibGVkJzogZGlzYWJsZWR9XCI+XG4gICAgICA8c3BhbiBbaW5uZXJUZXh0XT1cImJ1dHRvbkNhcHRpb25cIj48L3NwYW4+XG4gICAgICA8aW5wdXRcbiAgICAgICAgdHlwZT1cImZpbGVcIlxuICAgICAgICBbZGlzYWJsZWRdPVwiZGlzYWJsZWRcIlxuICAgICAgICBbYWNjZXB0XT1cInN1cHBvcnRlZEV4dGVuc2lvbnNcIlxuICAgICAgICBtdWx0aXBsZSAoY2hhbmdlKT1cIm9uRmlsZUNoYW5nZShpbnB1dC5maWxlcylcIlxuICAgICAgICAjaW5wdXQ+XG4gICAgPC9sYWJlbD5cbiAgPC9kaXY+XG48L2Rpdj5gLFxuICBzdHlsZXM6IFtgLmltZy11bHstLWNvbW1vbi1yYWRpdXM6M3B4O2JvcmRlci1yYWRpdXM6dmFyKC0tY29tbW9uLXJhZGl1cyk7cG9zaXRpb246cmVsYXRpdmU7Y29sb3I6IzliOWI5Yjtmb250LXdlaWdodDo0MDB9LmltZy11bC14LW1hcmt7YmFja2dyb3VuZC1jb2xvcjojMDAwO2JvcmRlci1yYWRpdXM6MTBweDtjb2xvcjojZmZmO2N1cnNvcjpwb2ludGVyO2hlaWdodDoyMHB4O29wYWNpdHk6Ljc7dGV4dC1hbGlnbjpjZW50ZXI7d2lkdGg6MjBweDtwb3NpdGlvbjphYnNvbHV0ZTt0b3A6LThweDtyaWdodDotMTBweH0uaW1nX2Rpdntwb3NpdGlvbjpyZWxhdGl2ZTt3aWR0aDoxMjBweDtoZWlnaHQ6MTIwcHg7b3ZlcmZsb3c6aGlkZGVufS5pbWdze21heC13aWR0aDoyMDAlO2hlaWdodDphdXRvO3Bvc2l0aW9uOmFic29sdXRlO3RvcDo1MCU7bGVmdDo1MCU7LXdlYmtpdC10cmFuc2Zvcm06dHJhbnNsYXRlKC01MCUsLTUwJSk7dHJhbnNmb3JtOnRyYW5zbGF0ZSgtNTAlLC01MCUpO2JhY2tncm91bmQ6IzAwMH0uaW1nLXVsLWZpbGUtaXMtb3Zlcntib3JkZXI6dmFyKC0tYWN0aXZlLWNvbG9yKSBzb2xpZH0uaW1nLXVsLWhyLWlubGluZS1ncm91cDphZnRlcntjbGVhcjpib3RoO2NvbnRlbnQ6XCJcIjtkaXNwbGF5OnRhYmxlfS5pbWctdWwtZmlsZS11cGxvYWR7ZGlzcGxheTppbmxpbmUtYmxvY2s7d2lkdGg6MTIwcHg7aGVpZ2h0OjEyMHB4O21hcmdpbjoxMHB4O2NvbG9yOiMwMDA7dGV4dC1hbGlnbjpjZW50ZXI7bGluZS1oZWlnaHQ6MTIwcHh9LmltZy11bC1kcmFnLWJveC1tc2d7ZGlzcGxheTppbmxpbmUtYmxvY2s7Zm9udC13ZWlnaHQ6NjAwO21hcmdpbi1sZWZ0OjEycHh9bGFiZWwuaW1nLXVsLWJ1dHRvbntib3JkZXI6MXB4IGRhc2hlZCAjZDBkMGQwO2ZvbnQtc2l6ZToxZW0haW1wb3J0YW50fWxhYmVsLmltZy11bC1idXR0b24gaW5wdXRbdHlwZT1maWxlXXtkaXNwbGF5Om5vbmU7cG9zaXRpb246Zml4ZWQ7dG9wOi05OTk5OXB4fS5pbWctdWwtY2xlYXJ7YmFja2dyb3VuZC1jb2xvcjpyZWQ7Zm9udC1zaXplOjFlbSFpbXBvcnRhbnR9LmltZy11bC1jbGVhcjpkaXNhYmxlZHtiYWNrZ3JvdW5kLWNvbG9yOiNmZjY0NjQ7Y3Vyc29yOmRlZmF1bHR9LmltZy11bC11cGxvYWR7YmFja2dyb3VuZC1jb2xvcjp2YXIoLS1hY3RpdmUtY29sb3IpO3dpZHRoOjEyMHB4O2hlaWdodDoxMjBweH0uaW1nLXVsLWJ1dHRvbntib3JkZXI6bm9uZTtjdXJzb3I6cG9pbnRlcjtkaXNwbGF5OmlubGluZS1ibG9jaztmbG9hdDpsZWZ0O2ZvbnQtc2l6ZToxLjI1ZW07Zm9udC13ZWlnaHQ6NTAwO3RleHQtdHJhbnNmb3JtOnVwcGVyY2FzZX0uaW1nLXVsLWJ1dHRvbjphY3RpdmUgc3BhbntkaXNwbGF5OmJsb2NrO3Bvc2l0aW9uOnJlbGF0aXZlO3RvcDoxcHh9LmltZy11bC1jb250YWluZXJ7cG9zaXRpb246cmVsYXRpdmU7ZGlzcGxheTppbmxpbmUtYmxvY2t9LmltZy11bC1pbWFnZXtib3gtc2hhZG93OjAgMCAxMHB4IDJweCAjZDBkMGQwO2JhY2tncm91bmQ6Y2VudGVyIGNlbnRlci9jb250YWluIG5vLXJlcGVhdDtkaXNwbGF5OmlubGluZS1ibG9jaztmbG9hdDpsZWZ0O2hlaWdodDoxMjBweDttYXJnaW46NnB4O3Bvc2l0aW9uOnJlbGF0aXZlO3dpZHRoOjEyMHB4fS5pbWctdWwtY2xvc2V7aGVpZ2h0OjIwcHg7b3BhY2l0eTouNztwb3NpdGlvbjpyZWxhdGl2ZTt3aWR0aDoyMHB4fS5pbWctdWwteC1tYXJrOmhvdmVyIC5pbWctdWwtY2xvc2V7b3BhY2l0eToxfS5pbWctdWwtY2xvc2U6YWZ0ZXIsLmltZy11bC1jbG9zZTpiZWZvcmV7YmFja2dyb3VuZC1jb2xvcjojZmZmO2JvcmRlci1yYWRpdXM6MnB4O2NvbnRlbnQ6Jyc7aGVpZ2h0OjEwcHg7cG9zaXRpb246YWJzb2x1dGU7dG9wOjVweDt3aWR0aDoycHh9LmltZy11bC1jbG9zZTpiZWZvcmV7LXdlYmtpdC10cmFuc2Zvcm06cm90YXRlKDQ1ZGVnKTt0cmFuc2Zvcm06cm90YXRlKDQ1ZGVnKX0uaW1nLXVsLWNsb3NlOmFmdGVyey13ZWJraXQtdHJhbnNmb3JtOnJvdGF0ZSgtNDVkZWcpO3RyYW5zZm9ybTpyb3RhdGUoLTQ1ZGVnKX0uaW1nLXVsLXgtbWFyay5pbWctdWwtZGlzYWJsZWR7ZGlzcGxheTpub25lfS5pbWctdWwtbG9hZGluZy1vdmVybGF5e2JhY2tncm91bmQtY29sb3I6IzAwMDtib3R0b206MDtsZWZ0OjA7b3BhY2l0eTouNztwb3NpdGlvbjphYnNvbHV0ZTtyaWdodDowO3RvcDowfS5pbWctdWwtc3Bpbm5pbmctY2lyY2xle2hlaWdodDozMHB4O3dpZHRoOjMwcHg7bWFyZ2luOmF1dG87cG9zaXRpb246YWJzb2x1dGU7dG9wOjA7bGVmdDowO2JvdHRvbTowO3JpZ2h0OjA7Ym9yZGVyLXJhZGl1czo1MCU7Ym9yZGVyOjNweCBzb2xpZCByZ2JhKDI1NSwyNTUsMjU1LDApO2JvcmRlci10b3A6M3B4IHNvbGlkICNmZmY7Ym9yZGVyLXJpZ2h0OjNweCBzb2xpZCAjZmZmOy13ZWJraXQtYW5pbWF0aW9uOjJzIGN1YmljLWJlemllciguMDg1LC42MjUsLjg1NSwuMzYpIGluZmluaXRlIHNwaW5uZXI7YW5pbWF0aW9uOjJzIGN1YmljLWJlemllciguMDg1LC42MjUsLjg1NSwuMzYpIGluZmluaXRlIHNwaW5uZXJ9LmltZy11bC1maWxlLXRvby1sYXJnZXtjb2xvcjpyZWR9LmltZy11bC11cGxvYWQuaW1nLXVsLWRpc2FibGVke2JhY2tncm91bmQtY29sb3I6Izg2ZTljOTtjdXJzb3I6ZGVmYXVsdH0uaW1nLXVsLXVwbG9hZC5pbWctdWwtZGlzYWJsZWQ6YWN0aXZlIHNwYW57dG9wOjB9QC13ZWJraXQta2V5ZnJhbWVzIHNwaW5uZXJ7MCV7LXdlYmtpdC10cmFuc2Zvcm06cm90YXRlKDApO3RyYW5zZm9ybTpyb3RhdGUoMCl9MTAwJXstd2Via2l0LXRyYW5zZm9ybTpyb3RhdGUoMzYwZGVnKTt0cmFuc2Zvcm06cm90YXRlKDM2MGRlZyl9fUBrZXlmcmFtZXMgc3Bpbm5lcnswJXstd2Via2l0LXRyYW5zZm9ybTpyb3RhdGUoMCk7dHJhbnNmb3JtOnJvdGF0ZSgwKX0xMDAley13ZWJraXQtdHJhbnNmb3JtOnJvdGF0ZSgzNjBkZWcpO3RyYW5zZm9ybTpyb3RhdGUoMzYwZGVnKX19YF1cbn0pXG5leHBvcnQgY2xhc3MgTmd4SW1hZ2VVcGxvYWRDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQsIE9uQ2hhbmdlcyB7XG5cbiAgZmlsZXM6IEZpbGVIb2xkZXJbXSA9IFtdO1xuICBmaWxlQ291bnRlcjogbnVtYmVyID0gMDtcbiAgZmlsZU92ZXI6IGJvb2xlYW4gPSBmYWxzZTtcbiAgc2hvd0ZpbGVUb29MYXJnZU1lc3NhZ2U6IGJvb2xlYW4gPSBmYWxzZTtcblxuICBASW5wdXQoKSBiZWZvcmVVcGxvYWQ6IChwYXJhbTogVXBsb2FkTWV0YWRhdGEpID0+IFVwbG9hZE1ldGFkYXRhIHwgUHJvbWlzZTxVcGxvYWRNZXRhZGF0YT4gPSBkYXRhID0+IGRhdGE7XG4gIEBJbnB1dCgpIGJ1dHRvbkNhcHRpb24gPSAn5re75Yqg5Zu+54mHJztcbiAgQElucHV0KCkgZGlzYWJsZWQgPSBmYWxzZTtcbiAgQElucHV0KCdjbGFzcycpIGNzc0NsYXNzID0gJ2ltZy11bCc7XG4gIEBJbnB1dCgpIGNsZWFyQnV0dG9uQ2FwdGlvbiA9ICfmuIXpmaQnO1xuICBASW5wdXQoKSBkcm9wQm94TWVzc2FnZSA9ICfmi5bmi73lm77niYfliLDmraTlpIQnO1xuICBASW5wdXQoKSBmaWxlVG9vTGFyZ2VNZXNzYWdlO1xuICBASW5wdXQoKSBoZWFkZXJzOiBIZWFkZXJzIHwgeyBbbmFtZTogc3RyaW5nXTogYW55IH07XG4gIEBJbnB1dCgpIG1heCA9IDEwMDtcbiAgQElucHV0KCkgbWF4RmlsZVNpemU6IG51bWJlcjtcbiAgQElucHV0KCkgcHJldmlldyA9IHRydWU7XG4gIEBJbnB1dCgpIHBhcnROYW1lOiBzdHJpbmc7XG4gIEBJbnB1dCgpIHN0eWxlOiBTdHlsZTtcbiAgQElucHV0KCdleHRlbnNpb25zJykgc3VwcG9ydGVkRXh0ZW5zaW9uczogc3RyaW5nW107XG4gIEBJbnB1dCgpIHVybDogc3RyaW5nO1xuICBASW5wdXQoKSB3aXRoQ3JlZGVudGlhbHMgPSBmYWxzZTtcbiAgQElucHV0KCkgdXBsb2FkZWRGaWxlczogc3RyaW5nW10gfCBBcnJheTx7IHVybDogc3RyaW5nLCBmaWxlTmFtZTogc3RyaW5nLCBibG9iPzogQmxvYiB9PiA9IFtdO1xuICBAT3V0cHV0KCkgcmVtb3ZlZCA9IG5ldyBFdmVudEVtaXR0ZXI8RmlsZUhvbGRlcj4oKTtcbiAgQE91dHB1dCgpIHVwbG9hZFN0YXRlQ2hhbmdlZCA9IG5ldyBFdmVudEVtaXR0ZXI8Ym9vbGVhbj4oKTtcbiAgQE91dHB1dCgpIHVwbG9hZEZpbmlzaGVkID0gbmV3IEV2ZW50RW1pdHRlcjxGaWxlSG9sZGVyPigpO1xuICBAT3V0cHV0KCkgcHJldmlld0NsaWNrZWQgPSBuZXcgRXZlbnRFbWl0dGVyPEZpbGVIb2xkZXI+KCk7XG5cbiAgQFZpZXdDaGlsZCgnaW5wdXQnKVxuICBwcml2YXRlIGlucHV0RWxlbWVudDogRWxlbWVudFJlZjtcbiAgcHJpdmF0ZSBwZW5kaW5nRmlsZXNDb3VudGVyOiBudW1iZXIgPSAwO1xuXG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgaW1hZ2VTZXJ2aWNlOiBOZ3hJbWFnZVVwbG9hZFNlcnZpY2UpIHsgfVxuXG4gIG5nT25Jbml0KCkge1xuICAgIGlmICghdGhpcy5maWxlVG9vTGFyZ2VNZXNzYWdlKSB7XG4gICAgICB0aGlzLmZpbGVUb29MYXJnZU1lc3NhZ2UgPSAn5Zu+54mH5aSq5aSn5peg5rOV5LiK5LygLicgKyAodGhpcy5tYXhGaWxlU2l6ZSA/ICgnIOacgOWkp+WFgeiuuCAnICsgdGhpcy5tYXhGaWxlU2l6ZSAvIDEwMjQpICsgJ0tpQi4nIDogJycpO1xuICAgIH1cbiAgICB0aGlzLnN1cHBvcnRlZEV4dGVuc2lvbnMgPSB0aGlzLnN1cHBvcnRlZEV4dGVuc2lvbnMgPyB0aGlzLnN1cHBvcnRlZEV4dGVuc2lvbnMubWFwKChleHQpID0+ICdpbWFnZS8nICsgZXh0KSA6IFsnaW1hZ2UvKiddO1xuICB9XG5cbiAgZGVsZXRlQWxsKCkge1xuICAgIHRoaXMuZmlsZXMuZm9yRWFjaChmID0+IHRoaXMucmVtb3ZlZC5lbWl0KGYpKTtcbiAgICB0aGlzLmZpbGVzID0gW107XG4gICAgdGhpcy5maWxlQ291bnRlciA9IDA7XG4gICAgaWYgKHRoaXMuaW5wdXRFbGVtZW50KSB7XG4gICAgICB0aGlzLmlucHV0RWxlbWVudC5uYXRpdmVFbGVtZW50LnZhbHVlID0gJyc7XG4gICAgfVxuICB9XG5cbiAgZGVsZXRlRmlsZShmaWxlOiBGaWxlSG9sZGVyKTogdm9pZCB7XG4gICAgbGV0IGluZGV4ID0gdGhpcy5maWxlcy5pbmRleE9mKGZpbGUpO1xuICAgIHRoaXMuZmlsZXMuc3BsaWNlKGluZGV4LCAxKTtcbiAgICB0aGlzLmZpbGVDb3VudGVyLS07XG5cbiAgICBpZiAodGhpcy5pbnB1dEVsZW1lbnQpIHtcbiAgICAgIHRoaXMuaW5wdXRFbGVtZW50Lm5hdGl2ZUVsZW1lbnQudmFsdWUgPSAnJztcbiAgICB9XG4gICAgdGhpcy5yZW1vdmVkLmVtaXQoZmlsZSk7XG4gIH1cblxuICBwcmV2aWV3RmlsZUNsaWNrZWQoZmlsZTogRmlsZUhvbGRlcikge1xuICAgIHRoaXMucHJldmlld0NsaWNrZWQuZW1pdChmaWxlKTtcbiAgfVxuXG4gIG5nT25DaGFuZ2VzKGNoYW5nZXMpIHtcbiAgICBpZiAoY2hhbmdlcy51cGxvYWRlZEZpbGVzICYmIGNoYW5nZXMudXBsb2FkZWRGaWxlcy5jdXJyZW50VmFsdWUgJiYgY2hhbmdlcy51cGxvYWRlZEZpbGVzLmN1cnJlbnRWYWx1ZS5sZW5ndGggPiAwKSB7XG4gICAgICB0aGlzLnByb2Nlc3NVcGxvYWRlZEZpbGVzKCk7XG4gICAgfVxuICB9XG5cbiAgb25GaWxlQ2hhbmdlKGZpbGVzOiBGaWxlTGlzdCkge1xuICAgIGlmICh0aGlzLmRpc2FibGVkKSByZXR1cm47XG5cbiAgICAvLyBsZXQgcmVtYWluaW5nU2xvdHMgPSAwO1xuICAgIGxldCByZW1haW5pbmdTbG90cyA9IHRoaXMuY291bnRSZW1haW5pbmdTbG90cygpO1xuICAgIGxldCBmaWxlc1RvVXBsb2FkTnVtID0gZmlsZXMubGVuZ3RoID4gcmVtYWluaW5nU2xvdHMgPyByZW1haW5pbmdTbG90cyA6IGZpbGVzLmxlbmd0aDtcblxuICAgIGlmICh0aGlzLnVybCAmJiBmaWxlc1RvVXBsb2FkTnVtICE9IDApIHtcbiAgICAgIHRoaXMudXBsb2FkU3RhdGVDaGFuZ2VkLmVtaXQodHJ1ZSk7XG4gICAgfVxuXG4gICAgdGhpcy5maWxlQ291bnRlciArPSBmaWxlc1RvVXBsb2FkTnVtO1xuICAgIHRoaXMuc2hvd0ZpbGVUb29MYXJnZU1lc3NhZ2UgPSBmYWxzZTtcbiAgICB0aGlzLnVwbG9hZEZpbGVzKGZpbGVzLCBmaWxlc1RvVXBsb2FkTnVtKTtcbiAgfVxuXG4gIG9uRmlsZU92ZXIgPSAoaXNPdmVyKSA9PiB0aGlzLmZpbGVPdmVyID0gaXNPdmVyO1xuXG4gIHByaXZhdGUgY291bnRSZW1haW5pbmdTbG90cyA9ICgpID0+IHRoaXMubWF4IC0gdGhpcy5maWxlQ291bnRlcjtcblxuICBwcml2YXRlIG9uUmVzcG9uc2UocmVzcG9uc2U6IFJlc3BvbnNlLCBmaWxlSG9sZGVyOiBGaWxlSG9sZGVyKSB7XG4gICAgZmlsZUhvbGRlci5zZXJ2ZXJSZXNwb25zZSA9IHsgc3RhdHVzOiByZXNwb25zZS5zdGF0dXMsIHJlc3BvbnNlIH07XG4gICAgZmlsZUhvbGRlci5wZW5kaW5nID0gZmFsc2U7XG5cbiAgICB0aGlzLnVwbG9hZEZpbmlzaGVkLmVtaXQoZmlsZUhvbGRlcik7XG5cbiAgICBpZiAoLS10aGlzLnBlbmRpbmdGaWxlc0NvdW50ZXIgPT0gMCkge1xuICAgICAgdGhpcy51cGxvYWRTdGF0ZUNoYW5nZWQuZW1pdChmYWxzZSk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBwcm9jZXNzVXBsb2FkZWRGaWxlcygpIHtcbiAgICBpZiAodHlwZW9mIHRoaXMudXBsb2FkZWRGaWxlcyA9PT0gJ3N0cmluZycpIHtcbiAgICAgIGxldCBkYXRhOiBhbnkgPSB0aGlzLnVwbG9hZGVkRmlsZXM7XG5cbiAgICAgIHRoaXMuZmlsZUNvdW50ZXIgPSAxO1xuICAgICAgdGhpcy5tYXggPSAxO1xuXG4gICAgICBsZXQgZmlsZUJsb2I6IEJsb2IsXG4gICAgICAgIGZpbGU6IEZpbGUsXG4gICAgICAgIGZpbGVVcmw6IHN0cmluZztcblxuICAgICAgaWYgKGRhdGEgaW5zdGFuY2VvZiBPYmplY3QpIHtcbiAgICAgICAgZmlsZVVybCA9IGRhdGEudXJsO1xuICAgICAgICBmaWxlQmxvYiA9IChkYXRhLmJsb2IpID8gZGF0YS5ibG9iIDogbmV3IEJsb2IoW2RhdGFdKTtcbiAgICAgICAgZmlsZSA9IG5ldyBGaWxlKFtmaWxlQmxvYl0sIGRhdGEuZmlsZU5hbWUpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZmlsZVVybCA9IGRhdGE7XG4gICAgICAgIGZpbGVCbG9iID0gbmV3IEJsb2IoW2ZpbGVVcmxdKTtcbiAgICAgICAgZmlsZSA9IG5ldyBGaWxlKFtmaWxlQmxvYl0sIGZpbGVVcmwpO1xuICAgICAgfVxuXG4gICAgICB0aGlzLmZpbGVzID0gW107XG4gICAgICB0aGlzLmZpbGVzLnB1c2gobmV3IEZpbGVIb2xkZXIoZmlsZVVybCwgZmlsZSkpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLm1heCA9IHRoaXMubWF4IC0gT2JqZWN0LmtleXModGhpcy51cGxvYWRlZEZpbGVzKS5sZW5ndGg7XG4gICAgICBmb3IgKGNvbnN0IGkgaW4gdGhpcy51cGxvYWRlZEZpbGVzKSB7XG4gICAgICAgIGxldCBkYXRhOiBhbnkgPSB0aGlzLnVwbG9hZGVkRmlsZXNbaV07XG5cbiAgICAgICAgbGV0IGZpbGVCbG9iOiBCbG9iLFxuICAgICAgICAgIGZpbGU6IEZpbGUsXG4gICAgICAgICAgZmlsZVVybDogc3RyaW5nO1xuXG4gICAgICAgIGlmIChkYXRhIGluc3RhbmNlb2YgT2JqZWN0KSB7XG4gICAgICAgICAgZmlsZVVybCA9IGRhdGEudXJsO1xuICAgICAgICAgIGZpbGVCbG9iID0gKGRhdGEuYmxvYikgPyBkYXRhLmJsb2IgOiBuZXcgQmxvYihbZGF0YV0pO1xuICAgICAgICAgIGZpbGUgPSBuZXcgRmlsZShbZmlsZUJsb2JdLCBkYXRhLmZpbGVOYW1lKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBmaWxlVXJsID0gZGF0YTtcbiAgICAgICAgICBmaWxlQmxvYiA9IG5ldyBCbG9iKFtmaWxlVXJsXSk7XG4gICAgICAgICAgZmlsZSA9IG5ldyBGaWxlKFtmaWxlQmxvYl0sIGZpbGVVcmwpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5maWxlcy5wdXNoKG5ldyBGaWxlSG9sZGVyKGZpbGVVcmwsIGZpbGUpKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIHVwbG9hZEZpbGVzKGZpbGVzOiBGaWxlTGlzdCwgZmlsZXNUb1VwbG9hZE51bTogbnVtYmVyKSB7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBmaWxlc1RvVXBsb2FkTnVtOyBpKyspIHtcbiAgICAgIGNvbnN0IGZpbGUgPSBmaWxlc1tpXTtcblxuICAgICAgaWYgKHRoaXMubWF4RmlsZVNpemUgJiYgZmlsZS5zaXplID4gdGhpcy5tYXhGaWxlU2l6ZSkge1xuICAgICAgICB0aGlzLmZpbGVDb3VudGVyLS07XG4gICAgICAgIHRoaXMuaW5wdXRFbGVtZW50Lm5hdGl2ZUVsZW1lbnQudmFsdWUgPSAnJztcbiAgICAgICAgdGhpcy5zaG93RmlsZVRvb0xhcmdlTWVzc2FnZSA9IHRydWU7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBiZWZvcmVVcGxvYWRSZXN1bHQ6IFVwbG9hZE1ldGFkYXRhID0gYXdhaXQgdGhpcy5iZWZvcmVVcGxvYWQoeyBmaWxlLCB1cmw6IHRoaXMudXJsLCBhYm9ydDogZmFsc2UgfSk7XG5cbiAgICAgIGlmIChiZWZvcmVVcGxvYWRSZXN1bHQuYWJvcnQpIHtcbiAgICAgICAgdGhpcy5maWxlQ291bnRlci0tO1xuICAgICAgICB0aGlzLmlucHV0RWxlbWVudC5uYXRpdmVFbGVtZW50LnZhbHVlID0gJyc7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBpbWcgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdpbWcnKTtcbiAgICAgIGltZy5zcmMgPSB3aW5kb3cuVVJMLmNyZWF0ZU9iamVjdFVSTChiZWZvcmVVcGxvYWRSZXN1bHQuZmlsZSk7XG5cbiAgICAgIGNvbnN0IHJlYWRlciA9IG5ldyBGaWxlUmVhZGVyKCk7XG4gICAgICByZWFkZXIuYWRkRXZlbnRMaXN0ZW5lcignbG9hZCcsIChldmVudDogYW55KSA9PiB7XG4gICAgICAgIGNvbnN0IGZpbGVIb2xkZXI6IEZpbGVIb2xkZXIgPSBuZXcgRmlsZUhvbGRlcihldmVudC50YXJnZXQucmVzdWx0LCBiZWZvcmVVcGxvYWRSZXN1bHQuZmlsZSk7XG4gICAgICAgIHRoaXMudXBsb2FkU2luZ2xlRmlsZShmaWxlSG9sZGVyLCBiZWZvcmVVcGxvYWRSZXN1bHQudXJsLCBiZWZvcmVVcGxvYWRSZXN1bHQuZm9ybURhdGEpO1xuICAgICAgICB0aGlzLmZpbGVzLnB1c2goZmlsZUhvbGRlcik7XG4gICAgICB9LCBmYWxzZSk7XG4gICAgICByZWFkZXIucmVhZEFzRGF0YVVSTChiZWZvcmVVcGxvYWRSZXN1bHQuZmlsZSk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSB1cGxvYWRTaW5nbGVGaWxlKGZpbGVIb2xkZXI6IEZpbGVIb2xkZXIsIHVybCA9IHRoaXMudXJsLCBjdXN0b21Gb3JtPzogeyBbbmFtZTogc3RyaW5nXTogYW55IH0pIHtcbiAgICBpZiAodXJsKSB7XG4gICAgICB0aGlzLnBlbmRpbmdGaWxlc0NvdW50ZXIrKztcbiAgICAgIGZpbGVIb2xkZXIucGVuZGluZyA9IHRydWU7XG5cbiAgICAgIHRoaXMuaW1hZ2VTZXJ2aWNlXG4gICAgICAgIC5wb3N0SW1hZ2UodXJsLCBmaWxlSG9sZGVyLmZpbGUsIHRoaXMuaGVhZGVycywgdGhpcy5wYXJ0TmFtZSwgY3VzdG9tRm9ybSwgdGhpcy53aXRoQ3JlZGVudGlhbHMpXG4gICAgICAgIC5zdWJzY3JpYmUoXG4gICAgICAgICAgcmVzcG9uc2UgPT4gdGhpcy5vblJlc3BvbnNlKHJlc3BvbnNlLCBmaWxlSG9sZGVyKSxcbiAgICAgICAgICBlcnJvciA9PiB7XG4gICAgICAgICAgICB0aGlzLm9uUmVzcG9uc2UoZXJyb3IsIGZpbGVIb2xkZXIpO1xuICAgICAgICAgICAgdGhpcy5kZWxldGVGaWxlKGZpbGVIb2xkZXIpO1xuICAgICAgICAgIH0pO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnVwbG9hZEZpbmlzaGVkLmVtaXQoZmlsZUhvbGRlcik7XG4gICAgfVxuICB9XG5cbn1cbiJdfQ==