/** * @license * Copyright 2020 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'; describeWithFlags('stft', ALL_ENVS, () => { it('3 length with hann window', async () => { const input = tf.tensor1d([1, 1, 1, 1, 1]); const frameLength = 3; const frameStep = 1; const output = tf.signal.stft(input, frameLength, frameStep); expect(output.shape).toEqual([3, 3]); expectArraysClose(await output.data(), [ 1.0, 0.0, 0.0, -1.0, -1.0, 0.0, 1.0, 0.0, 0.0, -1.0, -1.0, 0.0, 1.0, 0.0, 0.0, -1.0, -1.0, 0.0, ]); }); it('3 length with hann window (sequencial number)', async () => { const input = tf.tensor1d([1, 2, 3, 4, 5]); const frameLength = 3; const frameStep = 1; const output = tf.signal.stft(input, frameLength, frameStep); expect(output.shape).toEqual([3, 3]); expectArraysClose(await output.data(), [ 2.0, 0.0, 0.0, -2.0, -2.0, 0.0, 3.0, 0.0, 0.0, -3.0, -3.0, 0.0, 4.0, 0.0, 0.0, -4.0, -4.0, 0.0 ]); }); it('3 length, 2 step with hann window', async () => { const input = tf.tensor1d([1, 1, 1, 1, 1]); const frameLength = 3; const frameStep = 2; const output = tf.signal.stft(input, frameLength, frameStep); expect(output.shape).toEqual([2, 3]); expectArraysClose(await output.data(), [1.0, 0.0, 0.0, -1.0, -1.0, 0.0, 1.0, 0.0, 0.0, -1.0, -1.0, 0.0]); }); it('3 fftLength, 5 frameLength, 2 step', async () => { const input = tf.tensor1d([1, 1, 1, 1, 1, 1]); const frameLength = 5; const frameStep = 1; const fftLength = 3; const output = tf.signal.stft(input, frameLength, frameStep, fftLength); expect(output.shape[0]).toEqual(2); expectArraysClose(await output.data(), [1.5, 0.0, -0.749999, 0.433, 1.5, 0.0, -0.749999, 0.433]); }); it('5 length with hann window', async () => { const input = tf.tensor1d([1, 1, 1, 1, 1]); const frameLength = 5; const frameStep = 1; const output = tf.signal.stft(input, frameLength, frameStep); expect(output.shape).toEqual([1, 5]); expectArraysClose(await output.data(), [2.0, 0.0, 0.0, -1.7071068, -1.0, 0.0, 0.0, 0.29289323, 0.0, 0.0]); }); it('5 length with hann window (sequential)', async () => { const input = tf.tensor1d([1, 2, 3, 4, 5]); const frameLength = 5; const frameStep = 1; const output = tf.signal.stft(input, frameLength, frameStep); expect(output.shape).toEqual([1, 5]); expectArraysClose(await output.data(), [ 6.0, 0.0, -0.70710677, -5.1213202, -3.0, 1.0, 0.70710677, 0.87867975, 0.0, 0.0 ]); }); it('3 length with hamming window', async () => { const input = tf.tensor1d([1, 1, 1, 1, 1]); const frameLength = 3; const frameStep = 1; const fftLength = 3; const output = tf.signal.stft(input, frameLength, frameStep, fftLength, (length) => tf.signal.hammingWindow(length)); expect(output.shape).toEqual([3, 2]); expectArraysClose(await output.data(), [ 1.16, 0.0, -0.46, -0.79674333, 1.16, 0.0, -0.46, -0.79674333, 1.16, 0.0, -0.46, -0.79674333 ]); }); it('3 length, 2 step with hamming window', async () => { const input = tf.tensor1d([1, 1, 1, 1, 1]); const frameLength = 3; const frameStep = 2; const fftLength = 3; const output = tf.signal.stft(input, frameLength, frameStep, fftLength, (length) => tf.signal.hammingWindow(length)); expect(output.shape).toEqual([2, 2]); expectArraysClose(await output.data(), [1.16, 0.0, -0.46, -0.79674333, 1.16, 0.0, -0.46, -0.79674333]); }); it('3 fftLength, 5 frameLength, 2 step with hamming window', async () => { const input = tf.tensor1d([1, 1, 1, 1, 1, 1]); const frameLength = 5; const frameStep = 1; const fftLength = 3; const output = tf.signal.stft(input, frameLength, frameStep, fftLength, (length) => tf.signal.hammingWindow(length)); expect(output.shape).toEqual([2, 2]); expectArraysClose(await output.data(), [1.619999, 0.0, -0.69, 0.39837, 1.619999, 0.0, -0.69, 0.39837]); }); it('5 length with hann window (sequential)', async () => { const input = tf.tensor1d([1, 2, 3, 4, 5]); const frameLength = 5; const frameStep = 1; const fftLength = 5; const output = tf.signal.stft(input, frameLength, frameStep, fftLength, (length) => tf.signal.hammingWindow(length)); expect(output.shape).toEqual([1, 3]); expectArraysClose(await output.data(), [6.72, 0.0, -3.6371822, -1.1404576, 0.4771822, 0.39919350]); }); it('3 length without window function', async () => { const input = tf.tensor1d([1, 1, 1, 1, 1]); const frameLength = 3; const frameStep = 1; const fftLength = 3; const ident = (length) => tf.ones([length]).as1D(); const output = tf.signal.stft(input, frameLength, frameStep, fftLength, ident); expect(output.shape).toEqual([3, 2]); expectArraysClose(await output.data(), [3.0, 0.0, 0.0, 0.0, 3.0, 0.0, 0.0, 0.0, 3.0, 0.0, 0.0, 0.0]); }); it('3 length, 2 step without window function', async () => { const input = tf.tensor1d([1, 1, 1, 1, 1]); const frameLength = 3; const frameStep = 2; const fftLength = 3; const ident = (length) => tf.ones([length]).as1D(); const output = tf.signal.stft(input, frameLength, frameStep, fftLength, ident); expect(output.shape).toEqual([2, 2]); expectArraysClose(await output.data(), [3.0, 0.0, 0.0, 0.0, 3.0, 0.0, 0.0, 0.0]); }); }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RmdF90ZXN0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vdGZqcy1jb3JlL3NyYy9vcHMvc2lnbmFsL3N0ZnRfdGVzdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7O0dBZUc7QUFFSCxPQUFPLEtBQUssRUFBRSxNQUFNLGFBQWEsQ0FBQztBQUNsQyxPQUFPLEVBQUMsUUFBUSxFQUFFLGlCQUFpQixFQUFDLE1BQU0sb0JBQW9CLENBQUM7QUFDL0QsT0FBTyxFQUFDLGlCQUFpQixFQUFDLE1BQU0saUJBQWlCLENBQUM7QUFFbEQsaUJBQWlCLENBQUMsTUFBTSxFQUFFLFFBQVEsRUFBRSxHQUFHLEVBQUU7SUFDdkMsRUFBRSxDQUFDLDJCQUEyQixFQUFFLEtBQUssSUFBSSxFQUFFO1FBQ3pDLE1BQU0sS0FBSyxHQUFHLEVBQUUsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUMzQyxNQUFNLFdBQVcsR0FBRyxDQUFDLENBQUM7UUFDdEIsTUFBTSxTQUFTLEdBQUcsQ0FBQyxDQUFDO1FBQ3BCLE1BQU0sTUFBTSxHQUFHLEVBQUUsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLEtBQUssRUFBRSxXQUFXLEVBQUUsU0FBUyxDQUFDLENBQUM7UUFDN0QsTUFBTSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUNyQyxpQkFBaUIsQ0FBQyxNQUFNLE1BQU0sQ0FBQyxJQUFJLEVBQUUsRUFBRTtZQUNyQyxHQUFHO1lBQ0gsR0FBRztZQUNILEdBQUc7WUFDSCxDQUFDLEdBQUc7WUFDSixDQUFDLEdBQUc7WUFDSixHQUFHO1lBQ0gsR0FBRztZQUNILEdBQUc7WUFDSCxHQUFHO1lBQ0gsQ0FBQyxHQUFH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TSxDQUFDLElBQUksQ0FBQyxLQUFLLEVBQUUsV0FBVyxFQUFFLFNBQVMsRUFBRSxTQUFTLEVBQUUsS0FBSyxDQUFDLENBQUM7UUFDcEUsTUFBTSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUNyQyxpQkFBaUIsQ0FDYixNQUFNLE1BQU0sQ0FBQyxJQUFJLEVBQUUsRUFDbkIsQ0FBQyxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUM7SUFDcEUsQ0FBQyxDQUFDLENBQUM7SUFFSCxFQUFFLENBQUMsMENBQTBDLEVBQUUsS0FBSyxJQUFJLEVBQUU7UUFDeEQsTUFBTSxLQUFLLEdBQUcsRUFBRSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQzNDLE1BQU0sV0FBVyxHQUFHLENBQUMsQ0FBQztRQUN0QixNQUFNLFNBQVMsR0FBRyxDQUFDLENBQUM7UUFDcEIsTUFBTSxTQUFTLEdBQUcsQ0FBQyxDQUFDO1FBQ3BCLE1BQU0sS0FBSyxHQUFHLENBQUMsTUFBYyxFQUFFLEVBQUUsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxJQUFJLEVBQUUsQ0FBQztRQUMzRCxNQUFNLE1BQU0sR0FDUixFQUFFLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxLQUFLLEVBQUUsV0FBVyxFQUFFLFNBQVMsRUFBRSxTQUFTLEVBQUUsS0FBSyxDQUFDLENBQUM7UUFDcEUsTUFBTSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUNyQyxpQkFBaUIsQ0FDYixNQUFNLE1BQU0sQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDO0lBQ3JFLENBQUMsQ0FBQyxDQUFDO0FBQ0wsQ0FBQyxDQUFDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEBsaWNlbnNlXG4gKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICovXG5cbmltcG9ydCAqIGFzIHRmIGZyb20gJy4uLy4uL2luZGV4JztcbmltcG9ydCB7QUxMX0VOVlMsIGRlc2NyaWJlV2l0aEZsYWdzfSBmcm9tICcuLi8uLi9qYXNtaW5lX3V0aWwnO1xuaW1wb3J0IHtleHBlY3RBcnJheXNDbG9zZX0gZnJvbSAnLi4vLi4vdGVzdF91dGlsJztcblxuZGVzY3JpYmVXaXRoRmxhZ3MoJ3N0ZnQnLCBBTExfRU5WUywgKCkgPT4ge1xuICBpdCgnMyBsZW5ndGggd2l0aCBoYW5uIHdpbmRvdycsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBpbnB1dCA9IHRmLnRlbnNvcjFkKFsxLCAxLCAxLCAxLCAxXSk7XG4gICAgY29uc3QgZnJhbWVMZW5ndGggPSAzO1xuICAgIGNvbnN0IGZyYW1lU3RlcCA9IDE7XG4gICAgY29uc3Qgb3V0cHV0ID0gdGYuc2lnbmFsLnN0ZnQoaW5wdXQsIGZyYW1lTGVuZ3RoLCBmcmFtZVN0ZXApO1xuICAgIGV4cGVjdChvdXRwdXQuc2hhcGUpLnRvRXF1YWwoWzMsIDNdKTtcbiAgICBleHBlY3RBcnJheXNDbG9zZShhd2FpdCBvdXRwdXQuZGF0YSgpLCBbXG4gICAgICAxLjAsXG4gICAgICAwLjAsXG4gICAgICAwLjAsXG4gICAgICAtMS4wLFxuICAgICAgLTEuMCxcbiAgICAgIDAuMCxcbiAgICAgIDEuMCxcbiAgICAgIDAuMCxcbiAgICAgIDAuMCxcbiAgICAgIC0xLjAsXG4gICAgICAtMS4wLFxuICAgICAgMC4wLFxuICAgICAgMS4wLFxuICAgICAgMC4wLFxuICAgICAgMC4wLFxuICAgICAgLTEuMCxcbiAgICAgIC0xLjAsXG4gICAgICAwLjAsXG4gICAgXSk7XG4gIH0pO1xuXG4gIGl0KCczIGxlbmd0aCB3aXRoIGhhbm4gd2luZG93IChzZXF1ZW5jaWFsIG51bWJlciknLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgaW5wdXQgPSB0Zi50ZW5zb3IxZChbMSwgMiwgMywgNCwgNV0pO1xuICAgIGNvbnN0IGZyYW1lTGVuZ3RoID0gMztcbiAgICBjb25zdCBmcmFtZVN0ZXAgPSAxO1xuICAgIGNvbnN0IG91dHB1dCA9IHRmLnNpZ25hbC5zdGZ0KGlucHV0LCBmcmFtZUxlbmd0aCwgZnJhbWVTdGVwKTtcbiAgICBleHBlY3Qob3V0cHV0LnNoYXBlKS50b0VxdWFsKFszLCAzXSk7XG4gICAgZXhwZWN0QXJyYXlzQ2xvc2UoYXdhaXQgb3V0cHV0LmRhdGEoKSwgW1xuICAgICAgMi4wLCAwLjAsIDAuMCwgLTIuMCwgLTIuMCwgMC4wLCAzLjAsIDAuMCwgMC4wLCAtMy4wLCAtMy4wLCAwLjAsIDQuMCwgMC4wLFxuICAgICAgMC4wLCAtNC4wLCAtNC4wLCAwLjBcbiAgICBdKTtcbiAgfSk7XG5cbiAgaXQoJzMgbGVuZ3RoLCAyIHN0ZXAgd2l0aCBoYW5uIHdpbmRvdycsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBpbnB1dCA9IHRmLnRlbnNvcjFkKFsxLCAxLCAxLCAxLCAxXSk7XG4gICAgY29uc3QgZnJhbWVMZW5ndGggPSAzO1xuICAgIGNvbnN0IGZyYW1lU3RlcCA9IDI7XG4gICAgY29uc3Qgb3V0cHV0ID0gdGYuc2lnbmFsLnN0ZnQoaW5wdXQsIGZyYW1lTGVuZ3RoLCBmcmFtZVN0ZXApO1xuICAgIGV4cGVjdChvdXRwdXQuc2hhcGUpLnRvRXF1YWwoWzIsIDNdKTtcbiAgICBleHBlY3RBcnJheXNDbG9zZShcbiAgICAgICAgYXdhaXQgb3V0cHV0LmRhdGEoKSxcbiAgICAgICAgWzEuMCwgMC4wLCAwLjAsIC0xLjAsIC0xLjAsIDAuMCwgMS4wLCAwLjAsIDAuMCwgLTEuMCwgLTEuMCwgMC4wXSk7XG4gIH0pO1xuXG4gIGl0KCczIGZmdExlbmd0aCwgNSBmcmFtZUxlbmd0aCwgMiBzdGVwJywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IGlucHV0ID0gdGYudGVuc29yMWQoWzEsIDEsIDEsIDEsIDEsIDFdKTtcbiAgICBjb25zdCBmcmFtZUxlbmd0aCA9IDU7XG4gICAgY29uc3QgZnJhbWVTdGVwID0gMTtcbiAgICBjb25zdCBmZnRMZW5ndGggPSAzO1xuICAgIGNvbnN0IG91dHB1dCA9IHRmLnNpZ25hbC5zdGZ0KGlucHV0LCBmcmFtZUxlbmd0aCwgZnJhbWVTdGVwLCBmZnRMZW5ndGgpO1xuICAgIGV4cGVjdChvdXRwdXQuc2hhcGVbMF0pLnRvRXF1YWwoMik7XG4gICAgZXhwZWN0QXJyYXlzQ2xvc2UoXG4gICAgICAgIGF3YWl0IG91dHB1dC5kYXRhKCksXG4gICAgICAgIFsxLjUsIDAuMCwgLTAuNzQ5OTk5LCAwLjQzMywgMS41LCAwLjAsIC0wLjc0OTk5OSwgMC40MzNdKTtcbiAgfSk7XG5cbiAgaXQoJzUgbGVuZ3RoIHdpdGggaGFubiB3aW5kb3cnLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgaW5wdXQgPSB0Zi50ZW5zb3IxZChbMSwgMSwgMSwgMSwgMV0pO1xuICAgIGNvbnN0IGZyYW1lTGVuZ3RoID0gNTtcbiAgICBjb25zdCBmcmFtZVN0ZXAgPSAxO1xuICAgIGNvbnN0IG91dHB1dCA9IHRmLnNpZ25hbC5zdGZ0KGlucHV0LCBmcmFtZUxlbmd0aCwgZnJhbWVTdGVwKTtcbiAgICBleHBlY3Qob3V0cHV0LnNoYXBlKS50b0VxdWFsKFsxLCA1XSk7XG4gICAgZXhwZWN0QXJyYXlzQ2xvc2UoXG4gICAgICAgIGF3YWl0IG91dHB1dC5kYXRhKCksXG4gICAgICAgIFsyLjAsIDAuMCwgMC4wLCAtMS43MDcxMDY4LCAtMS4wLCAwLjAsIDAuMCwgMC4yOTI4OTMyMywgMC4wLCAwLjBdKTtcbiAgfSk7XG5cbiAgaXQoJzUgbGVuZ3RoIHdpdGggaGFubiB3aW5kb3cgKHNlcXVlbnRpYWwpJywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IGlucHV0ID0gdGYudGVuc29yMWQoWzEsIDIsIDMsIDQsIDVdKTtcbiAgICBjb25zdCBmcmFtZUxlbmd0aCA9IDU7XG4gICAgY29uc3QgZnJhbWVTdGVwID0gMTtcbiAgICBjb25zdCBvdXRwdXQgPSB0Zi5zaWduYWwuc3RmdChpbnB1dCwgZnJhbWVMZW5ndGgsIGZyYW1lU3RlcCk7XG4gICAgZXhwZWN0KG91dHB1dC5zaGFwZSkudG9FcXVhbChbMSwgNV0pO1xuICAgIGV4cGVjdEFycmF5c0Nsb3NlKGF3YWl0IG91dHB1dC5kYXRhKCksIFtcbiAgICAgIDYuMCwgMC4wLCAtMC43MDcxMDY3NywgLTUuMTIxMzIwMiwgLTMuMCwgMS4wLCAwLjcwNzEwNjc3LCAwLjg3ODY3OTc1LCAwLjAsXG4gICAgICAwLjBcbiAgICBdKTtcbiAgfSk7XG5cbiAgaXQoJzMgbGVuZ3RoIHdpdGggaGFtbWluZyB3aW5kb3cnLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgaW5wdXQgPSB0Zi50ZW5zb3IxZChbMSwgMSwgMSwgMSwgMV0pO1xuICAgIGNvbnN0IGZyYW1lTGVuZ3RoID0gMztcbiAgICBjb25zdCBmcmFtZVN0ZXAgPSAxO1xuICAgIGNvbnN0IGZmdExlbmd0aCA9IDM7XG4gICAgY29uc3Qgb3V0cHV0ID0gdGYuc2lnbmFsLnN0ZnQoXG4gICAgICAgIGlucHV0LCBmcmFtZUxlbmd0aCwgZnJhbWVTdGVwLCBmZnRMZW5ndGgsXG4gICAgICAgIChsZW5ndGgpID0+IHRmLnNpZ25hbC5oYW1taW5nV2luZG93KGxlbmd0aCkpO1xuICAgIGV4cGVjdChvdXRwdXQuc2hhcGUpLnRvRXF1YWwoWzMsIDJdKTtcbiAgICBleHBlY3RBcnJheXNDbG9zZShhd2FpdCBvdXRwdXQuZGF0YSgpLCBbXG4gICAgICAxLjE2LCAwLjAsIC0wLjQ2LCAtMC43OTY3NDMzMywgMS4xNiwgMC4wLCAtMC40NiwgLTAuNzk2NzQzMzMsIDEuMTYsIDAuMCxcbiAgICAgIC0wLjQ2LCAtMC43OTY3NDMzM1xuICAgIF0pO1xuICB9KTtcblxuICBpdCgnMyBsZW5ndGgsIDIgc3RlcCB3aXRoIGhhbW1pbmcgd2luZG93JywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IGlucHV0ID0gdGYudGVuc29yMWQoWzEsIDEsIDEsIDEsIDFdKTtcbiAgICBjb25zdCBmcmFtZUxlbmd0aCA9IDM7XG4gICAgY29uc3QgZnJhbWVTdGVwID0gMjtcbiAgICBjb25zdCBmZnRMZW5ndGggPSAzO1xuICAgIGNvbnN0IG91dHB1dCA9IHRmLnNpZ25hbC5zdGZ0KFxuICAgICAgICBpbnB1dCwgZnJhbWVMZW5ndGgsIGZyYW1lU3RlcCwgZmZ0TGVuZ3RoLFxuICAgICAgICAobGVuZ3RoKSA9PiB0Zi5zaWduYWwuaGFtbWluZ1dpbmRvdyhsZW5ndGgpKTtcbiAgICBleHBlY3Qob3V0cHV0LnNoYXBlKS50b0VxdWFsKFsyLCAyXSk7XG4gICAgZXhwZWN0QXJyYXlzQ2xvc2UoXG4gICAgICAgIGF3YWl0IG91dHB1dC5kYXRhKCksXG4gICAgICAgIFsxLjE2LCAwLjAsIC0wLjQ2LCAtMC43OTY3NDMzMywgMS4xNiwgMC4wLCAtMC40NiwgLTAuNzk2NzQzMzNdKTtcbiAgfSk7XG5cbiAgaXQoJzMgZmZ0TGVuZ3RoLCA1IGZyYW1lTGVuZ3RoLCAyIHN0ZXAgd2l0aCBoYW1taW5nIHdpbmRvdycsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBpbnB1dCA9IHRmLnRlbnNvcjFkKFsxLCAxLCAxLCAxLCAxLCAxXSk7XG4gICAgY29uc3QgZnJhbWVMZW5ndGggPSA1O1xuICAgIGNvbnN0IGZyYW1lU3RlcCA9IDE7XG4gICAgY29uc3QgZmZ0TGVuZ3RoID0gMztcbiAgICBjb25zdCBvdXRwdXQgPSB0Zi5zaWduYWwuc3RmdChcbiAgICAgICAgaW5wdXQsIGZyYW1lTGVuZ3RoLCBmcmFtZVN0ZXAsIGZmdExlbmd0aCxcbiAgICAgICAgKGxlbmd0aCkgPT4gdGYuc2lnbmFsLmhhbW1pbmdXaW5kb3cobGVuZ3RoKSk7XG4gICAgZXhwZWN0KG91dHB1dC5zaGFwZSkudG9FcXVhbChbMiwgMl0pO1xuICAgIGV4cGVjdEFycmF5c0Nsb3NlKFxuICAgICAgICBhd2FpdCBvdXRwdXQuZGF0YSgpLFxuICAgICAgICBbMS42MTk5OTksIDAuMCwgLTAuNjksIDAuMzk4MzcsIDEuNjE5OTk5LCAwLjAsIC0wLjY5LCAwLjM5ODM3XSk7XG4gIH0pO1xuXG4gIGl0KCc1IGxlbmd0aCB3aXRoIGhhbm4gd2luZG93IChzZXF1ZW50aWFsKScsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBpbnB1dCA9IHRmLnRlbnNvcjFkKFsxLCAyLCAzLCA0LCA1XSk7XG4gICAgY29uc3QgZnJhbWVMZW5ndGggPSA1O1xuICAgIGNvbnN0IGZyYW1lU3RlcCA9IDE7XG4gICAgY29uc3QgZmZ0TGVuZ3RoID0gNTtcbiAgICBjb25zdCBvdXRwdXQgPSB0Zi5zaWduYWwuc3RmdChcbiAgICAgICAgaW5wdXQsIGZyYW1lTGVuZ3RoLCBmcmFtZVN0ZXAsIGZmdExlbmd0aCxcbiAgICAgICAgKGxlbmd0aCkgPT4gdGYuc2lnbmFsLmhhbW1pbmdXaW5kb3cobGVuZ3RoKSk7XG4gICAgZXhwZWN0KG91dHB1dC5zaGFwZSkudG9FcXVhbChbMSwgM10pO1xuICAgIGV4cGVjdEFycmF5c0Nsb3NlKFxuICAgICAgICBhd2FpdCBvdXRwdXQuZGF0YSgpLFxuICAgICAgICBbNi43MiwgMC4wLCAtMy42MzcxODIyLCAtMS4xNDA0NTc2LCAwLjQ3NzE4MjIsIDAuMzk5MTkzNTBdKTtcbiAgfSk7XG5cbiAgaXQoJzMgbGVuZ3RoIHdpdGhvdXQgd2luZG93IGZ1bmN0aW9uJywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IGlucHV0ID0gdGYudGVuc29yMWQoWzEsIDEsIDEsIDEsIDFdKTtcbiAgICBjb25zdCBmcmFtZUxlbmd0aCA9IDM7XG4gICAgY29uc3QgZnJhbWVTdGVwID0gMTtcbiAgICBjb25zdCBmZnRMZW5ndGggPSAzO1xuICAgIGNvbnN0IGlkZW50ID0gKGxlbmd0aDogbnVtYmVyKSA9PiB0Zi5vbmVzKFtsZW5ndGhdKS5hczFEKCk7XG4gICAgY29uc3Qgb3V0cHV0ID1cbiAgICAgICAgdGYuc2lnbmFsLnN0ZnQoaW5wdXQsIGZyYW1lTGVuZ3RoLCBmcmFtZVN0ZXAsIGZmdExlbmd0aCwgaWRlbnQpO1xuICAgIGV4cGVjdChvdXRwdXQuc2hhcGUpLnRvRXF1YWwoWzMsIDJdKTtcbiAgICBleHBlY3RBcnJheXNDbG9zZShcbiAgICAgICAgYXdhaXQgb3V0cHV0LmRhdGEoKSxcbiAgICAgICAgWzMuMCwgMC4wLCAwLjAsIDAuMCwgMy4wLCAwLjAsIDAuMCwgMC4wLCAzLjAsIDAuMCwgMC4wLCAwLjBdKTtcbiAgfSk7XG5cbiAgaXQoJzMgbGVuZ3RoLCAyIHN0ZXAgd2l0aG91dCB3aW5kb3cgZnVuY3Rpb24nLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgaW5wdXQgPSB0Zi50ZW5zb3IxZChbMSwgMSwgMSwgMSwgMV0pO1xuICAgIGNvbnN0IGZyYW1lTGVuZ3RoID0gMztcbiAgICBjb25zdCBmcmFtZVN0ZXAgPSAyO1xuICAgIGNvbnN0IGZmdExlbmd0aCA9IDM7XG4gICAgY29uc3QgaWRlbnQgPSAobGVuZ3RoOiBudW1iZXIpID0+IHRmLm9uZXMoW2xlbmd0aF0pLmFzMUQoKTtcbiAgICBjb25zdCBvdXRwdXQgPVxuICAgICAgICB0Zi5zaWduYWwuc3RmdChpbnB1dCwgZnJhbWVMZW5ndGgsIGZyYW1lU3RlcCwgZmZ0TGVuZ3RoLCBpZGVudCk7XG4gICAgZXhwZWN0KG91dHB1dC5zaGFwZSkudG9FcXVhbChbMiwgMl0pO1xuICAgIGV4cGVjdEFycmF5c0Nsb3NlKFxuICAgICAgICBhd2FpdCBvdXRwdXQuZGF0YSgpLCBbMy4wLCAwLjAsIDAuMCwgMC4wLCAzLjAsIDAuMCwgMC4wLCAwLjBdKTtcbiAgfSk7XG59KTtcbiJdfQ==