gx
chenyc
2025-02-12 ea42ff3ebee1eeb3fb29423aa848a249441db81c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
/**
 * @license
 * Copyright 2022 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('cumprod', ALL_ENVS, () => {
    it('1D standard', async () => {
        const res = tf.tensor1d([1, 2, 3, 4]).cumprod();
        expect(res.shape).toEqual([4]);
        expectArraysClose(await res.data(), [1, 2, 6, 24]);
    });
    it('1D reverse', async () => {
        const reverse = true;
        const exclusive = false;
        const res = tf.tensor1d([1, 2, 3, 4]).cumprod(0, exclusive, reverse);
        expect(res.shape).toEqual([4]);
        expectArraysClose(await res.data(), [24, 24, 12, 4]);
    });
    it('1D exclusive', async () => {
        const exclusive = true;
        const res = tf.tensor1d([1, 2, 3, 4]).cumprod(0, exclusive);
        expect(res.shape).toEqual([4]);
        expectArraysClose(await res.data(), [1, 1, 2, 6]);
    });
    it('1D exclusive reverse', async () => {
        const reverse = true;
        const exclusive = true;
        const res = tf.tensor1d([1, 2, 3, 4]).cumprod(0, exclusive, reverse);
        expect(res.shape).toEqual([4]);
        expectArraysClose(await res.data(), [24, 12, 4, 1]);
    });
    // TODO: once gradients are implemented, create tests something like this.
    // it('gradient: 1D', async () => {
    //   const a = tf.tensor1d([1, 2, 3]);
    //   const dy = tf.tensor1d([4, 5, 6]);
    //   const da = tf.grad((x) => tf.cumprod(x))(a, dy);
    //   expect(da.shape).toEqual([3]);
    //   expectArraysClose(await da.data(), [15, 11, 6]);
    // });
    // it('gradient with clones', async () => {
    //   const a = tf.tensor1d([1, 2, 3]);
    //   const dy = tf.tensor1d([4, 5, 6]);
    //   const da = tf.grad((x) => tf.cumprod(x.clone()).clone())(a, dy);
    //   expect(da.shape).toEqual([3]);
    //   expectArraysClose(await da.data(), [15, 11, 6]);
    // });
    it('2D standard', async () => {
        const res = tf
            .tensor2d([
            [1, 2],
            [3, 4],
        ])
            .cumprod(1);
        expect(res.shape).toEqual([2, 2]);
        expectArraysClose(await res.array(), [[1, 2], [3, 12]]);
    });
    it('2D reverse exclusive', async () => {
        const reverse = true;
        const exclusive = true;
        const res = tf
            .tensor2d([
            [1, 2],
            [3, 4],
        ])
            .cumprod(1, exclusive, reverse);
        expect(res.shape).toEqual([2, 2]);
        expectArraysClose(await res.array(), [[2, 1], [4, 1]]);
    });
    it('2D axis=0', async () => {
        const res = tf
            .tensor2d([
            [1, 2],
            [3, 4],
        ])
            .cumprod();
        expect(res.shape).toEqual([2, 2]);
        expectArraysClose(await res.array(), [[1, 2], [3, 8]]);
    });
    it('3D standard', async () => {
        const res = tf
            .tensor3d([
            [
                [0, 1],
                [2, 3],
            ],
            [
                [4, 5],
                [6, 7],
            ],
        ])
            .cumprod(2);
        expect(res.shape).toEqual([2, 2, 2]);
        expectArraysClose(await res.array(), [
            [
                [0, 0 * 1],
                [2, 2 * 3]
            ],
            [
                [4, 4 * 5],
                [6, 6 * 7]
            ]
        ]);
    });
    it('4d axis=2', async () => {
        const input = tf.add(tf.ones([1, 32, 8, 4]), tf.ones([1, 32, 8, 4]));
        const res = tf.cumprod(input, 2, false, false);
        expect(res.shape).toEqual([1, 32, 8, 4]);
        const earlySlice = tf.slice(res, [0, 0, 0, 0], [1, 1, 8, 1]);
        const lateSlice = tf.slice(res, [0, 31, 0, 0], [1, 1, 8, 1]);
        const expectedDataInEachSlice = [2, 4, 8, 16, 32, 64, 128, 256];
        expectArraysClose(await earlySlice.data(), expectedDataInEachSlice);
        expectArraysClose(await lateSlice.data(), expectedDataInEachSlice);
    });
    it('handle permutation properly', async () => {
        const res = tf.ones([1, 240, 1, 10]).cumprod(1);
        expect(res.shape).toEqual([1, 240, 1, 10]);
    });
    it('throws when passed a non-tensor', () => {
        expect(() => tf.cumprod({})).toThrowError(/Argument 'x' passed to 'cumprod' must be a Tensor/);
    });
    it('accepts a tensor-like object', async () => {
        const res = tf.cumprod([1, 2, 3, 4]);
        expect(res.shape).toEqual([4]);
        expectArraysClose(await res.data(), [1, 2, 6, 24]);
    });
    it('throws error for string tensor', () => {
        expect(() => tf.cumprod(['a', 'b', 'c'])).toThrowError(/Argument 'x' passed to 'cumprod' must be numeric tensor/);
    });
});
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY3VtcHJvZF90ZXN0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vdGZqcy1jb3JlL3NyYy9vcHMvY3VtcHJvZF90ZXN0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7Ozs7Ozs7Ozs7R0FlRztBQUVILE9BQU8sS0FBSyxFQUFFLE1BQU0sVUFBVSxDQUFDO0FBQy9CLE9BQU8sRUFBRSxRQUFRLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUM5RCxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxjQUFjLENBQUM7QUFFakQsaUJBQWlCLENBQUMsU0FBUyxFQUFFLFFBQVEsRUFBRSxHQUFHLEVBQUU7SUFDMUMsRUFBRSxDQUFDLGFBQWEsRUFBRSxLQUFLLElBQUksRUFBRTtRQUMzQixNQUFNLEdBQUcsR0FBRyxFQUFFLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxPQUFPLEVBQUUsQ0FBQztRQUNoRCxNQUFNLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDL0IsaUJBQWlCLENBQUMsTUFBTSxHQUFHLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDO0lBQ3JELENBQUMsQ0FBQyxDQUFDO0lBRUgsRUFBRSxDQUFDLFlBQVksRUFBRSxLQUFLLElBQUksRUFBRTtRQUMxQixNQUFNLE9BQU8sR0FBRyxJQUFJLENBQUM7UUFDckIsTUFBTSxTQUFTLEdBQUcsS0FBSyxDQUFDO1FBQ3hCLE1BQU0sR0FBRyxHQUFHLEVBQUUsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLE9B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LENBQUM7SUFFSCxFQUFFLENBQUMsaUNBQWlDLEVBQUUsR0FBRyxFQUFFO1FBQ3pDLE1BQU0sQ0FBQyxHQUFHLEVBQUUsQ0FBQyxFQUFFLENBQUMsT0FBTyxDQUFDLEVBQWUsQ0FBQyxDQUFDLENBQUMsWUFBWSxDQUNwRCxtREFBbUQsQ0FDcEQsQ0FBQztJQUNKLENBQUMsQ0FBQyxDQUFDO0lBRUgsRUFBRSxDQUFDLDhCQUE4QixFQUFFLEtBQUssSUFBSSxFQUFFO1FBQzVDLE1BQU0sR0FBRyxHQUFHLEVBQUUsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3JDLE1BQU0sQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUMvQixpQkFBaUIsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFDckQsQ0FBQyxDQUFDLENBQUM7SUFFSCxFQUFFLENBQUMsZ0NBQWdDLEVBQUUsR0FBRyxFQUFFO1FBQ3hDLE1BQU0sQ0FBQyxHQUFHLEVBQUUsQ0FBQyxFQUFFLENBQUMsT0FBTyxDQUFDLENBQUMsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsWUFBWSxDQUNwRCx5REFBeUQsQ0FDMUQsQ0FBQztJQUNKLENBQUMsQ0FBQyxDQUFDO0FBQ0wsQ0FBQyxDQUFDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEBsaWNlbnNlXG4gKiBDb3B5cmlnaHQgMjAyMiBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICdMaWNlbnNlJyk7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAnQVMgSVMnIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gKi9cblxuaW1wb3J0ICogYXMgdGYgZnJvbSAnLi4vaW5kZXgnO1xuaW1wb3J0IHsgQUxMX0VOVlMsIGRlc2NyaWJlV2l0aEZsYWdzIH0gZnJvbSAnLi4vamFzbWluZV91dGlsJztcbmltcG9ydCB7IGV4cGVjdEFycmF5c0Nsb3NlIH0gZnJvbSAnLi4vdGVzdF91dGlsJztcblxuZGVzY3JpYmVXaXRoRmxhZ3MoJ2N1bXByb2QnLCBBTExfRU5WUywgKCkgPT4ge1xuICBpdCgnMUQgc3RhbmRhcmQnLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgcmVzID0gdGYudGVuc29yMWQoWzEsIDIsIDMsIDRdKS5jdW1wcm9kKCk7XG4gICAgZXhwZWN0KHJlcy5zaGFwZSkudG9FcXVhbChbNF0pO1xuICAgIGV4cGVjdEFycmF5c0Nsb3NlKGF3YWl0IHJlcy5kYXRhKCksIFsxLCAyLCA2LCAyNF0pO1xuICB9KTtcblxuICBpdCgnMUQgcmV2ZXJzZScsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCByZXZlcnNlID0gdHJ1ZTtcbiAgICBjb25zdCBleGNsdXNpdmUgPSBmYWxzZTtcbiAgICBjb25zdCByZXMgPSB0Zi50ZW5zb3IxZChbMSwgMiwgMywgNF0pLmN1bXByb2QoMCwgZXhjbHVzaXZlLCByZXZlcnNlKTtcbiAgICBleHBlY3QocmVzLnNoYXBlKS50b0VxdWFsKFs0XSk7XG4gICAgZXhwZWN0QXJyYXlzQ2xvc2UoYXdhaXQgcmVzLmRhdGEoKSwgWzI0LCAyNCwgMTIsIDRdKTtcbiAgfSk7XG5cbiAgaXQoJzFEIGV4Y2x1c2l2ZScsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBleGNsdXNpdmUgPSB0cnVlO1xuICAgIGNvbnN0IHJlcyA9IHRmLnRlbnNvcjFkKFsxLCAyLCAzLCA0XSkuY3VtcHJvZCgwLCBleGNsdXNpdmUpO1xuICAgIGV4cGVjdChyZXMuc2hhcGUpLnRvRXF1YWwoWzRdKTtcbiAgICBleHBlY3RBcnJheXNDbG9zZShhd2FpdCByZXMuZGF0YSgpLCBbMSwgMSwgMiwgNl0pO1xuICB9KTtcblxuICBpdCgnMUQgZXhjbHVzaXZlIHJldmVyc2UnLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgcmV2ZXJzZSA9IHRydWU7XG4gICAgY29uc3QgZXhjbHVzaXZlID0gdHJ1ZTtcbiAgICBjb25zdCByZXMgPSB0Zi50ZW5zb3IxZChbMSwgMiwgMywgNF0pLmN1bXByb2QoMCwgZXhjbHVzaXZlLCByZXZlcnNlKTtcbiAgICBleHBlY3QocmVzLnNoYXBlKS50b0VxdWFsKFs0XSk7XG4gICAgZXhwZWN0QXJyYXlzQ2xvc2UoYXdhaXQgcmVzLmRhdGEoKSwgWzI0LCAxMiwgNCwgMV0pO1xuICB9KTtcblxuICAvLyBUT0RPOiBvbmNlIGdyYWRpZW50cyBhcmUgaW1wbGVtZW50ZWQsIGNyZWF0ZSB0ZXN0cyBzb21ldGhpbmcgbGlrZSB0aGlzLlxuICAvLyBpdCgnZ3JhZGllbnQ6IDFEJywgYXN5bmMgKCkgPT4ge1xuICAvLyAgIGNvbnN0IGEgPSB0Zi50ZW5zb3IxZChbMSwgMiwgM10pO1xuICAvLyAgIGNvbnN0IGR5ID0gdGYudGVuc29yMWQoWzQsIDUsIDZdKTtcbiAgLy8gICBjb25zdCBkYSA9IHRmLmdyYWQoKHgpID0+IHRmLmN1bXByb2QoeCkpKGEsIGR5KTtcblxuICAvLyAgIGV4cGVjdChkYS5zaGFwZSkudG9FcXVhbChbM10pO1xuICAvLyAgIGV4cGVjdEFycmF5c0Nsb3NlKGF3YWl0IGRhLmRhdGEoKSwgWzE1LCAxMSwgNl0pO1xuICAvLyB9KTtcblxuICAvLyBpdCgnZ3JhZGllbnQgd2l0aCBjbG9uZXMnLCBhc3luYyAoKSA9PiB7XG4gIC8vICAgY29uc3QgYSA9IHRmLnRlbnNvcjFkKFsxLCAyLCAzXSk7XG4gIC8vICAgY29uc3QgZHkgPSB0Zi50ZW5zb3IxZChbNCwgNSwgNl0pO1xuICAvLyAgIGNvbnN0IGRhID0gdGYuZ3JhZCgoeCkgPT4gdGYuY3VtcHJvZCh4LmNsb25lKCkpLmNsb25lKCkpKGEsIGR5KTtcblxuICAvLyAgIGV4cGVjdChkYS5zaGFwZSkudG9FcXVhbChbM10pO1xuICAvLyAgIGV4cGVjdEFycmF5c0Nsb3NlKGF3YWl0IGRhLmRhdGEoKSwgWzE1LCAxMSwgNl0pO1xuICAvLyB9KTtcblxuICBpdCgnMkQgc3RhbmRhcmQnLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgcmVzID0gdGZcbiAgICAgIC50ZW5zb3IyZChbXG4gICAgICAgIFsxLCAyXSxcbiAgICAgICAgWzMsIDRdLFxuICAgICAgXSlcbiAgICAgIC5jdW1wcm9kKDEpO1xuICAgIGV4cGVjdChyZXMuc2hhcGUpLnRvRXF1YWwoWzIsIDJdKTtcbiAgICBleHBlY3RBcnJheXNDbG9zZShhd2FpdCByZXMuYXJyYXkoKSwgW1sxLCAyXSwgWzMsIDEyXV0pO1xuICB9KTtcblxuICBpdCgnMkQgcmV2ZXJzZSBleGNsdXNpdmUnLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgcmV2ZXJzZSA9IHRydWU7XG4gICAgY29uc3QgZXhjbHVzaXZlID0gdHJ1ZTtcbiAgICBjb25zdCByZXMgPSB0ZlxuICAgICAgLnRlbnNvcjJkKFtcbiAgICAgICAgWzEsIDJdLFxuICAgICAgICBbMywgNF0sXG4gICAgICBdKVxuICAgICAgLmN1bXByb2QoMSwgZXhjbHVzaXZlLCByZXZlcnNlKTtcbiAgICBleHBlY3QocmVzLnNoYXBlKS50b0VxdWFsKFsyLCAyXSk7XG4gICAgZXhwZWN0QXJyYXlzQ2xvc2UoYXdhaXQgcmVzLmFycmF5KCksIFtbMiwgMV0sIFs0LCAxXV0pO1xuICB9KTtcblxuICBpdCgnMkQgYXhpcz0wJywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IHJlcyA9IHRmXG4gICAgICAudGVuc29yMmQoW1xuICAgICAgICBbMSwgMl0sXG4gICAgICAgIFszLCA0XSxcbiAgICAgIF0pXG4gICAgICAuY3VtcHJvZCgpO1xuICAgIGV4cGVjdChyZXMuc2hhcGUpLnRvRXF1YWwoWzIsIDJdKTtcbiAgICBleHBlY3RBcnJheXNDbG9zZShhd2FpdCByZXMuYXJyYXkoKSwgW1sxLCAyXSwgWzMsIDhdXSk7XG4gIH0pO1xuXG4gIGl0KCczRCBzdGFuZGFyZCcsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCByZXMgPSB0ZlxuICAgICAgLnRlbnNvcjNkKFtcbiAgICAgICAgW1xuICAgICAgICAgIFswLCAxXSxcbiAgICAgICAgICBbMiwgM10sXG4gICAgICAgIF0sXG4gICAgICAgIFtcbiAgICAgICAgICBbNCwgNV0sXG4gICAgICAgICAgWzYsIDddLFxuICAgICAgICBdLFxuICAgICAgXSlcbiAgICAgIC5jdW1wcm9kKDIpO1xuICAgIGV4cGVjdChyZXMuc2hhcGUpLnRvRXF1YWwoWzIsIDIsIDJdKTtcbiAgICBleHBlY3RBcnJheXNDbG9zZShhd2FpdCByZXMuYXJyYXkoKSwgW1xuICAgICAgW1xuICAgICAgICBbMCwgMCAqIDFdLFxuICAgICAgICBbMiwgMiAqIDNdXG4gICAgICBdLFxuICAgICAgW1xuICAgICAgICBbNCwgNCAqIDVdLFxuICAgICAgICBbNiwgNiAqIDddXG4gICAgICBdXG4gICAgXSk7XG4gIH0pO1xuXG4gIGl0KCc0ZCBheGlzPTInLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgaW5wdXQgPSB0Zi5hZGQodGYub25lcyhbMSwgMzIsIDgsIDRdKSwgdGYub25lcyhbMSwgMzIsIDgsIDRdKSk7XG4gICAgY29uc3QgcmVzID0gdGYuY3VtcHJvZChpbnB1dCwgMiwgZmFsc2UsIGZhbHNlKTtcblxuICAgIGV4cGVjdChyZXMuc2hhcGUpLnRvRXF1YWwoWzEsIDMyLCA4LCA0XSk7XG5cbiAgICBjb25zdCBlYXJseVNsaWNlID0gdGYuc2xpY2UocmVzLCBbMCwgMCwgMCwgMF0sIFsxLCAxLCA4LCAxXSk7XG4gICAgY29uc3QgbGF0ZVNsaWNlID0gdGYuc2xpY2UocmVzLCBbMCwgMzEsIDAsIDBdLCBbMSwgMSwgOCwgMV0pO1xuICAgIGNvbnN0IGV4cGVjdGVkRGF0YUluRWFjaFNsaWNlID0gWzIsIDQsIDgsIDE2LCAzMiwgNjQsIDEyOCwgMjU2XTtcbiAgICBleHBlY3RBcnJheXNDbG9zZShhd2FpdCBlYXJseVNsaWNlLmRhdGEoKSwgZXhwZWN0ZWREYXRhSW5FYWNoU2xpY2UpO1xuICAgIGV4cGVjdEFycmF5c0Nsb3NlKGF3YWl0IGxhdGVTbGljZS5kYXRhKCksIGV4cGVjdGVkRGF0YUluRWFjaFNsaWNlKTtcbiAgfSk7XG5cbiAgaXQoJ2hhbmRsZSBwZXJtdXRhdGlvbiBwcm9wZXJseScsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCByZXMgPSB0Zi5vbmVzKFsxLCAyNDAsIDEsIDEwXSkuY3VtcHJvZCgxKTtcbiAgICBleHBlY3QocmVzLnNoYXBlKS50b0VxdWFsKFsxLCAyNDAsIDEsIDEwXSk7XG4gIH0pO1xuXG4gIGl0KCd0aHJvd3Mgd2hlbiBwYXNzZWQgYSBub24tdGVuc29yJywgKCkgPT4ge1xuICAgIGV4cGVjdCgoKSA9PiB0Zi5jdW1wcm9kKHt9IGFzIHRmLlRlbnNvcikpLnRvVGhyb3dFcnJvcihcbiAgICAgIC9Bcmd1bWVudCAneCcgcGFzc2VkIHRvICdjdW1wcm9kJyBtdXN0IGJlIGEgVGVuc29yL1xuICAgICk7XG4gIH0pO1xuXG4gIGl0KCdhY2NlcHRzIGEgdGVuc29yLWxpa2Ugb2JqZWN0JywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IHJlcyA9IHRmLmN1bXByb2QoWzEsIDIsIDMsIDRdKTtcbiAgICBleHBlY3QocmVzLnNoYXBlKS50b0VxdWFsKFs0XSk7XG4gICAgZXhwZWN0QXJyYXlzQ2xvc2UoYXdhaXQgcmVzLmRhdGEoKSwgWzEsIDIsIDYsIDI0XSk7XG4gIH0pO1xuXG4gIGl0KCd0aHJvd3MgZXJyb3IgZm9yIHN0cmluZyB0ZW5zb3InLCAoKSA9PiB7XG4gICAgZXhwZWN0KCgpID0+IHRmLmN1bXByb2QoWydhJywgJ2InLCAnYyddKSkudG9UaHJvd0Vycm9yKFxuICAgICAgL0FyZ3VtZW50ICd4JyBwYXNzZWQgdG8gJ2N1bXByb2QnIG11c3QgYmUgbnVtZXJpYyB0ZW5zb3IvXG4gICAgKTtcbiAgfSk7XG59KTtcbiJdfQ==