@bitgo/sdk-coin-apt 2.6.4 → 2.6.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/src/lib/transaction/customTransaction.d.ts +27 -1
- package/dist/src/lib/transaction/customTransaction.d.ts.map +1 -1
- package/dist/src/lib/transaction/customTransaction.js +96 -71
- package/dist/src/lib/utils.d.ts +9 -1
- package/dist/src/lib/utils.d.ts.map +1 -1
- package/dist/src/lib/utils.js +18 -1
- package/dist/test/unit/customTransaction.test.d.ts +2 -0
- package/dist/test/unit/customTransaction.test.d.ts.map +1 -0
- package/dist/test/unit/customTransaction.test.js +264 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +6 -6
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
+
};
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
const statics_1 = require("@bitgo/statics");
|
|
40
|
+
const customTransaction_1 = require("../../src/lib/transaction/customTransaction");
|
|
41
|
+
const ts_sdk_1 = require("@aptos-labs/ts-sdk");
|
|
42
|
+
const should_1 = __importDefault(require("should"));
|
|
43
|
+
const testData = __importStar(require("../resources/apt"));
|
|
44
|
+
describe('CustomTransaction - Argument Conversion', () => {
|
|
45
|
+
let customTransaction;
|
|
46
|
+
beforeEach(() => {
|
|
47
|
+
customTransaction = new customTransaction_1.CustomTransaction(statics_1.coins.get('tapt'));
|
|
48
|
+
});
|
|
49
|
+
// Helper function to access private method for testing
|
|
50
|
+
const callConvertArgumentByABI = (transaction, arg, paramType) => {
|
|
51
|
+
return transaction.convertArgumentByABI(arg, paramType);
|
|
52
|
+
};
|
|
53
|
+
describe('Real Transaction Scenarios', () => {
|
|
54
|
+
describe('Common Primitive Arguments', () => {
|
|
55
|
+
it('should handle address strings from test data', () => {
|
|
56
|
+
// Test with actual addresses from test resources
|
|
57
|
+
const result1 = callConvertArgumentByABI(customTransaction, testData.sender.address, new ts_sdk_1.TypeTagAddress());
|
|
58
|
+
const result2 = callConvertArgumentByABI(customTransaction, testData.recipients[0].address, new ts_sdk_1.TypeTagAddress());
|
|
59
|
+
should_1.default.exist(result1);
|
|
60
|
+
should_1.default.exist(result2);
|
|
61
|
+
// Results should be AccountAddress objects or original strings
|
|
62
|
+
if (typeof result1 === 'object') {
|
|
63
|
+
should_1.default.exist(result1.toString);
|
|
64
|
+
}
|
|
65
|
+
if (typeof result2 === 'object') {
|
|
66
|
+
should_1.default.exist(result2.toString);
|
|
67
|
+
}
|
|
68
|
+
});
|
|
69
|
+
it('should handle amount strings from test data', () => {
|
|
70
|
+
// Test with actual amounts from test resources
|
|
71
|
+
const result1 = callConvertArgumentByABI(customTransaction, testData.AMOUNT.toString(), new ts_sdk_1.TypeTagU64());
|
|
72
|
+
const result2 = callConvertArgumentByABI(customTransaction, testData.recipients[0].amount, new ts_sdk_1.TypeTagU64());
|
|
73
|
+
should_1.default.equal(result1, testData.AMOUNT.toString());
|
|
74
|
+
should_1.default.equal(result2, testData.recipients[0].amount);
|
|
75
|
+
});
|
|
76
|
+
it('should handle numeric amounts as numbers for small types', () => {
|
|
77
|
+
const result1 = callConvertArgumentByABI(customTransaction, 255, new ts_sdk_1.TypeTagU8());
|
|
78
|
+
const result2 = callConvertArgumentByABI(customTransaction, testData.AMOUNT, new ts_sdk_1.TypeTagU64());
|
|
79
|
+
should_1.default.equal(result1, 255);
|
|
80
|
+
should_1.default.equal(result2, testData.AMOUNT.toString()); // Large numbers become strings
|
|
81
|
+
});
|
|
82
|
+
it('should handle boolean values correctly', () => {
|
|
83
|
+
const result1 = callConvertArgumentByABI(customTransaction, true, new ts_sdk_1.TypeTagBool());
|
|
84
|
+
const result2 = callConvertArgumentByABI(customTransaction, false, new ts_sdk_1.TypeTagBool());
|
|
85
|
+
should_1.default.equal(result1, true);
|
|
86
|
+
should_1.default.equal(result2, false);
|
|
87
|
+
});
|
|
88
|
+
});
|
|
89
|
+
describe('BCS Encoded Arguments from Real Transactions', () => {
|
|
90
|
+
it('should handle BCS data with data property (from serialized tx)', () => {
|
|
91
|
+
// This simulates BCS-encoded data structure found in real transactions
|
|
92
|
+
const bcsData = {
|
|
93
|
+
data: new Uint8Array([0xe8, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]), // 1000 in little-endian
|
|
94
|
+
};
|
|
95
|
+
const result = callConvertArgumentByABI(customTransaction, bcsData, new ts_sdk_1.TypeTagU64());
|
|
96
|
+
should_1.default.equal(result, '0xe803000000000000');
|
|
97
|
+
});
|
|
98
|
+
it('should handle BCS address data', () => {
|
|
99
|
+
// Create proper 32-byte address data as found in real transactions
|
|
100
|
+
const addressBytes = new Array(32).fill(0);
|
|
101
|
+
addressBytes[31] = 0x01; // Standard address format
|
|
102
|
+
const bcsData = {
|
|
103
|
+
data: new Uint8Array(addressBytes),
|
|
104
|
+
};
|
|
105
|
+
const result = callConvertArgumentByABI(customTransaction, bcsData, new ts_sdk_1.TypeTagAddress());
|
|
106
|
+
should_1.default.exist(result);
|
|
107
|
+
if (typeof result === 'string') {
|
|
108
|
+
result.should.match(/^0x[0-9a-fA-F]+$/);
|
|
109
|
+
}
|
|
110
|
+
});
|
|
111
|
+
});
|
|
112
|
+
describe('Nested BCS Structures (Real Transaction Parsing)', () => {
|
|
113
|
+
it('should handle U64 amount in nested structure (typical from parsed tx)', () => {
|
|
114
|
+
// This structure is common when parsing amounts from real Aptos transactions
|
|
115
|
+
const nestedAmount = {
|
|
116
|
+
value: {
|
|
117
|
+
value: new Uint8Array([0xe8, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]), // 1000
|
|
118
|
+
},
|
|
119
|
+
};
|
|
120
|
+
const result = callConvertArgumentByABI(customTransaction, nestedAmount, new ts_sdk_1.TypeTagU64());
|
|
121
|
+
should_1.default.equal(result, '1000');
|
|
122
|
+
});
|
|
123
|
+
it('should handle double nested numeric structure from BCS parsing', () => {
|
|
124
|
+
// This represents the typical structure when deserializing BCS-encoded numeric values
|
|
125
|
+
const nestedData = {
|
|
126
|
+
value: {
|
|
127
|
+
value: {
|
|
128
|
+
0: 0xe8, // 1000 in little-endian format
|
|
129
|
+
1: 0x03,
|
|
130
|
+
2: 0x00,
|
|
131
|
+
3: 0x00,
|
|
132
|
+
4: 0x00,
|
|
133
|
+
5: 0x00,
|
|
134
|
+
6: 0x00,
|
|
135
|
+
7: 0x00,
|
|
136
|
+
},
|
|
137
|
+
},
|
|
138
|
+
};
|
|
139
|
+
const result = callConvertArgumentByABI(customTransaction, nestedData, new ts_sdk_1.TypeTagU64());
|
|
140
|
+
should_1.default.equal(result, '1000');
|
|
141
|
+
});
|
|
142
|
+
it('should handle nested structure for boolean values', () => {
|
|
143
|
+
// Boolean values in BCS format
|
|
144
|
+
const booleanTrue = {
|
|
145
|
+
value: {
|
|
146
|
+
value: {
|
|
147
|
+
0: 1,
|
|
148
|
+
},
|
|
149
|
+
},
|
|
150
|
+
};
|
|
151
|
+
const booleanFalse = {
|
|
152
|
+
value: {
|
|
153
|
+
value: {
|
|
154
|
+
0: 0,
|
|
155
|
+
},
|
|
156
|
+
},
|
|
157
|
+
};
|
|
158
|
+
const result1 = callConvertArgumentByABI(customTransaction, booleanTrue, new ts_sdk_1.TypeTagBool());
|
|
159
|
+
const result2 = callConvertArgumentByABI(customTransaction, booleanFalse, new ts_sdk_1.TypeTagBool());
|
|
160
|
+
should_1.default.equal(result1, true);
|
|
161
|
+
should_1.default.equal(result2, false);
|
|
162
|
+
});
|
|
163
|
+
it('should handle simple nested value (fix for original bug)', () => {
|
|
164
|
+
// This tests the bug fix where primitive values in nested structures failed
|
|
165
|
+
const nestedPrimitive = {
|
|
166
|
+
value: '1000',
|
|
167
|
+
};
|
|
168
|
+
const result = callConvertArgumentByABI(customTransaction, nestedPrimitive, new ts_sdk_1.TypeTagU64());
|
|
169
|
+
should_1.default.equal(result, '1000'); // Should extract and convert the primitive value
|
|
170
|
+
});
|
|
171
|
+
});
|
|
172
|
+
describe('Large Integer Types (Common in DeFi)', () => {
|
|
173
|
+
it('should handle U128 amounts (common for high-precision tokens)', () => {
|
|
174
|
+
const largeAmount = '340282366920938463463374607431768211455'; // Near max U128
|
|
175
|
+
const result = callConvertArgumentByABI(customTransaction, largeAmount, new ts_sdk_1.TypeTagU128());
|
|
176
|
+
should_1.default.equal(result, largeAmount);
|
|
177
|
+
});
|
|
178
|
+
it('should handle U128 in BCS format', () => {
|
|
179
|
+
// 16-byte array for U128 (example: value 1000)
|
|
180
|
+
const bytes = new Array(16).fill(0);
|
|
181
|
+
bytes[0] = 0xe8;
|
|
182
|
+
bytes[1] = 0x03;
|
|
183
|
+
const nestedData = {
|
|
184
|
+
value: {
|
|
185
|
+
value: Object.fromEntries(bytes.map((byte, index) => [index.toString(), byte])),
|
|
186
|
+
},
|
|
187
|
+
};
|
|
188
|
+
const result = callConvertArgumentByABI(customTransaction, nestedData, new ts_sdk_1.TypeTagU128());
|
|
189
|
+
should_1.default.equal(result, '1000');
|
|
190
|
+
});
|
|
191
|
+
});
|
|
192
|
+
describe('Error Handling for Real Edge Cases', () => {
|
|
193
|
+
it('should handle empty BCS structures gracefully', () => {
|
|
194
|
+
const emptyStructure = {
|
|
195
|
+
value: {
|
|
196
|
+
value: {},
|
|
197
|
+
},
|
|
198
|
+
};
|
|
199
|
+
const result = callConvertArgumentByABI(customTransaction, emptyStructure, new ts_sdk_1.TypeTagU64());
|
|
200
|
+
should_1.default.equal(result, emptyStructure); // Should return original when no valid bytes found
|
|
201
|
+
});
|
|
202
|
+
it('should handle non-BCS objects', () => {
|
|
203
|
+
const regularObject = { someProperty: 'value' };
|
|
204
|
+
const result = callConvertArgumentByABI(customTransaction, regularObject, new ts_sdk_1.TypeTagU64());
|
|
205
|
+
should_1.default.equal(result, regularObject); // Should return as-is for non-BCS objects
|
|
206
|
+
});
|
|
207
|
+
it('should handle null and undefined (defensive)', () => {
|
|
208
|
+
const result1 = callConvertArgumentByABI(customTransaction, null, new ts_sdk_1.TypeTagU64());
|
|
209
|
+
const result2 = callConvertArgumentByABI(customTransaction, undefined, new ts_sdk_1.TypeTagU64());
|
|
210
|
+
should_1.default.equal(result1, null);
|
|
211
|
+
should_1.default.equal(result2, undefined);
|
|
212
|
+
});
|
|
213
|
+
});
|
|
214
|
+
describe('Integration with Utility Functions', () => {
|
|
215
|
+
it('should use bytesToHex utility for non-numeric BCS data', () => {
|
|
216
|
+
const bcsData = {
|
|
217
|
+
data: new Uint8Array([0x12, 0x34, 0x56, 0x78]),
|
|
218
|
+
};
|
|
219
|
+
const result = callConvertArgumentByABI(customTransaction, bcsData, new ts_sdk_1.TypeTagAddress());
|
|
220
|
+
// Should either be converted to AccountAddress or remain as hex string
|
|
221
|
+
should_1.default.exist(result);
|
|
222
|
+
});
|
|
223
|
+
it('should use tryParseAccountAddress utility for address strings', () => {
|
|
224
|
+
const validAddress = '0x0000000000000000000000000000000000000000000000000000000000000001';
|
|
225
|
+
const result = callConvertArgumentByABI(customTransaction, validAddress, new ts_sdk_1.TypeTagAddress());
|
|
226
|
+
should_1.default.exist(result);
|
|
227
|
+
// Should either be AccountAddress object or original string
|
|
228
|
+
if (typeof result === 'object') {
|
|
229
|
+
should_1.default.exist(result.toString);
|
|
230
|
+
}
|
|
231
|
+
});
|
|
232
|
+
it('should use convertNumericArgument utility for byte arrays', () => {
|
|
233
|
+
const uint8Data = new Uint8Array([0xe8, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]); // 1000
|
|
234
|
+
const nestedData = {
|
|
235
|
+
value: {
|
|
236
|
+
value: uint8Data,
|
|
237
|
+
},
|
|
238
|
+
};
|
|
239
|
+
const result = callConvertArgumentByABI(customTransaction, nestedData, new ts_sdk_1.TypeTagU64());
|
|
240
|
+
should_1.default.equal(result, '1000'); // Should use existing numeric conversion logic
|
|
241
|
+
});
|
|
242
|
+
});
|
|
243
|
+
});
|
|
244
|
+
describe('Round-trip Compatibility', () => {
|
|
245
|
+
it('should maintain compatibility with existing transaction parsing', () => {
|
|
246
|
+
// This ensures our refactored method works with the existing transaction builder tests
|
|
247
|
+
const testArguments = [
|
|
248
|
+
{ arg: testData.sender.address, type: new ts_sdk_1.TypeTagAddress() },
|
|
249
|
+
{ arg: testData.AMOUNT.toString(), type: new ts_sdk_1.TypeTagU64() },
|
|
250
|
+
{ arg: true, type: new ts_sdk_1.TypeTagBool() },
|
|
251
|
+
{ arg: 255, type: new ts_sdk_1.TypeTagU8() },
|
|
252
|
+
];
|
|
253
|
+
testArguments.forEach(({ arg, type }) => {
|
|
254
|
+
const result = callConvertArgumentByABI(customTransaction, arg, type);
|
|
255
|
+
should_1.default.exist(result);
|
|
256
|
+
// Result should be compatible with existing transaction building logic
|
|
257
|
+
if (typeof result === 'string' || typeof result === 'number' || typeof result === 'boolean') {
|
|
258
|
+
should_1.default.exist(result.toString);
|
|
259
|
+
}
|
|
260
|
+
});
|
|
261
|
+
});
|
|
262
|
+
});
|
|
263
|
+
});
|
|
264
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY3VzdG9tVHJhbnNhY3Rpb24udGVzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3Rlc3QvdW5pdC9jdXN0b21UcmFuc2FjdGlvbi50ZXN0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUEsNENBQXVDO0FBQ3ZDLG1GQUFnRjtBQUNoRiwrQ0FBcUc7QUFDckcsb0RBQTRCO0FBQzVCLDJEQUE2QztBQUU3QyxRQUFRLENBQUMseUNBQXlDLEVBQUUsR0FBRyxFQUFFO0lBQ3ZELElBQUksaUJBQW9DLENBQUM7SUFFekMsVUFBVSxDQUFDLEdBQUcsRUFBRTtRQUNkLGlCQUFpQixHQUFHLElBQUkscUNBQWlCLENBQUMsZUFBSyxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDO0lBQy9ELENBQUMsQ0FBQyxDQUFDO0lBRUgsdURBQXVEO0lBQ3ZELE1BQU0sd0JBQXdCLEdBQUcsQ0FBQyxXQUE4QixFQUFFLEdBQVEsRUFBRSxTQUFjLEVBQU8sRUFBRTtRQUNqRyxPQUFRLFdBQW1CLENBQUMsb0JBQW9CLENBQUMsR0FBRyxFQUFFLFNBQVMsQ0FBQyxDQUFDO0lBQ25FLENBQUMsQ0FBQztJQUVGLFFBQVEsQ0FBQyw0QkFBNEIsRUFBRSxHQUFHLEVBQUU7UUFDMUMsUUFBUSxDQUFDLDRCQUE0QixFQUFFLEdBQUcsRUFBRTtZQUMxQyxFQUFFLENBQUMsOENBQThDLEVBQUUsR0FBRyxFQUFFO2dCQUN0RCxpREFBaUQ7Z0JBQ2pELE1BQU0sT0FBTyxHQUFHLHdCQUF3QixDQUFDLGlCQUFpQixFQUFFLFFBQVEsQ0FBQyxNQUFNLENBQUMsT0FBTyxFQUFFLElBQUksdUJBQWMsRUFBRSxDQUFDLENBQUM7Z0JBQzNHLE1BQU0sT0FBTyxHQUFHLHdCQUF3QixDQUN0QyxpQkFBaUIsRUFDakIsUUFBUSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxPQUFPLEVB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RSxDQUFDLGlFQUFpRSxFQUFFLEdBQUcsRUFBRTtZQUN6RSx1RkFBdUY7WUFDdkYsTUFBTSxhQUFhLEdBQUc7Z0JBQ3BCLEVBQUUsR0FBRyxFQUFFLFFBQVEsQ0FBQyxNQUFNLENBQUMsT0FBTyxFQUFFLElBQUksRUFBRSxJQUFJLHVCQUFjLEVBQUUsRUFBRTtnQkFDNUQsRUFBRSxHQUFHLEVBQUUsUUFBUSxDQUFDLE1BQU0sQ0FBQyxRQUFRLEVBQUUsRUFBRSxJQUFJLEVBQUUsSUFBSSxtQkFBVSxFQUFFLEVBQUU7Z0JBQzNELEVBQUUsR0FBRyxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsSUFBSSxvQkFBVyxFQUFFLEVBQUU7Z0JBQ3RDLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxJQUFJLEVBQUUsSUFBSSxrQkFBUyxFQUFFLEVBQUU7YUFDcEMsQ0FBQztZQUVGLGFBQWEsQ0FBQyxPQUFPLENBQUMsQ0FBQyxFQUFFLEdBQUcsRUFBRSxJQUFJLEVBQUUsRUFBRSxFQUFFO2dCQUN0QyxNQUFNLE1BQU0sR0FBRyx3QkFBd0IsQ0FBQyxpQkFBaUIsRUFBRSxHQUFHLEVBQUUsSUFBSSxDQUFDLENBQUM7Z0JBQ3RFLGdCQUFNLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxDQUFDO2dCQUVyQix1RUFBdUU7Z0JBQ3ZFLElBQUksT0FBTyxNQUFNLEtBQUssUUFBUSxJQUFJLE9BQU8sTUFBTSxLQUFLLFFBQVEsSUFBSSxPQUFPLE1BQU0sS0FBSyxTQUFTLEVBQUUsQ0FBQztvQkFDNUYsZ0JBQU0sQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxDQUFDO2dCQUNoQyxDQUFDO1lBQ0gsQ0FBQyxDQUFDLENBQUM7UUFDTCxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQyxDQUFDO0FBQ0wsQ0FBQyxDQUFDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBjb2lucyB9IGZyb20gJ0BiaXRnby9zdGF0aWNzJztcbmltcG9ydCB7IEN1c3RvbVRyYW5zYWN0aW9uIH0gZnJvbSAnLi4vLi4vc3JjL2xpYi90cmFuc2FjdGlvbi9jdXN0b21UcmFuc2FjdGlvbic7XG5pbXBvcnQgeyBUeXBlVGFnQWRkcmVzcywgVHlwZVRhZ0Jvb2wsIFR5cGVUYWdVOCwgVHlwZVRhZ1U2NCwgVHlwZVRhZ1UxMjggfSBmcm9tICdAYXB0b3MtbGFicy90cy1zZGsnO1xuaW1wb3J0IHNob3VsZCBmcm9tICdzaG91bGQnO1xuaW1wb3J0ICogYXMgdGVzdERhdGEgZnJvbSAnLi4vcmVzb3VyY2VzL2FwdCc7XG5cbmRlc2NyaWJlKCdDdXN0b21UcmFuc2FjdGlvbiAtIEFyZ3VtZW50IENvbnZlcnNpb24nLCAoKSA9PiB7XG4gIGxldCBjdXN0b21UcmFuc2FjdGlvbjogQ3VzdG9tVHJhbnNhY3Rpb247XG5cbiAgYmVmb3JlRWFjaCgoKSA9PiB7XG4gICAgY3VzdG9tVHJhbnNhY3Rpb24gPSBuZXcgQ3VzdG9tVHJhbnNhY3Rpb24oY29pbnMuZ2V0KCd0YXB0JykpO1xuICB9KTtcblxuICAvLyBIZWxwZXIgZnVuY3Rpb24gdG8gYWNjZXNzIHByaXZhdGUgbWV0aG9kIGZvciB0ZXN0aW5nXG4gIGNvbnN0IGNhbGxDb252ZXJ0QXJndW1lbnRCeUFCSSA9ICh0cmFuc2FjdGlvbjogQ3VzdG9tVHJhbnNhY3Rpb24sIGFyZzogYW55LCBwYXJhbVR5cGU6IGFueSk6IGFueSA9PiB7XG4gICAgcmV0dXJuICh0cmFuc2FjdGlvbiBhcyBhbnkpLmNvbnZlcnRBcmd1bWVudEJ5QUJJKGFyZywgcGFyYW1UeXBlKTtcbiAgfTtcblxuICBkZXNjcmliZSgnUmVhbCBUcmFuc2FjdGlvbiBTY2VuYXJpb3MnLCAoKSA9PiB7XG4gICAgZGVzY3JpYmUoJ0NvbW1vbiBQcmltaXRpdmUgQXJndW1lbnRzJywgKCkgPT4ge1xuICAgICAgaXQoJ3Nob3VsZCBoYW5kbGUgYWRkcmVzcyBzdHJpbmdzIGZyb20gdGVzdCBkYXRhJywgKCkgPT4ge1xuICAgICAgICAvLyBUZXN0IHdpdGggYWN0dWFsIGFkZHJlc3NlcyBmcm9tIHRlc3QgcmVzb3VyY2VzXG4gICAgICAgIGNvbnN0IHJlc3VsdDEgPSBjYWxsQ29udmVydEFyZ3VtZW50QnlBQkkoY3VzdG9tVHJhbnNhY3Rpb24sIHRlc3REYXRhLnNlbmRlci5hZGRyZXNzLCBuZXcgVHlwZVRhZ0FkZHJlc3MoKSk7XG4gICAgICAgIGNvbnN0IHJlc3VsdDIgPSBjYWxsQ29udmVydEFyZ3VtZW50QnlBQkkoXG4gICAgICAgICAgY3VzdG9tVHJhbnNhY3Rpb24sXG4gICAgICAgICAgdGVzdERhdGEucmVjaXBpZW50c1swXS5hZGRyZXNzLFxuICAgICAgICAgIG5ldyBUeXBlVGFnQWRkcmVzcygpXG4gICAgICAgICk7XG5cbiAgICAgICAgc2hvdWxkLmV4aXN0KHJlc3VsdDEpO1xuICAgICAgICBzaG91bGQuZXhpc3QocmVzdWx0Mik7XG5cbiAgICAgICAgLy8gUmVzdWx0cyBzaG91bGQgYmUgQWNjb3VudEFkZHJlc3Mgb2JqZWN0cyBvciBvcmlnaW5hbCBzdHJpbmdzXG4gICAgICAgIGlmICh0eXBlb2YgcmVzdWx0MSA9PT0gJ29iamVjdCcpIHtcbiAgICAgICAgICBzaG91bGQuZXhpc3QocmVzdWx0MS50b1N0cmluZyk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGVvZiByZXN1bHQyID09PSAnb2JqZWN0Jykge1xuICAgICAgICAgIHNob3VsZC5leGlzdChyZXN1bHQyLnRvU3RyaW5nKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgaGFuZGxlIGFtb3VudCBzdHJpbmdzIGZyb20gdGVzdCBkYXRhJywgKCkgPT4ge1xuICAgICAgICAvLyBUZXN0IHdpdGggYWN0dWFsIGFtb3VudHMgZnJvbSB0ZXN0IHJlc291cmNlc1xuICAgICAgICBjb25zdCByZXN1bHQxID0gY2FsbENvbnZlcnRBcmd1bWVudEJ5QUJJKGN1c3RvbVRyYW5zYWN0aW9uLCB0ZXN0RGF0YS5BTU9VTlQudG9TdHJpbmcoKSwgbmV3IFR5cGVUYWdVNjQoKSk7XG4gICAgICAgIGNvbnN0IHJlc3VsdDIgPSBjYWxsQ29udmVydEFyZ3VtZW50QnlBQkkoY3VzdG9tVHJhbnNhY3Rpb24sIHRlc3REYXRhLnJlY2lwaWVudHNbMF0uYW1vdW50LCBuZXcgVHlwZVRhZ1U2NCgpKTtcblxuICAgICAgICBzaG91bGQuZXF1YWwocmVzdWx0MSwgdGVzdERhdGEuQU1PVU5ULnRvU3RyaW5nKCkpO1xuICAgICAgICBzaG91bGQuZXF1YWwocmVzdWx0MiwgdGVzdERhdGEucmVjaXBpZW50c1swXS5hbW91bnQpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgaGFuZGxlIG51bWVyaWMgYW1vdW50cyBhcyBudW1iZXJzIGZvciBzbWFsbCB0eXBlcycsICgpID0+IHtcbiAgICAgICAgY29uc3QgcmVzdWx0MSA9IGNhbGxDb252ZXJ0QXJndW1lbnRCeUFCSShjdXN0b21UcmFuc2FjdGlvbiwgMjU1LCBuZXcgVHlwZVRhZ1U4KCkpO1xuICAgICAgICBjb25zdCByZXN1bHQyID0gY2FsbENvbnZlcnRBcmd1bWVudEJ5QUJJKGN1c3RvbVRyYW5zYWN0aW9uLCB0ZXN0RGF0YS5BTU9VTlQsIG5ldyBUeXBlVGFnVTY0KCkpO1xuXG4gICAgICAgIHNob3VsZC5lcXVhbChyZXN1bHQxLCAyNTUpO1xuICAgICAgICBzaG91bGQuZXF1YWwocmVzdWx0MiwgdGVzdERhdGEuQU1PVU5ULnRvU3RyaW5nKCkpOyAvLyBMYXJnZSBudW1iZXJzIGJlY29tZSBzdHJpbmdzXG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCBoYW5kbGUgYm9vbGVhbiB2YWx1ZXMgY29ycmVjdGx5JywgKCkgPT4ge1xuICAgICAgICBjb25zdCByZXN1bHQxID0gY2FsbENvbnZlcnRBcmd1bWVudEJ5QUJJKGN1c3RvbVRyYW5zYWN0aW9uLCB0cnVlLCBuZXcgVHlwZVRhZ0Jvb2woKSk7XG4gICAgICAgIGNvbnN0IHJlc3VsdDIgPSBjYWxsQ29udmVydEFyZ3VtZW50QnlBQkkoY3VzdG9tVHJhbnNhY3Rpb24sIGZhbHNlLCBuZXcgVHlwZVRhZ0Jvb2woKSk7XG5cbiAgICAgICAgc2hvdWxkLmVxdWFsKHJlc3VsdDEsIHRydWUpO1xuICAgICAgICBzaG91bGQuZXF1YWwocmVzdWx0MiwgZmFsc2UpO1xuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgnQkNTIEVuY29kZWQgQXJndW1lbnRzIGZyb20gUmVhbCBUcmFuc2FjdGlvbnMnLCAoKSA9PiB7XG4gICAgICBpdCgnc2hvdWxkIGhhbmRsZSBCQ1MgZGF0YSB3aXRoIGRhdGEgcHJvcGVydHkgKGZyb20gc2VyaWFsaXplZCB0eCknLCAoKSA9PiB7XG4gICAgICAgIC8vIFRoaXMgc2ltdWxhdGVzIEJDUy1lbmNvZGVkIGRhdGEgc3RydWN0dXJlIGZvdW5kIGluIHJlYWwgdHJhbnNhY3Rpb25zXG4gICAgICAgIGNvbnN0IGJjc0RhdGEgPSB7XG4gICAgICAgICAgZGF0YTogbmV3IFVpbnQ4QXJyYXkoWzB4ZTgsIDB4MDMsIDB4MDAsIDB4MDAsIDB4MDAsIDB4MDAsIDB4MDAsIDB4MDBdKSwgLy8gMTAwMCBpbiBsaXR0bGUtZW5kaWFuXG4gICAgICAgIH07XG5cbiAgICAgICAgY29uc3QgcmVzdWx0ID0gY2FsbENvbnZlcnRBcmd1bWVudEJ5QUJJKGN1c3RvbVRyYW5zYWN0aW9uLCBiY3NEYXRhLCBuZXcgVHlwZVRhZ1U2NCgpKTtcbiAgICAgICAgc2hvdWxkLmVxdWFsKHJlc3VsdCwgJzB4ZTgwMzAwMDAwMDAwMDAwMCcpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgaGFuZGxlIEJDUyBhZGRyZXNzIGRhdGEnLCAoKSA9PiB7XG4gICAgICAgIC8vIENyZWF0ZSBwcm9wZXIgMzItYnl0ZSBhZGRyZXNzIGRhdGEgYXMgZm91bmQgaW4gcmVhbCB0cmFuc2FjdGlvbnNcbiAgICAgICAgY29uc3QgYWRkcmVzc0J5dGVzID0gbmV3IEFycmF5KDMyKS5maWxsKDApO1xuICAgICAgICBhZGRyZXNzQnl0ZXNbMzFdID0gMHgwMTsgLy8gU3RhbmRhcmQgYWRkcmVzcyBmb3JtYXRcblxuICAgICAgICBjb25zdCBiY3NEYXRhID0ge1xuICAgICAgICAgIGRhdGE6IG5ldyBVaW50OEFycmF5KGFkZHJlc3NCeXRlcyksXG4gICAgICAgIH07XG5cbiAgICAgICAgY29uc3QgcmVzdWx0ID0gY2FsbENvbnZlcnRBcmd1bWVudEJ5QUJJKGN1c3RvbVRyYW5zYWN0aW9uLCBiY3NEYXRhLCBuZXcgVHlwZVRhZ0FkZHJlc3MoKSk7XG4gICAgICAgIHNob3VsZC5leGlzdChyZXN1bHQpO1xuXG4gICAgICAgIGlmICh0eXBlb2YgcmVzdWx0ID09PSAnc3RyaW5nJykge1xuICAgICAgICAgIHJlc3VsdC5zaG91bGQubWF0Y2goL14weFswLTlhLWZBLUZdKyQvKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgnTmVzdGVkIEJDUyBTdHJ1Y3R1cmVzIChSZWFsIFRyYW5zYWN0aW9uIFBhcnNpbmcpJywgKCkgPT4ge1xuICAgICAgaXQoJ3Nob3VsZCBoYW5kbGUgVTY0IGFtb3VudCBpbiBuZXN0ZWQgc3RydWN0dXJlICh0eXBpY2FsIGZyb20gcGFyc2VkIHR4KScsICgpID0+IHtcbiAgICAgICAgLy8gVGhpcyBzdHJ1Y3R1cmUgaXMgY29tbW9uIHdoZW4gcGFyc2luZyBhbW91bnRzIGZyb20gcmVhbCBBcHRvcyB0cmFuc2FjdGlvbnNcbiAgICAgICAgY29uc3QgbmVzdGVkQW1vdW50ID0ge1xuICAgICAgICAgIHZhbHVlOiB7XG4gICAgICAgICAgICB2YWx1ZTogbmV3IFVpbnQ4QXJyYXkoWzB4ZTgsIDB4MDMsIDB4MDAsIDB4MDAsIDB4MDAsIDB4MDAsIDB4MDAsIDB4MDBdKSwgLy8gMTAwMFxuICAgICAgICAgIH0sXG4gICAgICAgIH07XG5cbiAgICAgICAgY29uc3QgcmVzdWx0ID0gY2FsbENvbnZlcnRBcmd1bWVudEJ5QUJJKGN1c3RvbVRyYW5zYWN0aW9uLCBuZXN0ZWRBbW91bnQsIG5ldyBUeXBlVGFnVTY0KCkpO1xuICAgICAgICBzaG91bGQuZXF1YWwocmVzdWx0LCAnMTAwMCcpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgaGFuZGxlIGRvdWJsZSBuZXN0ZWQgbnVtZXJpYyBzdHJ1Y3R1cmUgZnJvbSBCQ1MgcGFyc2luZycsICgpID0+IHtcbiAgICAgICAgLy8gVGhpcyByZXByZXNlbnRzIHRoZSB0eXBpY2FsIHN0cnVjdHVyZSB3aGVuIGRlc2VyaWFsaXppbmcgQkNTLWVuY29kZWQgbnVtZXJpYyB2YWx1ZXNcbiAgICAgICAgY29uc3QgbmVzdGVkRGF0YSA9IHtcbiAgICAgICAgICB2YWx1ZToge1xuICAgICAgICAgICAgdmFsdWU6IHtcbiAgICAgICAgICAgICAgMDogMHhlOCwgLy8gMTAwMCBpbiBsaXR0bGUtZW5kaWFuIGZvcm1hdFxuICAgICAgICAgICAgICAxOiAweDAzLFxuICAgICAgICAgICAgICAyOiAweDAwLFxuICAgICAgICAgICAgICAzOiAweDAwLFxuICAgICAgICAgICAgICA0OiAweDAwLFxuICAgICAgICAgICAgICA1OiAweDAwLFxuICAgICAgICAgICAgICA2OiAweDAwLFxuICAgICAgICAgICAgICA3OiAweDAwLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9LFxuICAgICAgICB9O1xuXG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IGNhbGxDb252ZXJ0QXJndW1lbnRCeUFCSShjdXN0b21UcmFuc2FjdGlvbiwgbmVzdGVkRGF0YSwgbmV3IFR5cGVUYWdVNjQoKSk7XG4gICAgICAgIHNob3VsZC5lcXVhbChyZXN1bHQsICcxMDAwJyk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCBoYW5kbGUgbmVzdGVkIHN0cnVjdHVyZSBmb3IgYm9vbGVhbiB2YWx1ZXMnLCAoKSA9PiB7XG4gICAgICAgIC8vIEJvb2xlYW4gdmFsdWVzIGluIEJDUyBmb3JtYXRcbiAgICAgICAgY29uc3QgYm9vbGVhblRydWUgPSB7XG4gICAgICAgICAgdmFsdWU6IHtcbiAgICAgICAgICAgIHZhbHVlOiB7XG4gICAgICAgICAgICAgIDA6IDEsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0sXG4gICAgICAgIH07XG5cbiAgICAgICAgY29uc3QgYm9vbGVhbkZhbHNlID0ge1xuICAgICAgICAgIHZhbHVlOiB7XG4gICAgICAgICAgICB2YWx1ZToge1xuICAgICAgICAgICAgICAwOiAwLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9LFxuICAgICAgICB9O1xuXG4gICAgICAgIGNvbnN0IHJlc3VsdDEgPSBjYWxsQ29udmVydEFyZ3VtZW50QnlBQkkoY3VzdG9tVHJhbnNhY3Rpb24sIGJvb2xlYW5UcnVlLCBuZXcgVHlwZVRhZ0Jvb2woKSk7XG4gICAgICAgIGNvbnN0IHJlc3VsdDIgPSBjYWxsQ29udmVydEFyZ3VtZW50QnlBQkkoY3VzdG9tVHJhbnNhY3Rpb24sIGJvb2xlYW5GYWxzZSwgbmV3IFR5cGVUYWdCb29sKCkpO1xuXG4gICAgICAgIHNob3VsZC5lcXVhbChyZXN1bHQxLCB0cnVlKTtcbiAgICAgICAgc2hvdWxkLmVxdWFsKHJlc3VsdDIsIGZhbHNlKTtcbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIGhhbmRsZSBzaW1wbGUgbmVzdGVkIHZhbHVlIChmaXggZm9yIG9yaWdpbmFsIGJ1ZyknLCAoKSA9PiB7XG4gICAgICAgIC8vIFRoaXMgdGVzdHMgdGhlIGJ1ZyBmaXggd2hlcmUgcHJpbWl0aXZlIHZhbHVlcyBpbiBuZXN0ZWQgc3RydWN0dXJlcyBmYWlsZWRcbiAgICAgICAgY29uc3QgbmVzdGVkUHJpbWl0aXZlID0ge1xuICAgICAgICAgIHZhbHVlOiAnMTAwMCcsXG4gICAgICAgIH07XG5cbiAgICAgICAgY29uc3QgcmVzdWx0ID0gY2FsbENvbnZlcnRBcmd1bWVudEJ5QUJJKGN1c3RvbVRyYW5zYWN0aW9uLCBuZXN0ZWRQcmltaXRpdmUsIG5ldyBUeXBlVGFnVTY0KCkpO1xuICAgICAgICBzaG91bGQuZXF1YWwocmVzdWx0LCAnMTAwMCcpOyAvLyBTaG91bGQgZXh0cmFjdCBhbmQgY29udmVydCB0aGUgcHJpbWl0aXZlIHZhbHVlXG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGRlc2NyaWJlKCdMYXJnZSBJbnRlZ2VyIFR5cGVzIChDb21tb24gaW4gRGVGaSknLCAoKSA9PiB7XG4gICAgICBpdCgnc2hvdWxkIGhhbmRsZSBVMTI4IGFtb3VudHMgKGNvbW1vbiBmb3IgaGlnaC1wcmVjaXNpb24gdG9rZW5zKScsICgpID0+IHtcbiAgICAgICAgY29uc3QgbGFyZ2VBbW91bnQgPSAnMzQwMjgyMzY2OTIwOTM4NDYzNDYzMzc0NjA3NDMxNzY4MjExNDU1JzsgLy8gTmVhciBtYXggVTEyOFxuICAgICAgICBjb25zdCByZXN1bHQgPSBjYWxsQ29udmVydEFyZ3VtZW50QnlBQkkoY3VzdG9tVHJhbnNhY3Rpb24sIGxhcmdlQW1vdW50LCBuZXcgVHlwZVRhZ1UxMjgoKSk7XG5cbiAgICAgICAgc2hvdWxkLmVxdWFsKHJlc3VsdCwgbGFyZ2VBbW91bnQpO1xuICAgICAgfSk7XG5cbiAgICAgIGl0KCdzaG91bGQgaGFuZGxlIFUxMjggaW4gQkNTIGZvcm1hdCcsICgpID0+IHtcbiAgICAgICAgLy8gMTYtYnl0ZSBhcnJheSBmb3IgVTEyOCAoZXhhbXBsZTogdmFsdWUgMTAwMClcbiAgICAgICAgY29uc3QgYnl0ZXMgPSBuZXcgQXJyYXkoMTYpLmZpbGwoMCk7XG4gICAgICAgIGJ5dGVzWzBdID0gMHhlODtcbiAgICAgICAgYnl0ZXNbMV0gPSAweDAzO1xuXG4gICAgICAgIGNvbnN0IG5lc3RlZERhdGEgPSB7XG4gICAgICAgICAgdmFsdWU6IHtcbiAgICAgICAgICAgIHZhbHVlOiBPYmplY3QuZnJvbUVudHJpZXMoYnl0ZXMubWFwKChieXRlLCBpbmRleCkgPT4gW2luZGV4LnRvU3RyaW5nKCksIGJ5dGVdKSksXG4gICAgICAgICAgfSxcbiAgICAgICAgfTtcblxuICAgICAgICBjb25zdCByZXN1bHQgPSBjYWxsQ29udmVydEFyZ3VtZW50QnlBQkkoY3VzdG9tVHJhbnNhY3Rpb24sIG5lc3RlZERhdGEsIG5ldyBUeXBlVGFnVTEyOCgpKTtcbiAgICAgICAgc2hvdWxkLmVxdWFsKHJlc3VsdCwgJzEwMDAnKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgZGVzY3JpYmUoJ0Vycm9yIEhhbmRsaW5nIGZvciBSZWFsIEVkZ2UgQ2FzZXMnLCAoKSA9PiB7XG4gICAgICBpdCgnc2hvdWxkIGhhbmRsZSBlbXB0eSBCQ1Mgc3RydWN0dXJlcyBncmFjZWZ1bGx5JywgKCkgPT4ge1xuICAgICAgICBjb25zdCBlbXB0eVN0cnVjdHVyZSA9IHtcbiAgICAgICAgICB2YWx1ZToge1xuICAgICAgICAgICAgdmFsdWU6IHt9LFxuICAgICAgICAgIH0sXG4gICAgICAgIH07XG5cbiAgICAgICAgY29uc3QgcmVzdWx0ID0gY2FsbENvbnZlcnRBcmd1bWVudEJ5QUJJKGN1c3RvbVRyYW5zYWN0aW9uLCBlbXB0eVN0cnVjdHVyZSwgbmV3IFR5cGVUYWdVNjQoKSk7XG4gICAgICAgIHNob3VsZC5lcXVhbChyZXN1bHQsIGVtcHR5U3RydWN0dXJlKTsgLy8gU2hvdWxkIHJldHVybiBvcmlnaW5hbCB3aGVuIG5vIHZhbGlkIGJ5dGVzIGZvdW5kXG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCBoYW5kbGUgbm9uLUJDUyBvYmplY3RzJywgKCkgPT4ge1xuICAgICAgICBjb25zdCByZWd1bGFyT2JqZWN0ID0geyBzb21lUHJvcGVydHk6ICd2YWx1ZScgfTtcbiAgICAgICAgY29uc3QgcmVzdWx0ID0gY2FsbENvbnZlcnRBcmd1bWVudEJ5QUJJKGN1c3RvbVRyYW5zYWN0aW9uLCByZWd1bGFyT2JqZWN0LCBuZXcgVHlwZVRhZ1U2NCgpKTtcblxuICAgICAgICBzaG91bGQuZXF1YWwocmVzdWx0LCByZWd1bGFyT2JqZWN0KTsgLy8gU2hvdWxkIHJldHVybiBhcy1pcyBmb3Igbm9uLUJDUyBvYmplY3RzXG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCBoYW5kbGUgbnVsbCBhbmQgdW5kZWZpbmVkIChkZWZlbnNpdmUpJywgKCkgPT4ge1xuICAgICAgICBjb25zdCByZXN1bHQxID0gY2FsbENvbnZlcnRBcmd1bWVudEJ5QUJJKGN1c3RvbVRyYW5zYWN0aW9uLCBudWxsLCBuZXcgVHlwZVRhZ1U2NCgpKTtcbiAgICAgICAgY29uc3QgcmVzdWx0MiA9IGNhbGxDb252ZXJ0QXJndW1lbnRCeUFCSShjdXN0b21UcmFuc2FjdGlvbiwgdW5kZWZpbmVkLCBuZXcgVHlwZVRhZ1U2NCgpKTtcblxuICAgICAgICBzaG91bGQuZXF1YWwocmVzdWx0MSwgbnVsbCk7XG4gICAgICAgIHNob3VsZC5lcXVhbChyZXN1bHQyLCB1bmRlZmluZWQpO1xuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBkZXNjcmliZSgnSW50ZWdyYXRpb24gd2l0aCBVdGlsaXR5IEZ1bmN0aW9ucycsICgpID0+IHtcbiAgICAgIGl0KCdzaG91bGQgdXNlIGJ5dGVzVG9IZXggdXRpbGl0eSBmb3Igbm9uLW51bWVyaWMgQkNTIGRhdGEnLCAoKSA9PiB7XG4gICAgICAgIGNvbnN0IGJjc0RhdGEgPSB7XG4gICAgICAgICAgZGF0YTogbmV3IFVpbnQ4QXJyYXkoWzB4MTIsIDB4MzQsIDB4NTYsIDB4NzhdKSxcbiAgICAgICAgfTtcblxuICAgICAgICBjb25zdCByZXN1bHQgPSBjYWxsQ29udmVydEFyZ3VtZW50QnlBQkkoY3VzdG9tVHJhbnNhY3Rpb24sIGJjc0RhdGEsIG5ldyBUeXBlVGFnQWRkcmVzcygpKTtcbiAgICAgICAgLy8gU2hvdWxkIGVpdGhlciBiZSBjb252ZXJ0ZWQgdG8gQWNjb3VudEFkZHJlc3Mgb3IgcmVtYWluIGFzIGhleCBzdHJpbmdcbiAgICAgICAgc2hvdWxkLmV4aXN0KHJlc3VsdCk7XG4gICAgICB9KTtcblxuICAgICAgaXQoJ3Nob3VsZCB1c2UgdHJ5UGFyc2VBY2NvdW50QWRkcmVzcyB1dGlsaXR5IGZvciBhZGRyZXNzIHN0cmluZ3MnLCAoKSA9PiB7XG4gICAgICAgIGNvbnN0IHZhbGlkQWRkcmVzcyA9ICcweDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDEnO1xuICAgICAgICBjb25zdCByZXN1bHQgPSBjYWxsQ29udmVydEFyZ3VtZW50QnlBQkkoY3VzdG9tVHJhbnNhY3Rpb24sIHZhbGlkQWRkcmVzcywgbmV3IFR5cGVUYWdBZGRyZXNzKCkpO1xuXG4gICAgICAgIHNob3VsZC5leGlzdChyZXN1bHQpO1xuICAgICAgICAvLyBTaG91bGQgZWl0aGVyIGJlIEFjY291bnRBZGRyZXNzIG9iamVjdCBvciBvcmlnaW5hbCBzdHJpbmdcbiAgICAgICAgaWYgKHR5cGVvZiByZXN1bHQgPT09ICdvYmplY3QnKSB7XG4gICAgICAgICAgc2hvdWxkLmV4aXN0KHJlc3VsdC50b1N0cmluZyk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuXG4gICAgICBpdCgnc2hvdWxkIHVzZSBjb252ZXJ0TnVtZXJpY0FyZ3VtZW50IHV0aWxpdHkgZm9yIGJ5dGUgYXJyYXlzJywgKCkgPT4ge1xuICAgICAgICBjb25zdCB1aW50OERhdGEgPSBuZXcgVWludDhBcnJheShbMHhlOCwgMHgwMywgMHgwMCwgMHgwMCwgMHgwMCwgMHgwMCwgMHgwMCwgMHgwMF0pOyAvLyAxMDAwXG4gICAgICAgIGNvbnN0IG5lc3RlZERhdGEgPSB7XG4gICAgICAgICAgdmFsdWU6IHtcbiAgICAgICAgICAgIHZhbHVlOiB1aW50OERhdGEsXG4gICAgICAgICAgfSxcbiAgICAgICAgfTtcblxuICAgICAgICBjb25zdCByZXN1bHQgPSBjYWxsQ29udmVydEFyZ3VtZW50QnlBQkkoY3VzdG9tVHJhbnNhY3Rpb24sIG5lc3RlZERhdGEsIG5ldyBUeXBlVGFnVTY0KCkpO1xuICAgICAgICBzaG91bGQuZXF1YWwocmVzdWx0LCAnMTAwMCcpOyAvLyBTaG91bGQgdXNlIGV4aXN0aW5nIG51bWVyaWMgY29udmVyc2lvbiBsb2dpY1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdSb3VuZC10cmlwIENvbXBhdGliaWxpdHknLCAoKSA9PiB7XG4gICAgaXQoJ3Nob3VsZCBtYWludGFpbiBjb21wYXRpYmlsaXR5IHdpdGggZXhpc3RpbmcgdHJhbnNhY3Rpb24gcGFyc2luZycsICgpID0+IHtcbiAgICAgIC8vIFRoaXMgZW5zdXJlcyBvdXIgcmVmYWN0b3JlZCBtZXRob2Qgd29ya3Mgd2l0aCB0aGUgZXhpc3RpbmcgdHJhbnNhY3Rpb24gYnVpbGRlciB0ZXN0c1xuICAgICAgY29uc3QgdGVzdEFyZ3VtZW50cyA9IFtcbiAgICAgICAgeyBhcmc6IHRlc3REYXRhLnNlbmRlci5hZGRyZXNzLCB0eXBlOiBuZXcgVHlwZVRhZ0FkZHJlc3MoKSB9LFxuICAgICAgICB7IGFyZzogdGVzdERhdGEuQU1PVU5ULnRvU3RyaW5nKCksIHR5cGU6IG5ldyBUeXBlVGFnVTY0KCkgfSxcbiAgICAgICAgeyBhcmc6IHRydWUsIHR5cGU6IG5ldyBUeXBlVGFnQm9vbCgpIH0sXG4gICAgICAgIHsgYXJnOiAyNTUsIHR5cGU6IG5ldyBUeXBlVGFnVTgoKSB9LFxuICAgICAgXTtcblxuICAgICAgdGVzdEFyZ3VtZW50cy5mb3JFYWNoKCh7IGFyZywgdHlwZSB9KSA9PiB7XG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IGNhbGxDb252ZXJ0QXJndW1lbnRCeUFCSShjdXN0b21UcmFuc2FjdGlvbiwgYXJnLCB0eXBlKTtcbiAgICAgICAgc2hvdWxkLmV4aXN0KHJlc3VsdCk7XG5cbiAgICAgICAgLy8gUmVzdWx0IHNob3VsZCBiZSBjb21wYXRpYmxlIHdpdGggZXhpc3RpbmcgdHJhbnNhY3Rpb24gYnVpbGRpbmcgbG9naWNcbiAgICAgICAgaWYgKHR5cGVvZiByZXN1bHQgPT09ICdzdHJpbmcnIHx8IHR5cGVvZiByZXN1bHQgPT09ICdudW1iZXInIHx8IHR5cGVvZiByZXN1bHQgPT09ICdib29sZWFuJykge1xuICAgICAgICAgIHNob3VsZC5leGlzdChyZXN1bHQudG9TdHJpbmcpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfSk7XG59KTtcbiJdfQ==
|