filestack-js
Version:
Official JavaScript library for Filestack
345 lines (343 loc) • 43.3 kB
JavaScript
/*
* Copyright (c) 2019 by Filestack.
* Some rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
Object.defineProperty(exports, "__esModule", { value: true });
var tslib_1 = require("tslib");
var upload_1 = require("./upload");
var s3_1 = require("./uploaders/s3");
var config_1 = require("./../../../config");
var testBuffer = Buffer.from('test test test');
var customNameMocked = jest.fn();
var mockedFsFile = {};
Object.defineProperty(mockedFsFile, 'customName', {
set: customNameMocked,
});
jest.useFakeTimers();
jest.mock('./uploaders/s3');
jest.mock('./file_tools', function () { return ({
getFile: jest.fn().mockImplementation(function () { return mockedFsFile; }),
}); });
var mockedFileResponse = {
status: 'stored',
};
var sessionURls = config_1.config.urls;
var defaultSession = {
apikey: 'test',
policy: 'p',
signature: 's',
urls: sessionURls,
};
var mockExecute = jest.fn();
describe('Api/Upload/upload', function () {
beforeAll(function () {
jest.spyOn(s3_1.S3Uploader.prototype, 'execute').mockImplementation(mockExecute);
});
describe('Settings', function () {
it('should handle constructor options', function () {
var u = new upload_1.Upload({
partSize: 5 * 1024 * 1024,
intelligentChunkSize: 5 * 1024 * 1024,
});
expect(s3_1.S3Uploader.prototype.setPartSize).toHaveBeenCalledWith(5 * 1024 * 1024);
expect(s3_1.S3Uploader.prototype.setIntelligentChunkSize).toHaveBeenCalledWith(5 * 1024 * 1024);
});
it('should throw error on wrong upload options', function () {
// @ts-ignore
expect(function () { return new upload_1.Upload({ intelligent1: true }); }).toThrowError('Invalid upload params');
});
it('should accept sanitizer settings', function () {
expect(function () { return new upload_1.Upload({}, {
// @ts-ignore
sanitizer: false,
}); }).not.toThrowError('Invalid upload params');
expect(function () { return new upload_1.Upload({}, {
// @ts-ignore
sanitizer: {
exclude: ['1'],
replacement: '-',
},
}); }).not.toThrowError('Invalid upload params');
});
it('should throw error on wrong store options', function () {
// @ts-ignore
expect(function () { return new upload_1.Upload({ intelligent: true }, { test: 123 }); }).toThrowError('Invalid store upload params');
});
it('should set intelligent upload mode', function () {
var u = new upload_1.Upload({ intelligent: true });
expect(s3_1.S3Uploader.prototype.setUploadMode).toHaveBeenCalledWith("intelligent" /* UploadMode.INTELLIGENT */);
});
it('should set respect disableIntegrityCheck param', function () {
var u = new upload_1.Upload({ disableIntegrityCheck: true });
expect(s3_1.S3Uploader.prototype.setIntegrityCheck).toHaveBeenCalledWith(false);
});
it('should fallback upload mode', function () {
var u = new upload_1.Upload({ intelligent: 'fallback' });
expect(s3_1.S3Uploader.prototype.setUploadMode).toHaveBeenCalledWith("fallback" /* UploadMode.FALLBACK */);
});
it('should set upload tasks to uploader', function () {
var tags = { test: '123' };
var u = new upload_1.Upload({ tags: tags });
expect(s3_1.S3Uploader.prototype.setUploadTags).toHaveBeenCalledWith(tags);
});
it('should pass store options to uploader class', function () {
var storeOptions = {
location: 's3',
};
var u = new upload_1.Upload({}, storeOptions);
expect(s3_1.S3Uploader.prototype.constructor).toHaveBeenCalledWith(storeOptions, undefined);
});
it('should respect concurrency param in upload options', function () {
var uploadOptions = {
concurrency: 4,
};
var u = new upload_1.Upload(uploadOptions);
expect(s3_1.S3Uploader.prototype.constructor).toHaveBeenCalledWith({}, 4);
});
it('should set correct security to uploader', function () {
var security = {
policy: 'p',
signature: 's',
};
var u = new upload_1.Upload();
u.setSecurity(security);
expect(s3_1.S3Uploader.prototype.setSecurity).toHaveBeenCalledWith(security);
});
it('should pass session variable to uploader', function () {
var u = new upload_1.Upload();
u.setSession(defaultSession);
expect(s3_1.S3Uploader.prototype.setUrl).toHaveBeenCalledWith(defaultSession.urls.uploadApiUrl);
expect(s3_1.S3Uploader.prototype.setApikey).toHaveBeenCalledWith(defaultSession.apikey);
expect(s3_1.S3Uploader.prototype.setSecurity).toHaveBeenCalledWith({ policy: defaultSession.policy, signature: defaultSession.signature });
});
it('should set storeOption filename to class', function () { return tslib_1.__awaiter(void 0, void 0, void 0, function () {
var filenameFn, u;
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0:
mockExecute.mockReturnValue(Promise.resolve([mockedFileResponse]));
filenameFn = function () { return 'test'; };
u = new upload_1.Upload({}, {
filename: filenameFn,
});
return [4 /*yield*/, u.upload(testBuffer)];
case 1:
_a.sent();
expect(customNameMocked).toHaveBeenCalledWith(filenameFn);
return [2 /*return*/];
}
});
}); });
it('should assign methods to user provided token', function () {
var token = {};
var u = new upload_1.Upload();
u.setToken(token);
expect(token['cancel']).toBeTruthy();
expect(token['resume']).toBeTruthy();
expect(token['pause']).toBeTruthy();
token['cancel']();
token['pause']();
token['resume']();
});
it('should set token with methods that pause,cancel or resume uploads', function () {
var token = {};
var u = new upload_1.Upload();
u.setToken(token);
token['cancel']();
token['pause']();
token['resume']();
expect(s3_1.S3Uploader.prototype.abort).toHaveBeenCalled();
expect(s3_1.S3Uploader.prototype.pause).toHaveBeenCalled();
expect(s3_1.S3Uploader.prototype.resume).toHaveBeenCalled();
});
it('should throw an error if token is not an object', function () {
var token = '123123';
var u = new upload_1.Upload();
expect(function () {
u.setToken(token);
}).toThrowError();
});
});
describe('Upload', function () {
beforeEach(function () {
mockExecute.mockReturnValue(Promise.resolve([mockedFileResponse, mockedFileResponse]));
});
it('should execute normal upload without errors and return single file response', function () { return tslib_1.__awaiter(void 0, void 0, void 0, function () {
var u, res;
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0:
u = new upload_1.Upload();
return [4 /*yield*/, u.upload(testBuffer)];
case 1:
res = _a.sent();
expect(res).toEqual(mockedFileResponse);
return [2 /*return*/];
}
});
}); });
it('should execute normal upload with errors and return rejected promise', function () {
var u = new upload_1.Upload();
mockExecute.mockReturnValue(Promise.resolve([
{
status: "Failed" /* FileState.FAILED */,
},
]));
return expect(u.upload(testBuffer)).rejects.toEqual({
status: "Failed" /* FileState.FAILED */,
});
});
it('should execute multiupload without errors and return single file response', function () { return tslib_1.__awaiter(void 0, void 0, void 0, function () {
var u, res;
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0:
u = new upload_1.Upload();
return [4 /*yield*/, u.multiupload([testBuffer, testBuffer])];
case 1:
res = _a.sent();
expect(res).toEqual([mockedFileResponse, mockedFileResponse]);
return [2 /*return*/];
}
});
}); });
});
describe('Progress', function () {
var progress1 = {
totalBytes: 1,
totalPercent: 1,
files: [
{
totalBytes: 1,
totalPercent: 1,
},
],
};
var progress50 = {
totalBytes: 5,
totalPercent: 50,
files: [
{
totalBytes: 50,
totalPercent: 50,
},
],
};
var progress100 = {
totalBytes: 100,
totalPercent: 100,
files: [
{
totalBytes: 100,
totalPercent: 100,
},
],
};
it('should handle correct progress event', function () { return tslib_1.__awaiter(void 0, void 0, void 0, function () {
var progressMock, u;
var _this = this;
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0:
jest.spyOn(s3_1.S3Uploader.prototype, 'on').mockImplementation(function (ev, cb) {
cb(progress1);
cb(progress100);
return _this;
});
progressMock = jest.fn();
u = new upload_1.Upload({
onProgress: progressMock,
});
return [4 /*yield*/, u.upload(testBuffer)];
case 1:
_a.sent();
expect(progressMock).toHaveBeenCalledWith(progress100);
expect(progressMock).toHaveBeenCalledTimes(1);
return [2 /*return*/];
}
});
}); });
it('should call progress event on given interval', function () { return tslib_1.__awaiter(void 0, void 0, void 0, function () {
var progressCb, progressMock, u;
var _this = this;
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0:
mockExecute.mockImplementation(function () {
return new Promise(function (resolve) {
setTimeout(function () { return progressCb(progress1); }, 1);
setTimeout(function () { return progressCb(progress50); }, 2);
setTimeout(function () { return progressCb(progress100); }, 3);
setTimeout(function () { return resolve([]); }, 4);
jest.advanceTimersByTime(4);
});
});
jest.spyOn(s3_1.S3Uploader.prototype, 'on').mockImplementation(function (ev, cb) {
progressCb = cb;
return _this;
});
progressMock = jest.fn();
u = new upload_1.Upload({
progressInterval: 1,
onProgress: progressMock,
});
return [4 /*yield*/, u.multiupload([testBuffer])];
case 1:
_a.sent();
expect(progressMock).toHaveBeenCalledWith(progress1);
expect(progressMock).toHaveBeenCalledWith(progress50);
expect(progressMock).toHaveBeenCalledWith(progress100);
return [2 /*return*/];
}
});
}); });
it('should stay at the same progress when uploader goes back with file progress', function () { return tslib_1.__awaiter(void 0, void 0, void 0, function () {
var progressCb, progressMock, u;
var _this = this;
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0:
mockExecute.mockImplementation(function () {
return new Promise(function (resolve) {
setTimeout(function () { return progressCb(progress50); }, 1);
setTimeout(function () { return progressCb(progress1); }, 2);
setTimeout(function () { return progressCb(progress100); }, 3);
setTimeout(function () { return resolve([]); }, 4);
jest.advanceTimersByTime(4);
});
});
jest.spyOn(s3_1.S3Uploader.prototype, 'on').mockImplementation(function (ev, cb) {
progressCb = cb;
return _this;
});
progressMock = jest.fn();
u = new upload_1.Upload({
progressInterval: 1,
onProgress: progressMock,
});
return [4 /*yield*/, u.multiupload([testBuffer])];
case 1:
_a.sent();
expect(progressMock).toHaveBeenCalledWith(progress50);
expect(progressMock).toHaveBeenCalledWith(progress50);
expect(progressMock).toHaveBeenCalledWith(progress100);
return [2 /*return*/];
}
});
}); });
});
});
//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9saWIvYXBpL3VwbG9hZC91cGxvYWQuc3BlYy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUE7Ozs7Ozs7Ozs7Ozs7OztHQWVHOzs7QUFFSCxtQ0FBa0M7QUFFbEMscUNBQTRDO0FBQzVDLDRDQUEyQztBQUkzQyxJQUFNLFVBQVUsR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDLGdCQUFnQixDQUFDLENBQUM7QUFFakQsSUFBTSxnQkFBZ0IsR0FBRyxJQUFJLENBQUMsRUFBRSxFQUFFLENBQUM7QUFFbkMsSUFBTSxZQUFZLEdBQUcsRUFBRSxDQUFDO0FBQ3hCLE1BQU0sQ0FBQyxjQUFjLENBQUMsWUFBWSxFQUFFLFlBQVksRUFBRTtJQUNoRCxHQUFHLEVBQUUsZ0JBQWdCO0NBQ3RCLENBQUMsQ0FBQztBQUVILElBQUksQ0FBQyxhQUFhLEVBQUUsQ0FBQztBQUVyQixJQUFJLENBQUMsSUFBSSxDQUFDLGdCQUFnQixDQUFDLENBQUM7QUFDNUIsSUFBSSxDQUFDLElBQUksQ0FBQyxjQUFjLEVBQUUsY0FBTSxPQUFBLENBQUM7SUFDL0IsT0FBTyxFQUFFLElBQUksQ0FBQyxFQUFFLEVBQUUsQ0FBQyxrQkFBa0IsQ0FBQyxjQUFNLE9BQUEsWUFBWSxFQUFaLENBQVksQ0FBQztDQUMxRCxDQUFDLEVBRjhCLENBRTlCLENBQUMsQ0FBQztBQUVKLElBQU0sa0JBQWtCLEdBQUc7SUFDekIsTUFBTSxFQUFFLFFBQVE7Q0FDakIsQ0FBQztBQUVGLElBQU0sV0FBVyxHQUFHLGVBQU0sQ0FBQyxJQUFJLENBQUM7QUFDaEMsSUFBTSxjQUFjLEdBQUc7SUFDckIsTUFBTSxFQUFFLE1BQU07SUFDZCxNQUFNLEVBQUUsR0FBRztJQUNYLFNBQVMsRUFBRSxHQUFHO0lBQ2QsSUFBSSxFQUFFLFdBQVc7Q0FDbEIsQ0FBQztBQUVGLElBQU0sV0FBVyxHQUFHLElBQUksQ0FBQyxFQUFFLEVBQUUsQ0FBQztBQUU5QixRQUFRLENBQUMsbUJBQW1CLEVBQUU7SUFD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RCxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztBQUNMLENBQUMsQ0FBQyxDQUFDIiwiZmlsZSI6ImxpYi9hcGkvdXBsb2FkL3VwbG9hZC5zcGVjLmpzIiwic291cmNlc0NvbnRlbnQiOlsiLypcbiAqIENvcHlyaWdodCAoYykgMjAxOSBieSBGaWxlc3RhY2suXG4gKiBTb21lIHJpZ2h0cyByZXNlcnZlZC5cbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKi9cblxuaW1wb3J0IHsgVXBsb2FkIH0gZnJvbSAnLi91cGxvYWQnO1xuaW1wb3J0IHsgRmlsZVN0YXRlIH0gZnJvbSAnLi9maWxlJztcbmltcG9ydCB7IFMzVXBsb2FkZXIgfSBmcm9tICcuL3VwbG9hZGVycy9zMyc7XG5pbXBvcnQgeyBjb25maWcgfSBmcm9tICcuLy4uLy4uLy4uL2NvbmZpZyc7XG5pbXBvcnQgeyBTdG9yZVVwbG9hZE9wdGlvbnMgfSBmcm9tICcuL3R5cGVzJztcbmltcG9ydCB7IFVwbG9hZE1vZGUgfSBmcm9tICcuL3VwbG9hZGVycy9hYnN0cmFjdCc7XG5cbmNvbnN0IHRlc3RCdWZmZXIgPSBCdWZmZXIuZnJvbSgndGVzdCB0ZXN0IHRlc3QnKTtcblxuY29uc3QgY3VzdG9tTmFtZU1vY2tlZCA9IGplc3QuZm4oKTtcblxuY29uc3QgbW9ja2VkRnNGaWxlID0ge307XG5PYmplY3QuZGVmaW5lUHJvcGVydHkobW9ja2VkRnNGaWxlLCAnY3VzdG9tTmFtZScsIHtcbiAgc2V0OiBjdXN0b21OYW1lTW9ja2VkLFxufSk7XG5cbmplc3QudXNlRmFrZVRpbWVycygpO1xuXG5qZXN0Lm1vY2soJy4vdXBsb2FkZXJzL3MzJyk7XG5qZXN0Lm1vY2soJy4vZmlsZV90b29scycsICgpID0+ICh7XG4gIGdldEZpbGU6IGplc3QuZm4oKS5tb2NrSW1wbGVtZW50YXRpb24oKCkgPT4gbW9ja2VkRnNGaWxlKSxcbn0pKTtcblxuY29uc3QgbW9ja2VkRmlsZVJlc3BvbnNlID0ge1xuICBzdGF0dXM6ICdzdG9yZWQnLFxufTtcblxuY29uc3Qgc2Vzc2lvblVSbHMgPSBjb25maWcudXJscztcbmNvbnN0IGRlZmF1bHRTZXNzaW9uID0ge1xuICBhcGlrZXk6ICd0ZXN0JyxcbiAgcG9saWN5OiAncCcsXG4gIHNpZ25hdHVyZTogJ3MnLFxuICB1cmxzOiBzZXNzaW9uVVJscyxcbn07XG5cbmNvbnN0IG1vY2tFeGVjdXRlID0gamVzdC5mbigpO1xuXG5kZXNjcmliZSgnQXBpL1VwbG9hZC91cGxvYWQnLCAoKSA9PiB7XG4gIGJlZm9yZUFsbCgoKSA9PiB7XG4gICAgamVzdC5zcHlPbihTM1VwbG9hZGVyLnByb3RvdHlwZSwgJ2V4ZWN1dGUnKS5tb2NrSW1wbGVtZW50YXRpb24obW9ja0V4ZWN1dGUpO1xuICB9KTtcblxuICBkZXNjcmliZSgnU2V0dGluZ3MnLCAoKSA9PiB7XG4gICAgaXQoJ3Nob3VsZCBoYW5kbGUgY29uc3RydWN0b3Igb3B0aW9ucycsICgpID0+IHtcbiAgICAgIGNvbnN0IHUgPSBuZXcgVXBsb2FkKHtcbiAgICAgICAgcGFydFNpemU6IDUgKiAxMDI0ICogMTAyNCxcbiAgICAgICAgaW50ZWxsaWdlbnRDaHVua1NpemU6IDUgKiAxMDI0ICogMTAyNCxcbiAgICAgIH0pO1xuXG4gICAgICBleHBlY3QoUzNVcGxvYWRlci5wcm90b3R5cGUuc2V0UGFydFNpemUpLnRvSGF2ZUJlZW5DYWxsZWRXaXRoKDUgKiAxMDI0ICogMTAyNCk7XG4gICAgICBleHBlY3QoUzNVcGxvYWRlci5wcm90b3R5cGUuc2V0SW50ZWxsaWdlbnRDaHVua1NpemUpLnRvSGF2ZUJlZW5DYWxsZWRXaXRoKDUgKiAxMDI0ICogMTAyNCk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHRocm93IGVycm9yIG9uIHdyb25nIHVwbG9hZCBvcHRpb25zJywgKCkgPT4ge1xuICAgICAgLy8gQHRzLWlnbm9yZVxuICAgICAgZXhwZWN0KCgpID0+IG5ldyBVcGxvYWQoeyBpbnRlbGxpZ2VudDE6IHRydWUgfSkpLnRvVGhyb3dFcnJvcignSW52YWxpZCB1cGxvYWQgcGFyYW1zJyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGFjY2VwdCBzYW5pdGl6ZXIgc2V0dGluZ3MnLCAoKSA9PiB7XG4gICAgICBleHBlY3QoKCkgPT4gbmV3IFVwbG9hZCh7fSwge1xuICAgICAgICAvLyBAdHMtaWdub3JlXG4gICAgICAgIHNhbml0aXplcjogZmFsc2UsXG4gICAgICB9KSkubm90LnRvVGhyb3dFcnJvcignSW52YWxpZCB1cGxvYWQgcGFyYW1zJyk7XG5cbiAgICAgIGV4cGVjdCgoKSA9PiBuZXcgVXBsb2FkKHt9LCB7XG4gICAgICAgIC8vIEB0cy1pZ25vcmVcbiAgICAgICAgc2FuaXRpemVyOiB7XG4gICAgICAgICAgZXhjbHVkZTogWycxJ10sXG4gICAgICAgICAgcmVwbGFjZW1lbnQ6ICctJyxcbiAgICAgICAgfSxcbiAgICAgIH0pKS5ub3QudG9UaHJvd0Vycm9yKCdJbnZhbGlkIHVwbG9hZCBwYXJhbXMnKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgdGhyb3cgZXJyb3Igb24gd3Jvbmcgc3RvcmUgb3B0aW9ucycsICgpID0+IHtcbiAgICAgIC8vIEB0cy1pZ25vcmVcbiAgICAgIGV4cGVjdCgoKSA9PiBuZXcgVXBsb2FkKHsgaW50ZWxsaWdlbnQ6IHRydWUgfSwgeyB0ZXN0OiAxMjMgfSkpLnRvVGhyb3dFcnJvcignSW52YWxpZCBzdG9yZSB1cGxvYWQgcGFyYW1zJyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHNldCBpbnRlbGxpZ2VudCB1cGxvYWQgbW9kZScsICgpID0+IHtcbiAgICAgIGNvbnN0IHUgPSBuZXcgVXBsb2FkKHsgaW50ZWxsaWdlbnQ6IHRydWUgfSk7XG4gICAgICBleHBlY3QoUzNVcGxvYWRlci5wcm90b3R5cGUuc2V0VXBsb2FkTW9kZSkudG9IYXZlQmVlbkNhbGxlZFdpdGgoVXBsb2FkTW9kZS5JTlRFTExJR0VOVCk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHNldCByZXNwZWN0IGRpc2FibGVJbnRlZ3JpdHlDaGVjayBwYXJhbScsICgpID0+IHtcbiAgICAgIGNvbnN0IHUgPSBuZXcgVXBsb2FkKHsgZGlzYWJsZUludGVncml0eUNoZWNrOiB0cnVlIH0pO1xuICAgICAgZXhwZWN0KFMzVXBsb2FkZXIucHJvdG90eXBlLnNldEludGVncml0eUNoZWNrKS50b0hhdmVCZWVuQ2FsbGVkV2l0aChmYWxzZSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGZhbGxiYWNrIHVwbG9hZCBtb2RlJywgKCkgPT4ge1xuICAgICAgY29uc3QgdSA9IG5ldyBVcGxvYWQoeyBpbnRlbGxpZ2VudDogJ2ZhbGxiYWNrJyB9KTtcbiAgICAgIGV4cGVjdChTM1VwbG9hZGVyLnByb3RvdHlwZS5zZXRVcGxvYWRNb2RlKS50b0hhdmVCZWVuQ2FsbGVkV2l0aChVcGxvYWRNb2RlLkZBTExCQUNLKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgc2V0IHVwbG9hZCB0YXNrcyB0byB1cGxvYWRlcicsICgpID0+IHtcbiAgICAgIGNvbnN0IHRhZ3MgPSB7IHRlc3Q6ICcxMjMnIH07XG4gICAgICBjb25zdCB1ID0gbmV3IFVwbG9hZCh7IHRhZ3M6IHRhZ3MgfSk7XG4gICAgICBleHBlY3QoUzNVcGxvYWRlci5wcm90b3R5cGUuc2V0VXBsb2FkVGFncykudG9IYXZlQmVlbkNhbGxlZFdpdGgodGFncyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHBhc3Mgc3RvcmUgb3B0aW9ucyB0byB1cGxvYWRlciBjbGFzcycsICgpID0+IHtcbiAgICAgIGNvbnN0IHN0b3JlT3B0aW9uczogU3RvcmVVcGxvYWRPcHRpb25zID0ge1xuICAgICAgICBsb2NhdGlvbjogJ3MzJyxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHUgPSBuZXcgVXBsb2FkKHt9LCBzdG9yZU9wdGlvbnMpO1xuICAgICAgZXhwZWN0KFMzVXBsb2FkZXIucHJvdG90eXBlLmNvbnN0cnVjdG9yKS50b0hhdmVCZWVuQ2FsbGVkV2l0aChzdG9yZU9wdGlvbnMsIHVuZGVmaW5lZCk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJlc3BlY3QgY29uY3VycmVuY3kgcGFyYW0gaW4gdXBsb2FkIG9wdGlvbnMnLCAoKSA9PiB7XG4gICAgICBjb25zdCB1cGxvYWRPcHRpb25zID0ge1xuICAgICAgICBjb25jdXJyZW5jeTogNCxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHUgPSBuZXcgVXBsb2FkKHVwbG9hZE9wdGlvbnMpO1xuICAgICAgZXhwZWN0KFMzVXBsb2FkZXIucHJvdG90eXBlLmNvbnN0cnVjdG9yKS50b0hhdmVCZWVuQ2FsbGVkV2l0aCh7fSwgNCk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHNldCBjb3JyZWN0IHNlY3VyaXR5IHRvIHVwbG9hZGVyJywgKCkgPT4ge1xuICAgICAgY29uc3Qgc2VjdXJpdHkgPSB7XG4gICAgICAgIHBvbGljeTogJ3AnLFxuICAgICAgICBzaWduYXR1cmU6ICdzJyxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHUgPSBuZXcgVXBsb2FkKCk7XG4gICAgICB1LnNldFNlY3VyaXR5KHNlY3VyaXR5KTtcblxuICAgICAgZXhwZWN0KFMzVXBsb2FkZXIucHJvdG90eXBlLnNldFNlY3VyaXR5KS50b0hhdmVCZWVuQ2FsbGVkV2l0aChzZWN1cml0eSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHBhc3Mgc2Vzc2lvbiB2YXJpYWJsZSB0byB1cGxvYWRlcicsICgpID0+IHtcbiAgICAgIGNvbnN0IHUgPSBuZXcgVXBsb2FkKCk7XG4gICAgICB1LnNldFNlc3Npb24oZGVmYXVsdFNlc3Npb24pO1xuXG4gICAgICBleHBlY3QoUzNVcGxvYWRlci5wcm90b3R5cGUuc2V0VXJsKS50b0hhdmVCZWVuQ2FsbGVkV2l0aChkZWZhdWx0U2Vzc2lvbi51cmxzLnVwbG9hZEFwaVVybCk7XG4gICAgICBleHBlY3QoUzNVcGxvYWRlci5wcm90b3R5cGUuc2V0QXBpa2V5KS50b0hhdmVCZWVuQ2FsbGVkV2l0aChkZWZhdWx0U2Vzc2lvbi5hcGlrZXkpO1xuICAgICAgZXhwZWN0KFMzVXBsb2FkZXIucHJvdG90eXBlLnNldFNlY3VyaXR5KS50b0hhdmVCZWVuQ2FsbGVkV2l0aCh7IHBvbGljeTogZGVmYXVsdFNlc3Npb24ucG9saWN5LCBzaWduYXR1cmU6IGRlZmF1bHRTZXNzaW9uLnNpZ25hdHVyZSB9KTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgc2V0IHN0b3JlT3B0aW9uIGZpbGVuYW1lIHRvIGNsYXNzJywgYXN5bmMgKCkgPT4ge1xuICAgICAgbW9ja0V4ZWN1dGUubW9ja1JldHVyblZhbHVlKFByb21pc2UucmVzb2x2ZShbbW9ja2VkRmlsZVJlc3BvbnNlXSkpO1xuICAgICAgY29uc3QgZmlsZW5hbWVGbiA9ICgpID0+ICd0ZXN0JztcblxuICAgICAgY29uc3QgdSA9IG5ldyBVcGxvYWQoXG4gICAgICAgIHt9LFxuICAgICAgICB7XG4gICAgICAgICAgZmlsZW5hbWU6IGZpbGVuYW1lRm4sXG4gICAgICAgIH1cbiAgICAgICk7XG5cbiAgICAgIGF3YWl0IHUudXBsb2FkKHRlc3RCdWZmZXIpO1xuICAgICAgZXhwZWN0KGN1c3RvbU5hbWVNb2NrZWQpLnRvSGF2ZUJlZW5DYWxsZWRXaXRoKGZpbGVuYW1lRm4pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBhc3NpZ24gbWV0aG9kcyB0byB1c2VyIHByb3ZpZGVkIHRva2VuJywgKCkgPT4ge1xuICAgICAgbGV0IHRva2VuID0ge307XG5cbiAgICAgIGNvbnN0IHUgPSBuZXcgVXBsb2FkKCk7XG4gICAgICB1LnNldFRva2VuKHRva2VuKTtcblxuICAgICAgZXhwZWN0KHRva2VuWydjYW5jZWwnXSkudG9CZVRydXRoeSgpO1xuICAgICAgZXhwZWN0KHRva2VuWydyZXN1bWUnXSkudG9CZVRydXRoeSgpO1xuICAgICAgZXhwZWN0KHRva2VuWydwYXVzZSddKS50b0JlVHJ1dGh5KCk7XG5cbiAgICAgIHRva2VuWydjYW5jZWwnXSgpO1xuICAgICAgdG9rZW5bJ3BhdXNlJ10oKTtcbiAgICAgIHRva2VuWydyZXN1bWUnXSgpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBzZXQgdG9rZW4gd2l0aCBtZXRob2RzIHRoYXQgcGF1c2UsY2FuY2VsIG9yIHJlc3VtZSB1cGxvYWRzJywgKCkgPT4ge1xuICAgICAgbGV0IHRva2VuID0ge307XG5cbiAgICAgIGNvbnN0IHUgPSBuZXcgVXBsb2FkKCk7XG4gICAgICB1LnNldFRva2VuKHRva2VuKTtcblxuICAgICAgdG9rZW5bJ2NhbmNlbCddKCk7XG4gICAgICB0b2tlblsncGF1c2UnXSgpO1xuICAgICAgdG9rZW5bJ3Jlc3VtZSddKCk7XG5cbiAgICAgIGV4cGVjdChTM1VwbG9hZGVyLnByb3RvdHlwZS5hYm9ydCkudG9IYXZlQmVlbkNhbGxlZCgpO1xuICAgICAgZXhwZWN0KFMzVXBsb2FkZXIucHJvdG90eXBlLnBhdXNlKS50b0hhdmVCZWVuQ2FsbGVkKCk7XG4gICAgICBleHBlY3QoUzNVcGxvYWRlci5wcm90b3R5cGUucmVzdW1lKS50b0hhdmVCZWVuQ2FsbGVkKCk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHRocm93IGFuIGVycm9yIGlmIHRva2VuIGlzIG5vdCBhbiBvYmplY3QnLCAoKSA9PiB7XG4gICAgICBjb25zdCB0b2tlbiA9ICcxMjMxMjMnO1xuXG4gICAgICBjb25zdCB1ID0gbmV3IFVwbG9hZCgpO1xuICAgICAgZXhwZWN0KCgpID0+IHtcbiAgICAgICAgdS5zZXRUb2tlbih0b2tlbik7XG4gICAgICB9KS50b1Rocm93RXJyb3IoKTtcbiAgICB9KTtcblxuICB9KTtcblxuICBkZXNjcmliZSgnVXBsb2FkJywgKCkgPT4ge1xuICAgIGJlZm9yZUVhY2goKCkgPT4ge1xuICAgICAgbW9ja0V4ZWN1dGUubW9ja1JldHVyblZhbHVlKFByb21pc2UucmVzb2x2ZShbbW9ja2VkRmlsZVJlc3BvbnNlLCBtb2NrZWRGaWxlUmVzcG9uc2VdKSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGV4ZWN1dGUgbm9ybWFsIHVwbG9hZCB3aXRob3V0IGVycm9ycyBhbmQgcmV0dXJuIHNpbmdsZSBmaWxlIHJlc3BvbnNlJywgYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3QgdSA9IG5ldyBVcGxvYWQoKTtcbiAgICAgIGNvbnN0IHJlcyA9IGF3YWl0IHUudXBsb2FkKHRlc3RCdWZmZXIpO1xuICAgICAgZXhwZWN0KHJlcykudG9FcXVhbChtb2NrZWRGaWxlUmVzcG9uc2UpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBleGVjdXRlIG5vcm1hbCB1cGxvYWQgd2l0aCBlcnJvcnMgYW5kIHJldHVybiByZWplY3RlZCBwcm9taXNlJywgKCkgPT4ge1xuICAgICAgY29uc3QgdSA9IG5ldyBVcGxvYWQoKTtcblxuICAgICAgbW9ja0V4ZWN1dGUubW9ja1JldHVyblZhbHVlKFxuICAgICAgICBQcm9taXNlLnJlc29sdmUoW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIHN0YXR1czogRmlsZVN0YXRlLkZBSUxFRCxcbiAgICAgICAgICB9LFxuICAgICAgICBdKVxuICAgICAgKTtcblxuICAgICAgcmV0dXJuIGV4cGVjdCh1LnVwbG9hZCh0ZXN0QnVmZmVyKSkucmVqZWN0cy50b0VxdWFsKHtcbiAgICAgICAgc3RhdHVzOiBGaWxlU3RhdGUuRkFJTEVELFxuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGV4ZWN1dGUgbXVsdGl1cGxvYWQgd2l0aG91dCBlcnJvcnMgYW5kIHJldHVybiBzaW5nbGUgZmlsZSByZXNwb25zZScsIGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IHUgPSBuZXcgVXBsb2FkKCk7XG4gICAgICBjb25zdCByZXMgPSBhd2FpdCB1Lm11bHRpdXBsb2FkKFt0ZXN0QnVmZmVyLCB0ZXN0QnVmZmVyXSk7XG4gICAgICBleHBlY3QocmVzKS50b0VxdWFsKFttb2NrZWRGaWxlUmVzcG9uc2UsIG1vY2tlZEZpbGVSZXNwb25zZV0pO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnUHJvZ3Jlc3MnLCAoKSA9PiB7XG4gICAgY29uc3QgcHJvZ3Jlc3MxID0ge1xuICAgICAgdG90YWxCeXRlczogMSxcbiAgICAgIHRvdGFsUGVyY2VudDogMSxcbiAgICAgIGZpbGVzOiBbXG4gICAgICAgIHtcbiAgICAgICAgICB0b3RhbEJ5dGVzOiAxLFxuICAgICAgICAgIHRvdGFsUGVyY2VudDogMSxcbiAgICAgICAgfSxcbiAgICAgIF0sXG4gICAgfTtcblxuICAgIGNvbnN0IHByb2dyZXNzNTAgPSB7XG4gICAgICB0b3RhbEJ5dGVzOiA1LFxuICAgICAgdG90YWxQZXJjZW50OiA1MCxcbiAgICAgIGZpbGVzOiBbXG4gICAgICAgIHtcbiAgICAgICAgICB0b3RhbEJ5dGVzOiA1MCxcbiAgICAgICAgICB0b3RhbFBlcmNlbnQ6IDUwLFxuICAgICAgICB9LFxuICAgICAgXSxcbiAgICB9O1xuXG4gICAgY29uc3QgcHJvZ3Jlc3MxMDAgPSB7XG4gICAgICB0b3RhbEJ5dGVzOiAxMDAsXG4gICAgICB0b3RhbFBlcmNlbnQ6IDEwMCxcbiAgICAgIGZpbGVzOiBbXG4gICAgICAgIHtcbiAgICAgICAgICB0b3RhbEJ5dGVzOiAxMDAsXG4gICAgICAgICAgdG90YWxQZXJjZW50OiAxMDAsXG4gICAgICAgIH0sXG4gICAgICBdLFxuICAgIH07XG5cbiAgICBpdCgnc2hvdWxkIGhhbmRsZSBjb3JyZWN0IHByb2dyZXNzIGV2ZW50JywgYXN5bmMgKCkgPT4ge1xuICAgICAgamVzdC5zcHlPbihTM1VwbG9hZGVyLnByb3RvdHlwZSwgJ29uJykubW9ja0ltcGxlbWVudGF0aW9uKChldiwgY2IpID0+IHtcbiAgICAgICAgY2IocHJvZ3Jlc3MxKTtcbiAgICAgICAgY2IocHJvZ3Jlc3MxMDApO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgIH0pO1xuXG4gICAgICBjb25zdCBwcm9ncmVzc01vY2sgPSBqZXN0LmZuKCk7XG5cbiAgICAgIGNvbnN0IHUgPSBuZXcgVXBsb2FkKHtcbiAgICAgICAgb25Qcm9ncmVzczogcHJvZ3Jlc3NNb2NrLFxuICAgICAgfSk7XG5cbiAgICAgIGF3YWl0IHUudXBsb2FkKHRlc3RCdWZmZXIpO1xuXG4gICAgICBleHBlY3QocHJvZ3Jlc3NNb2NrKS50b0hhdmVCZWVuQ2FsbGVkV2l0aChwcm9ncmVzczEwMCk7XG4gICAgICBleHBlY3QocHJvZ3Jlc3NNb2NrKS50b0hhdmVCZWVuQ2FsbGVkVGltZXMoMSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGNhbGwgcHJvZ3Jlc3MgZXZlbnQgb24gZ2l2ZW4gaW50ZXJ2YWwnLCBhc3luYyAoKSA9PiB7XG4gICAgICBsZXQgcHJvZ3Jlc3NDYjtcblxuICAgICAgbW9ja0V4ZWN1dGUubW9ja0ltcGxlbWVudGF0aW9uKCgpID0+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKHJlc29sdmUgPT4ge1xuICAgICAgICAgIHNldFRpbWVvdXQoKCkgPT4gcHJvZ3Jlc3NDYihwcm9ncmVzczEpLCAxKTtcbiAgICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHByb2dyZXNzQ2IocHJvZ3Jlc3M1MCksIDIpO1xuICAgICAgICAgIHNldFRpbWVvdXQoKCkgPT4gcHJvZ3Jlc3NDYihwcm9ncmVzczEwMCksIDMpO1xuICAgICAgICAgIHNldFRpbWVvdXQoKCkgPT4gcmVzb2x2ZShbXSksIDQpO1xuXG4gICAgICAgICAgamVzdC5hZHZhbmNlVGltZXJzQnlUaW1lKDQpO1xuICAgICAgICB9KTtcbiAgICAgIH0pO1xuXG4gICAgICBqZXN0LnNweU9uKFMzVXBsb2FkZXIucHJvdG90eXBlLCAnb24nKS5tb2NrSW1wbGVtZW50YXRpb24oKGV2LCBjYikgPT4ge1xuICAgICAgICBwcm9ncmVzc0NiID0gY2I7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgfSk7XG5cbiAgICAgIGNvbnN0IHByb2dyZXNzTW9jayA9IGplc3QuZm4oKTtcblxuICAgICAgY29uc3QgdSA9IG5ldyBVcGxvYWQoe1xuICAgICAgICBwcm9ncmVzc0ludGVydmFsOiAxLFxuICAgICAgICBvblByb2dyZXNzOiBwcm9ncmVzc01vY2ssXG4gICAgICB9KTtcblxuICAgICAgYXdhaXQgdS5tdWx0aXVwbG9hZChbdGVzdEJ1ZmZlcl0pO1xuXG4gICAgICBleHBlY3QocHJvZ3Jlc3NNb2NrKS50b0hhdmVCZWVuQ2FsbGVkV2l0aChwcm9ncmVzczEpO1xuICAgICAgZXhwZWN0KHByb2dyZXNzTW9jaykudG9IYXZlQmVlbkNhbGxlZFdpdGgocHJvZ3Jlc3M1MCk7XG4gICAgICBleHBlY3QocHJvZ3Jlc3NNb2NrKS50b0hhdmVCZWVuQ2FsbGVkV2l0aChwcm9ncmVzczEwMCk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHN0YXkgYXQgdGhlIHNhbWUgcHJvZ3Jlc3Mgd2hlbiB1cGxvYWRlciBnb2VzIGJhY2sgd2l0aCBmaWxlIHByb2dyZXNzJywgYXN5bmMgKCkgPT4ge1xuICAgICAgbGV0IHByb2dyZXNzQ2I7XG5cbiAgICAgIG1vY2tFeGVjdXRlLm1vY2tJbXBsZW1lbnRhdGlvbigoKSA9PiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZShyZXNvbHZlID0+IHtcbiAgICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHByb2dyZXNzQ2IocHJvZ3Jlc3M1MCksIDEpO1xuICAgICAgICAgIHNldFRpbWVvdXQoKCkgPT4gcHJvZ3Jlc3NDYihwcm9ncmVzczEpLCAyKTtcbiAgICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHByb2dyZXNzQ2IocHJvZ3Jlc3MxMDApLCAzKTtcbiAgICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHJlc29sdmUoW10pLCA0KTtcblxuICAgICAgICAgIGplc3QuYWR2YW5jZVRpbWVyc0J5VGltZSg0KTtcbiAgICAgICAgfSk7XG4gICAgICB9KTtcblxuICAgICAgamVzdC5zcHlPbihTM1VwbG9hZGVyLnByb3RvdHlwZSwgJ29uJykubW9ja0ltcGxlbWVudGF0aW9uKChldiwgY2IpID0+IHtcbiAgICAgICAgcHJvZ3Jlc3NDYiA9IGNiO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgIH0pO1xuXG4gICAgICBjb25zdCBwcm9ncmVzc01vY2sgPSBqZXN0LmZuKCk7XG5cbiAgICAgIGNvbnN0IHUgPSBuZXcgVXBsb2FkKHtcbiAgICAgICAgcHJvZ3Jlc3NJbnRlcnZhbDogMSxcbiAgICAgICAgb25Qcm9ncmVzczogcHJvZ3Jlc3NNb2NrLFxuICAgICAgfSk7XG5cbiAgICAgIGF3YWl0IHUubXVsdGl1cGxvYWQoW3Rlc3RCdWZmZXJdKTtcblxuICAgICAgZXhwZWN0KHByb2dyZXNzTW9jaykudG9IYXZlQmVlbkNhbGxlZFdpdGgocHJvZ3Jlc3M1MCk7XG4gICAgICBleHBlY3QocHJvZ3Jlc3NNb2NrKS50b0hhdmVCZWVuQ2FsbGVkV2l0aChwcm9ncmVzczUwKTtcbiAgICAgIGV4cGVjdChwcm9ncmVzc01vY2spLnRvSGF2ZUJlZW5DYWxsZWRXaXRoKHByb2dyZXNzMTAwKTtcbiAgICB9KTtcbiAgfSk7XG59KTtcbiJdfQ==
;