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
| /**
| * @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('huberLoss', ALL_ENVS, () => {
| it('1D', async () => {
| const labels = tf.tensor1d([1, 2, 3]);
| const predictions = tf.tensor1d([0.3, 0.6, 0.1]);
| const y = tf.losses.huberLoss(labels, predictions);
| expect(y.shape).toEqual([]);
| expectArraysClose(await y.data(), 1.1816667);
| });
| it('1D - delta', async () => {
| const labels = tf.tensor1d([1, 2, 3]);
| const predictions = tf.tensor1d([0.3, 0.6, 0.1]);
| const delta = 0.4;
| const y = tf.losses.huberLoss(labels, predictions, undefined, delta);
| expect(y.shape).toEqual([]);
| expectArraysClose(await y.data(), 0.58666664);
| });
| it('1D - weighted - Reduction.SUM_BY_NONZERO_WEIGHTS', async () => {
| const labels = tf.tensor1d([1, 2, 3]);
| const predictions = tf.tensor1d([0.3, 0.6, 0.1]);
| const weights = tf.tensor1d([0.1, 0.2, 0.3]);
| const y = tf.losses.huberLoss(labels, predictions, weights);
| expect(y.shape).toEqual([]);
| expectArraysClose(await y.data(), 0.30816665);
| });
| it('1D - weighted - Reduction.NONE', async () => {
| const labels = tf.tensor1d([1, 2, 3]);
| const predictions = tf.tensor1d([0.3, 0.6, 0.1]);
| const weights = tf.tensor1d([0.1, 0.2, 0.3]);
| const y = tf.losses.huberLoss(labels, predictions, weights, undefined, tf.Reduction.NONE);
| expect(y.shape).toEqual([3]);
| expectArraysClose(await y.data(), [0.0245, 0.17999999, 0.72]);
| });
| it('1D - Reduction.MEAN', async () => {
| const labels = tf.tensor1d([1, 2, 3]);
| const predictions = tf.tensor1d([0.3, 0.6, 0.1]);
| const y = tf.losses.huberLoss(labels, predictions, undefined, undefined, tf.Reduction.MEAN);
| expect(y.shape).toEqual([]);
| expectArraysClose(await y.data(), 1.1816667);
| });
| it('1D - weighted - Reduction.MEAN', async () => {
| const labels = tf.tensor1d([1, 2, 3]);
| const predictions = tf.tensor1d([0.3, 0.6, 0.1]);
| const weights = tf.tensor1d([0.1, 0.2, 0.3]);
| const y = tf.losses.huberLoss(labels, predictions, weights, undefined, tf.Reduction.MEAN);
| expect(y.shape).toEqual([]);
| expectArraysClose(await y.data(), 1.5408332);
| });
| it('2D', async () => {
| const labels = tf.tensor2d([0.4, 0.8, 0.12, 0.8, 0.1, 0.3], [2, 3]);
| const predictions = tf.tensor2d([0.1, 0.7, 0.1, 0.5, 0.05, 0.15], [2, 3]);
| const y = tf.losses.huberLoss(labels, predictions);
| expect(y.shape).toEqual([]);
| expectArraysClose(await y.data(), 0.01795);
| });
| it('2D - weighted - Reduction.SUM_BY_NONZERO_WEIGHTS', async () => {
| const labels = tf.tensor2d([0.4, 0.8, 0.12, 0.8, 0.1, 0.3], [2, 3]);
| const predictions = tf.tensor2d([0.1, 0.7, 0.1, 0.5, 0.05, 0.15], [2, 3]);
| const weights = tf.tensor2d([3, 0, 5, 0, 4, 2], [2, 3]);
| const y = tf.losses.huberLoss(labels, predictions, weights);
| expect(y.shape).toEqual([]);
| expectArraysClose(await y.data(), 0.040875003);
| });
| it('2D - weighted - Reduction.NONE', async () => {
| const labels = tf.tensor2d([0.4, 0.8, 0.12, 0.8, 0.1, 0.3], [2, 3]);
| const predictions = tf.tensor2d([0.1, 0.7, 0.1, 0.5, 0.05, 0.15], [2, 3]);
| const weights = tf.tensor2d([3, 0, 5, 0, 4, 2], [2, 3]);
| const y = tf.losses.huberLoss(labels, predictions, weights, undefined, tf.Reduction.NONE);
| expect(y.shape).toEqual([2, 3]);
| expectArraysClose(await y.data(), [0.135, 0., 0.001, 0., 0.005, 0.0225]);
| });
| it('2D - Reduction.MEAN', async () => {
| const labels = tf.tensor2d([0.4, 0.8, 0.12, 0.8, 0.1, 0.3], [2, 3]);
| const predictions = tf.tensor2d([0.1, 0.7, 0.1, 0.5, 0.05, 0.15], [2, 3]);
| const y = tf.losses.huberLoss(labels, predictions, undefined, undefined, tf.Reduction.MEAN);
| expect(y.shape).toEqual([]);
| expectArraysClose(await y.data(), 0.01795);
| });
| it('2D - weighted - Reduction.MEAN', async () => {
| const labels = tf.tensor2d([0.4, 0.8, 0.12, 0.8, 0.1, 0.3], [2, 3]);
| const predictions = tf.tensor2d([0.1, 0.7, 0.1, 0.5, 0.05, 0.15], [2, 3]);
| const weights = tf.tensor2d([3, 0, 5, 0, 4, 2], [2, 3]);
| const y = tf.losses.huberLoss(labels, predictions, weights, undefined, tf.Reduction.MEAN);
| expect(y.shape).toEqual([]);
| expectArraysClose(await y.data(), 0.011678572);
| });
| it('throws when passed label as a non-tensor', () => {
| const predictions = tf.tensor2d([0.1, 0.7, 0.1, 0.5, 0.05, 0.15], [2, 3]);
| const weights = tf.tensor2d([3, 6, 5, 0, 4, 2], [2, 3]);
| const e = /Argument 'labels' passed to 'huberLoss' must be a Tensor/;
| expect(() => tf.losses.huberLoss({}, predictions, weights, tf.Reduction.MEAN))
| .toThrowError(e);
| });
| it('throws when passed label as a non-tensor', () => {
| const labels = tf.tensor2d([0.4, 0.8, 0.12, 0.8, 0.1, 0.3], [2, 3]);
| const weights = tf.tensor2d([3, 6, 5, 0, 4, 2], [2, 3]);
| const e = new RegExp('Argument \'predictions\' passed to \'huberLoss\' ' +
| 'must be a Tensor');
| expect(() => tf.losses.huberLoss(labels, {}, weights, tf.Reduction.MEAN))
| .toThrowError(e);
| });
| it('throws when passed weights as a non-tensor', () => {
| const labels = tf.tensor2d([0.4, 0.8, 0.12, 0.8, 0.1, 0.3], [2, 3]);
| const predictions = tf.tensor2d([0.1, 0.7, 0.1, 0.5, 0.05, 0.15], [2, 3]);
| const e = /Argument 'weights' passed to 'huberLoss' must be a Tensor/;
| expect(() => tf.losses.huberLoss(labels, predictions, {}, tf.Reduction.MEAN))
| .toThrowError(e);
| });
| it('accepts a tensor-like object', async () => {
| const labels = [1, 2, 3];
| const predictions = [0.3, 0.6, 0.1];
| const weights = [0.1, 0.2, 0.3];
| const y = tf.losses.huberLoss(labels, predictions, weights, undefined, tf.Reduction.NONE);
| expect(y.shape).toEqual([3]);
| expectArraysClose(await y.data(), [0.0245, 0.17999999, 0.72]);
| });
| });
| //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaHViZXJfbG9zc190ZXN0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vdGZqcy1jb3JlL3NyYy9vcHMvbG9zc2VzL2h1YmVyX2xvc3NfdGVzdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7O0dBZUc7QUFDSCxPQUFPLEtBQUssRUFBRSxNQUFNLGFBQWEsQ0FBQztBQUNsQyxPQUFPLEVBQUMsUUFBUSxFQUFFLGlCQUFpQixFQUFDLE1BQU0sb0JBQW9CLENBQUM7QUFDL0QsT0FBTyxFQUFDLGlCQUFpQixFQUFDLE1BQU0saUJBQWlCLENBQUM7QUFFbEQsaUJBQWlCLENBQUMsV0FBVyxFQUFFLFFBQVEsRUFBRSxHQUFHLEVBQUU7SUFDNUMsRUFBRSxDQUFDLElBQUksRUFBRSxLQUFLLElBQUksRUFBRTtRQUNsQixNQUFNLE1BQU0sR0FBRyxFQUFFLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3RDLE1BQU0sV0FBVyxHQUFHLEVBQUUsQ0FBQyxRQUFRLENBQUMsQ0FBQyxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUM7UUFFakQsTUFBTSxDQUFDLEdBQUcsRUFBRSxDQUFDLE1BQU0sQ0FBQyxTQUFTLENBQUMsTUFBTSxFQUFFLFdBQVcsQ0FBQyxDQUFDO1FBRW5ELE1BQU0sQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQyxDQUFDO1FBQzVCLGlCQUFpQixDQUFDLE1BQU0sQ0FBQyxDQUFDLElBQUksRUFBRSxFQUFFLFNBQVMsQ0FBQyxDQUFDO0lBQy9DLENBQUMsQ0FBQyxDQUFDO0lBRUgsRUFBRSxDQUFDLFlBQVksRUFBRSxLQUFLLElBQUksRUFBRTtRQUMxQixNQUFNLE1BQU0sR0FBRyxFQUFFLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxFQUFF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QUM7UUFFaEUsTUFBTSxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQzdCLGlCQUFpQixDQUFDLE1BQU0sQ0FBQyxDQUFDLElBQUksRUFBRSxFQUFFLENBQUMsTUFBTSxFQUFFLFVBQVUsRUFBRSxJQUFJLENBQUMsQ0FBQyxDQUFDO0lBQ2hFLENBQUMsQ0FBQyxDQUFDO0FBQ0wsQ0FBQyxDQUFDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEBsaWNlbnNlXG4gKiBDb3B5cmlnaHQgMjAyMCBHb29nbGUgTExDLiBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICovXG5pbXBvcnQgKiBhcyB0ZiBmcm9tICcuLi8uLi9pbmRleCc7XG5pbXBvcnQge0FMTF9FTlZTLCBkZXNjcmliZVdpdGhGbGFnc30gZnJvbSAnLi4vLi4vamFzbWluZV91dGlsJztcbmltcG9ydCB7ZXhwZWN0QXJyYXlzQ2xvc2V9IGZyb20gJy4uLy4uL3Rlc3RfdXRpbCc7XG5cbmRlc2NyaWJlV2l0aEZsYWdzKCdodWJlckxvc3MnLCBBTExfRU5WUywgKCkgPT4ge1xuICBpdCgnMUQnLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgbGFiZWxzID0gdGYudGVuc29yMWQoWzEsIDIsIDNdKTtcbiAgICBjb25zdCBwcmVkaWN0aW9ucyA9IHRmLnRlbnNvcjFkKFswLjMsIDAuNiwgMC4xXSk7XG5cbiAgICBjb25zdCB5ID0gdGYubG9zc2VzLmh1YmVyTG9zcyhsYWJlbHMsIHByZWRpY3Rpb25zKTtcblxuICAgIGV4cGVjdCh5LnNoYXBlKS50b0VxdWFsKFtdKTtcbiAgICBleHBlY3RBcnJheXNDbG9zZShhd2FpdCB5LmRhdGEoKSwgMS4xODE2NjY3KTtcbiAgfSk7XG5cbiAgaXQoJzFEIC0gZGVsdGEnLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgbGFiZWxzID0gdGYudGVuc29yMWQoWzEsIDIsIDNdKTtcbiAgICBjb25zdCBwcmVkaWN0aW9ucyA9IHRmLnRlbnNvcjFkKFswLjMsIDAuNiwgMC4xXSk7XG4gICAgY29uc3QgZGVsdGEgPSAwLjQ7XG5cbiAgICBjb25zdCB5ID0gdGYubG9zc2VzLmh1YmVyTG9zcyhsYWJlbHMsIHByZWRpY3Rpb25zLCB1bmRlZmluZWQsIGRlbHRhKTtcblxuICAgIGV4cGVjdCh5LnNoYXBlKS50b0VxdWFsKFtdKTtcbiAgICBleHBlY3RBcnJheXNDbG9zZShhd2FpdCB5LmRhdGEoKSwgMC41ODY2NjY2NCk7XG4gIH0pO1xuXG4gIGl0KCcxRCAtIHdlaWdodGVkIC0gUmVkdWN0aW9uLlNVTV9CWV9OT05aRVJPX1dFSUdIVFMnLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgbGFiZWxzID0gdGYudGVuc29yMWQoWzEsIDIsIDNdKTtcbiAgICBjb25zdCBwcmVkaWN0aW9ucyA9IHRmLnRlbnNvcjFkKFswLjMsIDAuNiwgMC4xXSk7XG4gICAgY29uc3Qgd2VpZ2h0cyA9IHRmLnRlbnNvcjFkKFswLjEsIDAuMiwgMC4zXSk7XG5cbiAgICBjb25zdCB5ID0gdGYubG9zc2VzLmh1YmVyTG9zcyhsYWJlbHMsIHByZWRpY3Rpb25zLCB3ZWlnaHRzKTtcblxuICAgIGV4cGVjdCh5LnNoYXBlKS50b0VxdWFsKFtdKTtcbiAgICBleHBlY3RBcnJheXNDbG9zZShhd2FpdCB5LmRhdGEoKSwgMC4zMDgxNjY2NSk7XG4gIH0pO1xuXG4gIGl0KCcxRCAtIHdlaWdodGVkIC0gUmVkdWN0aW9uLk5PTkUnLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgbGFiZWxzID0gdGYudGVuc29yMWQoWzEsIDIsIDNdKTtcbiAgICBjb25zdCBwcmVkaWN0aW9ucyA9IHRmLnRlbnNvcjFkKFswLjMsIDAuNiwgMC4xXSk7XG4gICAgY29uc3Qgd2VpZ2h0cyA9IHRmLnRlbnNvcjFkKFswLjEsIDAuMiwgMC4zXSk7XG5cbiAgICBjb25zdCB5ID0gdGYubG9zc2VzLmh1YmVyTG9zcyhcbiAgICAgICAgbGFiZWxzLCBwcmVkaWN0aW9ucywgd2VpZ2h0cywgdW5kZWZpbmVkLCB0Zi5SZWR1Y3Rpb24uTk9ORSk7XG5cbiAgICBleHBlY3QoeS5zaGFwZSkudG9FcXVhbChbM10pO1xuICAgIGV4cGVjdEFycmF5c0Nsb3NlKGF3YWl0IHkuZGF0YSgpLCBbMC4wMjQ1LCAwLjE3OTk5OTk5LCAwLjcyXSk7XG4gIH0pO1xuXG4gIGl0KCcxRCAtIFJlZHVjdGlvbi5NRUFOJywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IGxhYmVscyA9IHRmLnRlbnNvcjFkKFsxLCAyLCAzXSk7XG4gICAgY29uc3QgcHJlZGljdGlvbnMgPSB0Zi50ZW5zb3IxZChbMC4zLCAwLjYsIDAuMV0pO1xuXG4gICAgY29uc3QgeSA9IHRmLmxvc3Nlcy5odWJlckxvc3MoXG4gICAgICAgIGxhYmVscywgcHJlZGljdGlvbnMsIHVuZGVmaW5lZCwgdW5kZWZpbmVkLCB0Zi5SZWR1Y3Rpb24uTUVBTik7XG5cbiAgICBleHBlY3QoeS5zaGFwZSkudG9FcXVhbChbXSk7XG4gICAgZXhwZWN0QXJyYXlzQ2xvc2UoYXdhaXQgeS5kYXRhKCksIDEuMTgxNjY2Nyk7XG4gIH0pO1xuXG4gIGl0KCcxRCAtIHdlaWdodGVkIC0gUmVkdWN0aW9uLk1FQU4nLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgbGFiZWxzID0gdGYudGVuc29yMWQoWzEsIDIsIDNdKTtcbiAgICBjb25zdCBwcmVkaWN0aW9ucyA9IHRmLnRlbnNvcjFkKFswLjMsIDAuNiwgMC4xXSk7XG4gICAgY29uc3Qgd2VpZ2h0cyA9IHRmLnRlbnNvcjFkKFswLjEsIDAuMiwgMC4zXSk7XG5cbiAgICBjb25zdCB5ID0gdGYubG9zc2VzLmh1YmVyTG9zcyhcbiAgICAgICAgbGFiZWxzLCBwcmVkaWN0aW9ucywgd2VpZ2h0cywgdW5kZWZpbmVkLCB0Zi5SZWR1Y3Rpb24uTUVBTik7XG5cbiAgICBleHBlY3QoeS5zaGFwZSkudG9FcXVhbChbXSk7XG4gICAgZXhwZWN0QXJyYXlzQ2xvc2UoYXdhaXQgeS5kYXRhKCksIDEuNTQwODMzMik7XG4gIH0pO1xuXG4gIGl0KCcyRCcsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBsYWJlbHMgPSB0Zi50ZW5zb3IyZChbMC40LCAwLjgsIDAuMTIsIDAuOCwgMC4xLCAwLjNdLCBbMiwgM10pO1xuICAgIGNvbnN0IHByZWRpY3Rpb25zID0gdGYudGVuc29yMmQoWzAuMSwgMC43LCAwLjEsIDAuNSwgMC4wNSwgMC4xNV0sIFsyLCAzXSk7XG5cbiAgICBjb25zdCB5ID0gdGYubG9zc2VzLmh1YmVyTG9zcyhsYWJlbHMsIHByZWRpY3Rpb25zKTtcblxuICAgIGV4cGVjdCh5LnNoYXBlKS50b0VxdWFsKFtdKTtcbiAgICBleHBlY3RBcnJheXNDbG9zZShhd2FpdCB5LmRhdGEoKSwgMC4wMTc5NSk7XG4gIH0pO1xuXG4gIGl0KCcyRCAtIHdlaWdodGVkIC0gUmVkdWN0aW9uLlNVTV9CWV9OT05aRVJPX1dFSUdIVFMnLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgbGFiZWxzID0gdGYudGVuc29yMmQoWzAuNCwgMC44LCAwLjEyLCAwLjgsIDAuMSwgMC4zXSwgWzIsIDNdKTtcbiAgICBjb25zdCBwcmVkaWN0aW9ucyA9IHRmLnRlbnNvcjJkKFswLjEsIDAuNywgMC4xLCAwLjUsIDAuMDUsIDAuMTVdLCBbMiwgM10pO1xuICAgIGNvbnN0IHdlaWdodHMgPSB0Zi50ZW5zb3IyZChbMywgMCwgNSwgMCwgNCwgMl0sIFsyLCAzXSk7XG5cbiAgICBjb25zdCB5ID0gdGYubG9zc2VzLmh1YmVyTG9zcyhsYWJlbHMsIHByZWRpY3Rpb25zLCB3ZWlnaHRzKTtcblxuICAgIGV4cGVjdCh5LnNoYXBlKS50b0VxdWFsKFtdKTtcbiAgICBleHBlY3RBcnJheXNDbG9zZShhd2FpdCB5LmRhdGEoKSwgMC4wNDA4NzUwMDMpO1xuICB9KTtcblxuICBpdCgnMkQgLSB3ZWlnaHRlZCAtIFJlZHVjdGlvbi5OT05FJywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IGxhYmVscyA9IHRmLnRlbnNvcjJkKFswLjQsIDAuOCwgMC4xMiwgMC44LCAwLjEsIDAuM10sIFsyLCAzXSk7XG4gICAgY29uc3QgcHJlZGljdGlvbnMgPSB0Zi50ZW5zb3IyZChbMC4xLCAwLjcsIDAuMSwgMC41LCAwLjA1LCAwLjE1XSwgWzIsIDNdKTtcbiAgICBjb25zdCB3ZWlnaHRzID0gdGYudGVuc29yMmQoWzMsIDAsIDUsIDAsIDQsIDJdLCBbMiwgM10pO1xuXG4gICAgY29uc3QgeSA9IHRmLmxvc3Nlcy5odWJlckxvc3MoXG4gICAgICAgIGxhYmVscywgcHJlZGljdGlvbnMsIHdlaWdodHMsIHVuZGVmaW5lZCwgdGYuUmVkdWN0aW9uLk5PTkUpO1xuXG4gICAgZXhwZWN0KHkuc2hhcGUpLnRvRXF1YWwoWzIsIDNdKTtcbiAgICBleHBlY3RBcnJheXNDbG9zZShhd2FpdCB5LmRhdGEoKSwgWzAuMTM1LCAwLiwgMC4wMDEsIDAuLCAwLjAwNSwgMC4wMjI1XSk7XG4gIH0pO1xuXG4gIGl0KCcyRCAtIFJlZHVjdGlvbi5NRUFOJywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IGxhYmVscyA9IHRmLnRlbnNvcjJkKFswLjQsIDAuOCwgMC4xMiwgMC44LCAwLjEsIDAuM10sIFsyLCAzXSk7XG4gICAgY29uc3QgcHJlZGljdGlvbnMgPSB0Zi50ZW5zb3IyZChbMC4xLCAwLjcsIDAuMSwgMC41LCAwLjA1LCAwLjE1XSwgWzIsIDNdKTtcblxuICAgIGNvbnN0IHkgPSB0Zi5sb3NzZXMuaHViZXJMb3NzKFxuICAgICAgICBsYWJlbHMsIHByZWRpY3Rpb25zLCB1bmRlZmluZWQsIHVuZGVmaW5lZCwgdGYuUmVkdWN0aW9uLk1FQU4pO1xuXG4gICAgZXhwZWN0KHkuc2hhcGUpLnRvRXF1YWwoW10pO1xuICAgIGV4cGVjdEFycmF5c0Nsb3NlKGF3YWl0IHkuZGF0YSgpLCAwLjAxNzk1KTtcbiAgfSk7XG5cbiAgaXQoJzJEIC0gd2VpZ2h0ZWQgLSBSZWR1Y3Rpb24uTUVBTicsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBsYWJlbHMgPSB0Zi50ZW5zb3IyZChbMC40LCAwLjgsIDAuMTIsIDAuOCwgMC4xLCAwLjNdLCBbMiwgM10pO1xuICAgIGNvbnN0IHByZWRpY3Rpb25zID0gdGYudGVuc29yMmQoWzAuMSwgMC43LCAwLjEsIDAuNSwgMC4wNSwgMC4xNV0sIFsyLCAzXSk7XG4gICAgY29uc3Qgd2VpZ2h0cyA9IHRmLnRlbnNvcjJkKFszLCAwLCA1LCAwLCA0LCAyXSwgWzIsIDNdKTtcblxuICAgIGNvbnN0IHkgPSB0Zi5sb3NzZXMuaHViZXJMb3NzKFxuICAgICAgICBsYWJlbHMsIHByZWRpY3Rpb25zLCB3ZWlnaHRzLCB1bmRlZmluZWQsIHRmLlJlZHVjdGlvbi5NRUFOKTtcblxuICAgIGV4cGVjdCh5LnNoYXBlKS50b0VxdWFsKFtdKTtcbiAgICBleHBlY3RBcnJheXNDbG9zZShhd2FpdCB5LmRhdGEoKSwgMC4wMTE2Nzg1NzIpO1xuICB9KTtcblxuICBpdCgndGhyb3dzIHdoZW4gcGFzc2VkIGxhYmVsIGFzIGEgbm9uLXRlbnNvcicsICgpID0+IHtcbiAgICBjb25zdCBwcmVkaWN0aW9ucyA9IHRmLnRlbnNvcjJkKFswLjEsIDAuNywgMC4xLCAwLjUsIDAuMDUsIDAuMTVdLCBbMiwgM10pO1xuICAgIGNvbnN0IHdlaWdodHMgPSB0Zi50ZW5zb3IyZChbMywgNiwgNSwgMCwgNCwgMl0sIFsyLCAzXSk7XG5cbiAgICBjb25zdCBlID0gL0FyZ3VtZW50ICdsYWJlbHMnIHBhc3NlZCB0byAnaHViZXJMb3NzJyBtdXN0IGJlIGEgVGVuc29yLztcbiAgICBleHBlY3QoXG4gICAgICAgICgpID0+IHRmLmxvc3Nlcy5odWJlckxvc3MoXG4gICAgICAgICAgICB7fSBhcyB0Zi5UZW5zb3IsIHByZWRpY3Rpb25zLCB3ZWlnaHRzLCB0Zi5SZWR1Y3Rpb24uTUVBTikpXG4gICAgICAgIC50b1Rocm93RXJyb3IoZSk7XG4gIH0pO1xuXG4gIGl0KCd0aHJvd3Mgd2hlbiBwYXNzZWQgbGFiZWwgYXMgYSBub24tdGVuc29yJywgKCkgPT4ge1xuICAgIGNvbnN0IGxhYmVscyA9IHRmLnRlbnNvcjJkKFswLjQsIDAuOCwgMC4xMiwgMC44LCAwLjEsIDAuM10sIFsyLCAzXSk7XG4gICAgY29uc3Qgd2VpZ2h0cyA9IHRmLnRlbnNvcjJkKFszLCA2LCA1LCAwLCA0LCAyXSwgWzIsIDNdKTtcblxuICAgIGNvbnN0IGUgPSBuZXcgUmVnRXhwKFxuICAgICAgICAnQXJndW1lbnQgXFwncHJlZGljdGlvbnNcXCcgcGFzc2VkIHRvIFxcJ2h1YmVyTG9zc1xcJyAnICtcbiAgICAgICAgJ211c3QgYmUgYSBUZW5zb3InKTtcbiAgICBleHBlY3QoXG4gICAgICAgICgpID0+IHRmLmxvc3Nlcy5odWJlckxvc3MoXG4gICAgICAgICAgICBsYWJlbHMsIHt9IGFzIHRmLlRlbnNvciwgd2VpZ2h0cywgdGYuUmVkdWN0aW9uLk1FQU4pKVxuICAgICAgICAudG9UaHJvd0Vycm9yKGUpO1xuICB9KTtcblxuICBpdCgndGhyb3dzIHdoZW4gcGFzc2VkIHdlaWdodHMgYXMgYSBub24tdGVuc29yJywgKCkgPT4ge1xuICAgIGNvbnN0IGxhYmVscyA9IHRmLnRlbnNvcjJkKFswLjQsIDAuOCwgMC4xMiwgMC44LCAwLjEsIDAuM10sIFsyLCAzXSk7XG4gICAgY29uc3QgcHJlZGljdGlvbnMgPSB0Zi50ZW5zb3IyZChbMC4xLCAwLjcsIDAuMSwgMC41LCAwLjA1LCAwLjE1XSwgWzIsIDNdKTtcblxuICAgIGNvbnN0IGUgPSAvQXJndW1lbnQgJ3dlaWdodHMnIHBhc3NlZCB0byAnaHViZXJMb3NzJyBtdXN0IGJlIGEgVGVuc29yLztcbiAgICBleHBlY3QoXG4gICAgICAgICgpID0+IHRmLmxvc3Nlcy5odWJlckxvc3MoXG4gICAgICAgICAgICBsYWJlbHMsIHByZWRpY3Rpb25zLCB7fSBhcyB0Zi5UZW5zb3IsIHRmLlJlZHVjdGlvbi5NRUFOKSlcbiAgICAgICAgLnRvVGhyb3dFcnJvcihlKTtcbiAgfSk7XG5cbiAgaXQoJ2FjY2VwdHMgYSB0ZW5zb3ItbGlrZSBvYmplY3QnLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgbGFiZWxzID0gWzEsIDIsIDNdO1xuICAgIGNvbnN0IHByZWRpY3Rpb25zID0gWzAuMywgMC42LCAwLjFdO1xuICAgIGNvbnN0IHdlaWdodHMgPSBbMC4xLCAwLjIsIDAuM107XG5cbiAgICBjb25zdCB5ID0gdGYubG9zc2VzLmh1YmVyTG9zcyhcbiAgICAgICAgbGFiZWxzLCBwcmVkaWN0aW9ucywgd2VpZ2h0cywgdW5kZWZpbmVkLCB0Zi5SZWR1Y3Rpb24uTk9ORSk7XG5cbiAgICBleHBlY3QoeS5zaGFwZSkudG9FcXVhbChbM10pO1xuICAgIGV4cGVjdEFycmF5c0Nsb3NlKGF3YWl0IHkuZGF0YSgpLCBbMC4wMjQ1LCAwLjE3OTk5OTk5LCAwLjcyXSk7XG4gIH0pO1xufSk7XG4iXX0=
|
|