UNPKG

28.6 kBJavaScriptView Raw
1/**
2 * @license
3 * Copyright 2017 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';
20import * as axis_util from './axis_util';
21describe('axis_util combineLocations', () => {
22 it('rank 4, reduce last 2 dims', () => {
23 const loc = axis_util.combineLocations([4, 1], [3, 7], [2, 3]);
24 expect(loc).toEqual([4, 1, 3, 7]);
25 });
26 it('rank 4, reduce first two dims', () => {
27 const loc = axis_util.combineLocations([4, 1], [3, 7], [0, 1]);
28 expect(loc).toEqual([3, 7, 4, 1]);
29 });
30 it('rank 4, reduce 1st and 3rd dims', () => {
31 const loc = axis_util.combineLocations([4, 1], [3, 7], [0, 2]);
32 expect(loc).toEqual([3, 4, 7, 1]);
33 });
34 it('rank 4, reduce 1st and 4th dims', () => {
35 const loc = axis_util.combineLocations([4, 1], [3, 7], [0, 3]);
36 expect(loc).toEqual([3, 4, 1, 7]);
37 });
38 it('rank 3, reduce all dims', () => {
39 const loc = axis_util.combineLocations([], [3, 7, 1], [0, 1, 2]);
40 expect(loc).toEqual([3, 7, 1]);
41 });
42 it('rank 2, reduce last dim', () => {
43 const loc = axis_util.combineLocations([3], [5], [1]);
44 expect(loc).toEqual([3, 5]);
45 });
46 it('rank 2, reduce first dim', () => {
47 const loc = axis_util.combineLocations([3], [5], [0]);
48 expect(loc).toEqual([5, 3]);
49 });
50});
51describe('axis_util computeOutAndReduceShapes', () => {
52 it('rank 4, reduce all dims', () => {
53 const [out, red] = axis_util.computeOutAndReduceShapes([3, 7, 2, 4], [0, 1, 2, 3]);
54 expect(out).toEqual([]);
55 expect(red).toEqual([3, 7, 2, 4]);
56 });
57 it('rank 4, reduce last 2 dims', () => {
58 const [out, red] = axis_util.computeOutAndReduceShapes([3, 7, 2, 4], [2, 3]);
59 expect(out).toEqual([3, 7]);
60 expect(red).toEqual([2, 4]);
61 });
62 it('rank 4, reduce first 2 dims', () => {
63 const [out, red] = axis_util.computeOutAndReduceShapes([3, 7, 2, 4], [0, 1]);
64 expect(out).toEqual([2, 4]);
65 expect(red).toEqual([3, 7]);
66 });
67 it('rank 4, reduce last 3 dims', () => {
68 const [out, red] = axis_util.computeOutAndReduceShapes([3, 7, 2, 4], [1, 2, 3]);
69 expect(out).toEqual([3]);
70 expect(red).toEqual([7, 2, 4]);
71 });
72 it('rank 4, reduce 1st and 3rd dims', () => {
73 const [out, red] = axis_util.computeOutAndReduceShapes([3, 7, 2, 4], [0, 2]);
74 expect(out).toEqual([7, 4]);
75 expect(red).toEqual([3, 2]);
76 });
77 it('rank 3, reduce all dims', () => {
78 const [out, red] = axis_util.computeOutAndReduceShapes([3, 7, 2], [0, 1, 2]);
79 expect(out).toEqual([]);
80 expect(red).toEqual([3, 7, 2]);
81 });
82});
83describe('axis_util axesAreInnerMostDims', () => {
84 it('rank 4, reduce last dim', () => {
85 const res = axis_util.axesAreInnerMostDims([3], 4);
86 expect(res).toBe(true);
87 });
88 it('rank 4, reduce last 2 dims', () => {
89 const res = axis_util.axesAreInnerMostDims([2, 3], 4);
90 expect(res).toBe(true);
91 });
92 it('rank 4, reduce last 3 dims', () => {
93 const res = axis_util.axesAreInnerMostDims([1, 2, 3], 4);
94 expect(res).toBe(true);
95 });
96 it('rank 4, reduce all dims', () => {
97 const res = axis_util.axesAreInnerMostDims([0, 1, 2, 3], 4);
98 expect(res).toBe(true);
99 });
100 it('rank 4, reduce all but 2nd', () => {
101 const res = axis_util.axesAreInnerMostDims([0, 2, 3], 4);
102 expect(res).toBe(false);
103 });
104 it('rank 4, reduce all but 3rd', () => {
105 const res = axis_util.axesAreInnerMostDims([0, 1, 3], 4);
106 expect(res).toBe(false);
107 });
108 it('rank 4, reduce all but last', () => {
109 const res = axis_util.axesAreInnerMostDims([0, 1, 2], 4);
110 expect(res).toBe(false);
111 });
112});
113describe('axis_util expandShapeToKeepDim', () => {
114 it('2d -> 1d axis=0', () => {
115 const shape = axis_util.expandShapeToKeepDim([2], [0]);
116 expect(shape).toEqual([1, 2]);
117 });
118 it('2d -> 1d axis=1', () => {
119 const shape = axis_util.expandShapeToKeepDim([4], [1]);
120 expect(shape).toEqual([4, 1]);
121 });
122 it('3d -> 1d axis=1,2', () => {
123 const shape = axis_util.expandShapeToKeepDim([7], [1, 2]);
124 expect(shape).toEqual([7, 1, 1]);
125 });
126 it('3d -> 2d axis=1', () => {
127 const shape = axis_util.expandShapeToKeepDim([7, 3], [1]);
128 expect(shape).toEqual([7, 1, 3]);
129 });
130});
131describe('axis_util getPermAxes', () => {
132 it('all axes, no perm is needed', () => {
133 const perm = axis_util.getAxesPermutation([0, 1, 2], 3);
134 expect(perm).toBeNull();
135 });
136 it('no axes, no perm is needed', () => {
137 const perm = axis_util.getAxesPermutation([], 3);
138 expect(perm).toBeNull();
139 });
140 it('inner most 2 axes, no perm is needed', () => {
141 const perm = axis_util.getAxesPermutation([2, 3], 4);
142 expect(perm).toBeNull();
143 });
144 it('outer most axis, perm is needed', () => {
145 const perm = axis_util.getAxesPermutation([0], 4);
146 expect(perm).toEqual([1, 2, 3, 0]);
147 });
148 it('2 outer most axes, perm is needed', () => {
149 const perm = axis_util.getAxesPermutation([0, 1], 4);
150 expect(perm).toEqual([2, 3, 0, 1]);
151 });
152});
153describeWithFlags('axis_util getUndoAxesPermutation', ALL_ENVS, () => {
154 it('4d axes', () => {
155 const axes = [2, 0, 1, 3];
156 expect(axis_util.getUndoAxesPermutation(axes)).toEqual([1, 2, 0, 3]);
157 });
158 it('3d axes, no perm', () => {
159 const axes = [0, 1, 2];
160 expect(axis_util.getUndoAxesPermutation(axes)).toEqual([0, 1, 2]);
161 });
162 it('3d axes, complete flip', () => {
163 const axes = [2, 1, 0];
164 expect(axis_util.getUndoAxesPermutation(axes)).toEqual([2, 1, 0]);
165 });
166 it('4d array with values', async () => {
167 const axes = [2, 0, 1, 3];
168 const undoPermutation = axis_util.getUndoAxesPermutation(axes);
169 const a = tf.randomNormal([2, 3, 4, 5]);
170 const aT = tf.transpose(a, axes);
171 const aTT = tf.transpose(aT, undoPermutation);
172 expectArraysClose(await a.data(), await aTT.data());
173 });
174});
175//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXhpc191dGlsX3Rlc3QuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi90ZmpzLWNvcmUvc3JjL29wcy9heGlzX3V0aWxfdGVzdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7O0dBZUc7QUFFSCxPQUFPLEtBQUssRUFBRSxNQUFNLFVBQVUsQ0FBQztBQUMvQixPQUFPLEVBQUMsUUFBUSxFQUFFLGlCQUFpQixFQUFDLE1BQU0saUJBQWlCLENBQUM7QUFDNUQsT0FBTyxFQUFDLGlCQUFpQixFQUFDLE1BQU0sY0FBYyxDQUFDO0FBRS9DLE9BQU8sS0FBSyxTQUFTLE1BQU0sYUFBYSxDQUFDO0FBRXpDLFFBQVEsQ0FBQyw0QkFBNEIsRUFBRSxHQUFHLEVBQUU7SUFDMUMsRUFBRSxDQUFDLDRCQUE0QixFQUFFLEdBQUcsRUFBRTtRQUNwQyxNQUFNLEdBQUcsR0FBRyxTQUFTLENBQUMsZ0JBQWdCLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUMvRCxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUNwQyxDQUFDLENBQUMsQ0FBQztJQUVILEVBQUUsQ0FBQywrQkFBK0IsRUFBRSxHQUFHLEVBQUU7UUFDdkMsTUFBTSxHQUFHLEdBQUcsU0FBUyxDQUFDLGdCQUFnQixDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDL0QsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsRUFB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QyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7UUFDMUIsTUFBTSxlQUFlLEdBQUcsU0FBUyxDQUFDLHNCQUFzQixDQUFDLElBQUksQ0FBQyxDQUFDO1FBRS9ELE1BQU0sQ0FBQyxHQUFHLEVBQUUsQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3hDLE1BQU0sRUFBRSxHQUFHLEVBQUUsQ0FBQyxTQUFTLENBQUMsQ0FBQyxFQUFFLElBQUksQ0FBQyxDQUFDO1FBQ2pDLE1BQU0sR0FBRyxHQUFHLEVBQUUsQ0FBQyxTQUFTLENBQUMsRUFBRSxFQUFFLGVBQWUsQ0FBQyxDQUFDO1FBQzlDLGlCQUFpQixDQUFDLE1BQU0sQ0FBQyxDQUFDLElBQUksRUFBRSxFQUFFLE1BQU0sR0FBRyxDQUFDLElBQUksRUFBRSxDQUFDLENBQUM7SUFDdEQsQ0FBQyxDQUFDLENBQUM7QUFDTCxDQUFDLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQGxpY2Vuc2VcbiAqIENvcHlyaWdodCAyMDE3IEdvb2dsZSBMTEMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gKi9cblxuaW1wb3J0ICogYXMgdGYgZnJvbSAnLi4vaW5kZXgnO1xuaW1wb3J0IHtBTExfRU5WUywgZGVzY3JpYmVXaXRoRmxhZ3N9IGZyb20gJy4uL2phc21pbmVfdXRpbCc7XG5pbXBvcnQge2V4cGVjdEFycmF5c0Nsb3NlfSBmcm9tICcuLi90ZXN0X3V0aWwnO1xuXG5pbXBvcnQgKiBhcyBheGlzX3V0aWwgZnJvbSAnLi9heGlzX3V0aWwnO1xuXG5kZXNjcmliZSgnYXhpc191dGlsIGNvbWJpbmVMb2NhdGlvbnMnLCAoKSA9PiB7XG4gIGl0KCdyYW5rIDQsIHJlZHVjZSBsYXN0IDIgZGltcycsICgpID0+IHtcbiAgICBjb25zdCBsb2MgPSBheGlzX3V0aWwuY29tYmluZUxvY2F0aW9ucyhbNCwgMV0sIFszLCA3XSwgWzIsIDNdKTtcbiAgICBleHBlY3QobG9jKS50b0VxdWFsKFs0LCAxLCAzLCA3XSk7XG4gIH0pO1xuXG4gIGl0KCdyYW5rIDQsIHJlZHVjZSBmaXJzdCB0d28gZGltcycsICgpID0+IHtcbiAgICBjb25zdCBsb2MgPSBheGlzX3V0aWwuY29tYmluZUxvY2F0aW9ucyhbNCwgMV0sIFszLCA3XSwgWzAsIDFdKTtcbiAgICBleHBlY3QobG9jKS50b0VxdWFsKFszLCA3LCA0LCAxXSk7XG4gIH0pO1xuXG4gIGl0KCdyYW5rIDQsIHJlZHVjZSAxc3QgYW5kIDNyZCBkaW1zJywgKCkgPT4ge1xuICAgIGNvbnN0IGxvYyA9IGF4aXNfdXRpbC5jb21iaW5lTG9jYXRpb25zKFs0LCAxXSwgWzMsIDddLCBbMCwgMl0pO1xuICAgIGV4cGVjdChsb2MpLnRvRXF1YWwoWzMsIDQsIDcsIDFdKTtcbiAgfSk7XG5cbiAgaXQoJ3JhbmsgNCwgcmVkdWNlIDFzdCBhbmQgNHRoIGRpbXMnLCAoKSA9PiB7XG4gICAgY29uc3QgbG9jID0gYXhpc191dGlsLmNvbWJpbmVMb2NhdGlvbnMoWzQsIDFdLCBbMywgN10sIFswLCAzXSk7XG4gICAgZXhwZWN0KGxvYykudG9FcXVhbChbMywgNCwgMSwgN10pO1xuICB9KTtcblxuICBpdCgncmFuayAzLCByZWR1Y2UgYWxsIGRpbXMnLCAoKSA9PiB7XG4gICAgY29uc3QgbG9jID0gYXhpc191dGlsLmNvbWJpbmVMb2NhdGlvbnMoW10sIFszLCA3LCAxXSwgWzAsIDEsIDJdKTtcbiAgICBleHBlY3QobG9jKS50b0VxdWFsKFszLCA3LCAxXSk7XG4gIH0pO1xuXG4gIGl0KCdyYW5rIDIsIHJlZHVjZSBsYXN0IGRpbScsICgpID0+IHtcbiAgICBjb25zdCBsb2MgPSBheGlzX3V0aWwuY29tYmluZUxvY2F0aW9ucyhbM10sIFs1XSwgWzFdKTtcbiAgICBleHBlY3QobG9jKS50b0VxdWFsKFszLCA1XSk7XG4gIH0pO1xuXG4gIGl0KCdyYW5rIDIsIHJlZHVjZSBmaXJzdCBkaW0nLCAoKSA9PiB7XG4gICAgY29uc3QgbG9jID0gYXhpc191dGlsLmNvbWJpbmVMb2NhdGlvbnMoWzNdLCBbNV0sIFswXSk7XG4gICAgZXhwZWN0KGxvYykudG9FcXVhbChbNSwgM10pO1xuICB9KTtcbn0pO1xuXG5kZXNjcmliZSgnYXhpc191dGlsIGNvbXB1dGVPdXRBbmRSZWR1Y2VTaGFwZXMnLCAoKSA9PiB7XG4gIGl0KCdyYW5rIDQsIHJlZHVjZSBhbGwgZGltcycsICgpID0+IHtcbiAgICBjb25zdCBbb3V0LCByZWRdID1cbiAgICAgICAgYXhpc191dGlsLmNvbXB1dGVPdXRBbmRSZWR1Y2VTaGFwZXMoWzMsIDcsIDIsIDRdLCBbMCwgMSwgMiwgM10pO1xuICAgIGV4cGVjdChvdXQpLnRvRXF1YWwoW10pO1xuICAgIGV4cGVjdChyZWQpLnRvRXF1YWwoWzMsIDcsIDIsIDRdKTtcbiAgfSk7XG5cbiAgaXQoJ3JhbmsgNCwgcmVkdWNlIGxhc3QgMiBkaW1zJywgKCkgPT4ge1xuICAgIGNvbnN0IFtvdXQsIHJlZF0gPVxuICAgICAgICBheGlzX3V0aWwuY29tcHV0ZU91dEFuZFJlZHVjZVNoYXBlcyhbMywgNywgMiwgNF0sIFsyLCAzXSk7XG4gICAgZXhwZWN0KG91dCkudG9FcXVhbChbMywgN10pO1xuICAgIGV4cGVjdChyZWQpLnRvRXF1YWwoWzIsIDRdKTtcbiAgfSk7XG5cbiAgaXQoJ3JhbmsgNCwgcmVkdWNlIGZpcnN0IDIgZGltcycsICgpID0+IHtcbiAgICBjb25zdCBbb3V0LCByZWRdID1cbiAgICAgICAgYXhpc191dGlsLmNvbXB1dGVPdXRBbmRSZWR1Y2VTaGFwZXMoWzMsIDcsIDIsIDRdLCBbMCwgMV0pO1xuICAgIGV4cGVjdChvdXQpLnRvRXF1YWwoWzIsIDRdKTtcbiAgICBleHBlY3QocmVkKS50b0VxdWFsKFszLCA3XSk7XG4gIH0pO1xuXG4gIGl0KCdyYW5rIDQsIHJlZHVjZSBsYXN0IDMgZGltcycsICgpID0+IHtcbiAgICBjb25zdCBbb3V0LCByZWRdID1cbiAgICAgICAgYXhpc191dGlsLmNvbXB1dGVPdXRBbmRSZWR1Y2VTaGFwZXMoWzMsIDcsIDIsIDRdLCBbMSwgMiwgM10pO1xuICAgIGV4cGVjdChvdXQpLnRvRXF1YWwoWzNdKTtcbiAgICBleHBlY3QocmVkKS50b0VxdWFsKFs3LCAyLCA0XSk7XG4gIH0pO1xuXG4gIGl0KCdyYW5rIDQsIHJlZHVjZSAxc3QgYW5kIDNyZCBkaW1zJywgKCkgPT4ge1xuICAgIGNvbnN0IFtvdXQsIHJlZF0gPVxuICAgICAgICBheGlzX3V0aWwuY29tcHV0ZU91dEFuZFJlZHVjZVNoYXBlcyhbMywgNywgMiwgNF0sIFswLCAyXSk7XG4gICAgZXhwZWN0KG91dCkudG9FcXVhbChbNywgNF0pO1xuICAgIGV4cGVjdChyZWQpLnRvRXF1YWwoWzMsIDJdKTtcbiAgfSk7XG5cbiAgaXQoJ3JhbmsgMywgcmVkdWNlIGFsbCBkaW1zJywgKCkgPT4ge1xuICAgIGNvbnN0IFtvdXQsIHJlZF0gPVxuICAgICAgICBheGlzX3V0aWwuY29tcHV0ZU91dEFuZFJlZHVjZVNoYXBlcyhbMywgNywgMl0sIFswLCAxLCAyXSk7XG4gICAgZXhwZWN0KG91dCkudG9FcXVhbChbXSk7XG4gICAgZXhwZWN0KHJlZCkudG9FcXVhbChbMywgNywgMl0pO1xuICB9KTtcbn0pO1xuXG5kZXNjcmliZSgnYXhpc191dGlsIGF4ZXNBcmVJbm5lck1vc3REaW1zJywgKCkgPT4ge1xuICBpdCgncmFuayA0LCByZWR1Y2UgbGFzdCBkaW0nLCAoKSA9PiB7XG4gICAgY29uc3QgcmVzID0gYXhpc191dGlsLmF4ZXNBcmVJbm5lck1vc3REaW1zKFszXSwgNCk7XG4gICAgZXhwZWN0KHJlcykudG9CZSh0cnVlKTtcbiAgfSk7XG5cbiAgaXQoJ3JhbmsgNCwgcmVkdWNlIGxhc3QgMiBkaW1zJywgKCkgPT4ge1xuICAgIGNvbnN0IHJlcyA9IGF4aXNfdXRpbC5heGVzQXJlSW5uZXJNb3N0RGltcyhbMiwgM10sIDQpO1xuICAgIGV4cGVjdChyZXMpLnRvQmUodHJ1ZSk7XG4gIH0pO1xuXG4gIGl0KCdyYW5rIDQsIHJlZHVjZSBsYXN0IDMgZGltcycsICgpID0+IHtcbiAgICBjb25zdCByZXMgPSBheGlzX3V0aWwuYXhlc0FyZUlubmVyTW9zdERpbXMoWzEsIDIsIDNdLCA0KTtcbiAgICBleHBlY3QocmVzKS50b0JlKHRydWUpO1xuICB9KTtcblxuICBpdCgncmFuayA0LCByZWR1Y2UgYWxsIGRpbXMnLCAoKSA9PiB7XG4gICAgY29uc3QgcmVzID0gYXhpc191dGlsLmF4ZXNBcmVJbm5lck1vc3REaW1zKFswLCAxLCAyLCAzXSwgNCk7XG4gICAgZXhwZWN0KHJlcykudG9CZSh0cnVlKTtcbiAgfSk7XG5cbiAgaXQoJ3JhbmsgNCwgcmVkdWNlIGFsbCBidXQgMm5kJywgKCkgPT4ge1xuICAgIGNvbnN0IHJlcyA9IGF4aXNfdXRpbC5heGVzQXJlSW5uZXJNb3N0RGltcyhbMCwgMiwgM10sIDQpO1xuICAgIGV4cGVjdChyZXMpLnRvQmUoZmFsc2UpO1xuICB9KTtcblxuICBpdCgncmFuayA0LCByZWR1Y2UgYWxsIGJ1dCAzcmQnLCAoKSA9PiB7XG4gICAgY29uc3QgcmVzID0gYXhpc191dGlsLmF4ZXNBcmVJbm5lck1vc3REaW1zKFswLCAxLCAzXSwgNCk7XG4gICAgZXhwZWN0KHJlcykudG9CZShmYWxzZSk7XG4gIH0pO1xuXG4gIGl0KCdyYW5rIDQsIHJlZHVjZSBhbGwgYnV0IGxhc3QnLCAoKSA9PiB7XG4gICAgY29uc3QgcmVzID0gYXhpc191dGlsLmF4ZXNBcmVJbm5lck1vc3REaW1zKFswLCAxLCAyXSwgNCk7XG4gICAgZXhwZWN0KHJlcykudG9CZShmYWxzZSk7XG4gIH0pO1xufSk7XG5cbmRlc2NyaWJlKCdheGlzX3V0aWwgZXhwYW5kU2hhcGVUb0tlZXBEaW0nLCAoKSA9PiB7XG4gIGl0KCcyZCAtPiAxZCBheGlzPTAnLCAoKSA9PiB7XG4gICAgY29uc3Qgc2hhcGUgPSBheGlzX3V0aWwuZXhwYW5kU2hhcGVUb0tlZXBEaW0oWzJdLCBbMF0pO1xuICAgIGV4cGVjdChzaGFwZSkudG9FcXVhbChbMSwgMl0pO1xuICB9KTtcblxuICBpdCgnMmQgLT4gMWQgYXhpcz0xJywgKCkgPT4ge1xuICAgIGNvbnN0IHNoYXBlID0gYXhpc191dGlsLmV4cGFuZFNoYXBlVG9LZWVwRGltKFs0XSwgWzFdKTtcbiAgICBleHBlY3Qoc2hhcGUpLnRvRXF1YWwoWzQsIDFdKTtcbiAgfSk7XG5cbiAgaXQoJzNkIC0+IDFkIGF4aXM9MSwyJywgKCkgPT4ge1xuICAgIGNvbnN0IHNoYXBlID0gYXhpc191dGlsLmV4cGFuZFNoYXBlVG9LZWVwRGltKFs3XSwgWzEsIDJdKTtcbiAgICBleHBlY3Qoc2hhcGUpLnRvRXF1YWwoWzcsIDEsIDFdKTtcbiAgfSk7XG5cbiAgaXQoJzNkIC0+IDJkIGF4aXM9MScsICgpID0+IHtcbiAgICBjb25zdCBzaGFwZSA9IGF4aXNfdXRpbC5leHBhbmRTaGFwZVRvS2VlcERpbShbNywgM10sIFsxXSk7XG4gICAgZXhwZWN0KHNoYXBlKS50b0VxdWFsKFs3LCAxLCAzXSk7XG4gIH0pO1xufSk7XG5cbmRlc2NyaWJlKCdheGlzX3V0aWwgZ2V0UGVybUF4ZXMnLCAoKSA9PiB7XG4gIGl0KCdhbGwgYXhlcywgbm8gcGVybSBpcyBuZWVkZWQnLCAoKSA9PiB7XG4gICAgY29uc3QgcGVybSA9IGF4aXNfdXRpbC5nZXRBeGVzUGVybXV0YXRpb24oWzAsIDEsIDJdLCAzKTtcbiAgICBleHBlY3QocGVybSkudG9CZU51bGwoKTtcbiAgfSk7XG5cbiAgaXQoJ25vIGF4ZXMsIG5vIHBlcm0gaXMgbmVlZGVkJywgKCkgPT4ge1xuICAgIGNvbnN0IHBlcm0gPSBheGlzX3V0aWwuZ2V0QXhlc1Blcm11dGF0aW9uKFtdLCAzKTtcbiAgICBleHBlY3QocGVybSkudG9CZU51bGwoKTtcbiAgfSk7XG5cbiAgaXQoJ2lubmVyIG1vc3QgMiBheGVzLCBubyBwZXJtIGlzIG5lZWRlZCcsICgpID0+IHtcbiAgICBjb25zdCBwZXJtID0gYXhpc191dGlsLmdldEF4ZXNQZXJtdXRhdGlvbihbMiwgM10sIDQpO1xuICAgIGV4cGVjdChwZXJtKS50b0JlTnVsbCgpO1xuICB9KTtcblxuICBpdCgnb3V0ZXIgbW9zdCBheGlzLCBwZXJtIGlzIG5lZWRlZCcsICgpID0+IHtcbiAgICBjb25zdCBwZXJtID0gYXhpc191dGlsLmdldEF4ZXNQZXJtdXRhdGlvbihbMF0sIDQpO1xuICAgIGV4cGVjdChwZXJtKS50b0VxdWFsKFsxLCAyLCAzLCAwXSk7XG4gIH0pO1xuXG4gIGl0KCcyIG91dGVyIG1vc3QgYXhlcywgcGVybSBpcyBuZWVkZWQnLCAoKSA9PiB7XG4gICAgY29uc3QgcGVybSA9IGF4aXNfdXRpbC5nZXRBeGVzUGVybXV0YXRpb24oWzAsIDFdLCA0KTtcbiAgICBleHBlY3QocGVybSkudG9FcXVhbChbMiwgMywgMCwgMV0pO1xuICB9KTtcbn0pO1xuXG5kZXNjcmliZVdpdGhGbGFncygnYXhpc191dGlsIGdldFVuZG9BeGVzUGVybXV0YXRpb24nLCBBTExfRU5WUywgKCkgPT4ge1xuICBpdCgnNGQgYXhlcycsICgpID0+IHtcbiAgICBjb25zdCBheGVzID0gWzIsIDAsIDEsIDNdO1xuICAgIGV4cGVjdChheGlzX3V0aWwuZ2V0VW5kb0F4ZXNQZXJtdXRhdGlvbihheGVzKSkudG9FcXVhbChbMSwgMiwgMCwgM10pO1xuICB9KTtcblxuICBpdCgnM2QgYXhlcywgbm8gcGVybScsICgpID0+IHtcbiAgICBjb25zdCBheGVzID0gWzAsIDEsIDJdO1xuICAgIGV4cGVjdChheGlzX3V0aWwuZ2V0VW5kb0F4ZXNQZXJtdXRhdGlvbihheGVzKSkudG9FcXVhbChbMCwgMSwgMl0pO1xuICB9KTtcblxuICBpdCgnM2QgYXhlcywgY29tcGxldGUgZmxpcCcsICgpID0+IHtcbiAgICBjb25zdCBheGVzID0gWzIsIDEsIDBdO1xuICAgIGV4cGVjdChheGlzX3V0aWwuZ2V0VW5kb0F4ZXNQZXJtdXRhdGlvbihheGVzKSkudG9FcXVhbChbMiwgMSwgMF0pO1xuICB9KTtcblxuICBpdCgnNGQgYXJyYXkgd2l0aCB2YWx1ZXMnLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgYXhlcyA9IFsyLCAwLCAxLCAzXTtcbiAgICBjb25zdCB1bmRvUGVybXV0YXRpb24gPSBheGlzX3V0aWwuZ2V0VW5kb0F4ZXNQZXJtdXRhdGlvbihheGVzKTtcblxuICAgIGNvbnN0IGEgPSB0Zi5yYW5kb21Ob3JtYWwoWzIsIDMsIDQsIDVdKTtcbiAgICBjb25zdCBhVCA9IHRmLnRyYW5zcG9zZShhLCBheGVzKTtcbiAgICBjb25zdCBhVFQgPSB0Zi50cmFuc3Bvc2UoYVQsIHVuZG9QZXJtdXRhdGlvbik7XG4gICAgZXhwZWN0QXJyYXlzQ2xvc2UoYXdhaXQgYS5kYXRhKCksIGF3YWl0IGFUVC5kYXRhKCkpO1xuICB9KTtcbn0pO1xuIl19
\No newline at end of file