angular-material-datatransfer-lib
Version:
A HTML5 datatransfer UI for handling upload and download of multiple simultaneous files.
398 lines • 34.7 kB
JavaScript
/**
* @fileoverview added by tsickle
* Generated from: lib/io/downloaders/blob.downloader.ts
* @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
import * as tslib_1 from "tslib";
import { Injectable } from '@angular/core';
import { saveAs } from 'file-saver';
import { BaseDownloader } from './base.downloader';
import { DatatransferItem } from '../../models/datatransfer-item.model';
import { ConfigService } from '../../services/config.service';
import { LoggerService } from '../../services/logger.service';
import { GuidUtil } from '../../utils/guid.util';
import { CryptoService } from '../../services/crypto.service';
import { CommonUtil } from '../../utils/common.util';
import { TransferStatus } from '../../enums/transfer-status.enum';
import { SizeContainer } from '../../models/size-container.model';
import { DecimalByteUnit } from '../../enums/decimal-byte-unit.enum';
import { ProgressContainer } from '../../models/progress-container.model';
import { TransferType } from '../../enums/transfer-type.enum';
var BlobDownloader = /** @class */ (function (_super) {
tslib_1.__extends(BlobDownloader, _super);
function BlobDownloader(logger, guidUtil, cryptoService, commonUtil) {
var _this = _super.call(this, logger, guidUtil, cryptoService) || this;
_this.logger = logger;
_this.guidUtil = guidUtil;
_this.cryptoService = cryptoService;
_this.commonUtil = commonUtil;
_this.throttleProgressCallbacks = 0.1;
_this.files = [];
_this.queue = [];
_this.downloading = [];
return _this;
}
/**
* @return {?}
*/
BlobDownloader.prototype.startAll = /**
* @return {?}
*/
function () {
if (!this.isWorking()) {
for (var index = 0; index < ConfigService.settings.core.simultaneousDownloads; index++) {
this.downloadNext();
}
}
};
/**
* @return {?}
*/
BlobDownloader.prototype.pauseAll = /**
* @return {?}
*/
function () {
};
/**
* @return {?}
*/
BlobDownloader.prototype.removeAll = /**
* @return {?}
*/
function () {
var _this = this;
this.files.forEach((/**
* @param {?} item
* @param {?} index
* @return {?}
*/
function (item, index) {
/** @type {?} */
var that = (/** @type {?} */ (_this));
that.abortDownload(item);
}));
this.files.length = 0;
this.queue.length = 0;
this.downloading.length = 0;
this._isWorking = false;
this.updateOverallSize(this.getSize());
this.updateOverallProgress(this.transferType, this.getProgress());
};
/**
* @param {?} item
* @return {?}
*/
BlobDownloader.prototype.removeItem = /**
* @param {?} item
* @return {?}
*/
function (item) {
this.abortDownload(item);
this.removeItemFromArray(item, this.files);
this.removeItemFromArray(item, this.queue);
this.removeItemFromArray(item, this.downloading);
this.downloadNext();
};
/**
* @private
* @param {?} item
* @param {?} array
* @return {?}
*/
BlobDownloader.prototype.removeItemFromArray = /**
* @private
* @param {?} item
* @param {?} array
* @return {?}
*/
function (item, array) {
for (var i = array.length - 1; i >= 0; i--) {
if (array[i] === item) {
array.splice(i, 1);
break;
}
}
};
/**
* @param {?} item
* @return {?}
*/
BlobDownloader.prototype.retryItem = /**
* @param {?} item
* @return {?}
*/
function (item) {
this.abortDownload(item);
this.removeItemFromArray(item, this.queue);
this.removeItemFromArray(item, this.downloading);
this._isWorking = this.downloading.length > 0;
item.externalItem.progress = 0;
this.updateItemProgress(item, item.externalItem.progress);
this.changeItemStatus(item, TransferStatus.Queued);
this.queue.push(item);
this.initDownload(item);
this.downloadNext();
};
/**
* @param {?} filename
* @param {?} url
* @param {?} sizeInBytes
* @return {?}
*/
BlobDownloader.prototype.download = /**
* @param {?} filename
* @param {?} url
* @param {?} sizeInBytes
* @return {?}
*/
function (filename, url, sizeInBytes) {
/** @type {?} */
var newItem = new DatatransferItem({
id: this.generateUniqueIdentifier(),
name: filename,
sizeContainer: new SizeContainer({ decimalByteUnit: DecimalByteUnit.Byte, decimalByteUnitSize: sizeInBytes }),
progressContainer: new ProgressContainer(sizeInBytes),
transferType: TransferType.Download,
status: TransferStatus.Queued,
externalItem: {
url: url,
progress: 0,
size: sizeInBytes,
lastProgressCallback: new Date()
}
});
this.addItem(newItem);
this.files.push(newItem);
this.queue.push(newItem);
this.initDownload(newItem);
this.downloadNext();
};
/**
* @private
* @param {?} item
* @return {?}
*/
BlobDownloader.prototype.initDownload = /**
* @private
* @param {?} item
* @return {?}
*/
function (item) {
/** @type {?} */
var xhr = new XMLHttpRequest();
item.externalItem.xhr = xhr;
xhr.open(ConfigService.settings.core.downloadMethod, item.externalItem.url);
xhr.timeout = ConfigService.settings.core.downloadXhrTimeout;
xhr.withCredentials = ConfigService.settings.core.downloadWithCredentials;
// Add data from header options
/** @type {?} */
var customHeaders = ConfigService.settings.core.downloadHeaders;
if (typeof customHeaders === 'function') {
customHeaders = customHeaders(item);
}
this.commonUtil.each(customHeaders, (/**
* @param {?} k
* @param {?} v
* @return {?}
*/
function (k, v) {
xhr.setRequestHeader(k, v);
}));
xhr.responseType = 'blob';
xhr.onloadstart = (/**
* @param {?} e
* @return {?}
*/
function (e) {
/** @type {?} */
var that = (/** @type {?} */ (this));
that.changeItemStatus(item, TransferStatus.Downloading);
}).bind(this);
xhr.onprogress = (/**
* @param {?} e
* @return {?}
*/
function (e) {
/** @type {?} */
var that = (/** @type {?} */ (this));
if (new Date().getTime() - item.externalItem.lastProgressCallback.getTime() > that.throttleProgressCallbacks * 1000) {
item.externalItem.progress = e.loaded / e.total;
that.updateItemProgress(item, item.externalItem.progress);
that.updateOverallProgress(that.transferType, that.getProgress());
item.externalItem.lastProgressCallback = new Date();
}
}).bind(this);
xhr.onloadend = (/**
* @param {?} e
* @return {?}
*/
function (e) {
/*
Value State Description
0 UNSENT Client has been created. open() not called yet.
1 OPENED open() has been called.
2 HEADERS_RECEIVED send() has been called, and headers and status are available.
3 LOADING Downloading; responseText holds partial data.
4 DONE The operation is complete.
*/
/** @type {?} */
var that = (/** @type {?} */ (this));
if (xhr.readyState === 4) {
item.externalItem.progress = 1;
that.updateItemProgress(item, item.externalItem.progress);
if (xhr.status === 200) {
that.changeItemStatus(item, TransferStatus.Finished);
saveAs(xhr.response, item.name);
}
else if (xhr.status !== 0) { // don't change status for aborted items
that.changeItemStatus(item, TransferStatus.Failed);
}
that.removeItemFromArray(item, that.downloading);
that.downloadNext();
}
}).bind(this);
};
/**
* @private
* @return {?}
*/
BlobDownloader.prototype.downloadNext = /**
* @private
* @return {?}
*/
function () {
this.updateOverallSize(this.getSize());
this.updateOverallProgress(this.transferType, this.getProgress());
if (this.downloading.length < ConfigService.settings.core.simultaneousDownloads) {
/** @type {?} */
var item = this.queue.shift();
if (!!item && !!item.externalItem && !!item.externalItem.xhr) {
this.changeItemStatus(item, TransferStatus.Downloading);
this.downloading.push(item);
this._isWorking = this.downloading.length > 0;
item.externalItem.xhr.send();
}
}
};
/**
* @private
* @param {?} item
* @return {?}
*/
BlobDownloader.prototype.abortDownload = /**
* @private
* @param {?} item
* @return {?}
*/
function (item) {
if (!!item && !!item.externalItem && !!item.externalItem.xhr) {
item.externalItem.xhr.abort();
item.externalItem.xhr = null;
}
};
/**
* @private
* @return {?}
*/
BlobDownloader.prototype.getSize = /**
* @private
* @return {?}
*/
function () {
/** @type {?} */
var totalSize = 0;
this.files.forEach((/**
* @param {?} file
* @param {?} index
* @return {?}
*/
function (file, index) {
totalSize += file.externalItem.size;
}));
return totalSize;
};
/**
* @private
* @return {?}
*/
BlobDownloader.prototype.getProgress = /**
* @private
* @return {?}
*/
function () {
/** @type {?} */
var totalDone = 0;
/** @type {?} */
var totalSize = 0;
this.files.forEach((/**
* @param {?} file
* @param {?} index
* @return {?}
*/
function (file, index) {
/** @type {?} */
var currentFileProgress = file.externalItem.progress;
if (file.status === TransferStatus.Failed) {
currentFileProgress = 1;
}
totalDone += currentFileProgress * file.externalItem.size;
totalSize += file.externalItem.size;
}));
return totalSize > 0 ? totalDone / totalSize : 0;
};
BlobDownloader.decorators = [
{ type: Injectable }
];
/** @nocollapse */
BlobDownloader.ctorParameters = function () { return [
{ type: LoggerService },
{ type: GuidUtil },
{ type: CryptoService },
{ type: CommonUtil }
]; };
return BlobDownloader;
}(BaseDownloader));
export { BlobDownloader };
if (false) {
/**
* @type {?}
* @private
*/
BlobDownloader.prototype.throttleProgressCallbacks;
/**
* @type {?}
* @private
*/
BlobDownloader.prototype.files;
/**
* @type {?}
* @private
*/
BlobDownloader.prototype.queue;
/**
* @type {?}
* @private
*/
BlobDownloader.prototype.downloading;
/**
* @type {?}
* @protected
*/
BlobDownloader.prototype.logger;
/**
* @type {?}
* @protected
*/
BlobDownloader.prototype.guidUtil;
/**
* @type {?}
* @protected
*/
BlobDownloader.prototype.cryptoService;
/**
* @type {?}
* @private
*/
BlobDownloader.prototype.commonUtil;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmxvYi5kb3dubG9hZGVyLmpzIiwic291cmNlUm9vdCI6Im5nOi8vYW5ndWxhci1tYXRlcmlhbC1kYXRhdHJhbnNmZXItbGliLyIsInNvdXJjZXMiOlsibGliL2lvL2Rvd25sb2FkZXJzL2Jsb2IuZG93bmxvYWRlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7QUFBQSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQzNDLE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSxZQUFZLENBQUM7QUFDcEMsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLG1CQUFtQixDQUFDO0FBQ25ELE9BQU8sRUFBcUIsZ0JBQWdCLEVBQUUsTUFBTSxzQ0FBc0MsQ0FBQztBQUMzRixPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sK0JBQStCLENBQUM7QUFDOUQsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLCtCQUErQixDQUFDO0FBQzlELE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUNqRCxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sK0JBQStCLENBQUM7QUFDOUQsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBQ3JELE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSxrQ0FBa0MsQ0FBQztBQUNsRSxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sbUNBQW1DLENBQUM7QUFDbEUsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLG9DQUFvQyxDQUFDO0FBQ3JFLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLHVDQUF1QyxDQUFDO0FBQzFFLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxnQ0FBZ0MsQ0FBQztBQUU5RDtJQUNvQywwQ0FBYztJQU85Qyx3QkFBc0IsTUFBcUIsRUFBWSxRQUFrQixFQUNuRCxhQUE0QixFQUFVLFVBQXNCO1FBRGxGLFlBRUksa0JBQU0sTUFBTSxFQUFFLFFBQVEsRUFBRSxhQUFhLENBQUMsU0FD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Q0QsU0FBUyxJQUFJLG1CQUFtQixHQUFHLElBQUksQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDO1lBQzFELFNBQVMsSUFBSSxJQUFJLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQztRQUN4QyxDQUFDLEVBQUMsQ0FBQztRQUNILE9BQU8sU0FBUyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsU0FBUyxHQUFHLFNBQVMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ3JELENBQUM7O2dCQTVMSixVQUFVOzs7O2dCQVZGLGFBQWE7Z0JBQ2IsUUFBUTtnQkFDUixhQUFhO2dCQUNiLFVBQVU7O0lBb01uQixxQkFBQztDQUFBLEFBN0xELENBQ29DLGNBQWMsR0E0TGpEO1NBNUxZLGNBQWM7Ozs7OztJQUV2QixtREFBd0M7Ozs7O0lBQ3hDLCtCQUF3Qzs7Ozs7SUFDeEMsK0JBQXdDOzs7OztJQUN4QyxxQ0FBOEM7Ozs7O0lBRWxDLGdDQUErQjs7Ozs7SUFBRSxrQ0FBNEI7Ozs7O0lBQzdELHVDQUFzQzs7Ozs7SUFBRSxvQ0FBOEIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBJbmplY3RhYmxlIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcbmltcG9ydCB7IHNhdmVBcyB9IGZyb20gJ2ZpbGUtc2F2ZXInO1xyXG5pbXBvcnQgeyBCYXNlRG93bmxvYWRlciB9IGZyb20gJy4vYmFzZS5kb3dubG9hZGVyJztcclxuaW1wb3J0IHsgSURhdGF0cmFuc2Zlckl0ZW0sIERhdGF0cmFuc2Zlckl0ZW0gfSBmcm9tICcuLi8uLi9tb2RlbHMvZGF0YXRyYW5zZmVyLWl0ZW0ubW9kZWwnO1xyXG5pbXBvcnQgeyBDb25maWdTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vc2VydmljZXMvY29uZmlnLnNlcnZpY2UnO1xyXG5pbXBvcnQgeyBMb2dnZXJTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vc2VydmljZXMvbG9nZ2VyLnNlcnZpY2UnO1xyXG5pbXBvcnQgeyBHdWlkVXRpbCB9IGZyb20gJy4uLy4uL3V0aWxzL2d1aWQudXRpbCc7XHJcbmltcG9ydCB7IENyeXB0b1NlcnZpY2UgfSBmcm9tICcuLi8uLi9zZXJ2aWNlcy9jcnlwdG8uc2VydmljZSc7XHJcbmltcG9ydCB7IENvbW1vblV0aWwgfSBmcm9tICcuLi8uLi91dGlscy9jb21tb24udXRpbCc7XHJcbmltcG9ydCB7IFRyYW5zZmVyU3RhdHVzIH0gZnJvbSAnLi4vLi4vZW51bXMvdHJhbnNmZXItc3RhdHVzLmVudW0nO1xyXG5pbXBvcnQgeyBTaXplQ29udGFpbmVyIH0gZnJvbSAnLi4vLi4vbW9kZWxzL3NpemUtY29udGFpbmVyLm1vZGVsJztcclxuaW1wb3J0IHsgRGVjaW1hbEJ5dGVVbml0IH0gZnJvbSAnLi4vLi4vZW51bXMvZGVjaW1hbC1ieXRlLXVuaXQuZW51bSc7XHJcbmltcG9ydCB7IFByb2dyZXNzQ29udGFpbmVyIH0gZnJvbSAnLi4vLi4vbW9kZWxzL3Byb2dyZXNzLWNvbnRhaW5lci5tb2RlbCc7XHJcbmltcG9ydCB7IFRyYW5zZmVyVHlwZSB9IGZyb20gJy4uLy4uL2VudW1zL3RyYW5zZmVyLXR5cGUuZW51bSc7XHJcblxyXG5ASW5qZWN0YWJsZSgpXHJcbmV4cG9ydCBjbGFzcyBCbG9iRG93bmxvYWRlciBleHRlbmRzIEJhc2VEb3dubG9hZGVyIHtcclxuXHJcbiAgICBwcml2YXRlIHRocm90dGxlUHJvZ3Jlc3NDYWxsYmFja3MgPSAwLjE7XHJcbiAgICBwcml2YXRlIGZpbGVzOiBJRGF0YXRyYW5zZmVySXRlbVtdID0gW107XHJcbiAgICBwcml2YXRlIHF1ZXVlOiBJRGF0YXRyYW5zZmVySXRlbVtdID0gW107XHJcbiAgICBwcml2YXRlIGRvd25sb2FkaW5nOiBJRGF0YXRyYW5zZmVySXRlbVtdID0gW107XHJcblxyXG4gICAgY29uc3RydWN0b3IocHJvdGVjdGVkIGxvZ2dlcjogTG9nZ2VyU2VydmljZSwgcHJvdGVjdGVkIGd1aWRVdGlsOiBHdWlkVXRpbCxcclxuICAgICAgICAgICAgICAgIHByb3RlY3RlZCBjcnlwdG9TZXJ2aWNlOiBDcnlwdG9TZXJ2aWNlLCBwcml2YXRlIGNvbW1vblV0aWw6IENvbW1vblV0aWwpIHtcclxuICAgICAgICBzdXBlcihsb2dnZXIsIGd1aWRVdGlsLCBjcnlwdG9TZXJ2aWNlKTtcclxuICAgIH1cclxuXHJcbiAgICBwdWJsaWMgc3RhcnRBbGwoKTogdm9pZCB7XHJcbiAgICAgICAgaWYgKCF0aGlzLmlzV29ya2luZygpKSB7XHJcbiAgICAgICAgICAgIGZvciAobGV0IGluZGV4ID0gMDsgaW5kZXggPCBDb25maWdTZXJ2aWNlLnNldHRpbmdzLmNvcmUuc2ltdWx0YW5lb3VzRG93bmxvYWRzOyBpbmRleCsrKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmRvd25sb2FkTmV4dCgpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyBwYXVzZUFsbCgpOiB2b2lkIHtcclxuXHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIHJlbW92ZUFsbCgpOiB2b2lkIHtcclxuICAgICAgICB0aGlzLmZpbGVzLmZvckVhY2goKGl0ZW0sIGluZGV4KSA9PiB7XHJcbiAgICAgICAgICAgIGNvbnN0IHRoYXQgPSB0aGlzIGFzIEJsb2JEb3dubG9hZGVyO1xyXG4gICAgICAgICAgICB0aGF0LmFib3J0RG93bmxvYWQoaXRlbSk7XHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgdGhpcy5maWxlcy5sZW5ndGggPSAwO1xyXG4gICAgICAgIHRoaXMucXVldWUubGVuZ3RoID0gMDtcclxuICAgICAgICB0aGlzLmRvd25sb2FkaW5nLmxlbmd0aCA9IDA7XHJcbiAgICAgICAgdGhpcy5faXNXb3JraW5nID0gZmFsc2U7XHJcbiAgICAgICAgdGhpcy51cGRhdGVPdmVyYWxsU2l6ZSh0aGlzLmdldFNpemUoKSk7XHJcbiAgICAgICAgdGhpcy51cGRhdGVPdmVyYWxsUHJvZ3Jlc3ModGhpcy50cmFuc2ZlclR5cGUsIHRoaXMuZ2V0UHJvZ3Jlc3MoKSk7XHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIHJlbW92ZUl0ZW0oaXRlbTogSURhdGF0cmFuc2Zlckl0ZW0pOiB2b2lkIHtcclxuICAgICAgICB0aGlzLmFib3J0RG93bmxvYWQoaXRlbSk7XHJcbiAgICAgICAgdGhpcy5yZW1vdmVJdGVtRnJvbUFycmF5KGl0ZW0sIHRoaXMuZmlsZXMpO1xyXG4gICAgICAgIHRoaXMucmVtb3ZlSXRlbUZyb21BcnJheShpdGVtLCB0aGlzLnF1ZXVlKTtcclxuICAgICAgICB0aGlzLnJlbW92ZUl0ZW1Gcm9tQXJyYXkoaXRlbSwgdGhpcy5kb3dubG9hZGluZyk7XHJcbiAgICAgICAgdGhpcy5kb3dubG9hZE5leHQoKTtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIHJlbW92ZUl0ZW1Gcm9tQXJyYXkoaXRlbTogSURhdGF0cmFuc2Zlckl0ZW0sIGFycmF5OiBJRGF0YXRyYW5zZmVySXRlbVtdKTogdm9pZCB7XHJcbiAgICAgICAgZm9yIChsZXQgaSA9IGFycmF5Lmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XHJcbiAgICAgICAgICAgIGlmIChhcnJheVtpXSA9PT0gaXRlbSkge1xyXG4gICAgICAgICAgICAgICAgYXJyYXkuc3BsaWNlKGksIDEpO1xyXG4gICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIHJldHJ5SXRlbShpdGVtOiBJRGF0YXRyYW5zZmVySXRlbSk6IHZvaWQge1xyXG4gICAgICAgIHRoaXMuYWJvcnREb3dubG9hZChpdGVtKTtcclxuICAgICAgICB0aGlzLnJlbW92ZUl0ZW1Gcm9tQXJyYXkoaXRlbSwgdGhpcy5xdWV1ZSk7XHJcbiAgICAgICAgdGhpcy5yZW1vdmVJdGVtRnJvbUFycmF5KGl0ZW0sIHRoaXMuZG93bmxvYWRpbmcpO1xyXG4gICAgICAgIHRoaXMuX2lzV29ya2luZyA9IHRoaXMuZG93bmxvYWRpbmcubGVuZ3RoID4gMDtcclxuICAgICAgICBpdGVtLmV4dGVybmFsSXRlbS5wcm9ncmVzcyA9IDA7XHJcbiAgICAgICAgdGhpcy51cGRhdGVJdGVtUHJvZ3Jlc3MoaXRlbSwgaXRlbS5leHRlcm5hbEl0ZW0ucHJvZ3Jlc3MpO1xyXG4gICAgICAgIHRoaXMuY2hhbmdlSXRlbVN0YXR1cyhpdGVtLCBUcmFuc2ZlclN0YXR1cy5RdWV1ZWQpO1xyXG4gICAgICAgIHRoaXMucXVldWUucHVzaChpdGVtKTtcclxuICAgICAgICB0aGlzLmluaXREb3dubG9hZChpdGVtKTtcclxuICAgICAgICB0aGlzLmRvd25sb2FkTmV4dCgpO1xyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyBkb3dubG9hZChmaWxlbmFtZTogc3RyaW5nLCB1cmw6IHN0cmluZywgc2l6ZUluQnl0ZXM6IG51bWJlcik6IHZvaWQge1xyXG4gICAgICAgIGNvbnN0IG5ld0l0ZW0gPSBuZXcgRGF0YXRyYW5zZmVySXRlbSh7XHJcbiAgICAgICAgICAgIGlkOiB0aGlzLmdlbmVyYXRlVW5pcXVlSWRlbnRpZmllcigpLFxyXG4gICAgICAgICAgICBuYW1lOiBmaWxlbmFtZSxcclxuICAgICAgICAgICAgc2l6ZUNvbnRhaW5lcjogbmV3IFNpemVDb250YWluZXIoeyBkZWNpbWFsQnl0ZVVuaXQ6IERlY2ltYWxCeXRlVW5pdC5CeXRlLCBkZWNpbWFsQnl0ZVVuaXRTaXplOiBzaXplSW5CeXRlcyB9KSxcclxuICAgICAgICAgICAgcHJvZ3Jlc3NDb250YWluZXI6IG5ldyBQcm9ncmVzc0NvbnRhaW5lcihzaXplSW5CeXRlcyksXHJcbiAgICAgICAgICAgIHRyYW5zZmVyVHlwZTogVHJhbnNmZXJUeXBlLkRvd25sb2FkLFxyXG4gICAgICAgICAgICBzdGF0dXM6IFRyYW5zZmVyU3RhdHVzLlF1ZXVlZCxcclxuICAgICAgICAgICAgZXh0ZXJuYWxJdGVtOiB7XHJcbiAgICAgICAgICAgICAgICB1cmwsXHJcbiAgICAgICAgICAgICAgICBwcm9ncmVzczogMCxcclxuICAgICAgICAgICAgICAgIHNpemU6IHNpemVJbkJ5dGVzLFxyXG4gICAgICAgICAgICAgICAgbGFzdFByb2dyZXNzQ2FsbGJhY2s6IG5ldyBEYXRlKClcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0pO1xyXG5cclxuICAgICAgICB0aGlzLmFkZEl0ZW0obmV3SXRlbSk7XHJcbiAgICAgICAgdGhpcy5maWxlcy5wdXNoKG5ld0l0ZW0pO1xyXG4gICAgICAgIHRoaXMucXVldWUucHVzaChuZXdJdGVtKTtcclxuICAgICAgICB0aGlzLmluaXREb3dubG9hZChuZXdJdGVtKTtcclxuICAgICAgICB0aGlzLmRvd25sb2FkTmV4dCgpO1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgaW5pdERvd25sb2FkKGl0ZW06IElEYXRhdHJhbnNmZXJJdGVtKTogdm9pZCB7XHJcbiAgICAgICAgY29uc3QgeGhyID0gbmV3IFhNTEh0dHBSZXF1ZXN0KCk7XHJcbiAgICAgICAgaXRlbS5leHRlcm5hbEl0ZW0ueGhyID0geGhyO1xyXG5cclxuICAgICAgICB4aHIub3BlbihDb25maWdTZXJ2aWNlLnNldHRpbmdzLmNvcmUuZG93bmxvYWRNZXRob2QsIGl0ZW0uZXh0ZXJuYWxJdGVtLnVybCk7XHJcbiAgICAgICAgeGhyLnRpbWVvdXQgPSBDb25maWdTZXJ2aWNlLnNldHRpbmdzLmNvcmUuZG93bmxvYWRYaHJUaW1lb3V0O1xyXG4gICAgICAgIHhoci53aXRoQ3JlZGVudGlhbHMgPSBDb25maWdTZXJ2aWNlLnNldHRpbmdzLmNvcmUuZG93bmxvYWRXaXRoQ3JlZGVudGlhbHM7XHJcblxyXG4gICAgICAgIC8vIEFkZCBkYXRhIGZyb20gaGVhZGVyIG9wdGlvbnNcclxuICAgICAgICBsZXQgY3VzdG9tSGVhZGVycyA9IENvbmZpZ1NlcnZpY2Uuc2V0dGluZ3MuY29yZS5kb3dubG9hZEhlYWRlcnM7XHJcbiAgICAgICAgaWYgKHR5cGVvZiBjdXN0b21IZWFkZXJzID09PSAnZnVuY3Rpb24nKSB7XHJcbiAgICAgICAgICAgIGN1c3RvbUhlYWRlcnMgPSBjdXN0b21IZWFkZXJzKGl0ZW0pO1xyXG4gICAgICAgIH1cclxuICAgICAgICB0aGlzLmNvbW1vblV0aWwuZWFjaChjdXN0b21IZWFkZXJzLCBmdW5jdGlvbihrOiBzdHJpbmcsIHY6IHN0cmluZykge1xyXG4gICAgICAgICAgICB4aHIuc2V0UmVxdWVzdEhlYWRlcihrLCB2KTtcclxuICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgeGhyLnJlc3BvbnNlVHlwZSA9ICdibG9iJztcclxuICAgICAgICB4aHIub25sb2Fkc3RhcnQgPSBmdW5jdGlvbihlKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IHRoYXQgPSB0aGlzIGFzIEJsb2JEb3dubG9hZGVyO1xyXG4gICAgICAgICAgICB0aGF0LmNoYW5nZUl0ZW1TdGF0dXMoaXRlbSwgVHJhbnNmZXJTdGF0dXMuRG93bmxvYWRpbmcpO1xyXG4gICAgICAgIH0uYmluZCh0aGlzKTtcclxuICAgICAgICB4aHIub25wcm9ncmVzcyA9IGZ1bmN0aW9uKGUpIHtcclxuICAgICAgICAgICAgY29uc3QgdGhhdCA9IHRoaXMgYXMgQmxvYkRvd25sb2FkZXI7XHJcbiAgICAgICAgICAgIGlmIChuZXcgRGF0ZSgpLmdldFRpbWUoKSAtIGl0ZW0uZXh0ZXJuYWxJdGVtLmxhc3RQcm9ncmVzc0NhbGxiYWNrLmdldFRpbWUoKSA+IHRoYXQudGhyb3R0bGVQcm9ncmVzc0NhbGxiYWNrcyAqIDEwMDApIHtcclxuICAgICAgICAgICAgICAgIGl0ZW0uZXh0ZXJuYWxJdGVtLnByb2dyZXNzID0gZS5sb2FkZWQgLyBlLnRvdGFsO1xyXG4gICAgICAgICAgICAgICAgdGhhdC51cGRhdGVJdGVtUHJvZ3Jlc3MoaXRlbSwgaXRlbS5leHRlcm5hbEl0ZW0ucHJvZ3Jlc3MpO1xyXG4gICAgICAgICAgICAgICAgdGhhdC51cGRhdGVPdmVyYWxsUHJvZ3Jlc3ModGhhdC50cmFuc2ZlclR5cGUsIHRoYXQuZ2V0UHJvZ3Jlc3MoKSk7XHJcbiAgICAgICAgICAgICAgICBpdGVtLmV4dGVybmFsSXRlbS5sYXN0UHJvZ3Jlc3NDYWxsYmFjayA9IG5ldyBEYXRlKCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9LmJpbmQodGhpcyk7XHJcbiAgICAgICAgeGhyLm9ubG9hZGVuZCA9IGZ1bmN0aW9uKGUpIHtcclxuICAgICAgICAgICAgLypcclxuICAgICAgICAgICAgVmFsdWVcdFN0YXRlXHREZXNjcmlwdGlvblxyXG4gICAgICAgICAgICAwXHRVTlNFTlRcdENsaWVudCBoYXMgYmVlbiBjcmVhdGVkLiBvcGVuKCkgbm90IGNhbGxlZCB5ZXQuXHJcbiAgICAgICAgICAgIDFcdE9QRU5FRFx0b3BlbigpIGhhcyBiZWVuIGNhbGxlZC5cclxuICAgICAgICAgICAgMlx0SEVBREVSU19SRUNFSVZFRFx0c2VuZCgpIGhhcyBiZWVuIGNhbGxlZCwgYW5kIGhlYWRlcnMgYW5kIHN0YXR1cyBhcmUgYXZhaWxhYmxlLlxyXG4gICAgICAgICAgICAzXHRMT0FESU5HXHREb3dubG9hZGluZzsgcmVzcG9uc2VUZXh0IGhvbGRzIHBhcnRpYWwgZGF0YS5cclxuICAgICAgICAgICAgNFx0RE9ORVx0VGhlIG9wZXJhdGlvbiBpcyBjb21wbGV0ZS5cclxuICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgY29uc3QgdGhhdCA9IHRoaXMgYXMgQmxvYkRvd25sb2FkZXI7XHJcbiAgICAgICAgICAgIGlmICh4aHIucmVhZHlTdGF0ZSA9PT0gNCkge1xyXG4gICAgICAgICAgICAgICAgaXRlbS5leHRlcm5hbEl0ZW0ucHJvZ3Jlc3MgPSAxO1xyXG4gICAgICAgICAgICAgICAgdGhhdC51cGRhdGVJdGVtUHJvZ3Jlc3MoaXRlbSwgaXRlbS5leHRlcm5hbEl0ZW0ucHJvZ3Jlc3MpO1xyXG4gICAgICAgICAgICAgICAgaWYgKHhoci5zdGF0dXMgPT09IDIwMCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHRoYXQuY2hhbmdlSXRlbVN0YXR1cyhpdGVtLCBUcmFuc2ZlclN0YXR1cy5GaW5pc2hlZCk7XHJcbiAgICAgICAgICAgICAgICAgICAgc2F2ZUFzKHhoci5yZXNwb25zZSwgaXRlbS5uYW1lKTtcclxuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoeGhyLnN0YXR1cyAhPT0gMCkgeyAvLyBkb24ndCBjaGFuZ2Ugc3RhdHVzIGZvciBhYm9ydGVkIGl0ZW1zXHJcbiAgICAgICAgICAgICAgICAgICAgdGhhdC5jaGFuZ2VJdGVtU3RhdHVzKGl0ZW0sIFRyYW5zZmVyU3RhdHVzLkZhaWxlZCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB0aGF0LnJlbW92ZUl0ZW1Gcm9tQXJyYXkoaXRlbSwgdGhhdC5kb3dubG9hZGluZyk7XHJcbiAgICAgICAgICAgICAgICB0aGF0LmRvd25sb2FkTmV4dCgpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfS5iaW5kKHRoaXMpO1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgZG93bmxvYWROZXh0KCk6IHZvaWQge1xyXG4gICAgICAgIHRoaXMudXBkYXRlT3ZlcmFsbFNpemUodGhpcy5nZXRTaXplKCkpO1xyXG4gICAgICAgIHRoaXMudXBkYXRlT3ZlcmFsbFByb2dyZXNzKHRoaXMudHJhbnNmZXJUeXBlLCB0aGlzLmdldFByb2dyZXNzKCkpO1xyXG4gICAgICAgIGlmICh0aGlzLmRvd25sb2FkaW5nLmxlbmd0aCA8IENvbmZpZ1NlcnZpY2Uuc2V0dGluZ3MuY29yZS5zaW11bHRhbmVvdXNEb3dubG9hZHMpIHtcclxuICAgICAgICAgICAgY29uc3QgaXRlbSA9IHRoaXMucXVldWUuc2hpZnQoKTtcclxuICAgICAgICAgICAgaWYgKCEhaXRlbSAmJiAhIWl0ZW0uZXh0ZXJuYWxJdGVtICYmICEhaXRlbS5leHRlcm5hbEl0ZW0ueGhyKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmNoYW5nZUl0ZW1TdGF0dXMoaXRlbSwgVHJhbnNmZXJTdGF0dXMuRG93bmxvYWRpbmcpO1xyXG4gICAgICAgICAgICAgICAgdGhpcy5kb3dubG9hZGluZy5wdXNoKGl0ZW0pO1xyXG4gICAgICAgICAgICAgICAgdGhpcy5faXNXb3JraW5nID0gdGhpcy5kb3dubG9hZGluZy5sZW5ndGggPiAwO1xyXG4gICAgICAgICAgICAgICAgaXRlbS5leHRlcm5hbEl0ZW0ueGhyLnNlbmQoKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIGFib3J0RG93bmxvYWQoaXRlbTogSURhdGF0cmFuc2Zlckl0ZW0pOiB2b2lkIHtcclxuICAgICAgICBpZiAoISFpdGVtICYmICEhaXRlbS5leHRlcm5hbEl0ZW0gJiYgISFpdGVtLmV4dGVybmFsSXRlbS54aHIpIHtcclxuICAgICAgICAgICAgaXRlbS5leHRlcm5hbEl0ZW0ueGhyLmFib3J0KCk7XHJcbiAgICAgICAgICAgIGl0ZW0uZXh0ZXJuYWxJdGVtLnhociA9IG51bGw7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgZ2V0U2l6ZSgpOiBudW1iZXIge1xyXG4gICAgICAgIGxldCB0b3RhbFNpemUgPSAwO1xyXG4gICAgICAgIHRoaXMuZmlsZXMuZm9yRWFjaCgoZmlsZSwgaW5kZXgpID0+IHtcclxuICAgICAgICAgICAgdG90YWxTaXplICs9IGZpbGUuZXh0ZXJuYWxJdGVtLnNpemU7XHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgcmV0dXJuIHRvdGFsU2l6ZTtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIGdldFByb2dyZXNzKCk6IG51bWJlciB7XHJcbiAgICAgICAgbGV0IHRvdGFsRG9uZSA9IDA7XHJcbiAgICAgICAgbGV0IHRvdGFsU2l6ZSA9IDA7XHJcbiAgICAgICAgdGhpcy5maWxlcy5mb3JFYWNoKChmaWxlLCBpbmRleCkgPT4ge1xyXG4gICAgICAgICAgICBsZXQgY3VycmVudEZpbGVQcm9ncmVzcyA9IGZpbGUuZXh0ZXJuYWxJdGVtLnByb2dyZXNzO1xyXG4gICAgICAgICAgICBpZiAoZmlsZS5zdGF0dXMgPT09IFRyYW5zZmVyU3RhdHVzLkZhaWxlZCkge1xyXG4gICAgICAgICAgICAgICAgY3VycmVudEZpbGVQcm9ncmVzcyA9IDE7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgdG90YWxEb25lICs9IGN1cnJlbnRGaWxlUHJvZ3Jlc3MgKiBmaWxlLmV4dGVybmFsSXRlbS5zaXplO1xyXG4gICAgICAgICAgICB0b3RhbFNpemUgKz0gZmlsZS5leHRlcm5hbEl0ZW0uc2l6ZTtcclxuICAgICAgICB9KTtcclxuICAgICAgICByZXR1cm4gdG90YWxTaXplID4gMCA/IHRvdGFsRG9uZSAvIHRvdGFsU2l6ZSA6IDA7XHJcbiAgICB9XHJcbn1cclxuIl19