/** * @license * Copyright 2018 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 tf from '../index'; import { ALL_ENVS, describeWithFlags } from '../jasmine_util'; import { expectArraysClose } from '../test_util'; import { scalar } from './scalar'; import { tensor1d } from './tensor1d'; import { tensor2d } from './tensor2d'; import { tensor3d } from './tensor3d'; describeWithFlags('topk', ALL_ENVS, () => { beforeAll(() => { // Ensure WebGL environment uses GPU if (tf.getBackend() === 'webgl') { tf.env().set('TOPK_LAST_DIM_CPU_HANDOFF_SIZE_THRESHOLD', 0); tf.env().set('TOPK_K_CPU_HANDOFF_THRESHOLD', 1024); } }); it('1d array with k = 0', async () => { const a = tensor1d([20, 10, 40, 30]); const { values, indices } = tf.topk(a, 0); expect(values.shape).toEqual([0]); expect(indices.shape).toEqual([0]); expect(values.dtype).toBe('float32'); expect(indices.dtype).toBe('int32'); expectArraysClose(await values.data(), []); expectArraysClose(await indices.data(), []); }); it('1d array with length 1', async () => { const a = tensor1d([20]); const { values, indices } = tf.topk(a, 1); expect(values.shape).toEqual([1]); expect(indices.shape).toEqual([1]); expect(values.dtype).toBe('float32'); expect(indices.dtype).toBe('int32'); expectArraysClose(await values.data(), [20]); expectArraysClose(await indices.data(), [0]); }); it('1d array with default k', async () => { const a = tensor1d([20, 10, 40, 30]); const { values, indices } = tf.topk(a); expect(values.shape).toEqual([1]); expect(indices.shape).toEqual([1]); expect(values.dtype).toBe('float32'); expect(indices.dtype).toBe('int32'); expectArraysClose(await values.data(), [40]); expectArraysClose(await indices.data(), [2]); }); it('1d array with default k from tensor.topk', async () => { const a = tensor1d([20, 10, 40, 30]); const { values, indices } = a.topk(); expect(values.shape).toEqual([1]); expect(indices.shape).toEqual([1]); expect(values.dtype).toBe('float32'); expect(indices.dtype).toBe('int32'); expectArraysClose(await values.data(), [40]); expectArraysClose(await indices.data(), [2]); }); it('2d array with default k', async () => { const a = tensor2d([[10, 50], [40, 30]]); const { values, indices } = tf.topk(a); expect(values.shape).toEqual([2, 1]); expect(indices.shape).toEqual([2, 1]); expect(values.dtype).toBe('float32'); expect(indices.dtype).toBe('int32'); expectArraysClose(await values.data(), [50, 40]); expectArraysClose(await indices.data(), [1, 0]); }); it('2d array with k=2', async () => { const a = tensor2d([ [1, 5, 2], [4, 3, 6], [3, 2, 1], [1, 2, 3], ]); const k = 2; const { values, indices } = tf.topk(a, k); expect(values.shape).toEqual([4, 2]); expect(indices.shape).toEqual([4, 2]); expect(values.dtype).toBe('float32'); expect(indices.dtype).toBe('int32'); expectArraysClose(await values.data(), [5, 2, 6, 4, 3, 2, 3, 2]); expectArraysClose(await indices.data(), [1, 2, 2, 0, 0, 1, 2, 1]); }); it('2d array with k=2 from tensor.topk', async () => { const a = tensor2d([ [1, 5, 2], [4, 3, 6], [3, 2, 1], [1, 2, 3], ]); const k = 2; const { values, indices } = a.topk(k); expect(values.shape).toEqual([4, 2]); expect(indices.shape).toEqual([4, 2]); expect(values.dtype).toBe('float32'); expect(indices.dtype).toBe('int32'); expectArraysClose(await values.data(), [5, 2, 6, 4, 3, 2, 3, 2]); expectArraysClose(await indices.data(), [1, 2, 2, 0, 0, 1, 2, 1]); }); it('3d array with k=3', async () => { const a = tensor3d([ [[1, 5, 2], [4, 3, 6]], [[3, 2, 1], [1, 2, 3]], ]); // 2x2x3. const k = 3; const { values, indices } = tf.topk(a, k); expect(values.shape).toEqual([2, 2, 3]); expect(indices.shape).toEqual([2, 2, 3]); expect(values.dtype).toBe('float32'); expect(indices.dtype).toBe('int32'); expectArraysClose(await values.data(), [5, 2, 1, 6, 4, 3, 3, 2, 1, 3, 2, 1]); expectArraysClose(await indices.data(), [1, 2, 0, 2, 0, 1, 0, 1, 2, 2, 1, 0]); }); it('topk(int32) propagates int32 dtype', async () => { const a = tensor1d([2, 3, 1, 4], 'int32'); const { values, indices } = tf.topk(a); expect(values.shape).toEqual([1]); expect(indices.shape).toEqual([1]); expect(values.dtype).toBe('int32'); expect(indices.dtype).toBe('int32'); expectArraysClose(await values.data(), [4]); expectArraysClose(await indices.data(), [3]); }); it('lower-index element appears first, k=4', async () => { const a = tensor1d([1, 2, 2, 1], 'int32'); const k = 4; const { values, indices } = tf.topk(a, k); expect(values.shape).toEqual([4]); expect(indices.shape).toEqual([4]); expect(values.dtype).toBe('int32'); expect(indices.dtype).toBe('int32'); expectArraysClose(await values.data(), [2, 2, 1, 1]); expectArraysClose(await indices.data(), [1, 2, 0, 3]); }); it('lower-index element appears first, k=65', async () => { const a = [ 1, 1, 2, 1, 2, 1, 1, 1, 2, 2, 1, 1, 2, 1, 1, 2, 1, 1, 2, 1, 1, 2, 1, 2, 1, 1, 1, 2, 1, 1, 2, 1, 1, 2, 1, 1, 1, 1, 2, 1, 2, 2, 2, 2, 1, 2, 1, 2, 2, 2, 1, 2, 2, 1, 2, 2, 1, 2, 1, 1, 1, 2, 1, 2, 1 ]; const k = a.length; const { values, indices } = tf.topk(a, k); expectArraysClose(await values.data(), [ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 ]); expectArraysClose(await indices.data(), [ 2, 4, 8, 9, 12, 15, 18, 21, 23, 27, 30, 33, 38, 40, 41, 42, 43, 45, 47, 48, 49, 51, 52, 54, 55, 57, 61, 63, 0, 1, 3, 5, 6, 7, 10, 11, 13, 14, 16, 17, 19, 20, 22, 24, 25, 26, 28, 29, 31, 32, 34, 35, 36, 37, 39, 44, 46, 50, 53, 56, 58, 59, 60, 62, 64 ]); }); it('lower-index element appears first, sorted=false', async () => { const a = [ 1, 1, 2, 1, 2, 1, 1, 1, 2, 2, 1, 1, 2, 1, 1, 2, 1, 1, 2, 1, 1, 2, 1, 2, 1, 1, 1, 2, 1, 1, 2, 1, 1, 2, 1, 1, 1, 1, 2, 1, 2, 2, 2, 2, 1, 2, 1, 2, 2, 2, 1, 2, 2, 1, 2, 2, 1, 2, 1, 1, 1, 2, 1, 2, 1 ]; const k = a.length; const { values, indices } = tf.topk(a, k, false); expect(values.shape).toEqual([k]); expect(indices.shape).toEqual([k]); expect(values.dtype).toBe('float32'); expect(indices.dtype).toBe('int32'); const valuesData = await values.data(); valuesData.sort(); expectArraysClose(valuesData, [ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 ]); const indicesData = await indices.data(); const onesIndices = indicesData.filter((index) => a[index] === 1); const twosIndices = indicesData.filter((index) => a[index] === 2); expectArraysClose(onesIndices, [ 0, 1, 3, 5, 6, 7, 10, 11, 13, 14, 16, 17, 19, 20, 22, 24, 25, 26, 28, 29, 31, 32, 34, 35, 36, 37, 39, 44, 46, 50, 53, 56, 58, 59, 60, 62, 64 ]); expectArraysClose(twosIndices, [ 2, 4, 8, 9, 12, 15, 18, 21, 23, 27, 30, 33, 38, 40, 41, 42, 43, 45, 47, 48, 49, 51, 52, 54, 55, 57, 61, 63 ]); }); it('throws when k < 0', () => { const a = tensor2d([[10, 50], [40, 30]]); expect(() => tf.topk(a, -1)) .toThrowError(/'k' passed to topk\(\) must be >= 0/); }); it('throws when k > size of array', () => { const a = tensor2d([[10, 50], [40, 30]]); expect(() => tf.topk(a, 3)) .toThrowError(/'k' passed to topk\(\) must be <= the last dimension/); }); it('throws when passed a scalar', () => { const a = scalar(2); expect(() => tf.topk(a)) .toThrowError(/topk\(\) expects the input to be of rank 1 or higher/); }); it('negative infinity input', async () => { const a = [-Infinity, -Infinity, -Infinity, -Infinity, -Infinity]; const k = a.length; const { values, indices } = tf.topk(a, k); expect(values.shape).toEqual([k]); expect(indices.shape).toEqual([k]); expect(values.dtype).toBe('float32'); expect(indices.dtype).toBe('int32'); expectArraysClose(await values.data(), a); expectArraysClose(await indices.data(), [0, 1, 2, 3, 4]); }); it('accepts a tensor-like object, k=2', async () => { const a = [20, 10, 40, 30]; const k = 2; const { values, indices } = tf.topk(a, k); expect(values.shape).toEqual([2]); expect(indices.shape).toEqual([2]); expect(values.dtype).toBe('float32'); expect(indices.dtype).toBe('int32'); expectArraysClose(await values.data(), [40, 30]); expectArraysClose(await indices.data(), [2, 3]); }); it('handles output tensors from other ops', async () => { const a = tensor1d([20, 10, 40, 30]); const b = scalar(2); const { values, indices } = tf.topk(tf.add(a, b)); expect(values.shape).toEqual([1]); expect(indices.shape).toEqual([1]); expect(values.dtype).toBe('float32'); expect(indices.dtype).toBe('int32'); expectArraysClose(await values.data(), [42]); expectArraysClose(await indices.data(), [2]); }); }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidG9wa190ZXN0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vdGZqcy1jb3JlL3NyYy9vcHMvdG9wa190ZXN0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7Ozs7Ozs7Ozs7R0FlRztBQUVILE9BQU8sS0FBSyxFQUFFLE1BQU0sVUFBVSxDQUFDO0FBQy9CLE9BQU8sRUFBQyxRQUFRLEVBQUUsaUJBQWlCLEVBQUMsTUFBTSxpQkFBaUIsQ0FBQztBQUM1RCxPQUFPLEVBQUMsaUJBQWlCLEVBQUMsTUFBTSxjQUFjLENBQUM7QUFFL0MsT0FBTyxFQUFDLE1BQU0sRUFBQyxNQUFNLFVBQVUsQ0FBQztBQUNoQyxPQUFPLEVBQUMsUUFBUSxFQUFDLE1BQU0sWUFBWSxDQUFDO0FBQ3BDLE9BQU8sRUFBQyxRQUFRLEVBQUMsTUFBTSxZQUFZLENBQUM7QUFDcEMsT0FBTyxFQUFDLFFBQVEsRUFBQyxNQUFNLFlBQVksQ0FBQztBQUVwQyxpQkFBaUIsQ0FBQyxNQUFNLEVBQUUsUUFBUSxFQUFFLEdBQUcsRUFBRTtJQUN2QyxTQUFTLENBQUMsR0FBRyxFQUFFO1FBQ2Isb0NBQW9DO1FBQ3BDLElBQUksRUFBRSxDQUFDLFVBQVUsRUFBRSxLQUFLLE9BQU8sRUFBRTtZQUMvQixFQUFFLENBQUMsR0FBRyxFQUFFLENBQUMsR0FBRyxDQUFDLDBDQUEwQyxFQUFFLENBQUMsQ0FBQyxDQUFDO1lBQzVELEVBQUUsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxHQUFHLENBQUMsOEJBQThCLEVBQUUsSUFBSSxDQUFDLENBQUM7U0FDcEQ7SUFDSCxDQUFDLENBQUMsQ0FBQztJQUVILEVBQUUsQ0FBQyxxQkFBcUIsRUFBRSxLQUFLLElBQUksRUFBRTtRQUNuQyxNQUFNLENBQUMsR0FBRyxRQUFRLENBQUMsQ0FBQyxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBQ3JDLE1BQU0sRUFBQyxNQUFNLEVBQUUsT0FBTyxFQUFDLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7UUFFeEMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ2xDLE1BQU0sQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUNuQyxNQUFNLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUNyQyxNQUFNLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUNwQyxpQkFBaUIsQ0FBQyxNQUFNLE1BQU0sQ0FBQyxJQUFJLEVBQUUsRUFBRSxFQUFFLENBQUMsQ0FBQztRQUMzQyxpQkFBaUIsQ0FBQyxNQUFNLE9BQU8sQ0FBQyxJQUFJLEVBQUUsRUFBRSxFQUFFLENBQUMsQ0FBQztJQUM5QyxDQUFDLENBQUMsQ0FBQztJQUVILEVBQUUsQ0FBQyx3QkFBd0IsRUFBRSxLQUFLLElBQUksRUFBRTtRQUN0QyxNQUFNLENBQUMsR0FBRyxRQUFRLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBQ3pCLE1BQU0sRUFBQyxNQUFNLEVBQUUsT0FBTyxFQUFDLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7UUFFeEMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ2xDLE1BQU0sQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUNuQyxNQUFNLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUNyQyxNQUFNLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUNwQyxpQkFBaUIsQ0FBQyxNQUFNLE1BQU0sQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7UUFDN0MsaUJBQWlCLENBQUMsTUFBTSxPQUFPLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQy9DLENBQUMsQ0FBQyxDQUFDO0lBRUgsRUFBRSxDQUFDLHlCQUF5QixFQUFFLEtBQUssSUFBSSxFQUFFO1FBQ3ZDLE1BQU0sQ0FBQyxHQUFHLFFBQVEsQ0FBQyxDQUFDLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUM7UUFDckMsTUFBTSxFQUFDLE1BQU0sRUFBRSxPQUFPLEVBQUMsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBRXJDLE1BQU0sQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUNsQyxNQUFNLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDbkMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUM7UUFDckMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUM7UUFDcEMsaUJBQWlCLENBQUMsTUFBTSxNQUFNLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBQzdDLGlCQUFpQixDQUFDLE1BQU0sT0FBTyxDQUFDLElBQUksRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUMvQyxDQUFDLENBQUMsQ0FBQztJQUVILEVBQUUsQ0FBQywwQ0FBMEMsRUFBRSxLQUFLLElBQUksRUFBRTtRQUN4RCxNQUFNLENBQUMsR0FBRyxRQUFRLENBQUMsQ0FBQyxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBQ3JDLE1BQU0sRUFBQyxNQUFNLEVBQUUsT0FBTyxFQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksRUFBRSxDQUFDO1FBRW5DLE1BQU0sQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUNsQyxNQUFNLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDbkMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUM7UUFDckMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUM7UUFDcEMsaUJBQWlCLENBQUMsTUFBTSxNQUFNLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBQzdDLGlCQUFpQixDQUFDLE1BQU0sT0FBTyxDQUFDLElBQUksRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUMvQyxDQUFDLENBQUMsQ0FBQztJQUVILEVBQUUsQ0FBQyx5QkFBeUIsRUFBRSxLQUFLLElBQUksRUFBRTtRQUN2QyxNQUFNLENBQUMsR0FBRyxRQUFRLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDekMsTUFBTSxFQUFDLE1BQU0sRUFBRSxPQUFPLEVBQUMsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBRXJDLE1BQU0sQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDckMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUN0QyxNQUFNLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUNyQyxNQUFNLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUNwQyxpQkFBaUIsQ0FBQyxNQUFNLE1BQU0sQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLEVBQUUsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBQ2pELGlCQUFpQixDQUFDLE1BQU0sT0FBTyxDQUFDLElBQUksRUFBRSxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDbEQsQ0FBQyxDQUFDLENBQUM7SUFFSCxFQUFFLENBQUMsbUJBQW1CLEVBQUUsS0FBSyxJQUFJLEVBQUU7UUFDakMsTUFBTSxDQUFDLEdBQUcsUUFBUSxDQUFDO1lBQ2pCLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUM7WUFDVCxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDO1lBQ1QsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQztZQUNULENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUM7U0FDVixDQUFDLENBQUM7UUFDSCxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDWixNQUFNLEVBQUMsTUFBTSxFQUFFLE9BQU8sRUFBQyxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBRXhDLE1BQU0sQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDckMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUN0QyxNQUFNLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUNyQyxNQUFNLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUNwQyxpQkFBaUIsQ0FBQyxNQUFNLE1BQU0sQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ2pFLGlCQUFpQixDQUFDLE1BQU0sT0FBTyxDQUFDLElBQUksRUFBRSxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDcEUsQ0FBQyxDQUFDLENBQUM7SUFFSCxFQUFFLENBQUMsb0NBQW9DLEVBQUUsS0FBSyxJQUFJLEVBQUU7UUFDbEQsTUFBTSxDQUFDLEdBQUcsUUFBUSxDQUFDO1lBQ2pCLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUM7WUFDVCxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDO1lBQ1QsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQztZQUNULENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUM7U0FDVixDQUFDLENBQUM7UUFDSCxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDWixNQUFNLEVBQUMsTUFBTSxFQUFFLE9BQU8sRUFBQyxHQUFHLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFFcEMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUNyQyxNQUFNLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3RDLE1BQU0sQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDO1FBQ3JDLE1BQU0sQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQ3BDLGlCQUFpQixDQUFDLE1BQU0sTUFBTSxDQUFDLElBQUksRUFBRSxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDakUsaUJBQWlCLENBQUMsTUFBTSxPQUFPLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUNwRSxDQUFDLENBQUMsQ0FBQztJQUVILEVBQUUsQ0FBQyxtQkFBbUIsRUFBRSxLQUFLLElBQUksRUFBRTtRQUNqQyxNQUFNLENBQUMsR0FBRyxRQUFRLENBQUM7WUFDakIsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO1lBQ3RCLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztTQUN2QixDQUFDLENBQUMsQ0FBRSxTQUFTO1FBQ2QsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQ1osTUFBTSxFQUFDLE1BQU0sRUFBRSxPQUFPLEVBQUMsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztRQUV4QyxNQUFNLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUN4QyxNQUFNLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUN6QyxNQUFNLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUNyQyxNQUFNLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUNwQyxpQkFBaUIsQ0FDYixNQUFNLE1BQU0sQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUMvRCxpQkFBaUIsQ0FDYixNQUFNLE9BQU8sQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUNsRSxDQUFDLENBQUMsQ0FBQztJQUVILEVBQUUsQ0FBQyxvQ0FBb0MsRUFBRSxLQUFLLElBQUksRUFBRTtRQUNsRCxNQUFNLENBQUMsR0FBRyxRQUFRLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFB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RSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUM7U0FDOUQsQ0FBQyxDQUFDO1FBQ0gsaUJBQWlCLENBQUMsTUFBTSxPQUFPLENBQUMsSUFBSSxFQUFFLEVBQUU7WUFDdEMsQ0FBQyxFQUFHLENBQUMsRUFBRyxDQUFDLEVBQUcsQ0FBQyxFQUFHLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUU7WUFDbEUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxDQUFDLEVBQUcsQ0FBQyxFQUFHLENBQUMsRUFBRyxDQUFDLEVBQUcsQ0FBQyxFQUFHLENBQUM7WUFDakUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUU7WUFDbEUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUU7U0FDdkQsQ0FBQyxDQUFDO0lBQ0wsQ0FBQyxDQUFDLENBQUM7SUFFSCxFQUFFLENBQUMsaURBQWlELEVBQUUsS0FBSyxJQUFJLEVBQUU7UUFDL0QsTUFBTSxDQUFDLEdBQUc7WUFDUixDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDO1lBQ2hFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUM7WUFDaEUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDO1NBQzlELENBQUM7UUFDRixNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsTUFBTSxDQUFDO1FBQ25CLE1BQU0sRUFBQyxNQUFNLEVBQUUsT0FBTyxFQUFDLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLEtBQUssQ0FBQyxDQUFDO1FBRS9DLE1BQU0sQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUNsQyxNQUFNLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDbkMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUM7UUFDckMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUM7UUFFcEMsTUFBTSxVQUFVLEdBQUcsTUFBTSxNQUFNLENBQUMsSUFBSSxFQUFFLENBQUM7UUFDdkMsVUFBVSxDQUFDLElBQUksRUFBRSxDQUFDO1FBQ2xCLGlCQUFpQixDQUFDLFVBQVUsRUFBRTtZQUM1QixDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDO1lBQ2hFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUM7WUFDaEUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDO1NBQzlELENBQUMsQ0FBQztRQUVILE1BQU0sV0FBVyxHQUFHLE1BQU0sT0FBTyxDQUFDLElBQUksRUFBRSxDQUFDO1FBQ3pDLE1BQU0sV0FBVyxHQUFHLFdBQVcsQ0FBQyxNQUFNLENBQUMsQ0FBQyxLQUFhLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQztRQUMxRSxNQUFNLFdBQVcsR0FBRyxXQUFXLENBQUMsTUFBTSxDQUFDLENBQUMsS0FBYSxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUM7UUFDMUUsaUJBQWlCLENBQUMsV0FBVyxFQUFFO1lBQzdCLENBQUMsRUFBRyxDQUFDLEVBQUcsQ0FBQyxFQUFHLENBQUMsRUFBRyxDQUFDLEVBQUcsQ0FBQyxFQUFHLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUU7WUFDbEQsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRTtZQUNsRCxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRTtTQUMzQyxDQUFDLENBQUM7UUFDSCxpQkFBaUIsQ0FBQyxXQUFXLEVBQUU7WUFDN0IsQ0FBQyxFQUFHLENBQUMsRUFBRyxDQUFDLEVBQUcsQ0FB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QUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUVoRCxNQUFNLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDbEMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ25DLE1BQU0sQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDO1FBQ3JDLE1BQU0sQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQ3BDLGlCQUFpQixDQUFDLE1BQU0sTUFBTSxDQUFDLElBQUksRUFBRSxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztRQUM3QyxpQkFBaUIsQ0FBQyxNQUFNLE9BQU8sQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDL0MsQ0FBQyxDQUFDLENBQUM7QUFDTCxDQUFDLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQGxpY2Vuc2VcbiAqIENvcHlyaWdodCAyMDE4IEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gKi9cblxuaW1wb3J0ICogYXMgdGYgZnJvbSAnLi4vaW5kZXgnO1xuaW1wb3J0IHtBTExfRU5WUywgZGVzY3JpYmVXaXRoRmxhZ3N9IGZyb20gJy4uL2phc21pbmVfdXRpbCc7XG5pbXBvcnQge2V4cGVjdEFycmF5c0Nsb3NlfSBmcm9tICcuLi90ZXN0X3V0aWwnO1xuXG5pbXBvcnQge3NjYWxhcn0gZnJvbSAnLi9zY2FsYXInO1xuaW1wb3J0IHt0ZW5zb3IxZH0gZnJvbSAnLi90ZW5zb3IxZCc7XG5pbXBvcnQge3RlbnNvcjJkfSBmcm9tICcuL3RlbnNvcjJkJztcbmltcG9ydCB7dGVuc29yM2R9IGZyb20gJy4vdGVuc29yM2QnO1xuXG5kZXNjcmliZVdpdGhGbGFncygndG9waycsIEFMTF9FTlZTLCAoKSA9PiB7XG4gIGJlZm9yZUFsbCgoKSA9PiB7XG4gICAgLy8gRW5zdXJlIFdlYkdMIGVudmlyb25tZW50IHVzZXMgR1BVXG4gICAgaWYgKHRmLmdldEJhY2tlbmQoKSA9PT0gJ3dlYmdsJykge1xuICAgICAgdGYuZW52KCkuc2V0KCdUT1BLX0xBU1RfRElNX0NQVV9IQU5ET0ZGX1NJWkVfVEhSRVNIT0xEJywgMCk7XG4gICAgICB0Zi5lbnYoKS5zZXQoJ1RPUEtfS19DUFVfSEFORE9GRl9USFJFU0hPTEQnLCAxMDI0KTtcbiAgICB9XG4gIH0pO1xuXG4gIGl0KCcxZCBhcnJheSB3aXRoIGsgPSAwJywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IGEgPSB0ZW5zb3IxZChbMjAsIDEwLCA0MCwgMzBdKTtcbiAgICBjb25zdCB7dmFsdWVzLCBpbmRpY2VzfSA9IHRmLnRvcGsoYSwgMCk7XG5cbiAgICBleHBlY3QodmFsdWVzLnNoYXBlKS50b0VxdWFsKFswXSk7XG4gICAgZXhwZWN0KGluZGljZXMuc2hhcGUpLnRvRXF1YWwoWzBdKTtcbiAgICBleHBlY3QodmFsdWVzLmR0eXBlKS50b0JlKCdmbG9hdDMyJyk7XG4gICAgZXhwZWN0KGluZGljZXMuZHR5cGUpLnRvQmUoJ2ludDMyJyk7XG4gICAgZXhwZWN0QXJyYXlzQ2xvc2UoYXdhaXQgdmFsdWVzLmRhdGEoKSwgW10pO1xuICAgIGV4cGVjdEFycmF5c0Nsb3NlKGF3YWl0IGluZGljZXMuZGF0YSgpLCBbXSk7XG4gIH0pO1xuXG4gIGl0KCcxZCBhcnJheSB3aXRoIGxlbmd0aCAxJywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IGEgPSB0ZW5zb3IxZChbMjBdKTtcbiAgICBjb25zdCB7dmFsdWVzLCBpbmRpY2VzfSA9IHRmLnRvcGsoYSwgMSk7XG5cbiAgICBleHBlY3QodmFsdWVzLnNoYXBlKS50b0VxdWFsKFsxXSk7XG4gICAgZXhwZWN0KGluZGljZXMuc2hhcGUpLnRvRXF1YWwoWzFdKTtcbiAgICBleHBlY3QodmFsdWVzLmR0eXBlKS50b0JlKCdmbG9hdDMyJyk7XG4gICAgZXhwZWN0KGluZGljZXMuZHR5cGUpLnRvQmUoJ2ludDMyJyk7XG4gICAgZXhwZWN0QXJyYXlzQ2xvc2UoYXdhaXQgdmFsdWVzLmRhdGEoKSwgWzIwXSk7XG4gICAgZXhwZWN0QXJyYXlzQ2xvc2UoYXdhaXQgaW5kaWNlcy5kYXRhKCksIFswXSk7XG4gIH0pO1xuXG4gIGl0KCcxZCBhcnJheSB3aXRoIGRlZmF1bHQgaycsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBhID0gdGVuc29yMWQoWzIwLCAxMCwgNDAsIDMwXSk7XG4gICAgY29uc3Qge3ZhbHVlcywgaW5kaWNlc30gPSB0Zi50b3BrKGEpO1xuXG4gICAgZXhwZWN0KHZhbHVlcy5zaGFwZSkudG9FcXVhbChbMV0pO1xuICAgIGV4cGVjdChpbmRpY2VzLnNoYXBlKS50b0VxdWFsKFsxXSk7XG4gICAgZXhwZWN0KHZhbHVlcy5kdHlwZSkudG9CZSgnZmxvYXQzMicpO1xuICAgIGV4cGVjdChpbmRpY2VzLmR0eXBlKS50b0JlKCdpbnQzMicpO1xuICAgIGV4cGVjdEFycmF5c0Nsb3NlKGF3YWl0IHZhbHVlcy5kYXRhKCksIFs0MF0pO1xuICAgIGV4cGVjdEFycmF5c0Nsb3NlKGF3YWl0IGluZGljZXMuZGF0YSgpLCBbMl0pO1xuICB9KTtcblxuICBpdCgnMWQgYXJyYXkgd2l0aCBkZWZhdWx0IGsgZnJvbSB0ZW5zb3IudG9waycsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBhID0gdGVuc29yMWQoWzIwLCAxMCwgNDAsIDMwXSk7XG4gICAgY29uc3Qge3ZhbHVlcywgaW5kaWNlc30gPSBhLnRvcGsoKTtcblxuICAgIGV4cGVjdCh2YWx1ZXMuc2hhcGUpLnRvRXF1YWwoWzFdKTtcbiAgICBleHBlY3QoaW5kaWNlcy5zaGFwZSkudG9FcXVhbChbMV0pO1xuICAgIGV4cGVjdCh2YWx1ZXMuZHR5cGUpLnRvQmUoJ2Zsb2F0MzInKTtcbiAgICBleHBlY3QoaW5kaWNlcy5kdHlwZSkudG9CZSgnaW50MzInKTtcbiAgICBleHBlY3RBcnJheXNDbG9zZShhd2FpdCB2YWx1ZXMuZGF0YSgpLCBbNDBdKTtcbiAgICBleHBlY3RBcnJheXNDbG9zZShhd2FpdCBpbmRpY2VzLmRhdGEoKSwgWzJdKTtcbiAgfSk7XG5cbiAgaXQoJzJkIGFycmF5IHdpdGggZGVmYXVsdCBrJywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IGEgPSB0ZW5zb3IyZChbWzEwLCA1MF0sIFs0MCwgMzBdXSk7XG4gICAgY29uc3Qge3ZhbHVlcywgaW5kaWNlc30gPSB0Zi50b3BrKGEpO1xuXG4gICAgZXhwZWN0KHZhbHVlcy5zaGFwZSkudG9FcXVhbChbMiwgMV0pO1xuICAgIGV4cGVjdChpbmRpY2VzLnNoYXBlKS50b0VxdWFsKFsyLCAxXSk7XG4gICAgZXhwZWN0KHZhbHVlcy5kdHlwZSkudG9CZSgnZmxvYXQzMicpO1xuICAgIGV4cGVjdChpbmRpY2VzLmR0eXBlKS50b0JlKCdpbnQzMicpO1xuICAgIGV4cGVjdEFycmF5c0Nsb3NlKGF3YWl0IHZhbHVlcy5kYXRhKCksIFs1MCwgNDBdKTtcbiAgICBleHBlY3RBcnJheXNDbG9zZShhd2FpdCBpbmRpY2VzLmRhdGEoKSwgWzEsIDBdKTtcbiAgfSk7XG5cbiAgaXQoJzJkIGFycmF5IHdpdGggaz0yJywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IGEgPSB0ZW5zb3IyZChbXG4gICAgICBbMSwgNSwgMl0sXG4gICAgICBbNCwgMywgNl0sXG4gICAgICBbMywgMiwgMV0sXG4gICAgICBbMSwgMiwgM10sXG4gICAgXSk7XG4gICAgY29uc3QgayA9IDI7XG4gICAgY29uc3Qge3ZhbHVlcywgaW5kaWNlc30gPSB0Zi50b3BrKGEsIGspO1xuXG4gICAgZXhwZWN0KHZhbHVlcy5zaGFwZSkudG9FcXVhbChbNCwgMl0pO1xuICAgIGV4cGVjdChpbmRpY2VzLnNoYXBlKS50b0VxdWFsKFs0LCAyXSk7XG4gICAgZXhwZWN0KHZhbHVlcy5kdHlwZSkudG9CZSgnZmxvYXQzMicpO1xuICAgIGV4cGVjdChpbmRpY2VzLmR0eXBlKS50b0JlKCdpbnQzMicpO1xuICAgIGV4cGVjdEFycmF5c0Nsb3NlKGF3YWl0IHZhbHVlcy5kYXRhKCksIFs1LCAyLCA2LCA0LCAzLCAyLCAzLCAyXSk7XG4gICAgZXhwZWN0QXJyYXlzQ2xvc2UoYXdhaXQgaW5kaWNlcy5kYXRhKCksIFsxLCAyLCAyLCAwLCAwLCAxLCAyLCAxXSk7XG4gIH0pO1xuXG4gIGl0KCcyZCBhcnJheSB3aXRoIGs9MiBmcm9tIHRlbnNvci50b3BrJywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IGEgPSB0ZW5zb3IyZChbXG4gICAgICBbMSwgNSwgMl0sXG4gICAgICBbNCwgMywgNl0sXG4gICAgICBbMywgMiwgMV0sXG4gICAgICBbMSwgMiwgM10sXG4gICAgXSk7XG4gICAgY29uc3QgayA9IDI7XG4gICAgY29uc3Qge3ZhbHVlcywgaW5kaWNlc30gPSBhLnRvcGsoayk7XG5cbiAgICBleHBlY3QodmFsdWVzLnNoYXBlKS50b0VxdWFsKFs0LCAyXSk7XG4gICAgZXhwZWN0KGluZGljZXMuc2hhcGUpLnRvRXF1YWwoWzQsIDJdKTtcbiAgICBleHBlY3QodmFsdWVzLmR0eXBlKS50b0JlKCdmbG9hdDMyJyk7XG4gICAgZXhwZWN0KGluZGljZXMuZHR5cGUpLnRvQmUoJ2ludDMyJyk7XG4gICAgZXhwZWN0QXJyYXlzQ2xvc2UoYXdhaXQgdmFsdWVzLmRhdGEoKSwgWzUsIDIsIDYsIDQsIDMsIDIsIDMsIDJdKTtcbiAgICBleHBlY3RBcnJheXNDbG9zZShhd2FpdCBpbmRpY2VzLmRhdGEoKSwgWzEsIDIsIDIsIDAsIDAsIDEsIDIsIDFdKTtcbiAgfSk7XG5cbiAgaXQoJzNkIGFycmF5IHdpdGggaz0zJywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IGEgPSB0ZW5zb3IzZChbXG4gICAgICBbWzEsIDUsIDJdLCBbNCwgMywgNl1dLFxuICAgICAgW1szLCAyLCAxXSwgWzEsIDIsIDNdXSxcbiAgICBdKTsgIC8vIDJ4MngzLlxuICAgIGNvbnN0IGsgPSAzO1xuICAgIGNvbnN0IHt2YWx1ZXMsIGluZGljZXN9ID0gdGYudG9wayhhLCBrKTtcblxuICAgIGV4cGVjdCh2YWx1ZXMuc2hhcGUpLnRvRXF1YWwoWzIsIDIsIDNdKTtcbiAgICBleHBlY3QoaW5kaWNlcy5zaGFwZSkudG9FcXVhbChbMiwgMiwgM10pO1xuICAgIGV4cGVjdCh2YWx1ZXMuZHR5cGUpLnRvQmUoJ2Zsb2F0MzInKTtcbiAgICBleHBlY3QoaW5kaWNlcy5kdHlwZSkudG9CZSgnaW50MzInKTtcbiAgICBleHBlY3RBcnJheXNDbG9zZShcbiAgICAgICAgYXdhaXQgdmFsdWVzLmRhdGEoKSwgWzUsIDIsIDEsIDYsIDQsIDMsIDMsIDIsIDEsIDMsIDIsIDFdKTtcbiAgICBleHBlY3RBcnJheXNDbG9zZShcbiAgICAgICAgYXdhaXQgaW5kaWNlcy5kYXRhKCksIFsxLCAyLCAwLCAyLCAwLCAxLCAwLCAxLCAyLCAyLCAxLCAwXSk7XG4gIH0pO1xuXG4gIGl0KCd0b3BrKGludDMyKSBwcm9wYWdhdGVzIGludDMyIGR0eXBlJywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IGEgPSB0ZW5zb3IxZChbMiwgMywgMSwgNF0sICdpbnQzMicpO1xuICAgIGNvbnN0IHt2YWx1ZXMsIGluZGljZXN9ID0gdGYudG9wayhhKTtcblxuICAgIGV4cGVjdCh2YWx1ZXMuc2hhcGUpLnRvRXF1YWwoWzFdKTtcbiAgICBleHBlY3QoaW5kaWNlcy5zaGFwZSkudG9FcXVhbChbMV0pO1xuICAgIGV4cGVjdCh2YWx1ZXMuZHR5cGUpLnRvQmUoJ2ludDMyJyk7XG4gICAgZXhwZWN0KGluZGljZXMuZHR5cGUpLnRvQmUoJ2ludDMyJyk7XG4gICAgZXhwZWN0QXJyYXlzQ2xvc2UoYXdhaXQgdmFsdWVzLmRhdGEoKSwgWzRdKTtcbiAgICBleHBlY3RBcnJheXNDbG9zZShhd2FpdCBpbmRpY2VzLmRhdGEoKSwgWzNdKTtcbiAgfSk7XG5cbiAgaXQoJ2xvd2VyLWluZGV4IGVsZW1lbnQgYXBwZWFycyBmaXJzdCwgaz00JywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IGEgPSB0ZW5zb3IxZChbMSwgMiwgMiwgMV0sICdpbnQzMicpO1xuICAgIGNvbnN0IGsgPSA0O1xuICAgIGNvbnN0IHt2YWx1ZXMsIGluZGljZXN9ID0gdGYudG9wayhhLCBrKTtcblxuICAgIGV4cGVjdCh2YWx1ZXMuc2hhcGUpLnRvRXF1YWwoWzRdKTtcbiAgICBleHBlY3QoaW5kaWNlcy5zaGFwZSkudG9FcXVhbChbNF0pO1xuICAgIGV4cGVjdCh2YWx1ZXMuZHR5cGUpLnRvQmUoJ2ludDMyJyk7XG4gICAgZXhwZWN0KGluZGljZXMuZHR5cGUpLnRvQmUoJ2ludDMyJyk7XG4gICAgZXhwZWN0QXJyYXlzQ2xvc2UoYXdhaXQgdmFsdWVzLmRhdGEoKSwgWzIsIDIsIDEsIDFdKTtcbiAgICBleHBlY3RBcnJheXNDbG9zZShhd2FpdCBpbmRpY2VzLmRhdGEoKSwgWzEsIDIsIDAsIDNdKTtcbiAgfSk7XG5cbiAgaXQoJ2xvd2VyLWluZGV4IGVsZW1lbnQgYXBwZWFycyBmaXJzdCwgaz02NScsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBhID0gW1xuICAgICAgMSwgMSwgMiwgMSwgMiwgMSwgMSwgMSwgMiwgMiwgMSwgMSwgMiwgMSwgMSwgMiwgMSwgMSwgMiwgMSwgMSwgMixcbiAgICAgIDEsIDIsIDEsIDEsIDEsIDIsIDEsIDEsIDIsIDEsIDEsIDIsIDEsIDEsIDEsIDEsIDIsIDEsIDIsIDIsIDIsIDIsXG4gICAgICAxLCAyLCAxLCAyLCAyLCAyLCAxLCAyLCAyLCAxLCAyLCAyLCAxLCAyLCAxLCAxLCAxLCAyLCAxLCAyLCAxXG4gICAgXTtcbiAgICBjb25zdCBrID0gYS5sZW5ndGg7XG4gICAgY29uc3Qge3ZhbHVlcywgaW5kaWNlc30gPSB0Zi50b3BrKGEsIGspO1xuXG4gICAgZXhwZWN0QXJyYXlzQ2xvc2UoYXdhaXQgdmFsdWVzLmRhdGEoKSwgW1xuICAgICAgMiwgMiwgMiwgMiwgMiwgMiwgMiwgMiwgMiwgMiwgMiwgMiwgMiwgMiwgMiwgMiwgMiwgMiwgMiwgMiwgMiwgMixcbiAgICAgIDIsIDIsIDIsIDIsIDIsIDIsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsXG4gICAgICAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxXG4gICAgXSk7XG4gICAgZXhwZWN0QXJyYXlzQ2xvc2UoYXdhaXQgaW5kaWNlcy5kYXRhKCksIFtcbiAgICAgIDIsICA0LCAgOCwgIDksICAxMiwgMTUsIDE4LCAyMSwgMjMsIDI3LCAzMCwgMzMsIDM4LCA0MCwgNDEsIDQyLCA0MyxcbiAgICAgIDQ1LCA0NywgNDgsIDQ5LCA1MSwgNTIsIDU0LCA1NSwgNTcsIDYxLCA2MywgMCwgIDEsICAzLCAgNSwgIDYsICA3LFxuICAgICAgMTAsIDExLCAxMywgMTQsIDE2LCAxNywgMTksIDIwLCAyMiwgMjQsIDI1LCAyNiwgMjgsIDI5LCAzMSwgMzIsIDM0LFxuICAgICAgMzUsIDM2LCAzNywgMzksIDQ0LCA0NiwgNTAsIDUzLCA1NiwgNTgsIDU5LCA2MCwgNjIsIDY0XG4gICAgXSk7XG4gIH0pO1xuXG4gIGl0KCdsb3dlci1pbmRleCBlbGVtZW50IGFwcGVhcnMgZmlyc3QsIHNvcnRlZD1mYWxzZScsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBhID0gW1xuICAgICAgMSwgMSwgMiwgMSwgMiwgMSwgMSwgMSwgMiwgMiwgMSwgMSwgMiwgMSwgMSwgMiwgMSwgMSwgMiwgMSwgMSwgMixcbiAgICAgIDEsIDIsIDEsIDEsIDEsIDIsIDEsIDEsIDIsIDEsIDEsIDIsIDEsIDEsIDEsIDEsIDIsIDEsIDIsIDIsIDIsIDIsXG4gICAgICAxLCAyLCAxLCAyLCAyLCAyLCAxLCAyLCAyLCAxLCAyLCAyLCAxLCAyLCAxLCAxLCAxLCAyLCAxLCAyLCAxXG4gICAgXTtcbiAgICBjb25zdCBrID0gYS5sZW5ndGg7XG4gICAgY29uc3Qge3ZhbHVlcywgaW5kaWNlc30gPSB0Zi50b3BrKGEsIGssIGZhbHNlKTtcblxuICAgIGV4cGVjdCh2YWx1ZXMuc2hhcGUpLnRvRXF1YWwoW2tdKTtcbiAgICBleHBlY3QoaW5kaWNlcy5zaGFwZSkudG9FcXVhbChba10pO1xuICAgIGV4cGVjdCh2YWx1ZXMuZHR5cGUpLnRvQmUoJ2Zsb2F0MzInKTtcbiAgICBleHBlY3QoaW5kaWNlcy5kdHlwZSkudG9CZSgnaW50MzInKTtcblxuICAgIGNvbnN0IHZhbHVlc0RhdGEgPSBhd2FpdCB2YWx1ZXMuZGF0YSgpO1xuICAgIHZhbHVlc0RhdGEuc29ydCgpO1xuICAgIGV4cGVjdEFycmF5c0Nsb3NlKHZhbHVlc0RhdGEsIFtcbiAgICAgIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsXG4gICAgICAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAyLCAyLCAyLCAyLCAyLCAyLCAyLFxuICAgICAgMiwgMiwgMiwgMiwgMiwgMiwgMiwgMiwgMiwgMiwgMiwgMiwgMiwgMiwgMiwgMiwgMiwgMiwgMiwgMiwgMlxuICAgIF0pO1xuXG4gICAgY29uc3QgaW5kaWNlc0RhdGEgPSBhd2FpdCBpbmRpY2VzLmRhdGEoKTtcbiAgICBjb25zdCBvbmVzSW5kaWNlcyA9IGluZGljZXNEYXRhLmZpbHRlcigoaW5kZXg6IG51bWJlcikgPT4gYVtpbmRleF0gPT09IDEpO1xuICAgIGNvbnN0IHR3b3NJbmRpY2VzID0gaW5kaWNlc0RhdGEuZmlsdGVyKChpbmRleDogbnVtYmVyKSA9PiBhW2luZGV4XSA9PT0gMik7XG4gICAgZXhwZWN0QXJyYXlzQ2xvc2Uob25lc0luZGljZXMsIFtcbiAgICAgIDAsICAxLCAgMywgIDUsICA2LCAgNywgIDEwLCAxMSwgMTMsIDE0LCAxNiwgMTcsIDE5LFxuICAgICAgMjAsIDIyLCAyNCwgMjUsIDI2LCAyOCwgMjksIDMxLCAzMiwgMzQsIDM1LCAzNiwgMzcsXG4gICAgICAzOSwgNDQsIDQ2LCA1MCwgNTMsIDU2LCA1OCwgNTksIDYwLCA2MiwgNjRcbiAgICBdKTtcbiAgICBleHBlY3RBcnJheXNDbG9zZSh0d29zSW5kaWNlcywgW1xuICAgICAgMiwgIDQsICA4LCAgOSwgIDEyLCAxNSwgMTgsIDIxLCAyMywgMjcsIDMwLCAzMywgMzgsIDQwLFxuICAgICAgNDEsIDQyLCA0MywgNDUsIDQ3LCA0OCwgNDksIDUxLCA1MiwgNTQsIDU1LCA1NywgNjEsIDYzXG4gICAgXSk7XG4gIH0pO1xuXG4gIGl0KCd0aHJvd3Mgd2hlbiBrIDwgMCcsICgpID0+IHtcbiAgICBjb25zdCBhID0gdGVuc29yMmQoW1sxMCwgNTBdLCBbNDAsIDMwXV0pO1xuICAgIGV4cGVjdCgoKSA9PiB0Zi50b3BrKGEsIC0xKSlcbiAgICAgICAgLnRvVGhyb3dFcnJvcigvJ2snIHBhc3NlZCB0byB0b3BrXFwoXFwpIG11c3QgYmUgPj0gMC8pO1xuICB9KTtcblxuICBpdCgndGhyb3dzIHdoZW4gayA+IHNpemUgb2YgYXJyYXknLCAoKSA9PiB7XG4gICAgY29uc3QgYSA9IHRlbnNvcjJkKFtbMTAsIDUwXSwgWzQwLCAzMF1dKTtcbiAgICBleHBlY3QoKCkgPT4gdGYudG9wayhhLCAzKSlcbiAgICAgICAgLnRvVGhyb3dFcnJvcigvJ2snIHBhc3NlZCB0byB0b3BrXFwoXFwpIG11c3QgYmUgPD0gdGhlIGxhc3QgZGltZW5zaW9uLyk7XG4gIH0pO1xuXG4gIGl0KCd0aHJvd3Mgd2hlbiBwYXNzZWQgYSBzY2FsYXInLCAoKSA9PiB7XG4gICAgY29uc3QgYSA9IHNjYWxhcigyKTtcbiAgICBleHBlY3QoKCkgPT4gdGYudG9wayhhKSlcbiAgICAgICAgLnRvVGhyb3dFcnJvcigvdG9wa1xcKFxcKSBleHBlY3RzIHRoZSBpbnB1dCB0byBiZSBvZiByYW5rIDEgb3IgaGlnaGVyLyk7XG4gIH0pO1xuXG4gIGl0KCduZWdhdGl2ZSBpbmZpbml0eSBpbnB1dCcsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBhID0gWy1JbmZpbml0eSwgLUluZmluaXR5LCAtSW5maW5pdHksIC1JbmZpbml0eSwgLUluZmluaXR5XTtcbiAgICBjb25zdCBrID0gYS5sZW5ndGg7XG4gICAgY29uc3Qge3ZhbHVlcywgaW5kaWNlc30gPSB0Zi50b3BrKGEsIGspO1xuXG4gICAgZXhwZWN0KHZhbHVlcy5zaGFwZSkudG9FcXVhbChba10pO1xuICAgIGV4cGVjdChpbmRpY2VzLnNoYXBlKS50b0VxdWFsKFtrXSk7XG4gICAgZXhwZWN0KHZhbHVlcy5kdHlwZSkudG9CZSgnZmxvYXQzMicpO1xuICAgIGV4cGVjdChpbmRpY2VzLmR0eXBlKS50b0JlKCdpbnQzMicpO1xuICAgIGV4cGVjdEFycmF5c0Nsb3NlKGF3YWl0IHZhbHVlcy5kYXRhKCksIGEpO1xuICAgIGV4cGVjdEFycmF5c0Nsb3NlKGF3YWl0IGluZGljZXMuZGF0YSgpLCBbMCwgMSwgMiwgMywgNF0pO1xuICB9KTtcblxuICBpdCgnYWNjZXB0cyBhIHRlbnNvci1saWtlIG9iamVjdCwgaz0yJywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IGEgPSBbMjAsIDEwLCA0MCwgMzBdO1xuICAgIGNvbnN0IGsgPSAyO1xuICAgIGNvbnN0IHt2YWx1ZXMsIGluZGljZXN9ID0gdGYudG9wayhhLCBrKTtcblxuICAgIGV4cGVjdCh2YWx1ZXMuc2hhcGUpLnRvRXF1YWwoWzJdKTtcbiAgICBleHBlY3QoaW5kaWNlcy5zaGFwZSkudG9FcXVhbChbMl0pO1xuICAgIGV4cGVjdCh2YWx1ZXMuZHR5cGUpLnRvQmUoJ2Zsb2F0MzInKTtcbiAgICBleHBlY3QoaW5kaWNlcy5kdHlwZSkudG9CZSgnaW50MzInKTtcbiAgICBleHBlY3RBcnJheXNDbG9zZShhd2FpdCB2YWx1ZXMuZGF0YSgpLCBbNDAsIDMwXSk7XG4gICAgZXhwZWN0QXJyYXlzQ2xvc2UoYXdhaXQgaW5kaWNlcy5kYXRhKCksIFsyLCAzXSk7XG4gIH0pO1xuXG4gIGl0KCdoYW5kbGVzIG91dHB1dCB0ZW5zb3JzIGZyb20gb3RoZXIgb3BzJywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IGEgPSB0ZW5zb3IxZChbMjAsIDEwLCA0MCwgMzBdKTtcbiAgICBjb25zdCBiID0gc2NhbGFyKDIpO1xuICAgIGNvbnN0IHt2YWx1ZXMsIGluZGljZXN9ID0gdGYudG9wayh0Zi5hZGQoYSwgYikpO1xuXG4gICAgZXhwZWN0KHZhbHVlcy5zaGFwZSkudG9FcXVhbChbMV0pO1xuICAgIGV4cGVjdChpbmRpY2VzLnNoYXBlKS50b0VxdWFsKFsxXSk7XG4gICAgZXhwZWN0KHZhbHVlcy5kdHlwZSkudG9CZSgnZmxvYXQzMicpO1xuICAgIGV4cGVjdChpbmRpY2VzLmR0eXBlKS50b0JlKCdpbnQzMicpO1xuICAgIGV4cGVjdEFycmF5c0Nsb3NlKGF3YWl0IHZhbHVlcy5kYXRhKCksIFs0Ml0pO1xuICAgIGV4cGVjdEFycmF5c0Nsb3NlKGF3YWl0IGluZGljZXMuZGF0YSgpLCBbMl0pO1xuICB9KTtcbn0pO1xuIl19