/** * @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('dilation2d', ALL_ENVS, () => { it('valid padding.', async () => { const inputShape = [1, 2, 2, 1]; const filterShape = [2, 2, 1]; const x = tf.tensor4d([.1, .2, .3, .4], inputShape); const filter = tf.tensor3d([.4, .3, .1, .0], filterShape); const result = tf.dilation2d(x, filter, 1 /* strides */, 'valid'); expect(result.shape).toEqual([1, 1, 1, 1]); expectArraysClose(await result.data(), [.5]); }); it('same padding.', async () => { const inputShape = [1, 2, 2, 1]; const filterShape = [2, 2, 1]; const x = tf.tensor4d([.1, .2, .3, .4], inputShape); const filter = tf.tensor3d([.4, .3, .1, .0], filterShape); const result = tf.dilation2d(x, filter, 1 /* strides */, 'same'); expect(result.shape).toEqual([1, 2, 2, 1]); expectArraysClose(await result.data(), [.5, .6, .7, .8]); }); it('same padding depth 3.', async () => { const inputShape = [1, 2, 2, 3]; const filterShape = [2, 2, 3]; const x = tf.tensor4d([.1, .2, .0, .2, .3, .1, .3, .4, .2, .4, .5, .3], inputShape); const filter = tf.tensor3d([.4, .5, .3, .3, .4, .2, .1, .2, .0, .0, .1, -.1], filterShape); const result = tf.dilation2d(x, filter, 1 /* strides */, 'same'); expect(result.shape).toEqual([1, 2, 2, 3]); expectArraysClose(await result.data(), [.5, .7, .3, .6, .8, .4, .7, .9, .5, .8, 1., .6]); }); it('same padding batch 2.', async () => { const inputShape = [2, 2, 2, 1]; const filterShape = [2, 2, 1]; const x = tf.tensor4d([.1, .2, .3, .4, .2, .3, .4, .5], inputShape); const filter = tf.tensor3d([.4, .3, .1, .0], filterShape); const result = tf.dilation2d(x, filter, 1 /* strides */, 'same'); expect(result.shape).toEqual([2, 2, 2, 1]); expectArraysClose(await result.data(), [.5, .6, .7, .8, .6, .7, .8, .9]); }); it('same padding filter 2.', async () => { const inputShape = [1, 3, 3, 1]; const filterShape = [2, 2, 1]; const x = tf.tensor4d([.1, .2, .3, .4, .5, .6, .7, .8, .9], inputShape); const filter = tf.tensor3d([.4, .3, .1, .2], filterShape); const result = tf.dilation2d(x, filter, 1 /* strides */, 'same'); expect(result.shape).toEqual([1, 3, 3, 1]); expectArraysClose(await result.data(), [.7, .8, .7, 1, 1.1, 1, 1.1, 1.2, 1.3]); }); it('valid padding non-square-window.', async () => { const inputShape = [1, 2, 2, 1]; const filterShape = [1, 2, 1]; const x = tf.tensor4d([.1, .2, .3, .4], inputShape); const filter = tf.tensor3d([.4, .3], filterShape); const result = tf.dilation2d(x, filter, 1 /* strides */, 'valid'); expect(result.shape).toEqual([1, 2, 1, 1]); expectArraysClose(await result.data(), [.5, .7]); }); it('same padding dilations 2.', async () => { const inputShape = [1, 3, 3, 1]; const filterShape = [2, 2, 1]; const x = tf.tensor4d([.1, .2, .3, .4, .5, .6, .7, .8, .9], inputShape); const filter = tf.tensor3d([.4, .3, .1, .2], filterShape); const result = tf.dilation2d(x, filter, 1 /* strides */, 'same', 2); // Because dilations = 2, the effective filter is [3, 3, 1]: // filter_eff = [[[.4], [.0], [.3]], // [[.0], [.0], [.0]], // [[.1], [.0], [.2]]] expect(result.shape).toEqual([1, 3, 3, 1]); expectArraysClose(await result.data(), [.7, .8, .6, 1., 1.1, .9, .8, .9, .9]); }); it('valid padding uneven stride.', async () => { const inputShape = [1, 3, 4, 1]; const filterShape = [2, 2, 1]; const x = tf.tensor4d([.1, .2, .3, .4, .5, .6, .7, .8, .9, 1., 1.1, 1.2], inputShape); const filter = tf.tensor3d([.4, .3, .1, .2], filterShape); const result = tf.dilation2d(x, filter, [1, 2] /* strides */, 'valid'); expect(result.shape).toEqual([1, 2, 2, 1]); expectArraysClose(await result.data(), [.8, 1., 1.2, 1.4]); }); it('throws when input rank is not 3 or 4.', async () => { const filterShape = [1, 1, 1]; // tslint:disable-next-line:no-any const x = tf.tensor1d([.5]); const filter = tf.tensor3d([.4], filterShape); expect(() => tf.dilation2d(x, filter, 1, 'valid')).toThrowError(); }); it('thorws when filter is not rank 3.', async () => { const inputShape = [1, 2, 2, 1]; const filterShape = [2, 2]; const x = tf.tensor4d([.1, .2, .3, .4], inputShape); // tslint:disable-next-line:no-any const filter = tf.tensor2d([.4, .3, .1, .0], filterShape); expect(() => tf.dilation2d(x, filter, 1, 'valid')).toThrowError(); }); it('throws when data format is not NHWC.', async () => { const inputShape = [1, 2, 2, 1]; const filterShape = [2, 2, 1]; const x = tf.tensor4d([.1, .2, .3, .4], inputShape); const filter = tf.tensor3d([.4, .3, .1, .0], filterShape); // tslint:disable-next-line:no-any const dataFormat = 'NCHW'; expect(() => tf.dilation2d(x, filter, 1 /* strides */, 'valid', 1, dataFormat)) .toThrowError(); }); it('dilation gradient valid padding.', async () => { const inputShape = [1, 3, 3, 1]; const filterShape = [1, 1, 1]; const x = tf.tensor4d([.1, .2, .3, .4, .5, .6, .7, .8, .9], inputShape); const filter = tf.tensor3d([.5], filterShape); const dy = tf.tensor4d([.2, .3, .4, .2, .1, 1., .2, .3, .4], inputShape); const grads = tf.grads((x, filter) => x.dilation2d(filter, 1, 'valid')); const [dx, dfilter] = grads([x, filter], dy); expect(dx.shape).toEqual(x.shape); expectArraysClose(await dx.data(), [.2, .3, .4, .2, .1, 1., .2, .3, .4]); expect(dfilter.shape).toEqual(filterShape); expectArraysClose(await dfilter.data(), [3.1]); }); it('dilation gradient same padding.', async () => { const inputShape = [1, 3, 3, 1]; const filterShape = [1, 1, 1]; const x = tf.tensor4d([.1, .2, .3, .4, .5, .6, .7, .8, .9], inputShape); const filter = tf.tensor3d([.5], filterShape); const dy = tf.tensor4d([.2, .3, .4, .2, .1, 1., .2, .3, .4], inputShape); const grads = tf.grads((x, filter) => x.dilation2d(filter, 1, 'same')); const [dx, dfilter] = grads([x, filter], dy); expect(dx.shape).toEqual(x.shape); expectArraysClose(await dx.data(), [.2, .3, .4, .2, .1, 1., .2, .3, .4]); expect(dfilter.shape).toEqual(filterShape); expectArraysClose(await dfilter.data(), [3.1]); }); it('dilation gradient same padding depth 2.', async () => { const inputShape = [1, 2, 2, 3]; const filterShape = [1, 1, 3]; const x = tf.tensor4d([.1, .2, .0, .2, .3, .1, .3, .4, .2, .4, .5, .3], inputShape); const filter = tf.tensor3d([.4, .5, .6], filterShape); const dy = tf.tensor4d([.2, .3, .4, .2, .1, 1., .2, .3, .4, .8, -.1, .1], inputShape); const grads = tf.grads((x, filter) => x.dilation2d(filter, 1, 'same')); const [dx, dfilter] = grads([x, filter], dy); expect(dx.shape).toEqual(x.shape); expectArraysClose(await dx.data(), [.2, .3, .4, .2, .1, 1., .2, .3, .4, .8, -.1, .1]); expect(dfilter.shape).toEqual(filterShape); expectArraysClose(await dfilter.data(), [1.4, .6, 1.9]); }); it('dilation gradient valid padding filter 2.', async () => { const inputShape = [1, 3, 3, 1]; const filterShape = [2, 2, 1]; const dyShape = [1, 2, 2, 1]; const x = tf.tensor4d([.1, .2, .3, .4, .5, .6, .7, .8, .9], inputShape); const filter = tf.tensor3d([.4, .3, .1, .2], filterShape); const dy = tf.tensor4d([.2, .3, .4, .2], dyShape); const grads = tf.grads((x, filter) => x.dilation2d(filter, 1, 'valid')); const [dx, dfilter] = grads([x, filter], dy); expect(dx.shape).toEqual(x.shape); expectArraysClose(await dx.data(), [0, 0, 0, 0, .2, .3, 0, .4, .2]); expect(dfilter.shape).toEqual(filterShape); expectArraysClose(await dfilter.data(), [0, 0, 0, 1.1]); }); it('dilation gradient same padding filter 2 depth 3.', async () => { const inputShape = [1, 3, 3, 3]; const filterShape = [2, 2, 3]; const x = tf.tensor4d([ .1, .2, .3, .4, .5, .6, .7, .8, .9, .3, .2, .3, .4, .5, .1, .9, .6, .3, .4, .5, .6, .2, .3, .5, .1, .2, .3 ], inputShape); const filter = tf.tensor3d([.4, .3, .1, .2, .2, .1, .7, .3, .8, .4, .9, .1], filterShape); const dy = tf.tensor4d([ .2, .3, .4, .2, .1, .5, 0, .8, .7, .1, .2, .1, .2, .3, .4, .5, .6, .6, .6, .7, .8, .3, .2, .1, .2, .4, .2 ], inputShape); const grads = tf.grads((x, filter) => x.dilation2d(filter, 1, 'same')); const [dx, dfilter] = grads([x, filter], dy); expect(dx.shape).toEqual(x.shape); expectArraysClose(await dx.data(), [ 0, 0, 0, 0, 0, 0, 0, .8, .5, .2, 0, .4, 0, .3, 0, .9, .7, .7, .7, .7, .9, .3, .4, .5, .2, .7, .8 ]); expect(dfilter.shape).toEqual(filterShape); expectArraysClose(await dfilter.data(), [1.6, 2.7, 1.1, .2, 0, .5, .3, 0, 2.2, .2, .9, 0]); }); }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGlsYXRpb24yZF90ZXN0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vdGZqcy1jb3JlL3NyYy9vcHMvZGlsYXRpb24yZF90ZXN0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7Ozs7Ozs7Ozs7R0FlRztBQUVILE9BQU8sS0FBSyxFQUFFLE1BQU0sVUFBVSxDQUFDO0FBQy9CLE9BQU8sRUFBQyxRQUFRLEVBQUUsaUJBQWlCLEVBQUMsTUFBTSxpQkFBaUIsQ0FBQztBQUM1RCxPQUFPLEVBQUMsaUJBQWlCLEVBQUMsTUFBTSxjQUFjLENBQUM7QUFFL0MsaUJBQWlCLENBQUMsWUFBWSxFQUFFLFFBQVEsRUFBRSxHQUFHLEVBQUU7SUFDN0MsRUFBRSxDQUFDLGdCQUFnQixFQUFFLEtBQUssSUFBSSxFQUFFO1FBQzlCLE1BQU0sVUFBVSxHQUFxQyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBQ2xFLE1BQU0sV0FBVyxHQUE2QixDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7UUFDeEQsTUFBTSxDQUFDLEdBQUcsRUFBRSxDQUFDLFFBQVEsQ0FBQyxDQUFDLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsQ0FBQyxFQUFFLFVBQVUsQ0FBQyxDQUFDO1FBQ3BELE1BQU0sTUFBTSxHQUFHLEVBQUUsQ0FBQyxRQUFRLENBQUMsQ0FBQyxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLENBQUMsRUFBRSxXQUFXLENBQUMsQ0FBQztRQUUxRCxNQUFNLE1BQU0sR0FBRyxFQUFFLENBQUMsVUFBVSxDQUFDLENBQUMsRUFBRSxNQUFNLEVBQUUsQ0FBQyxDQUFDLGFBQWEsRUFBRSxPQUFPLENBQUMsQ0FBQztRQUVsRSxNQUFNLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMs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LEdBQUcsS0FBSyxDQUFDLENBQUMsQ0FBQyxFQUFFLE1BQU0sQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDO1FBRTdDLE1BQU0sQ0FBQyxFQUFFLENBQUMsS0FBSyxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUNsQyxpQkFBaUIsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxJQUFJLEVBQUUsRUFBRTtZQUNqQyxDQUFDLEVBQUUsQ0FBQyxFQUFHLENBQUMsRUFBRyxDQUFDLEVBQUcsQ0FBQyxFQUFHLENBQUMsRUFBRyxDQUFDLEVBQUcsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsQ0FBQyxFQUFHLEVBQUUsRUFBRSxDQUFDLEVBQUUsRUFBRTtZQUNwRCxDQUFDLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFO1NBQ2xELENBQUMsQ0FBQztRQUVILE1BQU0sQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLENBQUMsT0FBTyxDQUFDLFdBQVcsQ0FBQyxDQUFDO1FBQzNDLGlCQUFpQixDQUNiLE1BQU0sT0FBTyxDQUFDLElBQUksRUFBRSxFQUNwQixDQUFDLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEVBQUUsRUFBRSxDQUFDLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxDQUFDLEVBQUUsR0FBRyxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUN6RCxDQUFDLENBQUMsQ0FBQztBQUNMLENBQUMsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBAbGljZW5zZVxuICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAqL1xuXG5pbXBvcnQgKiBhcyB0ZiBmcm9tICcuLi9pbmRleCc7XG5pbXBvcnQge0FMTF9FTlZTLCBkZXNjcmliZVdpdGhGbGFnc30gZnJvbSAnLi4vamFzbWluZV91dGlsJztcbmltcG9ydCB7ZXhwZWN0QXJyYXlzQ2xvc2V9IGZyb20gJy4uL3Rlc3RfdXRpbCc7XG5cbmRlc2NyaWJlV2l0aEZsYWdzKCdkaWxhdGlvbjJkJywgQUxMX0VOVlMsICgpID0+IHtcbiAgaXQoJ3ZhbGlkIHBhZGRpbmcuJywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IGlucHV0U2hhcGU6IFtudW1iZXIsIG51bWJlciwgbnVtYmVyLCBudW1iZXJdID0gWzEsIDIsIDIsIDFdO1xuICAgIGNvbnN0IGZpbHRlclNoYXBlOiBbbnVtYmVyLCBudW1iZXIsIG51bWJlcl0gPSBbMiwgMiwgMV07XG4gICAgY29uc3QgeCA9IHRmLnRlbnNvcjRkKFsuMSwgLjIsIC4zLCAuNF0sIGlucHV0U2hhcGUpO1xuICAgIGNvbnN0IGZpbHRlciA9IHRmLnRlbnNvcjNkKFsuNCwgLjMsIC4xLCAuMF0sIGZpbHRlclNoYXBlKTtcblxuICAgIGNvbnN0IHJlc3VsdCA9IHRmLmRpbGF0aW9uMmQoeCwgZmlsdGVyLCAxIC8qIHN0cmlkZXMgKi8sICd2YWxpZCcpO1xuXG4gICAgZXhwZWN0KHJlc3VsdC5zaGFwZSkudG9FcXVhbChbMSwgMSwgMSwgMV0pO1xuICAgIGV4cGVjdEFycmF5c0Nsb3NlKGF3YWl0IHJlc3VsdC5kYXRhKCksIFsuNV0pO1xuICB9KTtcblxuICBpdCgnc2FtZSBwYWRkaW5nLicsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBpbnB1dFNoYXBlOiBbbnVtYmVyLCBudW1iZXIsIG51bWJlciwgbnVtYmVyXSA9IFsxLCAyLCAyLCAxXTtcbiAgICBjb25zdCBmaWx0ZXJTaGFwZTogW251bWJlciwgbnVtYmVyLCBudW1iZXJdID0gWzIsIDIsIDFdO1xuICAgIGNvbnN0IHggPSB0Zi50ZW5zb3I0ZChbLjEsIC4yLCAuMywgLjRdLCBpbnB1dFNoYXBlKTtcbiAgICBjb25zdCBmaWx0ZXIgPSB0Zi50ZW5zb3IzZChbLjQsIC4zLCAuMSwgLjBdLCBmaWx0ZXJTaGFwZSk7XG5cbiAgICBjb25zdCByZXN1bHQgPSB0Zi5kaWxhdGlvbjJkKHgsIGZpbHRlciwgMSAvKiBzdHJpZGVzICovLCAnc2FtZScpO1xuXG4gICAgZXhwZWN0KHJlc3VsdC5zaGFwZSkudG9FcXVhbChbMSwgMiwgMiwgMV0pO1xuICAgIGV4cGVjdEFycmF5c0Nsb3NlKGF3YWl0IHJlc3VsdC5kYXRhKCksIFsuNSwgLjYsIC43LCAuOF0pO1xuICB9KTtcblxuICBpdCgnc2FtZSBwYWRkaW5nIGRlcHRoIDMuJywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IGlucHV0U2hhcGU6IFtudW1iZXIsIG51bWJlciwgbnVtYmVyLCBudW1iZXJdID0gWzEsIDIsIDIsIDNdO1xuICAgIGNvbnN0IGZpbHRlclNoYXBlOiBbbnVtYmVyLCBudW1iZXIsIG51bWJlcl0gPSBbMiwgMiwgM107XG4gICAgY29uc3QgeCA9IHRmLnRlbnNvcjRkKFxuICAgICAgICBbLjEsIC4yLCAuMCwgLjIsIC4zLCAuMSwgLjMsIC40LCAuMiwgLjQsIC41LCAuM10sIGlucHV0U2hhcGUpO1xuICAgIGNvbnN0IGZpbHRlciA9IHRmLnRlbnNvcjNkKFxuICAgICAgICBbLjQsIC41LCAuMywgLjMsIC40LCAuMiwgLjEsIC4yLCAuMCwgLjAsIC4xLCAtLjFdLCBmaWx0ZXJTaGFwZSk7XG5cbiAgICBjb25zdCByZXN1bHQgPSB0Zi5kaWxhdGlvbjJkKHgsIGZpbHRlciwgMSAvKiBzdHJpZGVzICovLCAnc2FtZScpO1xuXG4gICAgZXhwZWN0KHJlc3VsdC5zaGFwZSkudG9FcXVhbChbMSwgMiwgMiwgM10pO1xuICAgIGV4cGVjdEFycmF5c0Nsb3NlKFxuICAgICAgICBhd2FpdCByZXN1bHQuZGF0YSgpLCBbLjUsIC43LCAuMywgLjYsIC44LCAuNCwgLjcsIC45LCAuNSwgLjgsIDEuLCAuNl0pO1xuICB9KTtcblxuICBpdCgnc2FtZSBwYWRkaW5nIGJhdGNoIDIuJywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IGlucHV0U2hhcGU6IFtudW1iZXIsIG51bWJlciwgbnVtYmVyLCBudW1iZXJdID0gWzIsIDIsIDIsIDFdO1xuICAgIGNvbnN0IGZpbHRlclNoYXBlOiBbbnVtYmVyLCBudW1iZXIsIG51bWJlcl0gPSBbMiwgMiwgMV07XG4gICAgY29uc3QgeCA9IHRmLnRlbnNvcjRkKFsuMSwgLjIsIC4zLCAuNCwgLjIsIC4zLCAuNCwgLjVdLCBpbnB1dFNoYXBlKTtcbiAgICBjb25zdCBmaWx0ZXIgPSB0Zi50ZW5zb3IzZChbLjQsIC4zLCAuMSwgLjBdLCBmaWx0ZXJTaGFwZSk7XG5cbiAgICBjb25zdCByZXN1bHQgPSB0Zi5kaWxhdGlvbjJkKHgsIGZpbHRlciwgMSAvKiBzdHJpZGVzICovLCAnc2FtZScpO1xuXG4gICAgZXhwZWN0KHJlc3VsdC5zaGFwZSkudG9FcXVhbChbMiwgMiwgMiwgMV0pO1xuICAgIGV4cGVjdEFycmF5c0Nsb3NlKGF3YWl0IHJlc3VsdC5kYXRhKCksIFsuNSwgLjYsIC43LCAuOCwgLjYsIC43LCAuOCwgLjldKTtcbiAgfSk7XG5cbiAgaXQoJ3NhbWUgcGFkZGluZyBmaWx0ZXIgMi4nLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgaW5wdXRTaGFwZTogW251bWJlciwgbnVtYmVyLCBudW1iZXIsIG51bWJlcl0gPSBbMSwgMywgMywgMV07XG4gICAgY29uc3QgZmlsdGVyU2hhcGU6IFtudW1iZXIsIG51bWJlciwgbnVtYmVyXSA9IFsyLCAyLCAxXTtcbiAgICBjb25zdCB4ID0gdGYudGVuc29yNGQoWy4xLCAuMiwgLjMsIC40LCAuNSwgLjYsIC43LCAuOCwgLjldLCBpbnB1dFNoYXBlKTtcbiAgICBjb25zdCBmaWx0ZXIgPSB0Zi50ZW5zb3IzZChbLjQsIC4zLCAuMSwgLjJdLCBmaWx0ZXJTaGFwZSk7XG5cbiAgICBjb25zdCByZXN1bHQgPSB0Zi5kaWxhdGlvbjJkKHgsIGZpbHRlciwgMSAvKiBzdHJpZGVzICovLCAnc2FtZScpO1xuXG4gICAgZXhwZWN0KHJlc3VsdC5zaGFwZSkudG9FcXVhbChbMSwgMywgMywgMV0pO1xuICAgIGV4cGVjdEFycmF5c0Nsb3NlKFxuICAgICAgICBhd2FpdCByZXN1bHQuZGF0YSgpLCBbLjcsIC44LCAuNywgMSwgMS4xLCAxLCAxLjEsIDEuMiwgMS4zXSk7XG4gIH0pO1xuXG4gIGl0KCd2YWxpZCBwYWRkaW5nIG5vbi1zcXVhcmUtd2luZG93LicsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBpbnB1dFNoYXBlOiBbbnVtYmVyLCBudW1iZXIsIG51bWJlciwgbnVtYmVyXSA9IFsxLCAyLCAyLCAxXTtcbiAgICBjb25zdCBmaWx0ZXJTaGFwZTogW251bWJlciwgbnVtYmVyLCBudW1iZXJdID0gWzEsIDIsIDFdO1xuICAgIGNvbnN0IHggPSB0Zi50ZW5zb3I0ZChbLjEsIC4yLCAuMywgLjRdLCBpbnB1dFNoYXBlKTtcbiAgICBjb25zdCBmaWx0ZXIgPSB0Zi50ZW5zb3IzZChbLjQsIC4zXSwgZmlsdGVyU2hhcGUpO1xuXG4gICAgY29uc3QgcmVzdWx0ID0gdGYuZGlsYXRpb24yZCh4LCBmaWx0ZXIsIDEgLyogc3RyaWRlcyAqLywgJ3ZhbGlkJyk7XG5cbiAgICBleHBlY3QocmVzdWx0LnNoYXBlKS50b0VxdWFsKFsxLCAyLCAxLCAxXSk7XG4gICAgZXhwZWN0QXJyYXlzQ2xvc2UoYXdhaXQgcmVzdWx0LmRhdGEoKSwgWy41LCAuN10pO1xuICB9KTtcblxuICBpdCgnc2FtZSBwYWRkaW5nIGRpbGF0aW9ucyAyLicsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBpbnB1dFNoYXBlOiBbbnVtYmVyLCBudW1iZXIsIG51bWJlciwgbnVtYmVyXSA9IFsxLCAzLCAzLCAxXTtcbiAgICBjb25zdCBmaWx0ZXJTaGFwZTogW251bWJlciwgbnVtYmVyLCBudW1iZXJdID0gWzIsIDIsIDFdO1xuICAgIGNvbnN0IHggPSB0Zi50ZW5zb3I0ZChbLjEsIC4yLCAuMywgLjQsIC41LCAuNiwgLjcsIC44LCAuOV0sIGlucHV0U2hhcGUpO1xuICAgIGNvbnN0IGZpbHRlciA9IHRmLnRlbnNvcjNkKFsuNCwgLjMsIC4xLCAuMl0sIGZpbHRlclNoYXBlKTtcblxuICAgIGNvbnN0IHJlc3VsdCA9IHRmLmRpbGF0aW9uMmQoeCwgZmlsdGVyLCAxIC8qIHN0cmlkZXMgKi8sICdzYW1lJywgMik7XG5cbiAgICAvLyBCZWNhdXNlIGRpbGF0aW9ucyA9IDIsIHRoZSBlZmZlY3RpdmUgZmlsdGVyIGlzIFszLCAzLCAxXTpcbiAgICAvLyBmaWx0ZXJfZWZmID0gW1tbLjRdLCBbLjBdLCBbLjNdXSxcbiAgICAvLyAgICAgICAgICAgICAgIFtbLjBdLCBbLjBdLCBbLjBdXSxcbiAgICAvLyAgICAgICAgICAgICAgIFtbLjFdLCBbLjBdLCBbLjJdXV1cbiAgICBleHBlY3QocmVzdWx0LnNoYXBlKS50b0VxdWFsKFsxLCAzLCAzLCAxXSk7XG4gICAgZXhwZWN0QXJyYXlzQ2xvc2UoXG4gICAgICAgIGF3YWl0IHJlc3VsdC5kYXRhKCksIFsuNywgLjgsIC42LCAxLiwgMS4xLCAuOSwgLjgsIC45LCAuOV0pO1xuICB9KTtcblxuICBpdCgndmFsaWQgcGFkZGluZyB1bmV2ZW4gc3RyaWRlLicsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBpbnB1dFNoYXBlOiBbbnVtYmVyLCBudW1iZXIsIG51bWJlciwgbnVtYmVyXSA9IFsxLCAzLCA0LCAxXTtcbiAgICBjb25zdCBmaWx0ZXJTaGFwZTogW251bWJlciwgbnVtYmVyLCBudW1iZXJdID0gWzIsIDIsIDFdO1xuICAgIGNvbnN0IHggPSB0Zi50ZW5zb3I0ZChcbiAgICAgICAgWy4xLCAuMiwgLjMsIC40LCAuNSwgLjYsIC43LCAuOCwgLjksIDEuLCAxLjEsIDEuMl0sIGlucHV0U2hhcGUpO1xuICAgIGNvbnN0IGZpbHRlciA9IHRmLnRlbnNvcjNkKFsuNCwgLjMsIC4xLCAuMl0sIGZpbHRlclNoYXBlKTtcblxuICAgIGNvbnN0IHJlc3VsdCA9IHRmLmRpbGF0aW9uMmQoeCwgZmlsdGVyLCBbMSwgMl0gLyogc3RyaWRlcyAqLywgJ3ZhbGlkJyk7XG5cbiAgICBleHBlY3QocmVzdWx0LnNoYXBlKS50b0VxdWFsKFsxLCAyLCAyLCAxXSk7XG4gICAgZXhwZWN0QXJyYXlzQ2xvc2UoYXdhaXQgcmVzdWx0LmRhdGEoKSwgWy44LCAxLiwgMS4yLCAxLjRdKTtcbiAgfSk7XG5cbiAgaXQoJ3Rocm93cyB3aGVuIGlucHV0IHJhbmsgaXMgbm90IDMgb3IgNC4nLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgZmlsdGVyU2hhcGU6IFtudW1iZXIsIG51bWJlciwgbnVtYmVyXSA9IFsxLCAxLCAxXTtcbiAgICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6bm8tYW55XG4gICAgY29uc3QgeDogYW55ID0gdGYudGVuc29yMWQoWy41XSk7XG4gICAgY29uc3QgZmlsdGVyID0gdGYudGVuc29yM2QoWy40XSwgZmlsdGVyU2hhcGUpO1xuXG4gICAgZXhwZWN0KCgpID0+IHRmLmRpbGF0aW9uMmQoeCwgZmlsdGVyLCAxLCAndmFsaWQnKSkudG9UaHJvd0Vycm9yKCk7XG4gIH0pO1xuXG4gIGl0KCd0aG9yd3Mgd2hlbiBmaWx0ZXIgaXMgbm90IHJhbmsgMy4nLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgaW5wdXRTaGFwZTogW251bWJlciwgbnVtYmVyLCBudW1iZXIsIG51bWJlcl0gPSBbMSwgMiwgMiwgMV07XG4gICAgY29uc3QgZmlsdGVyU2hhcGU6IFtudW1iZXIsIG51bWJlcl0gPSBbMiwgMl07XG4gICAgY29uc3QgeCA9IHRmLnRlbnNvcjRkKFsuMSwgLjIsIC4zLCAuNF0sIGlucHV0U2hhcGUpO1xuICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTpuby1hbnlcbiAgICBjb25zdCBmaWx0ZXI6IGFueSA9IHRmLnRlbnNvcjJkKFsuNCwgLjMsIC4xLCAuMF0sIGZpbHRlclNoYXBlKTtcblxuICAgIGV4cGVjdCgoKSA9PiB0Zi5kaWxhdGlvbjJkKHgsIGZpbHRlciwgMSwgJ3ZhbGlkJykpLnRvVGhyb3dFcnJvcigpO1xuICB9KTtcblxuICBpdCgndGhyb3dzIHdoZW4gZGF0YSBmb3JtYXQgaXMgbm90IE5IV0MuJywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IGlucHV0U2hhcGU6IFtudW1iZXIsIG51bWJlciwgbnVtYmVyLCBudW1iZXJdID0gWzEsIDIsIDIsIDFdO1xuICAgIGNvbnN0IGZpbHRlclNoYXBlOiBbbnVtYmVyLCBudW1iZXIsIG51bWJlcl0gPSBbMiwgMiwgMV07XG4gICAgY29uc3QgeCA9IHRmLnRlbnNvcjRkKFsuMSwgLjIsIC4zLCAuNF0sIGlucHV0U2hhcGUpO1xuICAgIGNvbnN0IGZpbHRlciA9IHRmLnRlbnNvcjNkKFsuNCwgLjMsIC4xLCAuMF0sIGZpbHRlclNoYXBlKTtcbiAgICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6bm8tYW55XG4gICAgY29uc3QgZGF0YUZvcm1hdDogYW55ID0gJ05DSFcnO1xuXG4gICAgZXhwZWN0KFxuICAgICAgICAoKSA9PiB0Zi5kaWxhdGlvbjJkKHgsIGZpbHRlciwgMSAvKiBzdHJpZGVzICovLCAndmFsaWQnLCAxLCBkYXRhRm9ybWF0KSlcbiAgICAgICAgLnRvVGhyb3dFcnJvcigpO1xuICB9KTtcblxuICBpdCgnZGlsYXRpb24gZ3JhZGllbnQgdmFsaWQgcGFkZGluZy4nLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgaW5wdXRTaGFwZTogW251bWJlciwgbnVtYmVyLCBudW1iZXIsIG51bWJlcl0gPSBbMSwgMywgMywgMV07XG4gICAgY29uc3QgZmlsdGVyU2hhcGU6IFtudW1iZXIsIG51bWJlciwgbnVtYmVyXSA9IFsxLCAxLCAxXTtcbiAgICBjb25zdCB4ID0gdGYudGVuc29yNGQoWy4xLCAuMiwgLjMsIC40LCAuNSwgLjYsIC43LCAuOCwgLjldLCBpbnB1dFNoYXBlKTtcbiAgICBjb25zdCBmaWx0ZXIgPSB0Zi50ZW5zb3IzZChbLjVdLCBmaWx0ZXJTaGFwZSk7XG4gICAgY29uc3QgZHkgPSB0Zi50ZW5zb3I0ZChbLjIsIC4zLCAuNCwgLjIsIC4xLCAxLiwgLjIsIC4zLCAuNF0sIGlucHV0U2hhcGUpO1xuXG4gICAgY29uc3QgZ3JhZHMgPSB0Zi5ncmFkcyhcbiAgICAgICAgKHg6IHRmLlRlbnNvcjRELCBmaWx0ZXI6IHRmLlRlbnNvcjNEKSA9PlxuICAgICAgICAgICAgeC5kaWxhdGlvbjJkKGZpbHRlciwgMSwgJ3ZhbGlkJykpO1xuXG4gICAgY29uc3QgW2R4LCBkZmlsdGVyXSA9IGdyYWRzKFt4LCBmaWx0ZXJdLCBkeSk7XG5cbiAgICBleHBlY3QoZHguc2hhcGUpLnRvRXF1YWwoeC5zaGFwZSk7XG4gICAgZXhwZWN0QXJyYXlzQ2xvc2UoYXdhaXQgZHguZGF0YSgpLCBbLjIsIC4zLCAuNCwgLjIsIC4xLCAxLiwgLjIsIC4zLCAuNF0pO1xuXG4gICAgZXhwZWN0KGRmaWx0ZXIuc2hhcGUpLnRvRXF1YWwoZmlsdGVyU2hhcGUpO1xuICAgIGV4cGVjdEFycmF5c0Nsb3NlKGF3YWl0IGRmaWx0ZXIuZGF0YSgpLCBbMy4xXSk7XG4gIH0pO1xuXG4gIGl0KCdkaWxhdGlvbiBncmFkaWVudCBzYW1lIHBhZGRpbmcuJywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IGlucHV0U2hhcGU6IFtudW1iZXIsIG51bWJlciwgbnVtYmVyLCBudW1iZXJdID0gWzEsIDMsIDMsIDFdO1xuICAgIGNvbnN0IGZpbHRlclNoYXBlOiBbbnVtYmVyLCBudW1iZXIsIG51bWJlcl0gPSBbMSwgMSwgMV07XG4gICAgY29uc3QgeCA9IHRmLnRlbnNvcjRkKFsuMSwgLjIsIC4zLCAuNCwgLjUsIC42LCAuNywgLjgsIC45XSwgaW5wdXRTaGFwZSk7XG4gICAgY29uc3QgZmlsdGVyID0gdGYudGVuc29yM2QoWy41XSwgZmlsdGVyU2hhcGUpO1xuICAgIGNvbnN0IGR5ID0gdGYudGVuc29yNGQoWy4yLCAuMywgLjQsIC4yLCAuMSwgMS4sIC4yLCAuMywgLjRdLCBpbnB1dFNoYXBlKTtcblxuICAgIGNvbnN0IGdyYWRzID0gdGYuZ3JhZHMoXG4gICAgICAgICh4OiB0Zi5UZW5zb3I0RCwgZmlsdGVyOiB0Zi5UZW5zb3IzRCkgPT5cbiAgICAgICAgICAgIHguZGlsYXRpb24yZChmaWx0ZXIsIDEsICdzYW1lJykpO1xuXG4gICAgY29uc3QgW2R4LCBkZmlsdGVyXSA9IGdyYWRzKFt4LCBmaWx0ZXJdLCBkeSk7XG5cbiAgICBleHBlY3QoZHguc2hhcGUpLnRvRXF1YWwoeC5zaGFwZSk7XG4gICAgZXhwZWN0QXJyYXlzQ2xvc2UoYXdhaXQgZHguZGF0YSgpLCBbLjIsIC4zLCAuNCwgLjIsIC4xLCAxLiwgLjIsIC4zLCAuNF0pO1xuXG4gICAgZXhwZWN0KGRmaWx0ZXIuc2hhcGUpLnRvRXF1YWwoZmlsdGVyU2hhcGUpO1xuICAgIGV4cGVjdEFycmF5c0Nsb3NlKGF3YWl0IGRmaWx0ZXIuZGF0YSgpLCBbMy4xXSk7XG4gIH0pO1xuXG4gIGl0KCdkaWxhdGlvbiBncmFkaWVudCBzYW1lIHBhZGRpbmcgZGVwdGggMi4nLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgaW5wdXRTaGFwZTogW251bWJlciwgbnVtYmVyLCBudW1iZXIsIG51bWJlcl0gPSBbMSwgMiwgMiwgM107XG4gICAgY29uc3QgZmlsdGVyU2hhcGU6IFtudW1iZXIsIG51bWJlciwgbnVtYmVyXSA9IFsxLCAxLCAzXTtcbiAgICBjb25zdCB4ID0gdGYudGVuc29yNGQoXG4gICAgICAgIFsuMSwgLjIsIC4wLCAuMiwgLjMsIC4xLCAuMywgLjQsIC4yLCAuNCwgLjUsIC4zXSwgaW5wdXRTaGFwZSk7XG4gICAgY29uc3QgZmlsdGVyID0gdGYudGVuc29yM2QoWy40LCAuNSwgLjZdLCBmaWx0ZXJTaGFwZSk7XG4gICAgY29uc3QgZHkgPSB0Zi50ZW5zb3I0ZChcbiAgICAgICAgWy4yLCAuMywgLjQsIC4yLCAuMSwgMS4sIC4yLCAuMywgLjQsIC44LCAtLjEsIC4xXSwgaW5wdXRTaGFwZSk7XG5cbiAgICBjb25zdCBncmFkcyA9IHRmLmdyYWRzKFxuICAgICAgICAoeDogdGYuVGVuc29yNEQsIGZpbHRlcjogdGYuVGVuc29yM0QpID0+XG4gICAgICAgICAgICB4LmRpbGF0aW9uMmQoZmlsdGVyLCAxLCAnc2FtZScpKTtcblxuICAgIGNvbnN0IFtkeCwgZGZpbHRlcl0gPSBncmFkcyhbeCwgZmlsdGVyXSwgZHkpO1xuXG4gICAgZXhwZWN0KGR4LnNoYXBlKS50b0VxdWFsKHguc2hhcGUpO1xuICAgIGV4cGVjdEFycmF5c0Nsb3NlKFxuICAgICAgICBhd2FpdCBkeC5kYXRhKCksIFsuMiwgLjMsIC40LCAuMiwgLjEsIDEuLCAuMiwgLjMsIC40LCAuOCwgLS4xLCAuMV0pO1xuXG4gICAgZXhwZWN0KGRmaWx0ZXIuc2hhcGUpLnRvRXF1YWwoZmlsdGVyU2hhcGUpO1xuICAgIGV4cGVjdEFycmF5c0Nsb3NlKGF3YWl0IGRmaWx0ZXIuZGF0YSgpLCBbMS40LCAuNiwgMS45XSk7XG4gIH0pO1xuXG4gIGl0KCdkaWxhdGlvbiBncmFkaWVudCB2YWxpZCBwYWRkaW5nIGZpbHRlciAyLicsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBpbnB1dFNoYXBlOiBbbnVtYmVyLCBudW1iZXIsIG51bWJlciwgbnVtYmVyXSA9IFsxLCAzLCAzLCAxXTtcbiAgICBjb25zdCBmaWx0ZXJTaGFwZTogW251bWJlciwgbnVtYmVyLCBudW1iZXJdID0gWzIsIDIsIDFdO1xuICAgIGNvbnN0IGR5U2hhcGU6IFtudW1iZXIsIG51bWJlciwgbnVtYmVyLCBudW1iZXJdID0gWzEsIDIsIDIsIDFdO1xuICAgIGNvbnN0IHggPSB0Zi50ZW5zb3I0ZChbLjEsIC4yLCAuMywgLjQsIC41LCAuNiwgLjcsIC44LCAuOV0sIGlucHV0U2hhcGUpO1xuICAgIGNvbnN0IGZpbHRlciA9IHRmLnRlbnNvcjNkKFsuNCwgLjMsIC4xLCAuMl0sIGZpbHRlclNoYXBlKTtcbiAgICBjb25zdCBkeSA9IHRmLnRlbnNvcjRkKFsuMiwgLjMsIC40LCAuMl0sIGR5U2hhcGUpO1xuXG4gICAgY29uc3QgZ3JhZHMgPSB0Zi5ncmFkcyhcbiAgICAgICAgKHg6IHRmLlRlbnNvcjRELCBmaWx0ZXI6IHRmLlRlbnNvcjNEKSA9PlxuICAgICAgICAgICAgeC5kaWxhdGlvbjJkKGZpbHRlciwgMSwgJ3ZhbGlkJykpO1xuXG4gICAgY29uc3QgW2R4LCBkZmlsdGVyXSA9IGdyYWRzKFt4LCBmaWx0ZXJdLCBkeSk7XG5cbiAgICBleHBlY3QoZHguc2hhcGUpLnRvRXF1YWwoeC5zaGFwZSk7XG4gICAgZXhwZWN0QXJyYXlzQ2xvc2UoYXdhaXQgZHguZGF0YSgpLCBbMCwgMCwgMCwgMCwgLjIsIC4zLCAwLCAuNCwgLjJdKTtcblxuICAgIGV4cGVjdChkZmlsdGVyLnNoYXBlKS50b0VxdWFsKGZpbHRlclNoYXBlKTtcbiAgICBleHBlY3RBcnJheXNDbG9zZShhd2FpdCBkZmlsdGVyLmRhdGEoKSwgWzAsIDAsIDAsIDEuMV0pO1xuICB9KTtcblxuICBpdCgnZGlsYXRpb24gZ3JhZGllbnQgc2FtZSBwYWRkaW5nIGZpbHRlciAyIGRlcHRoIDMuJywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IGlucHV0U2hhcGU6IFtudW1iZXIsIG51bWJlciwgbnVtYmVyLCBudW1iZXJdID0gWzEsIDMsIDMsIDNdO1xuICAgIGNvbnN0IGZpbHRlclNoYXBlOiBbbnVtYmVyLCBudW1iZXIsIG51bWJlcl0gPSBbMiwgMiwgM107XG4gICAgY29uc3QgeCA9IHRmLnRlbnNvcjRkKFxuICAgICAgICBbXG4gICAgICAgICAgLjEsIC4yLCAuMywgLjQsIC41LCAuNiwgLjcsIC44LCAuOSwgLjMsIC4yLCAuMywgLjQsIC41LFxuICAgICAgICAgIC4xLCAuOSwgLjYsIC4zLCAuNCwgLjUsIC42LCAuMiwgLjMsIC41LCAuMSwgLjIsIC4zXG4gICAgICAgIF0sXG4gICAgICAgIGlucHV0U2hhcGUpO1xuICAgIGNvbnN0IGZpbHRlciA9IHRmLnRlbnNvcjNkKFxuICAgICAgICBbLjQsIC4zLCAuMSwgLjIsIC4yLCAuMSwgLjcsIC4zLCAuOCwgLjQsIC45LCAuMV0sIGZpbHRlclNoYXBlKTtcbiAgICBjb25zdCBkeSA9IHRmLnRlbnNvcjRkKFxuICAgICAgICBbXG4gICAgICAgICAgLjIsIC4zLCAuNCwgLjIsIC4xLCAuNSwgMCwgIC44LCAuNywgLjEsIC4yLCAuMSwgLjIsIC4zLFxuICAgICAgICAgIC40LCAuNSwgLjYsIC42LCAuNiwgLjcsIC44LCAuMywgLjIsIC4xLCAuMiwgLjQsIC4yXG4gICAgICAgIF0sXG4gICAgICAgIGlucHV0U2hhcGUpO1xuXG4gICAgY29uc3QgZ3JhZHMgPSB0Zi5ncmFkcyhcbiAgICAgICAgKHg6IHRmLlRlbnNvcjRELCBmaWx0ZXI6IHRmLlRlbnNvcjNEKSA9PlxuICAgICAgICAgICAgeC5kaWxhdGlvbjJkKGZpbHRlciwgMSwgJ3NhbWUnKSk7XG5cbiAgICBjb25zdCBbZHgsIGRmaWx0ZXJdID0gZ3JhZHMoW3gsIGZpbHRlcl0sIGR5KTtcblxuICAgIGV4cGVjdChkeC5zaGFwZSkudG9FcXVhbCh4LnNoYXBlKTtcbiAgICBleHBlY3RBcnJheXNDbG9zZShhd2FpdCBkeC5kYXRhKCksIFtcbiAgICAgIDAsIDAsICAwLCAgMCwgIDAsICAwLCAgMCwgIC44LCAuNSwgLjIsIDAsICAuNCwgMCwgLjMsXG4gICAgICAwLCAuOSwgLjcsIC43LCAuNywgLjcsIC45LCAuMywgLjQsIC41LCAuMiwgLjcsIC44XG4gICAgXSk7XG5cbiAgICBleHBlY3QoZGZpbHRlci5zaGFwZSkudG9FcXVhbChmaWx0ZXJTaGFwZSk7XG4gICAgZXhwZWN0QXJyYXlzQ2xvc2UoXG4gICAgICAgIGF3YWl0IGRmaWx0ZXIuZGF0YSgpLFxuICAgICAgICBbMS42LCAyLjcsIDEuMSwgLjIsIDAsIC41LCAuMywgMCwgMi4yLCAuMiwgLjksIDBdKTtcbiAgfSk7XG59KTtcbiJdfQ==