UNPKG

24.6 kBJavaScriptView Raw
1/**
2 * @license
3 * Copyright 2018 Google LLC
4 *
5 * Use of this source code is governed by an MIT-style
6 * license that can be found in the LICENSE file or at
7 * https://opensource.org/licenses/MIT.
8 * =============================================================================
9 */
10import * as tfc from '@tensorflow/tfjs-core';
11import { Dataset, LazyIterator } from './dataset_stub';
12function mergeBatchSizeAndShape(batchSize, shape) {
13 if (Array.isArray(shape)) {
14 return [batchSize].concat(shape);
15 }
16 else {
17 const output = {};
18 for (const name in shape) {
19 output[name] = [batchSize].concat(shape[name]);
20 }
21 return output;
22 }
23}
24function generateRandomTensorContainer(shape) {
25 let output;
26 if (Array.isArray(shape)) {
27 output = tfc.randomNormal(shape);
28 }
29 else {
30 output = {};
31 for (const name in shape) {
32 output[name] = tfc.randomNormal(shape[name]);
33 }
34 }
35 return output;
36}
37class FakeNumericIterator extends LazyIterator {
38 constructor(args) {
39 super();
40 this.tensorIndex = 0;
41 this.xBatchShape = mergeBatchSizeAndShape(args.batchSize, args.xShape);
42 this.yBatchShape = mergeBatchSizeAndShape(args.batchSize, args.yShape);
43 this.numBatches = args.numBatches;
44 this.batchCount = 0;
45 this.xTensorsFunc = args.xTensorsFunc;
46 this.yTensorsFunc = args.yTensorsFunc;
47 // Sanity check on the preset tensors.
48 tfc.util.assert(this.xTensorsFunc == null && this.yTensorsFunc == null ||
49 this.xTensorsFunc != null && this.yTensorsFunc != null, () => 'presetXTensors and presetYTensors must be both null/undefined ' +
50 'or both set.');
51 }
52 async next() {
53 const done = ++this.batchCount > this.numBatches;
54 if (done) {
55 return { done, value: null };
56 }
57 if (this.xTensorsFunc == null) {
58 // Generate data randomly.
59 return {
60 done,
61 value: done ? null : {
62 xs: generateRandomTensorContainer(this.xBatchShape),
63 ys: generateRandomTensorContainer(this.yBatchShape)
64 }
65 };
66 }
67 else {
68 // Use preset tensors.
69 if ((this.batchCount - 1) % this.numBatches === 0) {
70 this.xTensorValues = this.xTensorsFunc();
71 this.yTensorValues = this.yTensorsFunc();
72 this.tensorIndex = 0;
73 }
74 const index = this.tensorIndex++;
75 let xs;
76 if (Array.isArray(this.xTensorValues)) {
77 xs = this.xTensorValues[index];
78 tfc.util.assert(tfc.util.arraysEqual(xs.shape, this.xBatchShape), () => `Shape mismatch: expected: ${JSON.stringify(this.xBatchShape)}; ` +
79 `actual: ${JSON.stringify(xs.shape)}`);
80 }
81 else {
82 xs = {};
83 for (const key in this.xTensorValues) {
84 xs[key] = this.xTensorValues[key][index];
85 tfc.util.assert(tfc.util.arraysEqual(xs[key].shape, this.xBatchShape), () => `Shape mismatch: expected: ${JSON.stringify(this.xBatchShape)}; ` +
86 `actual: ${JSON.stringify(xs.shape)}`);
87 }
88 }
89 let ys;
90 if (Array.isArray(this.yTensorValues)) {
91 // Get preset ys tensors for single-output models.
92 ys = this.yTensorValues[index];
93 tfc.util.assert(tfc.util.arraysEqual(ys.shape, this.yBatchShape), () => `Shape mismatch: expected: ${JSON.stringify(this.yBatchShape)}; ` +
94 `actual: ${JSON.stringify(ys.shape)}`);
95 }
96 else {
97 // Get preset ys tensors for multi-output models.
98 ys = {};
99 this.yBatchShape = this.yBatchShape;
100 for (const key in this.yTensorValues) {
101 ys[key] = this.yTensorValues[key][index];
102 tfc.util.assert(tfc.util.arraysEqual(ys[key].shape, this.yBatchShape[key]), () => `Shape mismatch: expected: ${JSON.stringify(this.yBatchShape)}; ` +
103 `actual: ${JSON.stringify(ys[key].shape)}`);
104 }
105 }
106 return { done, value: { xs, ys } };
107 }
108 }
109}
110/**
111 * A fake dataset with configurable feature and target shapes.
112 *
113 * The batch size and # of batches are also configurable.
114 *
115 * The iterator from the dataset always generate random-normal float32 values.
116 */
117export class FakeNumericDataset extends Dataset {
118 constructor(args) {
119 super();
120 this.args = args;
121 tfc.util.assert(args.batchSize > 0 && Number.isInteger(args.batchSize), () => `batchSize must be a positive integer, but got ${args.batchSize}`);
122 tfc.util.assert(args.numBatches > 0 && Number.isInteger(args.numBatches), () => `numBatches must be positive integer, but got ${args.numBatches}`);
123 this.size = args.numBatches;
124 }
125 async iterator() {
126 return new FakeNumericIterator(this.args);
127 }
128}
129// We can't use Dataset.map(...) because we don't depend on tfjs-data here,
130// so we manually transform the above {xs, ys} dataset to the [xs, ys] form.
131export class FakeNumericDatasetLegacyArrayForm extends Dataset {
132 constructor(args) {
133 super();
134 this.args = args;
135 this.ds = new FakeNumericDataset(args);
136 }
137 async iterator() {
138 const it = await this.ds.iterator();
139 return new FakeNumericIteratorLegacyArrayForm(it);
140 }
141}
142class FakeNumericIteratorLegacyArrayForm extends LazyIterator {
143 constructor(it) {
144 super();
145 this.it = it;
146 }
147 async next() {
148 const result = await this.it.next();
149 return {
150 done: result.done,
151 value: result.value == null ? null : [result.value.xs, result.value.ys]
152 };
153 }
154}
155//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGF0YXNldF9mYWtlcy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3RmanMtbGF5ZXJzL3NyYy9lbmdpbmUvZGF0YXNldF9mYWtlcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7R0FRRztBQUVILE9BQU8sS0FBSyxHQUFHLE1BQU0sdUJBQXVCLENBQUM7QUFLN0MsT0FBTyxFQUFDLE9BQU8sRUFBRSxZQUFZLEVBQUMsTUFBTSxnQkFBZ0IsQ0FBQztBQTJDckQsU0FBUyxzQkFBc0IsQ0FDM0IsU0FBaUIsRUFBRSxLQUFvQztJQUV6RCxJQUFJLEtBQUssQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLEVBQUU7UUFDeEIsT0FBTyxDQUFDLFNBQVMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQztLQUNsQztTQUFNO1FBQ0wsTUFBTSxNQUFNLEdBQTRCLEVBQUUsQ0FBQztRQUMzQyxLQUFLLE1BQU0sSUFBSSxJQUFJLEtBQUssRUFBRTtZQUN4QixNQUFNLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxTQUFTLENBQUMsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUM7U0FDaEQ7UUFDRCxPQUFPLE1BQU0sQ0FBQztLQUNmO0FBQ0gsQ0FBQztBQUVELFNBQVMsNkJBQTZCLENBQUMsS0FBb0M7SUFFekUsSUFBSSxNQUErQyxDQUFDO0lBQ3BELElBQUksS0FBSyxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsRUFBRTtRQUN4QixNQUFNLEdBQUcsR0FBRyxDQUFDLFlBQVksQ0FBQyxLQUFLLENBQUMsQ0FBQztLQUNsQztTQUFNO1FBQ0wsTUFBTSxHQUFHLEVBQUUsQ0FBQztRQUNaLEtBQUssTUFBTSxJQUFJLElBQUksS0FBSyxFQUFFO1lBQ3hCLE1BQU0sQ0FBQyxJQUFJLENBQUMsR0FBRyxHQUFHLENBQUMsWUFBWSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDO1NBQzlDO0tBQ0Y7SUFDRCxPQUFPLE1BQU0sQ0FBQztBQUNoQixDQUFDO0FBRUQsTUFBTSxtQkFBb0IsU0FBUSxZQUErQjtJQVcvRCxZQUFZLElBQXFCO1FBQy9CLEtBQUssRUFBRSxDQUFDO1FBSEYsZ0JBQVcsR0FBRyxDQUFDLENBQUM7UUFJdEIsSUFBSSxDQUFDLFdBQVcsR0FBRyxzQkFBc0IsQ0FBQyxJQUFJLENBQUMsU0FBUyxFQUFFLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUN2RSxJQUFJLENBQUMsV0FBVyxHQUFHLHNCQUFzQixDQUFDLElBQUksQ0FBQyxTQUFTLEVBQUUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQ3ZFLElBQUksQ0FBQyxVQUFVLEdBQUcsSUFBSSxDQUFDLFVBQVUsQ0FBQztRQUNsQyxJQUFJLENBQUMsVUFBVSxHQUFHLENBQUMsQ0FBQztRQUNwQixJQUFJLENBQUMsWUFBWSxHQUFHLElBQUksQ0FBQyxZQUFZLENBQUM7UUFDdEMsSUFBSSxDQUFDLFlBQVksR0FBRyxJQUFJLENBQUMsWUFBWSxDQUFDO1FBRXRDLHNDQUFzQztRQUN0QyxHQUFHLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FDWCxJQUFJLENBQUMsWUFBWSxJQUFJLElBQUksSUFBSSxJQUFJLENBQUMsWUFBWSxJQUFJLElBQUk7WUFDbEQsSUFBSSxDQUFDLFlBQVksSUFBSSxJQUFJLElBQUksSUFBSSxDQUFDLFlBQVksSUFBSSxJQUFJLEVBQzFELEdBQUcsRUFBRSxDQUFDLGdFQUFnRTtZQUNsRSxjQUFjLENBQUMsQ0FBQztJQUMxQixDQUFDO0lBRUQsS0FBSyxDQUFDLElBQUk7UUFDUixNQUFNLElBQUksR0FBRyxFQUFFLElBQUksQ0FBQyxVQUFVLEdBQUcsSUFBSSxDQUFDLFVBQVUsQ0FBQztRQUNqRCxJQUFJLElBQUksRUFBRTtZQUNSLE9BQU8sRUFBQyxJQUFJLEVBQUUsS0FBSyxFQUFFLElBQUksRUFBQyxDQUFDO1NBQzVCO1FBQ0QsSUFBSSxJQUFJLENBQUMsWUFBWSxJQUFJLElBQUksRUFBRTtZQUM3QiwwQkFBMEI7WUFDMUIsT0FBTztnQkFDTCxJQUFJO2dCQUNKLEtBQUssRUFBRSxJQUFJLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUM7b0JBQ25CLEVBQUUsRUFBRSw2QkFBNkIsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDO29CQUNuRCxFQUFFLEVBQUUsNkJBQTZCLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQztpQkFDcEQ7YUFDRixDQUFDO1NBQ0g7YUFBTTtZQUNMLHNCQUFzQjtZQUN0QixJQUFJLENBQUMsSUFBSSxDQUFDLFVBQVUsR0FBRyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsVUFBVSxLQUFLLENBQUMsRUFBRTtnQkFDakQsSUFBSSxDQUFDLGFBQWEsR0FBRyxJQUFJLENBQUMsWUFBWSxFQUFFLENBQUM7Z0JBQ3pDLElBQUksQ0FBQyxhQUFhLEdBQUcsSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFDO2dCQUN6QyxJQUFJLENBQUMsV0FBVyxHQUFHLENBQUMsQ0FBQzthQUN0QjtZQUNELE1BQU0sS0FBSyxHQUFHLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQztZQUVqQyxJQUFJLEVBQTJDLENBQUM7WUFDaEQsSUFBSSxLQUFLLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsRUFBRTtnQkFDckMsRUFBRSxHQUFHLElBQUksQ0FBQyxhQUFhLENBQUMsS0FBSyxDQUFDLENBQUM7Z0JBQy9CLEdBQUcsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUNYLEdBQUcsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLEVBQUUsQ0FBQyxLQUFLLEVBQUUsSUFBSSxDQUFDLFdBQW9CLENBQUMsRUFDekQsR0FBRyxFQUFFLENBQUMsNkJBQ0ksSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLElBQUk7b0JBQzFDLFdBQVcsSUFBSSxDQUFDLFNBQVMsQ0FBRSxFQUFpQixDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUMsQ0FBQzthQUNoRTtpQkFBTTtnQkFDTCxFQUFFLEdBQUcsRUFBRSxDQUFDO2dCQUNSLEtBQUssTUFBTSxHQUFHLElBQUksSUFBSSxDQUFDLGFBQWEsRUFBRTtvQkFDcEMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxHQUFHLElBQUksQ0FBQyxhQUFhLENBQUMsR0FBRyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUM7b0JBQ3pDLEdBQUcsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUNYLEdBQUcsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxLQUFLLEVBQUUsSUFBSSxDQUFDLFdBQW9CLENBQUMsRUFDOUQsR0FBRyxFQUFFLENBQUMsNkJBQ0ksSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLElBQUk7d0JBQzFDLFdBQVcsSUFBSSxDQUFDLFNBQVMsQ0FBRSxFQUFpQixDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUMsQ0FBQztpQkFDaEU7YUFDRjtZQUVELElBQUksRUFBMkMsQ0FBQztZQUNoRCxJQUFJLEtBQUssQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxFQUFFO2dCQUNyQyxrREFBa0Q7Z0JBQ2xELEVBQUUsR0FBRyxJQUFJLENBQUMsYUFBYSxDQUFDLEtBQUssQ0FBQyxDQUFDO2dCQUMvQixHQUFHLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FDWCxHQUFHLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxFQUFFLENBQUMsS0FBSyxFQUFFLElBQUksQ0FBQyxXQUFvQixDQUFDLEVBQ3pELEdBQUcsRUFBRSxDQUFDLDZCQUNJLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxJQUFJO29CQUMxQyxXQUFXLElBQUksQ0FBQyxTQUFTLENBQUUsRUFBaUIsQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDLENBQUM7YUFDaEU7aUJBQU07Z0JBQ0wsaURBQWlEO2dCQUNqRCxFQUFFLEdBQUcsRUFBRSxDQUFDO2dCQUNSLElBQUksQ0FBQyxXQUFXLEdBQUcsSUFBSSxDQUFDLFdBQXNDLENBQUM7Z0JBQy9ELEtBQUssTUFBTSxHQUFHLElBQUksSUFBSSxDQUFDLGFBQWEsRUFBRTtvQkFDcEMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxHQUFHLElBQUksQ0FBQyxhQUFhLENBQUMsR0FBRyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUM7b0JBQ3pDLEdBQUcsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUNYLEdBQUcsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxLQUFLLEVBQUUsSUFBSSxDQUFDLFdBQVcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUMxRCxHQUFHLEVBQUUsQ0FBQyw2QkFDSSxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsSUFBSTt3QkFDMUMsV0FDTSxJQUFJLENBQUMsU0FBUyxDQUNULEVBQW1DLENBQUMsR0FBRyxDQUFDLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQyxDQUFDO2lCQUN2RTthQUNGO1lBRUQsT0FBTyxFQUFDLElBQUksRUFBRSxLQUFLLEVBQUUsRUFBQyxFQUFFLEVBQUUsRUFBRSxFQUFDLEVBQUMsQ0FBQztTQUNoQztJQUNILENBQUM7Q0FDRjtBQUVEOzs7Ozs7R0FNRztBQUNILE1BQU0sT0FBTyxrQkFBbUIsU0FBUSxPQUEwQjtJQUNoRSxZQUFxQixJQUFxQjtRQUN4QyxLQUFLLEVBQUUsQ0FBQztRQURXLFNBQUksR0FBSixJQUFJLENBQWlCO1FBRXhDLEdBQUcsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUNYLElBQUksQ0FBQyxTQUFTLEdBQUcsQ0FBQyxJQUFJLE1BQU0sQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxFQUN0RCxHQUFHLEVBQUUsQ0FDRCxpREFBaUQsSUFBSSxDQUFDLFNBQVMsRUFBRSxDQUFDLENBQUM7UUFDM0UsR0FBRyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQ1gsSUFBSSxDQUFDLFVBQVUsR0FBRyxDQUFDLElBQUksTUFBTSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLEVBQ3hELEdBQUcsRUFBRSxDQUNELGdEQUFnRCxJQUFJLENBQUMsVUFBVSxFQUFFLENBQUMsQ0FBQztRQUMzRSxJQUFJLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQyxVQUFVLENBQUM7SUFDOUIsQ0FBQztJQUVELEtBQUssQ0FBQyxRQUFRO1FBQ1osT0FBTyxJQUFJLG1CQUFtQixDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUM1QyxDQUFDO0NBQ0Y7QUFFRCwyRUFBMkU7QUFDM0UsNEVBQTRFO0FBQzVFLE1BQU0sT0FBTyxpQ0FBa0MsU0FDM0MsT0FBaUQ7SUFFbkQsWUFBcUIsSUFBcUI7UUFDeEMsS0FBSyxFQUFFLENBQUM7UUFEVyxTQUFJLEdBQUosSUFBSSxDQUFpQjtRQUV4QyxJQUFJLENBQUMsRUFBRSxHQUFHLElBQUksa0JBQWtCLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDekMsQ0FBQztJQUVELEtBQUssQ0FBQyxRQUFRO1FBRVosTUFBTSxFQUFFLEdBQUcsTUFBTSxJQUFJLENBQUMsRUFBRSxDQUFDLFFBQVEsRUFBRSxDQUFDO1FBQ3BDLE9BQU8sSUFBSSxrQ0FBa0MsQ0FBQyxFQUFFLENBQUMsQ0FBQztJQUNwRCxDQUFDO0NBQ0Y7QUFFRCxNQUFNLGtDQUFtQyxTQUNyQyxZQUFzRDtJQUN4RCxZQUE2QixFQUFtQztRQUM5RCxLQUFLLEVBQUUsQ0FBQztRQURtQixPQUFFLEdBQUYsRUFBRSxDQUFpQztJQUVoRSxDQUFDO0lBRUQsS0FBSyxDQUFDLElBQUk7UUFFUixNQUFNLE1BQU0sR0FBRyxNQUFNLElBQUksQ0FBQyxFQUFFLENBQUMsSUFBSSxFQUFFLENBQUM7UUFDcEMsT0FBTztZQUNMLElBQUksRUFBRSxNQUFNLENBQUMsSUFBSTtZQUNqQixLQUFLLEVBQUUsTUFBTSxDQUFDLEtBQUssSUFBSSxJQUFJLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLEVBQUUsRUFBRSxNQUFNLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQztTQUN4RSxDQUFDO0lBQ0osQ0FBQztDQUNGIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBAbGljZW5zZVxuICogQ29weXJpZ2h0IDIwMTggR29vZ2xlIExMQ1xuICpcbiAqIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGFuIE1JVC1zdHlsZVxuICogbGljZW5zZSB0aGF0IGNhbiBiZSBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlIG9yIGF0XG4gKiBodHRwczovL29wZW5zb3VyY2Uub3JnL2xpY2Vuc2VzL01JVC5cbiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gKi9cblxuaW1wb3J0ICogYXMgdGZjIGZyb20gJ0B0ZW5zb3JmbG93L3RmanMtY29yZSc7XG5cbmltcG9ydCB7U2hhcGV9IGZyb20gJy4uL2tlcmFzX2Zvcm1hdC9jb21tb24nO1xuaW1wb3J0IHtUZW5zb3JPckFycmF5T3JNYXB9IGZyb20gJy4uL3R5cGVzJztcblxuaW1wb3J0IHtEYXRhc2V0LCBMYXp5SXRlcmF0b3J9IGZyb20gJy4vZGF0YXNldF9zdHViJztcbmltcG9ydCB7Rml0RGF0YXNldEVsZW1lbnR9IGZyb20gJy4vdHJhaW5pbmdfZGF0YXNldCc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgRmFrZURhdGFzZXRBcmdzIHtcbiAgLyoqXG4gICAqIFRoZSBzaGFwZShzKSBvZiB0aGUgZmVhdHVyZXMgb2YgYSBzaW5nbGUgZXhhbXBsZS5cbiAgICpcbiAgICogVXNlIGFuIG9iamVjdCBtYXBwaW5nIG5hbWUgdG8gc2hhcGUsIGlmIG1vcmUgdGhhbiBvbmUgZmVhdHVyZSB0ZW5zb3JzXG4gICAqIGFyZSByZXF1aXJlZC5cbiAgICovXG4gIHhTaGFwZTogU2hhcGV8e1tuYW1lOiBzdHJpbmddOiBTaGFwZX07XG5cbiAgLyoqXG4gICAqIFRoZSBzaGFwZSBvZiB0aGUgdGFyZ2V0KHMpIG9mIGEgc2luZ2xlIGV4YXBtbGUuXG4gICAqL1xuICB5U2hhcGU6IFNoYXBlfHtbbmFtZTogc3RyaW5nXTogU2hhcGV9O1xuXG4gIC8qKlxuICAgKiBBIGZ1bmN0aW9uIHRoYXQgZ2VuZXJhdGVzIHByZXNldCBzZXF1ZW5jZSBvZiBYIHRlbnNvcnMuXG4gICAqXG4gICAqIFRoaXMgZnVuY3Rpb24gaXMgaW52b2tlZCBlYWNoIHRpbWUgYSBuZXcgaXRlcmF0b3IgaXMgY3JlYXRlZC5cbiAgICovXG4gIHhUZW5zb3JzRnVuYz86ICgpID0+IHRmYy5UZW5zb3JbXSB8IHtbbmFtZTogc3RyaW5nXTogdGZjLlRlbnNvcltdfTtcblxuICAvKipcbiAgICogQSBmdW5jdGlvbiB0aGF0IGdlbmVyYXRlcyBwcmVzZXQgc2VxdWVuY2Ugb2YgWSB0ZW5zb3JzLlxuICAgKlxuICAgKiBUaGlzIGZ1bmN0aW9uIGlzIGludm9rZWQgZWFjaCB0aW1lIGEgbmV3IGl0ZXJhdG9yIGlzIGNyZWF0ZWQuXG4gICAqL1xuICB5VGVuc29yc0Z1bmM/OiAoKSA9PiB0ZmMuVGVuc29yW10gfCB7W25hbWU6IHN0cmluZ106IHRmYy5UZW5zb3JbXX07XG5cbiAgLyoqXG4gICAqIFRoZSBzaXplIG9mIGVhY2ggYmF0Y2ggZ2VuZXJhdGVkIGJ5IHRoZSBpdGVyYXRvci5cbiAgICovXG4gIGJhdGNoU2l6ZTogbnVtYmVyO1xuXG4gIC8qKlxuICAgKiBUaGUgbnVtYmVyIG9mIGJhdGNoZXMgYW4gaXRlcmF0b3IgZ2VuZXJhdGVzIGJlZm9yZSBkZWNsYXJpbmcgZG9uZSB0byBiZVxuICAgKiB0cnVlLlxuICAgKi9cbiAgbnVtQmF0Y2hlczogbnVtYmVyO1xufVxuXG5mdW5jdGlvbiBtZXJnZUJhdGNoU2l6ZUFuZFNoYXBlKFxuICAgIGJhdGNoU2l6ZTogbnVtYmVyLCBzaGFwZTogU2hhcGV8e1tuYW1lOiBzdHJpbmddOiBTaGFwZX0pOiBTaGFwZXxcbiAgICB7W25hbWU6IHN0cmluZ106IFNoYXBlfSB7XG4gIGlmIChBcnJheS5pc0FycmF5KHNoYXBlKSkge1xuICAgIHJldHVybiBbYmF0Y2hTaXplXS5jb25jYXQoc2hhcGUpO1xuICB9IGVsc2Uge1xuICAgIGNvbnN0IG91dHB1dDoge1tuYW1lOiBzdHJpbmddOiBTaGFwZX0gPSB7fTtcbiAgICBmb3IgKGNvbnN0IG5hbWUgaW4gc2hhcGUpIHtcbiAgICAgIG91dHB1dFtuYW1lXSA9IFtiYXRjaFNpemVdLmNvbmNhdChzaGFwZVtuYW1lXSk7XG4gICAgfVxuICAgIHJldHVybiBvdXRwdXQ7XG4gIH1cbn1cblxuZnVuY3Rpb24gZ2VuZXJhdGVSYW5kb21UZW5zb3JDb250YWluZXIoc2hhcGU6IFNoYXBlfHtbbmFtZTogc3RyaW5nXTogU2hhcGV9KTpcbiAgICB0ZmMuVGVuc29yfHtbbmFtZTogc3RyaW5nXTogdGZjLlRlbnNvcn0ge1xuICBsZXQgb3V0cHV0OiB0ZmMuVGVuc29yfHtbbmFtZTogc3RyaW5nXTogdGZjLlRlbnNvcn07XG4gIGlmIChBcnJheS5pc0FycmF5KHNoYXBlKSkge1xuICAgIG91dHB1dCA9IHRmYy5yYW5kb21Ob3JtYWwoc2hhcGUpO1xuICB9IGVsc2Uge1xuICAgIG91dHB1dCA9IHt9O1xuICAgIGZvciAoY29uc3QgbmFtZSBpbiBzaGFwZSkge1xuICAgICAgb3V0cHV0W25hbWVdID0gdGZjLnJhbmRvbU5vcm1hbChzaGFwZVtuYW1lXSk7XG4gICAgfVxuICB9XG4gIHJldHVybiBvdXRwdXQ7XG59XG5cbmNsYXNzIEZha2VOdW1lcmljSXRlcmF0b3IgZXh0ZW5kcyBMYXp5SXRlcmF0b3I8Rml0RGF0YXNldEVsZW1lbnQ+IHtcbiAgcHJpdmF0ZSB4QmF0Y2hTaGFwZTogU2hhcGV8e1tuYW1lOiBzdHJpbmddOiBTaGFwZX07XG4gIHByaXZhdGUgeUJhdGNoU2hhcGU6IFNoYXBlfHtbbmFtZTogc3RyaW5nXTogU2hhcGV9O1xuICBwcml2YXRlIG51bUJhdGNoZXM6IG51bWJlcjtcbiAgcHJpdmF0ZSBiYXRjaENvdW50OiBudW1iZXI7XG4gIHByaXZhdGUgeFRlbnNvcnNGdW5jOiAoKSA9PiB0ZmMuVGVuc29yW10gfCB7W25hbWU6IHN0cmluZ106IHRmYy5UZW5zb3JbXX07XG4gIHByaXZhdGUgeVRlbnNvcnNGdW5jOiAoKSA9PiB0ZmMuVGVuc29yW10gfCB7W25hbWU6IHN0cmluZ106IHRmYy5UZW5zb3JbXX07XG4gIHByaXZhdGUgeFRlbnNvclZhbHVlczogdGZjLlRlbnNvcltdfHtbbmFtZTogc3RyaW5nXTogdGZjLlRlbnNvcltdfTtcbiAgcHJpdmF0ZSB5VGVuc29yVmFsdWVzOiB0ZmMuVGVuc29yW118e1tuYW1lOiBzdHJpbmddOiB0ZmMuVGVuc29yW119O1xuICBwcml2YXRlIHRlbnNvckluZGV4ID0gMDtcblxuICBjb25zdHJ1Y3RvcihhcmdzOiBGYWtlRGF0YXNldEFyZ3MpIHtcbiAgICBzdXBlcigpO1xuICAgIHRoaXMueEJhdGNoU2hhcGUgPSBtZXJnZUJhdGNoU2l6ZUFuZFNoYXBlKGFyZ3MuYmF0Y2hTaXplLCBhcmdzLnhTaGFwZSk7XG4gICAgdGhpcy55QmF0Y2hTaGFwZSA9IG1lcmdlQmF0Y2hTaXplQW5kU2hhcGUoYXJncy5iYXRjaFNpemUsIGFyZ3MueVNoYXBlKTtcbiAgICB0aGlzLm51bUJhdGNoZXMgPSBhcmdzLm51bUJhdGNoZXM7XG4gICAgdGhpcy5iYXRjaENvdW50ID0gMDtcbiAgICB0aGlzLnhUZW5zb3JzRnVuYyA9IGFyZ3MueFRlbnNvcnNGdW5jO1xuICAgIHRoaXMueVRlbnNvcnNGdW5jID0gYXJncy55VGVuc29yc0Z1bmM7XG5cbiAgICAvLyBTYW5pdHkgY2hlY2sgb24gdGhlIHByZXNldCB0ZW5zb3JzLlxuICAgIHRmYy51dGlsLmFzc2VydChcbiAgICAgICAgdGhpcy54VGVuc29yc0Z1bmMgPT0gbnVsbCAmJiB0aGlzLnlUZW5zb3JzRnVuYyA9PSBudWxsIHx8XG4gICAgICAgICAgICB0aGlzLnhUZW5zb3JzRnVuYyAhPSBudWxsICYmIHRoaXMueVRlbnNvcnNGdW5jICE9IG51bGwsXG4gICAgICAgICgpID0+ICdwcmVzZXRYVGVuc29ycyBhbmQgcHJlc2V0WVRlbnNvcnMgbXVzdCBiZSBib3RoIG51bGwvdW5kZWZpbmVkICcgK1xuICAgICAgICAgICAgJ29yIGJvdGggc2V0LicpO1xuICB9XG5cbiAgYXN5bmMgbmV4dCgpOiBQcm9taXNlPEl0ZXJhdG9yUmVzdWx0PEZpdERhdGFzZXRFbGVtZW50Pj4ge1xuICAgIGNvbnN0IGRvbmUgPSArK3RoaXMuYmF0Y2hDb3VudCA+IHRoaXMubnVtQmF0Y2hlcztcbiAgICBpZiAoZG9uZSkge1xuICAgICAgcmV0dXJuIHtkb25lLCB2YWx1ZTogbnVsbH07XG4gICAgfVxuICAgIGlmICh0aGlzLnhUZW5zb3JzRnVuYyA9PSBudWxsKSB7XG4gICAgICAvLyBHZW5lcmF0ZSBkYXRhIHJhbmRvbWx5LlxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgZG9uZSxcbiAgICAgICAgdmFsdWU6IGRvbmUgPyBudWxsIDoge1xuICAgICAgICAgIHhzOiBnZW5lcmF0ZVJhbmRvbVRlbnNvckNvbnRhaW5lcih0aGlzLnhCYXRjaFNoYXBlKSxcbiAgICAgICAgICB5czogZ2VuZXJhdGVSYW5kb21UZW5zb3JDb250YWluZXIodGhpcy55QmF0Y2hTaGFwZSlcbiAgICAgICAgfVxuICAgICAgfTtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gVXNlIHByZXNldCB0ZW5zb3JzLlxuICAgICAgaWYgKCh0aGlzLmJhdGNoQ291bnQgLSAxKSAlIHRoaXMubnVtQmF0Y2hlcyA9PT0gMCkge1xuICAgICAgICB0aGlzLnhUZW5zb3JWYWx1ZXMgPSB0aGlzLnhUZW5zb3JzRnVuYygpO1xuICAgICAgICB0aGlzLnlUZW5zb3JWYWx1ZXMgPSB0aGlzLnlUZW5zb3JzRnVuYygpO1xuICAgICAgICB0aGlzLnRlbnNvckluZGV4ID0gMDtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGluZGV4ID0gdGhpcy50ZW5zb3JJbmRleCsrO1xuXG4gICAgICBsZXQgeHM6IHRmYy5UZW5zb3J8e1tuYW1lOiBzdHJpbmddOiB0ZmMuVGVuc29yfTtcbiAgICAgIGlmIChBcnJheS5pc0FycmF5KHRoaXMueFRlbnNvclZhbHVlcykpIHtcbiAgICAgICAgeHMgPSB0aGlzLnhUZW5zb3JWYWx1ZXNbaW5kZXhdO1xuICAgICAgICB0ZmMudXRpbC5hc3NlcnQoXG4gICAgICAgICAgICB0ZmMudXRpbC5hcnJheXNFcXVhbCh4cy5zaGFwZSwgdGhpcy54QmF0Y2hTaGFwZSBhcyBTaGFwZSksXG4gICAgICAgICAgICAoKSA9PiBgU2hhcGUgbWlzbWF0Y2g6IGV4cGVjdGVkOiAke1xuICAgICAgICAgICAgICAgICAgICAgIEpTT04uc3RyaW5naWZ5KHRoaXMueEJhdGNoU2hhcGUpfTsgYCArXG4gICAgICAgICAgICAgICAgYGFjdHVhbDogJHtKU09OLnN0cmluZ2lmeSgoeHMgYXMgdGZjLlRlbnNvcikuc2hhcGUpfWApO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgeHMgPSB7fTtcbiAgICAgICAgZm9yIChjb25zdCBrZXkgaW4gdGhpcy54VGVuc29yVmFsdWVzKSB7XG4gICAgICAgICAgeHNba2V5XSA9IHRoaXMueFRlbnNvclZhbHVlc1trZXldW2luZGV4XTtcbiAgICAgICAgICB0ZmMudXRpbC5hc3NlcnQoXG4gICAgICAgICAgICAgIHRmYy51dGlsLmFycmF5c0VxdWFsKHhzW2tleV0uc2hhcGUsIHRoaXMueEJhdGNoU2hhcGUgYXMgU2hhcGUpLFxuICAgICAgICAgICAgICAoKSA9PiBgU2hhcGUgbWlzbWF0Y2g6IGV4cGVjdGVkOiAke1xuICAgICAgICAgICAgICAgICAgICAgICAgSlNPTi5zdHJpbmdpZnkodGhpcy54QmF0Y2hTaGFwZSl9OyBgICtcbiAgICAgICAgICAgICAgICAgIGBhY3R1YWw6ICR7SlNPTi5zdHJpbmdpZnkoKHhzIGFzIHRmYy5UZW5zb3IpLnNoYXBlKX1gKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBsZXQgeXM6IHRmYy5UZW5zb3J8e1tuYW1lOiBzdHJpbmddOiB0ZmMuVGVuc29yfTtcbiAgICAgIGlmIChBcnJheS5pc0FycmF5KHRoaXMueVRlbnNvclZhbHVlcykpIHtcbiAgICAgICAgLy8gR2V0IHByZXNldCB5cyB0ZW5zb3JzIGZvciBzaW5nbGUtb3V0cHV0IG1vZGVscy5cbiAgICAgICAgeXMgPSB0aGlzLnlUZW5zb3JWYWx1ZXNbaW5kZXhdO1xuICAgICAgICB0ZmMudXRpbC5hc3NlcnQoXG4gICAgICAgICAgICB0ZmMudXRpbC5hcnJheXNFcXVhbCh5cy5zaGFwZSwgdGhpcy55QmF0Y2hTaGFwZSBhcyBTaGFwZSksXG4gICAgICAgICAgICAoKSA9PiBgU2hhcGUgbWlzbWF0Y2g6IGV4cGVjdGVkOiAke1xuICAgICAgICAgICAgICAgICAgICAgIEpTT04uc3RyaW5naWZ5KHRoaXMueUJhdGNoU2hhcGUpfTsgYCArXG4gICAgICAgICAgICAgICAgYGFjdHVhbDogJHtKU09OLnN0cmluZ2lmeSgoeXMgYXMgdGZjLlRlbnNvcikuc2hhcGUpfWApO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gR2V0IHByZXNldCB5cyB0ZW5zb3JzIGZvciBtdWx0aS1vdXRwdXQgbW9kZWxzLlxuICAgICAgICB5cyA9IHt9O1xuICAgICAgICB0aGlzLnlCYXRjaFNoYXBlID0gdGhpcy55QmF0Y2hTaGFwZSBhcyB7W25hbWU6IHN0cmluZ106IFNoYXBlfTtcbiAgICAgICAgZm9yIChjb25zdCBrZXkgaW4gdGhpcy55VGVuc29yVmFsdWVzKSB7XG4gICAgICAgICAgeXNba2V5XSA9IHRoaXMueVRlbnNvclZhbHVlc1trZXldW2luZGV4XTtcbiAgICAgICAgICB0ZmMudXRpbC5hc3NlcnQoXG4gICAgICAgICAgICAgIHRmYy51dGlsLmFycmF5c0VxdWFsKHlzW2tleV0uc2hhcGUsIHRoaXMueUJhdGNoU2hhcGVba2V5XSksXG4gICAgICAgICAgICAgICgpID0+IGBTaGFwZSBtaXNtYXRjaDogZXhwZWN0ZWQ6ICR7XG4gICAgICAgICAgICAgICAgICAgICAgICBKU09OLnN0cmluZ2lmeSh0aGlzLnlCYXRjaFNoYXBlKX07IGAgK1xuICAgICAgICAgICAgICAgICAgYGFjdHVhbDogJHtcbiAgICAgICAgICAgICAgICAgICAgICAgIEpTT04uc3RyaW5naWZ5KFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICh5cyBhcyB7W25hbWU6IHN0cmluZ106IHRmYy5UZW5zb3J9KVtrZXldLnNoYXBlKX1gKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICByZXR1cm4ge2RvbmUsIHZhbHVlOiB7eHMsIHlzfX07XG4gICAgfVxuICB9XG59XG5cbi8qKlxuICogQSBmYWtlIGRhdGFzZXQgd2l0aCBjb25maWd1cmFibGUgZmVhdHVyZSBhbmQgdGFyZ2V0IHNoYXBlcy5cbiAqXG4gKiBUaGUgYmF0Y2ggc2l6ZSBhbmQgIyBvZiBiYXRjaGVzIGFyZSBhbHNvIGNvbmZpZ3VyYWJsZS5cbiAqXG4gKiBUaGUgaXRlcmF0b3IgZnJvbSB0aGUgZGF0YXNldCBhbHdheXMgZ2VuZXJhdGUgcmFuZG9tLW5vcm1hbCBmbG9hdDMyIHZhbHVlcy5cbiAqL1xuZXhwb3J0IGNsYXNzIEZha2VOdW1lcmljRGF0YXNldCBleHRlbmRzIERhdGFzZXQ8Rml0RGF0YXNldEVsZW1lbnQ+IHtcbiAgY29uc3RydWN0b3IocmVhZG9ubHkgYXJnczogRmFrZURhdGFzZXRBcmdzKSB7XG4gICAgc3VwZXIoKTtcbiAgICB0ZmMudXRpbC5hc3NlcnQoXG4gICAgICAgIGFyZ3MuYmF0Y2hTaXplID4gMCAmJiBOdW1iZXIuaXNJbnRlZ2VyKGFyZ3MuYmF0Y2hTaXplKSxcbiAgICAgICAgKCkgPT5cbiAgICAgICAgICAgIGBiYXRjaFNpemUgbXVzdCBiZSBhIHBvc2l0aXZlIGludGVnZXIsIGJ1dCBnb3QgJHthcmdzLmJhdGNoU2l6ZX1gKTtcbiAgICB0ZmMudXRpbC5hc3NlcnQoXG4gICAgICAgIGFyZ3MubnVtQmF0Y2hlcyA+IDAgJiYgTnVtYmVyLmlzSW50ZWdlcihhcmdzLm51bUJhdGNoZXMpLFxuICAgICAgICAoKSA9PlxuICAgICAgICAgICAgYG51bUJhdGNoZXMgbXVzdCBiZSBwb3NpdGl2ZSBpbnRlZ2VyLCBidXQgZ290ICR7YXJncy5udW1CYXRjaGVzfWApO1xuICAgIHRoaXMuc2l6ZSA9IGFyZ3MubnVtQmF0Y2hlcztcbiAgfVxuXG4gIGFzeW5jIGl0ZXJhdG9yKCk6IFByb21pc2U8TGF6eUl0ZXJhdG9yPEZpdERhdGFzZXRFbGVtZW50Pj4ge1xuICAgIHJldHVybiBuZXcgRmFrZU51bWVyaWNJdGVyYXRvcih0aGlzLmFyZ3MpO1xuICB9XG59XG5cbi8vIFdlIGNhbid0IHVzZSBEYXRhc2V0Lm1hcCguLi4pIGJlY2F1c2Ugd2UgZG9uJ3QgZGVwZW5kIG9uIHRmanMtZGF0YSBoZXJlLFxuLy8gc28gd2UgbWFudWFsbHkgdHJhbnNmb3JtIHRoZSBhYm92ZSB7eHMsIHlzfSBkYXRhc2V0IHRvIHRoZSBbeHMsIHlzXSBmb3JtLlxuZXhwb3J0IGNsYXNzIEZha2VOdW1lcmljRGF0YXNldExlZ2FjeUFycmF5Rm9ybSBleHRlbmRzXG4gICAgRGF0YXNldDxbVGVuc29yT3JBcnJheU9yTWFwLCBUZW5zb3JPckFycmF5T3JNYXBdPiB7XG4gIGRzOiBGYWtlTnVtZXJpY0RhdGFzZXQ7XG4gIGNvbnN0cnVjdG9yKHJlYWRvbmx5IGFyZ3M6IEZha2VEYXRhc2V0QXJncykge1xuICAgIHN1cGVyKCk7XG4gICAgdGhpcy5kcyA9IG5ldyBGYWtlTnVtZXJpY0RhdGFzZXQoYXJncyk7XG4gIH1cblxuICBhc3luYyBpdGVyYXRvcigpOlxuICAgICAgUHJvbWlzZTxMYXp5SXRlcmF0b3I8W1RlbnNvck9yQXJyYXlPck1hcCwgVGVuc29yT3JBcnJheU9yTWFwXT4+IHtcbiAgICBjb25zdCBpdCA9IGF3YWl0IHRoaXMuZHMuaXRlcmF0b3IoKTtcbiAgICByZXR1cm4gbmV3IEZha2VOdW1lcmljSXRlcmF0b3JMZWdhY3lBcnJheUZvcm0oaXQpO1xuICB9XG59XG5cbmNsYXNzIEZha2VOdW1lcmljSXRlcmF0b3JMZWdhY3lBcnJheUZvcm0gZXh0ZW5kc1xuICAgIExhenlJdGVyYXRvcjxbVGVuc29yT3JBcnJheU9yTWFwLCBUZW5zb3JPckFycmF5T3JNYXBdPiB7XG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgcmVhZG9ubHkgaXQ6IExhenlJdGVyYXRvcjxGaXREYXRhc2V0RWxlbWVudD4pIHtcbiAgICBzdXBlcigpO1xuICB9XG5cbiAgYXN5bmMgbmV4dCgpOlxuICAgICAgUHJvbWlzZTxJdGVyYXRvclJlc3VsdDxbVGVuc29yT3JBcnJheU9yTWFwLCBUZW5zb3JPckFycmF5T3JNYXBdPj4ge1xuICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHRoaXMuaXQubmV4dCgpO1xuICAgIHJldHVybiB7XG4gICAgICBkb25lOiByZXN1bHQuZG9uZSxcbiAgICAgIHZhbHVlOiByZXN1bHQudmFsdWUgPT0gbnVsbCA/IG51bGwgOiBbcmVzdWx0LnZhbHVlLnhzLCByZXN1bHQudmFsdWUueXNdXG4gICAgfTtcbiAgfVxufVxuIl19
\No newline at end of file