ngx-uploadx
Version:
Angular Resumable Upload Module
290 lines • 36.6 kB
JavaScript
import { Canceler } from './canceler';
import { DynamicChunk } from './dynamic-chunk';
import { ErrorType, RetryHandler } from './retry-handler';
import { store } from './store';
import { isNumber, unfunc } from './utils';
const actionToStatusMap = {
pause: 'paused',
upload: 'queue',
cancel: 'cancelled',
update: 'updated'
};
/**
* Uploader Base Class
*/
export class Uploader {
file;
options;
stateChange;
ajax;
name;
size;
uploadId;
response = null;
responseStatus = 0;
responseHeaders = {};
progress = 0;
remaining;
speed = 0;
/** Custom headers */
headers = {};
/** Metadata Object */
metadata;
/** Upload endpoint */
endpoint = '/upload';
/** Chunk size in bytes */
chunkSize = 0;
/** Auth token/tokenGetter */
token;
/** Byte offset within the whole file */
offset;
/** Retries handler */
retry;
canceler = new Canceler();
abortController = new AbortController();
/** Set HttpRequest responseType */
responseType;
_authorize;
_prerequest;
_token;
_eventsCount = 0;
constructor(file, options, stateChange, ajax) {
this.file = file;
this.options = options;
this.stateChange = stateChange;
this.ajax = ajax;
this.retry = new RetryHandler(options.retryConfig);
this.name = file.name;
this.size = file.size;
this.metadata = {
name: file.name,
mimeType: file.type || 'application/octet-stream',
size: file.size,
lastModified: file.lastModified
};
options.maxChunkSize && (DynamicChunk.maxSize = options.maxChunkSize);
/** A function that is executed before the request is sent */
this._prerequest = options.prerequest || (req => req);
/** A function used to authorize the request */
this._authorize = options.authorize || (req => req);
this.configure(options);
}
_url = '';
get url() {
return this._url || store.get(this.uploadId) || '';
}
set url(value) {
this._url !== value && store.set(this.uploadId, value);
this._url = value;
}
_status;
get status() {
return this._status;
}
set status(s) {
if (s !== 'updated' && s !== 'cancelled') {
if (this._status === s)
return;
if (this._status === 'complete')
return;
}
if (this._status === 'cancelled')
return;
if (this._status === 'uploading' && s === 'queue')
return;
if (this._status === 'retry')
this.retry.cancel();
this._status = s;
if (s === 'paused')
this.abort();
if (s === 'cancelled' || s === 'complete' || s === 'error')
this.cleanup();
if (s === 'cancelled')
this.cancelAndSendState();
else if (s === 'updated')
this.updateAndSendState();
else
this.stateChange(this);
}
/**
* Configure uploader
*/
configure({ metadata, headers, token, endpoint, action }) {
endpoint && (this.endpoint = endpoint);
token && (this.token = token);
metadata && Object.assign(this.metadata, unfunc(metadata, this.file));
headers && Object.assign(this.headers, unfunc(headers, this.file));
action && (this.status = actionToStatusMap[action]);
}
/**
* Starts uploading
*/
async upload() {
do {
this.status = 'uploading';
try {
this._token ||= await this.updateToken();
this.url ||= await this.getFileUrl();
if (this.offset !== this.size) {
this.offset = isNumber(this.offset)
? await this.sendFileContent()
: await this.getOffset();
}
this.retry.observe(this.offset);
if (this.offset === this.size) {
this.remaining = 0;
this.progress = 100;
this.status = 'complete';
}
else if (!isNumber(this.offset)) {
this.stateChange(this);
await this.retry.wait(this.getRetryAfterFromBackend() || this.retry.config.onBusyDelay);
}
}
catch (e) {
e instanceof Error && console.error(e);
if (this.status !== 'uploading') {
return;
}
switch (this.retry.kind(this.responseStatus)) {
case ErrorType.Fatal:
this.status = 'error';
return;
case ErrorType.NotFound:
this.url = '';
break;
case ErrorType.Auth:
this._token = '';
break;
default:
if (unfunc(this.retry.config.keepPartial, this.responseStatus)) {
this.offset = undefined;
}
this.status = 'retry';
await this.retry.wait(this.getRetryAfterFromBackend());
}
}
} while (['uploading', 'retry', 'updated'].includes(this._status));
}
/**
* Performs http requests
*/
async request(requestOptions) {
this.responseStatus = 0;
this.response = null;
this.responseHeaders = {};
if (this.abortController.signal.aborted) {
this.abortController = new AbortController();
}
const signal = requestOptions.signal || this.abortController.signal;
let req = {
body: requestOptions.body || null,
canceler: this.canceler,
signal,
headers: { ...this.headers, ...requestOptions.headers },
method: requestOptions.method || 'GET',
url: requestOptions.url || this.url
};
if (!requestOptions.skipAuthorization) {
req = await this._authorize(req, this._token);
}
const { body = null, headers, method, url = req.url } = (await this._prerequest(req)) || req;
const ajaxRequestConfig = {
method,
headers: { ...req.headers, ...headers },
url,
data: body,
responseType: this.options.responseType ?? this.responseType,
withCredentials: !!this.options.withCredentials,
canceler: this.canceler,
signal,
validateStatus: () => true,
timeout: this.retry.config.timeout
};
if (isNumber(this.offset) && body && typeof body === 'object') {
ajaxRequestConfig.onUploadProgress = this.onProgress();
}
const response = await this.ajax.request(ajaxRequestConfig);
this.response = response.data;
this.responseHeaders = response.headers;
this.responseStatus = response.status;
if (response.status >= 400) {
return Promise.reject();
}
}
/**
* Set auth token string
*/
updateToken = () => {
return unfunc(this.token || '', this.responseStatus);
};
/**
* Updating the metadata of the upload
*/
update(_data) {
return Promise.reject('Not implemented');
}
abort() {
this.offset = undefined;
this.abortController.abort();
this.canceler.cancel();
}
async cancel() {
this.abort();
if (this.url) {
await this.request({ method: 'DELETE' }).catch(() => { });
}
}
/**
* Gets the value from the response
*/
getValueFromResponse(key) {
return this.responseHeaders[key.toLowerCase()] || null;
}
/**
* Get file chunk
* @param offset - number of bytes of the file to skip
* @param size - chunk size
*/
getChunk(offset, size) {
if (this.responseStatus === 413) {
DynamicChunk.maxSize = DynamicChunk.size = Math.floor(DynamicChunk.size / 2);
}
this.chunkSize =
this.options.chunkSize === 0 ? this.size : this.options.chunkSize || DynamicChunk.size;
const start = offset ?? this.offset ?? 0;
const end = Math.min(start + (size || this.chunkSize), this.size);
const body = this.file.slice(start, end);
return { start, end, body };
}
getRetryAfterFromBackend() {
return Number(this.getValueFromResponse('retry-after')) * 1000;
}
cancelAndSendState() {
this.cancel().then(() => this.stateChange(this), console.error);
}
updateAndSendState() {
this.update({ metadata: this.metadata }).then(() => this.stateChange(this), console.error);
}
cleanup = () => {
store.delete(this._url);
store.delete(this.uploadId);
};
onProgress() {
let throttle;
const startTime = Date.now();
return ({ loaded }) => {
const current = loaded / ((Date.now() - startTime) / 1000);
this.speed = ~~((this.speed * this._eventsCount + current) / ++this._eventsCount);
DynamicChunk.scale(this.speed);
if (!throttle) {
throttle = setTimeout(() => (throttle = undefined), 500);
const uploaded = (this.offset || 0) + loaded;
this.progress = +((uploaded / this.size) * 100).toFixed(2);
this.remaining = ~~((this.size - uploaded) / this.speed);
this.stateChange(this);
}
};
}
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXBsb2FkZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvdXBsb2FkeC9saWIvdXBsb2FkZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQ0EsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLFlBQVksQ0FBQztBQUN0QyxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFlL0MsT0FBTyxFQUFFLFNBQVMsRUFBRSxZQUFZLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUMxRCxPQUFPLEVBQUUsS0FBSyxFQUFFLE1BQU0sU0FBUyxDQUFDO0FBQ2hDLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxFQUFFLE1BQU0sU0FBUyxDQUFDO0FBRTNDLE1BQU0saUJBQWlCLEdBQTBDO0lBQy9ELEtBQUssRUFBRSxRQUFRO0lBQ2YsTUFBTSxFQUFFLE9BQU87SUFDZixNQUFNLEVBQUUsV0FBVztJQUNuQixNQUFNLEVBQUUsU0FBUztDQUNsQixDQUFDO0FBRUY7O0dBRUc7QUFDSCxNQUFNLE9BQWdCLFFBQVE7SUFrQ2pCO0lBQ0E7SUFDQTtJQUNBO0lBcENYLElBQUksQ0FBUztJQUNKLElBQUksQ0FBUztJQUNiLFFBQVEsQ0FBVTtJQUMzQixRQUFRLEdBQWlCLElBQUksQ0FBQztJQUM5QixjQUFjLEdBQUcsQ0FBQyxDQUFDO0lBQ25CLGVBQWUsR0FBMkIsRUFBRSxDQUFDO0lBQzdDLFFBQVEsR0FBRyxDQUFDLENBQUM7SUFDYixTQUFTLENBQVU7SUFDbkIsS0FBSyxHQUFHLENBQUMsQ0FBQztJQUNWLHFCQUFxQjtJQUNyQixPQUFPLEdBQW1CLEVBQUUsQ0FBQztJQUM3QixzQkFBc0I7SUFDdEIsUUFBUSxDQUFXO0lBQ25CLHNCQUFzQjtJQUN0QixRQUFRLEdBQUcsU0FBUyxDQUFDO0lBQ3JCLDBCQUEwQjtJQUMxQixTQUFTLEdBQUcsQ0FBQyxDQUFDO0lBQ2QsNkJBQTZCO0lBQzdCLEtBQUssQ0FBK0I7SUFDcEMs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QUFFLE1BQU0sRUFBRSxFQUFFLEVBQUU7WUFDcEIsTUFBTSxPQUFPLEdBQUcsTUFBTSxHQUFHLENBQUMsQ0FBQyxJQUFJLENBQUMsR0FBRyxFQUFFLEdBQUcsU0FBUyxDQUFDLEdBQUcsSUFBSSxDQUFDLENBQUM7WUFDM0QsSUFBSSxDQUFDLEtBQUssR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDLFlBQVksR0FBRyxPQUFPLENBQUMsR0FBRyxFQUFFLElBQUksQ0FBQyxZQUFZLENBQUMsQ0FBQztZQUNsRixZQUFZLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUMvQixJQUFJLENBQUMsUUFBUSxFQUFFLENBQUM7Z0JBQ2QsUUFBUSxHQUFHLFVBQVUsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxDQUFDLFFBQVEsR0FBRyxTQUFTLENBQUMsRUFBRSxHQUFHLENBQUMsQ0FBQztnQkFDekQsTUFBTSxRQUFRLEdBQUcsQ0FBQyxJQUFJLENBQUMsTUFBTSxJQUFJLENBQUMsQ0FBQyxHQUFHLE1BQU0sQ0FBQztnQkFDN0MsSUFBSSxDQUFDLFFBQVEsR0FBRyxDQUFDLENBQUMsQ0FBQyxRQUFRLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLEdBQUcsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQztnQkFDM0QsSUFBSSxDQUFDLFNBQVMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxJQUFJLEdBQUcsUUFBUSxDQUFDLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO2dCQUN6RCxJQUFJLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxDQUFDO1lBQ3pCLENBQUM7UUFDSCxDQUFDLENBQUM7SUFDSixDQUFDO0NBQ0YiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBBamF4LCBBamF4UmVxdWVzdENvbmZpZyB9IGZyb20gJy4vYWpheCc7XG5pbXBvcnQgeyBDYW5jZWxlciB9IGZyb20gJy4vY2FuY2VsZXInO1xuaW1wb3J0IHsgRHluYW1pY0NodW5rIH0gZnJvbSAnLi9keW5hbWljLWNodW5rJztcbmltcG9ydCB7XG4gIEF1dGhvcml6ZVJlcXVlc3QsXG4gIE1ldGFkYXRhLFxuICBQcmVSZXF1ZXN0LFxuICBSZXF1ZXN0Q29uZmlnLFxuICBSZXF1ZXN0SGVhZGVycyxcbiAgUmVxdWVzdE9wdGlvbnMsXG4gIFJlc3BvbnNlQm9keSxcbiAgVXBsb2FkQWN0aW9uLFxuICBVcGxvYWRlck9wdGlvbnMsXG4gIFVwbG9hZFN0YXRlLFxuICBVcGxvYWRTdGF0dXMsXG4gIFVwbG9hZHhDb250cm9sRXZlbnRcbn0gZnJvbSAnLi9pbnRlcmZhY2VzJztcbmltcG9ydCB7IEVycm9yVHlwZSwgUmV0cnlIYW5kbGVyIH0gZnJvbSAnLi9yZXRyeS1oYW5kbGVyJztcbmltcG9ydCB7IHN0b3JlIH0gZnJvbSAnLi9zdG9yZSc7XG5pbXBvcnQgeyBpc051bWJlciwgdW5mdW5jIH0gZnJvbSAnLi91dGlscyc7XG5cbmNvbnN0IGFjdGlvblRvU3RhdHVzTWFwOiB7IFtLIGluIFVwbG9hZEFjdGlvbl06IFVwbG9hZFN0YXR1cyB9ID0ge1xuICBwYXVzZTogJ3BhdXNlZCcsXG4gIHVwbG9hZDogJ3F1ZXVlJyxcbiAgY2FuY2VsOiAnY2FuY2VsbGVkJyxcbiAgdXBkYXRlOiAndXBkYXRlZCdcbn07XG5cbi8qKlxuICogVXBsb2FkZXIgQmFzZSBDbGFzc1xuICovXG5leHBvcnQgYWJzdHJhY3QgY2xhc3MgVXBsb2FkZXIgaW1wbGVtZW50cyBVcGxvYWRTdGF0ZSB7XG4gIG5hbWU6IHN0cmluZztcbiAgcmVhZG9ubHkgc2l6ZTogbnVtYmVyO1xuICByZWFkb25seSB1cGxvYWRJZCE6IHN0cmluZztcbiAgcmVzcG9uc2U6IFJlc3BvbnNlQm9keSA9IG51bGw7XG4gIHJlc3BvbnNlU3RhdHVzID0gMDtcbiAgcmVzcG9uc2VIZWFkZXJzOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+ID0ge307XG4gIHByb2dyZXNzID0gMDtcbiAgcmVtYWluaW5nITogbnVtYmVyO1xuICBzcGVlZCA9IDA7XG4gIC8qKiBDdXN0b20gaGVhZGVycyAqL1xuICBoZWFkZXJzOiBSZXF1ZXN0SGVhZGVycyA9IHt9O1xuICAvKiogTWV0YWRhdGEgT2JqZWN0ICovXG4gIG1ldGFkYXRhOiBNZXRhZGF0YTtcbiAgLyoqIFVwbG9hZCBlbmRwb2ludCAqL1xuICBlbmRwb2ludCA9ICcvdXBsb2FkJztcbiAgLyoqIENodW5rIHNpemUgaW4gYnl0ZXMgKi9cbiAgY2h1bmtTaXplID0gMDtcbiAgLyoqIEF1dGggdG9rZW4vdG9rZW5HZXR0ZXIgKi9cbiAgdG9rZW46IFVwbG9hZHhDb250cm9sRXZlbnRbJ3Rva2VuJ107XG4gIC8qKiBCeXRlIG9mZnNldCB3aXRoaW4gdGhlIHdob2xlIGZpbGUgKi9cbiAgb2Zmc2V0PzogbnVtYmVyO1xuICAvKiogUmV0cmllcyBoYW5kbGVyICovXG4gIHJldHJ5OiBSZXRyeUhhbmRsZXI7XG4gIGNhbmNlbGVyID0gbmV3IENhbmNlbGVyKCk7XG4gIGFib3J0Q29udHJvbGxlciA9IG5ldyBBYm9ydENvbnRyb2xsZXIoKTtcbiAgLyoqIFNldCBIdHRwUmVxdWVzdCByZXNwb25zZVR5cGUgKi9cbiAgcmVzcG9uc2VUeXBlPzogJ2pzb24nIHwgJ3RleHQnIHwgJ2RvY3VtZW50JztcbiAgcHJvdGVjdGVkIF9hdXRob3JpemU6IEF1dGhvcml6ZVJlcXVlc3Q7XG4gIHByb3RlY3RlZCBfcHJlcmVxdWVzdDogUHJlUmVxdWVzdDtcbiAgcHJvdGVjdGVkIF90b2tlbiE6IHN0cmluZztcbiAgcHJpdmF0ZSBfZXZlbnRzQ291bnQgPSAwO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHJlYWRvbmx5IGZpbGU6IEZpbGUsXG4gICAgcmVhZG9ubHkgb3B0aW9uczogUmVhZG9ubHk8VXBsb2FkZXJPcHRpb25zPixcbiAgICByZWFkb25seSBzdGF0ZUNoYW5nZTogKHVwbG9hZGVyOiBVcGxvYWRlcikgPT4gdm9pZCxcbiAgICByZWFkb25seSBhamF4OiBBamF4XG4gICkge1xuICAgIHRoaXMucmV0cnkgPSBuZXcgUmV0cnlIYW5kbGVyKG9wdGlvbnMucmV0cnlDb25maWcpO1xuICAgIHRoaXMubmFtZSA9IGZpbGUubmFtZTtcbiAgICB0aGlzLnNpemUgPSBmaWxlLnNpemU7XG4gICAgdGhpcy5tZXRhZGF0YSA9IHtcbiAgICAgIG5hbWU6IGZpbGUubmFtZSxcbiAgICAgIG1pbWVUeXBlOiBmaWxlLnR5cGUgfHwgJ2FwcGxpY2F0aW9uL29jdGV0LXN0cmVhbScsXG4gICAgICBzaXplOiBmaWxlLnNpemUsXG4gICAgICBsYXN0TW9kaWZpZWQ6IGZpbGUubGFzdE1vZGlmaWVkXG4gICAgfTtcbiAgICBvcHRpb25zLm1heENodW5rU2l6ZSAmJiAoRHluYW1pY0NodW5rLm1heFNpemUgPSBvcHRpb25zLm1heENodW5rU2l6ZSk7XG4gICAgLyoqIEEgZnVuY3Rpb24gdGhhdCBpcyBleGVjdXRlZCBiZWZvcmUgdGhlIHJlcXVlc3QgaXMgc2VudCAqL1xuICAgIHRoaXMuX3ByZXJlcXVlc3QgPSBvcHRpb25zLnByZXJlcXVlc3QgfHwgKHJlcSA9PiByZXEpO1xuICAgIC8qKiBBIGZ1bmN0aW9uIHVzZWQgdG8gYXV0aG9yaXplIHRoZSByZXF1ZXN0ICovXG4gICAgdGhpcy5fYXV0aG9yaXplID0gb3B0aW9ucy5hdXRob3JpemUgfHwgKHJlcSA9PiByZXEpO1xuICAgIHRoaXMuY29uZmlndXJlKG9wdGlvbnMpO1xuICB9XG5cbiAgcHJpdmF0ZSBfdXJsID0gJyc7XG5cbiAgZ2V0IHVybCgpOiBzdHJpbmcge1xuICAgIHJldHVybiB0aGlzLl91cmwgfHwgc3RvcmUuZ2V0KHRoaXMudXBsb2FkSWQpIHx8ICcnO1xuICB9XG5cbiAgc2V0IHVybCh2YWx1ZTogc3RyaW5nKSB7XG4gICAgdGhpcy5fdXJsICE9PSB2YWx1ZSAmJiBzdG9yZS5zZXQodGhpcy51cGxvYWRJZCwgdmFsdWUpO1xuICAgIHRoaXMuX3VybCA9IHZhbHVlO1xuICB9XG5cbiAgcHJpdmF0ZSBfc3RhdHVzITogVXBsb2FkU3RhdHVzO1xuXG4gIGdldCBzdGF0dXMoKTogVXBsb2FkU3RhdHVzIHtcbiAgICByZXR1cm4gdGhpcy5fc3RhdHVzO1xuICB9XG5cbiAgc2V0IHN0YXR1cyhzOiBVcGxvYWRTdGF0dXMpIHtcbiAgICBpZiAocyAhPT0gJ3VwZGF0ZWQnICYmIHMgIT09ICdjYW5jZWxsZWQnKSB7XG4gICAgICBpZiAodGhpcy5fc3RhdHVzID09PSBzKSByZXR1cm47XG4gICAgICBpZiAodGhpcy5fc3RhdHVzID09PSAnY29tcGxldGUnKSByZXR1cm47XG4gICAgfVxuICAgIGlmICh0aGlzLl9zdGF0dXMgPT09ICdjYW5jZWxsZWQnKSByZXR1cm47XG4gICAgaWYgKHRoaXMuX3N0YXR1cyA9PT0gJ3VwbG9hZGluZycgJiYgcyA9PT0gJ3F1ZXVlJykgcmV0dXJuO1xuICAgIGlmICh0aGlzLl9zdGF0dXMgPT09ICdyZXRyeScpIHRoaXMucmV0cnkuY2FuY2VsKCk7XG4gICAgdGhpcy5fc3RhdHVzID0gcztcbiAgICBpZiAocyA9PT0gJ3BhdXNlZCcpIHRoaXMuYWJvcnQoKTtcbiAgICBpZiAocyA9PT0gJ2NhbmNlbGxlZCcgfHwgcyA9PT0gJ2NvbXBsZXRlJyB8fCBzID09PSAnZXJyb3InKSB0aGlzLmNsZWFudXAoKTtcbiAgICBpZiAocyA9PT0gJ2NhbmNlbGxlZCcpIHRoaXMuY2FuY2VsQW5kU2VuZFN0YXRlKCk7XG4gICAgZWxzZSBpZiAocyA9PT0gJ3VwZGF0ZWQnKSB0aGlzLnVwZGF0ZUFuZFNlbmRTdGF0ZSgpO1xuICAgIGVsc2UgdGhpcy5zdGF0ZUNoYW5nZSh0aGlzKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDb25maWd1cmUgdXBsb2FkZXJcbiAgICovXG4gIGNvbmZpZ3VyZSh7IG1ldGFkYXRhLCBoZWFkZXJzLCB0b2tlbiwgZW5kcG9pbnQsIGFjdGlvbiB9OiBVcGxvYWR4Q29udHJvbEV2ZW50KTogdm9pZCB7XG4gICAgZW5kcG9pbnQgJiYgKHRoaXMuZW5kcG9pbnQgPSBlbmRwb2ludCk7XG4gICAgdG9rZW4gJiYgKHRoaXMudG9rZW4gPSB0b2tlbik7XG4gICAgbWV0YWRhdGEgJiYgT2JqZWN0LmFzc2lnbih0aGlzLm1ldGFkYXRhLCB1bmZ1bmMobWV0YWRhdGEsIHRoaXMuZmlsZSkpO1xuICAgIGhlYWRlcnMgJiYgT2JqZWN0LmFzc2lnbih0aGlzLmhlYWRlcnMsIHVuZnVuYyhoZWFkZXJzLCB0aGlzLmZpbGUpKTtcbiAgICBhY3Rpb24gJiYgKHRoaXMuc3RhdHVzID0gYWN0aW9uVG9TdGF0dXNNYXBbYWN0aW9uXSk7XG4gIH1cblxuICAvKipcbiAgICogU3RhcnRzIHVwbG9hZGluZ1xuICAgKi9cbiAgYXN5bmMgdXBsb2FkKCk6IFByb21pc2U8dm9pZD4ge1xuICAgIGRvIHtcbiAgICAgIHRoaXMuc3RhdHVzID0gJ3VwbG9hZGluZyc7XG4gICAgICB0cnkge1xuICAgICAgICB0aGlzLl90b2tlbiB8fD0gYXdhaXQgdGhpcy51cGRhdGVUb2tlbigpO1xuICAgICAgICB0aGlzLnVybCB8fD0gYXdhaXQgdGhpcy5nZXRGaWxlVXJsKCk7XG4gICAgICAgIGlmICh0aGlzLm9mZnNldCAhPT0gdGhpcy5zaXplKSB7XG4gICAgICAgICAgdGhpcy5vZmZzZXQgPSBpc051bWJlcih0aGlzLm9mZnNldClcbiAgICAgICAgICAgID8gYXdhaXQgdGhpcy5zZW5kRmlsZUNvbnRlbnQoKVxuICAgICAgICAgICAgOiBhd2FpdCB0aGlzLmdldE9mZnNldCgpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMucmV0cnkub2JzZXJ2ZSh0aGlzLm9mZnNldCk7XG4gICAgICAgIGlmICh0aGlzLm9mZnNldCA9PT0gdGhpcy5zaXplKSB7XG4gICAgICAgICAgdGhpcy5yZW1haW5pbmcgPSAwO1xuICAgICAgICAgIHRoaXMucHJvZ3Jlc3MgPSAxMDA7XG4gICAgICAgICAgdGhpcy5zdGF0dXMgPSAnY29tcGxldGUnO1xuICAgICAgICB9IGVsc2UgaWYgKCFpc051bWJlcih0aGlzLm9mZnNldCkpIHtcbiAgICAgICAgICB0aGlzLnN0YXRlQ2hhbmdlKHRoaXMpO1xuICAgICAgICAgIGF3YWl0IHRoaXMucmV0cnkud2FpdCh0aGlzLmdldFJldHJ5QWZ0ZXJGcm9tQmFja2VuZCgpIHx8IHRoaXMucmV0cnkuY29uZmlnLm9uQnVzeURlbGF5KTtcbiAgICAgICAgfVxuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICBlIGluc3RhbmNlb2YgRXJyb3IgJiYgY29uc29sZS5lcnJvcihlKTtcbiAgICAgICAgaWYgKHRoaXMuc3RhdHVzICE9PSAndXBsb2FkaW5nJykge1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBzd2l0Y2ggKHRoaXMucmV0cnkua2luZCh0aGlzLnJlc3BvbnNlU3RhdHVzKSkge1xuICAgICAgICAgIGNhc2UgRXJyb3JUeXBlLkZhdGFsOlxuICAgICAgICAgICAgdGhpcy5zdGF0dXMgPSAnZXJyb3InO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgIGNhc2UgRXJyb3JUeXBlLk5vdEZvdW5kOlxuICAgICAgICAgICAgdGhpcy51cmwgPSAnJztcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIGNhc2UgRXJyb3JUeXBlLkF1dGg6XG4gICAgICAgICAgICB0aGlzLl90b2tlbiA9ICcnO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgIGlmICh1bmZ1bmModGhpcy5yZXRyeS5jb25maWcua2VlcFBhcnRpYWwsIHRoaXMucmVzcG9uc2VTdGF0dXMpKSB7XG4gICAgICAgICAgICAgIHRoaXMub2Zmc2V0ID0gdW5kZWZpbmVkO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5zdGF0dXMgPSAncmV0cnknO1xuICAgICAgICAgICAgYXdhaXQgdGhpcy5yZXRyeS53YWl0KHRoaXMuZ2V0UmV0cnlBZnRlckZyb21CYWNrZW5kKCkpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSB3aGlsZSAoWyd1cGxvYWRpbmcnLCAncmV0cnknLCAndXBkYXRlZCddLmluY2x1ZGVzKHRoaXMuX3N0YXR1cykpO1xuICB9XG5cbiAgLyoqXG4gICAqIFBlcmZvcm1zIGh0dHAgcmVxdWVzdHNcbiAgICovXG4gIGFzeW5jIHJlcXVlc3QocmVxdWVzdE9wdGlvbnM6IFJlcXVlc3RPcHRpb25zKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgdGhpcy5yZXNwb25zZVN0YXR1cyA9IDA7XG4gICAgdGhpcy5yZXNwb25zZSA9IG51bGw7XG4gICAgdGhpcy5yZXNwb25zZUhlYWRlcnMgPSB7fTtcbiAgICBpZiAodGhpcy5hYm9ydENvbnRyb2xsZXIuc2lnbmFsLmFib3J0ZWQpIHtcbiAgICAgIHRoaXMuYWJvcnRDb250cm9sbGVyID0gbmV3IEFib3J0Q29udHJvbGxlcigpO1xuICAgIH1cbiAgICBjb25zdCBzaWduYWwgPSByZXF1ZXN0T3B0aW9ucy5zaWduYWwgfHwgdGhpcy5hYm9ydENvbnRyb2xsZXIuc2lnbmFsO1xuICAgIGxldCByZXE6IFJlcXVlc3RDb25maWcgPSB7XG4gICAgICBib2R5OiByZXF1ZXN0T3B0aW9ucy5ib2R5IHx8IG51bGwsXG4gICAgICBjYW5jZWxlcjogdGhpcy5jYW5jZWxlcixcbiAgICAgIHNpZ25hbCxcbiAgICAgIGhlYWRlcnM6IHsgLi4udGhpcy5oZWFkZXJzLCAuLi5yZXF1ZXN0T3B0aW9ucy5oZWFkZXJzIH0sXG4gICAgICBtZXRob2Q6IHJlcXVlc3RPcHRpb25zLm1ldGhvZCB8fCAnR0VUJyxcbiAgICAgIHVybDogcmVxdWVzdE9wdGlvbnMudXJsIHx8IHRoaXMudXJsXG4gICAgfTtcbiAgICBpZiAoIXJlcXVlc3RPcHRpb25zLnNraXBBdXRob3JpemF0aW9uKSB7XG4gICAgICByZXEgPSBhd2FpdCB0aGlzLl9hdXRob3JpemUocmVxLCB0aGlzLl90b2tlbik7XG4gICAgfVxuICAgIGNvbnN0IHsgYm9keSA9IG51bGwsIGhlYWRlcnMsIG1ldGhvZCwgdXJsID0gcmVxLnVybCB9ID0gKGF3YWl0IHRoaXMuX3ByZXJlcXVlc3QocmVxKSkgfHwgcmVxO1xuICAgIGNvbnN0IGFqYXhSZXF1ZXN0Q29uZmlnOiBBamF4UmVxdWVzdENvbmZpZyA9IHtcbiAgICAgIG1ldGhvZCxcbiAgICAgIGhlYWRlcnM6IHsgLi4ucmVxLmhlYWRlcnMsIC4uLmhlYWRlcnMgfSxcbiAgICAgIHVybCxcbiAgICAgIGRhdGE6IGJvZHksXG4gICAgICByZXNwb25zZVR5cGU6IHRoaXMub3B0aW9ucy5yZXNwb25zZVR5cGUgPz8gdGhpcy5yZXNwb25zZVR5cGUsXG4gICAgICB3aXRoQ3JlZGVudGlhbHM6ICEhdGhpcy5vcHRpb25zLndpdGhDcmVkZW50aWFscyxcbiAgICAgIGNhbmNlbGVyOiB0aGlzLmNhbmNlbGVyLFxuICAgICAgc2lnbmFsLFxuICAgICAgdmFsaWRhdGVTdGF0dXM6ICgpID0+IHRydWUsXG4gICAgICB0aW1lb3V0OiB0aGlzLnJldHJ5LmNvbmZpZy50aW1lb3V0XG4gICAgfTtcbiAgICBpZiAoaXNOdW1iZXIodGhpcy5vZmZzZXQpICYmIGJvZHkgJiYgdHlwZW9mIGJvZHkgPT09ICdvYmplY3QnKSB7XG4gICAgICBhamF4UmVxdWVzdENvbmZpZy5vblVwbG9hZFByb2dyZXNzID0gdGhpcy5vblByb2dyZXNzKCk7XG4gICAgfVxuICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgdGhpcy5hamF4LnJlcXVlc3QoYWpheFJlcXVlc3RDb25maWcpO1xuICAgIHRoaXMucmVzcG9uc2UgPSByZXNwb25zZS5kYXRhO1xuICAgIHRoaXMucmVzcG9uc2VIZWFkZXJzID0gcmVzcG9uc2UuaGVhZGVycztcbiAgICB0aGlzLnJlc3BvbnNlU3RhdHVzID0gcmVzcG9uc2Uuc3RhdHVzO1xuICAgIGlmIChyZXNwb25zZS5zdGF0dXMgPj0gNDAwKSB7XG4gICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QoKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogU2V0IGF1dGggdG9rZW4gc3RyaW5nXG4gICAqL1xuICB1cGRhdGVUb2tlbiA9ICgpOiBzdHJpbmcgfCBQcm9taXNlPHN0cmluZz4gPT4ge1xuICAgIHJldHVybiB1bmZ1bmModGhpcy50b2tlbiB8fCAnJywgdGhpcy5yZXNwb25zZVN0YXR1cyk7XG4gIH07XG5cbiAgLyoqXG4gICAqIEdldCBmaWxlIFVSSVxuICAgKi9cbiAgcHJvdGVjdGVkIGFic3RyYWN0IGdldEZpbGVVcmwoKTogUHJvbWlzZTxzdHJpbmc+O1xuXG4gIC8qKlxuICAgKiBTZW5kIGZpbGUgY29udGVudCBhbmQgcmV0dXJuIGFuIG9mZnNldCBmb3IgdGhlIG5leHQgcmVxdWVzdFxuICAgKi9cbiAgcHJvdGVjdGVkIGFic3RyYWN0IHNlbmRGaWxlQ29udGVudCgpOiBQcm9taXNlPG51bWJlciB8IHVuZGVmaW5lZD47XG5cbiAgLyoqXG4gICAqIEdldCBhbiBvZmZzZXQgZm9yIHRoZSBuZXh0IHJlcXVlc3RcbiAgICovXG4gIHByb3RlY3RlZCBhYnN0cmFjdCBnZXRPZmZzZXQoKTogUHJvbWlzZTxudW1iZXIgfCB1bmRlZmluZWQ+O1xuXG4gIC8qKlxuICAgKiAgVXBkYXRpbmcgdGhlIG1ldGFkYXRhIG9mIHRoZSB1cGxvYWRcbiAgICovXG4gIHByb3RlY3RlZCB1cGRhdGU8VCA9IHsgbWV0YWRhdGE/OiBNZXRhZGF0YSB9PihfZGF0YTogVCk6IFByb21pc2U8c3RyaW5nPiB7XG4gICAgcmV0dXJuIFByb21pc2UucmVqZWN0KCdOb3QgaW1wbGVtZW50ZWQnKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBhYm9ydCgpOiB2b2lkIHtcbiAgICB0aGlzLm9mZnNldCA9IHVuZGVmaW5lZDtcbiAgICB0aGlzLmFib3J0Q29udHJvbGxlci5hYm9ydCgpO1xuICAgIHRoaXMuY2FuY2VsZXIuY2FuY2VsKCk7XG4gIH1cblxuICBwcm90ZWN0ZWQgYXN5bmMgY2FuY2VsKCk6IFByb21pc2U8dm9pZD4ge1xuICAgIHRoaXMuYWJvcnQoKTtcbiAgICBpZiAodGhpcy51cmwpIHtcbiAgICAgIGF3YWl0IHRoaXMucmVxdWVzdCh7IG1ldGhvZDogJ0RFTEVURScgfSkuY2F0Y2goKCkgPT4ge30pO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBHZXRzIHRoZSB2YWx1ZSBmcm9tIHRoZSByZXNwb25zZVxuICAgKi9cbiAgcHJvdGVjdGVkIGdldFZhbHVlRnJvbVJlc3BvbnNlKGtleTogc3RyaW5nKTogc3RyaW5nIHwgbnVsbCB7XG4gICAgcmV0dXJuIHRoaXMucmVzcG9uc2VIZWFkZXJzW2tleS50b0xvd2VyQ2FzZSgpXSB8fCBudWxsO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCBmaWxlIGNodW5rXG4gICAqIEBwYXJhbSBvZmZzZXQgLSBudW1iZXIgb2YgYnl0ZXMgb2YgdGhlIGZpbGUgdG8gc2tpcFxuICAgKiBAcGFyYW0gc2l6ZSAtIGNodW5rIHNpemVcbiAgICovXG4gIGdldENodW5rKG9mZnNldD86IG51bWJlciwgc2l6ZT86IG51bWJlcik6IHsgc3RhcnQ6IG51bWJlcjsgZW5kOiBudW1iZXI7IGJvZHk6IEJsb2IgfSB7XG4gICAgaWYgKHRoaXMucmVzcG9uc2VTdGF0dXMgPT09IDQxMykge1xuICAgICAgRHluYW1pY0NodW5rLm1heFNpemUgPSBEeW5hbWljQ2h1bmsuc2l6ZSA9IE1hdGguZmxvb3IoRHluYW1pY0NodW5rLnNpemUgLyAyKTtcbiAgICB9XG4gICAgdGhpcy5jaHVua1NpemUgPVxuICAgICAgdGhpcy5vcHRpb25zLmNodW5rU2l6ZSA9PT0gMCA/IHRoaXMuc2l6ZSA6IHRoaXMub3B0aW9ucy5jaHVua1NpemUgfHwgRHluYW1pY0NodW5rLnNpemU7XG4gICAgY29uc3Qgc3RhcnQgPSBvZmZzZXQgPz8gdGhpcy5vZmZzZXQgPz8gMDtcbiAgICBjb25zdCBlbmQgPSBNYXRoLm1pbihzdGFydCArIChzaXplIHx8IHRoaXMuY2h1bmtTaXplKSwgdGhpcy5zaXplKTtcbiAgICBjb25zdCBib2R5ID0gdGhpcy5maWxlLnNsaWNlKHN0YXJ0LCBlbmQpO1xuICAgIHJldHVybiB7IHN0YXJ0LCBlbmQsIGJvZHkgfTtcbiAgfVxuXG4gIHByaXZhdGUgZ2V0UmV0cnlBZnRlckZyb21CYWNrZW5kKCk6IG51bWJlciB7XG4gICAgcmV0dXJuIE51bWJlcih0aGlzLmdldFZhbHVlRnJvbVJlc3BvbnNlKCdyZXRyeS1hZnRlcicpKSAqIDEwMDA7XG4gIH1cblxuICBwcml2YXRlIGNhbmNlbEFuZFNlbmRTdGF0ZSgpIHtcbiAgICB0aGlzLmNhbmNlbCgpLnRoZW4oKCkgPT4gdGhpcy5zdGF0ZUNoYW5nZSh0aGlzKSwgY29uc29sZS5lcnJvcik7XG4gIH1cblxuICBwcml2YXRlIHVwZGF0ZUFuZFNlbmRTdGF0ZSgpOiB2b2lkIHtcbiAgICB0aGlzLnVwZGF0ZSh7IG1ldGFkYXRhOiB0aGlzLm1ldGFkYXRhIH0pLnRoZW4oKCkgPT4gdGhpcy5zdGF0ZUNoYW5nZSh0aGlzKSwgY29uc29sZS5lcnJvcik7XG4gIH1cblxuICBwcml2YXRlIGNsZWFudXAgPSAoKSA9PiB7XG4gICAgc3RvcmUuZGVsZXRlKHRoaXMuX3VybCk7XG4gICAgc3RvcmUuZGVsZXRlKHRoaXMudXBsb2FkSWQpO1xuICB9O1xuXG4gIHByaXZhdGUgb25Qcm9ncmVzcygpOiAoZXZ0OiBQcm9ncmVzc0V2ZW50KSA9PiB2b2lkIHtcbiAgICBsZXQgdGhyb3R0bGU6IFJldHVyblR5cGU8dHlwZW9mIHNldFRpbWVvdXQ+IHwgdW5kZWZpbmVkO1xuICAgIGNvbnN0IHN0YXJ0VGltZSA9IERhdGUubm93KCk7XG4gICAgcmV0dXJuICh7IGxvYWRlZCB9KSA9PiB7XG4gICAgICBjb25zdCBjdXJyZW50ID0gbG9hZGVkIC8gKChEYXRlLm5vdygpIC0gc3RhcnRUaW1lKSAvIDEwMDApO1xuICAgICAgdGhpcy5zcGVlZCA9IH5+KCh0aGlzLnNwZWVkICogdGhpcy5fZXZlbnRzQ291bnQgKyBjdXJyZW50KSAvICsrdGhpcy5fZXZlbnRzQ291bnQpO1xuICAgICAgRHluYW1pY0NodW5rLnNjYWxlKHRoaXMuc3BlZWQpO1xuICAgICAgaWYgKCF0aHJvdHRsZSkge1xuICAgICAgICB0aHJvdHRsZSA9IHNldFRpbWVvdXQoKCkgPT4gKHRocm90dGxlID0gdW5kZWZpbmVkKSwgNTAwKTtcbiAgICAgICAgY29uc3QgdXBsb2FkZWQgPSAodGhpcy5vZmZzZXQgfHwgMCkgKyBsb2FkZWQ7XG4gICAgICAgIHRoaXMucHJvZ3Jlc3MgPSArKCh1cGxvYWRlZCAvIHRoaXMuc2l6ZSkgKiAxMDApLnRvRml4ZWQoMik7XG4gICAgICAgIHRoaXMucmVtYWluaW5nID0gfn4oKHRoaXMuc2l6ZSAtIHVwbG9hZGVkKSAvIHRoaXMuc3BlZWQpO1xuICAgICAgICB0aGlzLnN0YXRlQ2hhbmdlKHRoaXMpO1xuICAgICAgfVxuICAgIH07XG4gIH1cbn1cbiJdfQ==