UNPKG

35.1 kBJavaScriptView Raw
1/**
2 * @license
3 * Copyright 2020 Google LLC. All Rights Reserved.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 * =============================================================================
16 */
17import * as tf from '../index';
18import { ALL_ENVS, describeWithFlags } from '../jasmine_util';
19import { expectArraysClose } from '../test_util';
20describeWithFlags('slice2d', ALL_ENVS, () => {
21 it('slicing a 1x1 from a 1x1 returns a 1x1', () => {
22 const a = tf.tensor2d([0], [1, 1]);
23 const b = tf.slice2d(a, [0, 0], [1, 1]);
24 expect(b.shape).toEqual([1, 1]);
25 });
26 it('returns a tensor of slice size', () => {
27 const a = tf.zeros([100, 100]);
28 const b = tf.slice2d(a, [0, 0], [12, 34]);
29 expect(b.shape).toEqual([12, 34]);
30 });
31 it('returns the upper-left submatrix when begin is [0, 0]', async () => {
32 const a = tf.randomUniform([10, 10], -1, 1);
33 const b = tf.slice2d(a, [0, 0], [2, 2]);
34 const aValues = await a.data();
35 expectArraysClose(await b.data(), [aValues[0], aValues[1], aValues[10], aValues[11]]);
36 });
37 it('returns the rectangle specified', async () => {
38 const a = tf.tensor2d([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12], [4, 3]);
39 const b = tf.slice2d(a, [1, 1], [3, 2]);
40 expectArraysClose(await b.data(), [5, 6, 8, 9, 11, 12]);
41 });
42 it('throws when requesting out of bounds slice', () => {
43 const a = tf.tensor2d([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12], [4, 3]);
44 expect(() => tf.slice2d(a, [1, 1], [10, 10])).toThrowError();
45 });
46 it('grad', async () => {
47 const a = tf.tensor2d([[1, 2, 3], [4, 5, 6]]);
48 const dy = tf.tensor2d([[20], [50]]);
49 const da = tf.grad((x) => tf.slice2d(a, [0, 1], [2, 1]))(a, dy);
50 expect(da.shape).toEqual([2, 3]);
51 expectArraysClose(await da.data(), [0, 20, 0, 0, 50, 0]);
52 });
53 it('accepts a tensor-like object', () => {
54 const a = [[0]]; // 1x1
55 const b = tf.slice2d(a, [0, 0], [1, 1]);
56 expect(b.shape).toEqual([1, 1]);
57 });
58 it('slice an already sliced tensor, first was not continous', async () => {
59 const a = [
60 [1, 2, 3, 4],
61 [5, 6, 7, 8],
62 [9, 10, 11, 12],
63 ]; // 3x4.
64 const b = tf.slice(a, [0, 1]);
65 const c = tf.slice(b, [1, 1], [1, 1]);
66 expect(c.shape).toEqual([1, 1]);
67 expectArraysClose(await c.data(), [7]);
68 });
69 it('slice an already sliced tensor, first was continous', async () => {
70 const a = [
71 [1, 2, 3, 4],
72 [5, 6, 7, 8],
73 [9, 10, 11, 12],
74 ]; // 3x4.
75 const b = tf.slice(a, [1, 0]);
76 const c = tf.slice(b, [1, 0]);
77 expect(c.shape).toEqual([1, 4]);
78 expectArraysClose(await c.data(), [9, 10, 11, 12]);
79 });
80 it('slice an already sliced tensor and do async read', async () => {
81 const a = [
82 [1, 2, 3, 4],
83 [5, 6, 7, 8],
84 [9, 10, 11, 12],
85 ]; // 3x4.
86 const b = tf.slice(a, [0, 1]);
87 const c = tf.slice(b, [1, 1], [1, 1]);
88 expect(c.shape).toEqual([1, 1]);
89 expectArraysClose(await c.data(), new Float32Array([7]));
90 });
91 it('square a sliced texture, followed by non-sliced texture of same shape', async () => {
92 // Make a 2x3 tensor, upload to gpu and reshape to 3x2.
93 const input = tf.tensor([[1, 2, 3], [4, 5, 6]]).abs().as2D(3, 2);
94 const slicedInput = tf.slice(input, [0, 0], [3, 2]);
95 // First square program takes the sliced input.
96 const a = slicedInput.square();
97 expectArraysClose(await a.data(), [1, 4, 9, 16, 25, 36]);
98 // Second square program takes the non-sliced input.
99 const b = tf.square(input);
100 expectArraysClose(await b.data(), [1, 4, 9, 16, 25, 36]);
101 });
102 it('square a non-sliced texture, followed by a sliced texture of same shape', async () => {
103 // Make a 2x3 tensor, upload to gpu and reshape to 3x2.
104 const input = tf.tensor([[1, 2, 3], [4, 5, 6]]).abs().as2D(3, 2);
105 // Make a sliced version of the same tensor with the same shape.
106 const slicedInput = tf.slice(input, [0, 0], [3, 2]);
107 // First square program takes the non-sliced input.
108 const a = input.square();
109 expectArraysClose(await a.data(), [1, 4, 9, 16, 25, 36]);
110 // Second square program takes the sliced input.
111 const b = tf.square(slicedInput);
112 expectArraysClose(await b.data(), [1, 4, 9, 16, 25, 36]);
113 });
114 it('slice a tensor and do async read', async () => {
115 const a = [
116 [1, 2, 3, 4],
117 [5, 6, 7, 8],
118 [9, 10, 11, 12],
119 ]; // 3x4.
120 const b = tf.slice(a, [0, 1], [3, 2]);
121 expect(b.shape).toEqual([3, 2]);
122 const vals = await b.data();
123 expectArraysClose(vals, new Float32Array([2, 3, 6, 7, 10, 11]));
124 });
125 it('flatten a sliced tensor that was continuous in memory', async () => {
126 const a = [
127 [1, 2, 3, 4],
128 [5, 6, 7, 8],
129 [9, 10, 11, 12],
130 ]; // 3x4.
131 const b = tf.slice(a, [1, 0]).flatten();
132 expect(b.shape).toEqual([8]);
133 expectArraysClose(await b.data(), [5, 6, 7, 8, 9, 10, 11, 12]);
134 });
135 it('slice a tensor that was not continuous in memory', async () => {
136 const a = [
137 [1, 2, 3, 4],
138 [5, 6, 7, 8],
139 [9, 10, 11, 12],
140 ]; // 3x4.
141 const b = tf.slice(a, [0, 1]);
142 expect(b.shape).toEqual([3, 3]);
143 expectArraysClose(await b.data(), [2, 3, 4, 6, 7, 8, 10, 11, 12]);
144 });
145 it('flatten a sliced tensor that was not continuous in memory', async () => {
146 const a = [
147 [1, 2, 3, 4],
148 [5, 6, 7, 8],
149 [9, 10, 11, 12],
150 ]; // 3x4.
151 const b = tf.slice(a, [0, 1]).flatten();
152 expect(b.shape).toEqual([9]);
153 expectArraysClose(await b.data(), [2, 3, 4, 6, 7, 8, 10, 11, 12]);
154 });
155 it('flatten a sliced tensor not continuous in memory and run program', async () => {
156 const a = [
157 [1, 2, 3, 4],
158 [5, 6, 7, 8],
159 [9, 10, 11, 12],
160 ]; // 3x4.
161 const b = tf.slice(a, [0, 1]).flatten();
162 const c = tf.square(b);
163 expectArraysClose(await c.data(), [4, 9, 16, 36, 49, 64, 100, 121, 144]);
164 });
165 it('reshape a sliced 1d into a 2d tensor', async () => {
166 const a = [1, 2, 3, 4, 5];
167 const b = tf.slice(a, 1).as2D(2, 2);
168 expect(b.shape).toEqual([2, 2]);
169 expectArraysClose(await b.data(), [2, 3, 4, 5]);
170 });
171 it('reshape a sliced 1d into a 2d tensor and run program', async () => {
172 const a = [1, 2, 3, 4, 5];
173 const b = tf.slice(a, 1).as2D(2, 2).square();
174 expect(b.shape).toEqual([2, 2]);
175 expectArraysClose(await b.data(), [4, 9, 16, 25]);
176 });
177 it('broadcast the original with the sliced tensor', async () => {
178 const a = [[1, 2], [3, 4]];
179 const b = tf.slice(a, [0, 1]);
180 const c = tf.add(a, b);
181 expect(c.shape).toEqual([2, 2]);
182 expectArraysClose(await c.data(), [3, 4, 7, 8]);
183 });
184 it('zero-sized slice out of a non-zero sized tensor', async () => {
185 const a = tf.zeros([4, 2]);
186 const res = tf.slice(a, [0, 0], [0, 2]);
187 expect(res.shape).toEqual([0, 2]);
188 expectArraysClose(await res.data(), []);
189 });
190 it('zero-sized slice out of a zero-sized tensor', async () => {
191 const a = tf.zeros([0, 4]);
192 const res = tf.slice(a, [0, 1], [0, 3]);
193 expect(res.shape).toEqual([0, 3]);
194 expectArraysClose(await res.data(), []);
195 });
196});
197//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2xpY2UyZF90ZXN0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vdGZqcy1jb3JlL3NyYy9vcHMvc2xpY2UyZF90ZXN0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7Ozs7Ozs7Ozs7R0FlRztBQUVILE9BQU8sS0FBSyxFQUFFLE1BQU0sVUFBVSxDQUFDO0FBQy9CLE9BQU8sRUFBQyxRQUFRLEVBQUUsaUJBQWlCLEVBQUMsTUFBTSxpQkFBaUIsQ0FBQztBQUM1RCxPQUFPLEVBQUMsaUJBQWlCLEVBQUMsTUFBTSxjQUFjLENBQUM7QUFHL0MsaUJBQWlCLENBQUMsU0FBUyxFQUFFLFFBQVEsRUFBRSxHQUFHLEVBQUU7SUFDMUMsRUFBRSxDQUFDLHdDQUF3QyxFQUFFLEdBQUcsRUFBRTtRQUNoRCxNQUFNLENBQUMsR0FBRyxFQUFFLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUNuQyxNQUFNLENBQUMsR0FBRyxFQUFFLENBQUMsT0FBTyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3hDLE1BQU0sQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDbEMsQ0FBQyxDQUFDLENBQUM7SUFFSCxFQUFFLENBQUMsZ0NBQWdDLEVBQUUsR0FBRyxFQUFFO1FBQ3hDLE1BQU0sQ0FBQyxHQUFHLEVBQUUsQ0FBQyxLQUFLLENBQVUsQ0FBQyxHQUFHLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQztRQUN4QyxNQUFNLENBQUMsR0FBRyxFQUFFLENBQUMsT0FBTyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBQzFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsRUFBRSxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFDcEMsQ0FBQyxDQUFDLENBQUM7SUFFSCxFQUFFLENBQUMsdURBQXVELEVBQUUsS0FBSyxJQUFJLEVBQUU7UUFDckUsTUFBTSxDQUFDLEdBQUcsRUFBRSxDQUFDLGFBQWEsQ0FBVSxDQUFDLEVBQUUsRUFBRSxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztRQUNyRCxNQUFNLENBQUMsR0FBRyxFQUFFLENBQUMsT0FBTyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3hDLE1BQU0sT0FBTyxHQUFHLE1BQU0sQ0FBQyxDQUFDLElBQUksRUFBRSxDQUFDO1FBRS9CLGlCQUFpQixDQUNiLE1BQU0sQ0FBQyxDQUFDLElBQUksRUFBRSxFQUFFLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxFQUFFLE9BQU8sQ0FBQyxDQUFDLENBQUMsRUFBRSxPQUFPLENBQUMsRUFBRSxDQUFDLEVBQUUsT0FBTyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUMxRSxDQUFDLENBQUMsQ0FBQztJQUVILEVBQUUsQ0FBQyxpQ0FBaUMsRUFBRSxLQUFLLElBQUksRUFBRTtRQUMvQyxNQUFNLENBQUMsR0FBRyxFQUFFLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3ZFLE1BQU0sQ0FBQyxHQUFHLEVBQUUsQ0FBQyxPQUFPLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFFeEMsaUJBQWlCLENBQUMsTUFBTSxDQUFDLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRSxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFDMUQsQ0FBQyxDQUFDLENBQUM7SUFFSCxFQUFFLENBQUMsNENBQTRDLEVBQUUsR0FBRyxFQUFFO1FBQ3BELE1BQU0sQ0FBQyxHQUFHLEVBQUUsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDdkUsTUFBTSxDQUFDLEdBQUcsRUFBRSxDQUFDLEVBQUUsQ0FBQyxPQUFPLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxZQUFZLEVBQUUsQ0FBQztJQUMvRCxDQUFDLENBQUMsQ0FBQztJQUVILEVBQUUsQ0FBQyxNQUFNLEVBQUUsS0FBSyxJQUFJLEVBQUU7UUFDcEIsTUFBTSxDQUFDLEdBQUcsRUFBRSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQzlDLE1BQU0sRUFBRSxHQUFHLEVBQUUsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMs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LEVBQUUsQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDeEMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUNsQyxpQkFBaUIsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxJQUFJLEVBQUUsRUFBRSxFQUFFLENBQUMsQ0FBQztJQUMxQyxDQUFDLENBQUMsQ0FBQztBQUNMLENBQUMsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBAbGljZW5zZVxuICogQ29weXJpZ2h0IDIwMjAgR29vZ2xlIExMQy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAqL1xuXG5pbXBvcnQgKiBhcyB0ZiBmcm9tICcuLi9pbmRleCc7XG5pbXBvcnQge0FMTF9FTlZTLCBkZXNjcmliZVdpdGhGbGFnc30gZnJvbSAnLi4vamFzbWluZV91dGlsJztcbmltcG9ydCB7ZXhwZWN0QXJyYXlzQ2xvc2V9IGZyb20gJy4uL3Rlc3RfdXRpbCc7XG5pbXBvcnQge1Jhbmt9IGZyb20gJy4uL3R5cGVzJztcblxuZGVzY3JpYmVXaXRoRmxhZ3MoJ3NsaWNlMmQnLCBBTExfRU5WUywgKCkgPT4ge1xuICBpdCgnc2xpY2luZyBhIDF4MSBmcm9tIGEgMXgxIHJldHVybnMgYSAxeDEnLCAoKSA9PiB7XG4gICAgY29uc3QgYSA9IHRmLnRlbnNvcjJkKFswXSwgWzEsIDFdKTtcbiAgICBjb25zdCBiID0gdGYuc2xpY2UyZChhLCBbMCwgMF0sIFsxLCAxXSk7XG4gICAgZXhwZWN0KGIuc2hhcGUpLnRvRXF1YWwoWzEsIDFdKTtcbiAgfSk7XG5cbiAgaXQoJ3JldHVybnMgYSB0ZW5zb3Igb2Ygc2xpY2Ugc2l6ZScsICgpID0+IHtcbiAgICBjb25zdCBhID0gdGYuemVyb3M8UmFuay5SMj4oWzEwMCwgMTAwXSk7XG4gICAgY29uc3QgYiA9IHRmLnNsaWNlMmQoYSwgWzAsIDBdLCBbMTIsIDM0XSk7XG4gICAgZXhwZWN0KGIuc2hhcGUpLnRvRXF1YWwoWzEyLCAzNF0pO1xuICB9KTtcblxuICBpdCgncmV0dXJucyB0aGUgdXBwZXItbGVmdCBzdWJtYXRyaXggd2hlbiBiZWdpbiBpcyBbMCwgMF0nLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgYSA9IHRmLnJhbmRvbVVuaWZvcm08UmFuay5SMj4oWzEwLCAxMF0sIC0xLCAxKTtcbiAgICBjb25zdCBiID0gdGYuc2xpY2UyZChhLCBbMCwgMF0sIFsyLCAyXSk7XG4gICAgY29uc3QgYVZhbHVlcyA9IGF3YWl0IGEuZGF0YSgpO1xuXG4gICAgZXhwZWN0QXJyYXlzQ2xvc2UoXG4gICAgICAgIGF3YWl0IGIuZGF0YSgpLCBbYVZhbHVlc1swXSwgYVZhbHVlc1sxXSwgYVZhbHVlc1sxMF0sIGFWYWx1ZXNbMTFdXSk7XG4gIH0pO1xuXG4gIGl0KCdyZXR1cm5zIHRoZSByZWN0YW5nbGUgc3BlY2lmaWVkJywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IGEgPSB0Zi50ZW5zb3IyZChbMSwgMiwgMywgNCwgNSwgNiwgNywgOCwgOSwgMTAsIDExLCAxMl0sIFs0LCAzXSk7XG4gICAgY29uc3QgYiA9IHRmLnNsaWNlMmQoYSwgWzEsIDFdLCBbMywgMl0pO1xuXG4gICAgZXhwZWN0QXJyYXlzQ2xvc2UoYXdhaXQgYi5kYXRhKCksIFs1LCA2LCA4LCA5LCAxMSwgMTJdKTtcbiAgfSk7XG5cbiAgaXQoJ3Rocm93cyB3aGVuIHJlcXVlc3Rpbmcgb3V0IG9mIGJvdW5kcyBzbGljZScsICgpID0+IHtcbiAgICBjb25zdCBhID0gdGYudGVuc29yMmQoWzEsIDIsIDMsIDQsIDUsIDYsIDcsIDgsIDksIDEwLCAxMSwgMTJdLCBbNCwgM10pO1xuICAgIGV4cGVjdCgoKSA9PiB0Zi5zbGljZTJkKGEsIFsxLCAxXSwgWzEwLCAxMF0pKS50b1Rocm93RXJyb3IoKTtcbiAgfSk7XG5cbiAgaXQoJ2dyYWQnLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgYSA9IHRmLnRlbnNvcjJkKFtbMSwgMiwgM10sIFs0LCA1LCA2XV0pO1xuICAgIGNvbnN0IGR5ID0gdGYudGVuc29yMmQoW1syMF0sIFs1MF1dKTtcbiAgICBjb25zdCBkYSA9XG4gICAgICAgIHRmLmdyYWQoKHg6IHRmLlRlbnNvcjJEKSA9PiB0Zi5zbGljZTJkKGEsIFswLCAxXSwgWzIsIDFdKSkoYSwgZHkpO1xuICAgIGV4cGVjdChkYS5zaGFwZSkudG9FcXVhbChbMiwgM10pO1xuICAgIGV4cGVjdEFycmF5c0Nsb3NlKGF3YWl0IGRhLmRhdGEoKSwgWzAsIDIwLCAwLCAwLCA1MCwgMF0pO1xuICB9KTtcblxuICBpdCgnYWNjZXB0cyBhIHRlbnNvci1saWtlIG9iamVjdCcsICgpID0+IHtcbiAgICBjb25zdCBhID0gW1swXV07ICAvLyAxeDFcbiAgICBjb25zdCBiID0gdGYuc2xpY2UyZChhLCBbMCwgMF0sIFsxLCAxXSk7XG4gICAgZXhwZWN0KGIuc2hhcGUpLnRvRXF1YWwoWzEsIDFdKTtcbiAgfSk7XG5cbiAgaXQoJ3NsaWNlIGFuIGFscmVhZHkgc2xpY2VkIHRlbnNvciwgZmlyc3Qgd2FzIG5vdCBjb250aW5vdXMnLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgYSA9IFtcbiAgICAgIFsxLCAyLCAzLCA0XSxcbiAgICAgIFs1LCA2LCA3LCA4XSxcbiAgICAgIFs5LCAxMCwgMTEsIDEyXSxcbiAgICBdOyAgLy8gM3g0LlxuICAgIGNvbnN0IGIgPSB0Zi5zbGljZShhLCBbMCwgMV0pO1xuICAgIGNvbnN0IGMgPSB0Zi5zbGljZShiLCBbMSwgMV0sIFsxLCAxXSk7XG4gICAgZXhwZWN0KGMuc2hhcGUpLnRvRXF1YWwoWzEsIDFdKTtcbiAgICBleHBlY3RBcnJheXNDbG9zZShhd2FpdCBjLmRhdGEoKSwgWzddKTtcbiAgfSk7XG5cbiAgaXQoJ3NsaWNlIGFuIGFscmVhZHkgc2xpY2VkIHRlbnNvciwgZmlyc3Qgd2FzIGNvbnRpbm91cycsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBhID0gW1xuICAgICAgWzEsIDIsIDMsIDRdLFxuICAgICAgWzUsIDYsIDcsIDhdLFxuICAgICAgWzksIDEwLCAxMSwgMTJdLFxuICAgIF07ICAvLyAzeDQuXG4gICAgY29uc3QgYiA9IHRmLnNsaWNlKGEsIFsxLCAwXSk7XG4gICAgY29uc3QgYyA9IHRmLnNsaWNlKGIsIFsxLCAwXSk7XG4gICAgZXhwZWN0KGMuc2hhcGUpLnRvRXF1YWwoWzEsIDRdKTtcbiAgICBleHBlY3RBcnJheXNDbG9zZShhd2FpdCBjLmRhdGEoKSwgWzksIDEwLCAxMSwgMTJdKTtcbiAgfSk7XG5cbiAgaXQoJ3NsaWNlIGFuIGFscmVhZHkgc2xpY2VkIHRlbnNvciBhbmQgZG8gYXN5bmMgcmVhZCcsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBhID0gW1xuICAgICAgWzEsIDIsIDMsIDRdLFxuICAgICAgWzUsIDYsIDcsIDhdLFxuICAgICAgWzksIDEwLCAxMSwgMTJdLFxuICAgIF07ICAvLyAzeDQuXG4gICAgY29uc3QgYiA9IHRmLnNsaWNlKGEsIFswLCAxXSk7XG4gICAgY29uc3QgYyA9IHRmLnNsaWNlKGIsIFsxLCAxXSwgWzEsIDFdKTtcbiAgICBleHBlY3QoYy5zaGFwZSkudG9FcXVhbChbMSwgMV0pO1xuICAgIGV4cGVjdEFycmF5c0Nsb3NlKGF3YWl0IGMuZGF0YSgpLCBuZXcgRmxvYXQzMkFycmF5KFs3XSkpO1xuICB9KTtcblxuICBpdCgnc3F1YXJlIGEgc2xpY2VkIHRleHR1cmUsIGZvbGxvd2VkIGJ5IG5vbi1zbGljZWQgdGV4dHVyZSBvZiBzYW1lIHNoYXBlJyxcbiAgICAgYXN5bmMgKCkgPT4geyAgLy8gVGVzdHMgY29sbGlzaW9ucyBpbiB0aGUgc2hhZGVyIGNhY2hlLlxuICAgICAgIC8vIE1ha2UgYSAyeDMgdGVuc29yLCB1cGxvYWQgdG8gZ3B1IGFuZCByZXNoYXBlIHRvIDN4Mi5cbiAgICAgICBjb25zdCBpbnB1dCA9IHRmLnRlbnNvcihbWzEsIDIsIDNdLCBbNCwgNSwgNl1dKS5hYnMoKS5hczJEKDMsIDIpO1xuICAgICAgIGNvbnN0IHNsaWNlZElucHV0ID0gdGYuc2xpY2UoaW5wdXQsIFswLCAwXSwgWzMsIDJdKTtcbiAgICAgICAvLyBGaXJzdCBzcXVhcmUgcHJvZ3JhbSB0YWtlcyB0aGUgc2xpY2VkIGlucHV0LlxuICAgICAgIGNvbnN0IGEgPSBzbGljZWRJbnB1dC5zcXVhcmUoKTtcbiAgICAgICBleHBlY3RBcnJheXNDbG9zZShhd2FpdCBhLmRhdGEoKSwgWzEsIDQsIDksIDE2LCAyNSwgMzZdKTtcbiAgICAgICAvLyBTZWNvbmQgc3F1YXJlIHByb2dyYW0gdGFrZXMgdGhlIG5vbi1zbGljZWQgaW5wdXQuXG4gICAgICAgY29uc3QgYiA9IHRmLnNxdWFyZShpbnB1dCk7XG4gICAgICAgZXhwZWN0QXJyYXlzQ2xvc2UoYXdhaXQgYi5kYXRhKCksIFsxLCA0LCA5LCAxNiwgMjUsIDM2XSk7XG4gICAgIH0pO1xuXG4gIGl0KCdzcXVhcmUgYSBub24tc2xpY2VkIHRleHR1cmUsIGZvbGxvd2VkIGJ5IGEgc2xpY2VkIHRleHR1cmUgb2Ygc2FtZSBzaGFwZScsXG4gICAgIGFzeW5jICgpID0+IHsgIC8vIFRlc3RzIGNvbGxpc2lvbnMgaW4gdGhlIHNoYWRlciBjYWNoZS5cbiAgICAgICAvLyBNYWtlIGEgMngzIHRlbnNvciwgdXBsb2FkIHRvIGdwdSBhbmQgcmVzaGFwZSB0byAzeDIuXG4gICAgICAgY29uc3QgaW5wdXQgPSB0Zi50ZW5zb3IoW1sxLCAyLCAzXSwgWzQsIDUsIDZdXSkuYWJzKCkuYXMyRCgzLCAyKTtcbiAgICAgICAvLyBNYWtlIGEgc2xpY2VkIHZlcnNpb24gb2YgdGhlIHNhbWUgdGVuc29yIHdpdGggdGhlIHNhbWUgc2hhcGUuXG4gICAgICAgY29uc3Qgc2xpY2VkSW5wdXQgPSB0Zi5zbGljZShpbnB1dCwgWzAsIDBdLCBbMywgMl0pO1xuICAgICAgIC8vIEZpcnN0IHNxdWFyZSBwcm9ncmFtIHRha2VzIHRoZSBub24tc2xpY2VkIGlucHV0LlxuICAgICAgIGNvbnN0IGEgPSBpbnB1dC5zcXVhcmUoKTtcbiAgICAgICBleHBlY3RBcnJheXNDbG9zZShhd2FpdCBhLmRhdGEoKSwgWzEsIDQsIDksIDE2LCAyNSwgMzZdKTtcbiAgICAgICAvLyBTZWNvbmQgc3F1YXJlIHByb2dyYW0gdGFrZXMgdGhlIHNsaWNlZCBpbnB1dC5cbiAgICAgICBjb25zdCBiID0gdGYuc3F1YXJlKHNsaWNlZElucHV0KTtcbiAgICAgICBleHBlY3RBcnJheXNDbG9zZShhd2FpdCBiLmRhdGEoKSwgWzEsIDQsIDksIDE2LCAyNSwgMzZdKTtcbiAgICAgfSk7XG5cbiAgaXQoJ3NsaWNlIGEgdGVuc29yIGFuZCBkbyBhc3luYyByZWFkJywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IGEgPSBbXG4gICAgICBbMSwgMiwgMywgNF0sXG4gICAgICBbNSwgNiwgNywgOF0sXG4gICAgICBbOSwgMTAsIDExLCAxMl0sXG4gICAgXTsgIC8vIDN4NC5cbiAgICBjb25zdCBiID0gdGYuc2xpY2UoYSwgWzAsIDFdLCBbMywgMl0pO1xuICAgIGV4cGVjdChiLnNoYXBlKS50b0VxdWFsKFszLCAyXSk7XG4gICAgY29uc3QgdmFscyA9IGF3YWl0IGIuZGF0YSgpO1xuICAgIGV4cGVjdEFycmF5c0Nsb3NlKHZhbHMsIG5ldyBGbG9hdDMyQXJyYXkoWzIsIDMsIDYsIDcsIDEwLCAxMV0pKTtcbiAgfSk7XG5cbiAgaXQoJ2ZsYXR0ZW4gYSBzbGljZWQgdGVuc29yIHRoYXQgd2FzIGNvbnRpbnVvdXMgaW4gbWVtb3J5JywgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IGEgPSBbXG4gICAgICBbMSwgMiwgMywgNF0sXG4gICAgICBbNSwgNiwgNywgOF0sXG4gICAgICBbOSwgMTAsIDExLCAxMl0sXG4gICAgXTsgIC8vIDN4NC5cbiAgICBjb25zdCBiID0gdGYuc2xpY2UoYSwgWzEsIDBdKS5mbGF0dGVuKCk7XG4gICAgZXhwZWN0KGIuc2hhcGUpLnRvRXF1YWwoWzhdKTtcbiAgICBleHBlY3RBcnJheXNDbG9zZShhd2FpdCBiLmRhdGEoKSwgWzUsIDYsIDcsIDgsIDksIDEwLCAxMSwgMTJdKTtcbiAgfSk7XG5cbiAgaXQoJ3NsaWNlIGEgdGVuc29yIHRoYXQgd2FzIG5vdCBjb250aW51b3VzIGluIG1lbW9yeScsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBhID0gW1xuICAgICAgWzEsIDIsIDMsIDRdLFxuICAgICAgWzUsIDYsIDcsIDhdLFxuICAgICAgWzksIDEwLCAxMSwgMTJdLFxuICAgIF07ICAvLyAzeDQuXG4gICAgY29uc3QgYiA9IHRmLnNsaWNlKGEsIFswLCAxXSk7XG4gICAgZXhwZWN0KGIuc2hhcGUpLnRvRXF1YWwoWzMsIDNdKTtcbiAgICBleHBlY3RBcnJheXNDbG9zZShhd2FpdCBiLmRhdGEoKSwgWzIsIDMsIDQsIDYsIDcsIDgsIDEwLCAxMSwgMTJdKTtcbiAgfSk7XG5cbiAgaXQoJ2ZsYXR0ZW4gYSBzbGljZWQgdGVuc29yIHRoYXQgd2FzIG5vdCBjb250aW51b3VzIGluIG1lbW9yeScsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBhID0gW1xuICAgICAgWzEsIDIsIDMsIDRdLFxuICAgICAgWzUsIDYsIDcsIDhdLFxuICAgICAgWzksIDEwLCAxMSwgMTJdLFxuICAgIF07ICAvLyAzeDQuXG4gICAgY29uc3QgYiA9IHRmLnNsaWNlKGEsIFswLCAxXSkuZmxhdHRlbigpO1xuICAgIGV4cGVjdChiLnNoYXBlKS50b0VxdWFsKFs5XSk7XG4gICAgZXhwZWN0QXJyYXlzQ2xvc2UoYXdhaXQgYi5kYXRhKCksIFsyLCAzLCA0LCA2LCA3LCA4LCAxMCwgMTEsIDEyXSk7XG4gIH0pO1xuXG4gIGl0KCdmbGF0dGVuIGEgc2xpY2VkIHRlbnNvciBub3QgY29udGludW91cyBpbiBtZW1vcnkgYW5kIHJ1biBwcm9ncmFtJyxcbiAgICAgYXN5bmMgKCkgPT4ge1xuICAgICAgIGNvbnN0IGEgPSBbXG4gICAgICAgICBbMSwgMiwgMywgNF0sXG4gICAgICAgICBbNSwgNiwgNywgOF0sXG4gICAgICAgICBbOSwgMTAsIDExLCAxMl0sXG4gICAgICAgXTsgIC8vIDN4NC5cbiAgICAgICBjb25zdCBiID0gdGYuc2xpY2UoYSwgWzAsIDFdKS5mbGF0dGVuKCk7XG4gICAgICAgY29uc3QgYyA9IHRmLnNxdWFyZShiKTtcbiAgICAgICBleHBlY3RBcnJheXNDbG9zZShhd2FpdCBjLmRhdGEoKSwgWzQsIDksIDE2LCAzNiwgNDksIDY0LCAxMDAsIDEyMSwgMTQ0XSk7XG4gICAgIH0pO1xuXG4gIGl0KCdyZXNoYXBlIGEgc2xpY2VkIDFkIGludG8gYSAyZCB0ZW5zb3InLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgYSA9IFsxLCAyLCAzLCA0LCA1XTtcbiAgICBjb25zdCBiID0gdGYuc2xpY2UoYSwgMSkuYXMyRCgyLCAyKTtcbiAgICBleHBlY3QoYi5zaGFwZSkudG9FcXVhbChbMiwgMl0pO1xuICAgIGV4cGVjdEFycmF5c0Nsb3NlKGF3YWl0IGIuZGF0YSgpLCBbMiwgMywgNCwgNV0pO1xuICB9KTtcblxuICBpdCgncmVzaGFwZSBhIHNsaWNlZCAxZCBpbnRvIGEgMmQgdGVuc29yIGFuZCBydW4gcHJvZ3JhbScsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBhID0gWzEsIDIsIDMsIDQsIDVdO1xuICAgIGNvbnN0IGIgPSB0Zi5zbGljZShhLCAxKS5hczJEKDIsIDIpLnNxdWFyZSgpO1xuICAgIGV4cGVjdChiLnNoYXBlKS50b0VxdWFsKFsyLCAyXSk7XG4gICAgZXhwZWN0QXJyYXlzQ2xvc2UoYXdhaXQgYi5kYXRhKCksIFs0LCA5LCAxNiwgMjVdKTtcbiAgfSk7XG5cbiAgaXQoJ2Jyb2FkY2FzdCB0aGUgb3JpZ2luYWwgd2l0aCB0aGUgc2xpY2VkIHRlbnNvcicsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBhID0gW1sxLCAyXSwgWzMsIDRdXTtcbiAgICBjb25zdCBiID0gdGYuc2xpY2UoYSwgWzAsIDFdKTtcbiAgICBjb25zdCBjID0gdGYuYWRkKGEsIGIpO1xuICAgIGV4cGVjdChjLnNoYXBlKS50b0VxdWFsKFsyLCAyXSk7XG4gICAgZXhwZWN0QXJyYXlzQ2xvc2UoYXdhaXQgYy5kYXRhKCksIFszLCA0LCA3LCA4XSk7XG4gIH0pO1xuXG4gIGl0KCd6ZXJvLXNpemVkIHNsaWNlIG91dCBvZiBhIG5vbi16ZXJvIHNpemVkIHRlbnNvcicsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBhID0gdGYuemVyb3MoWzQsIDJdKTtcbiAgICBjb25zdCByZXMgPSB0Zi5zbGljZShhLCBbMCwgMF0sIFswLCAyXSk7XG4gICAgZXhwZWN0KHJlcy5zaGFwZSkudG9FcXVhbChbMCwgMl0pO1xuICAgIGV4cGVjdEFycmF5c0Nsb3NlKGF3YWl0IHJlcy5kYXRhKCksIFtdKTtcbiAgfSk7XG5cbiAgaXQoJ3plcm8tc2l6ZWQgc2xpY2Ugb3V0IG9mIGEgemVyby1zaXplZCB0ZW5zb3InLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgYSA9IHRmLnplcm9zKFswLCA0XSk7XG4gICAgY29uc3QgcmVzID0gdGYuc2xpY2UoYSwgWzAsIDFdLCBbMCwgM10pO1xuICAgIGV4cGVjdChyZXMuc2hhcGUpLnRvRXF1YWwoWzAsIDNdKTtcbiAgICBleHBlY3RBcnJheXNDbG9zZShhd2FpdCByZXMuZGF0YSgpLCBbXSk7XG4gIH0pO1xufSk7XG4iXX0=
\No newline at end of file