tfjs-evolution 0.0.3 → 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,165 @@
1
+ import * as tf from '@tensorflow/tfjs';
2
+ export class Util {
3
+ /**
4
+ * Receives an image and normalizes it between -1 and 1.
5
+ * Returns a batched image (1 - element batch) of shape [1, w, h, c]
6
+ * @param rasterElement the element with pixels to convert to a Tensor
7
+ * @param grayscale optinal flag that changes the crop to [1, w, h, 1]
8
+ */
9
+ capture(rasterElement, grayscale) {
10
+ return tf.tidy(() => {
11
+ const pixels = tf.browser.fromPixels(rasterElement);
12
+ // // crop the image so we're using the center square
13
+ const cropped = this.cropTensor(pixels, grayscale);
14
+ // // Expand the outer most dimension so we have a batch size of 1
15
+ const batchedImage = cropped.expandDims(0);
16
+ // // Normalize the image between -1 and a1. The image comes in between 0-255
17
+ // // so we divide by 127 and subtract 1.
18
+ return batchedImage.toFloat().div(tf.scalar(127)).sub(tf.scalar(1));
19
+ });
20
+ }
21
+ cropTensor(img, grayscaleModel, grayscaleInput) {
22
+ const size = Math.min(img.shape[0], img.shape[1]);
23
+ const centerHeight = img.shape[0] / 2;
24
+ const beginHeight = centerHeight - (size / 2);
25
+ const centerWidth = img.shape[1] / 2;
26
+ const beginWidth = centerWidth - (size / 2);
27
+ if (grayscaleModel && !grayscaleInput) {
28
+ //cropped rgb data
29
+ let grayscale_cropped = img.slice([beginHeight, beginWidth, 0], [size, size, 3]);
30
+ grayscale_cropped = grayscale_cropped.reshape([size * size, 1, 3]);
31
+ const rgb_weights = [0.2989, 0.5870, 0.1140];
32
+ grayscale_cropped = tf.mul(grayscale_cropped, rgb_weights);
33
+ grayscale_cropped = grayscale_cropped.reshape([size, size, 3]);
34
+ grayscale_cropped = tf.sum(grayscale_cropped, -1);
35
+ grayscale_cropped = tf.expandDims(grayscale_cropped, -1);
36
+ return grayscale_cropped;
37
+ }
38
+ return img.slice([beginHeight, beginWidth, 0], [size, size, 3]);
39
+ }
40
+ /**
41
+ * This function will make a copy of a model on the weight level
42
+ * This is an attempt to avoid influencing the new mode when the old one
43
+ * is eliminated.
44
+ *
45
+ * @param originalModel - the model to be copied
46
+ * @param recipient - the new model
47
+ */
48
+ async copyModel_v3(originalModel, recipient) {
49
+ originalModel.layers.forEach((layer, index) => {
50
+ recipient.layers[index].setWeights(layer.getWeights());
51
+ });
52
+ // originalModel.dispose();
53
+ }
54
+ /**
55
+ * This function will make a copy of a TFJS model, as so it would be possible
56
+ * to erase the original.
57
+ * @param model - model to be copied
58
+ * @returns - copy of the model
59
+ */
60
+ async copyModel_v2(originalModel) {
61
+ // Serialize the original model
62
+ const modelTopology = originalModel.toJSON();
63
+ // Load the serialized model into a new model
64
+ const copiedModel = await tf.loadLayersModel(tf.io.fromMemory(modelTopology, undefined, undefined));
65
+ // Compile the copied model with the same settings as the original
66
+ copiedModel.compile({
67
+ loss: originalModel.loss,
68
+ optimizer: originalModel.optimizer
69
+ });
70
+ return copiedModel;
71
+ }
72
+ /**
73
+ * This function will make a copy of a TFJS model, as so it would be possible
74
+ * to erase the original.
75
+ * @param model - model to be copied
76
+ * @returns - copy of the model
77
+ */
78
+ copyModel(model) {
79
+ const copy = tf.sequential();
80
+ `
81
+ `;
82
+ model.layers.forEach(layer => {
83
+ const aux = layer;
84
+ // layer.dispose();
85
+ copy.add(aux);
86
+ });
87
+ copy.compile({
88
+ loss: model.loss,
89
+ optimizer: model.optimizer
90
+ });
91
+ return copy;
92
+ }
93
+ removeElementByIndex(arr, index) {
94
+ // Check if the index is within bounds
95
+ if (index >= 0 && index < arr.length) {
96
+ // Remove the element at the specified index
97
+ arr.splice(index, 1);
98
+ }
99
+ return arr;
100
+ }
101
+ removeElement(arr, element) {
102
+ // Remove all occurrences of the specified element from the array
103
+ return arr.filter((item) => item !== element);
104
+ }
105
+ clean_array_of_tensors(tensors) {
106
+ tensors.forEach((elem, index) => {
107
+ // if(!index_selection.includes(index))
108
+ elem.dispose();
109
+ });
110
+ }
111
+ getClassNameBySignature(classes, signature) {
112
+ const class_name = classes.find(p => {
113
+ let match = true;
114
+ p.signature?.forEach((elem, index) => {
115
+ if (elem !== signature[index])
116
+ match = false;
117
+ });
118
+ return match;
119
+ });
120
+ return class_name ? class_name.name : "not found";
121
+ }
122
+ identityMatrix(n) {
123
+ return Array.from({ length: n }, (_, i) => Array.from({ length: n }, (_, j) => (i === j ? 1 : 0)));
124
+ }
125
+ indexOfMax(arr) {
126
+ if (arr.length === 0) {
127
+ return -1; // Return -1 for an empty array
128
+ }
129
+ let max = arr[0];
130
+ let maxIndex = 0;
131
+ for (let i = 1; i < arr.length; i++) {
132
+ if (arr[i] > max) {
133
+ maxIndex = i;
134
+ max = arr[i];
135
+ }
136
+ }
137
+ return maxIndex;
138
+ }
139
+ suffle(array1, array2) {
140
+ // Shuffle the order of elements
141
+ for (let i = array1.length - 1; i > 0; i--) {
142
+ const j = Math.floor(Math.random() * (i + 1));
143
+ // Swap elements in both arrays
144
+ [array1[i], array1[j]] = [array1[j], array1[i]];
145
+ [array2[i], array2[j]] = [array2[j], array2[i]];
146
+ }
147
+ }
148
+ sortByValuePreservingIndex(arr1, arr2) {
149
+ // console.log("Vector for organizing: ", arr1)
150
+ // arr2[0].summary()
151
+ // Create an array of objects with value, index from arr1, and original index
152
+ const pairingArray = arr1.map((value, index) => ({
153
+ value,
154
+ index,
155
+ originalIndex: index,
156
+ elementFromArr2: arr2[index], // Preserve the corresponding element from arr2
157
+ }));
158
+ // Sort the pairing array by value (largest to smallest)
159
+ pairingArray.sort((a, b) => b.value - a.value);
160
+ // Extract the sorted elements from arr2 based on the original index
161
+ const sortedElementsFromArr2 = pairingArray.map(pair => pair.elementFromArr2);
162
+ return sortedElementsFromArr2;
163
+ }
164
+ }
165
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXRpbC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL3RmanMtZXZvbHV0aW9uL3NyYy9saWIvdXRpbHMvdXRpbC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFFQSxPQUFPLEtBQUssRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBR3ZDLE1BQU0sT0FBTyxJQUFJO0lBRWpCOzs7OztPQUtHO0lBQ0gsT0FBTyxDQUFDLGFBQXNFLEVBQUUsU0FBbUI7UUFDL0YsT0FBTyxFQUFFLENBQUMsSUFBSSxDQUFDLEdBQUcsRUFBRTtZQUNoQixNQUFNLE1BQU0sR0FBRyxFQUFFLENBQUMsT0FBTyxDQUFDLFVBQVUsQ0FBQyxhQUFhLENBQUMsQ0FBQztZQUVwRCxxREFBcUQ7WUFDckQsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLFVBQVUsQ0FBQyxNQUFNLEVBQUUsU0FBUyxDQUFDLENBQUM7WUFFbkQsa0VBQWtFO1lBQ2xFLE1BQU0sWUFBWSxHQUFHLE9BQU8sQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFFM0MsNkVBQTZFO1lBQzdFLHlDQUF5QztZQUN6QyxPQUFPLFlBQVksQ0FBQyxPQUFPLEVBQUUsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDeEUsQ0FBQyxDQUFDLENBQUM7SUFDUCxDQUFDO0lBR0QsVUFBVSxDQUFFLEdBQWdCLEVBQUUsY0FBd0IsRUFBRSxjQUF3QjtRQUM1RSxNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLEVBQUUsR0FBRyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ2xELE1BQU0sWUFBWSxHQUFHLEdBQUcsQ0FBQyxLQUFLLENBQUMsQ0FB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QUFDO1FBSS9DLG9FQUFvRTtRQUNwRSxNQUFNLHNCQUFzQixHQUFHLFlBQVksQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsZUFBZSxDQUFDLENBQUM7UUFFOUUsT0FBTyxzQkFBc0IsQ0FBQztJQUNsQyxDQUFDO0NBRUoiLCJzb3VyY2VzQ29udGVudCI6WyJcclxuaW1wb3J0IHtDbGFzc30gZnJvbSBcIi4vY2xhc3NcIlxyXG5pbXBvcnQgKiBhcyB0ZiBmcm9tICdAdGVuc29yZmxvdy90ZmpzJztcclxuXHJcblxyXG5leHBvcnQgY2xhc3MgVXRpbCB7XHJcblxyXG4vKipcclxuICogUmVjZWl2ZXMgYW4gaW1hZ2UgYW5kIG5vcm1hbGl6ZXMgaXQgYmV0d2VlbiAtMSBhbmQgMS5cclxuICogUmV0dXJucyBhIGJhdGNoZWQgaW1hZ2UgKDEgLSBlbGVtZW50IGJhdGNoKSBvZiBzaGFwZSBbMSwgdywgaCwgY11cclxuICogQHBhcmFtIHJhc3RlckVsZW1lbnQgdGhlIGVsZW1lbnQgd2l0aCBwaXhlbHMgdG8gY29udmVydCB0byBhIFRlbnNvclxyXG4gKiBAcGFyYW0gZ3JheXNjYWxlIG9wdGluYWwgZmxhZyB0aGF0IGNoYW5nZXMgdGhlIGNyb3AgdG8gWzEsIHcsIGgsIDFdXHJcbiAqL1xyXG5jYXB0dXJlKHJhc3RlckVsZW1lbnQ6IEhUTUxJbWFnZUVsZW1lbnQgfCBIVE1MVmlkZW9FbGVtZW50IHwgSFRNTENhbnZhc0VsZW1lbnQsIGdyYXlzY2FsZT86IGJvb2xlYW4pIHtcclxuICAgIHJldHVybiB0Zi50aWR5KCgpID0+IHtcclxuICAgICAgICBjb25zdCBwaXhlbHMgPSB0Zi5icm93c2VyLmZyb21QaXhlbHMocmFzdGVyRWxlbWVudCk7XHJcblxyXG4gICAgICAgIC8vIC8vIGNyb3AgdGhlIGltYWdlIHNvIHdlJ3JlIHVzaW5nIHRoZSBjZW50ZXIgc3F1YXJlXHJcbiAgICAgICAgY29uc3QgY3JvcHBlZCA9IHRoaXMuY3JvcFRlbnNvcihwaXhlbHMsIGdyYXlzY2FsZSk7XHJcblxyXG4gICAgICAgIC8vIC8vIEV4cGFuZCB0aGUgb3V0ZXIgbW9zdCBkaW1lbnNpb24gc28gd2UgaGF2ZSBhIGJhdGNoIHNpemUgb2YgMVxyXG4gICAgICAgIGNvbnN0IGJhdGNoZWRJbWFnZSA9IGNyb3BwZWQuZXhwYW5kRGltcygwKTtcclxuXHJcbiAgICAgICAgLy8gLy8gTm9ybWFsaXplIHRoZSBpbWFnZSBiZXR3ZWVuIC0xIGFuZCBhMS4gVGhlIGltYWdlIGNvbWVzIGluIGJldHdlZW4gMC0yNTVcclxuICAgICAgICAvLyAvLyBzbyB3ZSBkaXZpZGUgYnkgMTI3IGFuZCBzdWJ0cmFjdCAxLlxyXG4gICAgICAgIHJldHVybiBiYXRjaGVkSW1hZ2UudG9GbG9hdCgpLmRpdih0Zi5zY2FsYXIoMTI3KSkuc3ViKHRmLnNjYWxhcigxKSk7ICAgIFxyXG4gICAgfSk7XHJcbn0gICAgXHJcblxyXG5cclxuY3JvcFRlbnNvciggaW1nOiB0Zi5UZW5zb3IzRCwgZ3JheXNjYWxlTW9kZWw/OiBib29sZWFuLCBncmF5c2NhbGVJbnB1dD86IGJvb2xlYW4gKSA6IHRmLlRlbnNvcjNEIHtcclxuICAgIGNvbnN0IHNpemUgPSBNYXRoLm1pbihpbWcuc2hhcGVbMF0sIGltZy5zaGFwZVsxXSk7XHJcbiAgICBjb25zdCBjZW50ZXJIZWlnaHQgPSBpbWcuc2hhcGVbMF0gLyAyO1xyXG4gICAgY29uc3QgYmVnaW5IZWlnaHQgPSBjZW50ZXJIZWlnaHQgLSAoc2l6ZSAvIDIpO1xyXG4gICAgY29uc3QgY2VudGVyV2lkdGggPSBpbWcuc2hhcGVbMV0gLyAyO1xyXG4gICAgY29uc3QgYmVnaW5XaWR0aCA9IGNlbnRlcldpZHRoIC0gKHNpemUgLyAyKTtcclxuICAgIFxyXG4gICAgaWYgKGdyYXlzY2FsZU1vZGVsICYmICFncmF5c2NhbGVJbnB1dCkge1xyXG4gICAgICAgIC8vY3JvcHBlZCByZ2IgZGF0YVxyXG4gICAgICAgIGxldCBncmF5c2NhbGVfY3JvcHBlZCA9IGltZy5zbGljZShbYmVnaW5IZWlnaHQsIGJlZ2luV2lkdGgsIDBdLCBbc2l6ZSwgc2l6ZSwgM10pO1xyXG4gICAgICAgIFxyXG4gICAgICAgIGdyYXlzY2FsZV9jcm9wcGVkID0gZ3JheXNjYWxlX2Nyb3BwZWQucmVzaGFwZShbc2l6ZSAqIHNpemUsIDEsIDNdKVxyXG4gICAgICAgIGNvbnN0IHJnYl93ZWlnaHRzID0gWzAuMjk4OSwgMC41ODcwLCAwLjExNDBdXHJcbiAgICAgICAgZ3JheXNjYWxlX2Nyb3BwZWQgPSB0Zi5tdWwoZ3JheXNjYWxlX2Nyb3BwZWQsIHJnYl93ZWlnaHRzKVxyXG4gICAgICAgIGdyYXlzY2FsZV9jcm9wcGVkID0gZ3JheXNjYWxlX2Nyb3BwZWQucmVzaGFwZShbc2l6ZSwgc2l6ZSwgM10pO1xyXG4gICAgXHJcbiAgICAgICAgZ3JheXNjYWxlX2Nyb3BwZWQgPSB0Zi5zdW0oZ3JheXNjYWxlX2Nyb3BwZWQsIC0xKVxyXG4gICAgICAgIGdyYXlzY2FsZV9jcm9wcGVkID0gdGYuZXhwYW5kRGltcyhncmF5c2NhbGVfY3JvcHBlZCwgLTEpXHJcblxyXG4gICAgICAgIHJldHVybiBncmF5c2NhbGVfY3JvcHBlZDtcclxuICAgIH1cclxuICAgIHJldHVybiBpbWcuc2xpY2UoW2JlZ2luSGVpZ2h0LCBiZWdpbldpZHRoLCAwXSwgW3NpemUsIHNpemUsIDNdKTtcclxufVxyXG5cclxuXHJcblxyXG5cclxuLyoqXHJcbiAqIFRoaXMgZnVuY3Rpb24gd2lsbCBtYWtlIGEgY29weSBvZiBhIG1vZGVsIG9uIHRoZSB3ZWlnaHQgbGV2ZWxcclxuICogVGhpcyBpcyBhbiBhdHRlbXB0IHRvIGF2b2lkIGluZmx1ZW5jaW5nIHRoZSBuZXcgbW9kZSB3aGVuIHRoZSBvbGQgb25lXHJcbiAqIGlzIGVsaW1pbmF0ZWQuIFxyXG4gKiBcclxuICogQHBhcmFtIG9yaWdpbmFsTW9kZWwgLSB0aGUgbW9kZWwgdG8gYmUgY29waWVkIFxyXG4gKiBAcGFyYW0gcmVjaXBpZW50IC0gdGhlIG5ldyBtb2RlbFxyXG4gKi9cclxuYXN5bmMgY29weU1vZGVsX3YzIChvcmlnaW5hbE1vZGVsOiB0Zi5TZXF1ZW50aWFsLCByZWNpcGllbnQ6IHRmLlNlcXVlbnRpYWwpICB7XHJcblxyXG4gICAgICAgIG9yaWdpbmFsTW9kZWwubGF5ZXJzLmZvckVhY2goKGxheWVyLCBpbmRleCk9PntcclxuICAgICAgICAgICAgcmVjaXBpZW50LmxheWVyc1tpbmRleF0uc2V0V2VpZ2h0cyhsYXllci5nZXRXZWlnaHRzKCkpXHJcbiAgICAgICAgfSlcclxuXHJcbiAgICAvLyBvcmlnaW5hbE1vZGVsLmRpc3Bvc2UoKTtcclxufVxyXG4gICAgXHJcbi8qKlxyXG4gKiBUaGlzIGZ1bmN0aW9uIHdpbGwgbWFrZSBhIGNvcHkgb2YgYSBURkpTIG1vZGVsLCBhcyBzbyBpdCB3b3VsZCBiZSBwb3NzaWJsZSBcclxuICogdG8gZXJhc2UgdGhlIG9yaWdpbmFsLlxyXG4gKiBAcGFyYW0gbW9kZWwgLSBtb2RlbCB0byBiZSBjb3BpZWRcclxuICogQHJldHVybnMgLSBjb3B5IG9mIHRoZSBtb2RlbFxyXG4gKi8gIFxyXG5hc3luYyBjb3B5TW9kZWxfdjIgKG9yaWdpbmFsTW9kZWw6IHRmLlNlcXVlbnRpYWwpICB7XHJcbiAgICAgICAgLy8gU2VyaWFsaXplIHRoZSBvcmlnaW5hbCBtb2RlbFxyXG4gICAgICAgIGNvbnN0IG1vZGVsVG9wb2xvZ3kgPSBvcmlnaW5hbE1vZGVsLnRvSlNPTigpO1xyXG5cclxuICAgICAgICAvLyBMb2FkIHRoZSBzZXJpYWxpemVkIG1vZGVsIGludG8gYSBuZXcgbW9kZWxcclxuICAgICAgICBjb25zdCBjb3BpZWRNb2RlbCA9IGF3YWl0IHRmLmxvYWRMYXllcnNNb2RlbChcclxuICAgICAgICAgICAgdGYuaW8uZnJvbU1lbW9yeShtb2RlbFRvcG9sb2d5LCB1bmRlZmluZWQsIHVuZGVmaW5lZClcclxuICAgICAgICApO1xyXG4gICAgXHJcbiAgICAgICAgLy8gQ29tcGlsZSB0aGUgY29waWVkIG1vZGVsIHdpdGggdGhlIHNhbWUgc2V0dGluZ3MgYXMgdGhlIG9yaWdpbmFsXHJcbiAgICAgICAgY29waWVkTW9kZWwuY29tcGlsZSh7XHJcbiAgICAgICAgICAgIGxvc3M6IG9yaWdpbmFsTW9kZWwubG9zcyxcclxuICAgICAgICAgICAgb3B0aW1pemVyOiBvcmlnaW5hbE1vZGVsLm9wdGltaXplclxyXG4gICAgICAgIH0pO1xyXG4gICAgXHJcbiAgICAgICAgcmV0dXJuIGNvcGllZE1vZGVsO1xyXG59XHJcblxyXG4vKipcclxuICogVGhpcyBmdW5jdGlvbiB3aWxsIG1ha2UgYSBjb3B5IG9mIGEgVEZKUyBtb2RlbCwgYXMgc28gaXQgd291bGQgYmUgcG9zc2libGUgXHJcbiAqIHRvIGVyYXNlIHRoZSBvcmlnaW5hbC5cclxuICogQHBhcmFtIG1vZGVsIC0gbW9kZWwgdG8gYmUgY29waWVkXHJcbiAqIEByZXR1cm5zIC0gY29weSBvZiB0aGUgbW9kZWxcclxuICovICBcclxuY29weU1vZGVsIChtb2RlbDogdGYuU2VxdWVudGlhbCkgIHtcclxuICAgIFxyXG4gICAgICAgIGNvbnN0IGNvcHkgPSB0Zi5zZXF1ZW50aWFsKCk7YFxyXG4gICAgICAgIGBcclxuICAgICAgICBtb2RlbC5sYXllcnMuZm9yRWFjaChsYXllciA9PiB7XHJcbiAgICAgICAgICAgIGNvbnN0IGF1eCA9bGF5ZXI7XHJcbiAgICAgICAgICAgIC8vIGxheWVyLmRpc3Bvc2UoKTtcclxuICAgICAgICAgICAgY29weS5hZGQoYXV4KTtcclxuICAgICAgICB9KTtcclxuICAgICAgICBjb3B5LmNvbXBpbGUoe1xyXG4gICAgICAgICAgICBsb3NzOiBtb2RlbC5sb3NzLFxyXG4gICAgICAgICAgICBvcHRpbWl6ZXI6IG1vZGVsLm9wdGltaXplclxyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIHJldHVybiBjb3B5O1xyXG4gICAgfVxyXG5cclxuXHJcbiAgICByZW1vdmVFbGVtZW50QnlJbmRleChhcnI6IGFueSwgaW5kZXg6IG51bWJlcik6IG51bWJlcltdIHtcclxuICAgICAgICAvLyBDaGVjayBpZiB0aGUgaW5kZXggaXMgd2l0aGluIGJvdW5kc1xyXG4gICAgICAgIGlmIChpbmRleCA+PSAwICYmIGluZGV4IDwgYXJyLmxlbmd0aCkge1xyXG4gICAgICAgICAgICAvLyBSZW1vdmUgdGhlIGVsZW1lbnQgYXQgdGhlIHNwZWNpZmllZCBpbmRleFxyXG4gICAgICAgICAgICBhcnIuc3BsaWNlKGluZGV4LCAxKTsgICAgICAgICAgICBcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIGFycjtcclxuICAgIH1cclxuXHJcbiAgICByZW1vdmVFbGVtZW50KGFycjogYW55LCBlbGVtZW50OiBhbnkpOiBudW1iZXJbXSB7XHJcbiAgICAgICAgLy8gUmVtb3ZlIGFsbCBvY2N1cnJlbmNlcyBvZiB0aGUgc3BlY2lmaWVkIGVsZW1lbnQgZnJvbSB0aGUgYXJyYXlcclxuICAgICAgICByZXR1cm4gYXJyLmZpbHRlcigoaXRlbTogYW55KSA9PiBpdGVtICE9PSBlbGVtZW50KTtcclxuICAgIH1cclxuXHJcbmNsZWFuX2FycmF5X29mX3RlbnNvcnModGVuc29yczogdGYuU2VxdWVudGlhbFtdKSB7XHJcblxyXG4gICAgdGVuc29ycy5mb3JFYWNoKChlbGVtLCBpbmRleCk9PnsgXHJcbiAgICAgICAgLy8gaWYoIWluZGV4X3NlbGVjdGlvbi5pbmNsdWRlcyhpbmRleCkpICBcclxuICAgICAgICAgICAgZWxlbS5kaXNwb3NlKCkgXHJcbiAgICAgICAgfSk7XHJcblxyXG59XHJcblxyXG4gZ2V0Q2xhc3NOYW1lQnlTaWduYXR1cmUoY2xhc3NlczogQ2xhc3NbXSwgc2lnbmF0dXJlOiBudW1iZXJbXSkgeyAgICAgICAgICAgXHJcbiAgICBcclxuICAgICAgICBjb25zdCBjbGFzc19uYW1lID0gY2xhc3Nlcy5maW5kKHAgPT4ge1xyXG4gICAgICAgICAgICBsZXQgbWF0Y2ggPSB0cnVlO1xyXG4gICAgICAgICAgICBwLnNpZ25hdHVyZT8uZm9yRWFjaCAoKGVsZW0saW5kZXgpPT57IFxyXG4gICAgICAgICAgICAgICAgaWYoZWxlbSE9PXNpZ25hdHVyZVtpbmRleF0pXHJcbiAgICAgICAgICAgICAgICAgICAgbWF0Y2g9ZmFsc2U7ICAgICAgICAgICAgICAgIFxyXG4gICAgICAgICAgICB9KVxyXG5cclxuICAgICAgICAgICAgcmV0dXJuIG1hdGNoO1xyXG4gICAgICAgIH0pO1xyXG5cclxuICAgICAgICByZXR1cm4gY2xhc3NfbmFtZSA/IGNsYXNzX25hbWUubmFtZSA6IFwibm90IGZvdW5kXCI7XHJcbn1cclxuXHJcbmlkZW50aXR5TWF0cml4KG46IG51bWJlcik6IG51bWJlcltdW10ge1xyXG4gICAgICAgIHJldHVybiBBcnJheS5mcm9tKHsgbGVuZ3RoOiBuIH0sIChfLCBpKSA9PiBBcnJheS5mcm9tKHsgbGVuZ3RoOiBuIH0sIChfLCBqKSA9PiAoaSA9PT0gaiA/IDEgOiAwKSkpO1xyXG59ICBcclxuXHJcblxyXG5pbmRleE9mTWF4KGFycjogbnVtYmVyW10pOiBudW1iZXIge1xyXG4gICAgICAgIGlmIChhcnIubGVuZ3RoID09PSAwKSB7XHJcbiAgICAgICAgICAgIHJldHVybiAtMTsgLy8gUmV0dXJuIC0xIGZvciBhbiBlbXB0eSBhcnJheVxyXG4gICAgICAgIH1cclxuICAgIFxyXG4gICAgICAgIGxldCBtYXggPSBhcnJbMF07XHJcbiAgICAgICAgbGV0IG1heEluZGV4ID0gMDtcclxuICAgIFxyXG4gICAgICAgIGZvciAobGV0IGkgPSAxOyBpIDwgYXJyLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgIGlmIChhcnJbaV0gPiBtYXgpIHtcclxuICAgICAgICAgICAgICAgIG1heEluZGV4ID0gaTtcclxuICAgICAgICAgICAgICAgIG1heCA9IGFycltpXTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgIFxyXG4gICAgICAgIHJldHVybiBtYXhJbmRleDtcclxuICAgIH1cclxuXHJcblxyXG5zdWZmbGUoYXJyYXkxOmFueSwgYXJyYXkyOiBhbnkpe1xyXG4gICAgICAgIC8vIFNodWZmbGUgdGhlIG9yZGVyIG9mIGVsZW1lbnRzXHJcbiAgICBmb3IgKGxldCBpID0gYXJyYXkxLmxlbmd0aCAtIDE7IGkgPiAwOyBpLS0pIHtcclxuICAgIGNvbnN0IGogPSBNYXRoLmZsb29yKE1hdGgucmFuZG9tKCkgKiAoaSArIDEpKTtcclxuXHJcbiAgICAvLyBTd2FwIGVsZW1lbnRzIGluIGJvdGggYXJyYXlzXHJcbiAgICBbYXJyYXkxW2ldLCBhcnJheTFbal1dID0gW2FycmF5MVtqXSwgYXJyYXkxW2ldXTtcclxuICAgIFthcnJheTJbaV0sIGFycmF5MltqXV0gPSBbYXJyYXkyW2pdLCBhcnJheTJbaV1dO1xyXG4gICAgICB9XHJcbiAgICBcclxuICAgIFxyXG4gICAgfVxyXG5cclxuICAgIHNvcnRCeVZhbHVlUHJlc2VydmluZ0luZGV4PFQ+KFxyXG4gICAgICAgIGFycjE6IG51bWJlcltdLFxyXG4gICAgICAgIGFycjI6IGFueVtdXHJcbiAgICApOiBUW10ge1xyXG5cclxuICAgICAgICAvLyBjb25zb2xlLmxvZyhcIlZlY3RvciBmb3Igb3JnYW5pemluZzogXCIsIGFycjEpXHJcbiAgICAgICAgLy8gYXJyMlswXS5zdW1tYXJ5KClcclxuXHJcbiAgICAgICAgLy8gQ3JlYXRlIGFuIGFycmF5IG9mIG9iamVjdHMgd2l0aCB2YWx1ZSwgaW5kZXggZnJvbSBhcnIxLCBhbmQgb3JpZ2luYWwgaW5kZXhcclxuICAgICAgICBjb25zdCBwYWlyaW5nQXJyYXkgPSBhcnIxLm1hcCgodmFsdWUsIGluZGV4KSA9PiAoe1xyXG4gICAgICAgICAgICB2YWx1ZSxcclxuICAgICAgICAgICAgaW5kZXgsXHJcbiAgICAgICAgICAgIG9yaWdpbmFsSW5kZXg6IGluZGV4LFxyXG4gICAgICAgICAgICBlbGVtZW50RnJvbUFycjI6IGFycjJbaW5kZXhdLCAvLyBQcmVzZXJ2ZSB0aGUgY29ycmVzcG9uZGluZyBlbGVtZW50IGZyb20gYXJyMlxyXG4gICAgICAgIH0pKTtcclxuICAgIFxyXG4gICAgICAgIC8vIFNvcnQgdGhlIHBhaXJpbmcgYXJyYXkgYnkgdmFsdWUgKGxhcmdlc3QgdG8gc21hbGxlc3QpXHJcbiAgICAgICAgcGFpcmluZ0FycmF5LnNvcnQoKGEsIGIpID0+IGIudmFsdWUgLSBhLnZhbHVlKTtcclxuXHJcbiAgICAgICAgXHJcbiAgICBcclxuICAgICAgICAvLyBFeHRyYWN0IHRoZSBzb3J0ZWQgZWxlbWVudHMgZnJvbSBhcnIyIGJhc2VkIG9uIHRoZSBvcmlnaW5hbCBpbmRleFxyXG4gICAgICAgIGNvbnN0IHNvcnRlZEVsZW1lbnRzRnJvbUFycjIgPSBwYWlyaW5nQXJyYXkubWFwKHBhaXIgPT4gcGFpci5lbGVtZW50RnJvbUFycjIpO1xyXG4gICAgXHJcbiAgICAgICAgcmV0dXJuIHNvcnRlZEVsZW1lbnRzRnJvbUFycjI7XHJcbiAgICB9ICAgIFxyXG4gICAgXHJcbn1cclxuXHJcbiJdfQ==