@selfage/test_matcher
Version:
A pattern to match actual value with expected in tests.
213 lines • 24.9 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.eqError = exports.isMap = exports.isSet = exports.isUnorderedArray = exports.containUnorderedElements = exports.isArray = exports.containStr = exports.eqAppr = exports.le = exports.lt = exports.ge = exports.gt = exports.eqLongStr = exports.ne = exports.eq = exports.any = exports.assertThat = exports.asyncAssertThat = exports.assertThrow = exports.assertReject = exports.assert = void 0;
function assert(tested, expected, actual) {
if (!tested) {
throw new Error(`Expect ${expected} but it actually is ${actual}.`);
}
}
exports.assert = assert;
async function assertReject(promise) {
try {
await promise;
}
catch (e) {
return e;
}
throw new Error("Failed to assert the promise to be rejected.");
}
exports.assertReject = assertReject;
function assertThrow(method) {
try {
method();
}
catch (e) {
return e;
}
throw new Error("Failed to assert an error to be thrown.");
}
exports.assertThrow = assertThrow;
async function asyncAssertThat(actual, asyncMatch, targetName) {
try {
await asyncMatch(actual);
}
catch (e) {
e.message = `When matching ${targetName}:\n${e.message}`;
throw e;
}
}
exports.asyncAssertThat = asyncAssertThat;
function assertThat(actual, match, targetName) {
try {
match(actual);
}
catch (e) {
e.message = `When matching ${targetName}:\n${e.message}`;
throw e;
}
}
exports.assertThat = assertThat;
function any() {
return (actual) => { };
}
exports.any = any;
function eq(expected) {
return (actual) => {
assert(expected === actual, `${expected}`, `${actual}`);
};
}
exports.eq = eq;
function ne(expected) {
return (actual) => {
assert(expected !== actual, `not equal to ${expected}`, `${actual}`);
};
}
exports.ne = ne;
function eqLongStr(expected) {
return (actual) => {
if (expected === undefined) {
assertThat(actual, eq(undefined), "nullity");
return;
}
let minLength = Math.min(actual.length, expected.length);
for (let i = 0; i < minLength; i++) {
assertThat(actual.charCodeAt(i), eq(expected.charCodeAt(i)), `char code at position ${i}, with expected string ${expected} and actual string ${actual}`);
}
assertThat(actual.length, eq(expected.length), `string length, with expected string ${expected} and actual string ${actual}`);
};
}
exports.eqLongStr = eqLongStr;
// Greater than
function gt(expected) {
return (actual) => {
assert(actual > expected, `> ${expected}`, `${actual}`);
};
}
exports.gt = gt;
// Greater and equal
function ge(expected) {
return (actual) => {
assert(actual >= expected, `>= ${expected}`, `${actual}`);
};
}
exports.ge = ge;
// Less than
function lt(expected) {
return (actual) => {
assert(actual < expected, `< ${expected}`, `${actual}`);
};
}
exports.lt = lt;
// Less and equal
function le(expected) {
return (actual) => {
assert(actual <= expected, `<= ${expected}`, `${actual}`);
};
}
exports.le = le;
// Equal approximately
function eqAppr(expected, deviation = 0.01) {
return (actual) => {
assert(actual >= expected * (1 - deviation), `to equal approximately to ${expected}`, `${actual}`);
assert(actual <= expected * (1 + deviation), `to equal approximately to ${expected}`, `${actual}`);
};
}
exports.eqAppr = eqAppr;
function containStr(expected) {
return (actual) => {
assert(Boolean(actual), `to not be null`, `null`);
assert(actual.indexOf(expected) != -1, `containing ${expected}`, actual);
};
}
exports.containStr = containStr;
function isArray(expected) {
return (actual) => {
if (expected === undefined) {
assertThat(actual, eq(undefined), "nullity");
return;
}
assert(Boolean(actual), `to not be null`, `null`);
assertThat(actual.length, eq(expected.length), `array length`);
for (let i = 0; i < actual.length; i++) {
assertThat(actual[i], expected[i], `${i}th element`);
}
};
}
exports.isArray = isArray;
function containUnorderedElements(expectedMatchers) {
return (actual) => {
assert(Boolean(actual), `to not be null`, `null`);
let matchedIndex = new Set();
for (let i = 0; i < expectedMatchers.length; i++) {
let matched = false;
for (let j = 0; j < actual.length; j++) {
if (matchedIndex.has(j)) {
continue;
}
try {
expectedMatchers[i](actual[j]);
matched = true;
matchedIndex.add(j);
break;
}
catch (e) { }
}
if (!matched) {
throw new Error(`Cannot match the ${i}th expected element.`);
}
}
};
}
exports.containUnorderedElements = containUnorderedElements;
function isUnorderedArray(expected) {
return (actual) => {
assert(Boolean(actual), `to not be null`, `null`);
assertThat(actual.length, eq(expected.length), `array length`);
assertThat(actual, containUnorderedElements(expected), `unordered elements`);
};
}
exports.isUnorderedArray = isUnorderedArray;
// Match Set in insertion order.
function isSet(expected) {
return (actual) => {
if (expected === undefined) {
assertThat(actual, eq(undefined), "nullity");
return;
}
assert(Boolean(actual), `to not be null`, `null`);
assertThat(actual.size, eq(expected.length), `set size`);
let i = 0;
for (let value of actual) {
assertThat(value, expected[i], `${i}th element`);
i++;
}
};
}
exports.isSet = isSet;
// Match Map in insertion order.
function isMap(expected) {
return (actual) => {
if (expected === undefined) {
assertThat(actual, eq(undefined), "nullity");
return;
}
assert(Boolean(actual), `to not be null`, `null`);
assertThat(actual.size, eq(expected.length), `map size`);
let i = 0;
for (let [key, value] of actual) {
assertThat(key, expected[i][0], `${i}th key`);
assertThat(value, expected[i][1], `${i}th value`);
i++;
}
};
}
exports.isMap = isMap;
function eqError(expected) {
return (actual) => {
assert(actual instanceof Error, `to be an Error`, `${actual}`);
assertThat(actual.name, eq(expected.name), `name of the error`);
assertThat(actual.message, containStr(expected.message), `${actual.stack}`);
};
}
exports.eqError = eqError;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWF0Y2hlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIm1hdGNoZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsU0FBZ0IsTUFBTSxDQUNwQixNQUFlLEVBQ2YsUUFBZ0IsRUFDaEIsTUFBYztJQUVkLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQztRQUNaLE1BQU0sSUFBSSxLQUFLLENBQUMsVUFBVSxRQUFRLHVCQUF1QixNQUFNLEdBQUcsQ0FBQyxDQUFDO0lBQ3RFLENBQUM7QUFDSCxDQUFDO0FBUkQsd0JBUUM7QUFFTSxLQUFLLFVBQVUsWUFBWSxDQUFDLE9BQXFCO0lBQ3RELElBQUksQ0FBQztRQUNILE1BQU0sT0FBTyxDQUFDO0lBQ2hCLENBQUM7SUFBQyxPQUFPLENBQUMsRUFBRSxDQUFDO1FBQ1gsT0FBTyxDQUFDLENBQUM7SUFDWCxDQUFDO0lBQ0QsTUFBTSxJQUFJLEtBQUssQ0FBQyw4Q0FBOEMsQ0FBQyxDQUFDO0FBQ2xFLENBQUM7QUFQRCxvQ0FPQztBQUVELFNBQWdCLFdBQVcsQ0FBQyxNQUFrQjtJQUM1QyxJQUFJLENBQUM7UUFDSCxNQUFNLEVBQUUsQ0FBQztJQUNYLENBQUM7SUFBQyxPQUFPLENBQUMsRUFBRSxDQUFDO1FBQ1gsT0FBTyxDQUFDLENBQUM7SUFDWCxDQUFDO0lBQ0QsTUFBTSxJQUFJLEtBQUssQ0FBQyx5Q0FBeUMsQ0FBQyxDQUFDO0FBQzdELENBQUM7QUFQRCxrQ0FPQztBQUlNLEtBQUssVUFBVSxlQUFlLENBQ25DLE1BQVMsRUFDVCxVQUEyQixFQUMzQixVQUFrQjtJQUVsQixJQUFJLENBQUM7UUFDSCxNQUFNLFVBQVUsQ0FBQyxNQUFNLENBQUMsQ0FBQztJQUMzQixDQUFDO0lBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQztRQUNYLENBQUMsQ0FBQyxPQUFPLEdBQUcsaUJBQWlCLFVBQVUsTUFBTSxDQUFDLENBQUMsT0FBTyxFQUFFLENBQUM7UUFDekQsTUFBTSxDQUFDLENBQUM7SUFDVixDQUFD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QUMsSUFBSSxNQUFNLEVBQUUsQ0FBQztZQUNoQyxVQUFVLENBQUMsR0FBRyxFQUFFLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxHQUFHLENBQUMsUUFBUSxDQUFDLENBQUM7WUFDOUMsVUFBVSxDQUFDLEtBQUssRUFBRSxRQUFRLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsR0FBRyxDQUFDLFVBQVUsQ0FBQyxDQUFDO1lBQ2xELENBQUMsRUFBRSxDQUFDO1FBQ04sQ0FBQztJQUNILENBQUMsQ0FBQztBQUNKLENBQUM7QUFqQkQsc0JBaUJDO0FBRUQsU0FBZ0IsT0FBTyxDQUFDLFFBQWU7SUFDckMsT0FBTyxDQUFDLE1BQU0sRUFBRSxFQUFFO1FBQ2hCLE1BQU0sQ0FBQyxNQUFNLFlBQVksS0FBSyxFQUFFLGdCQUFnQixFQUFFLEdBQUcsTUFBTSxFQUFFLENBQUMsQ0FBQztRQUMvRCxVQUFVLENBQUMsTUFBTSxDQUFDLElBQUksRUFBRSxFQUFFLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxFQUFFLG1CQUFtQixDQUFDLENBQUM7UUFDaEUsVUFBVSxDQUFDLE1BQU0sQ0FBQyxPQUFPLEVBQUUsVUFBVSxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsRUFBRSxHQUFHLE1BQU0sQ0FBQyxLQUFLLEVBQUUsQ0FBQyxDQUFDO0lBQzlFLENBQUMsQ0FBQztBQUNKLENBQUM7QUFORCwwQkFNQyIsInNvdXJjZXNDb250ZW50IjpbImV4cG9ydCBmdW5jdGlvbiBhc3NlcnQoXG4gIHRlc3RlZDogYm9vbGVhbixcbiAgZXhwZWN0ZWQ6IHN0cmluZyxcbiAgYWN0dWFsOiBzdHJpbmdcbik6IHZvaWQge1xuICBpZiAoIXRlc3RlZCkge1xuICAgIHRocm93IG5ldyBFcnJvcihgRXhwZWN0ICR7ZXhwZWN0ZWR9IGJ1dCBpdCBhY3R1YWxseSBpcyAke2FjdHVhbH0uYCk7XG4gIH1cbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGFzc2VydFJlamVjdChwcm9taXNlOiBQcm9taXNlPGFueT4pIHtcbiAgdHJ5IHtcbiAgICBhd2FpdCBwcm9taXNlO1xuICB9IGNhdGNoIChlKSB7XG4gICAgcmV0dXJuIGU7XG4gIH1cbiAgdGhyb3cgbmV3IEVycm9yKFwiRmFpbGVkIHRvIGFzc2VydCB0aGUgcHJvbWlzZSB0byBiZSByZWplY3RlZC5cIik7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBhc3NlcnRUaHJvdyhtZXRob2Q6ICgpID0+IHZvaWQpIHtcbiAgdHJ5IHtcbiAgICBtZXRob2QoKTtcbiAgfSBjYXRjaCAoZSkge1xuICAgIHJldHVybiBlO1xuICB9XG4gIHRocm93IG5ldyBFcnJvcihcIkZhaWxlZCB0byBhc3NlcnQgYW4gZXJyb3IgdG8gYmUgdGhyb3duLlwiKTtcbn1cblxuZXhwb3J0IHR5cGUgQXN5bmNNYXRjaEZuPFQ+ID0gKGFjdHVhbDogVCkgPT4gUHJvbWlzZTx2b2lkPjtcblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGFzeW5jQXNzZXJ0VGhhdDxUPihcbiAgYWN0dWFsOiBULFxuICBhc3luY01hdGNoOiBBc3luY01hdGNoRm48VD4sXG4gIHRhcmdldE5hbWU6IHN0cmluZ1xuKTogUHJvbWlzZTx2b2lkPiB7XG4gIHRyeSB7XG4gICAgYXdhaXQgYXN5bmNNYXRjaChhY3R1YWwpO1xuICB9IGNhdGNoIChlKSB7XG4gICAgZS5tZXNzYWdlID0gYFdoZW4gbWF0Y2hpbmcgJHt0YXJnZXROYW1lfTpcXG4ke2UubWVzc2FnZX1gO1xuICAgIHRocm93IGU7XG4gIH1cbn1cblxuZXhwb3J0IHR5cGUgTWF0Y2hGbjxUPiA9IChhY3R1YWw6IFQpID0+IHZvaWQ7XG5cbmV4cG9ydCBmdW5jdGlvbiBhc3NlcnRUaGF0PFQ+KFxuICBhY3R1YWw6IFQsXG4gIG1hdGNoOiBNYXRjaEZuPFQ+LFxuICB0YXJnZXROYW1lOiBzdHJpbmdcbik6IHZvaWQge1xuICB0cnkge1xuICAgIG1hdGNoKGFjdHVhbCk7XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICBlLm1lc3NhZ2UgPSBgV2hlbiBtYXRjaGluZyAke3RhcmdldE5hbWV9OlxcbiR7ZS5tZXNzYWdlfWA7XG4gICAgdGhyb3cgZTtcbiAgfVxufVxuXG5leHBvcnQgZnVuY3Rpb24gYW55PFQ+KCk6IE1hdGNoRm48VD4ge1xuICByZXR1cm4gKGFjdHVhbCkgPT4ge307XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBlcTxUPihleHBlY3RlZDogVCk6IE1hdGNoRm48VD4ge1xuICByZXR1cm4gKGFjdHVhbCkgPT4ge1xuICAgIGFzc2VydChleHBlY3RlZCA9PT0gYWN0dWFsLCBgJHtleHBlY3RlZH1gLCBgJHthY3R1YWx9YCk7XG4gIH07XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBuZTxUPihleHBlY3RlZDogVCk6IE1hdGNoRm48VD4ge1xuICByZXR1cm4gKGFjdHVhbCkgPT4ge1xuICAgIGFzc2VydChleHBlY3RlZCAhPT0gYWN0dWFsLCBgbm90IGVxdWFsIHRvICR7ZXhwZWN0ZWR9YCwgYCR7YWN0dWFsfWApO1xuICB9O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZXFMb25nU3RyKGV4cGVjdGVkOiBzdHJpbmcpOiBNYXRjaEZuPHN0cmluZz4ge1xuICByZXR1cm4gKGFjdHVhbCkgPT4ge1xuICAgIGlmIChleHBlY3RlZCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICBhc3NlcnRUaGF0KGFjdHVhbCwgZXEodW5kZWZpbmVkKSwgXCJudWxsaXR5XCIpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBsZXQgbWluTGVuZ3RoID0gTWF0aC5taW4oYWN0dWFsLmxlbmd0aCwgZXhwZWN0ZWQubGVuZ3RoKTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IG1pbkxlbmd0aDsgaSsrKSB7XG4gICAgICBhc3NlcnRUaGF0KGFjdHVhbC5jaGFyQ29kZUF0KGkpLCBlcShleHBlY3RlZC5jaGFyQ29kZUF0KGkpKSwgYGNoYXIgY29kZSBhdCBwb3NpdGlvbiAke2l9LCB3aXRoIGV4cGVjdGVkIHN0cmluZyAke2V4cGVjdGVkfSBhbmQgYWN0dWFsIHN0cmluZyAke2FjdHVhbH1gKTtcbiAgICB9XG4gICAgYXNzZXJ0VGhhdChhY3R1YWwubGVuZ3RoLCBlcShleHBlY3RlZC5sZW5ndGgpLCBgc3RyaW5nIGxlbmd0aCwgd2l0aCBleHBlY3RlZCBzdHJpbmcgJHtleHBlY3RlZH0gYW5kIGFjdHVhbCBzdHJpbmcgJHthY3R1YWx9YCk7XG4gIH07XG59XG5cbi8vIEdyZWF0ZXIgdGhhblxuZXhwb3J0IGZ1bmN0aW9uIGd0KGV4cGVjdGVkOiBudW1iZXIpOiBNYXRjaEZuPG51bWJlcj4ge1xuICByZXR1cm4gKGFjdHVhbCkgPT4ge1xuICAgIGFzc2VydChhY3R1YWwgPiBleHBlY3RlZCwgYD4gJHtleHBlY3RlZH1gLCBgJHthY3R1YWx9YCk7XG4gIH07XG59XG5cbi8vIEdyZWF0ZXIgYW5kIGVxdWFsXG5leHBvcnQgZnVuY3Rpb24gZ2UoZXhwZWN0ZWQ6IG51bWJlcik6IE1hdGNoRm48bnVtYmVyPiB7XG4gIHJldHVybiAoYWN0dWFsKSA9PiB7XG4gICAgYXNzZXJ0KGFjdHVhbCA+PSBleHBlY3RlZCwgYD49ICR7ZXhwZWN0ZWR9YCwgYCR7YWN0dWFsfWApO1xuICB9O1xufVxuXG4vLyBMZXNzIHRoYW5cbmV4cG9ydCBmdW5jdGlvbiBsdChleHBlY3RlZDogbnVtYmVyKTogTWF0Y2hGbjxudW1iZXI+IHtcbiAgcmV0dXJuIChhY3R1YWwpID0+IHtcbiAgICBhc3NlcnQoYWN0dWFsIDwgZXhwZWN0ZWQsIGA8ICR7ZXhwZWN0ZWR9YCwgYCR7YWN0dWFsfWApO1xuICB9O1xufVxuXG4vLyBMZXNzIGFuZCBlcXVhbFxuZXhwb3J0IGZ1bmN0aW9uIGxlKGV4cGVjdGVkOiBudW1iZXIpOiBNYXRjaEZuPG51bWJlcj4ge1xuICByZXR1cm4gKGFjdHVhbCkgPT4ge1xuICAgIGFzc2VydChhY3R1YWwgPD0gZXhwZWN0ZWQsIGA8PSAke2V4cGVjdGVkfWAsIGAke2FjdHVhbH1gKTtcbiAgfTtcbn1cblxuLy8gRXF1YWwgYXBwcm94aW1hdGVseVxuZXhwb3J0IGZ1bmN0aW9uIGVxQXBwcihcbiAgZXhwZWN0ZWQ6IG51bWJlcixcbiAgZGV2aWF0aW9uOiBudW1iZXIgPSAwLjAxXG4pOiBNYXRjaEZuPG51bWJlcj4ge1xuICByZXR1cm4gKGFjdHVhbCkgPT4ge1xuICAgIGFzc2VydChcbiAgICAgIGFjdHVhbCA+PSBleHBlY3RlZCAqICgxIC0gZGV2aWF0aW9uKSxcbiAgICAgIGB0byBlcXVhbCBhcHByb3hpbWF0ZWx5IHRvICR7ZXhwZWN0ZWR9YCxcbiAgICAgIGAke2FjdHVhbH1gXG4gICAgKTtcbiAgICBhc3NlcnQoXG4gICAgICBhY3R1YWwgPD0gZXhwZWN0ZWQgKiAoMSArIGRldmlhdGlvbiksXG4gICAgICBgdG8gZXF1YWwgYXBwcm94aW1hdGVseSB0byAke2V4cGVjdGVkfWAsXG4gICAgICBgJHthY3R1YWx9YFxuICAgICk7XG4gIH07XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBjb250YWluU3RyKGV4cGVjdGVkOiBzdHJpbmcpOiBNYXRjaEZuPHN0cmluZz4ge1xuICByZXR1cm4gKGFjdHVhbCkgPT4ge1xuICAgIGFzc2VydChCb29sZWFuKGFjdHVhbCksIGB0byBub3QgYmUgbnVsbGAsIGBudWxsYCk7XG4gICAgYXNzZXJ0KGFjdHVhbC5pbmRleE9mKGV4cGVjdGVkKSAhPSAtMSwgYGNvbnRhaW5pbmcgJHtleHBlY3RlZH1gLCBhY3R1YWwpO1xuICB9O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gaXNBcnJheTxUPihleHBlY3RlZD86IEFycmF5PE1hdGNoRm48VD4+KTogTWF0Y2hGbjxBcnJheTxUPj4ge1xuICByZXR1cm4gKGFjdHVhbCkgPT4ge1xuICAgIGlmIChleHBlY3RlZCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICBhc3NlcnRUaGF0KGFjdHVhbCwgZXEodW5kZWZpbmVkKSwgXCJudWxsaXR5XCIpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBhc3NlcnQoQm9vbGVhbihhY3R1YWwpLCBgdG8gbm90IGJlIG51bGxgLCBgbnVsbGApO1xuICAgIGFzc2VydFRoYXQoYWN0dWFsLmxlbmd0aCwgZXEoZXhwZWN0ZWQubGVuZ3RoKSwgYGFycmF5IGxlbmd0aGApO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgYWN0dWFsLmxlbmd0aDsgaSsrKSB7XG4gICAgICBhc3NlcnRUaGF0KGFjdHVhbFtpXSwgZXhwZWN0ZWRbaV0sIGAke2l9dGggZWxlbWVudGApO1xuICAgIH1cbiAgfTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGNvbnRhaW5Vbm9yZGVyZWRFbGVtZW50czxUPihcbiAgZXhwZWN0ZWRNYXRjaGVycz86IEFycmF5PE1hdGNoRm48VD4+XG4pOiBNYXRjaEZuPEFycmF5PFQ+PiB7XG4gIHJldHVybiAoYWN0dWFsKSA9PiB7XG4gICAgYXNzZXJ0KEJvb2xlYW4oYWN0dWFsKSwgYHRvIG5vdCBiZSBudWxsYCwgYG51bGxgKTtcbiAgICBsZXQgbWF0Y2hlZEluZGV4ID0gbmV3IFNldDxudW1iZXI+KCk7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBleHBlY3RlZE1hdGNoZXJzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBsZXQgbWF0Y2hlZCA9IGZhbHNlO1xuICAgICAgZm9yIChsZXQgaiA9IDA7IGogPCBhY3R1YWwubGVuZ3RoOyBqKyspIHtcbiAgICAgICAgaWYgKG1hdGNoZWRJbmRleC5oYXMoaikpIHtcbiAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgZXhwZWN0ZWRNYXRjaGVyc1tpXShhY3R1YWxbal0pO1xuICAgICAgICAgIG1hdGNoZWQgPSB0cnVlO1xuICAgICAgICAgIG1hdGNoZWRJbmRleC5hZGQoaik7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH0gY2F0Y2ggKGUpIHt9XG4gICAgICB9XG4gICAgICBpZiAoIW1hdGNoZWQpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBDYW5ub3QgbWF0Y2ggdGhlICR7aX10aCBleHBlY3RlZCBlbGVtZW50LmApO1xuICAgICAgfVxuICAgIH1cbiAgfTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGlzVW5vcmRlcmVkQXJyYXk8VD4oXG4gIGV4cGVjdGVkPzogQXJyYXk8TWF0Y2hGbjxUPj5cbik6IE1hdGNoRm48QXJyYXk8VD4+IHtcbiAgcmV0dXJuIChhY3R1YWwpID0+IHtcbiAgICBhc3NlcnQoQm9vbGVhbihhY3R1YWwpLCBgdG8gbm90IGJlIG51bGxgLCBgbnVsbGApO1xuICAgIGFzc2VydFRoYXQoYWN0dWFsLmxlbmd0aCwgZXEoZXhwZWN0ZWQubGVuZ3RoKSwgYGFycmF5IGxlbmd0aGApO1xuICAgIGFzc2VydFRoYXQoXG4gICAgICBhY3R1YWwsXG4gICAgICBjb250YWluVW5vcmRlcmVkRWxlbWVudHMoZXhwZWN0ZWQpLFxuICAgICAgYHVub3JkZXJlZCBlbGVtZW50c2BcbiAgICApO1xuICB9O1xufVxuXG4vLyBNYXRjaCBTZXQgaW4gaW5zZXJ0aW9uIG9yZGVyLlxuZXhwb3J0IGZ1bmN0aW9uIGlzU2V0PFQ+KGV4cGVjdGVkPzogQXJyYXk8TWF0Y2hGbjxUPj4pOiBNYXRjaEZuPFNldDxUPj4ge1xuICByZXR1cm4gKGFjdHVhbCkgPT4ge1xuICAgIGlmIChleHBlY3RlZCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICBhc3NlcnRUaGF0KGFjdHVhbCwgZXEodW5kZWZpbmVkKSwgXCJudWxsaXR5XCIpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBhc3NlcnQoQm9vbGVhbihhY3R1YWwpLCBgdG8gbm90IGJlIG51bGxgLCBgbnVsbGApO1xuICAgIGFzc2VydFRoYXQoYWN0dWFsLnNpemUsIGVxKGV4cGVjdGVkLmxlbmd0aCksIGBzZXQgc2l6ZWApO1xuICAgIGxldCBpID0gMDtcbiAgICBmb3IgKGxldCB2YWx1ZSBvZiBhY3R1YWwpIHtcbiAgICAgIGFzc2VydFRoYXQodmFsdWUsIGV4cGVjdGVkW2ldLCBgJHtpfXRoIGVsZW1lbnRgKTtcbiAgICAgIGkrKztcbiAgICB9XG4gIH07XG59XG5cbi8vIE1hdGNoIE1hcCBpbiBpbnNlcnRpb24gb3JkZXIuXG5leHBvcnQgZnVuY3Rpb24gaXNNYXA8SywgVj4oXG4gIGV4cGVjdGVkPzogQXJyYXk8W01hdGNoRm48Sz4sIE1hdGNoRm48Vj5dPlxuKTogTWF0Y2hGbjxNYXA8SywgVj4+IHtcbiAgcmV0dXJuIChhY3R1YWwpID0+IHtcbiAgICBpZiAoZXhwZWN0ZWQgPT09IHVuZGVmaW5lZCkge1xuICAgICAgYXNzZXJ0VGhhdChhY3R1YWwsIGVxKHVuZGVmaW5lZCksIFwibnVsbGl0eVwiKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgYXNzZXJ0KEJvb2xlYW4oYWN0dWFsKSwgYHRvIG5vdCBiZSBudWxsYCwgYG51bGxgKTtcbiAgICBhc3NlcnRUaGF0KGFjdHVhbC5zaXplLCBlcShleHBlY3RlZC5sZW5ndGgpLCBgbWFwIHNpemVgKTtcbiAgICBsZXQgaSA9IDA7XG4gICAgZm9yIChsZXQgW2tleSwgdmFsdWVdIG9mIGFjdHVhbCkge1xuICAgICAgYXNzZXJ0VGhhdChrZXksIGV4cGVjdGVkW2ldWzBdLCBgJHtpfXRoIGtleWApO1xuICAgICAgYXNzZXJ0VGhhdCh2YWx1ZSwgZXhwZWN0ZWRbaV1bMV0sIGAke2l9dGggdmFsdWVgKTtcbiAgICAgIGkrKztcbiAgICB9XG4gIH07XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBlcUVycm9yKGV4cGVjdGVkOiBFcnJvcik6IE1hdGNoRm48YW55PiB7XG4gIHJldHVybiAoYWN0dWFsKSA9PiB7XG4gICAgYXNzZXJ0KGFjdHVhbCBpbnN0YW5jZW9mIEVycm9yLCBgdG8gYmUgYW4gRXJyb3JgLCBgJHthY3R1YWx9YCk7XG4gICAgYXNzZXJ0VGhhdChhY3R1YWwubmFtZSwgZXEoZXhwZWN0ZWQubmFtZSksIGBuYW1lIG9mIHRoZSBlcnJvcmApO1xuICAgIGFzc2VydFRoYXQoYWN0dWFsLm1lc3NhZ2UsIGNvbnRhaW5TdHIoZXhwZWN0ZWQubWVzc2FnZSksIGAke2FjdHVhbC5zdGFja31gKTtcbiAgfTtcbn1cbiJdfQ==