filestack-js
Version:
Official JavaScript library for Filestack
393 lines (391 loc) • 47.5 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
var tslib_1 = require("tslib");
/*
* Copyright (c) 2018 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.
*/
var filestack_error_1 = require("./../filestack_error");
var config_1 = require("./../config");
var client_1 = require("./client");
var cloud_1 = require("./api/cloud");
var upload_1 = require("./api/upload/upload");
var picker_1 = require("./picker");
var preview_1 = require("./api/preview");
var file_1 = require("./api/file");
var store_1 = require("./api/store");
var transform_1 = require("./api/transform");
jest.mock('./api/upload/upload');
jest.mock('./api/cloud');
jest.mock('./api/file');
jest.mock('./api/store');
jest.mock('./picker');
jest.mock('./api/preview');
jest.mock('./api/transform');
describe('client', function () {
var defaultApikey = 'EXAMPLE_API_KEY';
var defaultHandle = 'EXAMPLE_HANDLE';
var defaultSecurity = {
policy: 'examplePolicy',
signature: 'exampleSignature',
};
var sessionURls = config_1.config.urls;
var defaultSession = {
apikey: defaultApikey,
urls: sessionURls,
};
it('should properly instantiate Client', function () {
var client = new client_1.Client(defaultApikey);
expect(client).toBeDefined();
expect(client).toBeInstanceOf(client_1.Client);
});
it('should throw an error if api key not provided', function () {
expect(function () {
return new client_1.Client('');
}).toThrow('An apikey is required to initialize the Filestack client');
});
it('should throw an error if provided security without signature', function () {
var options = {
security: {
policy: 'examplePolicy',
signature: '',
},
};
expect(function () {
return new client_1.Client(defaultApikey, options);
}).toThrow('Both policy and signature are required for client security');
});
it('should pass policy & signature to the session', function () {
var options = {
security: defaultSecurity,
};
var client = new client_1.Client(defaultApikey, options);
expect(client.session.policy).toBe(options.security.policy);
expect(client.session.signature).toBe(options.security.signature);
});
it('should pass cname to the session', function () {
var options = {
cname: 'testCname.com',
};
var client = new client_1.Client(defaultApikey, options);
expect(client.session.cname).toBe(options.cname);
});
it('should be able to logout for provied cloud', function () { return tslib_1.__awaiter(void 0, void 0, void 0, function () {
var client, cloudName;
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0:
client = new client_1.Client(defaultApikey);
cloudName = 'dropbox';
return [4 /*yield*/, client.logout(cloudName)];
case 1:
_a.sent();
expect(cloud_1.CloudClient.prototype.logout).toHaveBeenCalledWith(cloudName);
return [2 /*return*/];
}
});
}); });
it('should get metadata for a provided handle', function () { return tslib_1.__awaiter(void 0, void 0, void 0, function () {
var client, options;
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0:
client = new client_1.Client(defaultApikey);
options = {
sha224: true,
};
return [4 /*yield*/, client.metadata(defaultHandle, options, defaultSecurity)];
case 1:
_a.sent();
expect(file_1.metadata).toHaveBeenCalledWith(defaultSession, defaultHandle, options, defaultSecurity);
return [2 /*return*/];
}
});
}); });
it('should be able to open picker', function () {
var client = new client_1.Client(defaultApikey);
var pickerOptions = {
lang: 'de',
};
client.picker(pickerOptions);
expect(picker_1.picker).toHaveBeenCalledWith(client, pickerOptions);
});
it('should be able to open preview', function () {
var client = new client_1.Client(defaultApikey);
var previewOptions = {
id: 'testElement',
};
client.preview(defaultHandle, previewOptions);
expect(preview_1.preview).toHaveBeenCalledWith(defaultSession, defaultHandle, previewOptions);
});
it('should be able to remove handle', function () { return tslib_1.__awaiter(void 0, void 0, void 0, function () {
var client;
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0:
client = new client_1.Client(defaultApikey);
return [4 /*yield*/, client.remove(defaultHandle, defaultSecurity)];
case 1:
_a.sent();
expect(file_1.remove).toHaveBeenCalledWith(defaultSession, defaultHandle, false, defaultSecurity);
return [2 /*return*/];
}
});
}); });
it('should be able to remove metadata', function () { return tslib_1.__awaiter(void 0, void 0, void 0, function () {
var client;
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0:
client = new client_1.Client(defaultApikey);
return [4 /*yield*/, client.removeMetadata(defaultHandle, defaultSecurity)];
case 1:
_a.sent();
expect(file_1.remove).toHaveBeenCalledWith(defaultSession, defaultHandle, true, defaultSecurity);
return [2 /*return*/];
}
});
}); });
it('should be able to store url', function () { return tslib_1.__awaiter(void 0, void 0, void 0, function () {
var client, url, options, token, uploadTags, headers, workflowIds;
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0:
client = new client_1.Client(defaultApikey);
url = 'http://example.com/img3.jpg';
options = {};
token = {};
uploadTags = { test: '123' };
headers = { 'test': '123' };
workflowIds = ['123', '321'];
return [4 /*yield*/, client.storeURL(url, options, token, defaultSecurity, uploadTags, headers, workflowIds)];
case 1:
_a.sent();
expect(store_1.storeURL).toHaveBeenCalledWith({
session: defaultSession,
url: url,
storeParams: options,
token: token,
security: defaultSecurity,
uploadTags: uploadTags,
headers: headers,
workflowIds: workflowIds,
});
return [2 /*return*/];
}
});
}); });
it('should be able to retrieve handle', function () { return tslib_1.__awaiter(void 0, void 0, void 0, function () {
var client, retrieveOptions;
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0:
client = new client_1.Client(defaultApikey);
retrieveOptions = {};
return [4 /*yield*/, client.retrieve(defaultHandle, retrieveOptions, defaultSecurity)];
case 1:
_a.sent();
expect(file_1.retrieve).toHaveBeenCalledWith(defaultSession, defaultHandle, retrieveOptions, defaultSecurity);
return [2 /*return*/];
}
});
}); });
it('should be able to transform url with b64', function () {
var client = new client_1.Client(defaultApikey);
var transformOptions = {
blur: {
amount: 5,
},
};
var b64 = true;
client.transform(defaultHandle, transformOptions, b64);
expect(transform_1.transform).toHaveBeenCalledWith(defaultSession, defaultHandle, transformOptions, b64);
});
it('should be able to transform url without b64', function () {
var client = new client_1.Client(defaultApikey);
var transformOptions = {
blur: {
amount: 5,
},
};
client.transform(defaultHandle, transformOptions);
expect(transform_1.transform).toHaveBeenCalledWith(defaultSession, defaultHandle, transformOptions, false);
});
it('should be able to upload file', function () { return tslib_1.__awaiter(void 0, void 0, void 0, function () {
var client, file, uploadOptions, storeOptions, token;
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0:
client = new client_1.Client(defaultApikey);
file = 'anyFile';
uploadOptions = {};
storeOptions = {};
token = {};
jest.spyOn(upload_1.Upload.prototype, 'upload').mockImplementation(function () { return Promise.resolve(); });
return [4 /*yield*/, client.upload(file, uploadOptions, storeOptions, token, defaultSecurity)];
case 1:
_a.sent();
expect(upload_1.Upload.prototype.setSession).toHaveBeenCalledWith({
apikey: defaultApikey,
urls: sessionURls,
});
expect(upload_1.Upload.prototype.setToken).toHaveBeenCalledWith(token);
expect(upload_1.Upload.prototype.setSecurity).toHaveBeenCalledWith(defaultSecurity);
expect(upload_1.Upload.prototype.upload).toHaveBeenCalledWith(file);
return [2 /*return*/];
}
});
}); });
it('should be able to upload file with alt text', function () { return tslib_1.__awaiter(void 0, void 0, void 0, function () {
var client, file, uploadOptions, storeOptions, token;
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0:
client = new client_1.Client(defaultApikey);
file = 'anyFile';
uploadOptions = {};
storeOptions = {};
token = {};
jest.spyOn(upload_1.Upload.prototype, 'upload').mockImplementation(function () { return Promise.resolve(); });
return [4 /*yield*/, client.upload(file, uploadOptions, storeOptions, token, defaultSecurity)];
case 1:
_a.sent();
expect(upload_1.Upload.prototype.setSession).toHaveBeenCalledWith({
apikey: defaultApikey,
urls: sessionURls,
});
expect(upload_1.Upload.prototype.setToken).toHaveBeenCalledWith(token);
expect(upload_1.Upload.prototype.setSecurity).toHaveBeenCalledWith(defaultSecurity);
expect(upload_1.Upload.prototype.upload).toHaveBeenCalledWith(file);
return [2 /*return*/];
}
});
}); });
it('should be able to upload file without token and security', function () { return tslib_1.__awaiter(void 0, void 0, void 0, function () {
var client, file, uploadOptions, storeOptions;
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0:
client = new client_1.Client(defaultApikey);
file = 'anyFile';
uploadOptions = {};
storeOptions = {};
jest.spyOn(upload_1.Upload.prototype, 'upload').mockImplementation(function () { return Promise.resolve(); });
return [4 /*yield*/, client.upload(file, uploadOptions, storeOptions)];
case 1:
_a.sent();
expect(upload_1.Upload.prototype.setSession).toHaveBeenCalledWith({
apikey: defaultApikey,
urls: sessionURls,
});
expect(upload_1.Upload.prototype.upload).toHaveBeenCalledWith(file);
return [2 /*return*/];
}
});
}); });
it('should emit error', function () { return tslib_1.__awaiter(void 0, void 0, void 0, function () {
var client, file, uploadOptions, storeOptions, token, mockOnError, test;
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0:
client = new client_1.Client(defaultApikey);
file = 'anyFile';
uploadOptions = {};
storeOptions = {};
token = {};
mockOnError = jest.fn().mockName('mockOnError');
test = new filestack_error_1.FilestackError('test');
client.on('upload.error', mockOnError);
jest.spyOn(upload_1.Upload.prototype, 'on').mockImplementation(function (name, cb, ctx) { return cb(test); });
return [4 /*yield*/, client.upload(file, uploadOptions, storeOptions, token, defaultSecurity)];
case 1:
_a.sent();
expect(mockOnError).toHaveBeenCalledWith(test);
return [2 /*return*/];
}
});
}); });
it('should be able to multiupload file', function () { return tslib_1.__awaiter(void 0, void 0, void 0, function () {
var client, files, uploadOptions, storeOptions, token;
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0:
client = new client_1.Client(defaultApikey);
files = ['anyFile'];
uploadOptions = {};
storeOptions = {};
token = {};
jest.spyOn(upload_1.Upload.prototype, 'multiupload').mockImplementation(function () { return Promise.resolve(); });
return [4 /*yield*/, client.multiupload(files, uploadOptions, storeOptions, token, defaultSecurity)];
case 1:
_a.sent();
expect(upload_1.Upload.prototype.setSession).toHaveBeenCalledWith({
apikey: defaultApikey,
urls: sessionURls,
});
expect(upload_1.Upload.prototype.setToken).toHaveBeenCalledWith(token);
expect(upload_1.Upload.prototype.setSecurity).toHaveBeenCalledWith(defaultSecurity);
expect(upload_1.Upload.prototype.multiupload).toHaveBeenCalledWith(files);
return [2 /*return*/];
}
});
}); });
it('should call multiupload without security or token', function () { return tslib_1.__awaiter(void 0, void 0, void 0, function () {
var client, files, uploadOptions, storeOptions;
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0:
client = new client_1.Client(defaultApikey);
files = ['anyFile'];
uploadOptions = {};
storeOptions = {};
jest.spyOn(upload_1.Upload.prototype, 'multiupload').mockImplementation(function () { return Promise.resolve(); });
return [4 /*yield*/, client.multiupload(files, uploadOptions, storeOptions)];
case 1:
_a.sent();
expect(upload_1.Upload.prototype.setSession).toHaveBeenCalledWith({
apikey: defaultApikey,
urls: sessionURls,
});
expect(upload_1.Upload.prototype.multiupload).toHaveBeenCalledWith(files);
return [2 /*return*/];
}
});
}); });
it('should emit error for multiupload', function () { return tslib_1.__awaiter(void 0, void 0, void 0, function () {
var client, files, uploadOptions, storeOptions, token, mockOnError, test;
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0:
client = new client_1.Client(defaultApikey);
files = ['anyFile'];
uploadOptions = {};
storeOptions = {};
token = {};
jest.spyOn(upload_1.Upload.prototype, 'multiupload').mockImplementation(function () { return Promise.resolve(); });
mockOnError = jest.fn().mockName('mockOnError');
test = new filestack_error_1.FilestackError('test');
client.on('upload.error', mockOnError);
jest.spyOn(upload_1.Upload.prototype, 'on').mockImplementation(function (name, cb, ctx) { return cb(test); });
return [4 /*yield*/, client.multiupload(files, uploadOptions, storeOptions, token, defaultSecurity)];
case 1:
_a.sent();
expect(mockOnError).toHaveBeenCalledWith(test);
return [2 /*return*/];
}
});
}); });
});
//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9saWIvY2xpZW50LnNwZWMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUE7Ozs7Ozs7Ozs7Ozs7OztHQWVHO0FBQ0gsd0RBQXNEO0FBQ3RELHNDQUFxQztBQUNyQyxtQ0FBa0M7QUFDbEMscUNBQTBDO0FBQzFDLDhDQUE2QztBQUM3QyxtQ0FBa0M7QUFDbEMseUNBQXdDO0FBQ3hDLG1DQUF3RDtBQUN4RCxxQ0FBdUM7QUFDdkMsNkNBQTRDO0FBRTVDLElBQUksQ0FBQyxJQUFJLENBQUMscUJBQXFCLENBQUMsQ0FBQztBQUNqQyxJQUFJLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxDQUFDO0FBQ3pCLElBQUksQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLENBQUM7QUFDeEIsSUFBSSxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsQ0FBQztBQUN6QixJQUFJLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDO0FBQ3RCLElBQUksQ0FBQyxJQUFJLENBQUMsZUFBZSxDQUFDLENBQUM7QUFDM0IsSUFBSSxDQUFDLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDO0FBRTdCLFFBQVEsQ0FBQyxRQUFRLEVBQUU7SUFDakIsSUFBTSxhQUFhLEdBQUcsaUJBQWlCLENBQUM7SUFDeEMsSUFBTSxhQUFhLEdBQUcsZ0JBQWdCLENBQUM7SUFDdkMsSUFBTSxlQUFlLEdBQUc7UUFDdEIsTUFBTSxFQUFFLGVBQWU7UUFDdkIsU0FBUyxFQUFFLGtCQUFrQjtLQUM5QixDQUFDO0lBRUYsSUFBTSxXQUFXLEdBQUcsZUFBTSxDQUFDLElBQUksQ0FBQztJQUNoQyxJQUFNLGNBQWMsR0FBRztRQUNyQixNQUFNLEVBQUUsYUFBYTtRQUNyQixJQUFJLEVBQUUsV0FBVztLQUNsQixDQUFDO0lBRUYsRUFBRSxDQUFDLG9DQUFvQyxFQUFFO1FBQ3ZDLElBQU0sTUFBTSxHQUFHLElBQUksZUFBTSxDQUFDLGFBQWEsQ0FBQyxDQUFDO1FBQ3pDLE1BQU0sQ0FB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QixDQUFpQixDQUFDLENBQUM7b0JBRWxGLFdBQVcsR0FBRyxJQUFJLENBQUMsRUFBRSxFQUFFLENBQUMsUUFBUSxDQUFDLGFBQWEsQ0FBQyxDQUFDO29CQUVoRCxJQUFJLEdBQUcsSUFBSSxnQ0FBYyxDQUFDLE1BQU0sQ0FBQyxDQUFDO29CQUV4QyxNQUFNLENBQUMsRUFBRSxDQUFDLGNBQWMsRUFBRSxXQUFXLENBQUMsQ0FBQztvQkFFdkMsSUFBSSxDQUFDLEtBQUssQ0FBQyxlQUFNLENBQUMsU0FBUyxFQUFFLElBQUksQ0FBQyxDQUFDLGtCQUFrQixDQUFDLFVBQUMsSUFBSSxFQUFFLEVBQUUsRUFBRSxHQUFHLElBQVUsT0FBQSxFQUFFLENBQUMsSUFBSSxDQUFDLEVBQVIsQ0FBUSxDQUFDLENBQUM7b0JBRXhGLHFCQUFNLE1BQU0sQ0FBQyxXQUFXLENBQUMsS0FBSyxFQUFFLGFBQWEsRUFBRSxZQUFZLEVBQUUsS0FBSyxFQUFFLGVBQWUsQ0FBQyxFQUFBOztvQkFBcEYsU0FBb0YsQ0FBQztvQkFFckYsTUFBTSxDQUFDLFdBQVcsQ0FBQyxDQUFDLG9CQUFvQixDQUFDLElBQUksQ0FBQyxDQUFDOzs7O1NBQ2hELENBQUMsQ0FBQztBQUNMLENBQUMsQ0FBQyxDQUFDIiwiZmlsZSI6ImxpYi9jbGllbnQuc3BlYy5qcyIsInNvdXJjZXNDb250ZW50IjpbIi8qXG4gKiBDb3B5cmlnaHQgKGMpIDIwMTggYnkgRmlsZXN0YWNrLlxuICogU29tZSByaWdodHMgcmVzZXJ2ZWQuXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICovXG5pbXBvcnQgeyBGaWxlc3RhY2tFcnJvciB9IGZyb20gJy4vLi4vZmlsZXN0YWNrX2Vycm9yJztcbmltcG9ydCB7IGNvbmZpZyB9IGZyb20gJy4vLi4vY29uZmlnJztcbmltcG9ydCB7IENsaWVudCB9IGZyb20gJy4vY2xpZW50JztcbmltcG9ydCB7IENsb3VkQ2xpZW50IH0gZnJvbSAnLi9hcGkvY2xvdWQnO1xuaW1wb3J0IHsgVXBsb2FkIH0gZnJvbSAnLi9hcGkvdXBsb2FkL3VwbG9hZCc7XG5pbXBvcnQgeyBwaWNrZXIgfSBmcm9tICcuL3BpY2tlcic7XG5pbXBvcnQgeyBwcmV2aWV3IH0gZnJvbSAnLi9hcGkvcHJldmlldyc7XG5pbXBvcnQgeyBtZXRhZGF0YSwgcmVtb3ZlLCByZXRyaWV2ZSB9IGZyb20gJy4vYXBpL2ZpbGUnO1xuaW1wb3J0IHsgc3RvcmVVUkwgfSBmcm9tICcuL2FwaS9zdG9yZSc7XG5pbXBvcnQgeyB0cmFuc2Zvcm0gfSBmcm9tICcuL2FwaS90cmFuc2Zvcm0nO1xuXG5qZXN0Lm1vY2soJy4vYXBpL3VwbG9hZC91cGxvYWQnKTtcbmplc3QubW9jaygnLi9hcGkvY2xvdWQnKTtcbmplc3QubW9jaygnLi9hcGkvZmlsZScpO1xuamVzdC5tb2NrKCcuL2FwaS9zdG9yZScpO1xuamVzdC5tb2NrKCcuL3BpY2tlcicpO1xuamVzdC5tb2NrKCcuL2FwaS9wcmV2aWV3Jyk7XG5qZXN0Lm1vY2soJy4vYXBpL3RyYW5zZm9ybScpO1xuXG5kZXNjcmliZSgnY2xpZW50JywgKCkgPT4ge1xuICBjb25zdCBkZWZhdWx0QXBpa2V5ID0gJ0VYQU1QTEVfQVBJX0tFWSc7XG4gIGNvbnN0IGRlZmF1bHRIYW5kbGUgPSAnRVhBTVBMRV9IQU5ETEUnO1xuICBjb25zdCBkZWZhdWx0U2VjdXJpdHkgPSB7XG4gICAgcG9saWN5OiAnZXhhbXBsZVBvbGljeScsXG4gICAgc2lnbmF0dXJlOiAnZXhhbXBsZVNpZ25hdHVyZScsXG4gIH07XG5cbiAgY29uc3Qgc2Vzc2lvblVSbHMgPSBjb25maWcudXJscztcbiAgY29uc3QgZGVmYXVsdFNlc3Npb24gPSB7XG4gICAgYXBpa2V5OiBkZWZhdWx0QXBpa2V5LFxuICAgIHVybHM6IHNlc3Npb25VUmxzLFxuICB9O1xuXG4gIGl0KCdzaG91bGQgcHJvcGVybHkgaW5zdGFudGlhdGUgQ2xpZW50JywgKCkgPT4ge1xuICAgIGNvbnN0IGNsaWVudCA9IG5ldyBDbGllbnQoZGVmYXVsdEFwaWtleSk7XG4gICAgZXhwZWN0KGNsaWVudCkudG9CZURlZmluZWQoKTtcbiAgICBleHBlY3QoY2xpZW50KS50b0JlSW5zdGFuY2VPZihDbGllbnQpO1xuICB9KTtcblxuICBpdCgnc2hvdWxkIHRocm93IGFuIGVycm9yIGlmIGFwaSBrZXkgbm90IHByb3ZpZGVkJywgKCkgPT4ge1xuICAgIGV4cGVjdCgoKSA9PiB7XG4gICAgICByZXR1cm4gbmV3IENsaWVudCgnJyk7XG4gICAgfSkudG9UaHJvdygnQW4gYXBpa2V5IGlzIHJlcXVpcmVkIHRvIGluaXRpYWxpemUgdGhlIEZpbGVzdGFjayBjbGllbnQnKTtcbiAgfSk7XG5cbiAgaXQoJ3Nob3VsZCB0aHJvdyBhbiBlcnJvciBpZiBwcm92aWRlZCBzZWN1cml0eSB3aXRob3V0IHNpZ25hdHVyZScsICgpID0+IHtcbiAgICBjb25zdCBvcHRpb25zID0ge1xuICAgICAgc2VjdXJpdHk6IHtcbiAgICAgICAgcG9saWN5OiAnZXhhbXBsZVBvbGljeScsXG4gICAgICAgIHNpZ25hdHVyZTogJycsXG4gICAgICB9LFxuICAgIH07XG4gICAgZXhwZWN0KCgpID0+IHtcbiAgICAgIHJldHVybiBuZXcgQ2xpZW50KGRlZmF1bHRBcGlrZXksIG9wdGlvbnMpO1xuICAgIH0pLnRvVGhyb3coJ0JvdGggcG9saWN5IGFuZCBzaWduYXR1cmUgYXJlIHJlcXVpcmVkIGZvciBjbGllbnQgc2VjdXJpdHknKTtcbiAgfSk7XG5cbiAgaXQoJ3Nob3VsZCBwYXNzIHBvbGljeSAmIHNpZ25hdHVyZSB0byB0aGUgc2Vzc2lvbicsICgpID0+IHtcbiAgICBjb25zdCBvcHRpb25zID0ge1xuICAgICAgc2VjdXJpdHk6IGRlZmF1bHRTZWN1cml0eSxcbiAgICB9O1xuICAgIGNvbnN0IGNsaWVudCA9IG5ldyBDbGllbnQoZGVmYXVsdEFwaWtleSwgb3B0aW9ucyk7XG4gICAgZXhwZWN0KGNsaWVudC5zZXNzaW9uLnBvbGljeSkudG9CZShvcHRpb25zLnNlY3VyaXR5LnBvbGljeSk7XG4gICAgZXhwZWN0KGNsaWVudC5zZXNzaW9uLnNpZ25hdHVyZSkudG9CZShvcHRpb25zLnNlY3VyaXR5LnNpZ25hdHVyZSk7XG4gIH0pO1xuXG4gIGl0KCdzaG91bGQgcGFzcyBjbmFtZSB0byB0aGUgc2Vzc2lvbicsICgpID0+IHtcbiAgICBjb25zdCBvcHRpb25zID0ge1xuICAgICAgY25hbWU6ICd0ZXN0Q25hbWUuY29tJyxcbiAgICB9O1xuICAgIGNvbnN0IGNsaWVudCA9IG5ldyBDbGllbnQoZGVmYXVsdEFwaWtleSwgb3B0aW9ucyk7XG4gICAgZXhwZWN0KGNsaWVudC5zZXNzaW9uLmNuYW1lKS50b0JlKG9wdGlvbnMuY25hbWUpO1xuICB9KTtcblxuICBpdCgnc2hvdWxkIGJlIGFibGUgdG8gbG9nb3V0IGZvciBwcm92aWVkIGNsb3VkJywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IGNsaWVudCA9IG5ldyBDbGllbnQoZGVmYXVsdEFwaWtleSk7XG4gICAgY29uc3QgY2xvdWROYW1lID0gJ2Ryb3Bib3gnO1xuICAgIGF3YWl0IGNsaWVudC5sb2dvdXQoY2xvdWROYW1lKTtcblxuICAgIGV4cGVjdChDbG91ZENsaWVudC5wcm90b3R5cGUubG9nb3V0KS50b0hhdmVCZWVuQ2FsbGVkV2l0aChjbG91ZE5hbWUpO1xuICB9KTtcblxuICBpdCgnc2hvdWxkIGdldCBtZXRhZGF0YSBmb3IgYSBwcm92aWRlZCBoYW5kbGUnLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgY2xpZW50ID0gbmV3IENsaWVudChkZWZhdWx0QXBpa2V5KTtcbiAgICBjb25zdCBvcHRpb25zID0ge1xuICAgICAgc2hhMjI0OiB0cnVlLFxuICAgIH07XG5cbiAgICBhd2FpdCBjbGllbnQubWV0YWRhdGEoZGVmYXVsdEhhbmRsZSwgb3B0aW9ucywgZGVmYXVsdFNlY3VyaXR5KTtcbiAgICBleHBlY3QobWV0YWRhdGEpLnRvSGF2ZUJlZW5DYWxsZWRXaXRoKGRlZmF1bHRTZXNzaW9uLCBkZWZhdWx0SGFuZGxlLCBvcHRpb25zLCBkZWZhdWx0U2VjdXJpdHkpO1xuICB9KTtcblxuICBpdCgnc2hvdWxkIGJlIGFibGUgdG8gb3BlbiBwaWNrZXInLCAoKSA9PiB7XG4gICAgY29uc3QgY2xpZW50ID0gbmV3IENsaWVudChkZWZhdWx0QXBpa2V5KTtcbiAgICBjb25zdCBwaWNrZXJPcHRpb25zID0ge1xuICAgICAgbGFuZzogJ2RlJyxcbiAgICB9O1xuICAgIGNsaWVudC5waWNrZXIocGlja2VyT3B0aW9ucyk7XG5cbiAgICBleHBlY3QocGlja2VyKS50b0hhdmVCZWVuQ2FsbGVkV2l0aChjbGllbnQsIHBpY2tlck9wdGlvbnMpO1xuICB9KTtcblxuICBpdCgnc2hvdWxkIGJlIGFibGUgdG8gb3BlbiBwcmV2aWV3JywgKCkgPT4ge1xuICAgIGNvbnN0IGNsaWVudCA9IG5ldyBDbGllbnQoZGVmYXVsdEFwaWtleSk7XG4gICAgY29uc3QgcHJldmlld09wdGlvbnMgPSB7XG4gICAgICBpZDogJ3Rlc3RFbGVtZW50JyxcbiAgICB9O1xuICAgIGNsaWVudC5wcmV2aWV3KGRlZmF1bHRIYW5kbGUsIHByZXZpZXdPcHRpb25zKTtcblxuICAgIGV4cGVjdChwcmV2aWV3KS50b0hhdmVCZWVuQ2FsbGVkV2l0aChkZWZhdWx0U2Vzc2lvbiwgZGVmYXVsdEhhbmRsZSwgcHJldmlld09wdGlvbnMpO1xuICB9KTtcblxuICBpdCgnc2hvdWxkIGJlIGFibGUgdG8gcmVtb3ZlIGhhbmRsZScsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBjbGllbnQgPSBuZXcgQ2xpZW50KGRlZmF1bHRBcGlrZXkpO1xuICAgIGF3YWl0IGNsaWVudC5yZW1vdmUoZGVmYXVsdEhhbmRsZSwgZGVmYXVsdFNlY3VyaXR5KTtcbiAgICBleHBlY3QocmVtb3ZlKS50b0hhdmVCZWVuQ2FsbGVkV2l0aChkZWZhdWx0U2Vzc2lvbiwgZGVmYXVsdEhhbmRsZSwgZmFsc2UsIGRlZmF1bHRTZWN1cml0eSk7XG4gIH0pO1xuXG4gIGl0KCdzaG91bGQgYmUgYWJsZSB0byByZW1vdmUgbWV0YWRhdGEnLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgY2xpZW50ID0gbmV3IENsaWVudChkZWZhdWx0QXBpa2V5KTtcbiAgICBhd2FpdCBjbGllbnQucmVtb3ZlTWV0YWRhdGEoZGVmYXVsdEhhbmRsZSwgZGVmYXVsdFNlY3VyaXR5KTtcblxuICAgIGV4cGVjdChyZW1vdmUpLnRvSGF2ZUJlZW5DYWxsZWRXaXRoKGRlZmF1bHRTZXNzaW9uLCBkZWZhdWx0SGFuZGxlLCB0cnVlLCBkZWZhdWx0U2VjdXJpdHkpO1xuICB9KTtcblxuICBpdCgnc2hvdWxkIGJlIGFibGUgdG8gc3RvcmUgdXJsJywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IGNsaWVudCA9IG5ldyBDbGllbnQoZGVmYXVsdEFwaWtleSk7XG4gICAgY29uc3QgdXJsID0gJ2h0dHA6Ly9leGFtcGxlLmNvbS9pbWczLmpwZyc7XG4gICAgY29uc3Qgb3B0aW9ucyA9IHt9O1xuICAgIGNvbnN0IHRva2VuID0ge307XG4gICAgY29uc3QgdXBsb2FkVGFncyA9IHsgdGVzdDogJzEyMycgfTtcbiAgICBjb25zdCBoZWFkZXJzID0geyAndGVzdCc6ICcxMjMnIH07XG4gICAgY29uc3Qgd29ya2Zsb3dJZHMgPSBbJzEyMycsICczMjEnXTtcbiAgICBhd2FpdCBjbGllbnQuc3RvcmVVUkwodXJsLCBvcHRpb25zLCB0b2tlbiwgZGVmYXVsdFNlY3VyaXR5LCB1cGxvYWRUYWdzLGhlYWRlcnMsIHdvcmtmbG93SWRzKTtcblxuICAgIGV4cGVjdChzdG9yZVVSTCkudG9IYXZlQmVlbkNhbGxlZFdpdGgoe1xuICAgICAgc2Vzc2lvbjogZGVmYXVsdFNlc3Npb24sXG4gICAgICB1cmwsXG4gICAgICBzdG9yZVBhcmFtczogb3B0aW9ucyxcbiAgICAgIHRva2VuLFxuICAgICAgc2VjdXJpdHk6IGRlZmF1bHRTZWN1cml0eSxcbiAgICAgIHVwbG9hZFRhZ3MsXG4gICAgICBoZWFkZXJzLFxuICAgICAgd29ya2Zsb3dJZHMsXG4gICAgfSk7XG4gIH0pO1xuXG4gIGl0KCdzaG91bGQgYmUgYWJsZSB0byByZXRyaWV2ZSBoYW5kbGUnLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgY2xpZW50ID0gbmV3IENsaWVudChkZWZhdWx0QXBpa2V5KTtcbiAgICBjb25zdCByZXRyaWV2ZU9wdGlvbnMgPSB7fTtcblxuICAgIGF3YWl0IGNsaWVudC5yZXRyaWV2ZShkZWZhdWx0SGFuZGxlLCByZXRyaWV2ZU9wdGlvbnMsIGRlZmF1bHRTZWN1cml0eSk7XG4gICAgZXhwZWN0KHJldHJpZXZlKS50b0hhdmVCZWVuQ2FsbGVkV2l0aChkZWZhdWx0U2Vzc2lvbiwgZGVmYXVsdEhhbmRsZSwgcmV0cmlldmVPcHRpb25zLCBkZWZhdWx0U2VjdXJpdHkpO1xuICB9KTtcblxuICBpdCgnc2hvdWxkIGJlIGFibGUgdG8gdHJhbnNmb3JtIHVybCB3aXRoIGI2NCcsICgpID0+IHtcbiAgICBjb25zdCBjbGllbnQgPSBuZXcgQ2xpZW50KGRlZmF1bHRBcGlrZXkpO1xuICAgIGNvbnN0IHRyYW5zZm9ybU9wdGlvbnMgPSB7XG4gICAgICBibHVyOiB7XG4gICAgICAgIGFtb3VudDogNSxcbiAgICAgIH0sXG4gICAgfTtcbiAgICBjb25zdCBiNjQgPSB0cnVlO1xuICAgIGNsaWVudC50cmFuc2Zvcm0oZGVmYXVsdEhhbmRsZSwgdHJhbnNmb3JtT3B0aW9ucywgYjY0KTtcbiAgICBleHBlY3QodHJhbnNmb3JtKS50b0hhdmVCZWVuQ2FsbGVkV2l0aChkZWZhdWx0U2Vzc2lvbiwgZGVmYXVsdEhhbmRsZSwgdHJhbnNmb3JtT3B0aW9ucywgYjY0KTtcbiAgfSk7XG5cbiAgaXQoJ3Nob3VsZCBiZSBhYmxlIHRvIHRyYW5zZm9ybSB1cmwgd2l0aG91dCBiNjQnLCAoKSA9PiB7XG4gICAgY29uc3QgY2xpZW50ID0gbmV3IENsaWVudChkZWZhdWx0QXBpa2V5KTtcbiAgICBjb25zdCB0cmFuc2Zvcm1PcHRpb25zID0ge1xuICAgICAgYmx1cjoge1xuICAgICAgICBhbW91bnQ6IDUsXG4gICAgICB9LFxuICAgIH07XG4gICAgY2xpZW50LnRyYW5zZm9ybShkZWZhdWx0SGFuZGxlLCB0cmFuc2Zvcm1PcHRpb25zKTtcbiAgICBleHBlY3QodHJhbnNmb3JtKS50b0hhdmVCZWVuQ2FsbGVkV2l0aChkZWZhdWx0U2Vzc2lvbiwgZGVmYXVsdEhhbmRsZSwgdHJhbnNmb3JtT3B0aW9ucywgZmFsc2UpO1xuICB9KTtcblxuICBpdCgnc2hvdWxkIGJlIGFibGUgdG8gdXBsb2FkIGZpbGUnLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgY2xpZW50ID0gbmV3IENsaWVudChkZWZhdWx0QXBpa2V5KTtcbiAgICBjb25zdCBmaWxlID0gJ2FueUZpbGUnO1xuICAgIGNvbnN0IHVwbG9hZE9wdGlvbnMgPSB7fTtcbiAgICBjb25zdCBzdG9yZU9wdGlvbnMgPSB7fTtcbiAgICBjb25zdCB0b2tlbiA9IHt9O1xuXG4gICAgamVzdC5zcHlPbihVcGxvYWQucHJvdG90eXBlLCAndXBsb2FkJykubW9ja0ltcGxlbWVudGF0aW9uKCgpID0+IFByb21pc2UucmVzb2x2ZSgpKTtcblxuICAgIGF3YWl0IGNsaWVudC51cGxvYWQoZmlsZSwgdXBsb2FkT3B0aW9ucywgc3RvcmVPcHRpb25zLCB0b2tlbiwgZGVmYXVsdFNlY3VyaXR5KTtcblxuICAgIGV4cGVjdChVcGxvYWQucHJvdG90eXBlLnNldFNlc3Npb24pLnRvSGF2ZUJlZW5DYWxsZWRXaXRoKHtcbiAgICAgIGFwaWtleTogZGVmYXVsdEFwaWtleSxcbiAgICAgIHVybHM6IHNlc3Npb25VUmxzLFxuICAgIH0pO1xuXG4gICAgZXhwZWN0KFVwbG9hZC5wcm90b3R5cGUuc2V0VG9rZW4pLnRvSGF2ZUJlZW5DYWxsZWRXaXRoKHRva2VuKTtcbiAgICBleHBlY3QoVXBsb2FkLnByb3RvdHlwZS5zZXRTZWN1cml0eSkudG9IYXZlQmVlbkNhbGxlZFdpdGgoZGVmYXVsdFNlY3VyaXR5KTtcbiAgICBleHBlY3QoVXBsb2FkLnByb3RvdHlwZS51cGxvYWQpLnRvSGF2ZUJlZW5DYWxsZWRXaXRoKGZpbGUpO1xuICB9KTtcblxuICBpdCgnc2hvdWxkIGJlIGFibGUgdG8gdXBsb2FkIGZpbGUgd2l0aCBhbHQgdGV4dCcsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBjbGllbnQgPSBuZXcgQ2xpZW50KGRlZmF1bHRBcGlrZXkpO1xuICAgIGNvbnN0IGZpbGUgPSAnYW55RmlsZSc7XG4gICAgY29uc3QgdXBsb2FkT3B0aW9ucyA9IHt9O1xuICAgIGNvbnN0IHN0b3JlT3B0aW9ucyA9IHt9O1xuICAgIGNvbnN0IHRva2VuID0ge307XG5cbiAgICBqZXN0LnNweU9uKFVwbG9hZC5wcm90b3R5cGUsICd1cGxvYWQnKS5tb2NrSW1wbGVtZW50YXRpb24oKCkgPT4gUHJvbWlzZS5yZXNvbHZlKCkpO1xuXG4gICAgYXdhaXQgY2xpZW50LnVwbG9hZChmaWxlLCB1cGxvYWRPcHRpb25zLCBzdG9yZU9wdGlvbnMsIHRva2VuLCBkZWZhdWx0U2VjdXJpdHkpO1xuXG4gICAgZXhwZWN0KFVwbG9hZC5wcm90b3R5cGUuc2V0U2Vzc2lvbikudG9IYXZlQmVlbkNhbGxlZFdpdGgoe1xuICAgICAgYXBpa2V5OiBkZWZhdWx0QXBpa2V5LFxuICAgICAgdXJsczogc2Vzc2lvblVSbHMsXG4gICAgfSk7XG5cbiAgICBleHBlY3QoVXBsb2FkLnByb3RvdHlwZS5zZXRUb2tlbikudG9IYXZlQmVlbkNhbGxlZFdpdGgodG9rZW4pO1xuICAgIGV4cGVjdChVcGxvYWQucHJvdG90eXBlLnNldFNlY3VyaXR5KS50b0hhdmVCZWVuQ2FsbGVkV2l0aChkZWZhdWx0U2VjdXJpdHkpO1xuICAgIGV4cGVjdChVcGxvYWQucHJvdG90eXBlLnVwbG9hZCkudG9IYXZlQmVlbkNhbGxlZFdpdGgoZmlsZSk7XG4gIH0pO1xuXG4gIGl0KCdzaG91bGQgYmUgYWJsZSB0byB1cGxvYWQgZmlsZSB3aXRob3V0IHRva2VuIGFuZCBzZWN1cml0eScsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBjbGllbnQgPSBuZXcgQ2xpZW50KGRlZmF1bHRBcGlrZXkpO1xuICAgIGNvbnN0IGZpbGUgPSAnYW55RmlsZSc7XG4gICAgY29uc3QgdXBsb2FkT3B0aW9ucyA9IHt9O1xuICAgIGNvbnN0IHN0b3JlT3B0aW9ucyA9IHt9O1xuXG4gICAgamVzdC5zcHlPbihVcGxvYWQucHJvdG90eXBlLCAndXBsb2FkJykubW9ja0ltcGxlbWVudGF0aW9uKCgpID0+IFByb21pc2UucmVzb2x2ZSgpKTtcblxuICAgIGF3YWl0IGNsaWVudC51cGxvYWQoZmlsZSwgdXBsb2FkT3B0aW9ucywgc3RvcmVPcHRpb25zKTtcblxuICAgIGV4cGVjdChVcGxvYWQucHJvdG90eXBlLnNldFNlc3Npb24pLnRvSGF2ZUJlZW5DYWxsZWRXaXRoKHtcbiAgICAgIGFwaWtleTogZGVmYXVsdEFwaWtleSxcbiAgICAgIHVybHM6IHNlc3Npb25VUmxzLFxuICAgIH0pO1xuXG4gICAgZXhwZWN0KFVwbG9hZC5wcm90b3R5cGUudXBsb2FkKS50b0hhdmVCZWVuQ2FsbGVkV2l0aChmaWxlKTtcbiAgfSk7XG5cbiAgaXQoJ3Nob3VsZCBlbWl0IGVycm9yJywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IGNsaWVudCA9IG5ldyBDbGllbnQoZGVmYXVsdEFwaWtleSk7XG4gICAgY29uc3QgZmlsZSA9ICdhbnlGaWxlJztcbiAgICBjb25zdCB1cGxvYWRPcHRpb25zID0ge307XG4gICAgY29uc3Qgc3RvcmVPcHRpb25zID0ge307XG4gICAgY29uc3QgdG9rZW4gPSB7fTtcbiAgICBjb25zdCBtb2NrT25FcnJvciA9IGplc3QuZm4oKS5tb2NrTmFtZSgnbW9ja09uRXJyb3InKTtcblxuICAgIGNvbnN0IHRlc3QgPSBuZXcgRmlsZXN0YWNrRXJyb3IoJ3Rlc3QnKTtcblxuICAgIGNsaWVudC5vbigndXBsb2FkLmVycm9yJywgbW9ja09uRXJyb3IpO1xuXG4gICAgamVzdC5zcHlPbihVcGxvYWQucHJvdG90eXBlLCAnb24nKS5tb2NrSW1wbGVtZW50YXRpb24oKG5hbWUsIGNiLCBjdHgpOiBhbnkgPT4gY2IodGVzdCkpO1xuXG4gICAgYXdhaXQgY2xpZW50LnVwbG9hZChmaWxlLCB1cGxvYWRPcHRpb25zLCBzdG9yZU9wdGlvbnMsIHRva2VuLCBkZWZhdWx0U2VjdXJpdHkpO1xuXG4gICAgZXhwZWN0KG1vY2tPbkVycm9yKS50b0hhdmVCZWVuQ2FsbGVkV2l0aCh0ZXN0KTtcbiAgfSk7XG5cbiAgaXQoJ3Nob3VsZCBiZSBhYmxlIHRvIG11bHRpdXBsb2FkIGZpbGUnLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgY2xpZW50ID0gbmV3IENsaWVudChkZWZhdWx0QXBpa2V5KTtcbiAgICBjb25zdCBmaWxlcyA9IFsnYW55RmlsZSddO1xuICAgIGNvbnN0IHVwbG9hZE9wdGlvbnMgPSB7fTtcbiAgICBjb25zdCBzdG9yZU9wdGlvbnMgPSB7fTtcbiAgICBjb25zdCB0b2tlbiA9IHt9O1xuXG4gICAgamVzdC5zcHlPbihVcGxvYWQucHJvdG90eXBlLCAnbXVsdGl1cGxvYWQnKS5tb2NrSW1wbGVtZW50YXRpb24oKCkgPT4gUHJvbWlzZS5yZXNvbHZlKCkpO1xuXG4gICAgYXdhaXQgY2xpZW50Lm11bHRpdXBsb2FkKGZpbGVzLCB1cGxvYWRPcHRpb25zLCBzdG9yZU9wdGlvbnMsIHRva2VuLCBkZWZhdWx0U2VjdXJpdHkpO1xuXG4gICAgZXhwZWN0KFVwbG9hZC5wcm90b3R5cGUuc2V0U2Vzc2lvbikudG9IYXZlQmVlbkNhbGxlZFdpdGgoe1xuICAgICAgYXBpa2V5OiBkZWZhdWx0QXBpa2V5LFxuICAgICAgdXJsczogc2Vzc2lvblVSbHMsXG4gICAgfSk7XG5cbiAgICBleHBlY3QoVXBsb2FkLnByb3RvdHlwZS5zZXRUb2tlbikudG9IYXZlQmVlbkNhbGxlZFdpdGgodG9rZW4pO1xuICAgIGV4cGVjdChVcGxvYWQucHJvdG90eXBlLnNldFNlY3VyaXR5KS50b0hhdmVCZWVuQ2FsbGVkV2l0aChkZWZhdWx0U2VjdXJpdHkpO1xuICAgIGV4cGVjdChVcGxvYWQucHJvdG90eXBlLm11bHRpdXBsb2FkKS50b0hhdmVCZWVuQ2FsbGVkV2l0aChmaWxlcyk7XG4gIH0pO1xuXG4gIGl0KCdzaG91bGQgY2FsbCBtdWx0aXVwbG9hZCB3aXRob3V0IHNlY3VyaXR5IG9yIHRva2VuJywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IGNsaWVudCA9IG5ldyBDbGllbnQoZGVmYXVsdEFwaWtleSk7XG4gICAgY29uc3QgZmlsZXMgPSBbJ2FueUZpbGUnXTtcbiAgICBjb25zdCB1cGxvYWRPcHRpb25zID0ge307XG4gICAgY29uc3Qgc3RvcmVPcHRpb25zID0ge307XG5cbiAgICBqZXN0LnNweU9uKFVwbG9hZC5wcm90b3R5cGUsICdtdWx0aXVwbG9hZCcpLm1vY2tJbXBsZW1lbnRhdGlvbigoKSA9PiBQcm9taXNlLnJlc29sdmUoKSk7XG5cbiAgICBhd2FpdCBjbGllbnQubXVsdGl1cGxvYWQoZmlsZXMsIHVwbG9hZE9wdGlvbnMsIHN0b3JlT3B0aW9ucyk7XG5cbiAgICBleHBlY3QoVXBsb2FkLnByb3RvdHlwZS5zZXRTZXNzaW9uKS50b0hhdmVCZWVuQ2FsbGVkV2l0aCh7XG4gICAgICBhcGlrZXk6IGRlZmF1bHRBcGlrZXksXG4gICAgICB1cmxzOiBzZXNzaW9uVVJscyxcbiAgICB9KTtcblxuICAgIGV4cGVjdChVcGxvYWQucHJvdG90eXBlLm11bHRpdXBsb2FkKS50b0hhdmVCZWVuQ2FsbGVkV2l0aChmaWxlcyk7XG4gIH0pO1xuXG4gIGl0KCdzaG91bGQgZW1pdCBlcnJvciBmb3IgbXVsdGl1cGxvYWQnLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgY2xpZW50ID0gbmV3IENsaWVudChkZWZhdWx0QXBpa2V5KTtcbiAgICBjb25zdCBmaWxlcyA9IFsnYW55RmlsZSddO1xuICAgIGNvbnN0IHVwbG9hZE9wdGlvbnMgPSB7fTtcbiAgICBjb25zdCBzdG9yZU9wdGlvbnMgPSB7fTtcbiAgICBjb25zdCB0b2tlbiA9IHt9O1xuXG4gICAgamVzdC5zcHlPbihVcGxvYWQucHJvdG90eXBlLCAnbXVsdGl1cGxvYWQnKS5tb2NrSW1wbGVtZW50YXRpb24oKCkgPT4gUHJvbWlzZS5yZXNvbHZlKCkpO1xuXG4gICAgY29uc3QgbW9ja09uRXJyb3IgPSBqZXN0LmZuKCkubW9ja05hbWUoJ21vY2tPbkVycm9yJyk7XG5cbiAgICBjb25zdCB0ZXN0ID0gbmV3IEZpbGVzdGFja0Vycm9yKCd0ZXN0Jyk7XG5cbiAgICBjbGllbnQub24oJ3VwbG9hZC5lcnJvcicsIG1vY2tPbkVycm9yKTtcblxuICAgIGplc3Quc3B5T24oVXBsb2FkLnByb3RvdHlwZSwgJ29uJykubW9ja0ltcGxlbWVudGF0aW9uKChuYW1lLCBjYiwgY3R4KTogYW55ID0+IGNiKHRlc3QpKTtcblxuICAgIGF3YWl0IGNsaWVudC5tdWx0aXVwbG9hZChmaWxlcywgdXBsb2FkT3B0aW9ucywgc3RvcmVPcHRpb25zLCB0b2tlbiwgZGVmYXVsdFNlY3VyaXR5KTtcblxuICAgIGV4cGVjdChtb2NrT25FcnJvcikudG9IYXZlQmVlbkNhbGxlZFdpdGgodGVzdCk7XG4gIH0pO1xufSk7XG4iXX0=