/**
|
* @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 { expectArraysClose, expectArraysEqual } from '../test_util';
|
import * as reduce_util from './reduce_util';
|
describeWithFlags('argmin', ALL_ENVS, () => {
|
it('Tensor1D', async () => {
|
const a = tf.tensor1d([1, 0, 3, 2]);
|
const result = tf.argMin(a);
|
expectArraysEqual(await result.data(), 1);
|
});
|
it('one value', async () => {
|
const a = tf.tensor1d([10]);
|
const result = tf.argMin(a);
|
expectArraysEqual(await result.data(), 0);
|
});
|
it('N > than parallelization threshold', async () => {
|
const n = reduce_util.PARALLELIZE_THRESHOLD * 2;
|
const values = new Float32Array(n);
|
for (let i = 0; i < n; i++) {
|
values[i] = n - i;
|
}
|
const a = tf.tensor1d(values);
|
const result = tf.argMin(a);
|
expect(result.dtype).toBe('int32');
|
expectArraysEqual(await result.data(), n - 1);
|
});
|
it('4D, N > than parallelization threshold', async () => {
|
const n = reduce_util.PARALLELIZE_THRESHOLD * 2;
|
const values = new Float32Array(n);
|
for (let i = 0; i < n; i++) {
|
values[i] = n - i;
|
}
|
const a = tf.tensor4d(values, [1, 1, 1, n]);
|
const result = tf.argMin(a, -1);
|
expect(result.dtype).toBe('int32');
|
expectArraysEqual(await result.data(), n - 1);
|
});
|
it('min index corresponds to start of a non-initial window', async () => {
|
const n = reduce_util.PARALLELIZE_THRESHOLD * 2;
|
const windowSize = reduce_util.computeOptimalWindowSize(n);
|
const values = new Float32Array(n);
|
const index = windowSize * 2;
|
values[index] = -1;
|
const a = tf.tensor1d(values);
|
const result = tf.argMin(a);
|
expect(result.dtype).toBe('int32');
|
expectArraysEqual(await result.data(), index);
|
});
|
it('ignores NaNs', async () => {
|
const a = tf.tensor1d([5, 0, NaN, -1, 3]);
|
const res = tf.argMin(a);
|
expectArraysEqual(await res.data(), 3);
|
});
|
it('3D, ignores NaNs', async () => {
|
const a = tf.tensor3d([5, 0, NaN, -1, 3], [1, 1, 5]);
|
const res = tf.argMin(a, -1);
|
expectArraysEqual(await res.data(), 3);
|
});
|
it('2D, no axis specified', async () => {
|
const a = tf.tensor2d([3, -1, 0, 100, -7, 2], [2, 3]);
|
expectArraysEqual(await tf.argMin(a).data(), [0, 1, 0]);
|
});
|
it('2D, axis=0', async () => {
|
const a = tf.tensor2d([3, -1, 0, 100, -7, 2], [2, 3]);
|
const r = tf.argMin(a, 0);
|
expect(r.shape).toEqual([3]);
|
expect(r.dtype).toBe('int32');
|
expectArraysEqual(await r.data(), [0, 1, 0]);
|
});
|
it('2D, axis=1', async () => {
|
const a = tf.tensor2d([3, 2, 5, 100, -7, -8], [2, 3]);
|
const r = tf.argMin(a, 1);
|
expectArraysEqual(await r.data(), [1, 2]);
|
});
|
it('2D, axis = -1', async () => {
|
const a = tf.tensor2d([3, 2, 5, 100, -7, -8], [2, 3]);
|
const r = tf.argMin(a, -1);
|
expectArraysEqual(await r.data(), [1, 2]);
|
});
|
it('throws when passed a non-tensor', () => {
|
expect(() => tf.argMin({}))
|
.toThrowError(/Argument 'x' passed to 'argMin' must be a Tensor/);
|
});
|
it('accepts a tensor-like object', async () => {
|
const result = tf.argMin([1, 0, 3, 2]);
|
expectArraysEqual(await result.data(), 1);
|
});
|
it('accepts tensor with bool values', async () => {
|
const t = tf.tensor1d([0, 1], 'bool');
|
const result = tf.argMin(t);
|
expect(result.dtype).toBe('int32');
|
expectArraysEqual(await result.data(), 0);
|
});
|
it('has gradient', async () => {
|
const a = tf.tensor2d([3, 2, 5, 100, -7, 2], [2, 3]);
|
const dy = tf.ones([3], 'float32');
|
const da = tf.grad((x) => tf.argMin(x))(a, dy);
|
expect(da.dtype).toBe('float32');
|
expect(da.shape).toEqual([2, 3]);
|
expectArraysClose(await da.data(), [0, 0, 0, 0, 0, 0]);
|
});
|
it('gradient with clones', async () => {
|
const a = tf.tensor2d([3, 2, 5, 100, -7, 2], [2, 3]);
|
const dy = tf.ones([3], 'float32');
|
const da = tf.grad((x) => tf.argMin(x.clone()).clone())(a, dy);
|
expect(da.dtype).toBe('float32');
|
expect(da.shape).toEqual([2, 3]);
|
expectArraysClose(await da.data(), [0, 0, 0, 0, 0, 0]);
|
});
|
it('throws error for string tensor', () => {
|
expect(() => tf.argMin(['a']))
|
.toThrowError(/Argument 'x' passed to 'argMin' must be numeric tensor/);
|
});
|
});
|
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXJnX21pbl90ZXN0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vdGZqcy1jb3JlL3NyYy9vcHMvYXJnX21pbl90ZXN0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7Ozs7Ozs7Ozs7R0FlRztBQUVILE9BQU8sS0FBSyxFQUFFLE1BQU0sVUFBVSxDQUFDO0FBQy9CLE9BQU8sRUFBQyxRQUFRLEVBQUUsaUJBQWlCLEVBQUMsTUFBTSxpQkFBaUIsQ0FBQztBQUM1RCxPQUFPLEVBQUMsaUJBQWlCLEVBQUUsaUJBQWlCLEVBQUMsTUFBTSxjQUFjLENBQUM7QUFFbEUsT0FBTyxLQUFLLFdBQVcsTUFBTSxlQUFlLENBQUM7QUFFN0MsaUJBQWlCLENBQUMsUUFBUSxFQUFFLFFBQVEsRUFBRSxHQUFHLEVBQUU7SUFDekMsRUFBRSxDQUFDLFVBQVUsRUFBRSxLQUFLLElBQUksRUFBRTtRQUN4QixNQUFNLENBQUMsR0FBRyxFQUFFLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUNwQyxNQUFNLE1BQU0sR0FBRyxFQUFFLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQzVCLGlCQUFpQixDQUFDLE1BQU0sTUFBTSxDQUFDLElBQUksRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDO0lBQzVDLENBQUMsQ0FBQyxDQUFDO0lBRUgsRUFBRSxDQUFDLFdBQVcsRUFBRSxLQUFLLElBQUksRUFBRTtRQUN6QixNQUFNLENBQUMsR0FBRyxFQUFFLENBQUMsUUFBUSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztRQUM1QixNQUFNLE1BQU0sR0FBRyxFQUFFLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQzVCLGlCQUFpQixDQUFDLE1BQU0sTUFBTSxDQUFDLElBQUksRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDO0lB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QVEsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsR0FBRyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDMUMsTUFBTSxHQUFHLEdBQUcsRUFBRSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUN6QixpQkFBaUIsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQztJQUN6QyxDQUFDLENBQUMsQ0FBQztJQUVILEVBQUUsQ0FBQyxrQkFBa0IsRUFBRSxLQUFLLElBQUksRUFBRTtRQUNoQyxNQUFNLENBQUMsR0FBRyxFQUFFLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxHQUFHLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDckQsTUFBTSxHQUFHLEdBQUcsRUFBRSxDQUFDLE1BQU0sQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUM3QixpQkFBaUIsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQztJQUN6QyxDQUFDLENBQUMsQ0FBQztJQUVILEVBQUUsQ0FBQyx1QkFBdUIsRUFBRSxLQUFLLElBQUksRUFBRTtRQUNyQyxNQUFNLENBQUMsR0FBRyxFQUFFLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxHQUFHLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUN0RCxpQkFBaUIsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDMUQsQ0FBQyxDQUFDLENBQUM7SUFFSCxFQUFFLENBQUMsWUFBWSxFQUFFLEtBQUssSUFBSSxFQUFFO1FBQzFCLE1BQU0sQ0FBQyxHQUFHLEVBQUUsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLEdBQUcsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3RELE1BQU0sQ0FBQyxHQUFHLEVBQUUsQ0FBQyxNQUFNLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBRTFCLE1BQU0sQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUM3QixNQUFNLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUM5QixpQkFBaUIsQ0FBQyxNQUFNLENBQUMsQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUMvQyxDQUFDLENBQUMsQ0FBQztJQUVILEVBQUUsQ0FBQyxZQUFZLEVBQUUsS0FBSyxJQUFJLEVBQUU7UUFDMUIsTUFBTSxDQUFDLEdBQUcsRUFBRSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLEdBQUcsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDdEQsTUFBTSxDQUFDLEdBQUcsRUFBRSxDQUFDLE1BQU0sQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7UUFDMUIsaUJBQWlCLENBQUMsTUFBTSxDQUFDLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUM1QyxDQUFDLENBQUMsQ0FBQztJQUVILEVBQUUsQ0FBQyxlQUFlLEVBQUUsS0FBSyxJQUFJLEVBQUU7UUFDN0IsTUFBTSxDQUFDLEdBQUcsRUFBRSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLEdBQUcsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDdEQsTUFBTSxDQUFDLEdBQUcsRUFBRSxDQUFDLE1BQU0sQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUMzQixpQkFBaUIsQ0FBQyxNQUFNLENBQUMsQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQzVDLENBQUMsQ0FBQyxDQUFDO0lBRUgsRUFBRSxDQUFDLGlDQUFpQyxFQUFFLEdBQUcsRUFBRTtRQUN6QyxNQUFNLENBQUMsR0FBRyxFQUFFLENBQUMsRUFBRSxDQUFDLE1BQU0sQ0FBQyxFQUFlLENBQUMsQ0FBQzthQUNuQyxZQUFZLENBQUMsa0RBQWtELENBQUMsQ0FBQztJQUN4RSxDQUFDLENBQUMsQ0FBQztJQUVILEVBQUUsQ0FBQyw4QkFBOEIsRUFBRSxLQUFLLElBQUksRUFBRTtRQUM1QyxNQUFNLE1BQU0sR0FBRyxFQUFFLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUN2QyxpQkFBaUIsQ0FBQyxNQUFNLE1BQU0sQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQztJQUM1QyxDQUFDLENBQUMsQ0FBQztJQUVILEVBQUUsQ0FBQyxpQ0FBaUMsRUFBRSxLQUFLLElBQUksRUFBRTtRQUMvQyxNQUFNLENBQUMsR0FBRyxFQUFFLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLE1BQU0sQ0FBQyxDQUFDO1FBQ3RDLE1BQU0sTUFBTSxHQUFHLEVBQUUsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDNUIsTUFBTSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUM7UUFDbkMsaUJBQWlCLENBQUMsTUFBTSxNQUFNLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFDNUMsQ0FBQyxDQUFDLENBQUM7SUFFSCxFQUFFLENBQUMsY0FBYyxFQUFFLEtBQUssSUFBSSxFQUFFO1FBQzVCLE1BQU0sQ0FBQyxHQUFHLEVBQUUsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxHQUFHLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUNyRCxNQUFNLEVBQUUsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsU0FBUyxDQUFDLENBQUM7UUFDbkMsTUFBTSxFQUFFLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQWMsRUFBRSxFQUFFLENBQUMsRUFBRSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQztRQUU1RCxNQUFNLENBQUMsRUFBRSxDQUFDLEtBQUssQ0FBQyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUNqQyxNQUFNLENBQUMsRUFBRSxDQUFDLEtBQUssQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ2pDLGlCQUFpQixDQUFDLE1BQU0sRUFBRSxDQUFDLElBQUksRUFBRSxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ3pELENBQUMsQ0FBQyxDQUFDO0lBRUgsRUFBRSxDQUFDLHNCQUFzQixFQUFFLEtBQUssSUFBSSxFQUFFO1FBQ3BDLE1BQU0sQ0FBQyxHQUFHLEVBQUUsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxHQUFHLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUNyRCxNQUFNLEVBQUUsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsU0FBUyxDQUFDLENBQUM7UUFDbkMsTUFBTSxFQUFFLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQWMsRUFBRSxFQUFFLENBQUMsRUFBRSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsS0FBSyxFQUFFLENBQUMsQ0FBQyxLQUFLLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQztRQUU1RSxNQUFNLENBQUMsRUFBRSxDQUFDLEtBQUssQ0FBQyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUNqQyxNQUFNLENBQUMsRUFBRSxDQUFDLEtBQUssQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ2pDLGlCQUFpQixDQUFDLE1BQU0sRUFBRSxDQUFDLElBQUksRUFBRSxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ3pELENBQUMsQ0FBQyxDQUFDO0lBRUgsRUFBRSxDQUFDLGdDQUFnQyxFQUFFLEdBQUcsRUFBRTtRQUN4QyxNQUFNLENBQUMsR0FBRyxFQUFFLENBQUMsRUFBRSxDQUFDLE1BQU0sQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7YUFDekIsWUFBWSxDQUFDLHdEQUF3RCxDQUFDLENBQUM7SUFDOUUsQ0FBQyxDQUFDLENBQUM7QUFDTCxDQUFDLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQGxpY2Vuc2VcbiAqIENvcHlyaWdodCAyMDIwIEdvb2dsZSBJbmMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gKi9cblxuaW1wb3J0ICogYXMgdGYgZnJvbSAnLi4vaW5kZXgnO1xuaW1wb3J0IHtBTExfRU5WUywgZGVzY3JpYmVXaXRoRmxhZ3N9IGZyb20gJy4uL2phc21pbmVfdXRpbCc7XG5pbXBvcnQge2V4cGVjdEFycmF5c0Nsb3NlLCBleHBlY3RBcnJheXNFcXVhbH0gZnJvbSAnLi4vdGVzdF91dGlsJztcblxuaW1wb3J0ICogYXMgcmVkdWNlX3V0aWwgZnJvbSAnLi9yZWR1Y2VfdXRpbCc7XG5cbmRlc2NyaWJlV2l0aEZsYWdzKCdhcmdtaW4nLCBBTExfRU5WUywgKCkgPT4ge1xuICBpdCgnVGVuc29yMUQnLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgYSA9IHRmLnRlbnNvcjFkKFsxLCAwLCAzLCAyXSk7XG4gICAgY29uc3QgcmVzdWx0ID0gdGYuYXJnTWluKGEpO1xuICAgIGV4cGVjdEFycmF5c0VxdWFsKGF3YWl0IHJlc3VsdC5kYXRhKCksIDEpO1xuICB9KTtcblxuICBpdCgnb25lIHZhbHVlJywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IGEgPSB0Zi50ZW5zb3IxZChbMTBdKTtcbiAgICBjb25zdCByZXN1bHQgPSB0Zi5hcmdNaW4oYSk7XG4gICAgZXhwZWN0QXJyYXlzRXF1YWwoYXdhaXQgcmVzdWx0LmRhdGEoKSwgMCk7XG4gIH0pO1xuXG4gIGl0KCdOID4gdGhhbiBwYXJhbGxlbGl6YXRpb24gdGhyZXNob2xkJywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IG4gPSByZWR1Y2VfdXRpbC5QQVJBTExFTElaRV9USFJFU0hPTEQgKiAyO1xuICAgIGNvbnN0IHZhbHVlcyA9IG5ldyBGbG9hdDMyQXJyYXkobik7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBuOyBpKyspIHtcbiAgICAgIHZhbHVlc1tpXSA9IG4gLSBpO1xuICAgIH1cbiAgICBjb25zdCBhID0gdGYudGVuc29yMWQodmFsdWVzKTtcbiAgICBjb25zdCByZXN1bHQgPSB0Zi5hcmdNaW4oYSk7XG4gICAgZXhwZWN0KHJlc3VsdC5kdHlwZSkudG9CZSgnaW50MzInKTtcbiAgICBleHBlY3RBcnJheXNFcXVhbChhd2FpdCByZXN1bHQuZGF0YSgpLCBuIC0gMSk7XG4gIH0pO1xuXG4gIGl0KCc0RCwgTiA+IHRoYW4gcGFyYWxsZWxpemF0aW9uIHRocmVzaG9sZCcsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBuID0gcmVkdWNlX3V0aWwuUEFSQUxMRUxJWkVfVEhSRVNIT0xEICogMjtcbiAgICBjb25zdCB2YWx1ZXMgPSBuZXcgRmxvYXQzMkFycmF5KG4pO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbjsgaSsrKSB7XG4gICAgICB2YWx1ZXNbaV0gPSBuIC0gaTtcbiAgICB9XG4gICAgY29uc3QgYSA9IHRmLnRlbnNvcjRkKHZhbHVlcywgWzEsIDEsIDEsIG5dKTtcbiAgICBjb25zdCByZXN1bHQgPSB0Zi5hcmdNaW4oYSwgLTEpO1xuICAgIGV4cGVjdChyZXN1bHQuZHR5cGUpLnRvQmUoJ2ludDMyJyk7XG4gICAgZXhwZWN0QXJyYXlzRXF1YWwoYXdhaXQgcmVzdWx0LmRhdGEoKSwgbiAtIDEpO1xuICB9KTtcblxuICBpdCgnbWluIGluZGV4IGNvcnJlc3BvbmRzIHRvIHN0YXJ0IG9mIGEgbm9uLWluaXRpYWwgd2luZG93JywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IG4gPSByZWR1Y2VfdXRpbC5QQVJBTExFTElaRV9USFJFU0hPTEQgKiAyO1xuICAgIGNvbnN0IHdpbmRvd1NpemUgPSByZWR1Y2VfdXRpbC5jb21wdXRlT3B0aW1hbFdpbmRvd1NpemUobik7XG4gICAgY29uc3QgdmFsdWVzID0gbmV3IEZsb2F0MzJBcnJheShuKTtcbiAgICBjb25zdCBpbmRleCA9IHdpbmRvd1NpemUgKiAyO1xuICAgIHZhbHVlc1tpbmRleF0gPSAtMTtcbiAgICBjb25zdCBhID0gdGYudGVuc29yMWQodmFsdWVzKTtcbiAgICBjb25zdCByZXN1bHQgPSB0Zi5hcmdNaW4oYSk7XG4gICAgZXhwZWN0KHJlc3VsdC5kdHlwZSkudG9CZSgnaW50MzInKTtcbiAgICBleHBlY3RBcnJheXNFcXVhbChhd2FpdCByZXN1bHQuZGF0YSgpLCBpbmRleCk7XG4gIH0pO1xuXG4gIGl0KCdpZ25vcmVzIE5hTnMnLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgYSA9IHRmLnRlbnNvcjFkKFs1LCAwLCBOYU4sIC0xLCAzXSk7XG4gICAgY29uc3QgcmVzID0gdGYuYXJnTWluKGEpO1xuICAgIGV4cGVjdEFycmF5c0VxdWFsKGF3YWl0IHJlcy5kYXRhKCksIDMpO1xuICB9KTtcblxuICBpdCgnM0QsIGlnbm9yZXMgTmFOcycsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBhID0gdGYudGVuc29yM2QoWzUsIDAsIE5hTiwgLTEsIDNdLCBbMSwgMSwgNV0pO1xuICAgIGNvbnN0IHJlcyA9IHRmLmFyZ01pbihhLCAtMSk7XG4gICAgZXhwZWN0QXJyYXlzRXF1YWwoYXdhaXQgcmVzLmRhdGEoKSwgMyk7XG4gIH0pO1xuXG4gIGl0KCcyRCwgbm8gYXhpcyBzcGVjaWZpZWQnLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgYSA9IHRmLnRlbnNvcjJkKFszLCAtMSwgMCwgMTAwLCAtNywgMl0sIFsyLCAzXSk7XG4gICAgZXhwZWN0QXJyYXlzRXF1YWwoYXdhaXQgdGYuYXJnTWluKGEpLmRhdGEoKSwgWzAsIDEsIDBdKTtcbiAgfSk7XG5cbiAgaXQoJzJELCBheGlzPTAnLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgYSA9IHRmLnRlbnNvcjJkKFszLCAtMSwgMCwgMTAwLCAtNywgMl0sIFsyLCAzXSk7XG4gICAgY29uc3QgciA9IHRmLmFyZ01pbihhLCAwKTtcblxuICAgIGV4cGVjdChyLnNoYXBlKS50b0VxdWFsKFszXSk7XG4gICAgZXhwZWN0KHIuZHR5cGUpLnRvQmUoJ2ludDMyJyk7XG4gICAgZXhwZWN0QXJyYXlzRXF1YWwoYXdhaXQgci5kYXRhKCksIFswLCAxLCAwXSk7XG4gIH0pO1xuXG4gIGl0KCcyRCwgYXhpcz0xJywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IGEgPSB0Zi50ZW5zb3IyZChbMywgMiwgNSwgMTAwLCAtNywgLThdLCBbMiwgM10pO1xuICAgIGNvbnN0IHIgPSB0Zi5hcmdNaW4oYSwgMSk7XG4gICAgZXhwZWN0QXJyYXlzRXF1YWwoYXdhaXQgci5kYXRhKCksIFsxLCAyXSk7XG4gIH0pO1xuXG4gIGl0KCcyRCwgYXhpcyA9IC0xJywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IGEgPSB0Zi50ZW5zb3IyZChbMywgMiwgNSwgMTAwLCAtNywgLThdLCBbMiwgM10pO1xuICAgIGNvbnN0IHIgPSB0Zi5hcmdNaW4oYSwgLTEpO1xuICAgIGV4cGVjdEFycmF5c0VxdWFsKGF3YWl0IHIuZGF0YSgpLCBbMSwgMl0pO1xuICB9KTtcblxuICBpdCgndGhyb3dzIHdoZW4gcGFzc2VkIGEgbm9uLXRlbnNvcicsICgpID0+IHtcbiAgICBleHBlY3QoKCkgPT4gdGYuYXJnTWluKHt9IGFzIHRmLlRlbnNvcikpXG4gICAgICAgIC50b1Rocm93RXJyb3IoL0FyZ3VtZW50ICd4JyBwYXNzZWQgdG8gJ2FyZ01pbicgbXVzdCBiZSBhIFRlbnNvci8pO1xuICB9KTtcblxuICBpdCgnYWNjZXB0cyBhIHRlbnNvci1saWtlIG9iamVjdCcsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCByZXN1bHQgPSB0Zi5hcmdNaW4oWzEsIDAsIDMsIDJdKTtcbiAgICBleHBlY3RBcnJheXNFcXVhbChhd2FpdCByZXN1bHQuZGF0YSgpLCAxKTtcbiAgfSk7XG5cbiAgaXQoJ2FjY2VwdHMgdGVuc29yIHdpdGggYm9vbCB2YWx1ZXMnLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgdCA9IHRmLnRlbnNvcjFkKFswLCAxXSwgJ2Jvb2wnKTtcbiAgICBjb25zdCByZXN1bHQgPSB0Zi5hcmdNaW4odCk7XG4gICAgZXhwZWN0KHJlc3VsdC5kdHlwZSkudG9CZSgnaW50MzInKTtcbiAgICBleHBlY3RBcnJheXNFcXVhbChhd2FpdCByZXN1bHQuZGF0YSgpLCAwKTtcbiAgfSk7XG5cbiAgaXQoJ2hhcyBncmFkaWVudCcsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBhID0gdGYudGVuc29yMmQoWzMsIDIsIDUsIDEwMCwgLTcsIDJdLCBbMiwgM10pO1xuICAgIGNvbnN0IGR5ID0gdGYub25lcyhbM10sICdmbG9hdDMyJyk7XG4gICAgY29uc3QgZGEgPSB0Zi5ncmFkKCh4OiB0Zi5UZW5zb3IyRCkgPT4gdGYuYXJnTWluKHgpKShhLCBkeSk7XG5cbiAgICBleHBlY3QoZGEuZHR5cGUpLnRvQmUoJ2Zsb2F0MzInKTtcbiAgICBleHBlY3QoZGEuc2hhcGUpLnRvRXF1YWwoWzIsIDNdKTtcbiAgICBleHBlY3RBcnJheXNDbG9zZShhd2FpdCBkYS5kYXRhKCksIFswLCAwLCAwLCAwLCAwLCAwXSk7XG4gIH0pO1xuXG4gIGl0KCdncmFkaWVudCB3aXRoIGNsb25lcycsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBhID0gdGYudGVuc29yMmQoWzMsIDIsIDUsIDEwMCwgLTcsIDJdLCBbMiwgM10pO1xuICAgIGNvbnN0IGR5ID0gdGYub25lcyhbM10sICdmbG9hdDMyJyk7XG4gICAgY29uc3QgZGEgPSB0Zi5ncmFkKCh4OiB0Zi5UZW5zb3IyRCkgPT4gdGYuYXJnTWluKHguY2xvbmUoKSkuY2xvbmUoKSkoYSwgZHkpO1xuXG4gICAgZXhwZWN0KGRhLmR0eXBlKS50b0JlKCdmbG9hdDMyJyk7XG4gICAgZXhwZWN0KGRhLnNoYXBlKS50b0VxdWFsKFsyLCAzXSk7XG4gICAgZXhwZWN0QXJyYXlzQ2xvc2UoYXdhaXQgZGEuZGF0YSgpLCBbMCwgMCwgMCwgMCwgMCwgMF0pO1xuICB9KTtcblxuICBpdCgndGhyb3dzIGVycm9yIGZvciBzdHJpbmcgdGVuc29yJywgKCkgPT4ge1xuICAgIGV4cGVjdCgoKSA9PiB0Zi5hcmdNaW4oWydhJ10pKVxuICAgICAgICAudG9UaHJvd0Vycm9yKC9Bcmd1bWVudCAneCcgcGFzc2VkIHRvICdhcmdNaW4nIG11c3QgYmUgbnVtZXJpYyB0ZW5zb3IvKTtcbiAgfSk7XG59KTtcbiJdfQ==
|