UNPKG

ng7-pica

Version:

Angular module to resize images files in browser

391 lines (390 loc) 38.6 kB
/** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc */ import { Injectable } from '@angular/core'; import { Subject } from 'rxjs'; import { NgxPicaErrorType } from './ngx-pica-error.interface'; import { NgxPicaExifService } from './ngx-pica-exif.service'; import Pica from 'pica'; var NgxPicaService = /** @class */ (function () { function NgxPicaService(_ngxPicaExifService) { this._ngxPicaExifService = _ngxPicaExifService; this.picaResizer = new Pica(); this.MAX_STEPS = 20; if (!this.picaResizer || !this.picaResizer.resize) { this.picaResizer = new window.Pica(); } } /** * @param {?} files * @param {?} width * @param {?} height * @param {?=} options * @return {?} */ NgxPicaService.prototype.resizeImages = /** * @param {?} files * @param {?} width * @param {?} height * @param {?=} options * @return {?} */ function (files, width, height, options) { var _this = this; /** @type {?} */ var resizedImage = new Subject(); /** @type {?} */ var totalFiles = files.length; if (totalFiles > 0) { /** @type {?} */ var nextFile_1 = new Subject(); /** @type {?} */ var index_1 = 0; /** @type {?} */ var subscription_1 = nextFile_1.subscribe(function (file) { _this.resizeImage(file, width, height, options).subscribe(function (imageResized) { index_1++; resizedImage.next(imageResized); if (index_1 < totalFiles) { nextFile_1.next(files[index_1]); } else { resizedImage.complete(); subscription_1.unsubscribe(); } }, function (err) { /** @type {?} */ var ngxPicaError = { file: file, err: err }; resizedImage.error(ngxPicaError); }); }); nextFile_1.next(files[index_1]); } else { /** @type {?} */ var ngxPicaError = { err: NgxPicaErrorType.NO_FILES_RECEIVED }; resizedImage.error(ngxPicaError); resizedImage.complete(); } return resizedImage.asObservable(); }; /** * @param {?} file * @param {?} width * @param {?} height * @param {?=} options * @return {?} */ NgxPicaService.prototype.resizeImage = /** * @param {?} file * @param {?} width * @param {?} height * @param {?=} options * @return {?} */ function (file, width, height, options) { var _this = this; /** @type {?} */ var resizedImage = new Subject(); /** @type {?} */ var originCanvas = document.createElement('canvas'); /** @type {?} */ var ctx = originCanvas.getContext('2d'); /** @type {?} */ var img = new Image(); if (ctx) { img.onload = function () { _this._ngxPicaExifService.getExifOrientedImage(img).then(function (orientedImage) { window.URL.revokeObjectURL(img.src); originCanvas.width = orientedImage.width; originCanvas.height = orientedImage.height; ctx.drawImage(orientedImage, 0, 0); /** @type {?} */ var imageData = ctx.getImageData(0, 0, orientedImage.width, orientedImage.height); if (options && options.aspectRatio && options.aspectRatio.keepAspectRatio) { /** @type {?} */ var ratio = 0; if (options.aspectRatio.forceMinDimensions) { ratio = Math.max(width / imageData.width, height / imageData.height); } else { ratio = Math.min(width / imageData.width, height / imageData.height); } width = Math.round(imageData.width * ratio); height = Math.round(imageData.height * ratio); } /** @type {?} */ var destinationCanvas = document.createElement('canvas'); destinationCanvas.width = width; destinationCanvas.height = height; _this.picaResize(file, originCanvas, destinationCanvas, options) .catch(function (err) { return resizedImage.error(err); }) .then(function (imgResized) { resizedImage.next(imgResized); }); }); }; img.src = window.URL.createObjectURL(file); } else { resizedImage.error(NgxPicaErrorType.CANVAS_CONTEXT_IDENTIFIER_NOT_SUPPORTED); } return resizedImage.asObservable(); }; /** * @param {?} files * @param {?} sizeInMB * @return {?} */ NgxPicaService.prototype.compressImages = /** * @param {?} files * @param {?} sizeInMB * @return {?} */ function (files, sizeInMB) { var _this = this; /** @type {?} */ var compressedImage = new Subject(); /** @type {?} */ var totalFiles = files.length; if (totalFiles > 0) { /** @type {?} */ var nextFile_2 = new Subject(); /** @type {?} */ var index_2 = 0; /** @type {?} */ var subscription_2 = nextFile_2.subscribe(function (file) { _this.compressImage(file, sizeInMB).subscribe(function (imageCompressed) { index_2++; compressedImage.next(imageCompressed); if (index_2 < totalFiles) { nextFile_2.next(files[index_2]); } else { compressedImage.complete(); subscription_2.unsubscribe(); } }, function (err) { /** @type {?} */ var ngxPicaError = { file: file, err: err }; compressedImage.error(ngxPicaError); }); }); nextFile_2.next(files[index_2]); } else { /** @type {?} */ var ngxPicaError = { err: NgxPicaErrorType.NO_FILES_RECEIVED }; compressedImage.error(ngxPicaError); compressedImage.complete(); } return compressedImage.asObservable(); }; /** * @param {?} file * @param {?} sizeInMB * @return {?} */ NgxPicaService.prototype.compressImage = /** * @param {?} file * @param {?} sizeInMB * @return {?} */ function (file, sizeInMB) { var _this = this; /** @type {?} */ var compressedImage = new Subject(); /** @type {?} */ var originCanvas = document.createElement('canvas'); /** @type {?} */ var ctx = originCanvas.getContext('2d'); /** @type {?} */ var img = new Image(); if (ctx) { img.onload = function () { _this._ngxPicaExifService.getExifOrientedImage(img).then(function (orientedImage) { window.URL.revokeObjectURL(img.src); originCanvas.width = orientedImage.width; originCanvas.height = orientedImage.height; ctx.drawImage(orientedImage, 0, 0); if (_this.bytesToMB(file.size) <= sizeInMB) { _this.picaResizer.toBlob(originCanvas, file.type, 1) .catch(function (err) { return compressedImage.error(err); }) .then(function (blob) { /** @type {?} */ var imgCompressed = _this.blobToFile(blob, file.name, file.type, new Date().getTime()); compressedImage.next(imgCompressed); }); } else { _this.getCompressedImage(originCanvas, file.type, 1, sizeInMB, 0) .catch(function (err) { return compressedImage.error(err); }) .then(function (blob) { /** @type {?} */ var imgCompressed = _this.blobToFile(blob, file.name, file.type, new Date().getTime()); compressedImage.next(imgCompressed); }); } }); }; img.src = window.URL.createObjectURL(file); } else { compressedImage.error(NgxPicaErrorType.CANVAS_CONTEXT_IDENTIFIER_NOT_SUPPORTED); } return compressedImage.asObservable(); }; /** * @param {?} canvas * @param {?} type * @param {?} quality * @param {?} sizeInMB * @param {?} step * @return {?} */ NgxPicaService.prototype.getCompressedImage = /** * @param {?} canvas * @param {?} type * @param {?} quality * @param {?} sizeInMB * @param {?} step * @return {?} */ function (canvas, type, quality, sizeInMB, step) { var _this = this; return new Promise(function (resolve, reject) { _this.picaResizer.toBlob(canvas, type, quality) .catch(function (err) { return reject(err); }) .then(function (blob) { _this.checkCompressedImageSize(canvas, blob, quality, sizeInMB, step) .catch(function (err) { return reject(err); }) .then(function (compressedBlob) { resolve(compressedBlob); }); }); }); }; /** * @param {?} canvas * @param {?} blob * @param {?} quality * @param {?} sizeInMB * @param {?} step * @return {?} */ NgxPicaService.prototype.checkCompressedImageSize = /** * @param {?} canvas * @param {?} blob * @param {?} quality * @param {?} sizeInMB * @param {?} step * @return {?} */ function (canvas, blob, quality, sizeInMB, step) { var _this = this; return new Promise(function (resolve, reject) { if (step > _this.MAX_STEPS) { reject(NgxPicaErrorType.NOT_BE_ABLE_TO_COMPRESS_ENOUGH); } else if (_this.bytesToMB(blob.size) < sizeInMB) { resolve(blob); } else { /** @type {?} */ var newQuality = quality - (quality * 0.1); /** @type {?} */ var newStep = step + 1; // recursively compression resolve(_this.getCompressedImage(canvas, blob.type, newQuality, sizeInMB, newStep)); } }); }; /** * @param {?} file * @param {?} from * @param {?} to * @param {?} options * @return {?} */ NgxPicaService.prototype.picaResize = /** * @param {?} file * @param {?} from * @param {?} to * @param {?} options * @return {?} */ function (file, from, to, options) { var _this = this; return new Promise(function (resolve, reject) { _this.picaResizer.resize(from, to, options) .catch(function (err) { return reject(err); }) .then(function (resizedCanvas) { return _this.picaResizer.toBlob(resizedCanvas, file.type); }) .then(function (blob) { /** @type {?} */ var fileResized = _this.blobToFile(blob, file.name, file.type, new Date().getTime()); resolve(fileResized); }); }); }; /** * @param {?} blob * @param {?} name * @param {?} type * @param {?} lastModified * @return {?} */ NgxPicaService.prototype.blobToFile = /** * @param {?} blob * @param {?} name * @param {?} type * @param {?} lastModified * @return {?} */ function (blob, name, type, lastModified) { /** @type {?} */ var file = /** @type {?} */ (new Blob([blob], { type: type })); file.name = name; file.lastModifiedDate = lastModified; return /** @type {?} */ (file); }; /** * @param {?} bytes * @return {?} */ NgxPicaService.prototype.bytesToMB = /** * @param {?} bytes * @return {?} */ function (bytes) { return bytes / 1048576; }; NgxPicaService.decorators = [ { type: Injectable } ]; /** @nocollapse */ NgxPicaService.ctorParameters = function () { return [ { type: NgxPicaExifService } ]; }; return NgxPicaService; }()); export { NgxPicaService }; if (false) { /** @type {?} */ NgxPicaService.prototype.picaResizer; /** @type {?} */ NgxPicaService.prototype.MAX_STEPS; /** @type {?} */ NgxPicaService.prototype._ngxPicaExifService; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmd4LXBpY2Euc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiJuZzovL25nNy1waWNhLyIsInNvdXJjZXMiOlsibGliL25neC1waWNhLnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7OztBQUFBLE9BQU8sRUFBQyxVQUFVLEVBQUMsTUFBTSxlQUFlLENBQUM7QUFDekMsT0FBTyxFQUFDLE9BQU8sRUFBMkIsTUFBTSxNQUFNLENBQUM7QUFDdkQsT0FBTyxFQUF3QixnQkFBZ0IsRUFBQyxNQUFNLDRCQUE0QixDQUFDO0FBRW5GLE9BQU8sRUFBQyxrQkFBa0IsRUFBQyxNQUFNLHlCQUF5QixDQUFDO0FBQzNELE9BQU8sSUFBSSxNQUFNLE1BQU0sQ0FBQzs7SUFVcEIsd0JBQW9CLG1CQUF1QztRQUF2Qyx3QkFBbUIsR0FBbkIsbUJBQW1CLENBQW9COzJCQUhyQyxJQUFJLElBQUksRUFBRTt5QkFDWixFQUFFO1FBR2xCLElBQUksQ0FBQyxJQUFJLENBQUMsV0FBVyxJQUFJLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxNQUFNLEVBQUU7WUFDL0MsSUFBSSxDQUFDLFdBQVcsR0FBRyxJQUFJLE1BQU0sQ0FBQyxJQUFJLEVBQUUsQ0FBQztTQUN4QztLQUNKOzs7Ozs7OztJQUVNLHFDQUFZOzs7Ozs7O2NBQUMsS0FBYSxFQUFFLEtBQWEsRUFBRSxNQUFjLEVBQUUsT0FBdUM7OztRQUNyRyxJQUFNLFlBQVksR0FBa0IsSUFBSSxPQUFPLEVBQUUsQ0FBQzs7UUFDbEQsSUFBTSxVQUFVLEdBQVcsS0FBSyxDQUFDLE1BQU0sQ0FBQztRQUV4QyxJQUFJLFVBQVUsR0FBRyxDQUFDLEVBQUU7O1lBQ2hCLElBQU0sVUFBUSxHQUFrQixJQUFJLE9BQU8sRUFBRSxDQUFDOztZQUM5QyxJQUFJLE9BQUssR0FBRyxDQUFDLENBQUM7O1lBRWQsSUFBTSxjQUFZLEdBQWlCLFVBQVEsQ0FBQyxTQUFTLENBQUMsVUFBQyxJQUFVO2dCQUM3RCxLQUFJLENBQUMsV0FBVyxDQUFDLElBQUksRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFLE9BQU8sQ0FBQyxDQUFDLFNBQVMsQ0FBQyxVQUFBLFlBQVk7b0JBQ2pFLE9BQUssRUFBRSxDQUFDO29CQUNSLFlBQVksQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLENBQUM7b0JBRWhDLElBQUksT0FBSyxHQUFHLFVBQVUsRUFBRTt3QkFDcEIsVUFBUSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsT0FBSyxDQUFDLENBQUMsQ0FBQztxQkFFL0I7eUJBQU07d0JBQ0gsWUFBWSxDQUFDLFFBQVEsRUFBRSxDQUFDO3dCQUN4QixjQUFZLENBQUMsV0FBVyxFQUFFLENBQUM7cUJBQzlCO2lCQUNKLEVBQUUsVUFBQyxHQUFHOztvQkFDSCxJQUFNLFlBQVksR0FBMEI7d0JBQ3hDLElBQUksRUFBRSxJQUFJO3dCQUNWLEdBQUcsRUFBRSxHQUFHO3FCQUNYLENBQUM7b0JBRUYsWUFBWSxDQUFDLEtBQUssQ0FBQyxZQUFZLENBQUMsQ0FBQztpQkFDcEMsQ0FBQyxDQUFDO2FBQ04sQ0FBQyxDQUFDO1lBRUgsVUFBUSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsT0FBSyxDQUFDLENBQUMsQ0FBQztTQUMvQjthQUFNOztZQUNILElBQU0sWUFBWSxHQUEwQjtnQkFDeEMsR0FBRyxFQUFFLGdCQUFnQixDQUFDLGlCQUFpQjthQUMxQyxDQUFDO1lBRUYsWUFBWSxDQUFDLEtBQUssQ0FBQyxZQUFZLENBQUMsQ0FBQztZQUNqQyxZQUFZLENBQUMsUUFBUSxFQUFFLENBQUM7U0FDM0I7UUFFRCxPQUFPLFlBQVksQ0FBQyxZQUFZLEVBQUUsQ0FBQzs7Ozs7Ozs7O0lBR2hDLG9DQUFXOzs7Ozs7O2NBQUMsSUFBVSxFQUFFLEtBQWEsRUFBRSxNQUFjLEVBQUUsT0FBdUM7OztRQUNqRyxJQUFNLFlBQVksR0FBa0IsSUFBSSxPQUFPLEVBQUUsQ0FBQzs7UUFDbEQsSUFBTSxZQUFZLEdBQXNCLFFBQVEsQ0FBQyxhQUFhLENBQUMsUUFBUSxDQUFDLENBQUM7O1FBQ3pFLElBQU0sR0FBRyxHQUFHLFlBQVksQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLENBQUM7O1FBQzFDLElBQU0sR0FBRyxHQUFHLElBQUksS0FBSyxFQUFFLENBQUM7UUFFeEIsSUFBSSxHQUFHLEVBQUU7WUFDTCxHQUFHLENBQUMsTUFBTSxHQUFHO2dCQUNULEtBQUksQ0FBQyxtQkFBbUIsQ0FBQyxvQkFBb0IsQ0FBQyxHQUFHLENBQUMsQ0FBQyxJQUFJLENBQUMsVUFBQSxhQUFhO29CQUNqRSxNQUFNLENBQUMsR0FBRyxDQUFDLGVBQWUsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUM7b0JBQ3BDLFlBQVksQ0FBQyxLQUFLLEdBQUcsYUFBYSxDQUFDLEtBQUssQ0FBQztvQkFDekMsWUFBWSxDQUFDLE1BQU0sR0FBRyxhQUFhLENBQUMsTUFBTSxDQUFDO29CQUUzQyxHQUFHLENBQUMsU0FBUyxDQUFDLGFBQWEsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7O29CQUVuQyxJQUFNLFNBQVMsR0FBRyxHQUFHLENBQUMsWUFBWSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsYUFBYSxDQUFDLEtBQUssRUFBRSxhQUFhLENBQUMsTUFBTSxDQUFDLENBQUM7b0JBQ3BGLElBQUksT0FBTyxJQUFJLE9BQU8sQ0FBQyxXQUFXLElBQUksT0FBTyxDQUFDLFdBQVcsQ0FBQyxlQUFlLEVBQUU7O3dCQUN2RSxJQUFJLEtBQUssR0FBRyxDQUFDLENBQUM7d0JBRWQsSUFBSSxPQUFPLENBQUMsV0FBVyxDQUFDLGtCQUFrQixFQUFFOzRCQUN4QyxLQUFLLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxLQUFLLEdBQUcsU0FBUyxDQUFDLEtBQUssRUFBRSxNQUFNLEdBQUcsU0FBUyxDQUFDLE1BQU0sQ0FBQyxDQUFDO3lCQUN4RTs2QkFBTTs0QkFDSCxLQUFLLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxLQUFLLEdBQUcsU0FBUyxDQUFDLEtBQUssRUFBRSxNQUFNLEdBQUcsU0FBUyxDQUFDLE1BQU0sQ0FBQyxDQUFDO3lCQUN4RTt3QkFFRCxLQUFLLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxTQUFTLENBQUMsS0FBSyxHQUFHLEtBQUssQ0FBQyxDQUFDO3dCQUM1QyxNQUFNLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxTQUFTLENBQUMsTUFBTSxHQUFHLEtBQUssQ0FBQyxDQUFDO3FCQUNqRDs7b0JBRUQsSUFBTSxpQkFBaUIsR0FBc0IsUUFBUSxDQUFDLGFBQWEsQ0FBQyxRQUFRLENBQUMsQ0FBQztvQkFDOUUsaUJBQWlCLENBQUMsS0FBSyxHQUFHLEtBQUssQ0FBQztvQkFDaEMsaUJBQWlCLENBQUMsTUFBTSxHQUFHLE1BQU0sQ0FBQztvQkFFbEMsS0FBSSxDQUFDLFVBQVUsQ0FBQyxJQUFJLEVBQUUsWUFBWSxFQUFFLGlCQUFpQixFQUFFLE9BQU8sQ0FBQzt5QkFDMUQsS0FBSyxDQUFDLFVBQUMsR0FBRyxJQUFLLE9BQUEsWUFBWSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsRUFBdkIsQ0FBdUIsQ0FBQzt5QkFDdkMsSUFBSSxDQUFDLFVBQUMsVUFBZ0I7d0JBQ25CLFlBQVksQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUM7cUJBQ2pDLENBQUMsQ0FBQztpQkFDVixDQUFDLENBQUM7YUFDTixDQUFDO1lBRUYsR0FBRyxDQUFDLEdBQUcsR0FBRyxNQUFNLENBQUMsR0FBRyxDQUFDLGVBQWUsQ0FBQyxJQUFJLENBQUMsQ0FBQztTQUM5QzthQUFNO1lBQ0gsWUFBWSxDQUFDLEtBQUssQ0FBQyxnQkFBZ0IsQ0FBQyx1Q0FBdUMsQ0FBQyxDQUFDO1NBQ2hGO1FBRUQsT0FBTyxZQUFZLENBQUMsWUFBWSxFQUFFLENBQUM7Ozs7Ozs7SUFHaEMsdUNBQWM7Ozs7O2NBQUMsS0FBYSxFQUFFLFFBQWdCOzs7UUFDakQsSUFBTSxlQUFlLEdBQWtCLElBQUksT0FBTyxFQUFFLENBQUM7O1FBQ3JELElBQU0sVUFBVSxHQUFXLEtBQUssQ0FBQyxNQUFNLENBQUM7UUFFeEMsSUFBSSxVQUFVLEdBQUcsQ0FBQyxFQUFFOztZQUNoQixJQUFNLFVBQVEsR0FBa0IsSUFBSSxPQUFPLEVBQUUsQ0FBQzs7WUFDOUMsSUFBSSxPQUFLLEdBQUcsQ0FBQyxDQUFDOztZQUVkLElBQU0sY0FBWSxHQUFpQixVQUFRLENBQUMsU0FBUyxDQUFDLFVBQUMsSUFBVTtnQkFDN0QsS0FBSSxDQUFDLGFBQWEsQ0FBQyxJQUFJLEVBQUUsUUFBUSxDQUFDLENBQUMsU0FBUyxDQUFDLFVBQUEsZUFBZTtvQkFDeEQsT0FBSyxFQUFFLENBQUM7b0JBQ1IsZUFBZSxDQUFDLElBQUksQ0FBQyxlQUFlLENBQUMsQ0FBQztvQkFFdEMsSUFBSSxPQUFLLEdBQUcsVUFBVSxFQUFFO3dCQUNwQixVQUFRLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxPQUFLLENBQUMsQ0FBQyxDQUFDO3FCQUUvQjt5QkFBTTt3QkFDSCxlQUFlLENBQUMsUUFBUSxFQUFFLENBQUM7d0JBQzNCLGNBQVksQ0FBQyxXQUFXLEVBQUUsQ0FBQztxQkFDOUI7aUJBQ0osRUFBRSxVQUFDLEdBQUc7O29CQUNILElBQU0sWUFBWSxHQUEwQjt3QkFDeEMsSUFBSSxFQUFFLElBQUk7d0JBQ1YsR0FBRyxFQUFFLEdBQUc7cUJBQ1gsQ0FBQztvQkFFRixlQUFlLENBQUMsS0FBSyxDQUFDLFlBQVksQ0FBQyxDQUFDO2lCQUN2QyxDQUFDLENBQUM7YUFDTixDQUFDLENBQUM7WUFFSCxVQUFRLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxPQUFLLENBQUMsQ0FBQyxDQUFDO1NBQy9CO2FBQU07O1lBQ0gsSUFBTSxZQUFZLEdBQTBCO2dCQUN4QyxHQUFHLEVBQUUsZ0JBQWdCLENBQUMsaUJBQWlCO2FBQzFDLENBQUM7WUFFRixlQUFlLENBQUMsS0FBSyxDQUFDLFlBQVksQ0FBQyxDQUFDO1lBQ3BDLGVBQWUsQ0FBQyxRQUFRLEVBQUUsQ0FBQztTQUM5QjtRQUVELE9BQU8sZUFBZSxDQUFDLFlBQVksRUFBRSxDQUFDOzs7Ozs7O0lBR25DLHNDQUFhOzs7OztjQUFDLElBQVUsRUFBRSxRQUFnQjs7O1FBQzdDLElBQU0sZUFBZSxHQUFrQixJQUFJLE9BQU8sRUFBRSxDQUFDOztRQUVyRCxJQUFNLFlBQVksR0FBc0IsUUFBUSxDQUFDLGFBQWEsQ0FBQyxRQUFRLENBQUMsQ0FBQzs7UUFDekUsSUFBTSxHQUFHLEdBQUcsWUFBWSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsQ0FBQzs7UUFDMUMsSUFBTSxHQUFHLEdBQUcsSUFBSSxLQUFLLEVBQUUsQ0FBQztRQUV4QixJQUFJLEdBQUcsRUFBRTtZQUNMLEdBQUcsQ0FBQyxNQUFNLEdBQUc7Z0JBQ1QsS0FBSSxDQUFDLG1CQUFtQixDQUFDLG9CQUFvQixDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksQ0FBQyxVQUFBLGFBQWE7b0JBQ2pFLE1BQU0sQ0FBQyxHQUFHLENBQUMsZUFBZSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQztvQkFDcEMsWUFBWSxDQUFDLEtBQUssR0FBRyxhQUFhLENBQUMsS0FBSyxDQUFDO29CQUN6QyxZQUFZLENBQUMsTUFBTSxHQUFHLGFBQWEsQ0FBQyxNQUFNLENBQUM7b0JBRTNDLEdBQUcsQ0FBQyxTQUFTLENBQUMsYUFBYSxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztvQkFFbkMsSUFBSSxLQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxRQUFRLEVBQUU7d0JBQ3ZDLEtBQUksQ0FBQyxXQUFXLENBQUMsTUFBTSxDQUFDLFlBQVksRUFBRSxJQUFJLENBQUMsSUFBSSxFQUFFLENBQUMsQ0FBQzs2QkFDOUMsS0FBSyxDQUFDLFVBQUMsR0FBRyxJQUFLLE9BQUEsZUFBZSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsRUFBMUIsQ0FBMEIsQ0FBQzs2QkFDMUMsSUFBSSxDQUFDLFVBQUMsSUFBVTs7NEJBQ2IsSUFBTSxhQUFhLEdBQVMsS0FBSSxDQUFDLFVBQVUsQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLElBQUksRUFBRSxJQUFJLENBQUMsSUFBSSxFQUFFLElBQUksSUFBSSxFQUFFLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQzs0QkFDOUYsZUFBZSxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsQ0FBQzt5QkFDdkMsQ0FBQyxDQUFDO3FCQUNWO3lCQUFNO3dCQUNILEtBQUksQ0FBQyxrQkFBa0IsQ0FBQyxZQUFZLEVBQUUsSUFBSSxDQUFDLElBQUksRUFBRSxDQUFDLEVBQUUsUUFBUSxFQUFFLENBQUMsQ0FBQzs2QkFDM0QsS0FBSyxDQUFDLFVBQUMsR0FBRyxJQUFLLE9BQUEsZUFBZSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsRUFBMUIsQ0FBMEIsQ0FBQzs2QkFDMUMsSUFBSSxDQUFDLFVBQUMsSUFBVTs7NEJBQ2IsSUFBTSxhQUFhLEdBQVMsS0FBSSxDQUFDLFVBQVUsQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLElBQUksRUFBRSxJQUFJLENBQUMsSUFBSSxFQUFFLElBQUksSUFBSSxFQUFFLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQzs0QkFFOUYsZUFBZSxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsQ0FBQzt5QkFDdkMsQ0FBQyxDQUFDO3FCQUNWO2lCQUNKLENBQUMsQ0FBQzthQUNOLENBQUM7WUFFRixHQUFHLENBQUMsR0FBRyxHQUFHLE1BQU0sQ0FBQyxHQUFHLENBQUMsZUFBZSxDQUFDLElBQUksQ0FBQyxDQUFDO1NBQzlDO2FBQU07WUFDSCxlQUFlLENBQUMsS0FBSyxDQUFDLGdCQUFnQixDQUFDLHVDQUF1QyxDQUFDLENBQUM7U0FDbkY7UUFFRCxPQUFPLGVBQWUsQ0FBQyxZQUFZLEVBQUUsQ0FBQzs7Ozs7Ozs7OztJQUdsQywyQ0FBa0I7Ozs7Ozs7O2NBQUMsTUFBeUIsRUFBRSxJQUFZLEVBQUUsT0FBZSxFQUFFLFFBQWdCLEVBQUUsSUFBWTs7UUFDL0csT0FBTyxJQUFJLE9BQU8sQ0FBTyxVQUFDLE9BQU8sRUFBRSxNQUFNO1lBQ3JDLEtBQUksQ0FBQyxXQUFXLENBQUMsTUFBTSxDQUFDLE1BQU0sRUFBRSxJQUFJLEVBQUUsT0FBTyxDQUFDO2lCQUN6QyxLQUFLLENBQUMsVUFBQyxHQUFHLElBQUssT0FBQSxNQUFNLENBQUMsR0FBRyxDQUFDLEVBQVgsQ0FBVyxDQUFDO2lCQUMzQixJQUFJLENBQUMsVUFBQyxJQUFVO2dCQUNiLEtBQUksQ0FBQyx3QkFBd0IsQ0FBQyxNQUFNLEVBQUUsSUFBSSxFQUFFLE9BQU8sRUFBRSxRQUFRLEVBQUUsSUFBSSxDQUFDO3FCQUMvRCxLQUFLLENBQUMsVUFBQyxHQUFHLElBQUssT0FBQSxNQUFNLENBQUMsR0FBRyxDQUFDLEVBQVgsQ0FBVyxDQUFDO3FCQUMzQixJQUFJLENBQUMsVUFBQyxjQUFvQjtvQkFDbkIsT0FBTyxDQUFDLGNBQWMsQ0FBQyxDQUFDO2lCQUMzQixDQUNKLENBQUM7YUFDVCxDQUFDLENBQUM7U0FDVixDQUFDLENBQUM7Ozs7Ozs7Ozs7SUFHQyxpREFBd0I7Ozs7Ozs7O2NBQzVCLE1BQXlCLEVBQ3pCLElBQVUsRUFDVixPQUFlLEVBQ2YsUUFBZ0IsRUFDaEIsSUFBWTs7UUFFWixPQUFPLElBQUksT0FBTyxDQUFPLFVBQUMsT0FBTyxFQUM3QixNQUFNO1lBRU4sSUFBSSxJQUFJLEdBQUcsS0FBSSxDQUFDLFNBQVMsRUFBRTtnQkFDdkIsTUFBTSxDQUFDLGdCQUFnQixDQUFDLDhCQUE4QixDQUFDLENBQUM7YUFDM0Q7aUJBQU0sSUFBSSxLQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxRQUFRLEVBQUU7Z0JBQzdDLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQzthQUNqQjtpQkFBTTs7Z0JBQ0gsSUFBTSxVQUFVLEdBQVcsT0FBTyxHQUFHLENBQUMsT0FBTyxHQUFHLEdBQUcsQ0FBQyxDQUFDOztnQkFDckQsSUFBTSxPQUFPLEdBQVcsSUFBSSxHQUFHLENBQUMsQ0FBQzs7Z0JBR2pDLE9BQU8sQ0FBQyxLQUFJLENBQUMsa0JBQWtCLENBQUMsTUFBTSxFQUFFLElBQUksQ0FBQyxJQUFJLEVBQUUsVUFBVSxFQUFFLFFBQVEsRUFBRSxPQUFPLENBQUMsQ0FBQyxDQUFDO2FBQ3RGO1NBQ0osQ0FBQyxDQUFDOzs7Ozs7Ozs7SUFHQyxtQ0FBVTs7Ozs7OztjQUFDLElBQVUsRUFBRSxJQUF1QixFQUFFLEVBQXFCLEVBQUUsT0FBWTs7UUFDdkYsT0FBTyxJQUFJLE9BQU8sQ0FBTyxVQUFDLE9BQU8sRUFBRSxNQUFNO1lBQ3JDLEtBQUksQ0FBQyxXQUFXLENBQUMsTUFBTSxDQUFDLElBQUksRUFBRSxFQUFFLEVBQUUsT0FBTyxDQUFDO2lCQUNyQyxLQUFLLENBQUMsVUFBQyxHQUFHLElBQUssT0FBQSxNQUFNLENBQUMsR0FBRyxDQUFDLEVBQVgsQ0FBVyxDQUFDO2lCQUMzQixJQUFJLENBQUMsVUFBQyxhQUFnQyxJQUFLLE9BQUEsS0FBSSxDQUFDLFdBQVcsQ0FBQyxNQUFNLENBQUMsYUFBYSxFQUFFLElBQUksQ0FBQyxJQUFJLENBQUMsRUFBakQsQ0FBaUQsQ0FBQztpQkFDN0YsSUFBSSxDQUFDLFVBQUMsSUFBVTs7Z0JBQ2IsSUFBTSxXQUFXLEdBQVMsS0FBSSxDQUFDLFVBQVUsQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLElBQUksRUFBRSxJQUFJLENBQUMsSUFBSSxFQUFFLElBQUksSUFBSSxFQUFFLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQztnQkFDNUYsT0FBTyxDQUFDLFdBQVcsQ0FBQyxDQUFDO2FBQ3hCLENBQUMsQ0FBQztTQUNWLENBQUMsQ0FBQzs7Ozs7Ozs7O0lBR0MsbUNBQVU7Ozs7Ozs7Y0FBQyxJQUFVLEVBQUUsSUFBWSxFQUFFLElBQVksRUFBRSxZQUFvQjs7UUFFM0UsSUFBSSxJQUFJLHFCQUFHLElBQUksSUFBSSxDQUFDLENBQUMsSUFBSSxDQUFDLEVBQUUsRUFBQyxJQUFJLEVBQUcsSUFBSSxFQUFDLENBQVEsRUFBQztRQUNsRCxJQUFJLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQztRQUNqQixJQUFJLENBQUMsZ0JBQWdCLEdBQUcsWUFBWSxDQUFDO1FBQ3JDLHlCQUFPLElBQVksRUFBQTs7Ozs7O0lBR2Ysa0NBQVM7Ozs7Y0FBQyxLQUFhO1FBQzNCLE9BQU8sS0FBSyxHQUFHLE9BQU8sQ0FBQzs7O2dCQXpQOUIsVUFBVTs7OztnQkFOSCxrQkFBa0I7O3lCQUoxQjs7U0FXYSxjQUFjIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtJbmplY3RhYmxlfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7U3ViamVjdCwgT2JzZXJ2YWJsZSwgU3Vic2NyaXB0aW9ufSBmcm9tICdyeGpzJztcbmltcG9ydCB7Tmd4UGljYUVycm9ySW50ZXJmYWNlLCBOZ3hQaWNhRXJyb3JUeXBlfSBmcm9tICcuL25neC1waWNhLWVycm9yLmludGVyZmFjZSc7XG5pbXBvcnQge05neFBpY2FSZXNpemVPcHRpb25zSW50ZXJmYWNlfSBmcm9tICcuL25neC1waWNhLXJlc2l6ZS1vcHRpb25zLmludGVyZmFjZSc7XG5pbXBvcnQge05neFBpY2FFeGlmU2VydmljZX0gZnJvbSAnLi9uZ3gtcGljYS1leGlmLnNlcnZpY2UnO1xuaW1wb3J0IFBpY2EgZnJvbSAncGljYSc7XG5cblxuZGVjbGFyZSBsZXQgd2luZG93OiBhbnk7XG5cbkBJbmplY3RhYmxlKClcbmV4cG9ydCBjbGFzcyBOZ3hQaWNhU2VydmljZSB7XG4gICAgcHJpdmF0ZSBwaWNhUmVzaXplciA9IG5ldyBQaWNhKCk7XG4gICAgcHJpdmF0ZSBNQVhfU1RFUFMgPSAyMDtcblxuICAgIGNvbnN0cnVjdG9yKHByaXZhdGUgX25neFBpY2FFeGlmU2VydmljZTogTmd4UGljYUV4aWZTZXJ2aWNlKSB7XG4gICAgICAgIGlmICghdGhpcy5waWNhUmVzaXplciB8fCAhdGhpcy5waWNhUmVzaXplci5yZXNpemUpIHtcbiAgICAgICAgICAgIHRoaXMucGljYVJlc2l6ZXIgPSBuZXcgd2luZG93LlBpY2EoKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHB1YmxpYyByZXNpemVJbWFnZXMoZmlsZXM6IEZpbGVbXSwgd2lkdGg6IG51bWJlciwgaGVpZ2h0OiBudW1iZXIsIG9wdGlvbnM/OiBOZ3hQaWNhUmVzaXplT3B0aW9uc0ludGVyZmFjZSk6IE9ic2VydmFibGU8RmlsZT4ge1xuICAgICAgICBjb25zdCByZXNpemVkSW1hZ2U6IFN1YmplY3Q8RmlsZT4gPSBuZXcgU3ViamVjdCgpO1xuICAgICAgICBjb25zdCB0b3RhbEZpbGVzOiBudW1iZXIgPSBmaWxlcy5sZW5ndGg7XG5cbiAgICAgICAgaWYgKHRvdGFsRmlsZXMgPiAwKSB7XG4gICAgICAgICAgICBjb25zdCBuZXh0RmlsZTogU3ViamVjdDxGaWxlPiA9IG5ldyBTdWJqZWN0KCk7XG4gICAgICAgICAgICBsZXQgaW5kZXggPSAwO1xuXG4gICAgICAgICAgICBjb25zdCBzdWJzY3JpcHRpb246IFN1YnNjcmlwdGlvbiA9IG5leHRGaWxlLnN1YnNjcmliZSgoZmlsZTogRmlsZSkgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMucmVzaXplSW1hZ2UoZmlsZSwgd2lkdGgsIGhlaWdodCwgb3B0aW9ucykuc3Vic2NyaWJlKGltYWdlUmVzaXplZCA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGluZGV4Kys7XG4gICAgICAgICAgICAgICAgICAgIHJlc2l6ZWRJbWFnZS5uZXh0KGltYWdlUmVzaXplZCk7XG5cbiAgICAgICAgICAgICAgICAgICAgaWYgKGluZGV4IDwgdG90YWxGaWxlcykge1xuICAgICAgICAgICAgICAgICAgICAgICAgbmV4dEZpbGUubmV4dChmaWxlc1tpbmRleF0pO1xuXG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXNpemVkSW1hZ2UuY29tcGxldGUoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHN1YnNjcmlwdGlvbi51bnN1YnNjcmliZSgpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSwgKGVycikgPT4ge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBuZ3hQaWNhRXJyb3I6IE5neFBpY2FFcnJvckludGVyZmFjZSA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGZpbGU6IGZpbGUsXG4gICAgICAgICAgICAgICAgICAgICAgICBlcnI6IGVyclxuICAgICAgICAgICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICAgICAgICAgIHJlc2l6ZWRJbWFnZS5lcnJvcihuZ3hQaWNhRXJyb3IpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIG5leHRGaWxlLm5leHQoZmlsZXNbaW5kZXhdKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGNvbnN0IG5neFBpY2FFcnJvcjogTmd4UGljYUVycm9ySW50ZXJmYWNlID0ge1xuICAgICAgICAgICAgICAgIGVycjogTmd4UGljYUVycm9yVHlwZS5OT19GSUxFU19SRUNFSVZFRFxuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgcmVzaXplZEltYWdlLmVycm9yKG5neFBpY2FFcnJvcik7XG4gICAgICAgICAgICByZXNpemVkSW1hZ2UuY29tcGxldGUoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiByZXNpemVkSW1hZ2UuYXNPYnNlcnZhYmxlKCk7XG4gICAgfVxuXG4gICAgcHVibGljIHJlc2l6ZUltYWdlKGZpbGU6IEZpbGUsIHdpZHRoOiBudW1iZXIsIGhlaWdodDogbnVtYmVyLCBvcHRpb25zPzogTmd4UGljYVJlc2l6ZU9wdGlvbnNJbnRlcmZhY2UpOiBPYnNlcnZhYmxlPEZpbGU+IHtcbiAgICAgICAgY29uc3QgcmVzaXplZEltYWdlOiBTdWJqZWN0PEZpbGU+ID0gbmV3IFN1YmplY3QoKTtcbiAgICAgICAgY29uc3Qgb3JpZ2luQ2FudmFzOiBIVE1MQ2FudmFzRWxlbWVudCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2NhbnZhcycpO1xuICAgICAgICBjb25zdCBjdHggPSBvcmlnaW5DYW52YXMuZ2V0Q29udGV4dCgnMmQnKTtcbiAgICAgICAgY29uc3QgaW1nID0gbmV3IEltYWdlKCk7XG5cbiAgICAgICAgaWYgKGN0eCkge1xuICAgICAgICAgICAgaW1nLm9ubG9hZCA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLl9uZ3hQaWNhRXhpZlNlcnZpY2UuZ2V0RXhpZk9yaWVudGVkSW1hZ2UoaW1nKS50aGVuKG9yaWVudGVkSW1hZ2UgPT4ge1xuICAgICAgICAgICAgICAgICAgICB3aW5kb3cuVVJMLnJldm9rZU9iamVjdFVSTChpbWcuc3JjKTtcbiAgICAgICAgICAgICAgICAgICAgb3JpZ2luQ2FudmFzLndpZHRoID0gb3JpZW50ZWRJbWFnZS53aWR0aDtcbiAgICAgICAgICAgICAgICAgICAgb3JpZ2luQ2FudmFzLmhlaWdodCA9IG9yaWVudGVkSW1hZ2UuaGVpZ2h0O1xuXG4gICAgICAgICAgICAgICAgICAgIGN0eC5kcmF3SW1hZ2Uob3JpZW50ZWRJbWFnZSwgMCwgMCk7XG5cbiAgICAgICAgICAgICAgICAgICAgY29uc3QgaW1hZ2VEYXRhID0gY3R4LmdldEltYWdlRGF0YSgwLCAwLCBvcmllbnRlZEltYWdlLndpZHRoLCBvcmllbnRlZEltYWdlLmhlaWdodCk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChvcHRpb25zICYmIG9wdGlvbnMuYXNwZWN0UmF0aW8gJiYgb3B0aW9ucy5hc3BlY3RSYXRpby5rZWVwQXNwZWN0UmF0aW8pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGxldCByYXRpbyA9IDA7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChvcHRpb25zLmFzcGVjdFJhdGlvLmZvcmNlTWluRGltZW5zaW9ucykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJhdGlvID0gTWF0aC5tYXgod2lkdGggLyBpbWFnZURhdGEud2lkdGgsIGhlaWdodCAvIGltYWdlRGF0YS5oZWlnaHQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByYXRpbyA9IE1hdGgubWluKHdpZHRoIC8gaW1hZ2VEYXRhLndpZHRoLCBoZWlnaHQgLyBpbWFnZURhdGEuaGVpZ2h0KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgd2lkdGggPSBNYXRoLnJvdW5kKGltYWdlRGF0YS53aWR0aCAqIHJhdGlvKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGhlaWdodCA9IE1hdGgucm91bmQoaW1hZ2VEYXRhLmhlaWdodCAqIHJhdGlvKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGRlc3RpbmF0aW9uQ2FudmFzOiBIVE1MQ2FudmFzRWxlbWVudCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2NhbnZhcycpO1xuICAgICAgICAgICAgICAgICAgICBkZXN0aW5hdGlvbkNhbnZhcy53aWR0aCA9IHdpZHRoO1xuICAgICAgICAgICAgICAgICAgICBkZXN0aW5hdGlvbkNhbnZhcy5oZWlnaHQgPSBoZWlnaHQ7XG5cbiAgICAgICAgICAgICAgICAgICAgdGhpcy5waWNhUmVzaXplKGZpbGUsIG9yaWdpbkNhbnZhcywgZGVzdGluYXRpb25DYW52YXMsIG9wdGlvbnMpXG4gICAgICAgICAgICAgICAgICAgICAgICAuY2F0Y2goKGVycikgPT4gcmVzaXplZEltYWdlLmVycm9yKGVycikpXG4gICAgICAgICAgICAgICAgICAgICAgICAudGhlbigoaW1nUmVzaXplZDogRmlsZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc2l6ZWRJbWFnZS5uZXh0KGltZ1Jlc2l6ZWQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICBpbWcuc3JjID0gd2luZG93LlVSTC5jcmVhdGVPYmplY3RVUkwoZmlsZSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXNpemVkSW1hZ2UuZXJyb3IoTmd4UGljYUVycm9yVHlwZS5DQU5WQVNfQ09OVEVYVF9JREVOVElGSUVSX05PVF9TVVBQT1JURUQpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHJlc2l6ZWRJbWFnZS5hc09ic2VydmFibGUoKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgY29tcHJlc3NJbWFnZXMoZmlsZXM6IEZpbGVbXSwgc2l6ZUluTUI6IG51bWJlcik6IE9ic2VydmFibGU8RmlsZT4ge1xuICAgICAgICBjb25zdCBjb21wcmVzc2VkSW1hZ2U6IFN1YmplY3Q8RmlsZT4gPSBuZXcgU3ViamVjdCgpO1xuICAgICAgICBjb25zdCB0b3RhbEZpbGVzOiBudW1iZXIgPSBmaWxlcy5sZW5ndGg7XG5cbiAgICAgICAgaWYgKHRvdGFsRmlsZXMgPiAwKSB7XG4gICAgICAgICAgICBjb25zdCBuZXh0RmlsZTogU3ViamVjdDxGaWxlPiA9IG5ldyBTdWJqZWN0KCk7XG4gICAgICAgICAgICBsZXQgaW5kZXggPSAwO1xuXG4gICAgICAgICAgICBjb25zdCBzdWJzY3JpcHRpb246IFN1YnNjcmlwdGlvbiA9IG5leHRGaWxlLnN1YnNjcmliZSgoZmlsZTogRmlsZSkgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMuY29tcHJlc3NJbWFnZShmaWxlLCBzaXplSW5NQikuc3Vic2NyaWJlKGltYWdlQ29tcHJlc3NlZCA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGluZGV4Kys7XG4gICAgICAgICAgICAgICAgICAgIGNvbXByZXNzZWRJbWFnZS5uZXh0KGltYWdlQ29tcHJlc3NlZCk7XG5cbiAgICAgICAgICAgICAgICAgICAgaWYgKGluZGV4IDwgdG90YWxGaWxlcykge1xuICAgICAgICAgICAgICAgICAgICAgICAgbmV4dEZpbGUubmV4dChmaWxlc1tpbmRleF0pO1xuXG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb21wcmVzc2VkSW1hZ2UuY29tcGxldGUoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHN1YnNjcmlwdGlvbi51bnN1YnNjcmliZSgpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSwgKGVycikgPT4ge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBuZ3hQaWNhRXJyb3I6IE5neFBpY2FFcnJvckludGVyZmFjZSA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGZpbGU6IGZpbGUsXG4gICAgICAgICAgICAgICAgICAgICAgICBlcnI6IGVyclxuICAgICAgICAgICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICAgICAgICAgIGNvbXByZXNzZWRJbWFnZS5lcnJvcihuZ3hQaWNhRXJyb3IpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIG5leHRGaWxlLm5leHQoZmlsZXNbaW5kZXhdKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGNvbnN0IG5neFBpY2FFcnJvcjogTmd4UGljYUVycm9ySW50ZXJmYWNlID0ge1xuICAgICAgICAgICAgICAgIGVycjogTmd4UGljYUVycm9yVHlwZS5OT19GSUxFU19SRUNFSVZFRFxuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgY29tcHJlc3NlZEltYWdlLmVycm9yKG5neFBpY2FFcnJvcik7XG4gICAgICAgICAgICBjb21wcmVzc2VkSW1hZ2UuY29tcGxldGUoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBjb21wcmVzc2VkSW1hZ2UuYXNPYnNlcnZhYmxlKCk7XG4gICAgfVxuXG4gICAgcHVibGljIGNvbXByZXNzSW1hZ2UoZmlsZTogRmlsZSwgc2l6ZUluTUI6IG51bWJlcik6IE9ic2VydmFibGU8RmlsZT4ge1xuICAgICAgICBjb25zdCBjb21wcmVzc2VkSW1hZ2U6IFN1YmplY3Q8RmlsZT4gPSBuZXcgU3ViamVjdCgpO1xuXG4gICAgICAgIGNvbnN0IG9yaWdpbkNhbnZhczogSFRNTENhbnZhc0VsZW1lbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdjYW52YXMnKTtcbiAgICAgICAgY29uc3QgY3R4ID0gb3JpZ2luQ2FudmFzLmdldENvbnRleHQoJzJkJyk7XG4gICAgICAgIGNvbnN0IGltZyA9IG5ldyBJbWFnZSgpO1xuXG4gICAgICAgIGlmIChjdHgpIHtcbiAgICAgICAgICAgIGltZy5vbmxvYWQgPSAoKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5fbmd4UGljYUV4aWZTZXJ2aWNlLmdldEV4aWZPcmllbnRlZEltYWdlKGltZykudGhlbihvcmllbnRlZEltYWdlID0+IHtcbiAgICAgICAgICAgICAgICAgICAgd2luZG93LlVSTC5yZXZva2VPYmplY3RVUkwoaW1nLnNyYyk7XG4gICAgICAgICAgICAgICAgICAgIG9yaWdpbkNhbnZhcy53aWR0aCA9IG9yaWVudGVkSW1hZ2Uud2lkdGg7XG4gICAgICAgICAgICAgICAgICAgIG9yaWdpbkNhbnZhcy5oZWlnaHQgPSBvcmllbnRlZEltYWdlLmhlaWdodDtcblxuICAgICAgICAgICAgICAgICAgICBjdHguZHJhd0ltYWdlKG9yaWVudGVkSW1hZ2UsIDAsIDApO1xuXG4gICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLmJ5dGVzVG9NQihmaWxlLnNpemUpIDw9IHNpemVJbk1CKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnBpY2FSZXNpemVyLnRvQmxvYihvcmlnaW5DYW52YXMsIGZpbGUudHlwZSwgMSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAuY2F0Y2goKGVycikgPT4gY29tcHJlc3NlZEltYWdlLmVycm9yKGVycikpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLnRoZW4oKGJsb2I6IEJsb2IpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgaW1nQ29tcHJlc3NlZDogRmlsZSA9IHRoaXMuYmxvYlRvRmlsZShibG9iLCBmaWxlLm5hbWUsIGZpbGUudHlwZSwgbmV3IERhdGUoKS5nZXRUaW1lKCkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb21wcmVzc2VkSW1hZ2UubmV4dChpbWdDb21wcmVzc2VkKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZ2V0Q29tcHJlc3NlZEltYWdlKG9yaWdpbkNhbnZhcywgZmlsZS50eXBlLCAxLCBzaXplSW5NQiwgMClcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAuY2F0Y2goKGVycikgPT4gY29tcHJlc3NlZEltYWdlLmVycm9yKGVycikpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLnRoZW4oKGJsb2I6IEJsb2IpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgaW1nQ29tcHJlc3NlZDogRmlsZSA9IHRoaXMuYmxvYlRvRmlsZShibG9iLCBmaWxlLm5hbWUsIGZpbGUudHlwZSwgbmV3IERhdGUoKS5nZXRUaW1lKCkpO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbXByZXNzZWRJbWFnZS5uZXh0KGltZ0NvbXByZXNzZWQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICBpbWcuc3JjID0gd2luZG93LlVSTC5jcmVhdGVPYmplY3RVUkwoZmlsZSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb21wcmVzc2VkSW1hZ2UuZXJyb3IoTmd4UGljYUVycm9yVHlwZS5DQU5WQVNfQ09OVEVYVF9JREVOVElGSUVSX05PVF9TVVBQT1JURUQpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGNvbXByZXNzZWRJbWFnZS5hc09ic2VydmFibGUoKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGdldENvbXByZXNzZWRJbWFnZShjYW52YXM6IEhUTUxDYW52YXNFbGVtZW50LCB0eXBlOiBzdHJpbmcsIHF1YWxpdHk6IG51bWJlciwgc2l6ZUluTUI6IG51bWJlciwgc3RlcDogbnVtYmVyKTogUHJvbWlzZTxCbG9iPiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZTxCbG9iPigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICB0aGlzLnBpY2FSZXNpemVyLnRvQmxvYihjYW52YXMsIHR5cGUsIHF1YWxpdHkpXG4gICAgICAgICAgICAgICAgLmNhdGNoKChlcnIpID0+IHJlamVjdChlcnIpKVxuICAgICAgICAgICAgICAgIC50aGVuKChibG9iOiBCbG9iKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuY2hlY2tDb21wcmVzc2VkSW1hZ2VTaXplKGNhbnZhcywgYmxvYiwgcXVhbGl0eSwgc2l6ZUluTUIsIHN0ZXApXG4gICAgICAgICAgICAgICAgICAgICAgICAuY2F0Y2goKGVycikgPT4gcmVqZWN0KGVycikpXG4gICAgICAgICAgICAgICAgICAgICAgICAudGhlbigoY29tcHJlc3NlZEJsb2I6IEJsb2IpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZShjb21wcmVzc2VkQmxvYik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBjaGVja0NvbXByZXNzZWRJbWFnZVNpemUoXG4gICAgICAgIGNhbnZhczogSFRNTENhbnZhc0VsZW1lbnQsXG4gICAgICAgIGJsb2I6IEJsb2IsXG4gICAgICAgIHF1YWxpdHk6IG51bWJlcixcbiAgICAgICAgc2l6ZUluTUI6IG51bWJlcixcbiAgICAgICAgc3RlcDogbnVtYmVyXG4gICAgKTogUHJvbWlzZTxCbG9iPiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZTxCbG9iPigocmVzb2x2ZSxcbiAgICAgICAgICAgIHJlamVjdCkgPT4ge1xuXG4gICAgICAgICAgICBpZiAoc3RlcCA+IHRoaXMuTUFYX1NURVBTKSB7XG4gICAgICAgICAgICAgICAgcmVqZWN0KE5neFBpY2FFcnJvclR5cGUuTk9UX0JFX0FCTEVfVE9fQ09NUFJFU1NfRU5PVUdIKTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAodGhpcy5ieXRlc1RvTUIoYmxvYi5zaXplKSA8IHNpemVJbk1CKSB7XG4gICAgICAgICAgICAgICAgcmVzb2x2ZShibG9iKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgY29uc3QgbmV3UXVhbGl0eTogbnVtYmVyID0gcXVhbGl0eSAtIChxdWFsaXR5ICogMC4xKTtcbiAgICAgICAgICAgICAgICBjb25zdCBuZXdTdGVwOiBudW1iZXIgPSBzdGVwICsgMTtcblxuICAgICAgICAgICAgICAgIC8vIHJlY3Vyc2l2ZWx5IGNvbXByZXNzaW9uXG4gICAgICAgICAgICAgICAgcmVzb2x2ZSh0aGlzLmdldENvbXByZXNzZWRJbWFnZShjYW52YXMsIGJsb2IudHlwZSwgbmV3UXVhbGl0eSwgc2l6ZUluTUIsIG5ld1N0ZXApKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBwaWNhUmVzaXplKGZpbGU6IEZpbGUsIGZyb206IEhUTUxDYW52YXNFbGVtZW50LCB0bzogSFRNTENhbnZhc0VsZW1lbnQsIG9wdGlvbnM6IGFueSk6IFByb21pc2U8RmlsZT4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2U8RmlsZT4oKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5waWNhUmVzaXplci5yZXNpemUoZnJvbSwgdG8sIG9wdGlvbnMpXG4gICAgICAgICAgICAgICAgLmNhdGNoKChlcnIpID0+IHJlamVjdChlcnIpKVxuICAgICAgICAgICAgICAgIC50aGVuKChyZXNpemVkQ2FudmFzOiBIVE1MQ2FudmFzRWxlbWVudCkgPT4gdGhpcy5waWNhUmVzaXplci50b0Jsb2IocmVzaXplZENhbnZhcywgZmlsZS50eXBlKSlcbiAgICAgICAgICAgICAgICAudGhlbigoYmxvYjogQmxvYikgPT4ge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBmaWxlUmVzaXplZDogRmlsZSA9IHRoaXMuYmxvYlRvRmlsZShibG9iLCBmaWxlLm5hbWUsIGZpbGUudHlwZSwgbmV3IERhdGUoKS5nZXRUaW1lKCkpO1xuICAgICAgICAgICAgICAgICAgICByZXNvbHZlKGZpbGVSZXNpemVkKTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBibG9iVG9GaWxlKGJsb2I6IEJsb2IsIG5hbWU6IHN0cmluZywgdHlwZTogc3RyaW5nLCBsYXN0TW9kaWZpZWQ6IG51bWJlcik6IEZpbGUge1xuICAgICAgICAvLyByZXR1cm4gbmV3IEZpbGUoW2Jsb2JdLCBuYW1lLCB7dHlwZTogdHlwZSwgbGFzdE1vZGlmaWVkOiBsYXN0TW9kaWZpZWR9KTtcbiAgICAgICAgbGV0IGZpbGUgPSBuZXcgQmxvYihbYmxvYl0sIHt0eXBlIDogdHlwZX0pIGFzIGFueTtcbiAgICAgICAgZmlsZS5uYW1lID0gbmFtZTtcbiAgICAgICAgZmlsZS5sYXN0TW9kaWZpZWREYXRlID0gbGFzdE1vZGlmaWVkO1xuICAgICAgICByZXR1cm4gZmlsZSBhcyBGaWxlXG4gICAgfVxuXG4gICAgcHJpdmF0ZSBieXRlc1RvTUIoYnl0ZXM6IG51bWJlcikge1xuICAgICAgICByZXR1cm4gYnl0ZXMgLyAxMDQ4NTc2O1xuICAgIH1cbn1cbiJdfQ==