filestack-js
Version:
Official JavaScript library for Filestack
212 lines (210 loc) • 30.1 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.
*/
import { resolveCdnUrl, resolveHost, removeEmpty, uniqueTime, uniqueId, md5, extensionToMime, sanitizeName, filterObject, b64, getVersion, cleanUpCallbacks } from './index';
import { config } from '../../config';
var v = require('../../../../package.json').version;
describe('utils:index', function () {
describe('resolveCdnUrl', function () {
var session = {
apikey: 'TEST_API_KEY',
cname: 'example.com',
urls: config.urls,
};
it('should properly resolve cdn url with hashed handle', function () {
var handle = '5aYkEQJSQCmYShsoCnZN';
var result = resolveCdnUrl(session, handle);
expect(result).toEqual('https://cdn.filestackcontent.com');
});
it('should properly resolve cdn url with src handle', function () {
var handle = 'src://test123/test.jpg';
var result = resolveCdnUrl(session, handle);
expect(result).toEqual('https://cdn.filestackcontent.com/TEST_API_KEY');
});
it('should properly resolve cdn url with hashed handle', function () {
var handle = 'https://static1.squarespace.com/static/544eb3cce4b0ef091773611f/t/59ba7ce1bd10f00dcdc80a5f/1505394087367/DSC_0527.jpg';
var result = resolveCdnUrl(session, handle);
expect(result).toEqual('https://cdn.filestackcontent.com/TEST_API_KEY');
});
it('should throw an error when using src handle or url without apikey', function () {
var handle = 'src://test123/test.jpg';
session.apikey = '';
expect(function () { resolveCdnUrl(session, handle); }).toThrow('Api key is required when storage alias is provided');
});
});
describe('resolveHost', function () {
var hosts = config.urls;
var checkHosts = function (hosts, expected) {
Object.keys(hosts).forEach(function (k) {
expect(hosts[k].indexOf(expected) > -1).toBeTruthy();
});
};
it('should return proper host', function () {
var cname = 'example.com';
var result = resolveHost(hosts, cname);
checkHosts(result, cname);
});
it('should return hosts when cname is an empty string', function () {
var cname = '';
var result = resolveHost(hosts, cname);
checkHosts(result, cname);
});
it('should be idempotent', function () {
var cname = 'stage.filestackapi.com';
var firstResult = resolveHost(hosts, cname);
var copiedResult = JSON.parse(JSON.stringify(firstResult));
var secondResult = resolveHost(copiedResult, cname);
expect(JSON.stringify(firstResult)).toEqual(JSON.stringify(secondResult));
});
});
describe('removeEmpty', function () {
it('should remove empty options from an object', function () {
var testOb = { test1: true, test2: undefined, test3: false };
expect(removeEmpty(testOb)).toEqual({ test1: true, test3: false });
});
});
describe('uniqueTime', function () {
it('should return unique times', function () {
expect(uniqueTime()).not.toEqual(uniqueTime());
});
});
describe('uniqueId', function () {
it('should get different ids each time', function () {
expect(uniqueId()).not.toEqual(uniqueId());
});
it('should return id with given length', function () {
expect(uniqueId(12).length).toEqual(12);
expect(uniqueId(4).length).toEqual(4);
});
});
describe('md5', function () {
it('should return correct md5 value', function () {
expect(md5(Buffer.from('test'))).toEqual('CY9rzUYh03PK3k6DJie09g==');
});
});
describe('getVersion', function () {
it('should return correct version from package json', function () {
expect(getVersion()).toEqual("JS-".concat(v));
});
});
describe('b64', function () {
it('should return correct b65 value', function () {
expect(b64('testtext')).toEqual('dGVzdHRleHQ=');
});
it('should escape chars to make b64 url safe string - char "/"', function () {
expect(b64('*0eijATh#"I$PR)s<uTa}{t>E"LC:L', true)).toEqual('KjBlaWpBVGgjIkkkUFIpczx1VGF9e3Q-RSJMQzpM');
});
it('should escape chars to make b64 url safe string - char ""', function () {
expect(b64('W{wpB@ckYD0O@&?!||9PS)7^+F*H8N', true)).toEqual('V3t3cEJAY2tZRDBPQCY_IXx8OVBTKTdeK0YqSDhO');
});
});
describe('sanitizeName', function () {
it('should sanitize file name with extension', function () {
expect(sanitizeName('a\\{%`"~[]#|^<>1.jpg')).toEqual('a-------------1.jpg');
});
it('should sanitize file name without extension', function () {
expect(sanitizeName('123qwe')).toEqual('123qwe');
});
it('should return undefined on empty string', function () {
expect(sanitizeName('')).toEqual('undefined');
});
it('should respect sanitize options as boolean', function () {
expect(sanitizeName('[]#|.jpg', false)).toEqual('[]#|.jpg');
});
it('should not change dots in filename', function () {
expect(sanitizeName('[]#some.tar.gz', false)).toEqual('[]#some.tar.gz');
});
it('should respect sanitize options with provided options', function () {
expect(sanitizeName('[]#|.jpg', {
exclude: ['[', ']'],
replacement: '_',
})).toEqual('__#|.jpg');
});
});
describe('filterObject', function () {
it('should filter object', function () {
expect(filterObject({
test: 1,
test2: 2,
test3: 3,
}, ['test', 'test2'])).toEqual({
test: 1,
test2: 2,
});
});
it('should result the same object on empty requirements', function () {
expect(filterObject({
test: 1,
test2: 2,
test3: 3,
}, [])).toEqual({
test: 1,
test2: 2,
test3: 3,
});
});
it('should not throw on empty filtered object', function () {
expect(filterObject({}, ['test'])).toEqual({});
});
});
describe('extensionToMime', function () {
it('should return mimetype if mime is passed', function () {
expect(extensionToMime('')).toEqual(undefined);
});
it('should return same mime is passed', function () {
expect(extensionToMime('image/png')).toEqual('image/png');
expect(extensionToMime('image/jpg')).toEqual('image/jpg');
expect(extensionToMime('application/pdf')).toEqual('application/pdf');
});
it('it should return correct mimes for ext', function () {
expect(extensionToMime('.png')).toEqual('image/png');
expect(extensionToMime('.jpg')).toEqual('image/jpeg');
expect(extensionToMime('.pdf')).toEqual('application/pdf');
expect(extensionToMime('.key')).toEqual('application/vnd.apple.keynote');
expect(extensionToMime('.zip')).toEqual('application/zip');
expect(extensionToMime('.numbers')).toEqual('application/vnd.apple.numbers');
});
it('it should extract extensions form filename or ext with dot', function () {
expect(extensionToMime('test.png')).toEqual('image/png');
expect(extensionToMime('test.jpg')).toEqual('image/jpeg');
expect(extensionToMime('test.pdf')).toEqual('application/pdf');
});
});
describe('CleanupCallbacks', function () {
it('should set callbacks as undefined and return untouched object', function () {
var testObj = {
fn: function () { return 1; },
test: {
fn2: function () { return 2; },
},
testN: 123,
tests: 'string',
testObj: {
tst: 123,
},
};
expect(cleanUpCallbacks(testObj)).toEqual({
test: {},
testN: 123,
tests: 'string',
testObj: {
tst: 123,
},
});
});
});
});
//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9saWIvdXRpbHMvaW5kZXguc3BlYy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7O0dBZUc7QUFDSCxPQUFPLEVBQUUsYUFBYSxFQUFFLFdBQVcsRUFBRSxXQUFXLEVBQUUsVUFBVSxFQUFFLFFBQVEsRUFBRSxHQUFHLEVBQUUsZUFBZSxFQUFFLFlBQVksRUFBRSxZQUFZLEVBQUUsR0FBRyxFQUFFLFVBQVUsRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLFNBQVMsQ0FBQztBQUM3SyxPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0sY0FBYyxDQUFDO0FBQ3RDLElBQU0sQ0FBQyxHQUFHLE9BQU8sQ0FBQywwQkFBMEIsQ0FBQyxDQUFDLE9BQU8sQ0FBQztBQUV0RCxRQUFRLENBQUMsYUFBYSxFQUFFO0lBQ3RCLFFBQVEsQ0FBQyxlQUFlLEVBQUU7UUFFeEIsSUFBTSxPQUFPLEdBQUc7WUFDZCxNQUFNLEVBQUUsY0FBYztZQUN0QixLQUFLLEVBQUUsYUFBYTtZQUNwQixJQUFJLEVBQUUsTUFBTSxDQUFDLElBQUk7U0FDbEIsQ0FBQztRQUVGLEVBQUUsQ0FBQyxvREFBb0QsRUFBRTtZQUN2RCxJQUFNLE1BQU0sR0FBRyxzQkFBc0IsQ0FBQztZQUN0QyxJQUFNLE1BQU0sR0FBRyxhQUFhLENBQUMsT0FBTyxFQUFFLE1BQU0sQ0FBQyxDQUFDO1lBQzlDLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQyxPQUFPLENBQUMsa0NBQWtDLENBQUMsQ0FBQztRQUM3RCxDQUFDLENBQUMsQ0FBQztRQUVILEVBQUUsQ0FBQyxpREFBaUQsRUFBRTtZQUNwRCxJQUFNLE1BQU0sR0FBRyx3QkFBd0IsQ0FBQztZQUN4QyxJQUFNLE1BQU0sR0FBRyxhQUFhLENBQUMsT0FBTyxFQUFFLE1BQU0sQ0FBQyxDQUFDO1lBQzlDLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQyxPQUFPLENBQUMsK0NBQStDLENBQUMsQ0FBQztRQUMxRSxDQUFDLENBQUMs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QUNUO2FBQ0YsQ0FBQyxDQUFDO1FBQ0wsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztBQUNMLENBQUMsQ0FBQyxDQUFDIiwiZmlsZSI6ImxpYi91dGlscy9pbmRleC5zcGVjLmpzIiwic291cmNlc0NvbnRlbnQiOlsiLypcbiAqIENvcHlyaWdodCAoYykgMjAxOSBieSBGaWxlc3RhY2suXG4gKiBTb21lIHJpZ2h0cyByZXNlcnZlZC5cbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKi9cbmltcG9ydCB7IHJlc29sdmVDZG5VcmwsIHJlc29sdmVIb3N0LCByZW1vdmVFbXB0eSwgdW5pcXVlVGltZSwgdW5pcXVlSWQsIG1kNSwgZXh0ZW5zaW9uVG9NaW1lLCBzYW5pdGl6ZU5hbWUsIGZpbHRlck9iamVjdCwgYjY0LCBnZXRWZXJzaW9uLCBjbGVhblVwQ2FsbGJhY2tzIH0gZnJvbSAnLi9pbmRleCc7XG5pbXBvcnQgeyBjb25maWcgfSBmcm9tICcuLi8uLi9jb25maWcnO1xuY29uc3QgdiA9IHJlcXVpcmUoJy4uLy4uLy4uLy4uL3BhY2thZ2UuanNvbicpLnZlcnNpb247XG5cbmRlc2NyaWJlKCd1dGlsczppbmRleCcsICgpID0+IHtcbiAgZGVzY3JpYmUoJ3Jlc29sdmVDZG5VcmwnLCAoKSA9PiB7XG5cbiAgICBjb25zdCBzZXNzaW9uID0ge1xuICAgICAgYXBpa2V5OiAnVEVTVF9BUElfS0VZJyxcbiAgICAgIGNuYW1lOiAnZXhhbXBsZS5jb20nLFxuICAgICAgdXJsczogY29uZmlnLnVybHMsXG4gICAgfTtcblxuICAgIGl0KCdzaG91bGQgcHJvcGVybHkgcmVzb2x2ZSBjZG4gdXJsIHdpdGggaGFzaGVkIGhhbmRsZScsICgpID0+IHtcbiAgICAgIGNvbnN0IGhhbmRsZSA9ICc1YVlrRVFKU1FDbVlTaHNvQ25aTic7XG4gICAgICBjb25zdCByZXN1bHQgPSByZXNvbHZlQ2RuVXJsKHNlc3Npb24sIGhhbmRsZSk7XG4gICAgICBleHBlY3QocmVzdWx0KS50b0VxdWFsKCdodHRwczovL2Nkbi5maWxlc3RhY2tjb250ZW50LmNvbScpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBwcm9wZXJseSByZXNvbHZlIGNkbiB1cmwgd2l0aCBzcmMgaGFuZGxlJywgKCkgPT4ge1xuICAgICAgY29uc3QgaGFuZGxlID0gJ3NyYzovL3Rlc3QxMjMvdGVzdC5qcGcnO1xuICAgICAgY29uc3QgcmVzdWx0ID0gcmVzb2x2ZUNkblVybChzZXNzaW9uLCBoYW5kbGUpO1xuICAgICAgZXhwZWN0KHJlc3VsdCkudG9FcXVhbCgnaHR0cHM6Ly9jZG4uZmlsZXN0YWNrY29udGVudC5jb20vVEVTVF9BUElfS0VZJyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHByb3Blcmx5IHJlc29sdmUgY2RuIHVybCB3aXRoIGhhc2hlZCBoYW5kbGUnLCAoKSA9PiB7XG4gICAgICBjb25zdCBoYW5kbGUgPSAnaHR0cHM6Ly9zdGF0aWMxLnNxdWFyZXNwYWNlLmNvbS9zdGF0aWMvNTQ0ZWIzY2NlNGIwZWYwOTE3NzM2MTFmL3QvNTliYTdjZTFiZDEwZjAwZGNkYzgwYTVmLzE1MDUzOTQwODczNjcvRFNDXzA1MjcuanBnJztcbiAgICAgIGNvbnN0IHJlc3VsdCA9IHJlc29sdmVDZG5Vcmwoc2Vzc2lvbiwgaGFuZGxlKTtcbiAgICAgIGV4cGVjdChyZXN1bHQpLnRvRXF1YWwoJ2h0dHBzOi8vY2RuLmZpbGVzdGFja2NvbnRlbnQuY29tL1RFU1RfQVBJX0tFWScpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCB0aHJvdyBhbiBlcnJvciB3aGVuIHVzaW5nIHNyYyBoYW5kbGUgb3IgdXJsIHdpdGhvdXQgYXBpa2V5JywgKCkgPT4ge1xuICAgICAgY29uc3QgaGFuZGxlID0gJ3NyYzovL3Rlc3QxMjMvdGVzdC5qcGcnO1xuICAgICAgc2Vzc2lvbi5hcGlrZXkgPSAnJztcbiAgICAgIGV4cGVjdCgoKSA9PiB7IHJlc29sdmVDZG5Vcmwoc2Vzc2lvbiwgaGFuZGxlKTsgfSkudG9UaHJvdygnQXBpIGtleSBpcyByZXF1aXJlZCB3aGVuIHN0b3JhZ2UgYWxpYXMgaXMgcHJvdmlkZWQnKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ3Jlc29sdmVIb3N0JywgKCkgPT4ge1xuICAgIGNvbnN0IGhvc3RzID0gY29uZmlnLnVybHM7XG5cbiAgICBjb25zdCBjaGVja0hvc3RzID0gKGhvc3RzLCBleHBlY3RlZCkgPT4ge1xuICAgICAgT2JqZWN0LmtleXMoaG9zdHMpLmZvckVhY2goKGspID0+IHtcbiAgICAgICAgZXhwZWN0KGhvc3RzW2tdLmluZGV4T2YoZXhwZWN0ZWQpID4gLTEpLnRvQmVUcnV0aHkoKTtcbiAgICAgIH0pO1xuICAgIH07XG5cbiAgICBpdCgnc2hvdWxkIHJldHVybiBwcm9wZXIgaG9zdCcsICgpID0+IHtcbiAgICAgIGNvbnN0IGNuYW1lID0gJ2V4YW1wbGUuY29tJztcbiAgICAgIGNvbnN0IHJlc3VsdCA9IHJlc29sdmVIb3N0KGhvc3RzLCBjbmFtZSk7XG4gICAgICBjaGVja0hvc3RzKHJlc3VsdCwgY25hbWUpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gaG9zdHMgd2hlbiBjbmFtZSBpcyBhbiBlbXB0eSBzdHJpbmcnLCAoKSA9PiB7XG4gICAgICBjb25zdCBjbmFtZSA9ICcnO1xuICAgICAgY29uc3QgcmVzdWx0ID0gcmVzb2x2ZUhvc3QoaG9zdHMsIGNuYW1lKTtcbiAgICAgIGNoZWNrSG9zdHMocmVzdWx0LCBjbmFtZSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGJlIGlkZW1wb3RlbnQnLCAoKSA9PiB7XG4gICAgICBjb25zdCBjbmFtZSA9ICdzdGFnZS5maWxlc3RhY2thcGkuY29tJztcbiAgICAgIGNvbnN0IGZpcnN0UmVzdWx0ID0gcmVzb2x2ZUhvc3QoaG9zdHMsIGNuYW1lKTtcbiAgICAgIGNvbnN0IGNvcGllZFJlc3VsdCA9IEpTT04ucGFyc2UoSlNPTi5zdHJpbmdpZnkoZmlyc3RSZXN1bHQpKTtcbiAgICAgIGNvbnN0IHNlY29uZFJlc3VsdCA9IHJlc29sdmVIb3N0KGNvcGllZFJlc3VsdCwgY25hbWUpO1xuXG4gICAgICBleHBlY3QoSlNPTi5zdHJpbmdpZnkoZmlyc3RSZXN1bHQpKS50b0VxdWFsKEpTT04uc3RyaW5naWZ5KHNlY29uZFJlc3VsdCkpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgncmVtb3ZlRW1wdHknLCAoKSA9PiB7XG4gICAgaXQoJ3Nob3VsZCByZW1vdmUgZW1wdHkgb3B0aW9ucyBmcm9tIGFuIG9iamVjdCcsICgpID0+IHtcbiAgICAgIGNvbnN0IHRlc3RPYiA9IHsgdGVzdDE6IHRydWUsIHRlc3QyOiB1bmRlZmluZWQsIHRlc3QzOiBmYWxzZSB9O1xuICAgICAgZXhwZWN0KHJlbW92ZUVtcHR5KHRlc3RPYikpLnRvRXF1YWwoeyB0ZXN0MTogdHJ1ZSwgdGVzdDM6IGZhbHNlIH0pO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgndW5pcXVlVGltZScsICgpID0+IHtcbiAgICBpdCgnc2hvdWxkIHJldHVybiB1bmlxdWUgdGltZXMnLCAoKSA9PiB7XG4gICAgICBleHBlY3QodW5pcXVlVGltZSgpKS5ub3QudG9FcXVhbCh1bmlxdWVUaW1lKCkpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgndW5pcXVlSWQnLCAoKSA9PiB7XG4gICAgaXQoJ3Nob3VsZCBnZXQgZGlmZmVyZW50IGlkcyBlYWNoIHRpbWUnLCAoKSA9PiB7XG4gICAgICBleHBlY3QodW5pcXVlSWQoKSkubm90LnRvRXF1YWwodW5pcXVlSWQoKSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJldHVybiBpZCB3aXRoIGdpdmVuIGxlbmd0aCcsICgpID0+IHtcbiAgICAgIGV4cGVjdCh1bmlxdWVJZCgxMikubGVuZ3RoKS50b0VxdWFsKDEyKTtcbiAgICAgIGV4cGVjdCh1bmlxdWVJZCg0KS5sZW5ndGgpLnRvRXF1YWwoNCk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdtZDUnLCAoKSA9PiB7XG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gY29ycmVjdCBtZDUgdmFsdWUnLCAoKSA9PiB7XG4gICAgICBleHBlY3QobWQ1KEJ1ZmZlci5mcm9tKCd0ZXN0JykpKS50b0VxdWFsKCdDWTlyelVZaDAzUEszazZESmllMDlnPT0nKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ2dldFZlcnNpb24nLCAoKSA9PiB7XG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gY29ycmVjdCB2ZXJzaW9uIGZyb20gcGFja2FnZSBqc29uJywgKCkgPT4ge1xuICAgICAgZXhwZWN0KGdldFZlcnNpb24oKSkudG9FcXVhbChgSlMtJHt2fWApO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnYjY0JywgKCkgPT4ge1xuICAgIGl0KCdzaG91bGQgcmV0dXJuIGNvcnJlY3QgYjY1IHZhbHVlJywgKCkgPT4ge1xuICAgICAgZXhwZWN0KGI2NCgndGVzdHRleHQnKSkudG9FcXVhbCgnZEdWemRIUmxlSFE9Jyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGVzY2FwZSBjaGFycyB0byBtYWtlIGI2NCB1cmwgc2FmZSBzdHJpbmcgLSBjaGFyIFwiL1wiJywgKCkgPT4ge1xuICAgICAgZXhwZWN0KGI2NCgnKjBlaWpBVGgjXCJJJFBSKXM8dVRhfXt0PkVcIkxDOkwnLCB0cnVlKSkudG9FcXVhbCgnS2pCbGFXcEJWR2dqSWtra1VGSXBjengxVkdGOWUzUS1SU0pNUXpwTScpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBlc2NhcGUgY2hhcnMgdG8gbWFrZSBiNjQgdXJsIHNhZmUgc3RyaW5nIC0gY2hhciBcIlwiJywgKCkgPT4ge1xuICAgICAgZXhwZWN0KGI2NCgnV3t3cEJAY2tZRDBPQCY/IXx8OVBTKTdeK0YqSDhOJywgdHJ1ZSkpLnRvRXF1YWwoJ1YzdDNjRUpBWTJ0WlJEQlBRQ1lfSVh4OE9WQlRLVGRlSzBZcVNEaE8nKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ3Nhbml0aXplTmFtZScsICgpID0+IHtcbiAgICBpdCgnc2hvdWxkIHNhbml0aXplIGZpbGUgbmFtZSB3aXRoIGV4dGVuc2lvbicsICgpID0+IHtcbiAgICAgIGV4cGVjdChzYW5pdGl6ZU5hbWUoJ2FcXFxceyVgXCJ+W10jfF48PjEuanBnJykpLnRvRXF1YWwoJ2EtLS0tLS0tLS0tLS0tMS5qcGcnKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgc2FuaXRpemUgZmlsZSBuYW1lIHdpdGhvdXQgZXh0ZW5zaW9uJywgKCkgPT4ge1xuICAgICAgZXhwZWN0KHNhbml0aXplTmFtZSgnMTIzcXdlJykpLnRvRXF1YWwoJzEyM3F3ZScpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gdW5kZWZpbmVkIG9uIGVtcHR5IHN0cmluZycsICgpID0+IHtcbiAgICAgIGV4cGVjdChzYW5pdGl6ZU5hbWUoJycpKS50b0VxdWFsKCd1bmRlZmluZWQnKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmVzcGVjdCBzYW5pdGl6ZSBvcHRpb25zIGFzIGJvb2xlYW4nLCAoKSA9PiB7XG4gICAgICBleHBlY3Qoc2FuaXRpemVOYW1lKCdbXSN8LmpwZycsIGZhbHNlKSkudG9FcXVhbCgnW10jfC5qcGcnKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgbm90IGNoYW5nZSBkb3RzIGluIGZpbGVuYW1lJywgKCkgPT4ge1xuICAgICAgZXhwZWN0KHNhbml0aXplTmFtZSgnW10jc29tZS50YXIuZ3onLCBmYWxzZSkpLnRvRXF1YWwoJ1tdI3NvbWUudGFyLmd6Jyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHJlc3BlY3Qgc2FuaXRpemUgb3B0aW9ucyB3aXRoIHByb3ZpZGVkIG9wdGlvbnMnLCAoKSA9PiB7XG4gICAgICBleHBlY3Qoc2FuaXRpemVOYW1lKCdbXSN8LmpwZycsIHtcbiAgICAgICAgZXhjbHVkZTogWydbJywgJ10nXSxcbiAgICAgICAgcmVwbGFjZW1lbnQ6ICdfJyxcbiAgICAgIH0pKS50b0VxdWFsKCdfXyN8LmpwZycpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnZmlsdGVyT2JqZWN0JywgKCkgPT4ge1xuICAgIGl0KCdzaG91bGQgZmlsdGVyIG9iamVjdCcsICgpID0+IHtcbiAgICAgIGV4cGVjdChmaWx0ZXJPYmplY3Qoe1xuICAgICAgICB0ZXN0OiAxLFxuICAgICAgICB0ZXN0MjogMixcbiAgICAgICAgdGVzdDM6IDMsXG4gICAgICB9LCBbJ3Rlc3QnLCAndGVzdDInXSkpLnRvRXF1YWwoe1xuICAgICAgICB0ZXN0OiAxLFxuICAgICAgICB0ZXN0MjogMixcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZXN1bHQgdGhlIHNhbWUgb2JqZWN0IG9uIGVtcHR5IHJlcXVpcmVtZW50cycsICgpID0+IHtcbiAgICAgIGV4cGVjdChmaWx0ZXJPYmplY3Qoe1xuICAgICAgICB0ZXN0OiAxLFxuICAgICAgICB0ZXN0MjogMixcbiAgICAgICAgdGVzdDM6IDMsXG4gICAgICB9LCBbXSkpLnRvRXF1YWwoe1xuICAgICAgICB0ZXN0OiAxLFxuICAgICAgICB0ZXN0MjogMixcbiAgICAgICAgdGVzdDM6IDMsXG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgbm90IHRocm93IG9uIGVtcHR5IGZpbHRlcmVkIG9iamVjdCcsICgpID0+IHtcbiAgICAgIGV4cGVjdChmaWx0ZXJPYmplY3Qoe30sIFsndGVzdCddKSkudG9FcXVhbCh7fSk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdleHRlbnNpb25Ub01pbWUnLCAoKSA9PiB7XG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gbWltZXR5cGUgaWYgbWltZSBpcyBwYXNzZWQnLCAoKSA9PiB7XG4gICAgICBleHBlY3QoZXh0ZW5zaW9uVG9NaW1lKCcnKSkudG9FcXVhbCh1bmRlZmluZWQpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gc2FtZSBtaW1lIGlzIHBhc3NlZCcsICgpID0+IHtcbiAgICAgIGV4cGVjdChleHRlbnNpb25Ub01pbWUoJ2ltYWdlL3BuZycpKS50b0VxdWFsKCdpbWFnZS9wbmcnKTtcbiAgICAgIGV4cGVjdChleHRlbnNpb25Ub01pbWUoJ2ltYWdlL2pwZycpKS50b0VxdWFsKCdpbWFnZS9qcGcnKTtcbiAgICAgIGV4cGVjdChleHRlbnNpb25Ub01pbWUoJ2FwcGxpY2F0aW9uL3BkZicpKS50b0VxdWFsKCdhcHBsaWNhdGlvbi9wZGYnKTtcbiAgICB9KTtcblxuICAgIGl0KCdpdCBzaG91bGQgcmV0dXJuIGNvcnJlY3QgbWltZXMgZm9yIGV4dCcsICgpID0+IHtcbiAgICAgIGV4cGVjdChleHRlbnNpb25Ub01pbWUoJy5wbmcnKSkudG9FcXVhbCgnaW1hZ2UvcG5nJyk7XG4gICAgICBleHBlY3QoZXh0ZW5zaW9uVG9NaW1lKCcuanBnJykpLnRvRXF1YWwoJ2ltYWdlL2pwZWcnKTtcbiAgICAgIGV4cGVjdChleHRlbnNpb25Ub01pbWUoJy5wZGYnKSkudG9FcXVhbCgnYXBwbGljYXRpb24vcGRmJyk7XG5cbiAgICAgIGV4cGVjdChleHRlbnNpb25Ub01pbWUoJy5rZXknKSkudG9FcXVhbCgnYXBwbGljYXRpb24vdm5kLmFwcGxlLmtleW5vdGUnKTtcbiAgICAgIGV4cGVjdChleHRlbnNpb25Ub01pbWUoJy56aXAnKSkudG9FcXVhbCgnYXBwbGljYXRpb24vemlwJyk7XG4gICAgICBleHBlY3QoZXh0ZW5zaW9uVG9NaW1lKCcubnVtYmVycycpKS50b0VxdWFsKCdhcHBsaWNhdGlvbi92bmQuYXBwbGUubnVtYmVycycpO1xuICAgIH0pO1xuXG4gICAgaXQoJ2l0IHNob3VsZCBleHRyYWN0IGV4dGVuc2lvbnMgZm9ybSBmaWxlbmFtZSBvciBleHQgd2l0aCBkb3QnLCAoKSA9PiB7XG4gICAgICBleHBlY3QoZXh0ZW5zaW9uVG9NaW1lKCd0ZXN0LnBuZycpKS50b0VxdWFsKCdpbWFnZS9wbmcnKTtcbiAgICAgIGV4cGVjdChleHRlbnNpb25Ub01pbWUoJ3Rlc3QuanBnJykpLnRvRXF1YWwoJ2ltYWdlL2pwZWcnKTtcbiAgICAgIGV4cGVjdChleHRlbnNpb25Ub01pbWUoJ3Rlc3QucGRmJykpLnRvRXF1YWwoJ2FwcGxpY2F0aW9uL3BkZicpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnQ2xlYW51cENhbGxiYWNrcycsICgpID0+IHtcbiAgICBpdCgnc2hvdWxkIHNldCBjYWxsYmFja3MgYXMgdW5kZWZpbmVkIGFuZCByZXR1cm4gdW50b3VjaGVkIG9iamVjdCcsICgpID0+IHtcbiAgICAgIGNvbnN0IHRlc3RPYmogPSB7XG4gICAgICAgIGZuOiAoKSA9PiAxLFxuICAgICAgICB0ZXN0OiB7XG4gICAgICAgICAgZm4yOiAoKSA9PiAyLFxuICAgICAgICB9LFxuICAgICAgICB0ZXN0TjogMTIzLFxuICAgICAgICB0ZXN0czogJ3N0cmluZycsXG4gICAgICAgIHRlc3RPYmo6IHtcbiAgICAgICAgICB0c3Q6IDEyMyxcbiAgICAgICAgfSxcbiAgICAgIH07XG5cbiAgICAgIGV4cGVjdChjbGVhblVwQ2FsbGJhY2tzKHRlc3RPYmopKS50b0VxdWFsKHtcbiAgICAgICAgdGVzdDoge30sXG4gICAgICAgIHRlc3ROOiAxMjMsXG4gICAgICAgIHRlc3RzOiAnc3RyaW5nJyxcbiAgICAgICAgdGVzdE9iajoge1xuICAgICAgICAgIHRzdDogMTIzLFxuICAgICAgICB9LFxuICAgICAgfSk7XG4gICAgfSk7XG4gIH0pO1xufSk7XG4iXX0=