@tensorflow/tfjs-core
Version:
Hardware-accelerated JavaScript library for machine intelligence
146 lines • 22.4 kB
JavaScript
/**
* @license
* Copyright 2019 Google LLC. All 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 * as non_max_suppression_util from './non_max_suppression_util';
describe('non_max_suppression_util', () => {
const insertionPoint = (i) => -(i + 1);
describe('binarySearch', () => {
const d = [
-897123.9, -321434.58758, -1321.3124, -324, -9, -3, 0, 0, 0, 0.31255, 5,
142.88888708, 334, 342, 453, 54254
];
it('-897123.9 should be found at index 0', () => {
const result = non_max_suppression_util.binarySearch(d, -897123.9);
expect(result).toBe(0);
});
it(`54254 should be found at index ${d.length - 1}`, () => {
const result = non_max_suppression_util.binarySearch(d, 54254);
expect(result).toBe(d.length - 1);
});
it('-3 should be found at index 5', () => {
const result = non_max_suppression_util.binarySearch(d, -3);
expect(result).toBe(5);
});
it('0 should be found at index 6', () => {
const result = non_max_suppression_util.binarySearch(d, 0);
expect(result).toBe(6);
});
it('-900000 should have an insertion point of 0', () => {
const result = non_max_suppression_util.binarySearch(d, -900000);
expect(result).toBeLessThan(0);
expect(insertionPoint(result)).toBe(0);
});
it(`54255 should have an insertion point of ${d.length}`, () => {
const result = non_max_suppression_util.binarySearch(d, 54255);
expect(result).toBeLessThan(0);
expect(insertionPoint(result)).toEqual(d.length);
});
it('1.1 should have an insertion point of 10', () => {
const result = non_max_suppression_util.binarySearch(d, 1.1);
expect(result).toBeLessThan(0);
expect(insertionPoint(result)).toEqual(10);
});
});
describe('binarySearch with custom comparator', () => {
const e = [
54254,
453,
342,
334,
142.88888708,
5,
0.31255,
0,
0,
0,
-3,
-9,
-324,
-1321.3124,
-321434.58758,
-897123.9,
];
const revComparator = (a, b) => (b - a);
it('54254 should be found at index 0', () => {
const result = non_max_suppression_util.binarySearch(e, 54254, revComparator);
expect(result).toBe(0);
});
it(`-897123.9 should be found at index ${e.length - 1}`, () => {
const result = non_max_suppression_util.binarySearch(e, -897123.9, revComparator);
expect(result).toBe(e.length - 1);
});
it('-3 should be found at index 10', () => {
const result = non_max_suppression_util.binarySearch(e, -3, revComparator);
expect(result).toBe(10);
});
it('0 should be found at index 7', () => {
const result = non_max_suppression_util.binarySearch(e, 0, revComparator);
expect(result).toBe(7);
});
it('54254.1 should have an insertion point of 0', () => {
const result = non_max_suppression_util.binarySearch(e, 54254.1, revComparator);
expect(result).toBeLessThan(0);
expect(insertionPoint(result)).toBe(0);
});
it(`-897124 should have an insertion point of ${e.length}`, () => {
const result = non_max_suppression_util.binarySearch(e, -897124, revComparator);
expect(result).toBeLessThan(0);
expect(insertionPoint(result)).toBe(e.length);
});
});
describe('binarySearch with custom comparator with single element array', () => {
const g = [1];
const revComparator = (a, b) => (b - a);
it('1 should be found at index 0', () => {
const result = non_max_suppression_util.binarySearch(g, 1, revComparator);
expect(result).toBe(0);
});
it('2 should have an insertion point of 0', () => {
const result = non_max_suppression_util.binarySearch(g, 2, revComparator);
expect(result).toBeLessThan(0);
expect(insertionPoint(result)).toBe(0);
});
it('0 should have an insertion point of 1', () => {
const result = non_max_suppression_util.binarySearch(g, 0, revComparator);
expect(result).toBeLessThan(0);
expect(insertionPoint(result)).toBe(1);
});
});
describe('binarySearch test left-most duplicated element', () => {
it('should find the index of the first 0', () => {
const result = non_max_suppression_util.binarySearch([0, 0, 1], 0);
expect(result).toBe(0);
});
it('should find the index of the first 1', () => {
const result = non_max_suppression_util.binarySearch([0, 1, 1], 1);
expect(result).toBe(1);
});
});
describe('binaryInsert', () => {
it('inserts correctly', () => {
const a = [];
non_max_suppression_util.binaryInsert(a, 3);
expect(a).toEqual([3]);
non_max_suppression_util.binaryInsert(a, 3);
expect(a).toEqual([3, 3]);
non_max_suppression_util.binaryInsert(a, 1);
expect(a).toEqual([1, 3, 3]);
non_max_suppression_util.binaryInsert(a, 5);
expect(a).toEqual([1, 3, 3, 5]);
});
});
});
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibm9uX21heF9zdXBwcmVzc2lvbl91dGlsX3Rlc3QuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi90ZmpzLWNvcmUvc3JjL2JhY2tlbmRzL25vbl9tYXhfc3VwcHJlc3Npb25fdXRpbF90ZXN0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7Ozs7Ozs7Ozs7R0FlRztBQUVILE9BQU8sS0FBSyx3QkFBd0IsTUFBTSw0QkFBNEIsQ0FBQztBQUV2RSxRQUFRLENBQUMsMEJBQTBCLEVBQUUsR0FBRyxFQUFFO0lBQ3hDLE1BQU0sY0FBYyxHQUFHLENBQUMsQ0FBUyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO0lBRS9DLFFBQVEsQ0FBQyxjQUFjLEVBQUUsR0FBRyxFQUFFO1FBQzVCLE1BQU0sQ0FBQyxHQUFHO1lBQ1IsQ0FBQyxRQUFRLEVBQUUsQ0FBQyxZQUFZLEVBQUUsQ0FBQyxTQUFTLEVBQUUsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsT0FBTyxFQUFFLENBQUM7WUFDdkUsWUFBWSxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEtBQUs7U0FDbkMsQ0FBQztRQUVGLEVBQUUsQ0FBQyxzQ0FBc0MsRUFBRSxHQUFHLEVBQUU7WUFDOUMsTUFBTSxNQUFNLEdBQUcsd0JBQXdCLENBQUMsWUFBWSxDQUFDLENBQUMsRUFBRSxDQUFDLFFBQVEsQ0FBQyxDQUFDO1lBQ25FLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDekIsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsa0NBQWtDLENBQUMsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFLEVBQUUsR0FBRyxFQUFFO1lBQ3hELE1BQU0sTUFBTSxHQUFHLHdC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NUIsRUFBRSxDQUFDLG1CQUFtQixFQUFFLEdBQUcsRUFBRTtZQUMzQixNQUFNLENBQUMsR0FBYSxFQUFFLENBQUM7WUFFdkIsd0JBQXdCLENBQUMsWUFBWSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztZQUM1QyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUV2Qix3QkFBd0IsQ0FBQyxZQUFZLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO1lBQzVDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUUxQix3QkFBd0IsQ0FBQyxZQUFZLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO1lBQzVDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFFN0Isd0JBQXdCLENBQUMsWUFBWSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztZQUM1QyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUNsQyxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQyxDQUFDO0FBQ0wsQ0FBQyxDQUFDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEBsaWNlbnNlXG4gKiBDb3B5cmlnaHQgMjAxOSBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICovXG5cbmltcG9ydCAqIGFzIG5vbl9tYXhfc3VwcHJlc3Npb25fdXRpbCBmcm9tICcuL25vbl9tYXhfc3VwcHJlc3Npb25fdXRpbCc7XG5cbmRlc2NyaWJlKCdub25fbWF4X3N1cHByZXNzaW9uX3V0aWwnLCAoKSA9PiB7XG4gIGNvbnN0IGluc2VydGlvblBvaW50ID0gKGk6IG51bWJlcikgPT4gLShpICsgMSk7XG5cbiAgZGVzY3JpYmUoJ2JpbmFyeVNlYXJjaCcsICgpID0+IHtcbiAgICBjb25zdCBkID0gW1xuICAgICAgLTg5NzEyMy45LCAtMzIxNDM0LjU4NzU4LCAtMTMyMS4zMTI0LCAtMzI0LCAtOSwgLTMsIDAsIDAsIDAsIDAuMzEyNTUsIDUsXG4gICAgICAxNDIuODg4ODg3MDgsIDMzNCwgMzQyLCA0NTMsIDU0MjU0XG4gICAgXTtcblxuICAgIGl0KCctODk3MTIzLjkgc2hvdWxkIGJlIGZvdW5kIGF0IGluZGV4IDAnLCAoKSA9PiB7XG4gICAgICBjb25zdCByZXN1bHQgPSBub25fbWF4X3N1cHByZXNzaW9uX3V0aWwuYmluYXJ5U2VhcmNoKGQsIC04OTcxMjMuOSk7XG4gICAgICBleHBlY3QocmVzdWx0KS50b0JlKDApO1xuICAgIH0pO1xuXG4gICAgaXQoYDU0MjU0IHNob3VsZCBiZSBmb3VuZCBhdCBpbmRleCAke2QubGVuZ3RoIC0gMX1gLCAoKSA9PiB7XG4gICAgICBjb25zdCByZXN1bHQgPSBub25fbWF4X3N1cHByZXNzaW9uX3V0aWwuYmluYXJ5U2VhcmNoKGQsIDU0MjU0KTtcbiAgICAgIGV4cGVjdChyZXN1bHQpLnRvQmUoZC5sZW5ndGggLSAxKTtcbiAgICB9KTtcblxuICAgIGl0KCctMyBzaG91bGQgYmUgZm91bmQgYXQgaW5kZXggNScsICgpID0+IHtcbiAgICAgIGNvbnN0IHJlc3VsdCA9IG5vbl9tYXhfc3VwcHJlc3Npb25fdXRpbC5iaW5hcnlTZWFyY2goZCwgLTMpO1xuICAgICAgZXhwZWN0KHJlc3VsdCkudG9CZSg1KTtcbiAgICB9KTtcblxuICAgIGl0KCcwIHNob3VsZCBiZSBmb3VuZCBhdCBpbmRleCA2JywgKCkgPT4ge1xuICAgICAgY29uc3QgcmVzdWx0ID0gbm9uX21heF9zdXBwcmVzc2lvbl91dGlsLmJpbmFyeVNlYXJjaChkLCAwKTtcbiAgICAgIGV4cGVjdChyZXN1bHQpLnRvQmUoNik7XG4gICAgfSk7XG5cbiAgICBpdCgnLTkwMDAwMCBzaG91bGQgaGF2ZSBhbiBpbnNlcnRpb24gcG9pbnQgb2YgMCcsICgpID0+IHtcbiAgICAgIGNvbnN0IHJlc3VsdCA9IG5vbl9tYXhfc3VwcHJlc3Npb25fdXRpbC5iaW5hcnlTZWFyY2goZCwgLTkwMDAwMCk7XG4gICAgICBleHBlY3QocmVzdWx0KS50b0JlTGVzc1RoYW4oMCk7XG4gICAgICBleHBlY3QoaW5zZXJ0aW9uUG9pbnQocmVzdWx0KSkudG9CZSgwKTtcbiAgICB9KTtcblxuICAgIGl0KGA1NDI1NSBzaG91bGQgaGF2ZSBhbiBpbnNlcnRpb24gcG9pbnQgb2YgJHtkLmxlbmd0aH1gLCAoKSA9PiB7XG4gICAgICBjb25zdCByZXN1bHQgPSBub25fbWF4X3N1cHByZXNzaW9uX3V0aWwuYmluYXJ5U2VhcmNoKGQsIDU0MjU1KTtcbiAgICAgIGV4cGVjdChyZXN1bHQpLnRvQmVMZXNzVGhhbigwKTtcbiAgICAgIGV4cGVjdChpbnNlcnRpb25Qb2ludChyZXN1bHQpKS50b0VxdWFsKGQubGVuZ3RoKTtcbiAgICB9KTtcblxuICAgIGl0KCcxLjEgc2hvdWxkIGhhdmUgYW4gaW5zZXJ0aW9uIHBvaW50IG9mIDEwJywgKCkgPT4ge1xuICAgICAgY29uc3QgcmVzdWx0ID0gbm9uX21heF9zdXBwcmVzc2lvbl91dGlsLmJpbmFyeVNlYXJjaChkLCAxLjEpO1xuICAgICAgZXhwZWN0KHJlc3VsdCkudG9CZUxlc3NUaGFuKDApO1xuICAgICAgZXhwZWN0KGluc2VydGlvblBvaW50KHJlc3VsdCkpLnRvRXF1YWwoMTApO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnYmluYXJ5U2VhcmNoIHdpdGggY3VzdG9tIGNvbXBhcmF0b3InLCAoKSA9PiB7XG4gICAgY29uc3QgZSA9IFtcbiAgICAgIDU0MjU0LFxuICAgICAgNDUzLFxuICAgICAgMzQyLFxuICAgICAgMzM0LFxuICAgICAgMTQyLjg4ODg4NzA4LFxuICAgICAgNSxcbiAgICAgIDAuMzEyNTUsXG4gICAgICAwLFxuICAgICAgMCxcbiAgICAgIDAsXG4gICAgICAtMyxcbiAgICAgIC05LFxuICAgICAgLTMyNCxcbiAgICAgIC0xMzIxLjMxMjQsXG4gICAgICAtMzIxNDM0LjU4NzU4LFxuICAgICAgLTg5NzEyMy45LFxuICAgIF07XG5cbiAgICBjb25zdCByZXZDb21wYXJhdG9yID0gKGE6IG51bWJlciwgYjogbnVtYmVyKSA9PiAoYiAtIGEpO1xuXG4gICAgaXQoJzU0MjU0IHNob3VsZCBiZSBmb3VuZCBhdCBpbmRleCAwJywgKCkgPT4ge1xuICAgICAgY29uc3QgcmVzdWx0ID1cbiAgICAgICAgICBub25fbWF4X3N1cHByZXNzaW9uX3V0aWwuYmluYXJ5U2VhcmNoKGUsIDU0MjU0LCByZXZDb21wYXJhdG9yKTtcbiAgICAgIGV4cGVjdChyZXN1bHQpLnRvQmUoMCk7XG4gICAgfSk7XG5cbiAgICBpdChgLTg5NzEyMy45IHNob3VsZCBiZSBmb3VuZCBhdCBpbmRleCAke2UubGVuZ3RoIC0gMX1gLCAoKSA9PiB7XG4gICAgICBjb25zdCByZXN1bHQgPVxuICAgICAgICAgIG5vbl9tYXhfc3VwcHJlc3Npb25fdXRpbC5iaW5hcnlTZWFyY2goZSwgLTg5NzEyMy45LCByZXZDb21wYXJhdG9yKTtcbiAgICAgIGV4cGVjdChyZXN1bHQpLnRvQmUoZS5sZW5ndGggLSAxKTtcbiAgICB9KTtcblxuICAgIGl0KCctMyBzaG91bGQgYmUgZm91bmQgYXQgaW5kZXggMTAnLCAoKSA9PiB7XG4gICAgICBjb25zdCByZXN1bHQgPVxuICAgICAgICAgIG5vbl9tYXhfc3VwcHJlc3Npb25fdXRpbC5iaW5hcnlTZWFyY2goZSwgLTMsIHJldkNvbXBhcmF0b3IpO1xuICAgICAgZXhwZWN0KHJlc3VsdCkudG9CZSgxMCk7XG4gICAgfSk7XG5cbiAgICBpdCgnMCBzaG91bGQgYmUgZm91bmQgYXQgaW5kZXggNycsICgpID0+IHtcbiAgICAgIGNvbnN0IHJlc3VsdCA9IG5vbl9tYXhfc3VwcHJlc3Npb25fdXRpbC5iaW5hcnlTZWFyY2goZSwgMCwgcmV2Q29tcGFyYXRvcik7XG4gICAgICBleHBlY3QocmVzdWx0KS50b0JlKDcpO1xuICAgIH0pO1xuXG4gICAgaXQoJzU0MjU0LjEgc2hvdWxkIGhhdmUgYW4gaW5zZXJ0aW9uIHBvaW50IG9mIDAnLCAoKSA9PiB7XG4gICAgICBjb25zdCByZXN1bHQgPVxuICAgICAgICAgIG5vbl9tYXhfc3VwcHJlc3Npb25fdXRpbC5iaW5hcnlTZWFyY2goZSwgNTQyNTQuMSwgcmV2Q29tcGFyYXRvcik7XG4gICAgICBleHBlY3QocmVzdWx0KS50b0JlTGVzc1RoYW4oMCk7XG4gICAgICBleHBlY3QoaW5zZXJ0aW9uUG9pbnQocmVzdWx0KSkudG9CZSgwKTtcbiAgICB9KTtcblxuICAgIGl0KGAtODk3MTI0IHNob3VsZCBoYXZlIGFuIGluc2VydGlvbiBwb2ludCBvZiAke2UubGVuZ3RofWAsICgpID0+IHtcbiAgICAgIGNvbnN0IHJlc3VsdCA9XG4gICAgICAgICAgbm9uX21heF9zdXBwcmVzc2lvbl91dGlsLmJpbmFyeVNlYXJjaChlLCAtODk3MTI0LCByZXZDb21wYXJhdG9yKTtcbiAgICAgIGV4cGVjdChyZXN1bHQpLnRvQmVMZXNzVGhhbigwKTtcbiAgICAgIGV4cGVjdChpbnNlcnRpb25Qb2ludChyZXN1bHQpKS50b0JlKGUubGVuZ3RoKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoXG4gICAgICAnYmluYXJ5U2VhcmNoIHdpdGggY3VzdG9tIGNvbXBhcmF0b3Igd2l0aCBzaW5nbGUgZWxlbWVudCBhcnJheScsICgpID0+IHtcbiAgICAgICAgY29uc3QgZyA9IFsxXTtcblxuICAgICAgICBjb25zdCByZXZDb21wYXJhdG9yID0gKGE6IG51bWJlciwgYjogbnVtYmVyKSA9PiAoYiAtIGEpO1xuXG4gICAgICAgIGl0KCcxIHNob3VsZCBiZSBmb3VuZCBhdCBpbmRleCAwJywgKCkgPT4ge1xuICAgICAgICAgIGNvbnN0IHJlc3VsdCA9XG4gICAgICAgICAgICAgIG5vbl9tYXhfc3VwcHJlc3Npb25fdXRpbC5iaW5hcnlTZWFyY2goZywgMSwgcmV2Q29tcGFyYXRvcik7XG4gICAgICAgICAgZXhwZWN0KHJlc3VsdCkudG9CZSgwKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaXQoJzIgc2hvdWxkIGhhdmUgYW4gaW5zZXJ0aW9uIHBvaW50IG9mIDAnLCAoKSA9PiB7XG4gICAgICAgICAgY29uc3QgcmVzdWx0ID1cbiAgICAgICAgICAgICAgbm9uX21heF9zdXBwcmVzc2lvbl91dGlsLmJpbmFyeVNlYXJjaChnLCAyLCByZXZDb21wYXJhdG9yKTtcbiAgICAgICAgICBleHBlY3QocmVzdWx0KS50b0JlTGVzc1RoYW4oMCk7XG4gICAgICAgICAgZXhwZWN0KGluc2VydGlvblBvaW50KHJlc3VsdCkpLnRvQmUoMCk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGl0KCcwIHNob3VsZCBoYXZlIGFuIGluc2VydGlvbiBwb2ludCBvZiAxJywgKCkgPT4ge1xuICAgICAgICAgIGNvbnN0IHJlc3VsdCA9XG4gICAgICAgICAgICAgIG5vbl9tYXhfc3VwcHJlc3Npb25fdXRpbC5iaW5hcnlTZWFyY2goZywgMCwgcmV2Q29tcGFyYXRvcik7XG4gICAgICAgICAgZXhwZWN0KHJlc3VsdCkudG9CZUxlc3NUaGFuKDApO1xuICAgICAgICAgIGV4cGVjdChpbnNlcnRpb25Qb2ludChyZXN1bHQpKS50b0JlKDEpO1xuICAgICAgICB9KTtcbiAgICAgIH0pO1xuXG4gIGRlc2NyaWJlKCdiaW5hcnlTZWFyY2ggdGVzdCBsZWZ0LW1vc3QgZHVwbGljYXRlZCBlbGVtZW50JywgKCkgPT4ge1xuICAgIGl0KCdzaG91bGQgZmluZCB0aGUgaW5kZXggb2YgdGhlIGZpcnN0IDAnLCAoKSA9PiB7XG4gICAgICBjb25zdCByZXN1bHQgPSBub25fbWF4X3N1cHByZXNzaW9uX3V0aWwuYmluYXJ5U2VhcmNoKFswLCAwLCAxXSwgMCk7XG4gICAgICBleHBlY3QocmVzdWx0KS50b0JlKDApO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBmaW5kIHRoZSBpbmRleCBvZiB0aGUgZmlyc3QgMScsICgpID0+IHtcbiAgICAgIGNvbnN0IHJlc3VsdCA9IG5vbl9tYXhfc3VwcHJlc3Npb25fdXRpbC5iaW5hcnlTZWFyY2goWzAsIDEsIDFdLCAxKTtcbiAgICAgIGV4cGVjdChyZXN1bHQpLnRvQmUoMSk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdiaW5hcnlJbnNlcnQnLCAoKSA9PiB7XG4gICAgaXQoJ2luc2VydHMgY29ycmVjdGx5JywgKCkgPT4ge1xuICAgICAgY29uc3QgYTogbnVtYmVyW10gPSBbXTtcblxuICAgICAgbm9uX21heF9zdXBwcmVzc2lvbl91dGlsLmJpbmFyeUluc2VydChhLCAzKTtcbiAgICAgIGV4cGVjdChhKS50b0VxdWFsKFszXSk7XG5cbiAgICAgIG5vbl9tYXhfc3VwcHJlc3Npb25fdXRpbC5iaW5hcnlJbnNlcnQoYSwgMyk7XG4gICAgICBleHBlY3QoYSkudG9FcXVhbChbMywgM10pO1xuXG4gICAgICBub25fbWF4X3N1cHByZXNzaW9uX3V0aWwuYmluYXJ5SW5zZXJ0KGEsIDEpO1xuICAgICAgZXhwZWN0KGEpLnRvRXF1YWwoWzEsIDMsIDNdKTtcblxuICAgICAgbm9uX21heF9zdXBwcmVzc2lvbl91dGlsLmJpbmFyeUluc2VydChhLCA1KTtcbiAgICAgIGV4cGVjdChhKS50b0VxdWFsKFsxLCAzLCAzLCA1XSk7XG4gICAgfSk7XG4gIH0pO1xufSk7XG4iXX0=