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
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
/**
 * @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('computeWeightedLoss', ALL_ENVS, () => {
    it('1D - no weights', async () => {
        const losses = tf.tensor1d([1, 2, 3]);
        const y = tf.losses.computeWeightedLoss(losses);
        expect(y.shape).toEqual([]);
        expectArraysClose(await y.data(), (1 + 2 + 3) / 3);
    });
    it('1D - no weights - Reduction.NONE', async () => {
        const losses = tf.tensor1d([1, 2, 3]);
        const y = tf.losses.computeWeightedLoss(losses, undefined, tf.Reduction.NONE);
        expect(y.shape).toEqual([3]);
        expectArraysClose(await y.data(), [1, 2, 3]);
    });
    it('1D - no weights - Reduction.MEAN', async () => {
        const losses = tf.tensor1d([1, 2, 3]);
        const y = tf.losses.computeWeightedLoss(losses, undefined, tf.Reduction.MEAN);
        expect(y.shape).toEqual([]);
        expectArraysClose(await y.data(), (1 + 2 + 3) / 3);
    });
    it('1D - no weights - Reduction.SUM', async () => {
        const losses = tf.tensor1d([1, 2, 3]);
        const y = tf.losses.computeWeightedLoss(losses, undefined, tf.Reduction.SUM);
        expect(y.shape).toEqual([]);
        expectArraysClose(await y.data(), (1 + 2 + 3));
    });
    it('1D - weights', async () => {
        const losses = tf.tensor1d([1, 2, 3]);
        const weights = tf.tensor1d([0.1, 0, 0.3]);
        const y = tf.losses.computeWeightedLoss(losses, weights);
        expect(y.shape).toEqual([]);
        expectArraysClose(await y.data(), (1 * 0.1 + 2 * 0 + 3 * 0.3) / 2);
    });
    it('2D - weights - broadcast', async () => {
        const losses = tf.tensor2d([[0, 0, 1], [1, 0, 0], [0, 1, 0]], [3, 3]);
        const weights = tf.tensor2d([[0.1, 0.2, 0.3]]);
        const y = tf.losses.computeWeightedLoss(losses, weights);
        expect(y.shape).toEqual([]);
        expectArraysClose(await y.data(), 0.06666667);
    });
    it('1D - weights - Reduction.NONE', async () => {
        const losses = tf.tensor1d([1, 2, 3]);
        const weights = tf.tensor1d([0.1, 0.2, 0.3]);
        const y = tf.losses.computeWeightedLoss(losses, weights, tf.Reduction.NONE);
        expect(y.shape).toEqual([3]);
        expectArraysClose(await y.data(), [1 * 0.1, 2 * 0.2, 3 * 0.3]);
    });
    it('1D - weights - Reduction.MEAN', async () => {
        const losses = tf.tensor1d([1, 2, 3]);
        const weights = tf.tensor1d([0.1, 0.2, 0.3]);
        const y = tf.losses.computeWeightedLoss(losses, weights, tf.Reduction.MEAN);
        expect(y.shape).toEqual([]);
        expectArraysClose(await y.data(), (1 * 0.1 + 2 * 0.2 + 3 * 0.3) / 0.6);
    });
    it('1D - weights - Reduction.SUM', async () => {
        const losses = tf.tensor1d([1, 2, 3]);
        const weights = tf.tensor1d([0.1, 0.2, 0.3]);
        const y = tf.losses.computeWeightedLoss(losses, weights, tf.Reduction.SUM);
        expect(y.shape).toEqual([]);
        expectArraysClose(await y.data(), (1 * 0.1 + 2 * 0.2 + 3 * 0.3));
    });
    it('2D - no weights', async () => {
        const losses = tf.tensor2d([4, 8, 12, 8, 1, 3], [2, 3]);
        const y = tf.losses.computeWeightedLoss(losses);
        expect(y.shape).toEqual([]);
        expectArraysClose(await y.data(), (4 + 8 + 12 + 8 + 1 + 3) / 6);
    });
    it('2D - weights', async () => {
        const losses = tf.tensor2d([4, 8, 12, 8, 1, 3], [2, 3]);
        const weights = tf.tensor2d([1, 0, 2, -5, 0, 6], [2, 3]);
        const y = tf.losses.computeWeightedLoss(losses, weights);
        expect(y.shape).toEqual([]);
        expectArraysClose(await y.data(), (4 * 1 + 8 * 0 + 12 * 2 + (8 * -5) + 1 * 0 + 3 * 6) / 4);
    });
    it('2D - no weights - Reduction.MEAN', async () => {
        const losses = tf.tensor2d([4, 8, 12, 8, 1, 3], [2, 3]);
        const y = tf.losses.computeWeightedLoss(losses, undefined, tf.Reduction.MEAN);
        expect(y.shape).toEqual([]);
        expectArraysClose(await y.data(), (4 + 8 + 12 + 8 + 1 + 3) / 6);
    });
    it('2D - weights - Reduction.MEAN', async () => {
        const losses = tf.tensor2d([4, 8, 12, 8, 1, 3], [2, 3]);
        const weights = tf.tensor2d([1, 0, 2, -5, 0, 6], [2, 3]);
        const y = tf.losses.computeWeightedLoss(losses, weights, tf.Reduction.MEAN);
        expect(y.shape).toEqual([]);
        expectArraysClose(await y.data(), (4 * 1 + 8 * 0 + 12 * 2 + (8 * -5) + 1 * 0 + 3 * 6) / 4);
    });
    it('2D - weights - broadcast - MEAN', async () => {
        const losses = tf.tensor2d([[0, 0, 1], [1, 0, 0], [0, 1, 0]], [3, 3]);
        const weights = tf.tensor2d([[0.1, 0.2, 0.3]]);
        const y = tf.losses.computeWeightedLoss(losses, weights, tf.Reduction.MEAN);
        expect(y.shape).toEqual([]);
        expectArraysClose(await y.data(), (0.3 + 0.1 + 0.2) / (3 * 0.6));
    });
    it('2D - no weights - Reduction.SUM', async () => {
        const losses = tf.tensor2d([4, 8, 12, 8, 1, 3], [2, 3]);
        const y = tf.losses.computeWeightedLoss(losses, undefined, tf.Reduction.SUM);
        expect(y.shape).toEqual([]);
        expectArraysClose(await y.data(), (4 + 8 + 12 + 8 + 1 + 3));
    });
    it('2D - weights - Reduction.SUM', async () => {
        const losses = tf.tensor2d([4, 8, 12, 8, 1, 3], [2, 3]);
        const weights = tf.tensor2d([1, 0, 2, -5, 0, 6], [2, 3]);
        const y = tf.losses.computeWeightedLoss(losses, weights, tf.Reduction.SUM);
        expect(y.shape).toEqual([]);
        expectArraysClose(await y.data(), (4 * 1 + 8 * 0 + 12 * 2 + (8 * -5) + 1 * 0 + 3 * 6));
    });
    it('2D - no weights - Reduction.NONE', async () => {
        const losses = tf.tensor2d([4, 8, 12, 8, 1, 3], [2, 3]);
        const y = tf.losses.computeWeightedLoss(losses, undefined, tf.Reduction.NONE);
        expect(y.shape).toEqual([2, 3]);
        expectArraysClose(await y.data(), [4, 8, 12, 8, 1, 3]);
    });
    it('2D - weights - Reduction.NONE', async () => {
        const losses = tf.tensor2d([4, 8, 12, 8, 1, 3], [2, 3]);
        const weights = tf.tensor2d([1, 0, 2, -5, 0, 6], [2, 3]);
        const y = tf.losses.computeWeightedLoss(losses, weights, tf.Reduction.NONE);
        expect(y.shape).toEqual([2, 3]);
        expectArraysClose(await y.data(), [4 * 1, 8 * 0, 12 * 2, (8 * -5), 1 * 0, 3 * 6]);
    });
    it('throws when passed losses as a non-tensor', () => {
        const weights = tf.tensor2d([1, 0, 2, -5, 0, 6], [2, 3]);
        const e = /Argument 'losses' passed to 'computeWeightedLoss' must be a Tensor/;
        expect(() => tf.losses.computeWeightedLoss({}, weights, tf.Reduction.NONE))
            .toThrowError(e);
    });
    it('throws when passed weights as a non-tensor', () => {
        const losses = tf.tensor2d([4, 8, 12, 8, 1, 3], [2, 3]);
        const e = /Argument 'weights' passed to 'computeWeightedLoss' must be a Tensor/;
        expect(() => tf.losses.computeWeightedLoss(losses, {}, tf.Reduction.NONE))
            .toThrowError(e);
    });
    it('accepts a tensor-like object', async () => {
        const losses = [1, 2, 3];
        const weights = [0.1, 0, 0.3];
        const y = tf.losses.computeWeightedLoss(losses, weights);
        expect(y.shape).toEqual([]);
        expectArraysClose(await y.data(), (1 * 0.1 + 2 * 0 + 3 * 0.3) / 2);
    });
});
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29tcHV0ZV93ZWlnaHRlZF9sb3NzX3Rlc3QuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi90ZmpzLWNvcmUvc3JjL29wcy9sb3NzZXMvY29tcHV0ZV93ZWlnaHRlZF9sb3NzX3Rlc3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7Ozs7Ozs7OztHQWVHO0FBRUgsT0FBTyxLQUFLLEVBQUUsTUFBTSxhQUFhLENBQUM7QUFDbEMsT0FBTyxFQUFDLFFBQVEsRUFBRSxpQkFBaUIsRUFBQyxNQUFNLG9CQUFvQixDQUFDO0FBQy9ELE9BQU8sRUFBQyxpQkFBaUIsRUFBQyxNQUFNLGlCQUFpQixDQUFDO0FBRWxELGlCQUFpQixDQUFDLHFCQUFxQixFQUFFLFFBQVEsRUFBRSxHQUFHLEVBQUU7SUFDdEQsRUFBRSxDQUFDLGlCQUFpQixFQUFFLEtBQUssSUFBSSxFQUFFO1FBQy9CLE1BQU0sTUFBTSxHQUFHLEVBQUUsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFFdEMsTUFBTSxDQUFDLEdBQUcsRUFBRSxDQUFDLE1BQU0sQ0FBQyxtQkFBbUIsQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUVoRCxNQUFNLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUMsQ0FBQztRQUM1QixpQkFBaUIsQ0FBQyxNQUFNLENBQUMsQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7SUFDckQsQ0FBQyxDQUFDLENBQUM7SUFFSCxFQUFFLENBQUMsa0NBQWtDLEVBQUUsS0FBSyxJQUFJLEVBQUU7UUFDaEQsTUFBTSxNQUFNLEdBQUcsRUFBRSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUV0QyxNQUFNLENBQUMsR0FDSCxFQUFFLENBQUMsTUFBTSxDQUFDLG1CQUFtQixDQUFDLE1BQU0sRUFBRSxTQUFTLEVBQUUsRUFBRSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUV4RSxNQUFNLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDN0IsaUJBQWlCLENBQUMsTUFBTSxDQUFDLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDL0MsQ0FBQyxDQUFDLENBQUM7SUFFSCxFQUFFLENBQUMsa0NBQWtDLEVBQUUsS0FBSyxJQUFJLEVBQUU7UUFDaEQsTUFBTSxNQUFNLEdBQUcsRUFBRSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUV0QyxNQUFNLENBQUMsR0FDSCxFQUFFLENBQUMsTUFBTSxDQUFDLG1CQUFtQixDQUFDLE1BQU0sRUFBRSxTQUFTLEVBQUUsRUFBRSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUV4RSxNQUFNLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUMsQ0FBQztRQUM1QixpQkFBaUIsQ0FBQyxNQUFNLENBQUMsQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7SUFDckQsQ0FBQyxDQUFDLENBQUM7SUFFSCxFQUFFLENBQUMsaUNBQWlDLEVBQUUsS0FBSyxJQUFJLEVBQUU7UUFDL0MsTUFBTSxNQUFNLEdBQUcsRUFBRSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUV0QyxNQUFNLENBQUMsR0FDSCxFQUFFLENBQUMsTUFBTSxDQUFDLG1C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TUFBTSxNQUFNLEdBQUcsRUFBRSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRSxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUV4RCxNQUFNLENBQUMsR0FDSCxxRUFBcUUsQ0FBQztRQUMxRSxNQUFNLENBQ0YsR0FBRyxFQUFFLENBQUMsRUFBRSxDQUFDLE1BQU0sQ0FBQyxtQkFBbUIsQ0FDL0IsTUFBTSxFQUFFLEVBQWUsRUFBRSxFQUFFLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxDQUFDO2FBQy9DLFlBQVksQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUN2QixDQUFDLENBQUMsQ0FBQztJQUVILEVBQUUsQ0FBQyw4QkFBOEIsRUFBRSxLQUFLLElBQUksRUFBRTtRQUM1QyxNQUFNLE1BQU0sR0FBRyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7UUFDekIsTUFBTSxPQUFPLEdBQUcsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDO1FBQzlCLE1BQU0sQ0FBQyxHQUFHLEVBQUUsQ0FBQyxNQUFNLENBQUMsbUJBQW1CLENBQUMsTUFBTSxFQUFFLE9BQU8sQ0FBQyxDQUFDO1FBRXpELE1BQU0sQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQyxDQUFDO1FBQzVCLGlCQUFpQixDQUFDLE1BQU0sQ0FBQyxDQUFDLElBQUksRUFBRSxFQUFFLENBQUMsQ0FBQyxHQUFHLEdBQUcsR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsR0FBRyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztJQUNyRSxDQUFDLENBQUMsQ0FBQztBQUNMLENBQUMsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBAbGljZW5zZVxuICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAqL1xuXG5pbXBvcnQgKiBhcyB0ZiBmcm9tICcuLi8uLi9pbmRleCc7XG5pbXBvcnQge0FMTF9FTlZTLCBkZXNjcmliZVdpdGhGbGFnc30gZnJvbSAnLi4vLi4vamFzbWluZV91dGlsJztcbmltcG9ydCB7ZXhwZWN0QXJyYXlzQ2xvc2V9IGZyb20gJy4uLy4uL3Rlc3RfdXRpbCc7XG5cbmRlc2NyaWJlV2l0aEZsYWdzKCdjb21wdXRlV2VpZ2h0ZWRMb3NzJywgQUxMX0VOVlMsICgpID0+IHtcbiAgaXQoJzFEIC0gbm8gd2VpZ2h0cycsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBsb3NzZXMgPSB0Zi50ZW5zb3IxZChbMSwgMiwgM10pO1xuXG4gICAgY29uc3QgeSA9IHRmLmxvc3Nlcy5jb21wdXRlV2VpZ2h0ZWRMb3NzKGxvc3Nlcyk7XG5cbiAgICBleHBlY3QoeS5zaGFwZSkudG9FcXVhbChbXSk7XG4gICAgZXhwZWN0QXJyYXlzQ2xvc2UoYXdhaXQgeS5kYXRhKCksICgxICsgMiArIDMpIC8gMyk7XG4gIH0pO1xuXG4gIGl0KCcxRCAtIG5vIHdlaWdodHMgLSBSZWR1Y3Rpb24uTk9ORScsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBsb3NzZXMgPSB0Zi50ZW5zb3IxZChbMSwgMiwgM10pO1xuXG4gICAgY29uc3QgeSA9XG4gICAgICAgIHRmLmxvc3Nlcy5jb21wdXRlV2VpZ2h0ZWRMb3NzKGxvc3NlcywgdW5kZWZpbmVkLCB0Zi5SZWR1Y3Rpb24uTk9ORSk7XG5cbiAgICBleHBlY3QoeS5zaGFwZSkudG9FcXVhbChbM10pO1xuICAgIGV4cGVjdEFycmF5c0Nsb3NlKGF3YWl0IHkuZGF0YSgpLCBbMSwgMiwgM10pO1xuICB9KTtcblxuICBpdCgnMUQgLSBubyB3ZWlnaHRzIC0gUmVkdWN0aW9uLk1FQU4nLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgbG9zc2VzID0gdGYudGVuc29yMWQoWzEsIDIsIDNdKTtcblxuICAgIGNvbnN0IHkgPVxuICAgICAgICB0Zi5sb3NzZXMuY29tcHV0ZVdlaWdodGVkTG9zcyhsb3NzZXMsIHVuZGVmaW5lZCwgdGYuUmVkdWN0aW9uLk1FQU4pO1xuXG4gICAgZXhwZWN0KHkuc2hhcGUpLnRvRXF1YWwoW10pO1xuICAgIGV4cGVjdEFycmF5c0Nsb3NlKGF3YWl0IHkuZGF0YSgpLCAoMSArIDIgKyAzKSAvIDMpO1xuICB9KTtcblxuICBpdCgnMUQgLSBubyB3ZWlnaHRzIC0gUmVkdWN0aW9uLlNVTScsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBsb3NzZXMgPSB0Zi50ZW5zb3IxZChbMSwgMiwgM10pO1xuXG4gICAgY29uc3QgeSA9XG4gICAgICAgIHRmLmxvc3Nlcy5jb21wdXRlV2VpZ2h0ZWRMb3NzKGxvc3NlcywgdW5kZWZpbmVkLCB0Zi5SZWR1Y3Rpb24uU1VNKTtcblxuICAgIGV4cGVjdCh5LnNoYXBlKS50b0VxdWFsKFtdKTtcbiAgICBleHBlY3RBcnJheXNDbG9zZShhd2FpdCB5LmRhdGEoKSwgKDEgKyAyICsgMykpO1xuICB9KTtcblxuICBpdCgnMUQgLSB3ZWlnaHRzJywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IGxvc3NlcyA9IHRmLnRlbnNvcjFkKFsxLCAyLCAzXSk7XG4gICAgY29uc3Qgd2VpZ2h0cyA9IHRmLnRlbnNvcjFkKFswLjEsIDAsIDAuM10pO1xuXG4gICAgY29uc3QgeSA9IHRmLmxvc3Nlcy5jb21wdXRlV2VpZ2h0ZWRMb3NzKGxvc3Nlcywgd2VpZ2h0cyk7XG5cbiAgICBleHBlY3QoeS5zaGFwZSkudG9FcXVhbChbXSk7XG4gICAgZXhwZWN0QXJyYXlzQ2xvc2UoYXdhaXQgeS5kYXRhKCksICgxICogMC4xICsgMiAqIDAgKyAzICogMC4zKSAvIDIpO1xuICB9KTtcblxuICBpdCgnMkQgLSB3ZWlnaHRzIC0gYnJvYWRjYXN0JywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IGxvc3NlcyA9IHRmLnRlbnNvcjJkKFtbMCwgMCwgMV0sIFsxLCAwLCAwXSwgWzAsIDEsIDBdXSwgWzMsIDNdKTtcbiAgICBjb25zdCB3ZWlnaHRzID0gdGYudGVuc29yMmQoW1swLjEsIDAuMiwgMC4zXV0pO1xuXG4gICAgY29uc3QgeSA9IHRmLmxvc3Nlcy5jb21wdXRlV2VpZ2h0ZWRMb3NzKGxvc3Nlcywgd2VpZ2h0cyk7XG5cbiAgICBleHBlY3QoeS5zaGFwZSkudG9FcXVhbChbXSk7XG4gICAgZXhwZWN0QXJyYXlzQ2xvc2UoYXdhaXQgeS5kYXRhKCksIDAuMDY2NjY2NjcpO1xuICB9KTtcblxuICBpdCgnMUQgLSB3ZWlnaHRzIC0gUmVkdWN0aW9uLk5PTkUnLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgbG9zc2VzID0gdGYudGVuc29yMWQoWzEsIDIsIDNdKTtcbiAgICBjb25zdCB3ZWlnaHRzID0gdGYudGVuc29yMWQoWzAuMSwgMC4yLCAwLjNdKTtcblxuICAgIGNvbnN0IHkgPSB0Zi5sb3NzZXMuY29tcHV0ZVdlaWdodGVkTG9zcyhsb3NzZXMsIHdlaWdodHMsIHRmLlJlZHVjdGlvbi5OT05FKTtcblxuICAgIGV4cGVjdCh5LnNoYXBlKS50b0VxdWFsKFszXSk7XG4gICAgZXhwZWN0QXJyYXlzQ2xvc2UoYXdhaXQgeS5kYXRhKCksIFsxICogMC4xLCAyICogMC4yLCAzICogMC4zXSk7XG4gIH0pO1xuXG4gIGl0KCcxRCAtIHdlaWdodHMgLSBSZWR1Y3Rpb24uTUVBTicsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBsb3NzZXMgPSB0Zi50ZW5zb3IxZChbMSwgMiwgM10pO1xuICAgIGNvbnN0IHdlaWdodHMgPSB0Zi50ZW5zb3IxZChbMC4xLCAwLjIsIDAuM10pO1xuXG4gICAgY29uc3QgeSA9IHRmLmxvc3Nlcy5jb21wdXRlV2VpZ2h0ZWRMb3NzKGxvc3Nlcywgd2VpZ2h0cywgdGYuUmVkdWN0aW9uLk1FQU4pO1xuXG4gICAgZXhwZWN0KHkuc2hhcGUpLnRvRXF1YWwoW10pO1xuICAgIGV4cGVjdEFycmF5c0Nsb3NlKGF3YWl0IHkuZGF0YSgpLCAoMSAqIDAuMSArIDIgKiAwLjIgKyAzICogMC4zKSAvIDAuNik7XG4gIH0pO1xuXG4gIGl0KCcxRCAtIHdlaWdodHMgLSBSZWR1Y3Rpb24uU1VNJywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IGxvc3NlcyA9IHRmLnRlbnNvcjFkKFsxLCAyLCAzXSk7XG4gICAgY29uc3Qgd2VpZ2h0cyA9IHRmLnRlbnNvcjFkKFswLjEsIDAuMiwgMC4zXSk7XG5cbiAgICBjb25zdCB5ID0gdGYubG9zc2VzLmNvbXB1dGVXZWlnaHRlZExvc3MobG9zc2VzLCB3ZWlnaHRzLCB0Zi5SZWR1Y3Rpb24uU1VNKTtcblxuICAgIGV4cGVjdCh5LnNoYXBlKS50b0VxdWFsKFtdKTtcbiAgICBleHBlY3RBcnJheXNDbG9zZShhd2FpdCB5LmRhdGEoKSwgKDEgKiAwLjEgKyAyICogMC4yICsgMyAqIDAuMykpO1xuICB9KTtcblxuICBpdCgnMkQgLSBubyB3ZWlnaHRzJywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IGxvc3NlcyA9IHRmLnRlbnNvcjJkKFs0LCA4LCAxMiwgOCwgMSwgM10sIFsyLCAzXSk7XG5cbiAgICBjb25zdCB5ID0gdGYubG9zc2VzLmNvbXB1dGVXZWlnaHRlZExvc3MobG9zc2VzKTtcblxuICAgIGV4cGVjdCh5LnNoYXBlKS50b0VxdWFsKFtdKTtcbiAgICBleHBlY3RBcnJheXNDbG9zZShhd2FpdCB5LmRhdGEoKSwgKDQgKyA4ICsgMTIgKyA4ICsgMSArIDMpIC8gNik7XG4gIH0pO1xuXG4gIGl0KCcyRCAtIHdlaWdodHMnLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgbG9zc2VzID0gdGYudGVuc29yMmQoWzQsIDgsIDEyLCA4LCAxLCAzXSwgWzIsIDNdKTtcbiAgICBjb25zdCB3ZWlnaHRzID0gdGYudGVuc29yMmQoWzEsIDAsIDIsIC01LCAwLCA2XSwgWzIsIDNdKTtcblxuICAgIGNvbnN0IHkgPSB0Zi5sb3NzZXMuY29tcHV0ZVdlaWdodGVkTG9zcyhsb3NzZXMsIHdlaWdodHMpO1xuXG4gICAgZXhwZWN0KHkuc2hhcGUpLnRvRXF1YWwoW10pO1xuICAgIGV4cGVjdEFycmF5c0Nsb3NlKFxuICAgICAgICBhd2FpdCB5LmRhdGEoKSxcbiAgICAgICAgKDQgKiAxICsgOCAqIDAgKyAxMiAqIDIgKyAoOCAqIC01KSArIDEgKiAwICsgMyAqIDYpIC8gNCk7XG4gIH0pO1xuXG4gIGl0KCcyRCAtIG5vIHdlaWdodHMgLSBSZWR1Y3Rpb24uTUVBTicsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBsb3NzZXMgPSB0Zi50ZW5zb3IyZChbNCwgOCwgMTIsIDgsIDEsIDNdLCBbMiwgM10pO1xuXG4gICAgY29uc3QgeSA9XG4gICAgICAgIHRmLmxvc3Nlcy5jb21wdXRlV2VpZ2h0ZWRMb3NzKGxvc3NlcywgdW5kZWZpbmVkLCB0Zi5SZWR1Y3Rpb24uTUVBTik7XG5cbiAgICBleHBlY3QoeS5zaGFwZSkudG9FcXVhbChbXSk7XG4gICAgZXhwZWN0QXJyYXlzQ2xvc2UoYXdhaXQgeS5kYXRhKCksICg0ICsgOCArIDEyICsgOCArIDEgKyAzKSAvIDYpO1xuICB9KTtcblxuICBpdCgnMkQgLSB3ZWlnaHRzIC0gUmVkdWN0aW9uLk1FQU4nLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgbG9zc2VzID0gdGYudGVuc29yMmQoWzQsIDgsIDEyLCA4LCAxLCAzXSwgWzIsIDNdKTtcbiAgICBjb25zdCB3ZWlnaHRzID0gdGYudGVuc29yMmQoWzEsIDAsIDIsIC01LCAwLCA2XSwgWzIsIDNdKTtcblxuICAgIGNvbnN0IHkgPSB0Zi5sb3NzZXMuY29tcHV0ZVdlaWdodGVkTG9zcyhsb3NzZXMsIHdlaWdodHMsIHRmLlJlZHVjdGlvbi5NRUFOKTtcblxuICAgIGV4cGVjdCh5LnNoYXBlKS50b0VxdWFsKFtdKTtcbiAgICBleHBlY3RBcnJheXNDbG9zZShcbiAgICAgICAgYXdhaXQgeS5kYXRhKCksXG4gICAgICAgICg0ICogMSArIDggKiAwICsgMTIgKiAyICsgKDggKiAtNSkgKyAxICogMCArIDMgKiA2KSAvIDQpO1xuICB9KTtcblxuICBpdCgnMkQgLSB3ZWlnaHRzIC0gYnJvYWRjYXN0IC0gTUVBTicsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBsb3NzZXMgPSB0Zi50ZW5zb3IyZChbWzAsIDAsIDFdLCBbMSwgMCwgMF0sIFswLCAxLCAwXV0sIFszLCAzXSk7XG4gICAgY29uc3Qgd2VpZ2h0cyA9IHRmLnRlbnNvcjJkKFtbMC4xLCAwLjIsIDAuM11dKTtcblxuICAgIGNvbnN0IHkgPSB0Zi5sb3NzZXMuY29tcHV0ZVdlaWdodGVkTG9zcyhsb3NzZXMsIHdlaWdodHMsIHRmLlJlZHVjdGlvbi5NRUFOKTtcblxuICAgIGV4cGVjdCh5LnNoYXBlKS50b0VxdWFsKFtdKTtcbiAgICBleHBlY3RBcnJheXNDbG9zZShhd2FpdCB5LmRhdGEoKSwgKDAuMyArIDAuMSArIDAuMikgLyAoMyAqIDAuNikpO1xuICB9KTtcblxuICBpdCgnMkQgLSBubyB3ZWlnaHRzIC0gUmVkdWN0aW9uLlNVTScsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBsb3NzZXMgPSB0Zi50ZW5zb3IyZChbNCwgOCwgMTIsIDgsIDEsIDNdLCBbMiwgM10pO1xuXG4gICAgY29uc3QgeSA9XG4gICAgICAgIHRmLmxvc3Nlcy5jb21wdXRlV2VpZ2h0ZWRMb3NzKGxvc3NlcywgdW5kZWZpbmVkLCB0Zi5SZWR1Y3Rpb24uU1VNKTtcblxuICAgIGV4cGVjdCh5LnNoYXBlKS50b0VxdWFsKFtdKTtcbiAgICBleHBlY3RBcnJheXNDbG9zZShhd2FpdCB5LmRhdGEoKSwgKDQgKyA4ICsgMTIgKyA4ICsgMSArIDMpKTtcbiAgfSk7XG5cbiAgaXQoJzJEIC0gd2VpZ2h0cyAtIFJlZHVjdGlvbi5TVU0nLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgbG9zc2VzID0gdGYudGVuc29yMmQoWzQsIDgsIDEyLCA4LCAxLCAzXSwgWzIsIDNdKTtcbiAgICBjb25zdCB3ZWlnaHRzID0gdGYudGVuc29yMmQoWzEsIDAsIDIsIC01LCAwLCA2XSwgWzIsIDNdKTtcblxuICAgIGNvbnN0IHkgPSB0Zi5sb3NzZXMuY29tcHV0ZVdlaWdodGVkTG9zcyhsb3NzZXMsIHdlaWdodHMsIHRmLlJlZHVjdGlvbi5TVU0pO1xuXG4gICAgZXhwZWN0KHkuc2hhcGUpLnRvRXF1YWwoW10pO1xuICAgIGV4cGVjdEFycmF5c0Nsb3NlKFxuICAgICAgICBhd2FpdCB5LmRhdGEoKSwgKDQgKiAxICsgOCAqIDAgKyAxMiAqIDIgKyAoOCAqIC01KSArIDEgKiAwICsgMyAqIDYpKTtcbiAgfSk7XG5cbiAgaXQoJzJEIC0gbm8gd2VpZ2h0cyAtIFJlZHVjdGlvbi5OT05FJywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IGxvc3NlcyA9IHRmLnRlbnNvcjJkKFs0LCA4LCAxMiwgOCwgMSwgM10sIFsyLCAzXSk7XG5cbiAgICBjb25zdCB5ID1cbiAgICAgICAgdGYubG9zc2VzLmNvbXB1dGVXZWlnaHRlZExvc3MobG9zc2VzLCB1bmRlZmluZWQsIHRmLlJlZHVjdGlvbi5OT05FKTtcblxuICAgIGV4cGVjdCh5LnNoYXBlKS50b0VxdWFsKFsyLCAzXSk7XG4gICAgZXhwZWN0QXJyYXlzQ2xvc2UoYXdhaXQgeS5kYXRhKCksIFs0LCA4LCAxMiwgOCwgMSwgM10pO1xuICB9KTtcblxuICBpdCgnMkQgLSB3ZWlnaHRzIC0gUmVkdWN0aW9uLk5PTkUnLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgbG9zc2VzID0gdGYudGVuc29yMmQoWzQsIDgsIDEyLCA4LCAxLCAzXSwgWzIsIDNdKTtcbiAgICBjb25zdCB3ZWlnaHRzID0gdGYudGVuc29yMmQoWzEsIDAsIDIsIC01LCAwLCA2XSwgWzIsIDNdKTtcblxuICAgIGNvbnN0IHkgPSB0Zi5sb3NzZXMuY29tcHV0ZVdlaWdodGVkTG9zcyhsb3NzZXMsIHdlaWdodHMsIHRmLlJlZHVjdGlvbi5OT05FKTtcblxuICAgIGV4cGVjdCh5LnNoYXBlKS50b0VxdWFsKFsyLCAzXSk7XG4gICAgZXhwZWN0QXJyYXlzQ2xvc2UoXG4gICAgICAgIGF3YWl0IHkuZGF0YSgpLCBbNCAqIDEsIDggKiAwLCAxMiAqIDIsICg4ICogLTUpLCAxICogMCwgMyAqIDZdKTtcbiAgfSk7XG5cbiAgaXQoJ3Rocm93cyB3aGVuIHBhc3NlZCBsb3NzZXMgYXMgYSBub24tdGVuc29yJywgKCkgPT4ge1xuICAgIGNvbnN0IHdlaWdodHMgPSB0Zi50ZW5zb3IyZChbMSwgMCwgMiwgLTUsIDAsIDZdLCBbMiwgM10pO1xuXG4gICAgY29uc3QgZSA9XG4gICAgICAgIC9Bcmd1bWVudCAnbG9zc2VzJyBwYXNzZWQgdG8gJ2NvbXB1dGVXZWlnaHRlZExvc3MnIG11c3QgYmUgYSBUZW5zb3IvO1xuICAgIGV4cGVjdChcbiAgICAgICAgKCkgPT4gdGYubG9zc2VzLmNvbXB1dGVXZWlnaHRlZExvc3MoXG4gICAgICAgICAgICB7fSBhcyB0Zi5UZW5zb3IsIHdlaWdodHMsIHRmLlJlZHVjdGlvbi5OT05FKSlcbiAgICAgICAgLnRvVGhyb3dFcnJvcihlKTtcbiAgfSk7XG5cbiAgaXQoJ3Rocm93cyB3aGVuIHBhc3NlZCB3ZWlnaHRzIGFzIGEgbm9uLXRlbnNvcicsICgpID0+IHtcbiAgICBjb25zdCBsb3NzZXMgPSB0Zi50ZW5zb3IyZChbNCwgOCwgMTIsIDgsIDEsIDNdLCBbMiwgM10pO1xuXG4gICAgY29uc3QgZSA9XG4gICAgICAgIC9Bcmd1bWVudCAnd2VpZ2h0cycgcGFzc2VkIHRvICdjb21wdXRlV2VpZ2h0ZWRMb3NzJyBtdXN0IGJlIGEgVGVuc29yLztcbiAgICBleHBlY3QoXG4gICAgICAgICgpID0+IHRmLmxvc3Nlcy5jb21wdXRlV2VpZ2h0ZWRMb3NzKFxuICAgICAgICAgICAgbG9zc2VzLCB7fSBhcyB0Zi5UZW5zb3IsIHRmLlJlZHVjdGlvbi5OT05FKSlcbiAgICAgICAgLnRvVGhyb3dFcnJvcihlKTtcbiAgfSk7XG5cbiAgaXQoJ2FjY2VwdHMgYSB0ZW5zb3ItbGlrZSBvYmplY3QnLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgbG9zc2VzID0gWzEsIDIsIDNdO1xuICAgIGNvbnN0IHdlaWdodHMgPSBbMC4xLCAwLCAwLjNdO1xuICAgIGNvbnN0IHkgPSB0Zi5sb3NzZXMuY29tcHV0ZVdlaWdodGVkTG9zcyhsb3NzZXMsIHdlaWdodHMpO1xuXG4gICAgZXhwZWN0KHkuc2hhcGUpLnRvRXF1YWwoW10pO1xuICAgIGV4cGVjdEFycmF5c0Nsb3NlKGF3YWl0IHkuZGF0YSgpLCAoMSAqIDAuMSArIDIgKiAwICsgMyAqIDAuMykgLyAyKTtcbiAgfSk7XG59KTtcbiJdfQ==