/**
|
* @license
|
* Copyright 2020 Google Inc. 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 tf from '../index';
|
import { ALL_ENVS, describeWithFlags } from '../jasmine_util';
|
import { expectPromiseToFail } from '../test_util';
|
describeWithFlags('toPixels no canvas', ALL_ENVS, () => {
|
it('draws a rank-2 float32 tensor', async () => {
|
const x = tf.tensor2d([.15, .2], [2, 1], 'float32');
|
const data = await tf.browser.toPixels(x);
|
const expected = new Uint8ClampedArray([
|
Math.round(.15 * 255), Math.round(.15 * 255), Math.round(.15 * 255), 255,
|
Math.round(.2 * 255), Math.round(.2 * 255), Math.round(.2 * 255), 255
|
]);
|
expect(data).toEqual(expected);
|
});
|
it('draws a rank-2 int32 tensor', async () => {
|
const x = tf.tensor2d([10, 20], [2, 1], 'int32');
|
const data = await tf.browser.toPixels(x);
|
const expected = new Uint8ClampedArray([10, 10, 10, 255, 20, 20, 20, 255]);
|
expect(data).toEqual(expected);
|
});
|
it('draws a rank-3 float32 tensor, 1 channel', async () => {
|
const x = tf.tensor3d([.15, .2], [2, 1, 1], 'float32');
|
const data = await tf.browser.toPixels(x);
|
const expected = new Uint8ClampedArray([
|
Math.round(.15 * 255), Math.round(.15 * 255), Math.round(.15 * 255), 255,
|
Math.round(.2 * 255), Math.round(.2 * 255), Math.round(.2 * 255), 255
|
]);
|
expect(data).toEqual(expected);
|
});
|
it('draws a rank-3 int32 tensor, 1 channel', async () => {
|
const x = tf.tensor3d([10, 20], [2, 1, 1], 'int32');
|
const data = await tf.browser.toPixels(x);
|
const expected = new Uint8ClampedArray([10, 10, 10, 255, 20, 20, 20, 255]);
|
expect(data).toEqual(expected);
|
});
|
it('draws a rank-3 float32 tensor, 3 channel', async () => {
|
// 0.1 and 0.3 are changed to 0.1001 and 0.3001 to avoid boundary conditions
|
// such as Math.round(~25.5) which on Mobile Safari gives 25 and Desktop
|
// gives 26.
|
const x = tf.tensor3d([.05, .1001, .15, .2, .25, .3001], [2, 1, 3], 'float32');
|
const data = await tf.browser.toPixels(x);
|
const expected = new Uint8ClampedArray([
|
Math.round(.05 * 255), Math.round(.1001 * 255), Math.round(.15 * 255),
|
255, Math.round(.2 * 255), Math.round(.25 * 255), Math.round(.3001 * 255),
|
255
|
]);
|
expect(data).toEqual(expected);
|
});
|
it('draws a rank-3 int32 tensor, 3 channel', async () => {
|
const x = tf.tensor3d([10, 20, 30, 40, 50, 60], [2, 1, 3], 'int32');
|
const data = await tf.browser.toPixels(x);
|
const expected = new Uint8ClampedArray([10, 20, 30, 255, 40, 50, 60, 255]);
|
expect(data).toEqual(expected);
|
});
|
it('draws a rank-3 float32 tensor, 4 channel', async () => {
|
const x = tf.tensor3d([.05, .1001, .15, .2, .25, .3001, .35, .4], [2, 1, 4], 'float32');
|
const data = await tf.browser.toPixels(x);
|
const expected = new Uint8ClampedArray([
|
Math.round(.05 * 255), Math.round(.1001 * 255), Math.round(.15 * 255),
|
Math.round(.20 * 255), Math.round(.25 * 255), Math.round(.3001 * 255),
|
Math.round(.35 * 255), Math.round(.4 * 255)
|
]);
|
expect(data).toEqual(expected);
|
});
|
it('draws a rank-3 int32 tensor, 4 channel', async () => {
|
const x = tf.tensor3d([10, 20, 30, 40, 50, 60, 70, 80], [2, 1, 4], 'int32');
|
const data = await tf.browser.toPixels(x);
|
const expected = new Uint8ClampedArray([10, 20, 30, 40, 50, 60, 70, 80]);
|
expect(data).toEqual(expected);
|
});
|
it('throws for scalars', done => {
|
// tslint:disable-next-line:no-any
|
expectPromiseToFail(() => tf.browser.toPixels(tf.scalar(1)), done);
|
});
|
it('throws for rank-1 tensors', done => {
|
expectPromiseToFail(
|
// tslint:disable-next-line:no-any
|
() => tf.browser.toPixels(tf.tensor1d([1])), done);
|
});
|
it('throws for rank-4 tensors', done => {
|
expectPromiseToFail(
|
// tslint:disable-next-line:no-any
|
() => tf.browser.toPixels(tf.tensor4d([1], [1, 1, 1, 1])), done);
|
});
|
it('throws for bool dtype', done => {
|
expectPromiseToFail(() => tf.browser.toPixels(tf.tensor2d([1], [1, 1], 'bool')), done);
|
});
|
it('throws for rank-3 depth = 2', done => {
|
expectPromiseToFail(() => tf.browser.toPixels(tf.tensor3d([1, 2], [1, 1, 2])), done);
|
});
|
it('throws for rank-3 depth = 5', done => {
|
expectPromiseToFail(() => tf.browser.toPixels(tf.tensor3d([1, 2, 3, 4, 5], [1, 1, 5])), done);
|
});
|
it('throws for float32 tensor with values not in [0 - 1]', done => {
|
expectPromiseToFail(() => tf.browser.toPixels(tf.tensor2d([-1, .5], [1, 2])), done);
|
});
|
it('throws for int32 tensor with values not in [0 - 255]', done => {
|
expectPromiseToFail(() => tf.browser.toPixels(tf.tensor2d([-1, 100], [1, 2], 'int32')), done);
|
});
|
it('throws when passed a non-tensor', done => {
|
// tslint:disable-next-line:no-any
|
expectPromiseToFail(() => tf.browser.toPixels({}), done);
|
});
|
it('accepts a tensor-like object', async () => {
|
const x = [[10], [20]]; // 2x1;
|
const data = await tf.browser.toPixels(x);
|
const expected = new Uint8ClampedArray([10, 10, 10, 255, 20, 20, 20, 255]);
|
expect(data).toEqual(expected);
|
});
|
it('does not leak memory', async () => {
|
const x = tf.tensor2d([[.1], [.2]], [2, 1]);
|
const startNumTensors = tf.memory().numTensors;
|
await tf.browser.toPixels(x);
|
expect(tf.memory().numTensors).toEqual(startNumTensors);
|
});
|
it('does not leak memory given a tensor-like object', async () => {
|
const x = [[10], [20]]; // 2x1;
|
const startNumTensors = tf.memory().numTensors;
|
await tf.browser.toPixels(x);
|
expect(tf.memory().numTensors).toEqual(startNumTensors);
|
});
|
});
|
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidG9fcGl4ZWxzX3Rlc3QuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi90ZmpzLWNvcmUvc3JjL29wcy90b19waXhlbHNfdGVzdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7O0dBZUc7QUFFSCxPQUFPLEtBQUssRUFBRSxNQUFNLFVBQVUsQ0FBQztBQUMvQixPQUFPLEVBQUMsUUFBUSxFQUFFLGlCQUFpQixFQUFDLE1BQU0saUJBQWlCLENBQUM7QUFDNUQsT0FBTyxFQUFDLG1CQUFtQixFQUFDLE1BQU0sY0FBYyxDQUFDO0FBRWpELGlCQUFpQixDQUFDLG9CQUFvQixFQUFFLFFBQVEsRUFBRSxHQUFHLEVBQUU7SUFDckQsRUFBRSxDQUFDLCtCQUErQixFQUFFLEtBQUssSUFBSSxFQUFFO1FBQzdDLE1BQU0sQ0FBQyxHQUFHLEVBQUUsQ0FBQyxRQUFRLENBQUMsQ0FBQyxHQUFHLEVBQUUsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsU0FBUyxDQUFDLENBQUM7UUFFcEQsTUFBTSxJQUFJLEdBQUcsTUFBTSxFQUFFLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUMxQyxNQUFNLFFBQVEsR0FBRyxJQUFJLGlCQUFpQixDQUFDO1lBQ3JDLElBQUksQ0FBQyxLQUFLLENBQUMsR0FBRyxHQUFHLEdBQUcsQ0FBQyxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsR0FBRyxHQUFHLEdBQUcsQ0FBQyxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsR0FBRyxHQUFHLEdBQUcsQ0FBQyxFQUFFLEdBQUc7WUFDeEUsSUFBSSxDQUFDLEtBQUssQ0FBQyxFQUFFLEdBQUcsR0FBRyxDQUFDLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxFQUFFLEdBQUcsR0FBRyxDQUFDLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxFQUFFLEdBQUcsR0FBRyxD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QWlCLENBQUMsQ0FBQyxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxHQUFHLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQztRQUMzRSxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxDQUFDO0lBQ2pDLENBQUMsQ0FBQyxDQUFDO0lBRUgsRUFBRSxDQUFDLDBDQUEwQyxFQUFFLEtBQUssSUFBSSxFQUFFO1FBQ3hELE1BQU0sQ0FBQyxHQUFHLEVBQUUsQ0FBQyxRQUFRLENBQ2pCLENBQUMsR0FBRyxFQUFFLEtBQUssRUFBRSxHQUFHLEVBQUUsRUFBRSxFQUFFLEdBQUcsRUFBRSxLQUFLLEVBQUUsR0FBRyxFQUFFLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxTQUFTLENBQUMsQ0FBQztRQUV0RSxNQUFNLElBQUksR0FBRyxNQUFNLEVBQUUsQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQzFDLE1BQU0sUUFBUSxHQUFHLElBQUksaUJBQWlCLENBQUM7WUFDckMsSUFBSSxDQUFDLEtBQUssQ0FBQyxHQUFHLEdBQUcsR0FBRyxDQUFDLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxLQUFLLEdBQUcsR0FBRyxDQUFDLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxHQUFHLEdBQUcsR0FBRyxDQUFDO1lBQ3JFLElBQUksQ0FBQyxLQUFLLENBQUMsR0FBRyxHQUFHLEdBQUcsQ0FBQyxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsR0FBRyxHQUFHLEdBQUcsQ0FBQyxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsS0FBSyxHQUFHLEdBQUcsQ0FBQztZQUNyRSxJQUFJLENBQUMsS0FBSyxDQUFDLEdBQUcsR0FBRyxHQUFHLENBQUMsRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLEVBQUUsR0FBRyxHQUFHLENBQUM7U0FDNUMsQ0FBQyxDQUFDO1FB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TUFBTSxFQUFFLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUM3QixNQUFNLENBQUMsRUFBRSxDQUFDLE1BQU0sRUFBRSxDQUFDLFVBQVUsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxlQUFlLENBQUMsQ0FBQztJQUMxRCxDQUFDLENBQUMsQ0FBQztBQUNMLENBQUMsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBAbGljZW5zZVxuICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIEluYy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAqL1xuXG5pbXBvcnQgKiBhcyB0ZiBmcm9tICcuLi9pbmRleCc7XG5pbXBvcnQge0FMTF9FTlZTLCBkZXNjcmliZVdpdGhGbGFnc30gZnJvbSAnLi4vamFzbWluZV91dGlsJztcbmltcG9ydCB7ZXhwZWN0UHJvbWlzZVRvRmFpbH0gZnJvbSAnLi4vdGVzdF91dGlsJztcblxuZGVzY3JpYmVXaXRoRmxhZ3MoJ3RvUGl4ZWxzIG5vIGNhbnZhcycsIEFMTF9FTlZTLCAoKSA9PiB7XG4gIGl0KCdkcmF3cyBhIHJhbmstMiBmbG9hdDMyIHRlbnNvcicsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCB4ID0gdGYudGVuc29yMmQoWy4xNSwgLjJdLCBbMiwgMV0sICdmbG9hdDMyJyk7XG5cbiAgICBjb25zdCBkYXRhID0gYXdhaXQgdGYuYnJvd3Nlci50b1BpeGVscyh4KTtcbiAgICBjb25zdCBleHBlY3RlZCA9IG5ldyBVaW50OENsYW1wZWRBcnJheShbXG4gICAgICBNYXRoLnJvdW5kKC4xNSAqIDI1NSksIE1hdGgucm91bmQoLjE1ICogMjU1KSwgTWF0aC5yb3VuZCguMTUgKiAyNTUpLCAyNTUsXG4gICAgICBNYXRoLnJvdW5kKC4yICogMjU1KSwgTWF0aC5yb3VuZCguMiAqIDI1NSksIE1hdGgucm91bmQoLjIgKiAyNTUpLCAyNTVcbiAgICBdKTtcbiAgICBleHBlY3QoZGF0YSkudG9FcXVhbChleHBlY3RlZCk7XG4gIH0pO1xuXG4gIGl0KCdkcmF3cyBhIHJhbmstMiBpbnQzMiB0ZW5zb3InLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgeCA9IHRmLnRlbnNvcjJkKFsxMCwgMjBdLCBbMiwgMV0sICdpbnQzMicpO1xuICAgIGNvbnN0IGRhdGEgPSBhd2FpdCB0Zi5icm93c2VyLnRvUGl4ZWxzKHgpO1xuICAgIGNvbnN0IGV4cGVjdGVkID0gbmV3IFVpbnQ4Q2xhbXBlZEFycmF5KFsxMCwgMTAsIDEwLCAyNTUsIDIwLCAyMCwgMjAsIDI1NV0pO1xuICAgIGV4cGVjdChkYXRhKS50b0VxdWFsKGV4cGVjdGVkKTtcbiAgfSk7XG5cbiAgaXQoJ2RyYXdzIGEgcmFuay0zIGZsb2F0MzIgdGVuc29yLCAxIGNoYW5uZWwnLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgeCA9IHRmLnRlbnNvcjNkKFsuMTUsIC4yXSwgWzIsIDEsIDFdLCAnZmxvYXQzMicpO1xuXG4gICAgY29uc3QgZGF0YSA9IGF3YWl0IHRmLmJyb3dzZXIudG9QaXhlbHMoeCk7XG4gICAgY29uc3QgZXhwZWN0ZWQgPSBuZXcgVWludDhDbGFtcGVkQXJyYXkoW1xuICAgICAgTWF0aC5yb3VuZCguMTUgKiAyNTUpLCBNYXRoLnJvdW5kKC4xNSAqIDI1NSksIE1hdGgucm91bmQoLjE1ICogMjU1KSwgMjU1LFxuICAgICAgTWF0aC5yb3VuZCguMiAqIDI1NSksIE1hdGgucm91bmQoLjIgKiAyNTUpLCBNYXRoLnJvdW5kKC4yICogMjU1KSwgMjU1XG4gICAgXSk7XG4gICAgZXhwZWN0KGRhdGEpLnRvRXF1YWwoZXhwZWN0ZWQpO1xuICB9KTtcblxuICBpdCgnZHJhd3MgYSByYW5rLTMgaW50MzIgdGVuc29yLCAxIGNoYW5uZWwnLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgeCA9IHRmLnRlbnNvcjNkKFsxMCwgMjBdLCBbMiwgMSwgMV0sICdpbnQzMicpO1xuXG4gICAgY29uc3QgZGF0YSA9IGF3YWl0IHRmLmJyb3dzZXIudG9QaXhlbHMoeCk7XG4gICAgY29uc3QgZXhwZWN0ZWQgPSBuZXcgVWludDhDbGFtcGVkQXJyYXkoWzEwLCAxMCwgMTAsIDI1NSwgMjAsIDIwLCAyMCwgMjU1XSk7XG4gICAgZXhwZWN0KGRhdGEpLnRvRXF1YWwoZXhwZWN0ZWQpO1xuICB9KTtcblxuICBpdCgnZHJhd3MgYSByYW5rLTMgZmxvYXQzMiB0ZW5zb3IsIDMgY2hhbm5lbCcsIGFzeW5jICgpID0+IHtcbiAgICAvLyAwLjEgYW5kIDAuMyBhcmUgY2hhbmdlZCB0byAwLjEwMDEgYW5kIDAuMzAwMSB0byBhdm9pZCBib3VuZGFyeSBjb25kaXRpb25zXG4gICAgLy8gc3VjaCBhcyBNYXRoLnJvdW5kKH4yNS41KSB3aGljaCBvbiBNb2JpbGUgU2FmYXJpIGdpdmVzIDI1IGFuZCBEZXNrdG9wXG4gICAgLy8gZ2l2ZXMgMjYuXG4gICAgY29uc3QgeCA9XG4gICAgICAgIHRmLnRlbnNvcjNkKFsuMDUsIC4xMDAxLCAuMTUsIC4yLCAuMjUsIC4zMDAxXSwgWzIsIDEsIDNdLCAnZmxvYXQzMicpO1xuXG4gICAgY29uc3QgZGF0YSA9IGF3YWl0IHRmLmJyb3dzZXIudG9QaXhlbHMoeCk7XG4gICAgY29uc3QgZXhwZWN0ZWQgPSBuZXcgVWludDhDbGFtcGVkQXJyYXkoW1xuICAgICAgTWF0aC5yb3VuZCguMDUgKiAyNTUpLCBNYXRoLnJvdW5kKC4xMDAxICogMjU1KSwgTWF0aC5yb3VuZCguMTUgKiAyNTUpLFxuICAgICAgMjU1LCBNYXRoLnJvdW5kKC4yICogMjU1KSwgTWF0aC5yb3VuZCguMjUgKiAyNTUpLCBNYXRoLnJvdW5kKC4zMDAxICogMjU1KSxcbiAgICAgIDI1NVxuICAgIF0pO1xuICAgIGV4cGVjdChkYXRhKS50b0VxdWFsKGV4cGVjdGVkKTtcbiAgfSk7XG5cbiAgaXQoJ2RyYXdzIGEgcmFuay0zIGludDMyIHRlbnNvciwgMyBjaGFubmVsJywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IHggPSB0Zi50ZW5zb3IzZChbMTAsIDIwLCAzMCwgNDAsIDUwLCA2MF0sIFsyLCAxLCAzXSwgJ2ludDMyJyk7XG5cbiAgICBjb25zdCBkYXRhID0gYXdhaXQgdGYuYnJvd3Nlci50b1BpeGVscyh4KTtcbiAgICBjb25zdCBleHBlY3RlZCA9IG5ldyBVaW50OENsYW1wZWRBcnJheShbMTAsIDIwLCAzMCwgMjU1LCA0MCwgNTAsIDYwLCAyNTVdKTtcbiAgICBleHBlY3QoZGF0YSkudG9FcXVhbChleHBlY3RlZCk7XG4gIH0pO1xuXG4gIGl0KCdkcmF3cyBhIHJhbmstMyBmbG9hdDMyIHRlbnNvciwgNCBjaGFubmVsJywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IHggPSB0Zi50ZW5zb3IzZChcbiAgICAgICAgWy4wNSwgLjEwMDEsIC4xNSwgLjIsIC4yNSwgLjMwMDEsIC4zNSwgLjRdLCBbMiwgMSwgNF0sICdmbG9hdDMyJyk7XG5cbiAgICBjb25zdCBkYXRhID0gYXdhaXQgdGYuYnJvd3Nlci50b1BpeGVscyh4KTtcbiAgICBjb25zdCBleHBlY3RlZCA9IG5ldyBVaW50OENsYW1wZWRBcnJheShbXG4gICAgICBNYXRoLnJvdW5kKC4wNSAqIDI1NSksIE1hdGgucm91bmQoLjEwMDEgKiAyNTUpLCBNYXRoLnJvdW5kKC4xNSAqIDI1NSksXG4gICAgICBNYXRoLnJvdW5kKC4yMCAqIDI1NSksIE1hdGgucm91bmQoLjI1ICogMjU1KSwgTWF0aC5yb3VuZCguMzAwMSAqIDI1NSksXG4gICAgICBNYXRoLnJvdW5kKC4zNSAqIDI1NSksIE1hdGgucm91bmQoLjQgKiAyNTUpXG4gICAgXSk7XG4gICAgZXhwZWN0KGRhdGEpLnRvRXF1YWwoZXhwZWN0ZWQpO1xuICB9KTtcblxuICBpdCgnZHJhd3MgYSByYW5rLTMgaW50MzIgdGVuc29yLCA0IGNoYW5uZWwnLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgeCA9IHRmLnRlbnNvcjNkKFsxMCwgMjAsIDMwLCA0MCwgNTAsIDYwLCA3MCwgODBdLCBbMiwgMSwgNF0sICdpbnQzMicpO1xuXG4gICAgY29uc3QgZGF0YSA9IGF3YWl0IHRmLmJyb3dzZXIudG9QaXhlbHMoeCk7XG4gICAgY29uc3QgZXhwZWN0ZWQgPSBuZXcgVWludDhDbGFtcGVkQXJyYXkoWzEwLCAyMCwgMzAsIDQwLCA1MCwgNjAsIDcwLCA4MF0pO1xuICAgIGV4cGVjdChkYXRhKS50b0VxdWFsKGV4cGVjdGVkKTtcbiAgfSk7XG5cbiAgaXQoJ3Rocm93cyBmb3Igc2NhbGFycycsIGRvbmUgPT4ge1xuICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTpuby1hbnlcbiAgICBleHBlY3RQcm9taXNlVG9GYWlsKCgpID0+IHRmLmJyb3dzZXIudG9QaXhlbHModGYuc2NhbGFyKDEpIGFzIGFueSksIGRvbmUpO1xuICB9KTtcblxuICBpdCgndGhyb3dzIGZvciByYW5rLTEgdGVuc29ycycsIGRvbmUgPT4ge1xuICAgIGV4cGVjdFByb21pc2VUb0ZhaWwoXG4gICAgICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTpuby1hbnlcbiAgICAgICAgKCkgPT4gdGYuYnJvd3Nlci50b1BpeGVscyh0Zi50ZW5zb3IxZChbMV0pIGFzIGFueSksIGRvbmUpO1xuICB9KTtcbiAgaXQoJ3Rocm93cyBmb3IgcmFuay00IHRlbnNvcnMnLCBkb25lID0+IHtcbiAgICBleHBlY3RQcm9taXNlVG9GYWlsKFxuICAgICAgICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6bm8tYW55XG4gICAgICAgICgpID0+IHRmLmJyb3dzZXIudG9QaXhlbHModGYudGVuc29yNGQoWzFdLCBbMSwgMSwgMSwgMV0pIGFzIGFueSksIGRvbmUpO1xuICB9KTtcbiAgaXQoJ3Rocm93cyBmb3IgYm9vbCBkdHlwZScsIGRvbmUgPT4ge1xuICAgIGV4cGVjdFByb21pc2VUb0ZhaWwoXG4gICAgICAgICgpID0+IHRmLmJyb3dzZXIudG9QaXhlbHModGYudGVuc29yMmQoWzFdLCBbMSwgMV0sICdib29sJykpLCBkb25lKTtcbiAgfSk7XG4gIGl0KCd0aHJvd3MgZm9yIHJhbmstMyBkZXB0aCA9IDInLCBkb25lID0+IHtcbiAgICBleHBlY3RQcm9taXNlVG9GYWlsKFxuICAgICAgICAoKSA9PiB0Zi5icm93c2VyLnRvUGl4ZWxzKHRmLnRlbnNvcjNkKFsxLCAyXSwgWzEsIDEsIDJdKSksIGRvbmUpO1xuICB9KTtcbiAgaXQoJ3Rocm93cyBmb3IgcmFuay0zIGRlcHRoID0gNScsIGRvbmUgPT4ge1xuICAgIGV4cGVjdFByb21pc2VUb0ZhaWwoXG4gICAgICAgICgpID0+IHRmLmJyb3dzZXIudG9QaXhlbHModGYudGVuc29yM2QoWzEsIDIsIDMsIDQsIDVdLCBbMSwgMSwgNV0pKSxcbiAgICAgICAgZG9uZSk7XG4gIH0pO1xuICBpdCgndGhyb3dzIGZvciBmbG9hdDMyIHRlbnNvciB3aXRoIHZhbHVlcyBub3QgaW4gWzAgLSAxXScsIGRvbmUgPT4ge1xuICAgIGV4cGVjdFByb21pc2VUb0ZhaWwoXG4gICAgICAgICgpID0+IHRmLmJyb3dzZXIudG9QaXhlbHModGYudGVuc29yMmQoWy0xLCAuNV0sIFsxLCAyXSkpLCBkb25lKTtcbiAgfSk7XG4gIGl0KCd0aHJvd3MgZm9yIGludDMyIHRlbnNvciB3aXRoIHZhbHVlcyBub3QgaW4gWzAgLSAyNTVdJywgZG9uZSA9PiB7XG4gICAgZXhwZWN0UHJvbWlzZVRvRmFpbChcbiAgICAgICAgKCkgPT4gdGYuYnJvd3Nlci50b1BpeGVscyh0Zi50ZW5zb3IyZChbLTEsIDEwMF0sIFsxLCAyXSwgJ2ludDMyJykpLFxuICAgICAgICBkb25lKTtcbiAgfSk7XG4gIGl0KCd0aHJvd3Mgd2hlbiBwYXNzZWQgYSBub24tdGVuc29yJywgZG9uZSA9PiB7XG4gICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOm5vLWFueVxuICAgIGV4cGVjdFByb21pc2VUb0ZhaWwoKCkgPT4gdGYuYnJvd3Nlci50b1BpeGVscyh7fSBhcyBhbnkpLCBkb25lKTtcbiAgfSk7XG5cbiAgaXQoJ2FjY2VwdHMgYSB0ZW5zb3ItbGlrZSBvYmplY3QnLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgeCA9IFtbMTBdLCBbMjBdXTsgIC8vIDJ4MTtcbiAgICBjb25zdCBkYXRhID0gYXdhaXQgdGYuYnJvd3Nlci50b1BpeGVscyh4KTtcblxuICAgIGNvbnN0IGV4cGVjdGVkID0gbmV3IFVpbnQ4Q2xhbXBlZEFycmF5KFsxMCwgMTAsIDEwLCAyNTUsIDIwLCAyMCwgMjAsIDI1NV0pO1xuICAgIGV4cGVjdChkYXRhKS50b0VxdWFsKGV4cGVjdGVkKTtcbiAgfSk7XG5cbiAgaXQoJ2RvZXMgbm90IGxlYWsgbWVtb3J5JywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IHggPSB0Zi50ZW5zb3IyZChbWy4xXSwgWy4yXV0sIFsyLCAxXSk7XG4gICAgY29uc3Qgc3RhcnROdW1UZW5zb3JzID0gdGYubWVtb3J5KCkubnVtVGVuc29ycztcbiAgICBhd2FpdCB0Zi5icm93c2VyLnRvUGl4ZWxzKHgpO1xuICAgIGV4cGVjdCh0Zi5tZW1vcnkoKS5udW1UZW5zb3JzKS50b0VxdWFsKHN0YXJ0TnVtVGVuc29ycyk7XG4gIH0pO1xuXG4gIGl0KCdkb2VzIG5vdCBsZWFrIG1lbW9yeSBnaXZlbiBhIHRlbnNvci1saWtlIG9iamVjdCcsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCB4ID0gW1sxMF0sIFsyMF1dOyAgLy8gMngxO1xuICAgIGNvbnN0IHN0YXJ0TnVtVGVuc29ycyA9IHRmLm1lbW9yeSgpLm51bVRlbnNvcnM7XG4gICAgYXdhaXQgdGYuYnJvd3Nlci50b1BpeGVscyh4KTtcbiAgICBleHBlY3QodGYubWVtb3J5KCkubnVtVGVuc29ycykudG9FcXVhbChzdGFydE51bVRlbnNvcnMpO1xuICB9KTtcbn0pO1xuIl19
|