UNPKG

@trendster-io/ng-uploader

Version:

A fully featured Angular file uploader that utilizes Angular's HttpClient internally, allows you to customize outgoing HTTP requests using the "Angular Way" (Interceptors), provides customizable concurrent queuing of uploads and a simple way to select fil

858 lines 54.6 kB
/** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ import { HttpEventType } from '@angular/common/http'; import { Subject, Observable, of } from 'rxjs'; import { mergeMap, tap, filter, map, catchError, finalize } from 'rxjs/operators'; import { UploadItem } from './upload-item.class'; var Uploader = /** @class */ (function () { function Uploader(httpClient, options) { if (options === void 0) { options = {}; } this.httpClient = httpClient; this.onItemSuccessSubject = new Subject(); this.onItemProgressSubject = new Subject(); this.onItemErrorSubject = new Subject(); this.onItemSuccess = this.onItemSuccessSubject.asObservable(); this.onItemProgress = this.onItemProgressSubject.asObservable(); this.onItemError = this.onItemErrorSubject.asObservable(); this._totalProgress = 0; this.url = options.url; this.method = options.method; this.autoUpload = options.autoUpload; this.removeAfterUpload = options.removeAfterUpload; this.queueLimit = options.queueLimit; this.concurrency = options.concurrency || 1; this.maxFileSize = options.maxFileSize; this.allowedMimeTypes = options.allowedMimeTypes; this.setupQueue(); } Object.defineProperty(Uploader.prototype, "itemsCount", { get: /** * @return {?} */ function () { return this.queue.length; }, enumerable: true, configurable: true }); Object.defineProperty(Uploader.prototype, "items", { get: /** * @return {?} */ function () { return this.queue.map((/** * @param {?} queueItem * @return {?} */ function (queueItem) { return queueItem.item; })); }, enumerable: true, configurable: true }); Object.defineProperty(Uploader.prototype, "readyItemsCount", { get: /** * @return {?} */ function () { return this.queue .map((/** * @param {?} queueItem * @return {?} */ function (queueItem) { return queueItem.item; })) .filter((/** * @param {?} item * @return {?} */ function (item) { return item.isReady && !item.isUploading; })).length; }, enumerable: true, configurable: true }); Object.defineProperty(Uploader.prototype, "readyItems", { get: /** * @private * @return {?} */ function () { return this.queue .map((/** * @param {?} queueItem * @return {?} */ function (queueItem) { return queueItem.item; })) .filter((/** * @param {?} item * @return {?} */ function (item) { return item.isReady && !item.isUploading; })); }, enumerable: true, configurable: true }); Object.defineProperty(Uploader.prototype, "uploadingItemsCount", { get: /** * @return {?} */ function () { return this.queue .map((/** * @param {?} queueItem * @return {?} */ function (queueItem) { return queueItem.item; })) .filter((/** * @param {?} item * @return {?} */ function (item) { return item.isUploading; })).length; }, enumerable: true, configurable: true }); Object.defineProperty(Uploader.prototype, "uploadingItems", { get: /** * @private * @return {?} */ function () { return this.queue .map((/** * @param {?} queueItem * @return {?} */ function (queueItem) { return queueItem.item; })) .filter((/** * @param {?} item * @return {?} */ function (item) { return item.isUploading; })); }, enumerable: true, configurable: true }); Object.defineProperty(Uploader.prototype, "uploadedItemsCount", { get: /** * @return {?} */ function () { return this.queue .map((/** * @param {?} queueItem * @return {?} */ function (queueItem) { return queueItem.item; })) .filter((/** * @param {?} item * @return {?} */ function (item) { return item.isUploaded; })).length; }, enumerable: true, configurable: true }); Object.defineProperty(Uploader.prototype, "uploadedItems", { get: /** * @private * @return {?} */ function () { return this.queue .map((/** * @param {?} queueItem * @return {?} */ function (queueItem) { return queueItem.item; })) .filter((/** * @param {?} item * @return {?} */ function (item) { return item.isUploaded; })); }, enumerable: true, configurable: true }); Object.defineProperty(Uploader.prototype, "notUploadedItemsCount", { get: /** * @return {?} */ function () { return this.queue .map((/** * @param {?} queueItem * @return {?} */ function (queueItem) { return queueItem.item; })) .filter((/** * @param {?} item * @return {?} */ function (item) { return !item.isUploaded; })).length; }, enumerable: true, configurable: true }); Object.defineProperty(Uploader.prototype, "notUploadedItems", { get: /** * @private * @return {?} */ function () { return this.queue .map((/** * @param {?} queueItem * @return {?} */ function (queueItem) { return queueItem.item; })) .filter((/** * @param {?} item * @return {?} */ function (item) { return !item.isUploaded; })); }, enumerable: true, configurable: true }); Object.defineProperty(Uploader.prototype, "cancelledItemsCount", { get: /** * @return {?} */ function () { return this.queue .map((/** * @param {?} queueItem * @return {?} */ function (queueItem) { return queueItem.item; })) .filter((/** * @param {?} item * @return {?} */ function (item) { return item.isCancelled; })).length; }, enumerable: true, configurable: true }); Object.defineProperty(Uploader.prototype, "cancelledItems", { get: /** * @private * @return {?} */ function () { return this.queue .map((/** * @param {?} queueItem * @return {?} */ function (queueItem) { return queueItem.item; })) .filter((/** * @param {?} item * @return {?} */ function (item) { return item.isCancelled; })); }, enumerable: true, configurable: true }); Object.defineProperty(Uploader.prototype, "errorItemsCount", { get: /** * @return {?} */ function () { return this.queue .map((/** * @param {?} queueItem * @return {?} */ function (queueItem) { return queueItem.item; })) .filter((/** * @param {?} item * @return {?} */ function (item) { return item.isError; })).length; }, enumerable: true, configurable: true }); Object.defineProperty(Uploader.prototype, "errorItems", { get: /** * @private * @return {?} */ function () { return this.queue .map((/** * @param {?} queueItem * @return {?} */ function (queueItem) { return queueItem.item; })) .filter((/** * @param {?} item * @return {?} */ function (item) { return item.isError; })); }, enumerable: true, configurable: true }); Object.defineProperty(Uploader.prototype, "totalProgress", { get: /** * @return {?} */ function () { return this._totalProgress; }, enumerable: true, configurable: true }); Object.defineProperty(Uploader.prototype, "isUploading", { get: /** * @return {?} */ function () { return this.uploadingItemsCount > 0; }, enumerable: true, configurable: true }); /** * @private * @param {?} __0 * @return {?} */ Uploader.prototype.onQueueItemSuccess = /** * @private * @param {?} __0 * @return {?} */ function (_a) { var item = _a.item, res = _a.res; item.onUploadSuccess(res); this.onItemSuccessSubject.next({ item: item, res: res }); if (this.removeAfterUpload) { item.remove(); } }; /** * @private * @param {?} __0 * @return {?} */ Uploader.prototype.onQueueItemError = /** * @private * @param {?} __0 * @return {?} */ function (_a) { var item = _a.item, err = _a.err; item.onUploadError(err); this.onItemErrorSubject.next({ item: item, err: err }); }; /** * @private * @param {?} req * @return {?} */ Uploader.prototype.request = /** * @private * @param {?} req * @return {?} */ function (req) { return this.httpClient.request(req).pipe(filter((/** * @param {?} event * @return {?} */ function (event) { return event.type === HttpEventType.Sent || event.type === HttpEventType.UploadProgress || event.type === HttpEventType.Response; })), map((/** * @param {?} event * @return {?} */ function (event) { switch (event.type) { case HttpEventType.Sent: return { type: 'start', value: null }; case HttpEventType.UploadProgress: /** @type {?} */ var progress = Math.round((100 * event.loaded) / event.total); return { type: 'progress', value: progress }; case HttpEventType.Response: return { type: 'response', value: event.body }; } }))); }; /** * @private * @return {?} */ Uploader.prototype.calculateTotalProgress = /** * @private * @return {?} */ function () { /** @type {?} */ var value = this.uploadingItems.reduce((/** * @param {?} acc * @param {?} item * @return {?} */ function (acc, item) { return item.progress + acc; }), 0) / (this.uploadingItemsCount || 1); if (this.removeAfterUpload) { this._totalProgress = value; } else { /** @type {?} */ var ratio = 100 / this.itemsCount; /** @type {?} */ var current = (value * ratio) / 100; this._totalProgress = Math.round(this.uploadedItemsCount * ratio + current); } }; /** * @private * @param {?} queueItem * @return {?} */ Uploader.prototype.prepareQueueItem = /** * @private * @param {?} queueItem * @return {?} */ function (queueItem) { var _this = this; return new Observable((/** * @param {?} observer * @return {?} */ function (observer) { queueItem.subscription = _this.request(queueItem.item.req) .pipe(finalize((/** * @return {?} */ function () { if (!observer.closed) { observer.complete(); } })), tap((/** * @param {?} event * @return {?} */ function (event) { switch (event.type) { case 'start': queueItem.item.onUploadStart(); break; case 'progress': /** @type {?} */ var progress = event.value; /** @type {?} */ var item = queueItem.item; item.onUploadProgress(progress); _this.onItemProgressSubject.next({ item: item, progress: progress }); _this.calculateTotalProgress(); break; default: break; } })), filter((/** * @param {?} event * @return {?} */ function (event) { return event.type === 'response'; })), map((/** * @param {?} event * @return {?} */ function (event) { return event.value; }))) .subscribe({ next: (/** * @param {?} res * @return {?} */ function (res) { queueItem.subscription = null; observer.next({ item: queueItem.item, res: res }); observer.complete(); }), error: (/** * @param {?} err * @return {?} */ function (err) { queueItem.subscription = null; observer.error({ item: queueItem.item, err: err }); }), complete: (/** * @return {?} */ function () { return observer.complete(); }) }); })); }; /** * @private * @return {?} */ Uploader.prototype.setupQueue = /** * @private * @return {?} */ function () { var _this = this; this.queue = []; this.scheduler = new Subject(); this.scheduler .pipe(mergeMap((/** * @param {?} queueItem * @return {?} */ function (queueItem) { return _this.prepareQueueItem(queueItem).pipe(catchError((/** * @param {?} uploadEvent * @return {?} */ function (uploadEvent) { _this.onQueueItemError(uploadEvent); return of(null); }))); }), this.concurrency), filter((/** * @param {?} uploadEvent * @return {?} */ function (uploadEvent) { return Boolean(uploadEvent); }))) .subscribe((/** * @param {?} uploadEvent * @return {?} */ function (uploadEvent) { return _this.onQueueItemSuccess(uploadEvent); })); }; /** * @private * @param {?} __0 * @return {?} */ Uploader.prototype.isValidRequestParams = /** * @private * @param {?} __0 * @return {?} */ function (_a) { var url = _a.url, method = _a.method; return Boolean(url || this.url) && Boolean(method || this.method); }; /** * @private * @param {?} file * @return {?} */ Uploader.prototype.isValidFileType = /** * @private * @param {?} file * @return {?} */ function (file) { return this.allowedMimeTypes && this.allowedMimeTypes.length ? this.allowedMimeTypes.includes(file.type) : true; }; /** * @private * @param {?} file * @return {?} */ Uploader.prototype.isValidFileSize = /** * @private * @param {?} file * @return {?} */ function (file) { return this.maxFileSize ? file.size <= this.maxFileSize : true; }; /** * @private * @param {?} file * @return {?} */ Uploader.prototype.isValidFile = /** * @private * @param {?} file * @return {?} */ function (file) { return this.isValidFileType(file) && this.isValidFileSize(file); }; /** * @private * @return {?} */ Uploader.prototype.canAddToQueue = /** * @private * @return {?} */ function () { return this.queueLimit ? this.itemsCount < this.queueLimit : true; }; /** * @private * @param {?} options * @return {?} */ Uploader.prototype.checkItem = /** * @private * @param {?} options * @return {?} */ function (options) { if (!this.isValidRequestParams(options)) { throw { name: 'RequestParamsMissing', message: 'You have not supplied a general url or method to the uploader and also didn\'t provide them in your item.' }; } if (!this.isValidFileType(options.file)) { throw { name: 'NotAllowedFileType', message: 'The file type is not included in the allowedMimeTypes.' }; } if (!this.isValidFileSize(options.file)) { throw { name: 'FileSizeExceeded', message: 'The file size exceeded the maximumFileSize.' }; } if (!this.canAddToQueue()) { throw { name: 'QueueLimitReached', message: 'The specified queueLimit was reached, cannot add more items at the moment.' }; } }; /** * @param {?} options * @return {?} */ Uploader.prototype.addItem = /** * @param {?} options * @return {?} */ function (options) { this.checkItem(options); Object.assign(options, { url: options.url || this.url, method: options.method || this.method }); /** @type {?} */ var item = new UploadItem(this, options); this.queue.push({ item: item, subscription: null }); this.calculateTotalProgress(); if (this.autoUpload) { item.upload(); } return item; }; /** * @param {?} item * @return {?} */ Uploader.prototype.uploadItem = /** * @param {?} item * @return {?} */ function (item) { /** @type {?} */ var queueItem = this.queue.find((/** * @param {?} current * @return {?} */ function (current) { return current.item === item && !(current.item.isReady || current.item.isUploading || current.item.isUploaded); })); if (queueItem) { item.onBeforeUpload(); this.scheduler.next(queueItem); } }; /** * @return {?} */ Uploader.prototype.uploadAll = /** * @return {?} */ function () { this.items .filter((/** * @param {?} item * @return {?} */ function (item) { return !(item.isReady || item.isUploading || item.isUploaded); })) .forEach((/** * @param {?} item * @return {?} */ function (item) { return item.upload(); })); }; /** * @param {?} item * @return {?} */ Uploader.prototype.cancelItem = /** * @param {?} item * @return {?} */ function (item) { /** @type {?} */ var queueItem = this.queue.find((/** * @param {?} current * @return {?} */ function (current) { return current.item === item && item.isReady; })); if (queueItem) { if (queueItem.subscription) { queueItem.subscription.unsubscribe(); queueItem.subscription = null; } queueItem.item.onUploadCancelled(); this.calculateTotalProgress(); } }; /** * @return {?} */ Uploader.prototype.cancelAll = /** * @return {?} */ function () { this.notUploadedItems.forEach((/** * @param {?} item * @return {?} */ function (item) { return item.cancel(); })); }; /** * @param {?} item * @return {?} */ Uploader.prototype.removeItem = /** * @param {?} item * @return {?} */ function (item) { if (item.isUploading) { item.cancel(); } item.cleanup(); this.queue = this.queue.filter((/** * @param {?} current * @return {?} */ function (current) { return current.item !== item; })); this.calculateTotalProgress(); }; /** * @return {?} */ Uploader.prototype.clearQueue = /** * @return {?} */ function () { while (this.itemsCount) { this.queue[0].item.remove(); } this._totalProgress = 0; }; return Uploader; }()); export { Uploader }; if (false) { /** @type {?} */ Uploader.prototype.onItemSuccess; /** @type {?} */ Uploader.prototype.onItemProgress; /** @type {?} */ Uploader.prototype.onItemError; /** * @type {?} * @private */ Uploader.prototype.onItemSuccessSubject; /** * @type {?} * @private */ Uploader.prototype.onItemProgressSubject; /** * @type {?} * @private */ Uploader.prototype.onItemErrorSubject; /** * @type {?} * @private */ Uploader.prototype._totalProgress; /** * @type {?} * @private */ Uploader.prototype.url; /** * @type {?} * @private */ Uploader.prototype.method; /** * @type {?} * @private */ Uploader.prototype.autoUpload; /** * @type {?} * @private */ Uploader.prototype.removeAfterUpload; /** * @type {?} * @private */ Uploader.prototype.queueLimit; /** * @type {?} * @private */ Uploader.prototype.concurrency; /** * @type {?} * @private */ Uploader.prototype.maxFileSize; /** * @type {?} * @private */ Uploader.prototype.allowedMimeTypes; /** * @type {?} * @private */ Uploader.prototype.queue; /** * @type {?} * @private */ Uploader.prototype.scheduler; /** * @type {?} * @private */ Uploader.prototype.httpClient; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXBsb2FkZXIuY2xhc3MuanMiLCJzb3VyY2VSb290Ijoibmc6Ly9AdHJlbmRzdGVyLWlvL25nLXVwbG9hZGVyLyIsInNvdXJjZXMiOlsibGliL3VwbG9hZGVyLmNsYXNzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7QUFBQSxPQUFPLEVBSUwsYUFBYSxFQUNkLE1BQU0sc0JBQXNCLENBQUM7QUFFOUIsT0FBTyxFQUFFLE9BQU8sRUFBRSxVQUFVLEVBQUUsRUFBRSxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQy9DLE9BQU8sRUFDTCxRQUFRLEVBQ1IsR0FBRyxFQUNILE1BQU0sRUFDTixHQUFHLEVBQ0gsVUFBVSxFQUNWLFFBQVEsRUFDVCxNQUFNLGdCQUFnQixDQUFDO0FBRXhCLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQVVqRDtJQW1CRSxrQkFBb0IsVUFBc0IsRUFBRSxPQUE2QjtRQUE3Qix3QkFBQSxFQUFBLFlBQTZCO1FBQXJELGVBQVUsR0FBVixVQUFVLENBQVk7UUFDeEMsSUFBSSxDQUFDLG9CQUFvQixHQUFHLElBQUksT0FBTyxFQUFFLENBQUM7UUFDMUMsSUFBSSxDQUFDLHFCQUFxQixHQUFHLElBQUksT0FBTyxFQUFFLENBQUM7UUFDM0MsSUFBSSxDQUFDLGtCQUFrQixHQUFHLElBQUksT0FBTyxFQUFFLENBQUM7UUFDeEMsSUFBSSxDQUFDLGFBQWEsR0FBRyxJQUFJLENBQUMsb0JBQW9CLENBQUMsWUFBWSxFQUFFLENBQUM7UUFDOUQsSUFBSSxDQUFDLGNBQWMsR0FBRyxJQUFJLENBQUMscUJBQXFCLENBQUMsWUFBWSxFQUFFLENBQUM7UUFDaEUsSUFBSSxDQUFDLFdBQVcsR0FBRyxJQUFJLENBQUMsa0JBQWtCLENBQUMsWUFBWSxFQUFFLENBQUM7UUFDMUQsSUFBSSxDQUFDLGNBQWMsR0FBRyxDQUFDLENBQUM7UUFDeEIsSUFBSSxDQUFDLEdBQUcsR0FBRyxPQUFPLENBQUMsR0FBRyxDQUFDO1FBQ3ZCLElBQUks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QkFBNEI7Ozs7O0lBQzVCLCtCQUE0Qjs7Ozs7SUFDNUIsb0NBQW1DOzs7OztJQUNuQyx5QkFBaUM7Ozs7O0lBQ2pDLDZCQUE0Qzs7Ozs7SUFFaEMsOEJBQThCIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgSHR0cEVycm9yUmVzcG9uc2UsXG4gIEh0dHBDbGllbnQsXG4gIEh0dHBSZXF1ZXN0LFxuICBIdHRwRXZlbnRUeXBlXG59IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbi9odHRwJztcblxuaW1wb3J0IHsgU3ViamVjdCwgT2JzZXJ2YWJsZSwgb2YgfSBmcm9tICdyeGpzJztcbmltcG9ydCB7XG4gIG1lcmdlTWFwLFxuICB0YXAsXG4gIGZpbHRlcixcbiAgbWFwLFxuICBjYXRjaEVycm9yLFxuICBmaW5hbGl6ZVxufSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5cbmltcG9ydCB7IFVwbG9hZEl0ZW0gfSBmcm9tICcuL3VwbG9hZC1pdGVtLmNsYXNzJztcblxuaW1wb3J0IHtcbiAgVXBsb2FkTGlzdGVuZXIsXG4gIFVwbG9hZGVyT3B0aW9ucyxcbiAgVXBsb2FkSXRlbU9wdGlvbnMsXG4gIFVwbG9hZEl0ZW1FdmVudCxcbiAgVXBsb2FkUXVldWVJdGVtXG59IGZyb20gJy4vbW9kZWxzJztcblxuZXhwb3J0IGNsYXNzIFVwbG9hZGVyIGltcGxlbWVudHMgVXBsb2FkTGlzdGVuZXIge1xuICByZWFkb25seSBvbkl0ZW1TdWNjZXNzOiBPYnNlcnZhYmxlPFVwbG9hZEl0ZW1FdmVudD47XG4gIHJlYWRvbmx5IG9uSXRlbVByb2dyZXNzOiBPYnNlcnZhYmxlPFVwbG9hZEl0ZW1FdmVudD47XG4gIHJlYWRvbmx5IG9uSXRlbUVycm9yOiBPYnNlcnZhYmxlPFVwbG9hZEl0ZW1FdmVudD47XG4gIHByaXZhdGUgb25JdGVtU3VjY2Vzc1N1YmplY3Q6IFN1YmplY3Q8VXBsb2FkSXRlbUV2ZW50PjtcbiAgcHJpdmF0ZSBvbkl0ZW1Qcm9ncmVzc1N1YmplY3Q6IFN1YmplY3Q8VXBsb2FkSXRlbUV2ZW50PjtcbiAgcHJpdmF0ZSBvbkl0ZW1FcnJvclN1YmplY3Q6IFN1YmplY3Q8VXBsb2FkSXRlbUV2ZW50PjtcbiAgcHJpdmF0ZSBfdG90YWxQcm9ncmVzczogbnVtYmVyO1xuICBwcml2YXRlIHVybDogc3RyaW5nO1xuICBwcml2YXRlIG1ldGhvZDogJ1BPU1QnIHwgJ1BVVCcgfCAnUEFUQ0gnO1xuICBwcml2YXRlIGF1dG9VcGxvYWQ6IGJvb2xlYW47XG4gIHByaXZhdGUgcmVtb3ZlQWZ0ZXJVcGxvYWQ6IGJvb2xlYW47XG4gIHByaXZhdGUgcXVldWVMaW1pdDogbnVtYmVyO1xuICBwcml2YXRlIGNvbmN1cnJlbmN5OiBudW1iZXI7XG4gIHByaXZhdGUgbWF4RmlsZVNpemU6IG51bWJlcjtcbiAgcHJpdmF0ZSBhbGxvd2VkTWltZVR5cGVzOiBzdHJpbmdbXTtcbiAgcHJpdmF0ZSBxdWV1ZTogVXBsb2FkUXVldWVJdGVtW107XG4gIHByaXZhdGUgc2NoZWR1bGVyOiBTdWJqZWN0PFVwbG9hZFF1ZXVlSXRlbT47XG5cbiAgY29uc3RydWN0b3IocHJpdmF0ZSBodHRwQ2xpZW50OiBIdHRwQ2xpZW50LCBvcHRpb25zOiBVcGxvYWRlck9wdGlvbnMgPSB7fSkge1xuICAgIHRoaXMub25JdGVtU3VjY2Vzc1N1YmplY3QgPSBuZXcgU3ViamVjdCgpO1xuICAgIHRoaXMub25JdGVtUHJvZ3Jlc3NTdWJqZWN0ID0gbmV3IFN1YmplY3QoKTtcbiAgICB0aGlzLm9uSXRlbUVycm9yU3ViamVjdCA9IG5ldyBTdWJqZWN0KCk7XG4gICAgdGhpcy5vbkl0ZW1TdWNjZXNzID0gdGhpcy5vbkl0ZW1TdWNjZXNzU3ViamVjdC5hc09ic2VydmFibGUoKTtcbiAgICB0aGlzLm9uSXRlbVByb2dyZXNzID0gdGhpcy5vbkl0ZW1Qcm9ncmVzc1N1YmplY3QuYXNPYnNlcnZhYmxlKCk7XG4gICAgdGhpcy5vbkl0ZW1FcnJvciA9IHRoaXMub25JdGVtRXJyb3JTdWJqZWN0LmFzT2JzZXJ2YWJsZSgpO1xuICAgIHRoaXMuX3RvdGFsUHJvZ3Jlc3MgPSAwO1xuICAgIHRoaXMudXJsID0gb3B0aW9ucy51cmw7XG4gICAgdGhpcy5tZXRob2QgPSBvcHRpb25zLm1ldGhvZDtcbiAgICB0aGlzLmF1dG9VcGxvYWQgPSBvcHRpb25zLmF1dG9VcGxvYWQ7XG4gICAgdGhpcy5yZW1vdmVBZnRlclVwbG9hZCA9IG9wdGlvbnMucmVtb3ZlQWZ0ZXJVcGxvYWQ7XG4gICAgdGhpcy5xdWV1ZUxpbWl0ID0gb3B0aW9ucy5xdWV1ZUxpbWl0O1xuICAgIHRoaXMuY29uY3VycmVuY3kgPSBvcHRpb25zLmNvbmN1cnJlbmN5IHx8IDE7XG4gICAgdGhpcy5tYXhGaWxlU2l6ZSA9IG9wdGlvbnMubWF4RmlsZVNpemU7XG4gICAgdGhpcy5hbGxvd2VkTWltZVR5cGVzID0gb3B0aW9ucy5hbGxvd2VkTWltZVR5cGVzO1xuICAgIHRoaXMuc2V0dXBRdWV1ZSgpO1xuICB9XG5cbiAgZ2V0IGl0ZW1zQ291bnQoKTogbnVtYmVyIHtcbiAgICByZXR1cm4gdGhpcy5xdWV1ZS5sZW5ndGg7XG4gIH1cblxuICBnZXQgaXRlbXMoKTogVXBsb2FkSXRlbVtdIHtcbiAgICByZXR1cm4gdGhpcy5xdWV1ZS5tYXAocXVldWVJdGVtID0+IHF1ZXVlSXRlbS5pdGVtKTtcbiAgfVxuXG4gIGdldCByZWFkeUl0ZW1zQ291bnQoKTogbnVtYmVyIHtcbiAgICByZXR1cm4gdGhpcy5xdWV1ZVxuICAgICAgLm1hcChxdWV1ZUl0ZW0gPT4gcXVldWVJdGVtLml0ZW0pXG4gICAgICAuZmlsdGVyKGl0ZW0gPT4gaXRlbS5pc1JlYWR5ICYmICFpdGVtLmlzVXBsb2FkaW5nKS5sZW5ndGg7XG4gIH1cblxuICBwcml2YXRlIGdldCByZWFkeUl0ZW1zKCk6IFVwbG9hZEl0ZW1bXSB7XG4gICAgcmV0dXJuIHRoaXMucXVldWVcbiAgICAgIC5tYXAocXVldWVJdGVtID0+IHF1ZXVlSXRlbS5pdGVtKVxuICAgICAgLmZpbHRlcihpdGVtID0+IGl0ZW0uaXNSZWFkeSAmJiAhaXRlbS5pc1VwbG9hZGluZyk7XG4gIH1cblxuICBnZXQgdXBsb2FkaW5nSXRlbXNDb3VudCgpOiBudW1iZXIge1xuICAgIHJldHVybiB0aGlzLnF1ZXVlXG4gICAgICAubWFwKHF1ZXVlSXRlbSA9PiBxdWV1ZUl0ZW0uaXRlbSlcbiAgICAgIC5maWx0ZXIoaXRlbSA9PiBpdGVtLmlzVXBsb2FkaW5nKS5sZW5ndGg7XG4gIH1cblxuICBwcml2YXRlIGdldCB1cGxvYWRpbmdJdGVtcygpOiBVcGxvYWRJdGVtW10ge1xuICAgIHJldHVybiB0aGlzLnF1ZXVlXG4gICAgICAubWFwKHF1ZXVlSXRlbSA9PiBxdWV1ZUl0ZW0uaXRlbSlcbiAgICAgIC5maWx0ZXIoaXRlbSA9PiBpdGVtLmlzVXBsb2FkaW5nKTtcbiAgfVxuXG4gIGdldCB1cGxvYWRlZEl0ZW1zQ291bnQoKTogbnVtYmVyIHtcbiAgICByZXR1cm4gdGhpcy5xdWV1ZVxuICAgICAgLm1hcChxdWV1ZUl0ZW0gPT4gcXVldWVJdGVtLml0ZW0pXG4gICAgICAuZmlsdGVyKGl0ZW0gPT4gaXRlbS5pc1VwbG9hZGVkKS5sZW5ndGg7XG4gIH1cblxuICBwcml2YXRlIGdldCB1cGxvYWRlZEl0ZW1zKCk6IFVwbG9hZEl0ZW1bXSB7XG4gICAgcmV0dXJuIHRoaXMucXVldWVcbiAgICAgIC5tYXAocXVldWVJdGVtID0+IHF1ZXVlSXRlbS5pdGVtKVxuICAgICAgLmZpbHRlcihpdGVtID0+IGl0ZW0uaXNVcGxvYWRlZCk7XG4gIH1cblxuICBnZXQgbm90VXBsb2FkZWRJdGVtc0NvdW50KCk6IG51bWJlciB7XG4gICAgcmV0dXJuIHRoaXMucXVldWVcbiAgICAgIC5tYXAocXVldWVJdGVtID0+IHF1ZXVlSXRlbS5pdGVtKVxuICAgICAgLmZpbHRlcihpdGVtID0+ICFpdGVtLmlzVXBsb2FkZWQpLmxlbmd0aDtcbiAgfVxuXG4gIHByaXZhdGUgZ2V0IG5vdFVwbG9hZGVkSXRlbXMoKTogVXBsb2FkSXRlbVtdIHtcbiAgICByZXR1cm4gdGhpcy5xdWV1ZVxuICAgICAgLm1hcChxdWV1ZUl0ZW0gPT4gcXVldWVJdGVtLml0ZW0pXG4gICAgICAuZmlsdGVyKGl0ZW0gPT4gIWl0ZW0uaXNVcGxvYWRlZCk7XG4gIH1cblxuICBnZXQgY2FuY2VsbGVkSXRlbXNDb3VudCgpOiBudW1iZXIge1xuICAgIHJldHVybiB0aGlzLnF1ZXVlXG4gICAgICAubWFwKHF1ZXVlSXRlbSA9PiBxdWV1ZUl0ZW0uaXRlbSlcbiAgICAgIC5maWx0ZXIoaXRlbSA9PiBpdGVtLmlzQ2FuY2VsbGVkKS5sZW5ndGg7XG4gIH1cblxuICBwcml2YXRlIGdldCBjYW5jZWxsZWRJdGVtcygpOiBVcGxvYWRJdGVtW10ge1xuICAgIHJldHVybiB0aGlzLnF1ZXVlXG4gICAgICAubWFwKHF1ZXVlSXRlbSA9PiBxdWV1ZUl0ZW0uaXRlbSlcbiAgICAgIC5maWx0ZXIoaXRlbSA9PiBpdGVtLmlzQ2FuY2VsbGVkKTtcbiAgfVxuXG4gIGdldCBlcnJvckl0ZW1zQ291bnQoKTogbnVtYmVyIHtcbiAgICByZXR1cm4gdGhpcy5xdWV1ZVxuICAgICAgLm1hcChxdWV1ZUl0ZW0gPT4gcXVldWVJdGVtLml0ZW0pXG4gICAgICAuZmlsdGVyKGl0ZW0gPT4gaXRlbS5pc0Vycm9yKS5sZW5ndGg7XG4gIH1cblxuICBwcml2YXRlIGdldCBlcnJvckl0ZW1zKCk6IFVwbG9hZEl0ZW1bXSB7XG4gICAgcmV0dXJuIHRoaXMucXVldWVcbiAgICAgIC5tYXAocXVldWVJdGVtID0+IHF1ZXVlSXRlbS5pdGVtKVxuICAgICAgLmZpbHRlcihpdGVtID0+IGl0ZW0uaXNFcnJvcik7XG4gIH1cblxuICBnZXQgdG90YWxQcm9ncmVzcygpOiBudW1iZXIge1xuICAgIHJldHVybiB0aGlzLl90b3RhbFByb2dyZXNzO1xuICB9XG5cbiAgZ2V0IGlzVXBsb2FkaW5nKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLnVwbG9hZGluZ0l0ZW1zQ291bnQgPiAwO1xuICB9XG5cbiAgcHJpdmF0ZSBvblF1ZXVlSXRlbVN1Y2Nlc3MoeyBpdGVtLCByZXMgfTogVXBsb2FkSXRlbUV2ZW50KTogdm9pZCB7XG4gICAgaXRlbS5vblVwbG9hZFN1Y2Nlc3MocmVzKTtcbiAgICB0aGlzLm9uSXRlbVN1Y2Nlc3NTdWJqZWN0Lm5leHQoeyBpdGVtLCByZXMgfSk7XG4gICAgaWYgKHRoaXMucmVtb3ZlQWZ0ZXJVcGxvYWQpIHtcbiAgICAgIGl0ZW0ucmVtb3ZlKCk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBvblF1ZXVlSXRlbUVycm9yKHsgaXRlbSwgZXJyIH06IFVwbG9hZEl0ZW1FdmVudCk6IHZvaWQge1xuICAgIGl0ZW0ub25VcGxvYWRFcnJvcihlcnIpO1xuICAgIHRoaXMub25JdGVtRXJyb3JTdWJqZWN0Lm5leHQoeyBpdGVtLCBlcnIgfSk7XG4gIH1cblxuICBwcml2YXRlIHJlcXVlc3QocmVxOiBIdHRwUmVxdWVzdDxGb3JtRGF0YT4pOiBPYnNlcnZhYmxlPGFueT4ge1xuICAgIHJldHVybiB0aGlzLmh0dHBDbGllbnQucmVxdWVzdChyZXEpLnBpcGUoXG4gICAgICBmaWx0ZXIoXG4gICAgICAgIGV2ZW50ID0+XG4gICAgICAgICAgZXZlbnQudHlwZSA9PT0gSHR0cEV2ZW50VHlwZS5TZW50IHx8XG4gICAgICAgICAgZXZlbnQudHlwZSA9PT0gSHR0cEV2ZW50VHlwZS5VcGxvYWRQcm9ncmVzcyB8fFxuICAgICAgICAgIGV2ZW50LnR5cGUgPT09IEh0dHBFdmVudFR5cGUuUmVzcG9uc2VcbiAgICAgICksXG4gICAgICBtYXAoZXZlbnQgPT4ge1xuICAgICAgICBzd2l0Y2ggKGV2ZW50LnR5cGUpIHtcbiAgICAgICAgICBjYXNlIEh0dHBFdmVudFR5cGUuU2VudDpcbiAgICAgICAgICAgIHJldHVybiB7IHR5cGU6ICdzdGFydCcsIHZhbHVlOiBudWxsIH07XG4gICAgICAgICAgY2FzZSBIdHRwRXZlbnRUeXBlLlVwbG9hZFByb2dyZXNzOlxuICAgICAgICAgICAgY29uc3QgcHJvZ3Jlc3MgPSBNYXRoLnJvdW5kKCgxMDAgKiBldmVudC5sb2FkZWQpIC8gZXZlbnQudG90YWwpO1xuICAgICAgICAgICAgcmV0dXJuIHsgdHlwZTogJ3Byb2dyZXNzJywgdmFsdWU6IHByb2dyZXNzIH07XG4gICAgICAgICAgY2FzZSBIdHRwRXZlbnRUeXBlLlJlc3BvbnNlOlxuICAgICAgICAgICAgcmV0dXJuIHsgdHlwZTogJ3Jlc3BvbnNlJywgdmFsdWU6IGV2ZW50LmJvZHkgfTtcbiAgICAgICAgfVxuICAgICAgfSlcbiAgICApO1xuICB9XG5cbiAgcHJpdmF0ZSBjYWxjdWxhdGVUb3RhbFByb2dyZXNzKCk6IHZvaWQge1xuICAgIGNvbnN0IHZhbHVlID1cbiAgICAgIHRoaXMudXBsb2FkaW5nSXRlbXMucmVkdWNlKChhY2MsIGl0ZW0pID0+IGl0ZW0ucHJvZ3Jlc3MgKyBhY2MsIDApIC9cbiAgICAgICh0aGlzLnVwbG9hZGluZ0l0ZW1zQ291bnQgfHwgMSk7XG4gICAgaWYgKHRoaXMucmVtb3ZlQWZ0ZXJVcGxvYWQpIHtcbiAgICAgIHRoaXMuX3RvdGFsUHJvZ3Jlc3MgPSB2YWx1ZTtcbiAgICB9IGVsc2Uge1xuICAgICAgY29uc3QgcmF0aW8gPSAxMDAgLyB0aGlzLml0ZW1zQ291bnQ7XG4gICAgICBjb25zdCBjdXJyZW50ID0gKHZhbHVlICogcmF0aW8pIC8gMTAwO1xuICAgICAgdGhpcy5fdG90YWxQcm9ncmVzcyA9IE1hdGgucm91bmQoXG4gICAgICAgIHRoaXMudXBsb2FkZWRJdGVtc0NvdW50ICogcmF0aW8gKyBjdXJyZW50XG4gICAgICApO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgcHJlcGFyZVF1ZXVlSXRlbShxdWV1ZUl0ZW06IFVwbG9hZFF1ZXVlSXRlbSk6IE9ic2VydmFibGU8YW55PiB7XG4gICAgcmV0dXJuIG5ldyBPYnNlcnZhYmxlKG9ic2VydmVyID0+IHtcbiAgICAgIHF1ZXVlSXRlbS5zdWJzY3JpcHRpb24gPSB0aGlzLnJlcXVlc3QocXVldWVJdGVtLml0ZW0ucmVxKVxuICAgICAgICAucGlwZShcbiAgICAgICAgICBmaW5hbGl6ZSgoKSA9PiB7XG4gICAgICAgICAgICBpZiAoIW9ic2VydmVyLmNsb3NlZCkge1xuICAgICAgICAgICAgICBvYnNlcnZlci5jb21wbGV0ZSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0pLFxuICAgICAgICAgIHRhcChldmVudCA9PiB7XG4gICAgICAgICAgICBzd2l0Y2ggKGV2ZW50LnR5cGUpIHtcbiAgICAgICAgICAgICAgY2FzZSAnc3RhcnQnOlxuICAgICAgICAgICAgICAgIHF1ZXVlSXRlbS5pdGVtLm9uVXBsb2FkU3RhcnQoKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgY2FzZSAncHJvZ3Jlc3MnOlxuICAgICAgICAgICAgICAgIGNvbnN0IHByb2dyZXNzID0gZXZlbnQudmFsdWU7XG4gICAgICAgICAgICAgICAgY29uc3QgaXRlbSA9IHF1ZXVlSXRlbS5pdGVtO1xuICAgICAgICAgICAgICAgIGl0ZW0ub25VcGxvYWRQcm9ncmVzcyhwcm9ncmVzcyk7XG4gICAgICAgICAgICAgICAgdGhpcy5vbkl0ZW1Qcm9ncmVzc1N1YmplY3QubmV4dCh7IGl0ZW0sIHByb2dyZXNzIH0pO1xuICAgICAgICAgICAgICAgIHRoaXMuY2FsY3VsYXRlVG90YWxQcm9ncmVzcygpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0pLFxuICAgICAgICAgIGZpbHRlcihldmVudCA9PiBldmVudC50eXBlID09PSAncmVzcG9uc2UnKSxcbiAgICAgICAgICBtYXAoZXZlbnQgPT4gZXZlbnQudmFsdWUpXG4gICAgICAgIClcbiAgICAgICAgLnN1YnNjcmliZSh7XG4gICAgICAgICAgbmV4dDogcmVzID0+IHtcbiAgICAgICAgICAgIHF1ZXVlSXRlbS5zdWJzY3JpcHRpb24gPSBudWxsO1xuICAgICAgICAgICAgb2JzZXJ2ZXIubmV4dCh7IGl0ZW06IHF1ZXVlSXRlbS5pdGVtLCByZXMgfSk7XG4gICAgICAgICAgICBvYnNlcnZlci5jb21wbGV0ZSgpO1xuICAgICAgICAgIH0sXG4gICAgICAgICAgZXJyb3I6IChlcnI6IEh0dHBFcnJvclJlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgICBxdWV1ZUl0ZW0uc3Vic2NyaXB0aW9uID0gbnVsbDtcbiAgICAgICAgICAgIG9ic2VydmVyLmVycm9yKHsgaXRlbTogcXVldWVJdGVtLml0ZW0sIGVyciB9KTtcbiAgICAgICAgICB9LFxuICAgICAgICAgIGNvbXBsZXRlOiAoKSA9PiBvYnNlcnZlci5jb21wbGV0ZSgpXG4gICAgICAgIH0pO1xuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBzZXR1cFF1ZXVlKCk6IHZvaWQge1xuICAgIHRoaXMucXVldWUgPSBbXTtcbiAgICB0aGlzLnNjaGVkdWxlciA9IG5ldyBTdWJqZWN0KCk7XG4gICAgdGhpcy5zY2hlZHVsZXJcbiAgICAgIC5waXBlKFxuICAgICAgICBtZXJnZU1hcChcbiAgICAgICAgICBxdWV1ZUl0ZW0gPT5cbiAgICAgICAgICAgIHRoaXMucHJlcGFyZVF1ZXVlSXRlbShxdWV1ZUl0ZW0pLnBpcGUoXG4gICAgICAgICAgICAgIGNhdGNoRXJyb3IoKHVwbG9hZEV2ZW50OiBVcGxvYWRJdGVtRXZlbnQpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLm9uUXVldWVJdGVtRXJyb3IodXBsb2FkRXZlbnQpO1xuICAgICAgICAgICAgICAgIHJldHVybiBvZihudWxsKTtcbiAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICksXG4gICAgICAgICAgdGhpcy5jb25jdXJyZW5jeVxuICAgICAgICApLFxuICAgICAgICBmaWx0ZXIoKHVwbG9hZEV2ZW50OiBVcGxvYWRJdGVtRXZlbnQpID0+IEJvb2xlYW4odXBsb2FkRXZlbnQpKVxuICAgICAgKVxuICAgICAgLnN1YnNjcmliZSh1cGxvYWRFdmVudCA9PiB0aGlzLm9uU