computed-types
Version:
Runtime validation types for TypeScript.
314 lines (247 loc) • 33.7 kB
JavaScript
;
require("mocha");
var _chai = require("chai");
var _utils = require("./utils");
var _logic = require("./logic");
var _chaiAsPromised = _interopRequireDefault(require("chai-as-promised"));
var _string = _interopRequireDefault(require("../string"));
var _number = _interopRequireDefault(require("../number"));
var _errors = require("./errors");
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
(0, _chai.use)(_chaiAsPromised.default);
/* eslint-disable @typescript-eslint/no-explicit-any,@typescript-eslint/ban-types */
describe('schema/logic', () => {
describe('either', () => {
it('no candidates', () => {
_chai.assert.throw(() => (0, _logic.either)(...[]), RangeError);
});
it('sync candidate', () => {
const validator = (0, _logic.either)(x => {
if (x <= 0) {
throw new RangeError(`Negative input`);
}
return String(x);
});
(0, _utils.typeCheck)('ok');
_chai.assert.equal(validator(1), '1');
_chai.assert.throw(() => validator(-1), RangeError, 'Negative input');
});
it('async candidate', async () => {
const validator = (0, _logic.either)(async x => {
if (x <= 0) {
throw new RangeError(`Negative input`);
}
return String(x);
});
(0, _utils.typeCheck)('ok');
await _chai.assert.isFulfilled(validator(1));
await _chai.assert.isRejected(validator(-1));
await _chai.assert.becomes(validator(1), '1');
});
it('2 sync candidates', () => {
const validator = (0, _logic.either)(x => {
if (typeof x !== 'number' || x <= 0) {
throw new RangeError(`Negative input`);
}
return String(x);
}, x => {
if (typeof x !== 'boolean') {
throw new RangeError(`Non boolean`);
}
return x ? 1 : 0;
});
(0, _utils.typeCheck)('ok');
_chai.assert.equal(validator(1), '1');
_chai.assert.equal(validator(false), 0);
_chai.assert.throw(() => validator(''), RangeError, 'Non boolean');
});
it('[sync,async] candidates', async () => {
const validator = (0, _logic.either)(x => {
if (typeof x !== 'number' || x <= 0) {
throw new RangeError(`Negative input`);
}
return String(x);
}, async x => {
if (typeof x !== 'boolean') {
throw new RangeError(`Non boolean`);
}
return x ? 1 : 0;
});
(0, _utils.typeCheck)('ok');
_chai.assert.equal(validator(1), '1');
await _chai.assert.becomes(validator(true), 1);
await _chai.assert.isRejected(validator(''));
});
it('[async,async] candidates', async () => {
const validator = (0, _logic.either)(async x => {
if (typeof x !== 'number' || x <= 0) {
throw new RangeError(`Negative input`);
}
return String(x);
}, async x => {
if (typeof x !== 'boolean') {
throw new RangeError(`Non boolean`);
}
return x ? 1 : 0;
});
(0, _utils.typeCheck)('ok');
await _chai.assert.becomes(validator(1), '1');
await _chai.assert.becomes(validator(true), 1);
await _chai.assert.isRejected(validator(''));
});
it('use switch', () => {
const validator = (0, _logic.either)({
type: 'foo',
foo: _number.default
}, {
type: 'bar',
bar: _string.default
});
(0, _utils.typeCheck)('ok');
_chai.assert.deepEqual(validator({
type: 'foo',
foo: 2
}), {
type: 'foo',
foo: 2
});
_chai.assert.deepEqual(validator({
type: 'bar',
bar: 'hello'
}), {
type: 'bar',
bar: 'hello'
});
_chai.assert.throw(() => validator({
type: 'foo',
foo: 'dd'
}), _errors.ValidationError, 'foo: Expect value to be "number"');
_chai.assert.throw(() => validator({
type: 'bar',
foo: 'dd'
}), _errors.ValidationError, 'bar: Expect value to be "string"');
_chai.assert.throw(() => validator({
type: 'hello',
foo: 'dd'
}), _errors.ValidationError, 'type: Expect value to equal "foo"');
});
});
describe('merge', () => {
it('no items', () => {
_chai.assert.throw(() => (0, _logic.merge)(...[]), RangeError);
});
it('one item', () => {
const validator = (0, _logic.merge)('foo');
(0, _utils.typeCheck)('ok');
_chai.assert.equal(validator('foo'), 'foo');
_chai.assert.throw(() => validator('bar'), _errors.ValidationError);
});
it('never string items', () => {
const validator = (0, _logic.merge)('foo', 'bar');
(0, _utils.typeCheck)('ok');
_chai.assert.throw(() => validator('foo'), _errors.ValidationError);
_chai.assert.throw(() => validator('bar'), _errors.ValidationError);
});
it('never [string,object] items', () => {
const validator = (0, _logic.merge)('foo', {});
(0, _utils.typeCheck)('ok');
_chai.assert.throw(() => validator('foo'), _errors.ValidationError);
_chai.assert.throw(() => validator({}), _errors.ValidationError);
_chai.assert.throw(() => validator('bar'), _errors.ValidationError);
});
it('never [object,undefined] items', () => {
const validator = (0, _logic.merge)({}, undefined);
(0, _utils.typeCheck)('ok');
_chai.assert.throw(() => validator(undefined), _errors.ValidationError);
_chai.assert.throw(() => validator({}), _errors.ValidationError);
_chai.assert.throw(() => validator('bar'), _errors.ValidationError);
});
it('merging object [string,object] items', () => {
const validator = (0, _logic.merge)({}, {
foo: 'bar'
});
(0, _utils.typeCheck)('ok');
_chai.assert.deepEqual(validator({
foo: 'bar'
}), {
foo: 'bar'
});
_chai.assert.deepEqual(validator({
foo: 'bar',
x: 1
}), {
foo: 'bar'
});
_chai.assert.throw(() => validator({}), _errors.ValidationError);
_chai.assert.throw(() => validator(undefined), _errors.ValidationError);
});
it('merging functions', () => {
const validator = (0, _logic.merge)(o => ({
x: String(o.x)
}), o => ({
y: String((o.y || 0) + 1)
}));
(0, _utils.typeCheck)('ok');
_chai.assert.deepEqual(validator({
x: 1,
y: 2
}), {
x: '1',
y: '3'
});
_chai.assert.deepEqual(validator({
x: 1
}), {
x: '1',
y: '1'
});
});
it('merging [sync, async]', async () => {
const validator = (0, _logic.merge)(n => n + 1, n => n > 0 ? Promise.resolve(n + 1) : Promise.reject(new Error('negative')));
(0, _utils.typeCheck)('ok');
await _chai.assert.isFulfilled(validator(2));
await _chai.assert.isRejected(validator(-1), 'negative');
_chai.assert.equal(await validator(2), 3);
_chai.assert.equal(await validator(6), 7);
});
});
describe('optional', () => {
it('function', () => {
const validator = (0, _logic.optional)(x => {
if (x <= 0) {
throw new RangeError(`Negative input`);
}
return String(x);
});
(0, _utils.typeCheck)('ok');
_chai.assert.equal(validator(1), '1');
_chai.assert.equal(validator(), undefined);
_chai.assert.equal(validator(undefined), undefined);
_chai.assert.equal(validator(null), undefined);
_chai.assert.equal(validator(''), undefined);
_chai.assert.throw(() => validator(false), RangeError, 'Negative input');
_chai.assert.throw(() => validator(0), RangeError, 'Negative input');
_chai.assert.throw(() => validator(-1), RangeError, 'Negative input');
});
});
describe('strictOptional', () => {
it('function', () => {
const validator = (0, _logic.strictOptional)(x => {
if (x <= 0) {
throw new RangeError(`Negative input`);
}
return String(x);
});
(0, _utils.typeCheck)('ok');
_chai.assert.equal(validator(1), '1');
_chai.assert.equal(validator(), undefined);
_chai.assert.equal(validator(undefined), undefined);
_chai.assert.throw(() => validator(''), RangeError, 'Negative input');
_chai.assert.throw(() => validator(null), RangeError, 'Negative input');
_chai.assert.throw(() => validator(false), RangeError, 'Negative input');
_chai.assert.throw(() => validator(0), RangeError, 'Negative input');
_chai.assert.throw(() => validator(-1), RangeError, 'Negative input');
});
});
});
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9zY2hlbWEvbG9naWMudGVzdC50cyJdLCJuYW1lcyI6WyJjaGFpQXNQcm9taXNlZCIsImRlc2NyaWJlIiwiaXQiLCJhc3NlcnQiLCJ0aHJvdyIsIlJhbmdlRXJyb3IiLCJ2YWxpZGF0b3IiLCJ4IiwiU3RyaW5nIiwiZXF1YWwiLCJpc0Z1bGZpbGxlZCIsImlzUmVqZWN0ZWQiLCJiZWNvbWVzIiwidHlwZSIsImZvbyIsIm51bWJlciIsImJhciIsInN0cmluZyIsImRlZXBFcXVhbCIsIlZhbGlkYXRpb25FcnJvciIsInVuZGVmaW5lZCIsIm8iLCJ5IiwibiIsIlByb21pc2UiLCJyZXNvbHZlIiwicmVqZWN0IiwiRXJyb3IiXSwibWFwcGluZ3MiOiI7O0FBQUE7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7Ozs7QUFFQSxlQUFJQSx1QkFBSjtBQUVBOztBQUVBQyxRQUFRLENBQUMsY0FBRCxFQUFpQixNQUFNO0FBQzdCQSxFQUFBQSxRQUFRLENBQUMsUUFBRCxFQUFXLE1BQU07QUFDdkJDLElBQUFBLEVBQUUsQ0FBQyxlQUFELEVBQWtCLE1BQU07QUFDeEJDLG1CQUFPQyxLQUFQLENBQWEsTUFBTSxtQkFBTyxHQUFJLEVBQVgsQ0FBbkIsRUFBNERDLFVBQTVEO0FBQ0QsS0FGQyxDQUFGO0FBSUFILElBQUFBLEVBQUUsQ0FBQyxnQkFBRCxFQUFtQixNQUFNO0FBQ3pCLFlBQU1JLFNBQVMsR0FBRyxtQkFBUUMsQ0FBRCxJQUF1QjtBQUM5QyxZQUFJQSxDQUFDLElBQUksQ0FBVCxFQUFZO0FBQ1YsZ0JBQU0sSUFBSUYsVUFBSixDQUFnQixnQkFBaEIsQ0FBTjtBQUNEOztBQUVELGVBQU9HLE1BQU0sQ0FBQ0QsQ0FBRCxDQUFiO0FBQ0QsT0FOaUIsQ0FBbEI7QUFRQSw0QkFBbUQsSUFBbkQ7O0FBQ0FKLG1CQUFPTSxLQUFQLENBQWFILFNBQVMsQ0FBQyxDQUFELENBQXRCLEVBQTJCLEdBQTNCOztBQUNBSCxtQkFBT0Ms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QUFNSSxTQUFTLEdBQUcsMkJBQWdCQyxDQUFELElBQXVCO0FBQ3RELFlBQUlBLENBQUMsSUFBSSxDQUFULEVBQVk7QUFDVixnQkFBTSxJQUFJRixVQUFKLENBQWdCLGdCQUFoQixDQUFOO0FBQ0Q7O0FBRUQsZUFBT0csTUFBTSxDQUFDRCxDQUFELENBQWI7QUFDRCxPQU5pQixDQUFsQjtBQVFBLDRCQUFnRSxJQUFoRTs7QUFDQUosbUJBQU9NLEtBQVAsQ0FBYUgsU0FBUyxDQUFDLENBQUQsQ0FBdEIsRUFBMkIsR0FBM0I7O0FBQ0FILG1CQUFPTSxLQUFQLENBQWFILFNBQVMsRUFBdEIsRUFBMEJjLFNBQTFCOztBQUNBakIsbUJBQU9NLEtBQVAsQ0FBYUgsU0FBUyxDQUFDYyxTQUFELENBQXRCLEVBQW1DQSxTQUFuQzs7QUFDQWpCLG1CQUFPQyxLQUFQLENBQWEsTUFBTUUsU0FBUyxDQUFDLEVBQUQsQ0FBNUIsRUFBeUNELFVBQXpDLEVBQXFELGdCQUFyRDs7QUFDQUYsbUJBQU9DLEtBQVAsQ0FBYSxNQUFNRSxTQUFTLENBQUMsSUFBRCxDQUE1QixFQUEyQ0QsVUFBM0MsRUFBdUQsZ0JBQXZEOztBQUNBRixtQkFBT0MsS0FBUCxDQUFhLE1BQU1FLFNBQVMsQ0FBQyxLQUFELENBQTVCLEVBQTRDRCxVQUE1QyxFQUF3RCxnQkFBeEQ7O0FBQ0FGLG1CQUFPQyxLQUFQLENBQWEsTUFBTUUsU0FBUyxDQUFDLENBQUQsQ0FBNUIsRUFBaUNELFVBQWpDLEVBQTZDLGdCQUE3Qzs7QUFDQUYsbUJBQU9DLEtBQVAsQ0FBYSxNQUFNRSxTQUFTLENBQUMsQ0FBQyxDQUFGLENBQTVCLEVBQWtDRCxVQUFsQyxFQUE4QyxnQkFBOUM7QUFDRCxLQWxCQyxDQUFGO0FBbUJELEdBcEJPLENBQVI7QUFxQkQsQ0FqU08sQ0FBUiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCAnbW9jaGEnO1xuaW1wb3J0IHsgYXNzZXJ0LCB1c2UgfSBmcm9tICdjaGFpJztcbmltcG9ydCB7IHR5cGVDaGVjayB9IGZyb20gJy4vdXRpbHMnO1xuaW1wb3J0IHsgbWVyZ2UsIGVpdGhlciwgb3B0aW9uYWwsIHN0cmljdE9wdGlvbmFsIH0gZnJvbSAnLi9sb2dpYyc7XG5pbXBvcnQgY2hhaUFzUHJvbWlzZWQgZnJvbSAnY2hhaS1hcy1wcm9taXNlZCc7XG5pbXBvcnQgc3RyaW5nIGZyb20gJy4uL3N0cmluZyc7XG5pbXBvcnQgbnVtYmVyIGZyb20gJy4uL251bWJlcic7XG5pbXBvcnQgeyBWYWxpZGF0aW9uRXJyb3IgfSBmcm9tICcuL2Vycm9ycyc7XG5cbnVzZShjaGFpQXNQcm9taXNlZCk7XG5cbi8qIGVzbGludC1kaXNhYmxlIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnksQHR5cGVzY3JpcHQtZXNsaW50L2Jhbi10eXBlcyAqL1xuXG5kZXNjcmliZSgnc2NoZW1hL2xvZ2ljJywgKCkgPT4ge1xuICBkZXNjcmliZSgnZWl0aGVyJywgKCkgPT4ge1xuICAgIGl0KCdubyBjYW5kaWRhdGVzJywgKCkgPT4ge1xuICAgICAgYXNzZXJ0LnRocm93KCgpID0+IGVpdGhlciguLi4oW10gYXMgdW5rbm93biBhcyBbdW5rbm93bl0pKSwgUmFuZ2VFcnJvcik7XG4gICAgfSk7XG5cbiAgICBpdCgnc3luYyBjYW5kaWRhdGUnLCAoKSA9PiB7XG4gICAgICBjb25zdCB2YWxpZGF0b3IgPSBlaXRoZXIoKHg6IG51bWJlcik6IHN0cmluZyA9PiB7XG4gICAgICAgIGlmICh4IDw9IDApIHtcbiAgICAgICAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcihgTmVnYXRpdmUgaW5wdXRgKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBTdHJpbmcoeCk7XG4gICAgICB9KTtcblxuICAgICAgdHlwZUNoZWNrPHR5cGVvZiB2YWxpZGF0b3IsICh4OiBudW1iZXIpID0+IHN0cmluZz4oJ29rJyk7XG4gICAgICBhc3NlcnQuZXF1YWwodmFsaWRhdG9yKDEpLCAnMScpO1xuICAgICAgYXNzZXJ0LnRocm93KCgpID0+IHZhbGlkYXRvcigtMSksIFJhbmdlRXJyb3IsICdOZWdhdGl2ZSBpbnB1dCcpO1xuICAgIH0pO1xuXG4gICAgaXQoJ2FzeW5jIGNhbmRpZGF0ZScsIGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IHZhbGlkYXRvciA9IGVpdGhlcihhc3luYyAoeDogbnVtYmVyKTogUHJvbWlzZTxzdHJpbmc+ID0+IHtcbiAgICAgICAgaWYgKHggPD0gMCkge1xuICAgICAgICAgIHRocm93IG5ldyBSYW5nZUVycm9yKGBOZWdhdGl2ZSBpbnB1dGApO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIFN0cmluZyh4KTtcbiAgICAgIH0pO1xuXG4gICAgICB0eXBlQ2hlY2s8dHlwZW9mIHZhbGlkYXRvciwgKHg6IG51bWJlcikgPT4gUHJvbWlzZUxpa2U8c3RyaW5nPj4oJ29rJyk7XG5cbiAgICAgIGF3YWl0IGFzc2VydC5pc0Z1bGZpbGxlZCh2YWxpZGF0b3IoMSkpO1xuICAgICAgYXdhaXQgYXNzZXJ0LmlzUmVqZWN0ZWQodmFsaWRhdG9yKC0xKSk7XG4gICAgICBhd2FpdCBhc3NlcnQuYmVjb21lcyh2YWxpZGF0b3IoMSksICcxJyk7XG4gICAgfSk7XG5cbiAgICBpdCgnMiBzeW5jIGNhbmRpZGF0ZXMnLCAoKSA9PiB7XG4gICAgICBjb25zdCB2YWxpZGF0b3IgPSBlaXRoZXIoXG4gICAgICAgICh4OiBudW1iZXIpOiBzdHJpbmcgPT4ge1xuICAgICAgICAgIGlmICh0eXBlb2YgeCAhPT0gJ251bWJlcicgfHwgeCA8PSAwKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcihgTmVnYXRpdmUgaW5wdXRgKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICByZXR1cm4gU3RyaW5nKHgpO1xuICAgICAgICB9LFxuICAgICAgICAoeDogYm9vbGVhbik6IG51bWJlciA9PiB7XG4gICAgICAgICAgaWYgKHR5cGVvZiB4ICE9PSAnYm9vbGVhbicpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBSYW5nZUVycm9yKGBOb24gYm9vbGVhbmApO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHJldHVybiB4ID8gMSA6IDA7XG4gICAgICAgIH0sXG4gICAgICApO1xuXG4gICAgICB0eXBlQ2hlY2s8dHlwZW9mIHZhbGlkYXRvciwgKHg6IG51bWJlciB8IGJvb2xlYW4pID0+IHN0cmluZyB8IG51bWJlcj4oXG4gICAgICAgICdvaycsXG4gICAgICApO1xuICAgICAgYXNzZXJ0LmVxdWFsKHZhbGlkYXRvcigxKSwgJzEnKTtcbiAgICAgIGFzc2VydC5lcXVhbCh2YWxpZGF0b3IoZmFsc2UpLCAwKTtcbiAgICAgIGFzc2VydC50aHJvdygoKSA9PiB2YWxpZGF0b3IoJycgYXMgYW55KSwgUmFuZ2VFcnJvciwgJ05vbiBib29sZWFuJyk7XG4gICAgfSk7XG5cbiAgICBpdCgnW3N5bmMsYXN5bmNdIGNhbmRpZGF0ZXMnLCBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCB2YWxpZGF0b3IgPSBlaXRoZXIoXG4gICAgICAgICh4OiBudW1iZXIpOiBzdHJpbmcgPT4ge1xuICAgICAgICAgIGlmICh0eXBlb2YgeCAhPT0gJ251bWJlcicgfHwgeCA8PSAwKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcihgTmVnYXRpdmUgaW5wdXRgKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICByZXR1cm4gU3RyaW5nKHgpO1xuICAgICAgICB9LFxuICAgICAgICBhc3luYyAoeDogYm9vbGVhbik6IFByb21pc2U8bnVtYmVyPiA9PiB7XG4gICAgICAgICAgaWYgKHR5cGVvZiB4ICE9PSAnYm9vbGVhbicpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBSYW5nZUVycm9yKGBOb24gYm9vbGVhbmApO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHJldHVybiB4ID8gMSA6IDA7XG4gICAgICAgIH0sXG4gICAgICApO1xuXG4gICAgICB0eXBlQ2hlY2s8XG4gICAgICAgIHR5cGVvZiB2YWxpZGF0b3IsXG4gICAgICAgICh4OiBudW1iZXIgfCBib29sZWFuKSA9PiBzdHJpbmcgfCBQcm9taXNlTGlrZTxudW1iZXI+XG4gICAgICA+KCdvaycpO1xuICAgICAgYXNzZXJ0LmVxdWFsKHZhbGlkYXRvcigxKSwgJzEnKTtcbiAgICAgIGF3YWl0IGFzc2VydC5iZWNvbWVzKHZhbGlkYXRvcih0cnVlKSBhcyBQcm9taXNlTGlrZTxudW1iZXI+LCAxKTtcbiAgICAgIGF3YWl0IGFzc2VydC5pc1JlamVjdGVkKHZhbGlkYXRvcignJyBhcyBhbnkpIGFzIGFueSk7XG4gICAgfSk7XG5cbiAgICBpdCgnW2FzeW5jLGFzeW5jXSBjYW5kaWRhdGVzJywgYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3QgdmFsaWRhdG9yID0gZWl0aGVyKFxuICAgICAgICBhc3luYyAoeDogbnVtYmVyKTogUHJvbWlzZTxzdHJpbmc+ID0+IHtcbiAgICAgICAgICBpZiAodHlwZW9mIHggIT09ICdudW1iZXInIHx8IHggPD0gMCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoYE5lZ2F0aXZlIGlucHV0YCk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgcmV0dXJuIFN0cmluZyh4KTtcbiAgICAgICAgfSxcbiAgICAgICAgYXN5bmMgKHg6IGJvb2xlYW4pOiBQcm9taXNlPG51bWJlcj4gPT4ge1xuICAgICAgICAgIGlmICh0eXBlb2YgeCAhPT0gJ2Jvb2xlYW4nKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcihgTm9uIGJvb2xlYW5gKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICByZXR1cm4geCA/IDEgOiAwO1xuICAgICAgICB9LFxuICAgICAgKTtcblxuICAgICAgdHlwZUNoZWNrPFxuICAgICAgICB0eXBlb2YgdmFsaWRhdG9yLFxuICAgICAgICAoeDogbnVtYmVyIHwgYm9vbGVhbikgPT4gUHJvbWlzZUxpa2U8c3RyaW5nPiB8IFByb21pc2VMaWtlPG51bWJlcj5cbiAgICAgID4oJ29rJyk7XG4gICAgICBhd2FpdCBhc3NlcnQuYmVjb21lcyh2YWxpZGF0b3IoMSksICcxJyk7XG4gICAgICBhd2FpdCBhc3NlcnQuYmVjb21lcyh2YWxpZGF0b3IodHJ1ZSksIDEpO1xuICAgICAgYXdhaXQgYXNzZXJ0LmlzUmVqZWN0ZWQodmFsaWRhdG9yKCcnIGFzIGFueSkgYXMgYW55KTtcbiAgICB9KTtcblxuICAgIGl0KCd1c2Ugc3dpdGNoJywgKCkgPT4ge1xuICAgICAgY29uc3QgdmFsaWRhdG9yID0gZWl0aGVyKFxuICAgICAgICB7IHR5cGU6ICdmb28nIGFzIGNvbnN0LCBmb286IG51bWJlciB9LFxuICAgICAgICB7IHR5cGU6ICdiYXInIGFzIGNvbnN0LCBiYXI6IHN0cmluZyB9LFxuICAgICAgKTtcblxuICAgICAgdHlwZUNoZWNrPFxuICAgICAgICB0eXBlb2YgdmFsaWRhdG9yLFxuICAgICAgICAoXG4gICAgICAgICAgeDogeyB0eXBlOiAnZm9vJzsgZm9vOiBudW1iZXIgfSB8IHsgdHlwZTogJ2Jhcic7IGJhcjogc3RyaW5nIH0sXG4gICAgICAgICkgPT4geyB0eXBlOiAnZm9vJzsgZm9vOiBudW1iZXIgfSB8IHsgdHlwZTogJ2Jhcic7IGJhcjogc3RyaW5nIH1cbiAgICAgID4oJ29rJyk7XG5cbiAgICAgIGFzc2VydC5kZWVwRXF1YWwodmFsaWRhdG9yKHsgdHlwZTogJ2ZvbycsIGZvbzogMiB9KSwge1xuICAgICAgICB0eXBlOiAnZm9vJyxcbiAgICAgICAgZm9vOiAyLFxuICAgICAgfSk7XG4gICAgICBhc3NlcnQuZGVlcEVxdWFsKHZhbGlkYXRvcih7IHR5cGU6ICdiYXInLCBiYXI6ICdoZWxsbycgfSksIHtcbiAgICAgICAgdHlwZTogJ2JhcicsXG4gICAgICAgIGJhcjogJ2hlbGxvJyxcbiAgICAgIH0pO1xuXG4gICAgICBhc3NlcnQudGhyb3coXG4gICAgICAgICgpID0+IHZhbGlkYXRvcih7IHR5cGU6ICdmb28nLCBmb286ICdkZCcgfSBhcyBhbnkpLFxuICAgICAgICBWYWxpZGF0aW9uRXJyb3IsXG4gICAgICAgICdmb286IEV4cGVjdCB2YWx1ZSB0byBiZSBcIm51bWJlclwiJyxcbiAgICAgICk7XG5cbiAgICAgIGFzc2VydC50aHJvdyhcbiAgICAgICAgKCkgPT4gdmFsaWRhdG9yKHsgdHlwZTogJ2JhcicsIGZvbzogJ2RkJyB9IGFzIGFueSksXG4gICAgICAgIFZhbGlkYXRpb25FcnJvcixcbiAgICAgICAgJ2JhcjogRXhwZWN0IHZhbHVlIHRvIGJlIFwic3RyaW5nXCInLFxuICAgICAgKTtcblxuICAgICAgYXNzZXJ0LnRocm93KFxuICAgICAgICAoKSA9PiB2YWxpZGF0b3IoeyB0eXBlOiAnaGVsbG8nLCBmb286ICdkZCcgfSBhcyBhbnkpLFxuICAgICAgICBWYWxpZGF0aW9uRXJyb3IsXG4gICAgICAgICd0eXBlOiBFeHBlY3QgdmFsdWUgdG8gZXF1YWwgXCJmb29cIicsXG4gICAgICApO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnbWVyZ2UnLCAoKSA9PiB7XG4gICAgaXQoJ25vIGl0ZW1zJywgKCkgPT4ge1xuICAgICAgYXNzZXJ0LnRocm93KCgpID0+IG1lcmdlKC4uLihbXSBhcyB1bmtub3duIGFzIFt1bmtub3duXSkpLCBSYW5nZUVycm9yKTtcbiAgICB9KTtcblxuICAgIGl0KCdvbmUgaXRlbScsICgpID0+IHtcbiAgICAgIGNvbnN0IHZhbGlkYXRvciA9IG1lcmdlKCdmb28nIGFzIGNvbnN0KTtcblxuICAgICAgdHlwZUNoZWNrPHR5cGVvZiB2YWxpZGF0b3IsICh4OiAnZm9vJykgPT4gJ2Zvbyc+KCdvaycpO1xuICAgICAgYXNzZXJ0LmVxdWFsKHZhbGlkYXRvcignZm9vJyksICdmb28nKTtcbiAgICAgIGFzc2VydC50aHJvdygoKSA9PiB2YWxpZGF0b3IoJ2JhcicgYXMgYW55KSwgVmFsaWRhdGlvbkVycm9yKTtcbiAgICB9KTtcblxuICAgIGl0KCduZXZlciBzdHJpbmcgaXRlbXMnLCAoKSA9PiB7XG4gICAgICBjb25zdCB2YWxpZGF0b3IgPSBtZXJnZSgnZm9vJyBhcyBjb25zdCwgJ2JhcicgYXMgY29uc3QpO1xuXG4gICAgICB0eXBlQ2hlY2s8dHlwZW9mIHZhbGlkYXRvciwgKHg6IG5ldmVyKSA9PiBuZXZlcj4oJ29rJyk7XG4gICAgICBhc3NlcnQudGhyb3coKCkgPT4gdmFsaWRhdG9yKCdmb28nIGFzIG5ldmVyKSwgVmFsaWRhdGlvbkVycm9yKTtcbiAgICAgIGFzc2VydC50aHJvdygoKSA9PiB2YWxpZGF0b3IoJ2JhcicgYXMgbmV2ZXIpLCBWYWxpZGF0aW9uRXJyb3IpO1xuICAgIH0pO1xuXG4gICAgaXQoJ25ldmVyIFtzdHJpbmcsb2JqZWN0XSBpdGVtcycsICgpID0+IHtcbiAgICAgIGNvbnN0IHZhbGlkYXRvciA9IG1lcmdlKCdmb28nIGFzIGNvbnN0LCB7fSk7XG5cbiAgICAgIHR5cGVDaGVjazx0eXBlb2YgdmFsaWRhdG9yLCAoeDogJ2ZvbycgJiB7fSkgPT4gJ2ZvbycgJiB7fT4oJ29rJyk7XG4gICAgICBhc3NlcnQudGhyb3coKCkgPT4gdmFsaWRhdG9yKCdmb28nKSwgVmFsaWRhdGlvbkVycm9yKTtcbiAgICAgIGFzc2VydC50aHJvdygoKSA9PiB2YWxpZGF0b3Ioe30gYXMgYW55KSwgVmFsaWRhdGlvbkVycm9yKTtcbiAgICAgIGFzc2VydC50aHJvdygoKSA9PiB2YWxpZGF0b3IoJ2JhcicgYXMgbmV2ZXIpLCBWYWxpZGF0aW9uRXJyb3IpO1xuICAgIH0pO1xuXG4gICAgaXQoJ25ldmVyIFtvYmplY3QsdW5kZWZpbmVkXSBpdGVtcycsICgpID0+IHtcbiAgICAgIGNvbnN0IHZhbGlkYXRvciA9IG1lcmdlKHt9LCB1bmRlZmluZWQpO1xuXG4gICAgICB0eXBlQ2hlY2s8dHlwZW9mIHZhbGlkYXRvciwgKHg6IG5ldmVyKSA9PiBuZXZlcj4oJ29rJyk7XG4gICAgICBhc3NlcnQudGhyb3coKCkgPT4gdmFsaWRhdG9yKHVuZGVmaW5lZCBhcyBuZXZlciksIFZhbGlkYXRpb25FcnJvcik7XG4gICAgICBhc3NlcnQudGhyb3coKCkgPT4gdmFsaWRhdG9yKHt9IGFzIG5ldmVyKSwgVmFsaWRhdGlvbkVycm9yKTtcbiAgICAgIGFzc2VydC50aHJvdygoKSA9PiB2YWxpZGF0b3IoJ2JhcicgYXMgbmV2ZXIpLCBWYWxpZGF0aW9uRXJyb3IpO1xuICAgIH0pO1xuXG4gICAgaXQoJ21lcmdpbmcgb2JqZWN0IFtzdHJpbmcsb2JqZWN0XSBpdGVtcycsICgpID0+IHtcbiAgICAgIGNvbnN0IHZhbGlkYXRvciA9IG1lcmdlKHt9LCB7IGZvbzogJ2JhcicgYXMgY29uc3QgfSk7XG5cbiAgICAgIHR5cGVDaGVjazx0eXBlb2YgdmFsaWRhdG9yLCAoeDogeyBmb286ICdiYXInIH0pID0+IHsgZm9vOiAnYmFyJyB9Pignb2snKTtcbiAgICAgIGFzc2VydC5kZWVwRXF1YWwodmFsaWRhdG9yKHsgZm9vOiAnYmFyJyB9KSwgeyBmb286ICdiYXInIH0pO1xuICAgICAgYXNzZXJ0LmRlZXBFcXVhbCh2YWxpZGF0b3IoeyBmb286ICdiYXInLCB4OiAxIH0gYXMgYW55KSwgeyBmb286ICdiYXInIH0pO1xuICAgICAgYXNzZXJ0LnRocm93KCgpID0+IHZhbGlkYXRvcih7fSBhcyBhbnkpLCBWYWxpZGF0aW9uRXJyb3IpO1xuICAgICAgYXNzZXJ0LnRocm93KCgpID0+IHZhbGlkYXRvcih1bmRlZmluZWQgYXMgYW55KSwgVmFsaWRhdGlvbkVycm9yKTtcbiAgICB9KTtcblxuICAgIGl0KCdtZXJnaW5nIGZ1bmN0aW9ucycsICgpID0+IHtcbiAgICAgIGNvbnN0IHZhbGlkYXRvciA9IG1lcmdlKFxuICAgICAgICAobzogeyB4OiBudW1iZXIgfSkgPT4gKHtcbiAgICAgICAgICB4OiBTdHJpbmcoby54KSxcbiAgICAgICAgfSksXG4gICAgICAgIChvOiB7IHk/OiBudW1iZXIgfSkgPT4gKHtcbiAgICAgICAgICB5OiBTdHJpbmcoKG8ueSB8fCAwKSArIDEpLFxuICAgICAgICB9KSxcbiAgICAgICk7XG5cbiAgICAgIHR5cGVDaGVjazxcbiAgICAgICAgdHlwZW9mIHZhbGlkYXRvcixcbiAgICAgICAgKHg6IHsgeDogbnVtYmVyOyB5PzogbnVtYmVyIH0pID0+IHsgeDogc3RyaW5nOyB5OiBzdHJpbmcgfVxuICAgICAgPignb2snKTtcbiAgICAgIGFzc2VydC5kZWVwRXF1YWwodmFsaWRhdG9yKHsgeDogMSwgeTogMiB9KSwgeyB4OiAnMScsIHk6ICczJyB9KTtcbiAgICAgIGFzc2VydC5kZWVwRXF1YWwodmFsaWRhdG9yKHsgeDogMSB9KSwgeyB4OiAnMScsIHk6ICcxJyB9KTtcbiAgICB9KTtcblxuICAgIGl0KCdtZXJnaW5nIFtzeW5jLCBhc3luY10nLCBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCB2YWxpZGF0b3IgPSBtZXJnZShcbiAgICAgICAgKG46IG51bWJlcikgPT4gbiArIDEsXG4gICAgICAgIChuOiBudW1iZXIpID0+XG4gICAgICAgICAgbiA+IDBcbiAgICAgICAgICAgID8gUHJvbWlzZS5yZXNvbHZlKG4gKyAxKVxuICAgICAgICAgICAgOiBQcm9taXNlLnJlamVjdChuZXcgRXJyb3IoJ25lZ2F0aXZlJykpLFxuICAgICAgKTtcblxuICAgICAgdHlwZUNoZWNrPHR5cGVvZiB2YWxpZGF0b3IsICh4OiBudW1iZXIpID0+IFByb21pc2VMaWtlPG51bWJlcj4+KCdvaycpO1xuXG4gICAgICBhd2FpdCBhc3NlcnQuaXNGdWxmaWxsZWQodmFsaWRhdG9yKDIpKTtcbiAgICAgIGF3YWl0IGFzc2VydC5pc1JlamVjdGVkKHZhbGlkYXRvcigtMSksICduZWdhdGl2ZScpO1xuXG4gICAgICBhc3NlcnQuZXF1YWwoYXdhaXQgdmFsaWRhdG9yKDIpLCAzKTtcbiAgICAgIGFzc2VydC5lcXVhbChhd2FpdCB2YWxpZGF0b3IoNiksIDcpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnb3B0aW9uYWwnLCAoKSA9PiB7XG4gICAgaXQoJ2Z1bmN0aW9uJywgKCkgPT4ge1xuICAgICAgY29uc3QgdmFsaWRhdG9yID0gb3B0aW9uYWwoKHg6IG51bWJlcik6IHN0cmluZyA9PiB7XG4gICAgICAgIGlmICh4IDw9IDApIHtcbiAgICAgICAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcihgTmVnYXRpdmUgaW5wdXRgKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBTdHJpbmcoeCk7XG4gICAgICB9KTtcblxuICAgICAgdHlwZUNoZWNrPHR5cGVvZiB2YWxpZGF0b3IsICh4PzogbnVtYmVyIHwgbnVsbCkgPT4gc3RyaW5nIHwgdW5kZWZpbmVkPihcbiAgICAgICAgJ29rJyxcbiAgICAgICk7XG4gICAgICBhc3NlcnQuZXF1YWwodmFsaWRhdG9yKDEpLCAnMScpO1xuICAgICAgYXNzZXJ0LmVxdWFsKHZhbGlkYXRvcigpLCB1bmRlZmluZWQpO1xuICAgICAgYXNzZXJ0LmVxdWFsKHZhbGlkYXRvcih1bmRlZmluZWQpLCB1bmRlZmluZWQpO1xuICAgICAgYXNzZXJ0LmVxdWFsKHZhbGlkYXRvcihudWxsKSwgdW5kZWZpbmVkKTtcbiAgICAgIGFzc2VydC5lcXVhbCh2YWxpZGF0b3IoJycgYXMgYW55KSwgdW5kZWZpbmVkKTtcbiAgICAgIGFzc2VydC50aHJvdygoKSA9PiB2YWxpZGF0b3IoZmFsc2UgYXMgYW55KSwgUmFuZ2VFcnJvciwgJ05lZ2F0aXZlIGlucHV0Jyk7XG4gICAgICBhc3NlcnQudGhyb3coKCkgPT4gdmFsaWRhdG9yKDApLCBSYW5nZUVycm9yLCAnTmVnYXRpdmUgaW5wdXQnKTtcbiAgICAgIGFzc2VydC50aHJvdygoKSA9PiB2YWxpZGF0b3IoLTEpLCBSYW5nZUVycm9yLCAnTmVnYXRpdmUgaW5wdXQnKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ3N0cmljdE9wdGlvbmFsJywgKCkgPT4ge1xuICAgIGl0KCdmdW5jdGlvbicsICgpID0+IHtcbiAgICAgIGNvbnN0IHZhbGlkYXRvciA9IHN0cmljdE9wdGlvbmFsKCh4OiBudW1iZXIpOiBzdHJpbmcgPT4ge1xuICAgICAgICBpZiAoeCA8PSAwKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoYE5lZ2F0aXZlIGlucHV0YCk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gU3RyaW5nKHgpO1xuICAgICAgfSk7XG5cbiAgICAgIHR5cGVDaGVjazx0eXBlb2YgdmFsaWRhdG9yLCAoeD86IG51bWJlcikgPT4gc3RyaW5nIHwgdW5kZWZpbmVkPignb2snKTtcbiAgICAgIGFzc2VydC5lcXVhbCh2YWxpZGF0b3IoMSksICcxJyk7XG4gICAgICBhc3NlcnQuZXF1YWwodmFsaWRhdG9yKCksIHVuZGVmaW5lZCk7XG4gICAgICBhc3NlcnQuZXF1YWwodmFsaWRhdG9yKHVuZGVmaW5lZCksIHVuZGVmaW5lZCk7XG4gICAgICBhc3NlcnQudGhyb3coKCkgPT4gdmFsaWRhdG9yKCcnIGFzIGFueSksIFJhbmdlRXJyb3IsICdOZWdhdGl2ZSBpbnB1dCcpO1xuICAgICAgYXNzZXJ0LnRocm93KCgpID0+IHZhbGlkYXRvcihudWxsIGFzIGFueSksIFJhbmdlRXJyb3IsICdOZWdhdGl2ZSBpbnB1dCcpO1xuICAgICAgYXNzZXJ0LnRocm93KCgpID0+IHZhbGlkYXRvcihmYWxzZSBhcyBhbnkpLCBSYW5nZUVycm9yLCAnTmVnYXRpdmUgaW5wdXQnKTtcbiAgICAgIGFzc2VydC50aHJvdygoKSA9PiB2YWxpZGF0b3IoMCksIFJhbmdlRXJyb3IsICdOZWdhdGl2ZSBpbnB1dCcpO1xuICAgICAgYXNzZXJ0LnRocm93KCgpID0+IHZhbGlkYXRvcigtMSksIFJhbmdlRXJyb3IsICdOZWdhdGl2ZSBpbnB1dCcpO1xuICAgIH0pO1xuICB9KTtcbn0pO1xuIl19