UNPKG

ngx-image-upload

Version:
405 lines (404 loc) 45.2 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'; var FileHolder = /** @class */ (function () { function FileHolder(src, file) { this.src = src; this.file = file; this.pending = false; } return FileHolder; }()); export { FileHolder }; function FileHolder_tsickle_Closure_declarations() { /** @type {?} */ FileHolder.prototype.pending; /** @type {?} */ FileHolder.prototype.serverResponse; /** @type {?} */ FileHolder.prototype.src; /** @type {?} */ FileHolder.prototype.file; } var NgxImageUploadComponent = /** @class */ (function () { function NgxImageUploadComponent(imageService) { var _this = this; this.imageService = imageService; this.files = []; this.fileCounter = 0; this.fileOver = false; this.showFileTooLargeMessage = false; this.beforeUpload = function (data) { return 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 = function (isOver) { return _this.fileOver = isOver; }; this.countRemainingSlots = function () { return _this.max - _this.fileCounter; }; } /** * @return {?} */ NgxImageUploadComponent.prototype.ngOnInit = /** * @return {?} */ function () { if (!this.fileTooLargeMessage) { this.fileTooLargeMessage = '图片太大无法上传.' + (this.maxFileSize ? (' 最大允许 ' + this.maxFileSize / 1024) + 'KiB.' : ''); } this.supportedExtensions = this.supportedExtensions ? this.supportedExtensions.map(function (ext) { return 'image/' + ext; }) : ['image/*']; }; /** * @return {?} */ NgxImageUploadComponent.prototype.deleteAll = /** * @return {?} */ function () { var _this = this; this.files.forEach(function (f) { return _this.removed.emit(f); }); this.files = []; this.fileCounter = 0; if (this.inputElement) { this.inputElement.nativeElement.value = ''; } }; /** * @param {?} file * @return {?} */ NgxImageUploadComponent.prototype.deleteFile = /** * @param {?} file * @return {?} */ function (file) { var /** @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 {?} */ NgxImageUploadComponent.prototype.previewFileClicked = /** * @param {?} file * @return {?} */ function (file) { this.previewClicked.emit(file); }; /** * @param {?} changes * @return {?} */ NgxImageUploadComponent.prototype.ngOnChanges = /** * @param {?} changes * @return {?} */ function (changes) { if (changes.uploadedFiles && changes.uploadedFiles.currentValue && changes.uploadedFiles.currentValue.length > 0) { this.processUploadedFiles(); } }; /** * @param {?} files * @return {?} */ NgxImageUploadComponent.prototype.onFileChange = /** * @param {?} files * @return {?} */ function (files) { if (this.disabled) return; // let remainingSlots = 0; var /** @type {?} */ remainingSlots = this.countRemainingSlots(); var /** @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 {?} */ NgxImageUploadComponent.prototype.onResponse = /** * @param {?} response * @param {?} fileHolder * @return {?} */ function (response, fileHolder) { fileHolder.serverResponse = { status: response.status, response: response }; fileHolder.pending = false; this.uploadFinished.emit(fileHolder); if (--this.pendingFilesCounter == 0) { this.uploadStateChanged.emit(false); } }; /** * @return {?} */ NgxImageUploadComponent.prototype.processUploadedFiles = /** * @return {?} */ function () { if (typeof this.uploadedFiles === 'string') { var /** @type {?} */ data = this.uploadedFiles; this.fileCounter = 1; this.max = 1; var /** @type {?} */ fileBlob = void 0, /** @type {?} */ file = void 0, /** @type {?} */ fileUrl = void 0; 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 (var /** @type {?} */ i in this.uploadedFiles) { var /** @type {?} */ data = this.uploadedFiles[i]; var /** @type {?} */ fileBlob = void 0, /** @type {?} */ file = void 0, /** @type {?} */ fileUrl = void 0; 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 {?} */ NgxImageUploadComponent.prototype.uploadFiles = /** * @param {?} files * @param {?} filesToUploadNum * @return {?} */ function (files, filesToUploadNum) { return tslib_1.__awaiter(this, void 0, void 0, function () { var _this = this; var _loop_1, this_1, i; return tslib_1.__generator(this, function (_a) { switch (_a.label) { case 0: _loop_1 = function (i) { var file, beforeUploadResult, img, reader; return tslib_1.__generator(this, function (_a) { switch (_a.label) { case 0: file = files[i]; if (this_1.maxFileSize && file.size > this_1.maxFileSize) { this_1.fileCounter--; this_1.inputElement.nativeElement.value = ''; this_1.showFileTooLargeMessage = true; return [2 /*return*/, "continue"]; } return [4 /*yield*/, this_1.beforeUpload({ file: file, url: this_1.url, abort: false })]; case 1: beforeUploadResult = _a.sent(); if (beforeUploadResult.abort) { this_1.fileCounter--; this_1.inputElement.nativeElement.value = ''; return [2 /*return*/, "continue"]; } img = document.createElement('img'); img.src = window.URL.createObjectURL(beforeUploadResult.file); reader = new FileReader(); reader.addEventListener('load', function (event) { var /** @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); return [2 /*return*/]; } }); }; this_1 = this; i = 0; _a.label = 1; case 1: if (!(i < filesToUploadNum)) return [3 /*break*/, 4]; return [5 /*yield**/, _loop_1(i)]; case 2: _a.sent(); _a.label = 3; case 3: i++; return [3 /*break*/, 1]; case 4: return [2 /*return*/]; } }); }); }; /** * @param {?} fileHolder * @param {?=} url * @param {?=} customForm * @return {?} */ NgxImageUploadComponent.prototype.uploadSingleFile = /** * @param {?} fileHolder * @param {?=} url * @param {?=} customForm * @return {?} */ function (fileHolder, url, customForm) { var _this = this; if (url === void 0) { url = this.url; } if (url) { this.pendingFilesCounter++; fileHolder.pending = true; this.imageService .postImage(url, fileHolder.file, this.headers, this.partName, customForm, this.withCredentials) .subscribe(function (response) { return _this.onResponse(response, fileHolder); }, function (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\n fileDrop\n [accept]=\"supportedExtensions\"\n (fileOver)=\"onFileOver($event)\"\n (fileDrop)=\"onFileChange($event)\"\n [ngClass]=\"cssClass\"\n [ngClass]=\"{'img-ul-file-is-over': fileOver}\" \n [ngStyle]=\"style?.layout\"\n>\n <p class=\"img-ul-file-too-large\" *ngIf=\"showFileTooLargeMessage\" [innerText]=\"fileTooLargeMessage\"></p>\n\n <div *ngIf=\"preview\" class=\"img-ul-container img-ul-hr-inline-group\" [ngStyle]=\"style?.previewPanel\">\n <!-- img -->\n <div\n class=\"img-ul-image\"\n *ngFor=\"let file of files\"\n (click)=\"previewFileClicked(file)\"\n >\n <!-- [ngStyle]=\"{'background-image': 'url('+ file.src +')'}\" -->\n <div class=\"img_div\"><img src={{file.src}} class=\"imgs\"></div>\n <div *ngIf=\"file.pending\" class=\"img-ul-loading-overlay\">\n <div class=\"img-ul-spinning-circle\"></div>\n </div>\n <div *ngIf=\"!file.pending\" \n [ngClass]=\"{'img-ul-disabled': disabled}\" \n class=\"img-ul-x-mark\" \n (click)=\"deleteFile(file)\">\n <span class=\"img-ul-close\"></span>\n </div>\n </div>\n </div>\n \n <div class=\"img-ul-file-upload img-ul-hr-inline-group\"> \n <label *ngIf=\"fileCounter != max\"\n class=\"img-ul-upload img-ul-button\" \n [ngStyle]=\"style?.selectButton\"\n [ngClass]=\"{'img-ul-disabled': disabled}\">\n <span [innerText]=\"buttonCaption\"></span>\n <input\n type=\"file\"\n [disabled]=\"disabled\"\n [accept]=\"supportedExtensions\"\n multiple (change)=\"onFileChange(input.files)\"\n #input>\n </label>\n </div>\n</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 = function () { return [ { 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',] }] }; return NgxImageUploadComponent; }()); export { NgxImageUploadComponent }; 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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmd4LWltYWdlLXVwbG9hZC5jb21wb25lbnQuanMiLCJzb3VyY2VSb290Ijoibmc6Ly9uZ3gtaW1hZ2UtdXBsb2FkLyIsInNvdXJjZXMiOlsibGliL25neC1pbWFnZS11cGxvYWQuY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBQUEsT0FBTyxFQUFFLFNBQVMsRUFBcUIsS0FBSyxFQUFFLE1BQU0sRUFBRSxZQUFZLEVBQUUsVUFBVSxFQUFFLFNBQVMsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUdqSCxPQUFPLEVBQUUscUJBQXFCLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUduRSxJQUFBO0lBSUUsb0JBQW1CLEdBQVcsRUFBUyxJQUFVO1FBQTlCLFFBQUcsR0FBSCxHQUFHLENBQVE7UUFBUyxTQUFJLEdBQUosSUFBSSxDQUFNO3VCQUh2QixLQUFLO0tBSTlCO3FCQVhIO0lBWUMsQ0FBQTtBQU5ELHNCQU1DOzs7Ozs7Ozs7Ozs7SUFzRkMsaUNBQW9CLFlBQW1DO1FBQXZELGlCQUE0RDtRQUF4QyxpQkFBWSxHQUFaLFlBQVksQ0FBdUI7cUJBL0JqQyxFQUFFOzJCQUNGLENBQUM7d0JBQ0gsS0FBSzt1Q0FDVSxLQUFLOzRCQUVxRCxVQUFBLElBQUksSUFBSSxPQUFBLElBQUksRUFBSixDQUFJOzZCQUNoRixNQUFNO3dCQUNYLEtBQUs7d0JBQ0UsUUFBUTtrQ0FDTCxJQUFJOzhCQUNSLFNBQVM7bUJBR3BCLEdBQUc7dUJBRUMsSUFBSTsrQkFLSSxLQUFLOzZCQUMyRCxFQUFFO3VCQUN6RSxJQUFJLFlBQVksRUFBYztrQ0FDbkIsSUFBSSxZQUFZLEVBQVc7OEJBQy9CLElBQUksWUFBWSxFQUFjOzhCQUM5QixJQUFJLFlBQVksRUFBYzttQ0FJbkIsQ0FBQzswQkF5RDFCLFVBQUMsTUFBTSxJQUFLLE9BQUEsS0FBSSxDQUFDLFFBQVEsR0FBRyxNQUFNLEVBQXRCLENBQXNCO21DQUVqQixjQUFNLE9BQUEsS0FBSSxDQUFDLEdBQUcsR0FBRyxL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RnBCOztTQWlFYSx1QkFBdUIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21wb25lbnQsIE9uSW5pdCwgT25DaGFuZ2VzLCBJbnB1dCwgT3V0cHV0LCBFdmVudEVtaXR0ZXIsIEVsZW1lbnRSZWYsIFZpZXdDaGlsZCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuXG5pbXBvcnQgeyBVcGxvYWRNZXRhZGF0YSB9IGZyb20gJy4vYmVmb3JlLXVwbG9hZC5pbnRlcmZhY2UnO1xuaW1wb3J0IHsgTmd4SW1hZ2VVcGxvYWRTZXJ2aWNlIH0gZnJvbSAnLi9uZ3gtaW1hZ2UtdXBsb2FkLnNlcnZpY2UnO1xuaW1wb3J0IHsgU3R5bGUgfSBmcm9tICcuL3N0eWxlJztcblxuZXhwb3J0IGNsYXNzIEZpbGVIb2xkZXIge1xuICBwdWJsaWMgcGVuZGluZzogYm9vbGVhbiA9IGZhbHNlO1xuICBwdWJsaWMgc2VydmVyUmVzcG9uc2U6IHsgc3RhdHVzOiBudW1iZXIsIHJlc3BvbnNlOiBhbnkgfTtcblxuICBjb25zdHJ1Y3RvcihwdWJsaWMgc3JjOiBzdHJpbmcsIHB1YmxpYyBmaWxlOiBGaWxlKSB7XG4gIH1cbn1cblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnZHMtbmd4LWltYWdlLXVwbG9hZCcsXG4gIHRlbXBsYXRlOiBgPGRpdlxuICAgICBmaWxlRHJvcFxuICAgICBbYWNjZXB0XT1cInN1cHBvcnRlZEV4dGVuc2lvbnNcIlxuICAgICAoZmlsZU92ZXIpPVwib25GaWxlT3ZlcigkZXZlbnQpXCJcbiAgICAgKGZpbGVEcm9wKT1cIm9uRmlsZUNoYW5nZSgkZXZlbnQpXCJcbiAgICAgW25nQ2xhc3NdPVwiY3NzQ2xhc3NcIlxuICAgICBbbmdDbGFzc109XCJ7J2ltZy11bC1maWxlLWlzLW92ZXInOiBmaWxlT3Zlcn1cIiAgICAgXG4gICAgIFtuZ1N0eWxlXT1cInN0eWxlPy5sYXlvdXRcIlxuPlxuICA8cCBjbGFzcz1cImltZy11bC1maWxlLXRvby1sYXJnZVwiICpuZ0lmPVwic2hvd0ZpbGVUb29MYXJnZU1lc3NhZ2VcIiBbaW5uZXJUZXh0XT1cImZpbGVUb29MYXJnZU1lc3NhZ2VcIj48L3A+XG5cbiAgPGRpdiAqbmdJZj1cInByZXZpZXdcIiBjbGFzcz1cImltZy11bC1jb250YWluZXIgaW1nLXVsLWhyLWlubGluZS1ncm91cFwiIFtuZ1N0eWxlXT1cInN0eWxlPy5wcmV2aWV3UGFuZWxcIj5cbiAgICA8IS0tIGltZyAtLT5cbiAgICA8ZGl2XG4gICAgICBjbGFzcz1cImltZy11bC1pbWFnZVwiXG4gICAgICAqbmdGb3I9XCJsZXQgZmlsZSBvZiBmaWxlc1wiXG4gICAgICAoY2xpY2spPVwicHJldmlld0ZpbGVDbGlja2VkKGZpbGUpXCJcbiAgICA+XG4gICAgICA8IS0tIFtuZ1N0eWxlXT1cInsnYmFja2dyb3VuZC1pbWFnZSc6ICd1cmwoJysgZmlsZS5zcmMgKycpJ31cIiAtLT5cbiAgICAgIDxkaXYgY2xhc3M9XCJpbWdfZGl2XCI+PGltZyBzcmM9e3tmaWxlLnNyY319IGNsYXNzPVwiaW1nc1wiPjwvZGl2PlxuICAgICAgPGRpdiAqbmdJZj1cImZpbGUucGVuZGluZ1wiIGNsYXNzPVwiaW1nLXVsLWxvYWRpbmctb3ZlcmxheVwiPlxuICAgICAgICA8ZGl2IGNsYXNzPVwiaW1nLXVsLXNwaW5uaW5nLWNpcmNsZVwiPjwvZGl2PlxuICAgICAgPC9kaXY+XG4gICAgICA8ZGl2ICpuZ0lmPVwiIWZpbGUucGVuZGluZ1wiIFxuICAgICAgICBbbmdDbGFzc109XCJ7J2ltZy11bC1kaXNhYmxlZCc6IGRpc2FibGVkfVwiIFxuICAgICAgICBjbGFzcz1cImltZy11bC14LW1hcmtcIiBcbiAgICAgICAgKGNsaWNrKT1cImRlbGV0ZUZpbGUoZmlsZSlcIj5cbiAgICAgICAgPHNwYW4gY2xhc3M9XCJpbWctdWwtY2xvc2VcIj48L3NwYW4+XG4gICAgICA8L2Rpdj5cbiAgICA8L2Rpdj5cbiAgPC9kaXY+XG4gIFxuICA8ZGl2IGNsYXNzPVwiaW1nLXVsLWZpbGUtdXBsb2FkIGltZy11bC1oci1pbmxpbmUtZ3JvdXBcIj4gICAgXG4gICAgPGxhYmVsICpuZ0lmPVwiZmlsZUNvdW50ZXIgIT0gbWF4XCJcbiAgICAgIGNsYXNzPVwiaW1nLXVsLXVwbG9hZCBpbWctdWwtYnV0dG9uXCIgXG4gICAgICBbbmdTdHlsZV09XCJzdHlsZT8uc2VsZWN0QnV0dG9uXCJcbiAgICAgIFtuZ0NsYXNzXT1cInsnaW1nLXVsLWRpc2FibGVkJzogZGlzYWJsZWR9XCI+XG4gICAgICA8c3BhbiBbaW5uZXJUZXh0XT1cImJ1dHRvbkNhcHRpb25cIj48L3NwYW4+XG4gICAgICA8aW5wdXRcbiAgICAgICAgdHlwZT1cImZpbGVcIlxuICAgICAgICBbZGlzYWJsZWRdPVwiZGlzYWJsZWRcIlxuICAgICAgICBbYWNjZXB0XT1cInN1cHBvcnRlZEV4dGVuc2lvbnNcIlxuICAgICAgICBtdWx0aXBsZSAoY2hhbmdlKT1cIm9uRmlsZUNoYW5nZShpbnB1dC5maWxlcylcIlxuICAgICAgICAjaW5wdXQ+XG4gICAgPC9sYWJlbD5cbiAgPC9kaXY+XG48L2Rpdj5gLFxuICBzdHlsZXM6IFtgLmltZy11bHstLWNvbW1vbi1yYWRpdXM6M3B4O2JvcmRlci1yYWRpdXM6dmFyKC0tY29tbW9uLXJhZGl1cyk7cG9zaXRpb246cmVsYXRpdmU7Y29sb3I6IzliOWI5Yjtmb250LXdlaWdodDo0MDB9LmltZy11bC14LW1hcmt7YmFja2dyb3VuZC1jb2xvcjojMDAwO2JvcmRlci1yYWRpdXM6MTBweDtjb2xvcjojZmZmO2N1cnNvcjpwb2ludGVyO2hlaWdodDoyMHB4O29wYWNpdHk6Ljc7dGV4dC1hbGlnbjpjZW50ZXI7d2lkdGg6MjBweDtwb3NpdGlvbjphYnNvbHV0ZTt0b3A6LThweDtyaWdodDotMTBweH0uaW1nX2Rpdntwb3NpdGlvbjpyZWxhdGl2ZTt3aWR0aDoxMjBweDtoZWlnaHQ6MTIwcHg7b3ZlcmZsb3c6aGlkZGVufS5pbWdze21heC13aWR0aDoyMDAlO2hlaWdodDphdXRvO3Bvc2l0aW9uOmFic29sdXRlO3RvcDo1MCU7bGVmdDo1MCU7LXdlYmtpdC10cmFuc2Zvcm06dHJhbnNsYXRlKC01MCUsLTUwJSk7dHJhbnNmb3JtOnRyYW5zbGF0ZSgtNTAlLC01MCUpO2JhY2tncm91bmQ6IzAwMH0uaW1nLXVsLWZpbGUtaXMtb3Zlcntib3JkZXI6dmFyKC0tYWN0aXZlLWNvbG9yKSBzb2xpZH0uaW1nLXVsLWhyLWlubGluZS1ncm91cDphZnRlcntjbGVhcjpib3RoO2NvbnRlbnQ6XCJcIjtkaXNwbGF5OnRhYmxlfS5pbWctdWwtZmlsZS11cGxvYWR7ZGlzcGxheTppbmxpbmUtYmxvY2s7d2lkdGg6MTIwcHg7aGVpZ2h0OjEyMHB4O21hcmdpbjoxMHB4O2NvbG9yOiMwMDA7dGV4dC1hbGlnbjpjZW50ZXI7bGluZS1oZWlnaHQ6MTIwcHh9LmltZy11bC1kcmFnLWJveC1tc2d7ZGlzcGxheTppbmxpbmUtYmxvY2s7Zm9udC13ZWlnaHQ6NjAwO21hcmdpbi1sZWZ0OjEycHh9bGFiZWwuaW1nLXVsLWJ1dHRvbntib3JkZXI6MXB4IGRhc2hlZCAjZDBkMGQwO2ZvbnQtc2l6ZToxZW0haW1wb3J0YW50fWxhYmVsLmltZy11bC1idXR0b24gaW5wdXRbdHlwZT1maWxlXXtkaXNwbGF5Om5vbmU7cG9zaXRpb246Zml4ZWQ7dG9wOi05OTk5OXB4fS5pbWctdWwtY2xlYXJ7YmFja2dyb3VuZC1jb2xvcjpyZWQ7Zm9udC1zaXplOjFlbSFpbXBvcnRhbnR9LmltZy11bC1jbGVhcjpkaXNhYmxlZHtiYWNrZ3JvdW5kLWNvbG9yOiNmZjY0NjQ7Y3Vyc29yOmRlZmF1bHR9LmltZy11bC11cGxvYWR7YmFja2dyb3VuZC1jb2xvcjp2YXIoLS1hY3RpdmUtY29sb3IpO3dpZHRoOjEyMHB4O2hlaWdodDoxMjBweH0uaW1nLXVsLWJ1dHRvbntib3JkZXI6bm9uZTtjdXJzb3I6cG9pbnRlcjtkaXNwbGF5OmlubGluZS1ibG9jaztmbG9hdDpsZWZ0O2ZvbnQtc2l6ZToxLjI1ZW07Zm9udC13ZWlnaHQ6NTAwO3RleHQtdHJhbnNmb3JtOnVwcGVyY2FzZX0uaW1nLXVsLWJ1dHRvbjphY3RpdmUgc3BhbntkaXNwbGF5OmJsb2NrO3Bvc2l0aW9uOnJlbGF0aXZlO3RvcDoxcHh9LmltZy11bC1jb250YWluZXJ7cG9zaXRpb246cmVsYXRpdmU7ZGlzcGxheTppbmxpbmUtYmxvY2t9LmltZy11bC1pbWFnZXtib3gtc2hhZG93OjAgMCAxMHB4IDJweCAjZDBkMGQwO2JhY2tncm91bmQ6Y2VudGVyIGNlbnRlci9jb250YWluIG5vLXJlcGVhdDtkaXNwbGF5OmlubGluZS1ibG9jaztmbG9hdDpsZWZ0O2hlaWdodDoxMjBweDttYXJnaW46NnB4O3Bvc2l0aW9uOnJlbGF0aXZlO3dpZHRoOjEyMHB4fS5pbWctdWwtY2xvc2V7aGVpZ2h0OjIwcHg7b3BhY2l0eTouNztwb3NpdGlvbjpyZWxhdGl2ZTt3aWR0aDoyMHB4fS5pbWctdWwteC1tYXJrOmhvdmVyIC5pbWctdWwtY2xvc2V7b3BhY2l0eToxfS5pbWctdWwtY2xvc2U6YWZ0ZXIsLmltZy11bC1jbG9zZTpiZWZvcmV7YmFja2dyb3VuZC1jb2xvcjojZmZmO2JvcmRlci1yYWRpdXM6MnB4O2NvbnRlbnQ6Jyc7aGVpZ2h0OjEwcHg7cG9zaXRpb246YWJzb2x1dGU7dG9wOjVweDt3aWR0aDoycHh9LmltZy11bC1jbG9zZTpiZWZvcmV7LXdlYmtpdC10cmFuc2Zvcm06cm90YXRlKDQ1ZGVnKTt0cmFuc2Zvcm06cm90YXRlKDQ1ZGVnKX0uaW1nLXVsLWNsb3NlOmFmdGVyey13ZWJraXQtdHJhbnNmb3JtOnJvdGF0ZSgtNDVkZWcpO3RyYW5zZm9ybTpyb3RhdGUoLTQ1ZGVnKX0uaW1nLXVsLXgtbWFyay5pbWctdWwtZGlzYWJsZWR7ZGlzcGxheTpub25lfS5pbWctdWwtbG9hZGluZy1vdmVybGF5e2JhY2tncm91bmQtY29sb3I6IzAwMDtib3R0b206MDtsZWZ0OjA7b3BhY2l0eTouNztwb3NpdGlvbjphYnNvbHV0ZTtyaWdodDowO3RvcDowfS5pbWctdWwtc3Bpbm5pbmctY2lyY2xle2hlaWdodDozMHB4O3dpZHRoOjMwcHg7bWFyZ2luOmF1dG87cG9zaXRpb246YWJzb2x1dGU7dG9wOjA7bGVmdDowO2JvdHRvbTowO3JpZ2h0OjA7Ym9yZGVyLXJhZGl1czo1MCU7Ym9yZGVyOjNweCBzb2xpZCByZ2JhKDI1NSwyNTUsMjU1LDApO2JvcmRlci10b3A6M3B4IHNvbGlkICNmZmY7Ym9yZGVyLXJpZ2h0OjNweCBzb2xpZCAjZmZmOy13ZWJraXQtYW5pbWF0aW9uOjJzIGN1YmljLWJlemllciguMDg1LC42MjUsLjg1NSwuMzYpIGluZmluaXRlIHNwaW5uZXI7YW5pbWF0aW9uOjJzIGN1YmljLWJlemllciguMDg1LC42MjUsLjg1NSwuMzYpIGluZmluaXRlIHNwaW5uZXJ9LmltZy11bC1maWxlLXRvby1sYXJnZXtjb2xvcjpyZWR9LmltZy11bC11cGxvYWQuaW1nLXVsLWRpc2FibGVke2JhY2tncm91bmQtY29sb3I6Izg2ZTljOTtjdXJzb3I6ZGVmYXVsdH0uaW1nLXVsLXVwbG9hZC5pbWctdWwtZGlzYWJsZWQ6YWN0aXZlIHNwYW57dG9wOjB9QC13ZWJraXQta2V5ZnJhbWVzIHNwaW5uZXJ7MCV7LXdlYmtpdC10cmFuc2Zvcm06cm90YXRlKDApO3RyYW5zZm9ybTpyb3RhdGUoMCl9MTAwJXstd2Via2l0LXRyYW5zZm9ybTpyb3RhdGUoMzYwZGVnKTt0cmFuc2Zvcm06cm90YXRlKDM2MGRlZyl9fUBrZXlmcmFtZXMgc3Bpbm5lcnswJXstd2Via2l0LXRyYW5zZm9ybTpyb3RhdGUoMCk7dHJhbnNmb3JtOnJvdGF0ZSgwKX0xMDAley13ZWJraXQtdHJhbnNmb3JtOnJvdGF0ZSgzNjBkZWcpO3RyYW5zZm9ybTpyb3RhdGUoMzYwZGVnKX19YF1cbn0pXG5leHBvcnQgY2xhc3MgTmd4SW1hZ2VVcGxvYWRDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQsIE9uQ2hhbmdlcyB7XG5cbiAgZmlsZXM6IEZpbGVIb2xkZXJbXSA9IFtdO1xuICBmaWxlQ291bnRlcjogbnVtYmVyID0gMDtcbiAgZmlsZU92ZXI6IGJvb2xlYW4gPSBmYWxzZTtcbiAgc2hvd0ZpbGVUb29MYXJnZU1lc3NhZ2U6IGJvb2xlYW4gPSBmYWxzZTtcblxuICBASW5wdXQoKSBiZWZvcmVVcGxvYWQ6IChwYXJhbTogVXBsb2FkTWV0YWRhdGEpID0+IFVwbG9hZE1ldGFkYXRhIHwgUHJvbWlzZTxVcGxvYWRNZXRhZGF0YT4gPSBkYXRhID0+IGRhdGE7XG4gIEBJbnB1dCgpIGJ1dHRvbkNhcHRpb24gPSAn5re75Yqg5Zu+54mHJztcbiAgQElucHV0KCkgZGlzYWJsZWQgPSBmYWxzZTtcbiAgQElucHV0KCdjbGFzcycpIGNzc0NsYXNzID0gJ2ltZy11bCc7XG4gIEBJbnB1dCgpIGNsZWFyQnV0dG9uQ2FwdGlvbiA9ICfmuIXpmaQnO1xuICBASW5wdXQoKSBkcm9wQm94TWVzc2FnZSA9ICfmi5bmi73lm77niYfliLDmraTlpIQnO1xuICBASW5wdXQoKSBmaWxlVG9vTGFyZ2VNZXNzYWdlO1xuICBASW5wdXQoKSBoZWFkZXJzOiBIZWFkZXJzIHwgeyBbbmFtZTogc3RyaW5nXTogYW55IH07XG4gIEBJbnB1dCgpIG1heCA9IDEwMDtcbiAgQElucHV0KCkgbWF4RmlsZVNpemU6IG51bWJlcjtcbiAgQElucHV0KCkgcHJldmlldyA9IHRydWU7XG4gIEBJbnB1dCgpIHBhcnROYW1lOiBzdHJpbmc7XG4gIEBJbnB1dCgpIHN0eWxlOiBTdHlsZTtcbiAgQElucHV0KCdleHRlbnNpb25zJykgc3VwcG9ydGVkRXh0ZW5zaW9uczogc3RyaW5nW107XG4gIEBJbnB1dCgpIHVybDogc3RyaW5nO1xuICBASW5wdXQoKSB3aXRoQ3JlZGVudGlhbHMgPSBmYWxzZTtcbiAgQElucHV0KCkgdXBsb2FkZWRGaWxlczogc3RyaW5nW10gfCBBcnJheTx7IHVybDogc3RyaW5nLCBmaWxlTmFtZTogc3RyaW5nLCBibG9iPzogQmxvYiB9PiA9IFtdO1xuICBAT3V0cHV0KCkgcmVtb3ZlZCA9IG5ldyBFdmVudEVtaXR0ZXI8RmlsZUhvbGRlcj4oKTtcbiAgQE91dHB1dCgpIHVwbG9hZFN0YXRlQ2hhbmdlZCA9IG5ldyBFdmVudEVtaXR0ZXI8Ym9vbGVhbj4oKTtcbiAgQE91dHB1dCgpIHVwbG9hZEZpbmlzaGVkID0gbmV3IEV2ZW50RW1pdHRlcjxGaWxlSG9sZGVyPigpO1xuICBAT3V0cHV0KCkgcHJldmlld0NsaWNrZWQgPSBuZXcgRXZlbnRFbWl0dGVyPEZpbGVIb2xkZXI+KCk7XG5cbiAgQFZpZXdDaGlsZCgnaW5wdXQnKVxuICBwcml2YXRlIGlucHV0RWxlbWVudDogRWxlbWVudFJlZjtcbiAgcHJpdmF0ZSBwZW5kaW5nRmlsZXNDb3VudGVyOiBudW1iZXIgPSAwO1xuXG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgaW1hZ2VTZXJ2aWNlOiBOZ3hJbWFnZVVwbG9hZFNlcnZpY2UpIHsgfVxuXG4gIG5nT25Jbml0KCkge1xuICAgIGlmICghdGhpcy5maWxlVG9vTGFyZ2VNZXNzYWdlKSB7XG4gICAgICB0aGlzLmZpbGVUb29MYXJnZU1lc3NhZ2UgPSAn5Zu+54mH5aSq5aSn5peg5rOV5LiK5LygLicgKyAodGhpcy5tYXhGaWxlU2l6ZSA/ICgnIOacgOWkp+WFgeiuuCAnICsgdGhpcy5tYXhGaWxlU2l6ZSAvIDEwMjQpICsgJ0tpQi4nIDogJycpO1xuICAgIH1cbiAgICB0aGlzLnN1cHBvcnRlZEV4dGVuc2lvbnMgPSB0aGlzLnN1cHBvcnRlZEV4dGVuc2lvbnMgPyB0aGlzLnN1cHBvcnRlZEV4dGVuc2lvbnMubWFwKChleHQpID0+ICdpbWFnZS8nICsgZXh0KSA6IFsnaW1hZ2UvKiddO1xuICB9XG5cbiAgZGVsZXRlQWxsKCkge1xuICAgIHRoaXMuZmlsZXMuZm9yRWFjaChmID0+IHRoaXMucmVtb3ZlZC5lbWl0KGYpKTtcbiAgICB0aGlzLmZpbGVzID0gW107XG4gICAgdGhpcy5maWxlQ291bnRlciA9IDA7XG4gICAgaWYgKHRoaXMuaW5wdXRFbGVtZW50KSB7XG4gICAgICB0aGlzLmlucHV0RWxlbWVudC5uYXRpdmVFbGVtZW50LnZhbHVlID0gJyc7XG4gICAgfVxuICB9XG5cbiAgZGVsZXRlRmlsZShmaWxlOiBGaWxlSG9sZGVyKTogdm9pZCB7XG4gICAgbGV0IGluZGV4ID0gdGhpcy5maWxlcy5pbmRleE9mKGZpbGUpO1xuICAgIHRoaXMuZmlsZXMuc3BsaWNlKGluZGV4LCAxKTtcbiAgICB0aGlzLmZpbGVDb3VudGVyLS07XG5cbiAgICBpZiAodGhpcy5pbnB1dEVsZW1lbnQpIHtcbiAgICAgIHRoaXMuaW5wdXRFbGVtZW50Lm5hdGl2ZUVsZW1lbnQudmFsdWUgPSAnJztcbiAgICB9XG4gICAgdGhpcy5yZW1vdmVkLmVtaXQoZmlsZSk7XG4gIH1cblxuICBwcmV2aWV3RmlsZUNsaWNrZWQoZmlsZTogRmlsZUhvbGRlcikge1xuICAgIHRoaXMucHJldmlld0NsaWNrZWQuZW1pdChmaWxlKTtcbiAgfVxuXG4gIG5nT25DaGFuZ2VzKGNoYW5nZXMpIHtcbiAgICBpZiAoY2hhbmdlcy51cGxvYWRlZEZpbGVzICYmIGNoYW5nZXMudXBsb2FkZWRGaWxlcy5jdXJyZW50VmFsdWUgJiYgY2hhbmdlcy51cGxvYWRlZEZpbGVzLmN1cnJlbnRWYWx1ZS5sZW5ndGggPiAwKSB7XG4gICAgICB0aGlzLnByb2Nlc3NVcGxvYWRlZEZpbGVzKCk7XG4gICAgfVxuICB9XG5cbiAgb25GaWxlQ2hhbmdlKGZpbGVzOiBGaWxlTGlzdCkge1xuICAgIGlmICh0aGlzLmRpc2FibGVkKSByZXR1cm47XG5cbiAgICAvLyBsZXQgcmVtYWluaW5nU2xvdHMgPSAwO1xuICAgIGxldCByZW1haW5pbmdTbG90cyA9IHRoaXMuY291bnRSZW1haW5pbmdTbG90cygpO1xuICAgIGxldCBmaWxlc1RvVXBsb2FkTnVtID0gZmlsZXMubGVuZ3RoID4gcmVtYWluaW5nU2xvdHMgPyByZW1haW5pbmdTbG90cyA6IGZpbGVzLmxlbmd0aDtcblxuICAgIGlmICh0aGlzLnVybCAmJiBmaWxlc1RvVXBsb2FkTnVtICE9IDApIHtcbiAgICAgIHRoaXMudXBsb2FkU3RhdGVDaGFuZ2VkLmVtaXQodHJ1ZSk7XG4gICAgfVxuXG4gICAgdGhpcy5maWxlQ291bnRlciArPSBmaWxlc1RvVXBsb2FkTnVtO1xuICAgIHRoaXMuc2hvd0ZpbGVUb29MYXJnZU1lc3NhZ2UgPSBmYWxzZTtcbiAgICB0aGlzLnVwbG9hZEZpbGVzKGZpbGVzLCBmaWxlc1RvVXBsb2FkTnVtKTtcbiAgfVxuXG4gIG9uRmlsZU92ZXIgPSAoaXNPdmVyKSA9PiB0aGlzLmZpbGVPdmVyID0gaXNPdmVyO1xuXG4gIHByaXZhdGUgY291bnRSZW1haW5pbmdTbG90cyA9ICgpID0+IHRoaXMubWF4IC0gdGhpcy5maWxlQ291bnRlcjtcblxuICBwcml2YXRlIG9uUmVzcG9uc2UocmVzcG9uc2U6IFJlc3BvbnNlLCBmaWxlSG9sZGVyOiBGaWxlSG9sZGVyKSB7XG4gICAgZmlsZUhvbGRlci5zZXJ2ZXJSZXNwb25zZSA9IHsgc3RhdHVzOiByZXNwb25zZS5zdGF0dXMsIHJlc3BvbnNlIH07XG4gICAgZmlsZUhvbGRlci5wZW5kaW5nID0gZmFsc2U7XG5cbiAgICB0aGlzLnVwbG9hZEZpbmlzaGVkLmVtaXQoZmlsZUhvbGRlcik7XG5cbiAgICBpZiAoLS10aGlzLnBlbmRpbmdGaWxlc0NvdW50ZXIgPT0gMCkge1xuICAgICAgdGhpcy51cGxvYWRTdGF0ZUNoYW5nZWQuZW1pdChmYWxzZSk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBwcm9jZXNzVXBsb2FkZWRGaWxlcygpIHtcbiAgICBpZiAodHlwZW9mIHRoaXMudXBsb2FkZWRGaWxlcyA9PT0gJ3N0cmluZycpIHtcbiAgICAgIGxldCBkYXRhOiBhbnkgPSB0aGlzLnVwbG9hZGVkRmlsZXM7XG5cbiAgICAgIHRoaXMuZmlsZUNvdW50ZXIgPSAxO1xuICAgICAgdGhpcy5tYXggPSAxO1xuXG4gICAgICBsZXQgZmlsZUJsb2I6IEJsb2IsXG4gICAgICAgIGZpbGU6IEZpbGUsXG4gICAgICAgIGZpbGVVcmw6IHN0cmluZztcblxuICAgICAgaWYgKGRhdGEgaW5zdGFuY2VvZiBPYmplY3QpIHtcbiAgICAgICAgZmlsZVVybCA9IGRhdGEudXJsO1xuICAgICAgICBmaWxlQmxvYiA9IChkYXRhLmJsb2IpID8gZGF0YS5ibG9iIDogbmV3IEJsb2IoW2RhdGFdKTtcbiAgICAgICAgZmlsZSA9IG5ldyBGaWxlKFtmaWxlQmxvYl0sIGRhdGEuZmlsZU5hbWUpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZmlsZVVybCA9IGRhdGE7XG4gICAgICAgIGZpbGVCbG9iID0gbmV3IEJsb2IoW2ZpbGVVcmxdKTtcbiAgICAgICAgZmlsZSA9IG5ldyBGaWxlKFtmaWxlQmxvYl0sIGZpbGVVcmwpO1xuICAgICAgfVxuXG4gICAgICB0aGlzLmZpbGVzID0gW107XG4gICAgICB0aGlzLmZpbGVzLnB1c2gobmV3IEZpbGVIb2xkZXIoZmlsZVVybCwgZmlsZSkpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLm1heCA9IHRoaXMubWF4IC0gT2JqZWN0LmtleXModGhpcy51cGxvYWRlZEZpbGVzKS5sZW5ndGg7XG4gICAgICBmb3IgKGNvbnN0IGkgaW4gdGhpcy51cGxvYWRlZEZpbGVzKSB7XG4gICAgICAgIGxldCBkYXRhOiBhbnkgPSB0aGlzLnVwbG9hZGVkRmlsZXNbaV07XG5cbiAgICAgICAgbGV0IGZpbGVCbG9iOiBCbG9iLFxuICAgICAgICAgIGZpbGU6IEZpbGUsXG4gICAgICAgICAgZmlsZVVybDogc3RyaW5nO1xuXG4gICAgICAgIGlmIChkYXRhIGluc3RhbmNlb2YgT2JqZWN0KSB7XG4gICAgICAgICAgZmlsZVVybCA9IGRhdGEudXJsO1xuICAgICAgICAgIGZpbGVCbG9iID0gKGRhdGEuYmxvYikgPyBkYXRhLmJsb2IgOiBuZXcgQmxvYihbZGF0YV0pO1xuICAgICAgICAgIGZpbGUgPSBuZXcgRmlsZShbZmlsZUJsb2JdLCBkYXRhLmZpbGVOYW1lKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBmaWxlVXJsID0gZGF0YTtcbiAgICAgICAgICBmaWxlQmxvYiA9IG5ldyBCbG9iKFtmaWxlVXJsXSk7XG4gICAgICAgICAgZmlsZSA9IG5ldyBGaWxlKFtmaWxlQmxvYl0sIGZpbGVVcmwpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5maWxlcy5wdXNoKG5ldyBGaWxlSG9sZGVyKGZpbGVVcmwsIGZpbGUpKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIHVwbG9hZEZpbGVzKGZpbGVzOiBGaWxlTGlzdCwgZmlsZXNUb1VwbG9hZE51bTogbnVtYmVyKSB7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBmaWxlc1RvVXBsb2FkTnVtOyBpKyspIHtcbiAgICAgIGNvbnN0IGZpbGUgPSBmaWxlc1tpXTtcblxuICAgICAgaWYgKHRoaXMubWF4RmlsZVNpemUgJiYgZmlsZS5zaXplID4gdGhpcy5tYXhGaWxlU2l6ZSkge1xuICAgICAgICB0aGlzLmZpbGVDb3VudGVyLS07XG4gICAgICAgIHRoaXMuaW5wdXRFbGVtZW50Lm5hdGl2ZUVsZW1lbnQudmFsdWUgPSAnJztcbiAgICAgICAgdGhpcy5zaG93RmlsZVRvb0xhcmdlTWVzc2FnZSA9IHRydWU7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBiZWZvcmVVcGxvYWRSZXN1bHQ6IFVwbG9hZE1ldGFkYXRhID0gYXdhaXQgdGhpcy5iZWZvcmVVcGxvYWQoeyBmaWxlLCB1cmw6IHRoaXMudXJsLCBhYm9ydDogZmFsc2UgfSk7XG5cbiAgICAgIGlmIChiZWZvcmVVcGxvYWRSZXN1bHQuYWJvcnQpIHtcbiAgICAgICAgdGhpcy5maWxlQ291bnRlci0tO1xuICAgICAgICB0aGlzLmlucHV0RWxlbWVudC5uYXRpdmVFbGVtZW50LnZhbHVlID0gJyc7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBpbWcgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdpbWcnKTtcbiAgICAgIGltZy5zcmMgPSB3aW5kb3cuVVJMLmNyZWF0ZU9iamVjdFVSTChiZWZvcmVVcGxvYWRSZXN1bHQuZmlsZSk7XG5cbiAgICAgIGNvbnN0IHJlYWRlciA9IG5ldyBGaWxlUmVhZGVyKCk7XG4gICAgICByZWFkZXIuYWRkRXZlbnRMaXN0ZW5lcignbG9hZCcsIChldmVudDogYW55KSA9PiB7XG4gICAgICAgIGNvbnN0IGZpbGVIb2xkZXI6IEZpbGVIb2xkZXIgPSBuZXcgRmlsZUhvbGRlcihldmVudC50YXJnZXQucmVzdWx0LCBiZWZvcmVVcGxvYWRSZXN1bHQuZmlsZSk7XG4gICAgICAgIHRoaXMudXBsb2FkU2luZ2xlRmlsZShmaWxlSG9sZGVyLCBiZWZvcmVVcGxvYWRSZXN1bHQudXJsLCBiZWZvcmVVcGxvYWRSZXN1bHQuZm9ybURhdGEpO1xuICAgICAgICB0aGlzLmZpbGVzLnB1c2goZmlsZUhvbGRlcik7XG4gICAgICB9LCBmYWxzZSk7XG4gICAgICByZWFkZXIucmVhZEFzRGF0YVVSTChiZWZvcmVVcGxvYWRSZXN1bHQuZmlsZSk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSB1cGxvYWRTaW5nbGVGaWxlKGZpbGVIb2xkZXI6IEZpbGVIb2xkZXIsIHVybCA9IHRoaXMudXJsLCBjdXN0b21Gb3JtPzogeyBbbmFtZTogc3RyaW5nXTogYW55IH0pIHtcbiAgICBpZiAodXJsKSB7XG4gICAgICB0aGlzLnBlbmRpbmdGaWxlc0NvdW50ZXIrKztcbiAgICAgIGZpbGVIb2xkZXIucGVuZGluZyA9IHRydWU7XG5cbiAgICAgIHRoaXMuaW1hZ2VTZXJ2aWNlXG4gICAgICAgIC5wb3N0SW1hZ2UodXJsLCBmaWxlSG9sZGVyLmZpbGUsIHRoaXMuaGVhZGVycywgdGhpcy5wYXJ0TmFtZSwgY3VzdG9tRm9ybSwgdGhpcy53aXRoQ3JlZGVudGlhbHMpXG4gICAgICAgIC5zdWJzY3JpYmUoXG4gICAgICAgICAgcmVzcG9uc2UgPT4gdGhpcy5vblJlc3BvbnNlKHJlc3BvbnNlLCBmaWxlSG9sZGVyKSxcbiAgICAgICAgICBlcnJvciA9PiB7XG4gICAgICAgICAgICB0aGlzLm9uUmVzcG9uc2UoZXJyb3IsIGZpbGVIb2xkZXIpO1xuICAgICAgICAgICAgdGhpcy5kZWxldGVGaWxlKGZpbGVIb2xkZXIpO1xuICAgICAgICAgIH0pO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnVwbG9hZEZpbmlzaGVkLmVtaXQoZmlsZUhvbGRlcik7XG4gICAgfVxuICB9XG5cbn1cbiJdfQ==