@bitgo-beta/sdk-coin-iota 1.0.1-beta.42 → 1.0.1-beta.420

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.
Files changed (69) hide show
  1. package/README.md +1 -1
  2. package/dist/src/iota.d.ts +134 -23
  3. package/dist/src/iota.d.ts.map +1 -1
  4. package/dist/src/iota.js +286 -46
  5. package/dist/src/lib/constants.d.ts +59 -6
  6. package/dist/src/lib/constants.d.ts.map +1 -1
  7. package/dist/src/lib/constants.js +76 -8
  8. package/dist/src/lib/iface.d.ts +174 -2
  9. package/dist/src/lib/iface.d.ts.map +1 -1
  10. package/dist/src/lib/iface.js +1 -1
  11. package/dist/src/lib/index.d.ts +1 -0
  12. package/dist/src/lib/index.d.ts.map +1 -1
  13. package/dist/src/lib/index.js +4 -2
  14. package/dist/src/lib/keyPair.d.ts +100 -6
  15. package/dist/src/lib/keyPair.d.ts.map +1 -1
  16. package/dist/src/lib/keyPair.js +103 -10
  17. package/dist/src/lib/transaction.d.ts +175 -5
  18. package/dist/src/lib/transaction.d.ts.map +1 -1
  19. package/dist/src/lib/transaction.js +390 -6
  20. package/dist/src/lib/transactionBuilder.d.ts +109 -9
  21. package/dist/src/lib/transactionBuilder.d.ts.map +1 -1
  22. package/dist/src/lib/transactionBuilder.js +200 -14
  23. package/dist/src/lib/transactionBuilderFactory.d.ts +98 -2
  24. package/dist/src/lib/transactionBuilderFactory.d.ts.map +1 -1
  25. package/dist/src/lib/transactionBuilderFactory.js +132 -5
  26. package/dist/src/lib/transferBuilder.d.ts +52 -2
  27. package/dist/src/lib/transferBuilder.d.ts.map +1 -1
  28. package/dist/src/lib/transferBuilder.js +86 -3
  29. package/dist/src/lib/transferTransaction.d.ts +124 -0
  30. package/dist/src/lib/transferTransaction.d.ts.map +1 -0
  31. package/dist/src/lib/transferTransaction.js +341 -0
  32. package/dist/src/lib/utils.d.ts +108 -7
  33. package/dist/src/lib/utils.d.ts.map +1 -1
  34. package/dist/src/lib/utils.js +146 -11
  35. package/dist/test/resources/iota.d.ts +35 -0
  36. package/dist/test/resources/iota.d.ts.map +1 -0
  37. package/dist/test/resources/iota.js +93 -0
  38. package/dist/test/unit/helpers/testHelpers.d.ts +57 -0
  39. package/dist/test/unit/helpers/testHelpers.d.ts.map +1 -0
  40. package/dist/test/unit/helpers/testHelpers.js +176 -0
  41. package/dist/test/unit/index.d.ts +2 -0
  42. package/dist/test/unit/index.d.ts.map +1 -0
  43. package/dist/test/unit/index.js +16 -0
  44. package/dist/test/unit/iota.d.ts +2 -0
  45. package/dist/test/unit/iota.d.ts.map +1 -0
  46. package/dist/test/unit/iota.js +501 -0
  47. package/dist/test/unit/keyPair.d.ts +2 -0
  48. package/dist/test/unit/keyPair.d.ts.map +1 -0
  49. package/dist/test/unit/keyPair.js +108 -0
  50. package/dist/test/unit/transactionBuilder/transactionBuilder.d.ts +2 -0
  51. package/dist/test/unit/transactionBuilder/transactionBuilder.d.ts.map +1 -0
  52. package/dist/test/unit/transactionBuilder/transactionBuilder.js +188 -0
  53. package/dist/test/unit/transactionBuilder/transactionBuilderFactory.d.ts +2 -0
  54. package/dist/test/unit/transactionBuilder/transactionBuilderFactory.d.ts.map +1 -0
  55. package/dist/test/unit/transactionBuilder/transactionBuilderFactory.js +178 -0
  56. package/dist/test/unit/transactionBuilder/transferBuilder.d.ts +2 -0
  57. package/dist/test/unit/transactionBuilder/transferBuilder.d.ts.map +1 -0
  58. package/dist/test/unit/transactionBuilder/transferBuilder.js +438 -0
  59. package/dist/test/unit/transferTransaction.d.ts +2 -0
  60. package/dist/test/unit/transferTransaction.d.ts.map +1 -0
  61. package/dist/test/unit/transferTransaction.js +218 -0
  62. package/dist/test/unit/utils.d.ts +2 -0
  63. package/dist/test/unit/utils.d.ts.map +1 -0
  64. package/dist/test/unit/utils.js +252 -0
  65. package/dist/tsconfig.tsbuildinfo +1 -0
  66. package/package.json +16 -10
  67. package/.eslintignore +0 -5
  68. package/.mocharc.yml +0 -8
  69. package/CHANGELOG.md +0 -28
@@ -0,0 +1,218 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const should_1 = __importDefault(require("should"));
7
+ const statics_1 = require("@bitgo-beta/statics");
8
+ const sdk_core_1 = require("@bitgo-beta/sdk-core");
9
+ const src_1 = require("../../src");
10
+ const testHelpers_1 = require("./helpers/testHelpers");
11
+ describe('Iota Transfer Transaction', () => {
12
+ describe('Transaction Properties', () => {
13
+ it('should have correct basic properties', async function () {
14
+ const tx = (await (0, testHelpers_1.createBasicTransferBuilder)().build());
15
+ should_1.default.equal(tx.type, sdk_core_1.TransactionType.Send);
16
+ should_1.default.equal(tx.sender, testHelpers_1.testData.sender.address);
17
+ should_1.default.deepEqual(tx.recipients, testHelpers_1.testData.recipients);
18
+ should_1.default.deepEqual(tx.paymentObjects, testHelpers_1.testData.paymentObjects);
19
+ should_1.default.equal(tx.isSimulateTx, true);
20
+ });
21
+ it('should switch to real transaction mode when gas data is provided', async function () {
22
+ const tx = (await (0, testHelpers_1.createTransferBuilderWithGas)().build());
23
+ should_1.default.equal(tx.isSimulateTx, false);
24
+ should_1.default.equal(tx.gasBudget, testHelpers_1.testData.GAS_BUDGET);
25
+ should_1.default.equal(tx.gasPrice, testHelpers_1.testData.GAS_PRICE);
26
+ should_1.default.deepEqual(tx.gasPaymentObjects, testHelpers_1.testData.gasPaymentObjects);
27
+ should_1.default.equal(tx.getFee(), testHelpers_1.testData.GAS_BUDGET.toString());
28
+ });
29
+ it('should correctly set gas sponsor', async function () {
30
+ const tx = (await (0, testHelpers_1.createTransferBuilderWithSponsor)().build());
31
+ should_1.default.equal(tx.gasSponsor, testHelpers_1.testData.gasSponsor.address);
32
+ should_1.default.equal(tx.sender, testHelpers_1.testData.sender.address);
33
+ should_1.default.notEqual(tx.sender, tx.gasSponsor);
34
+ });
35
+ });
36
+ describe('Inputs and Outputs', () => {
37
+ it('should correctly calculate inputs and outputs', async function () {
38
+ const tx = (await (0, testHelpers_1.createTransferBuilderWithGas)().build());
39
+ const totalAmount = testHelpers_1.testData.recipients.reduce((sum, r) => sum + Number(r.amount), 0);
40
+ tx.inputs.length.should.equal(1);
41
+ tx.inputs[0].should.deepEqual({
42
+ address: testHelpers_1.testData.sender.address,
43
+ value: totalAmount.toString(),
44
+ coin: 'tiota',
45
+ });
46
+ tx.outputs.length.should.equal(testHelpers_1.testData.recipients.length);
47
+ testHelpers_1.testData.recipients.forEach((recipient, index) => {
48
+ tx.outputs[index].should.deepEqual({
49
+ address: recipient.address,
50
+ value: recipient.amount,
51
+ coin: 'tiota',
52
+ });
53
+ });
54
+ });
55
+ });
56
+ describe('Serialization', () => {
57
+ it('should serialize to and deserialize from JSON', async function () {
58
+ const tx = (await (0, testHelpers_1.createTransferBuilderWithGas)().build());
59
+ const json = tx.toJson();
60
+ // Verify JSON structure
61
+ should_1.default.equal(json.sender, testHelpers_1.testData.sender.address);
62
+ should_1.default.deepEqual(json.recipients, testHelpers_1.testData.recipients);
63
+ should_1.default.deepEqual(json.paymentObjects, testHelpers_1.testData.paymentObjects);
64
+ should_1.default.equal(json.gasBudget, testHelpers_1.testData.GAS_BUDGET);
65
+ should_1.default.equal(json.gasPrice, testHelpers_1.testData.GAS_PRICE);
66
+ should_1.default.deepEqual(json.gasPaymentObjects, testHelpers_1.testData.gasPaymentObjects);
67
+ should_1.default.equal(json.type, sdk_core_1.TransactionType.Send);
68
+ // Deserialize and verify
69
+ const newTx = new src_1.TransferTransaction(statics_1.coins.get('tiota'));
70
+ newTx.parseFromJSON(json);
71
+ should_1.default.equal(newTx.sender, tx.sender);
72
+ should_1.default.deepEqual(newTx.recipients, tx.recipients);
73
+ should_1.default.deepEqual(newTx.paymentObjects, tx.paymentObjects);
74
+ should_1.default.equal(newTx.gasBudget, tx.gasBudget);
75
+ should_1.default.equal(newTx.gasPrice, tx.gasPrice);
76
+ });
77
+ it('should serialize to broadcast format', async function () {
78
+ const tx = (await (0, testHelpers_1.createTransferBuilderWithGas)().build());
79
+ const broadcastFormat = await tx.toBroadcastFormat();
80
+ should_1.default.exist(broadcastFormat);
81
+ should_1.default.equal(typeof broadcastFormat, 'string');
82
+ should_1.default.equal(broadcastFormat.length > 0, true);
83
+ });
84
+ });
85
+ describe('Transaction ID and Signing', () => {
86
+ it('should generate transaction ID for built transaction', async function () {
87
+ const tx = (await (0, testHelpers_1.createTransferBuilderWithGas)().build());
88
+ const txId = tx.id;
89
+ should_1.default.exist(txId);
90
+ should_1.default.equal(typeof txId, 'string');
91
+ should_1.default.equal(txId.length > 0, true);
92
+ });
93
+ it('should throw error when getting ID before build', function () {
94
+ const tx = new src_1.TransferTransaction(statics_1.coins.get('tiota'));
95
+ tx.sender = testHelpers_1.testData.sender.address;
96
+ (0, should_1.default)(() => tx.id).throwError('Tx not built or a rebuild is required');
97
+ });
98
+ it('should provide signable payload for non-simulate transactions', async function () {
99
+ const tx = (await (0, testHelpers_1.createTransferBuilderWithGas)().build());
100
+ const payload = tx.signablePayload;
101
+ should_1.default.exist(payload);
102
+ should_1.default.equal(Buffer.isBuffer(payload), true);
103
+ should_1.default.equal(payload.length, 32); // Blake2b produces 32-byte hash
104
+ });
105
+ it('should throw error when getting signable payload for simulate transaction', async function () {
106
+ const tx = (await (0, testHelpers_1.createBasicTransferBuilder)().build());
107
+ should_1.default.equal(tx.isSimulateTx, true);
108
+ (0, should_1.default)(() => tx.signablePayload).throwError('Cannot sign a simulate tx');
109
+ });
110
+ it('should correctly report canSign based on transaction mode', async function () {
111
+ const simulateTx = (await (0, testHelpers_1.createBasicTransferBuilder)().build());
112
+ const realTx = (await (0, testHelpers_1.createTransferBuilderWithGas)().build());
113
+ should_1.default.equal(simulateTx.canSign({}), false);
114
+ should_1.default.equal(realTx.canSign({}), true);
115
+ });
116
+ });
117
+ describe('Transaction Explanation', () => {
118
+ it('should provide detailed transaction explanation', async function () {
119
+ const tx = (await (0, testHelpers_1.createTransferBuilderWithGas)().build());
120
+ const explanation = tx.explainTransaction();
121
+ should_1.default.exist(explanation);
122
+ should_1.default.equal(explanation.type, sdk_core_1.TransactionType.Send);
123
+ should_1.default.exist(explanation.id);
124
+ should_1.default.exist(explanation.outputs);
125
+ should_1.default.equal(explanation.outputs.length, testHelpers_1.testData.recipients.length);
126
+ should_1.default.equal(explanation.fee.fee, testHelpers_1.testData.GAS_BUDGET.toString());
127
+ });
128
+ });
129
+ describe('Rebuild Requirements', () => {
130
+ const rebuildTriggers = [
131
+ {
132
+ name: 'sender changes',
133
+ modifier: (tx) => (tx.sender = testHelpers_1.testData.gasSponsor.address),
134
+ },
135
+ {
136
+ name: 'gas budget changes',
137
+ modifier: (tx) => (tx.gasBudget = 10000000),
138
+ },
139
+ {
140
+ name: 'recipients change',
141
+ modifier: (tx) => (tx.recipients = [{ address: testHelpers_1.testData.addresses.validAddresses[0], amount: '5000' }]),
142
+ },
143
+ ];
144
+ rebuildTriggers.forEach(({ name, modifier }) => {
145
+ it(`should require rebuild when ${name}`, async function () {
146
+ const tx = (await (0, testHelpers_1.createTransferBuilderWithGas)().build());
147
+ modifier(tx);
148
+ (0, should_1.default)(() => tx.id).throwError('Tx not built or a rebuild is required');
149
+ });
150
+ });
151
+ });
152
+ describe('Signature Serialization', () => {
153
+ it('should have undefined serialized signatures before signing', async function () {
154
+ const tx = (await (0, testHelpers_1.createTransferBuilderWithGas)().build());
155
+ should_1.default.equal(tx.serializedSignature, undefined);
156
+ should_1.default.equal(tx.serializedGasSponsorSignature, undefined);
157
+ });
158
+ it('should serialize sender signature after adding and rebuilding', async function () {
159
+ const tx = (await (0, testHelpers_1.createTransferBuilderWithGas)().build());
160
+ tx.addSignature(testHelpers_1.testData.testSignature.publicKey, testHelpers_1.testData.testSignature.signature);
161
+ await tx.build();
162
+ should_1.default.exist(tx.serializedSignature);
163
+ should_1.default.equal(typeof tx.serializedSignature, 'string');
164
+ should_1.default.equal(/^[A-Za-z0-9+/]*={0,2}$/.test(tx.serializedSignature), true);
165
+ });
166
+ it('should serialize gas sponsor signature correctly', async function () {
167
+ const tx = (await (0, testHelpers_1.createTransferBuilderWithSponsor)().build());
168
+ tx.addGasSponsorSignature(testHelpers_1.testData.testGasSponsorSignature.publicKey, testHelpers_1.testData.testGasSponsorSignature.signature);
169
+ await tx.build();
170
+ should_1.default.exist(tx.serializedGasSponsorSignature);
171
+ should_1.default.equal(typeof tx.serializedGasSponsorSignature, 'string');
172
+ should_1.default.equal(/^[A-Za-z0-9+/]*={0,2}$/.test(tx.serializedGasSponsorSignature), true);
173
+ });
174
+ it('should serialize both sender and gas sponsor signatures', async function () {
175
+ const tx = (await (0, testHelpers_1.createTransferBuilderWithSponsor)().build());
176
+ tx.addSignature(testHelpers_1.testData.testSignature.publicKey, testHelpers_1.testData.testSignature.signature);
177
+ tx.addGasSponsorSignature(testHelpers_1.testData.testGasSponsorSignature.publicKey, testHelpers_1.testData.testGasSponsorSignature.signature);
178
+ await tx.build();
179
+ should_1.default.exist(tx.serializedSignature);
180
+ should_1.default.exist(tx.serializedGasSponsorSignature);
181
+ should_1.default.notEqual(tx.serializedSignature, tx.serializedGasSponsorSignature);
182
+ });
183
+ it('should include serialized signatures in signatures array', async function () {
184
+ const tx = (await (0, testHelpers_1.createTransferBuilderWithGas)().build());
185
+ tx.addSignature(testHelpers_1.testData.testSignature.publicKey, testHelpers_1.testData.testSignature.signature);
186
+ await tx.build();
187
+ tx.signature.length.should.equal(1);
188
+ tx.signature[0].should.equal(tx.serializedSignature);
189
+ });
190
+ it('should include both signatures in correct order when gas sponsor is present', async function () {
191
+ const tx = (await (0, testHelpers_1.createTransferBuilderWithSponsor)().build());
192
+ tx.addSignature(testHelpers_1.testData.testSignature.publicKey, testHelpers_1.testData.testSignature.signature);
193
+ tx.addGasSponsorSignature(testHelpers_1.testData.testGasSponsorSignature.publicKey, testHelpers_1.testData.testGasSponsorSignature.signature);
194
+ await tx.build();
195
+ tx.signature.length.should.equal(2);
196
+ tx.signature[0].should.equal(tx.serializedSignature);
197
+ tx.signature[1].should.equal(tx.serializedGasSponsorSignature);
198
+ });
199
+ it('should verify signature serialization format (EDDSA scheme)', async function () {
200
+ const tx = (await (0, testHelpers_1.createTransferBuilderWithGas)().build());
201
+ tx.addSignature(testHelpers_1.testData.testSignature.publicKey, testHelpers_1.testData.testSignature.signature);
202
+ await tx.build();
203
+ // Decode and verify format: 0x00 + signature (64 bytes) + pubkey (32 bytes) = 97 bytes
204
+ const decoded = Buffer.from(tx.serializedSignature, 'base64');
205
+ // Should be 97 bytes total (1 prefix + 64 signature + 32 pubkey)
206
+ decoded.length.should.equal(97);
207
+ // First byte should be 0x00 (EDDSA scheme)
208
+ decoded[0].should.equal(0x00);
209
+ // Next 64 bytes should be the signature
210
+ const signatureBytes = decoded.slice(1, 65);
211
+ signatureBytes.toString('hex').should.equal(testHelpers_1.testData.testSignature.signature.toString('hex'));
212
+ // Last 32 bytes should be the public key
213
+ const pubKeyBytes = decoded.slice(65);
214
+ pubKeyBytes.toString('hex').should.equal(testHelpers_1.testData.testSignature.publicKey.pub);
215
+ });
216
+ });
217
+ });
218
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJhbnNmZXJUcmFuc2FjdGlvbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3Rlc3QvdW5pdC90cmFuc2ZlclRyYW5zYWN0aW9uLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBQUEsb0RBQTRCO0FBQzVCLGlEQUE0QztBQUM1QyxtREFBdUQ7QUFDdkQsbUNBQWdEO0FBQ2hELHVEQUsrQjtBQUUvQixRQUFRLENBQUMsMkJBQTJCLEVBQUUsR0FBRyxFQUFFO0lBQ3pDLFFBQVEsQ0FBQyx3QkFBd0IsRUFBRSxHQUFHLEVBQUU7UUFDdEMsRUFBRSxDQUFDLHNDQUFzQyxFQUFFLEtBQUs7WUFDOUMsTUFBTSxFQUFFLEdBQUcsQ0FBQyxNQUFNLElBQUEsd0NBQTBCLEdBQUUsQ0FBQyxLQUFLLEVBQUUsQ0FBd0IsQ0FBQztZQUUvRSxnQkFBTSxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUMsSUFBSSxFQUFFLDBCQUFlLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDNUMsZ0JBQU0sQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDLE1BQU0sRUFBRSxzQkFBUSxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsQ0FBQztZQUNqRCxnQkFBTSxDQUFDLFNBQVMsQ0FBQyxFQUFFLENBQUMsVUFBVSxFQUFFLHNCQUFRLENBQUMsVUFBVSxDQUFDLENBQUM7WUFDckQsZ0JBQU0sQ0FBQyxTQUFTLENBQUMsRUFBRSxDQUFDLGNBQWMsRUFBRSxzQkFBUSxDQUFDLGNBQWMsQ0FBQyxDQUFDO1lBQzdELGdCQUFNLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQyxZQUFZLEVBQUUsSUFBSSxDQUFDLENBQUM7UUFDdEMsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsa0VBQWtFLEVBQUUsS0FBSztZQUMxRSxNQUFNLEVBQUUsR0FBRyxDQUFDLE1BQU0sSUFBQSwwQ0FBNEIsR0FBRSxDQUFDLEtBQUssRUFBRSxDQUF3QixDQUFDO1lBRWpGLGdCQUFNLENBQUMs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QVEsQ0FBQyxhQUFhLENBQUMsU0FBUyxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDO1lBRTlGLHlDQUF5QztZQUN6QyxNQUFNLFdBQVcsR0FBRyxPQUFPLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQyxDQUFDO1lBQ3RDLFdBQVcsQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxzQkFBUSxDQUFDLGFBQWEsQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDakYsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztBQUNMLENBQUMsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHNob3VsZCBmcm9tICdzaG91bGQnO1xuaW1wb3J0IHsgY29pbnMgfSBmcm9tICdAYml0Z28tYmV0YS9zdGF0aWNzJztcbmltcG9ydCB7IFRyYW5zYWN0aW9uVHlwZSB9IGZyb20gJ0BiaXRnby1iZXRhL3Nkay1jb3JlJztcbmltcG9ydCB7IFRyYW5zZmVyVHJhbnNhY3Rpb24gfSBmcm9tICcuLi8uLi9zcmMnO1xuaW1wb3J0IHtcbiAgY3JlYXRlQmFzaWNUcmFuc2ZlckJ1aWxkZXIsXG4gIGNyZWF0ZVRyYW5zZmVyQnVpbGRlcldpdGhHYXMsXG4gIGNyZWF0ZVRyYW5zZmVyQnVpbGRlcldpdGhTcG9uc29yLFxuICB0ZXN0RGF0YSxcbn0gZnJvbSAnLi9oZWxwZXJzL3Rlc3RIZWxwZXJzJztcblxuZGVzY3JpYmUoJ0lvdGEgVHJhbnNmZXIgVHJhbnNhY3Rpb24nLCAoKSA9PiB7XG4gIGRlc2NyaWJlKCdUcmFuc2FjdGlvbiBQcm9wZXJ0aWVzJywgKCkgPT4ge1xuICAgIGl0KCdzaG91bGQgaGF2ZSBjb3JyZWN0IGJhc2ljIHByb3BlcnRpZXMnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB0eCA9IChhd2FpdCBjcmVhdGVCYXNpY1RyYW5zZmVyQnVpbGRlcigpLmJ1aWxkKCkpIGFzIFRyYW5zZmVyVHJhbnNhY3Rpb247XG5cbiAgICAgIHNob3VsZC5lcXVhbCh0eC50eXBlLCBUcmFuc2FjdGlvblR5cGUuU2VuZCk7XG4gICAgICBzaG91bGQuZXF1YWwodHguc2VuZGVyLCB0ZXN0RGF0YS5zZW5kZXIuYWRkcmVzcyk7XG4gICAgICBzaG91bGQuZGVlcEVxdWFsKHR4LnJlY2lwaWVudHMsIHRlc3REYXRhLnJlY2lwaWVudHMpO1xuICAgICAgc2hvdWxkLmRlZXBFcXVhbCh0eC5wYXltZW50T2JqZWN0cywgdGVzdERhdGEucGF5bWVudE9iamVjdHMpO1xuICAgICAgc2hvdWxkLmVxdWFsKHR4LmlzU2ltdWxhdGVUeCwgdHJ1ZSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHN3aXRjaCB0byByZWFsIHRyYW5zYWN0aW9uIG1vZGUgd2hlbiBnYXMgZGF0YSBpcyBwcm92aWRlZCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHR4ID0gKGF3YWl0IGNyZWF0ZVRyYW5zZmVyQnVpbGRlcldpdGhHYXMoKS5idWlsZCgpKSBhcyBUcmFuc2ZlclRyYW5zYWN0aW9uO1xuXG4gICAgICBzaG91bGQuZXF1YWwodHguaXNTaW11bGF0ZVR4LCBmYWxzZSk7XG4gICAgICBzaG91bGQuZXF1YWwodHguZ2FzQnVkZ2V0LCB0ZXN0RGF0YS5HQVNfQlVER0VUKTtcbiAgICAgIHNob3VsZC5lcXVhbCh0eC5nYXNQcmljZSwgdGVzdERhdGEuR0FTX1BSSUNFKTtcbiAgICAgIHNob3VsZC5kZWVwRXF1YWwodHguZ2FzUGF5bWVudE9iamVjdHMsIHRlc3REYXRhLmdhc1BheW1lbnRPYmplY3RzKTtcbiAgICAgIHNob3VsZC5lcXVhbCh0eC5nZXRGZWUoKSwgdGVzdERhdGEuR0FTX0JVREdFVC50b1N0cmluZygpKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgY29ycmVjdGx5IHNldCBnYXMgc3BvbnNvcicsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHR4ID0gKGF3YWl0IGNyZWF0ZVRyYW5zZmVyQnVpbGRlcldpdGhTcG9uc29yKCkuYnVpbGQoKSkgYXMgVHJhbnNmZXJUcmFuc2FjdGlvbjtcblxuICAgICAgc2hvdWxkLmVxdWFsKHR4Lmdhc1Nwb25zb3IsIHRlc3REYXRhLmdhc1Nwb25zb3IuYWRkcmVzcyk7XG4gICAgICBzaG91bGQuZXF1YWwodHguc2VuZGVyLCB0ZXN0RGF0YS5zZW5kZXIuYWRkcmVzcyk7XG4gICAgICBzaG91bGQubm90RXF1YWwodHguc2VuZGVyLCB0eC5nYXNTcG9uc29yKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ0lucHV0cyBhbmQgT3V0cHV0cycsICgpID0+IHtcbiAgICBpdCgnc2hvdWxkIGNvcnJlY3RseSBjYWxjdWxhdGUgaW5wdXRzIGFuZCBvdXRwdXRzJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgdHggPSAoYXdhaXQgY3JlYXRlVHJhbnNmZXJCdWlsZGVyV2l0aEdhcygpLmJ1aWxkKCkpIGFzIFRyYW5zZmVyVHJhbnNhY3Rpb247XG4gICAgICBjb25zdCB0b3RhbEFtb3VudCA9IHRlc3REYXRhLnJlY2lwaWVudHMucmVkdWNlKChzdW0sIHIpID0+IHN1bSArIE51bWJlcihyLmFtb3VudCksIDApO1xuXG4gICAgICB0eC5pbnB1dHMubGVuZ3RoLnNob3VsZC5lcXVhbCgxKTtcbiAgICAgIHR4LmlucHV0c1swXS5zaG91bGQuZGVlcEVxdWFsKHtcbiAgICAgICAgYWRkcmVzczogdGVzdERhdGEuc2VuZGVyLmFkZHJlc3MsXG4gICAgICAgIHZhbHVlOiB0b3RhbEFtb3VudC50b1N0cmluZygpLFxuICAgICAgICBjb2luOiAndGlvdGEnLFxuICAgICAgfSk7XG5cbiAgICAgIHR4Lm91dHB1dHMubGVuZ3RoLnNob3VsZC5lcXVhbCh0ZXN0RGF0YS5yZWNpcGllbnRzLmxlbmd0aCk7XG4gICAgICB0ZXN0RGF0YS5yZWNpcGllbnRzLmZvckVhY2goKHJlY2lwaWVudCwgaW5kZXgpID0+IHtcbiAgICAgICAgdHgub3V0cHV0c1tpbmRleF0uc2hvdWxkLmRlZXBFcXVhbCh7XG4gICAgICAgICAgYWRkcmVzczogcmVjaXBpZW50LmFkZHJlc3MsXG4gICAgICAgICAgdmFsdWU6IHJlY2lwaWVudC5hbW91bnQsXG4gICAgICAgICAgY29pbjogJ3Rpb3RhJyxcbiAgICAgICAgfSk7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ1NlcmlhbGl6YXRpb24nLCAoKSA9PiB7XG4gICAgaXQoJ3Nob3VsZCBzZXJpYWxpemUgdG8gYW5kIGRlc2VyaWFsaXplIGZyb20gSlNPTicsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHR4ID0gKGF3YWl0IGNyZWF0ZVRyYW5zZmVyQnVpbGRlcldpdGhHYXMoKS5idWlsZCgpKSBhcyBUcmFuc2ZlclRyYW5zYWN0aW9uO1xuICAgICAgY29uc3QganNvbiA9IHR4LnRvSnNvbigpO1xuXG4gICAgICAvLyBWZXJpZnkgSlNPTiBzdHJ1Y3R1cmVcbiAgICAgIHNob3VsZC5lcXVhbChqc29uLnNlbmRlciwgdGVzdERhdGEuc2VuZGVyLmFkZHJlc3MpO1xuICAgICAgc2hvdWxkLmRlZXBFcXVhbChqc29uLnJlY2lwaWVudHMsIHRlc3REYXRhLnJlY2lwaWVudHMpO1xuICAgICAgc2hvdWxkLmRlZXBFcXVhbChqc29uLnBheW1lbnRPYmplY3RzLCB0ZXN0RGF0YS5wYXltZW50T2JqZWN0cyk7XG4gICAgICBzaG91bGQuZXF1YWwoanNvbi5nYXNCdWRnZXQsIHRlc3REYXRhLkdBU19CVURHRVQpO1xuICAgICAgc2hvdWxkLmVxdWFsKGpzb24uZ2FzUHJpY2UsIHRlc3REYXRhLkdBU19QUklDRSk7XG4gICAgICBzaG91bGQuZGVlcEVxdWFsKGpzb24uZ2FzUGF5bWVudE9iamVjdHMsIHRlc3REYXRhLmdhc1BheW1lbnRPYmplY3RzKTtcbiAgICAgIHNob3VsZC5lcXVhbChqc29uLnR5cGUsIFRyYW5zYWN0aW9uVHlwZS5TZW5kKTtcblxuICAgICAgLy8gRGVzZXJpYWxpemUgYW5kIHZlcmlmeVxuICAgICAgY29uc3QgbmV3VHggPSBuZXcgVHJhbnNmZXJUcmFuc2FjdGlvbihjb2lucy5nZXQoJ3Rpb3RhJykpO1xuICAgICAgbmV3VHgucGFyc2VGcm9tSlNPTihqc29uKTtcblxuICAgICAgc2hvdWxkLmVxdWFsKG5ld1R4LnNlbmRlciwgdHguc2VuZGVyKTtcbiAgICAgIHNob3VsZC5kZWVwRXF1YWwobmV3VHgucmVjaXBpZW50cywgdHgucmVjaXBpZW50cyk7XG4gICAgICBzaG91bGQuZGVlcEVxdWFsKG5ld1R4LnBheW1lbnRPYmplY3RzLCB0eC5wYXltZW50T2JqZWN0cyk7XG4gICAgICBzaG91bGQuZXF1YWwobmV3VHguZ2FzQnVkZ2V0LCB0eC5nYXNCdWRnZXQpO1xuICAgICAgc2hvdWxkLmVxdWFsKG5ld1R4Lmdhc1ByaWNlLCB0eC5nYXNQcmljZSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHNlcmlhbGl6ZSB0byBicm9hZGNhc3QgZm9ybWF0JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgdHggPSAoYXdhaXQgY3JlYXRlVHJhbnNmZXJCdWlsZGVyV2l0aEdhcygpLmJ1aWxkKCkpIGFzIFRyYW5zZmVyVHJhbnNhY3Rpb247XG4gICAgICBjb25zdCBicm9hZGNhc3RGb3JtYXQgPSBhd2FpdCB0eC50b0Jyb2FkY2FzdEZvcm1hdCgpO1xuXG4gICAgICBzaG91bGQuZXhpc3QoYnJvYWRjYXN0Rm9ybWF0KTtcbiAgICAgIHNob3VsZC5lcXVhbCh0eXBlb2YgYnJvYWRjYXN0Rm9ybWF0LCAnc3RyaW5nJyk7XG4gICAgICBzaG91bGQuZXF1YWwoYnJvYWRjYXN0Rm9ybWF0Lmxlbmd0aCA+IDAsIHRydWUpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnVHJhbnNhY3Rpb24gSUQgYW5kIFNpZ25pbmcnLCAoKSA9PiB7XG4gICAgaXQoJ3Nob3VsZCBnZW5lcmF0ZSB0cmFuc2FjdGlvbiBJRCBmb3IgYnVpbHQgdHJhbnNhY3Rpb24nLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB0eCA9IChhd2FpdCBjcmVhdGVUcmFuc2ZlckJ1aWxkZXJXaXRoR2FzKCkuYnVpbGQoKSkgYXMgVHJhbnNmZXJUcmFuc2FjdGlvbjtcbiAgICAgIGNvbnN0IHR4SWQgPSB0eC5pZDtcblxuICAgICAgc2hvdWxkLmV4aXN0KHR4SWQpO1xuICAgICAgc2hvdWxkLmVxdWFsKHR5cGVvZiB0eElkLCAnc3RyaW5nJyk7XG4gICAgICBzaG91bGQuZXF1YWwodHhJZC5sZW5ndGggPiAwLCB0cnVlKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgdGhyb3cgZXJyb3Igd2hlbiBnZXR0aW5nIElEIGJlZm9yZSBidWlsZCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHR4ID0gbmV3IFRyYW5zZmVyVHJhbnNhY3Rpb24oY29pbnMuZ2V0KCd0aW90YScpKTtcbiAgICAgIHR4LnNlbmRlciA9IHRlc3REYXRhLnNlbmRlci5hZGRyZXNzO1xuXG4gICAgICBzaG91bGQoKCkgPT4gdHguaWQpLnRocm93RXJyb3IoJ1R4IG5vdCBidWlsdCBvciBhIHJlYnVpbGQgaXMgcmVxdWlyZWQnKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcHJvdmlkZSBzaWduYWJsZSBwYXlsb2FkIGZvciBub24tc2ltdWxhdGUgdHJhbnNhY3Rpb25zJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgdHggPSAoYXdhaXQgY3JlYXRlVHJhbnNmZXJCdWlsZGVyV2l0aEdhcygpLmJ1aWxkKCkpIGFzIFRyYW5zZmVyVHJhbnNhY3Rpb247XG4gICAgICBjb25zdCBwYXlsb2FkID0gdHguc2lnbmFibGVQYXlsb2FkO1xuXG4gICAgICBzaG91bGQuZXhpc3QocGF5bG9hZCk7XG4gICAgICBzaG91bGQuZXF1YWwoQnVmZmVyLmlzQnVmZmVyKHBheWxvYWQpLCB0cnVlKTtcbiAgICAgIHNob3VsZC5lcXVhbChwYXlsb2FkLmxlbmd0aCwgMzIpOyAvLyBCbGFrZTJiIHByb2R1Y2VzIDMyLWJ5dGUgaGFzaFxuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCB0aHJvdyBlcnJvciB3aGVuIGdldHRpbmcgc2lnbmFibGUgcGF5bG9hZCBmb3Igc2ltdWxhdGUgdHJhbnNhY3Rpb24nLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB0eCA9IChhd2FpdCBjcmVhdGVCYXNpY1RyYW5zZmVyQnVpbGRlcigpLmJ1aWxkKCkpIGFzIFRyYW5zZmVyVHJhbnNhY3Rpb247XG5cbiAgICAgIHNob3VsZC5lcXVhbCh0eC5pc1NpbXVsYXRlVHgsIHRydWUpO1xuICAgICAgc2hvdWxkKCgpID0+IHR4LnNpZ25hYmxlUGF5bG9hZCkudGhyb3dFcnJvcignQ2Fubm90IHNpZ24gYSBzaW11bGF0ZSB0eCcpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBjb3JyZWN0bHkgcmVwb3J0IGNhblNpZ24gYmFzZWQgb24gdHJhbnNhY3Rpb24gbW9kZScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHNpbXVsYXRlVHggPSAoYXdhaXQgY3JlYXRlQmFzaWNUcmFuc2ZlckJ1aWxkZXIoKS5idWlsZCgpKSBhcyBUcmFuc2ZlclRyYW5zYWN0aW9uO1xuICAgICAgY29uc3QgcmVhbFR4ID0gKGF3YWl0IGNyZWF0ZVRyYW5zZmVyQnVpbGRlcldpdGhHYXMoKS5idWlsZCgpKSBhcyBUcmFuc2ZlclRyYW5zYWN0aW9uO1xuXG4gICAgICBzaG91bGQuZXF1YWwoc2ltdWxhdGVUeC5jYW5TaWduKHt9IGFzIGFueSksIGZhbHNlKTtcbiAgICAgIHNob3VsZC5lcXVhbChyZWFsVHguY2FuU2lnbih7fSBhcyBhbnkpLCB0cnVlKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ1RyYW5zYWN0aW9uIEV4cGxhbmF0aW9uJywgKCkgPT4ge1xuICAgIGl0KCdzaG91bGQgcHJvdmlkZSBkZXRhaWxlZCB0cmFuc2FjdGlvbiBleHBsYW5hdGlvbicsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHR4ID0gKGF3YWl0IGNyZWF0ZVRyYW5zZmVyQnVpbGRlcldpdGhHYXMoKS5idWlsZCgpKSBhcyBUcmFuc2ZlclRyYW5zYWN0aW9uO1xuICAgICAgY29uc3QgZXhwbGFuYXRpb24gPSB0eC5leHBsYWluVHJhbnNhY3Rpb24oKTtcblxuICAgICAgc2hvdWxkLmV4aXN0KGV4cGxhbmF0aW9uKTtcbiAgICAgIHNob3VsZC5lcXVhbChleHBsYW5hdGlvbi50eXBlLCBUcmFuc2FjdGlvblR5cGUuU2VuZCk7XG4gICAgICBzaG91bGQuZXhpc3QoZXhwbGFuYXRpb24uaWQpO1xuICAgICAgc2hvdWxkLmV4aXN0KGV4cGxhbmF0aW9uLm91dHB1dHMpO1xuICAgICAgc2hvdWxkLmVxdWFsKGV4cGxhbmF0aW9uLm91dHB1dHMubGVuZ3RoLCB0ZXN0RGF0YS5yZWNpcGllbnRzLmxlbmd0aCk7XG4gICAgICBzaG91bGQuZXF1YWwoZXhwbGFuYXRpb24uZmVlLmZlZSwgdGVzdERhdGEuR0FTX0JVREdFVC50b1N0cmluZygpKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ1JlYnVpbGQgUmVxdWlyZW1lbnRzJywgKCkgPT4ge1xuICAgIGNvbnN0IHJlYnVpbGRUcmlnZ2VycyA9IFtcbiAgICAgIHtcbiAgICAgICAgbmFtZTogJ3NlbmRlciBjaGFuZ2VzJyxcbiAgICAgICAgbW9kaWZpZXI6ICh0eDogVHJhbnNmZXJUcmFuc2FjdGlvbikgPT4gKHR4LnNlbmRlciA9IHRlc3REYXRhLmdhc1Nwb25zb3IuYWRkcmVzcyksXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBuYW1lOiAnZ2FzIGJ1ZGdldCBjaGFuZ2VzJyxcbiAgICAgICAgbW9kaWZpZXI6ICh0eDogVHJhbnNmZXJUcmFuc2FjdGlvbikgPT4gKHR4Lmdhc0J1ZGdldCA9IDEwMDAwMDAwKSxcbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIG5hbWU6ICdyZWNpcGllbnRzIGNoYW5nZScsXG4gICAgICAgIG1vZGlmaWVyOiAodHg6IFRyYW5zZmVyVHJhbnNhY3Rpb24pID0+XG4gICAgICAgICAgKHR4LnJlY2lwaWVudHMgPSBbeyBhZGRyZXNzOiB0ZXN0RGF0YS5hZGRyZXNzZXMudmFsaWRBZGRyZXNzZXNbMF0sIGFtb3VudDogJzUwMDAnIH1dKSxcbiAgICAgIH0sXG4gICAgXTtcblxuICAgIHJlYnVpbGRUcmlnZ2Vycy5mb3JFYWNoKCh7IG5hbWUsIG1vZGlmaWVyIH0pID0+IHtcbiAgICAgIGl0KGBzaG91bGQgcmVxdWlyZSByZWJ1aWxkIHdoZW4gJHtuYW1lfWAsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgY29uc3QgdHggPSAoYXdhaXQgY3JlYXRlVHJhbnNmZXJCdWlsZGVyV2l0aEdhcygpLmJ1aWxkKCkpIGFzIFRyYW5zZmVyVHJhbnNhY3Rpb247XG4gICAgICAgIG1vZGlmaWVyKHR4KTtcbiAgICAgICAgc2hvdWxkKCgpID0+IHR4LmlkKS50aHJvd0Vycm9yKCdUeCBub3QgYnVpbHQgb3IgYSByZWJ1aWxkIGlzIHJlcXVpcmVkJyk7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ1NpZ25hdHVyZSBTZXJpYWxpemF0aW9uJywgKCkgPT4ge1xuICAgIGl0KCdzaG91bGQgaGF2ZSB1bmRlZmluZWQgc2VyaWFsaXplZCBzaWduYXR1cmVzIGJlZm9yZSBzaWduaW5nJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgdHggPSAoYXdhaXQgY3JlYXRlVHJhbnNmZXJCdWlsZGVyV2l0aEdhcygpLmJ1aWxkKCkpIGFzIFRyYW5zZmVyVHJhbnNhY3Rpb247XG5cbiAgICAgIHNob3VsZC5lcXVhbCh0eC5zZXJpYWxpemVkU2lnbmF0dXJlLCB1bmRlZmluZWQpO1xuICAgICAgc2hvdWxkLmVxdWFsKHR4LnNlcmlhbGl6ZWRHYXNTcG9uc29yU2lnbmF0dXJlLCB1bmRlZmluZWQpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBzZXJpYWxpemUgc2VuZGVyIHNpZ25hdHVyZSBhZnRlciBhZGRpbmcgYW5kIHJlYnVpbGRpbmcnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB0eCA9IChhd2FpdCBjcmVhdGVUcmFuc2ZlckJ1aWxkZXJXaXRoR2FzKCkuYnVpbGQoKSkgYXMgVHJhbnNmZXJUcmFuc2FjdGlvbjtcbiAgICAgIHR4LmFkZFNpZ25hdHVyZSh0ZXN0RGF0YS50ZXN0U2lnbmF0dXJlLnB1YmxpY0tleSwgdGVzdERhdGEudGVzdFNpZ25hdHVyZS5zaWduYXR1cmUpO1xuXG4gICAgICBhd2FpdCB0eC5idWlsZCgpO1xuXG4gICAgICBzaG91bGQuZXhpc3QodHguc2VyaWFsaXplZFNpZ25hdHVyZSk7XG4gICAgICBzaG91bGQuZXF1YWwodHlwZW9mIHR4LnNlcmlhbGl6ZWRTaWduYXR1cmUsICdzdHJpbmcnKTtcbiAgICAgIHNob3VsZC5lcXVhbCgvXltBLVphLXowLTkrL10qPXswLDJ9JC8udGVzdCh0eC5zZXJpYWxpemVkU2lnbmF0dXJlISksIHRydWUpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBzZXJpYWxpemUgZ2FzIHNwb25zb3Igc2lnbmF0dXJlIGNvcnJlY3RseScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHR4ID0gKGF3YWl0IGNyZWF0ZVRyYW5zZmVyQnVpbGRlcldpdGhTcG9uc29yKCkuYnVpbGQoKSkgYXMgVHJhbnNmZXJUcmFuc2FjdGlvbjtcbiAgICAgIHR4LmFkZEdhc1Nwb25zb3JTaWduYXR1cmUodGVzdERhdGEudGVzdEdhc1Nwb25zb3JTaWduYXR1cmUucHVibGljS2V5LCB0ZXN0RGF0YS50ZXN0R2FzU3BvbnNvclNpZ25hdHVyZS5zaWduYXR1cmUpO1xuXG4gICAgICBhd2FpdCB0eC5idWlsZCgpO1xuXG4gICAgICBzaG91bGQuZXhpc3QodHguc2VyaWFsaXplZEdhc1Nwb25zb3JTaWduYXR1cmUpO1xuICAgICAgc2hvdWxkLmVxdWFsKHR5cGVvZiB0eC5zZXJpYWxpemVkR2FzU3BvbnNvclNpZ25hdHVyZSwgJ3N0cmluZycpO1xuICAgICAgc2hvdWxkLmVxdWFsKC9eW0EtWmEtejAtOSsvXSo9ezAsMn0kLy50ZXN0KHR4LnNlcmlhbGl6ZWRHYXNTcG9uc29yU2lnbmF0dXJlISksIHRydWUpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBzZXJpYWxpemUgYm90aCBzZW5kZXIgYW5kIGdhcyBzcG9uc29yIHNpZ25hdHVyZXMnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB0eCA9IChhd2FpdCBjcmVhdGVUcmFuc2ZlckJ1aWxkZXJXaXRoU3BvbnNvcigpLmJ1aWxkKCkpIGFzIFRyYW5zZmVyVHJhbnNhY3Rpb247XG5cbiAgICAgIHR4LmFkZFNpZ25hdHVyZSh0ZXN0RGF0YS50ZXN0U2lnbmF0dXJlLnB1YmxpY0tleSwgdGVzdERhdGEudGVzdFNpZ25hdHVyZS5zaWduYXR1cmUpO1xuICAgICAgdHguYWRkR2FzU3BvbnNvclNpZ25hdHVyZSh0ZXN0RGF0YS50ZXN0R2FzU3BvbnNvclNpZ25hdHVyZS5wdWJsaWNLZXksIHRlc3REYXRhLnRlc3RHYXNTcG9uc29yU2lnbmF0dXJlLnNpZ25hdHVyZSk7XG5cbiAgICAgIGF3YWl0IHR4LmJ1aWxkKCk7XG5cbiAgICAgIHNob3VsZC5leGlzdCh0eC5zZXJpYWxpemVkU2lnbmF0dXJlKTtcbiAgICAgIHNob3VsZC5leGlzdCh0eC5zZXJpYWxpemVkR2FzU3BvbnNvclNpZ25hdHVyZSk7XG4gICAgICBzaG91bGQubm90RXF1YWwodHguc2VyaWFsaXplZFNpZ25hdHVyZSwgdHguc2VyaWFsaXplZEdhc1Nwb25zb3JTaWduYXR1cmUpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBpbmNsdWRlIHNlcmlhbGl6ZWQgc2lnbmF0dXJlcyBpbiBzaWduYXR1cmVzIGFycmF5JywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgdHggPSAoYXdhaXQgY3JlYXRlVHJhbnNmZXJCdWlsZGVyV2l0aEdhcygpLmJ1aWxkKCkpIGFzIFRyYW5zZmVyVHJhbnNhY3Rpb247XG4gICAgICB0eC5hZGRTaWduYXR1cmUodGVzdERhdGEudGVzdFNpZ25hdHVyZS5wdWJsaWNLZXksIHRlc3REYXRhLnRlc3RTaWduYXR1cmUuc2lnbmF0dXJlKTtcblxuICAgICAgYXdhaXQgdHguYnVpbGQoKTtcblxuICAgICAgdHguc2lnbmF0dXJlLmxlbmd0aC5zaG91bGQuZXF1YWwoMSk7XG4gICAgICB0eC5zaWduYXR1cmVbMF0uc2hvdWxkLmVxdWFsKHR4LnNlcmlhbGl6ZWRTaWduYXR1cmUpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBpbmNsdWRlIGJvdGggc2lnbmF0dXJlcyBpbiBjb3JyZWN0IG9yZGVyIHdoZW4gZ2FzIHNwb25zb3IgaXMgcHJlc2VudCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHR4ID0gKGF3YWl0IGNyZWF0ZVRyYW5zZmVyQnVpbGRlcldpdGhTcG9uc29yKCkuYnVpbGQoKSkgYXMgVHJhbnNmZXJUcmFuc2FjdGlvbjtcblxuICAgICAgdHguYWRkU2lnbmF0dXJlKHRlc3REYXRhLnRlc3RTaWduYXR1cmUucHVibGljS2V5LCB0ZXN0RGF0YS50ZXN0U2lnbmF0dXJlLnNpZ25hdHVyZSk7XG4gICAgICB0eC5hZGRHYXNTcG9uc29yU2lnbmF0dXJlKHRlc3REYXRhLnRlc3RHYXNTcG9uc29yU2lnbmF0dXJlLnB1YmxpY0tleSwgdGVzdERhdGEudGVzdEdhc1Nwb25zb3JTaWduYXR1cmUuc2lnbmF0dXJlKTtcblxuICAgICAgYXdhaXQgdHguYnVpbGQoKTtcblxuICAgICAgdHguc2lnbmF0dXJlLmxlbmd0aC5zaG91bGQuZXF1YWwoMik7XG4gICAgICB0eC5zaWduYXR1cmVbMF0uc2hvdWxkLmVxdWFsKHR4LnNlcmlhbGl6ZWRTaWduYXR1cmUpO1xuICAgICAgdHguc2lnbmF0dXJlWzFdLnNob3VsZC5lcXVhbCh0eC5zZXJpYWxpemVkR2FzU3BvbnNvclNpZ25hdHVyZSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHZlcmlmeSBzaWduYXR1cmUgc2VyaWFsaXphdGlvbiBmb3JtYXQgKEVERFNBIHNjaGVtZSknLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCB0eCA9IChhd2FpdCBjcmVhdGVUcmFuc2ZlckJ1aWxkZXJXaXRoR2FzKCkuYnVpbGQoKSkgYXMgVHJhbnNmZXJUcmFuc2FjdGlvbjtcbiAgICAgIHR4LmFkZFNpZ25hdHVyZSh0ZXN0RGF0YS50ZXN0U2lnbmF0dXJlLnB1YmxpY0tleSwgdGVzdERhdGEudGVzdFNpZ25hdHVyZS5zaWduYXR1cmUpO1xuXG4gICAgICBhd2FpdCB0eC5idWlsZCgpO1xuXG4gICAgICAvLyBEZWNvZGUgYW5kIHZlcmlmeSBmb3JtYXQ6IDB4MDAgKyBzaWduYXR1cmUgKDY0IGJ5dGVzKSArIHB1YmtleSAoMzIgYnl0ZXMpID0gOTcgYnl0ZXNcbiAgICAgIGNvbnN0IGRlY29kZWQgPSBCdWZmZXIuZnJvbSh0eC5zZXJpYWxpemVkU2lnbmF0dXJlISwgJ2Jhc2U2NCcpO1xuXG4gICAgICAvLyBTaG91bGQgYmUgOTcgYnl0ZXMgdG90YWwgKDEgcHJlZml4ICsgNjQgc2lnbmF0dXJlICsgMzIgcHVia2V5KVxuICAgICAgZGVjb2RlZC5sZW5ndGguc2hvdWxkLmVxdWFsKDk3KTtcblxuICAgICAgLy8gRmlyc3QgYnl0ZSBzaG91bGQgYmUgMHgwMCAoRUREU0Egc2NoZW1lKVxuICAgICAgZGVjb2RlZFswXS5zaG91bGQuZXF1YWwoMHgwMCk7XG5cbiAgICAgIC8vIE5leHQgNjQgYnl0ZXMgc2hvdWxkIGJlIHRoZSBzaWduYXR1cmVcbiAgICAgIGNvbnN0IHNpZ25hdHVyZUJ5dGVzID0gZGVjb2RlZC5zbGljZSgxLCA2NSk7XG4gICAgICBzaWduYXR1cmVCeXRlcy50b1N0cmluZygnaGV4Jykuc2hvdWxkLmVxdWFsKHRlc3REYXRhLnRlc3RTaWduYXR1cmUuc2lnbmF0dXJlLnRvU3RyaW5nKCdoZXgnKSk7XG5cbiAgICAgIC8vIExhc3QgMzIgYnl0ZXMgc2hvdWxkIGJlIHRoZSBwdWJsaWMga2V5XG4gICAgICBjb25zdCBwdWJLZXlCeXRlcyA9IGRlY29kZWQuc2xpY2UoNjUpO1xuICAgICAgcHViS2V5Qnl0ZXMudG9TdHJpbmcoJ2hleCcpLnNob3VsZC5lcXVhbCh0ZXN0RGF0YS50ZXN0U2lnbmF0dXJlLnB1YmxpY0tleS5wdWIpO1xuICAgIH0pO1xuICB9KTtcbn0pO1xuIl19
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../test/unit/utils.ts"],"names":[],"mappings":""}
@@ -0,0 +1,252 @@
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 testData = __importStar(require("../resources/iota"));
40
+ const should_1 = __importDefault(require("should"));
41
+ const utils_1 = __importDefault(require("../../src/lib/utils"));
42
+ const testHelpers_1 = require("./helpers/testHelpers");
43
+ describe('Iota util library', function () {
44
+ describe('Address Validation', function () {
45
+ it('should validate all correct addresses', function () {
46
+ testData.addresses.validAddresses.forEach((address) => {
47
+ utils_1.default.isValidAddress(address).should.be.true();
48
+ });
49
+ });
50
+ it('should reject all invalid addresses', function () {
51
+ testData.addresses.invalidAddresses.forEach((address) => {
52
+ utils_1.default.isValidAddress(address).should.be.false();
53
+ });
54
+ });
55
+ const addressTestCases = [
56
+ { address: '0x' + 'a'.repeat(64), valid: true, description: 'correct length (64 hex chars)' },
57
+ { address: '0x' + 'a'.repeat(32), valid: false, description: 'too short' },
58
+ { address: '0x' + 'a'.repeat(128), valid: false, description: 'too long' },
59
+ { address: 'a'.repeat(64), valid: false, description: 'missing 0x prefix' },
60
+ { address: '0x' + 'g'.repeat(64), valid: false, description: 'non-hex characters' },
61
+ { address: undefined, valid: false, description: 'undefined' },
62
+ ];
63
+ addressTestCases.forEach(({ address, valid, description }) => {
64
+ it(`should ${valid ? 'accept' : 'reject'} address with ${description}`, function () {
65
+ // @ts-expect-error Testing for undefined
66
+ utils_1.default.isValidAddress(address).should.equal(valid);
67
+ });
68
+ });
69
+ });
70
+ describe('Public Key Validation', function () {
71
+ const validPublicKeys = [
72
+ 'b2051899478edeb36a79d1d16dfec56dc3a6ebd29fbbbb4a4ef2dfaf46043355',
73
+ testData.sender.publicKey,
74
+ ];
75
+ it('should validate all correct public keys', function () {
76
+ validPublicKeys.forEach((key) => {
77
+ utils_1.default.isValidPublicKey(key).should.be.true();
78
+ });
79
+ });
80
+ const invalidPublicKeyTestCases = [
81
+ { key: '0x413f7fa8beb54459e1e9ede3af3b12e5a4a3550390bb616da30dd72017701263', description: 'with 0x prefix' },
82
+ { key: 'invalid', description: 'invalid format' },
83
+ { key: '', description: 'empty string' },
84
+ { key: '123', description: 'too short' },
85
+ { key: 'a'.repeat(32), description: 'incorrect length (too short)' },
86
+ { key: 'a'.repeat(128), description: 'incorrect length (too long)' },
87
+ ];
88
+ invalidPublicKeyTestCases.forEach(({ key, description }) => {
89
+ it(`should reject public key ${description}`, function () {
90
+ utils_1.default.isValidPublicKey(key).should.be.false();
91
+ });
92
+ });
93
+ });
94
+ describe('Private Key Validation', function () {
95
+ it('should validate ed25519 secret keys with correct length', function () {
96
+ // Ed25519 secret keys are 128 hex chars (64 bytes: 32-byte seed + 32-byte public key)
97
+ const validSecretKey = '0'.repeat(128);
98
+ utils_1.default.isValidPrivateKey(validSecretKey).should.be.true();
99
+ });
100
+ const invalidPrivateKeyTestCases = [
101
+ { key: 'invalid', description: 'invalid format' },
102
+ { key: '', description: 'empty string' },
103
+ { key: '123', description: 'too short' },
104
+ { key: 'a'.repeat(32), description: '16 bytes (too short)' },
105
+ { key: 'a'.repeat(64), description: '32 bytes (seed only, not full secret)' },
106
+ { key: 'a'.repeat(256), description: '128 bytes (too long)' },
107
+ ];
108
+ invalidPrivateKeyTestCases.forEach(({ key, description }) => {
109
+ it(`should reject private key: ${description}`, function () {
110
+ utils_1.default.isValidPrivateKey(key).should.be.false();
111
+ });
112
+ });
113
+ });
114
+ describe('Transaction and Block ID Validation', function () {
115
+ it('should validate correct transaction ID (base58)', function () {
116
+ utils_1.default.isValidTransactionId('BftEk3BeKUWTj9uzVGntd4Ka16QZG8hUnr6KsAb7q7bt').should.be.true();
117
+ });
118
+ it('should validate correct block ID (base58)', function () {
119
+ utils_1.default.isValidBlockId('GZXZvvLS3ZnuE4E9CxQJJ2ij5xeNsvUXdAKVrPCQKrPz').should.be.true();
120
+ });
121
+ const invalidIdTestCases = [
122
+ {
123
+ validator: 'isValidTransactionId',
124
+ cases: [
125
+ { id: '0xff86b121181a43d03df52e8930785af3dda944ec87654cdba3a378ff518cd75b', description: 'hex format' },
126
+ { id: 'BftEk3BeKUWTj9uzVGntd4Ka16QZG8hUnr6KsAb7q7b53t', description: 'wrong length' },
127
+ { id: '0xabcdef123456', description: 'hex with prefix' },
128
+ { id: '', description: 'empty string' },
129
+ ],
130
+ },
131
+ {
132
+ validator: 'isValidBlockId',
133
+ cases: [
134
+ { id: '0x9ac6a0c313c4a0563a169dad29f1d018647683be54a314ed229a2693293dfc98', description: 'hex format' },
135
+ { id: 'GZXZvvLS3ZnuE4E9CxQJJ2ij5xeNsvUXdAK56VrPCQKrPz', description: 'wrong length' },
136
+ { id: '0xabcdef', description: 'hex with prefix' },
137
+ { id: '', description: 'empty string' },
138
+ ],
139
+ },
140
+ ];
141
+ invalidIdTestCases.forEach(({ validator, cases }) => {
142
+ cases.forEach(({ id, description }) => {
143
+ it(`${validator} should reject ${description}`, function () {
144
+ utils_1.default[validator](id).should.be.false();
145
+ });
146
+ });
147
+ });
148
+ });
149
+ describe('Signature Validation', function () {
150
+ it('should validate correct base64-encoded 64-byte signature', function () {
151
+ const validSignature = 'iXrcUjgQgpYUsa7O90KZicdTmIdJSjB99+tJW6l6wPCqI/lUTou6sQ2sLoZgC0n4qQKX+vFDz+lBIXl7J/ZgCg==';
152
+ utils_1.default.isValidSignature(validSignature).should.be.true();
153
+ });
154
+ const invalidSignatureTestCases = [
155
+ { sig: '0x9ac6a0c313c4a0563a169dad29f1d018647683be54a314ed229a2693293dfc98', description: 'hex format' },
156
+ { sig: 'goppBTDgLuBbcU5tP90n3igvZGHmcE23HCoxLfdJwOCcbyztVh9r0TPacJRXmjZ6', description: 'wrong format' },
157
+ { sig: 'dG9vU2hvcnQ=', description: 'too short (base64)' },
158
+ { sig: 'not a base64 string!!!', description: 'invalid base64' },
159
+ { sig: '', description: 'empty string' },
160
+ ];
161
+ invalidSignatureTestCases.forEach(({ sig, description }) => {
162
+ it(`should reject ${description}`, function () {
163
+ utils_1.default.isValidSignature(sig).should.be.false();
164
+ });
165
+ });
166
+ });
167
+ describe('Hex String Validation', function () {
168
+ const hexTestCases = [
169
+ { hex: '0xabcdef', length: 6, valid: true, description: 'lowercase' },
170
+ { hex: '0x123456', length: 6, valid: true, description: 'numbers' },
171
+ { hex: '0XABCDEF', length: 6, valid: true, description: 'uppercase prefix' },
172
+ { hex: '0xABCDEF', length: 6, valid: true, description: 'uppercase' },
173
+ { hex: '0xAbCdEf', length: 6, valid: true, description: 'mixed case' },
174
+ { hex: '0xabcd', length: 6, valid: false, description: 'too short' },
175
+ { hex: '0xabcdefgh', length: 6, valid: false, description: 'too long' },
176
+ { hex: 'abcdef', length: 6, valid: false, description: 'no prefix' },
177
+ { hex: '0xghijkl', length: 6, valid: false, description: 'non-hex chars' },
178
+ { hex: '0xabcdeg', length: 6, valid: false, description: 'invalid char at end' },
179
+ ];
180
+ hexTestCases.forEach(({ hex, length, valid, description }) => {
181
+ it(`should ${valid ? 'accept' : 'reject'} ${description}`, function () {
182
+ utils_1.default.isValidHex(hex, length).should.equal(valid);
183
+ });
184
+ });
185
+ });
186
+ describe('Address Derivation from Public Key', function () {
187
+ it('should generate valid address from public key', function () {
188
+ const address = utils_1.default.getAddressFromPublicKey(testData.sender.publicKey);
189
+ should_1.default.exist(address);
190
+ utils_1.default.isValidAddress(address).should.be.true();
191
+ });
192
+ it('should generate consistent addresses from same key', function () {
193
+ const address1 = utils_1.default.getAddressFromPublicKey(testData.sender.publicKey);
194
+ const address2 = utils_1.default.getAddressFromPublicKey(testData.sender.publicKey);
195
+ address1.should.equal(address2);
196
+ });
197
+ it('should generate different addresses for different keys', function () {
198
+ const address1 = utils_1.default.getAddressFromPublicKey(testData.sender.publicKey);
199
+ const address2 = utils_1.default.getAddressFromPublicKey(testData.gasSponsor.publicKey);
200
+ address1.should.not.equal(address2);
201
+ });
202
+ });
203
+ describe('Base64 String Conversion', function () {
204
+ const conversionTestCases = [
205
+ { input: new Uint8Array([72, 101, 108, 108, 111]), description: 'Uint8Array ("Hello")' },
206
+ { input: '48656c6c6f', description: 'hex string ("Hello")' },
207
+ { input: new Uint8Array([]), description: 'empty Uint8Array' },
208
+ { input: new Uint8Array(Buffer.from('Hello World')), description: 'Buffer as Uint8Array' },
209
+ ];
210
+ conversionTestCases.forEach(({ input, description }) => {
211
+ it(`should convert ${description} to base64`, function () {
212
+ const result = utils_1.default.getBase64String(input);
213
+ should_1.default.exist(result);
214
+ should_1.default.equal(typeof result, 'string');
215
+ });
216
+ });
217
+ it('should produce consistent output for same input', function () {
218
+ const uint8Array = new Uint8Array([1, 2, 3, 4, 5]);
219
+ const result1 = utils_1.default.getBase64String(uint8Array);
220
+ const result2 = utils_1.default.getBase64String(new Uint8Array([1, 2, 3, 4, 5]));
221
+ result1.should.equal(result2);
222
+ });
223
+ });
224
+ describe('Raw Transaction Validation', function () {
225
+ it('should validate properly built transaction (base64)', async function () {
226
+ const txBuilder = (0, testHelpers_1.createTransferBuilderWithGas)();
227
+ const tx = await txBuilder.build();
228
+ const rawTx = await tx.toBroadcastFormat();
229
+ utils_1.default.isValidRawTransaction(rawTx).should.be.true();
230
+ });
231
+ it('should validate transaction as Uint8Array', async function () {
232
+ const txBuilder = (0, testHelpers_1.createTransferBuilderWithGas)();
233
+ const tx = await txBuilder.build();
234
+ const rawTx = await tx.toBroadcastFormat();
235
+ const rawTxBytes = Buffer.from(rawTx, 'base64');
236
+ utils_1.default.isValidRawTransaction(rawTxBytes).should.be.true();
237
+ });
238
+ const invalidRawTxTestCases = [
239
+ { tx: 'invalidRawTx', description: 'invalid string' },
240
+ { tx: '', description: 'empty string' },
241
+ { tx: '0x123456', description: 'hex format' },
242
+ { tx: 'not-base64!!!', description: 'invalid base64' },
243
+ { tx: Buffer.from('malformed data').toString('base64'), description: 'malformed data' },
244
+ ];
245
+ invalidRawTxTestCases.forEach(({ tx, description }) => {
246
+ it(`should reject ${description}`, function () {
247
+ utils_1.default.isValidRawTransaction(tx).should.be.false();
248
+ });
249
+ });
250
+ });
251
+ });
252
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXRpbHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi90ZXN0L3VuaXQvdXRpbHMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQSw0REFBOEM7QUFDOUMsb0RBQTRCO0FBQzVCLGdFQUF3QztBQUN4Qyx1REFBcUU7QUFFckUsUUFBUSxDQUFDLG1CQUFtQixFQUFFO0lBQzVCLFFBQVEsQ0FBQyxvQkFBb0IsRUFBRTtRQUM3QixFQUFFLENBQUMsdUNBQXVDLEVBQUU7WUFDMUMsUUFBUSxDQUFDLFNBQVMsQ0FBQyxjQUFjLENBQUMsT0FBTyxDQUFDLENBQUMsT0FBTyxFQUFFLEVBQUU7Z0JBQ3BELGVBQUssQ0FBQyxjQUFjLENBQUMsT0FBTyxDQUFDLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxJQUFJLEVBQUUsQ0FBQztZQUNqRCxDQUFDLENBQUMsQ0FBQztRQUNMLENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLHFDQUFxQyxFQUFFO1lBQ3hDLFFBQVEsQ0FBQyxTQUFTLENBQUMsZ0JBQWdCLENBQUMsT0FBTyxDQUFDLENBQUMsT0FBTyxFQUFFLEVBQUU7Z0JBQ3RELGVBQUssQ0FBQyxjQUFjLENBQUMsT0FBTyxDQUFDLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxLQUFLLEVBQUUsQ0FBQztZQUNsRCxDQUFDLENBQUMsQ0FBQztRQUNMLENBQUMsQ0FBQyxDQUFDO1FBRUgsTUFBTSxnQkFBZ0IsR0FBRztZQUN2QixFQUFFLE9BQU8sRUFBRSxJQUFJLEdBQUcsR0FBRyxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsRUFBRSxLQUFLLEVBQUUsSUFBSSxFQUFFLFdBQVcsRUFBRSwrQkFBK0IsRUFBRTtZQUM3RixFQUFFLE9BQU8sRUFBRSxJQUFJLEdBQUcsR0FBRyxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLFdB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USxDQUFDLHVCQUF1QixFQUFFO1FBQ2hDLE1BQU0sWUFBWSxHQUFHO1lBQ25CLEVBQUUsR0FBRyxFQUFFLFVBQVUsRUFBRSxNQUFNLEVBQUUsQ0FBQyxFQUFFLEtBQUssRUFBRSxJQUFJLEVBQUUsV0FBVyxFQUFFLFdBQVcsRUFBRTtZQUNyRSxFQUFFLEdBQUcsRUFBRSxVQUFVLEVBQUUsTUFBTSxFQUFFLENBQUMsRUFBRSxLQUFLLEVBQUUsSUFBSSxFQUFFLFdBQVcsRUFBRSxTQUFTLEVBQUU7WUFDbkUsRUFBRSxHQUFHLEVBQUUsVUFBVSxFQUFFLE1BQU0sRUFBRSxDQUFDLEVBQUUsS0FBSyxFQUFFLElBQUksRUFBRSxXQUFXLEVBQUUsa0JBQWtCLEVBQUU7WUFDNUUsRUFBRSxHQUFHLEVBQUUsVUFBVSxFQUFFLE1BQU0sRUFBRSxDQUFDLEVBQUUsS0FBSyxFQUFFLElBQUksRUFBRSxXQUFXLEVBQUUsV0FBVyxFQUFFO1lBQ3JFLEVBQUUsR0FBRyxFQUFFLFVBQVUsRUFBRSxNQUFNLEVBQUUsQ0FBQyxFQUFFLEtBQUssRUFBRSxJQUFJLEVBQUUsV0FBVyxFQUFFLFlBQVksRUFBRTtZQUN0RSxFQUFFLEdBQUcsRUFBRSxRQUFRLEVBQUUsTUFBTSxFQUFFLENBQUMsRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLFdBQVcsRUFBRSxXQUFXLEVBQUU7WUFDcEUsRUFBRSxHQUFHLEVBQUUsWUFBWSxFQUFFLE1BQU0sRUFBRSxDQUFDLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxXQUFXLEVBQUUsVUFBVSxFQUFFO1lBQ3ZFLEVBQUUsR0FBRyxFQUFFLFFBQVEsRUFBRSxNQUFNLEVBQUUsQ0FBQyxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsV0FBVyxFQUFFLFdBQVcsRUFBRTtZQUNwRSxFQUFFLEdBQUcsRUFBRSxVQUFVLEVBQUUsTUFBTSxFQUFFLENBQUMsRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLFdBQVcsRUFBRSxlQUFlLEVBQUU7WUFDMUUsRUFBRSxHQUFHLEVBQUUsVUFBVSxFQUFFLE1BQU0sRUFB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YXMgdGVzdERhdGEgZnJvbSAnLi4vcmVzb3VyY2VzL2lvdGEnO1xuaW1wb3J0IHNob3VsZCBmcm9tICdzaG91bGQnO1xuaW1wb3J0IHV0aWxzIGZyb20gJy4uLy4uL3NyYy9saWIvdXRpbHMnO1xuaW1wb3J0IHsgY3JlYXRlVHJhbnNmZXJCdWlsZGVyV2l0aEdhcyB9IGZyb20gJy4vaGVscGVycy90ZXN0SGVscGVycyc7XG5cbmRlc2NyaWJlKCdJb3RhIHV0aWwgbGlicmFyeScsIGZ1bmN0aW9uICgpIHtcbiAgZGVzY3JpYmUoJ0FkZHJlc3MgVmFsaWRhdGlvbicsIGZ1bmN0aW9uICgpIHtcbiAgICBpdCgnc2hvdWxkIHZhbGlkYXRlIGFsbCBjb3JyZWN0IGFkZHJlc3NlcycsIGZ1bmN0aW9uICgpIHtcbiAgICAgIHRlc3REYXRhLmFkZHJlc3Nlcy52YWxpZEFkZHJlc3Nlcy5mb3JFYWNoKChhZGRyZXNzKSA9PiB7XG4gICAgICAgIHV0aWxzLmlzVmFsaWRBZGRyZXNzKGFkZHJlc3MpLnNob3VsZC5iZS50cnVlKCk7XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmVqZWN0IGFsbCBpbnZhbGlkIGFkZHJlc3NlcycsIGZ1bmN0aW9uICgpIHtcbiAgICAgIHRlc3REYXRhLmFkZHJlc3Nlcy5pbnZhbGlkQWRkcmVzc2VzLmZvckVhY2goKGFkZHJlc3MpID0+IHtcbiAgICAgICAgdXRpbHMuaXNWYWxpZEFkZHJlc3MoYWRkcmVzcykuc2hvdWxkLmJlLmZhbHNlKCk7XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGNvbnN0IGFkZHJlc3NUZXN0Q2FzZXMgPSBbXG4gICAgICB7IGFkZHJlc3M6ICcweCcgKyAnYScucmVwZWF0KDY0KSwgdmFsaWQ6IHRydWUsIGRlc2NyaXB0aW9uOiAnY29ycmVjdCBsZW5ndGggKDY0IGhleCBjaGFycyknIH0sXG4gICAgICB7IGFkZHJlc3M6ICcweCcgKyAnYScucmVwZWF0KDMyKSwgdmFsaWQ6IGZhbHNlLCBkZXNjcmlwdGlvbjogJ3RvbyBzaG9ydCcgfSxcbiAgICAgIHsgYWRkcmVzczogJzB4JyArICdhJy5yZXBlYXQoMTI4KSwgdmFsaWQ6IGZhbHNlLCBkZXNjcmlwdGlvbjogJ3RvbyBsb25nJyB9LFxuICAgICAgeyBhZGRyZXNzOiAnYScucmVwZWF0KDY0KSwgdmFsaWQ6IGZhbHNlLCBkZXNjcmlwdGlvbjogJ21pc3NpbmcgMHggcHJlZml4JyB9LFxuICAgICAgeyBhZGRyZXNzOiAnMHgnICsgJ2cnLnJlcGVhdCg2NCksIHZhbGlkOiBmYWxzZSwgZGVzY3JpcHRpb246ICdub24taGV4IGNoYXJhY3RlcnMnIH0sXG4gICAgICB7IGFkZHJlc3M6IHVuZGVmaW5lZCwgdmFsaWQ6IGZhbHNlLCBkZXNjcmlwdGlvbjogJ3VuZGVmaW5lZCcgfSxcbiAgICBdO1xuXG4gICAgYWRkcmVzc1Rlc3RDYXNlcy5mb3JFYWNoKCh7IGFkZHJlc3MsIHZhbGlkLCBkZXNjcmlwdGlvbiB9KSA9PiB7XG4gICAgICBpdChgc2hvdWxkICR7dmFsaWQgPyAnYWNjZXB0JyA6ICdyZWplY3QnfSBhZGRyZXNzIHdpdGggJHtkZXNjcmlwdGlvbn1gLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIC8vIEB0cy1leHBlY3QtZXJyb3IgVGVzdGluZyBmb3IgdW5kZWZpbmVkXG4gICAgICAgIHV0aWxzLmlzVmFsaWRBZGRyZXNzKGFkZHJlc3MpLnNob3VsZC5lcXVhbCh2YWxpZCk7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ1B1YmxpYyBLZXkgVmFsaWRhdGlvbicsIGZ1bmN0aW9uICgpIHtcbiAgICBjb25zdCB2YWxpZFB1YmxpY0tleXMgPSBbXG4gICAgICAnYjIwNTE4OTk0NzhlZGViMzZhNzlkMWQxNmRmZWM1NmRjM2E2ZWJkMjlmYmJiYjRhNGVmMmRmYWY0NjA0MzM1NScsXG4gICAgICB0ZXN0RGF0YS5zZW5kZXIucHVibGljS2V5LFxuICAgIF07XG5cbiAgICBpdCgnc2hvdWxkIHZhbGlkYXRlIGFsbCBjb3JyZWN0IHB1YmxpYyBrZXlzJywgZnVuY3Rpb24gKCkge1xuICAgICAgdmFsaWRQdWJsaWNLZXlzLmZvckVhY2goKGtleSkgPT4ge1xuICAgICAgICB1dGlscy5pc1ZhbGlkUHVibGljS2V5KGtleSkuc2hvdWxkLmJlLnRydWUoKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgY29uc3QgaW52YWxpZFB1YmxpY0tleVRlc3RDYXNlcyA9IFtcbiAgICAgIHsga2V5OiAnMHg0MTNmN2ZhOGJlYjU0NDU5ZTFlOWVkZTNhZjNiMTJlNWE0YTM1NTAzOTBiYjYxNmRhMzBkZDcyMDE3NzAxMjYzJywgZGVzY3JpcHRpb246ICd3aXRoIDB4IHByZWZpeCcgfSxcbiAgICAgIHsga2V5OiAnaW52YWxpZCcsIGRlc2NyaXB0aW9uOiAnaW52YWxpZCBmb3JtYXQnIH0sXG4gICAgICB7IGtleTogJycsIGRlc2NyaXB0aW9uOiAnZW1wdHkgc3RyaW5nJyB9LFxuICAgICAgeyBrZXk6ICcxMjMnLCBkZXNjcmlwdGlvbjogJ3RvbyBzaG9ydCcgfSxcbiAgICAgIHsga2V5OiAnYScucmVwZWF0KDMyKSwgZGVzY3JpcHRpb246ICdpbmNvcnJlY3QgbGVuZ3RoICh0b28gc2hvcnQpJyB9LFxuICAgICAgeyBrZXk6ICdhJy5yZXBlYXQoMTI4KSwgZGVzY3JpcHRpb246ICdpbmNvcnJlY3QgbGVuZ3RoICh0b28gbG9uZyknIH0sXG4gICAgXTtcblxuICAgIGludmFsaWRQdWJsaWNLZXlUZXN0Q2FzZXMuZm9yRWFjaCgoeyBrZXksIGRlc2NyaXB0aW9uIH0pID0+IHtcbiAgICAgIGl0KGBzaG91bGQgcmVqZWN0IHB1YmxpYyBrZXkgJHtkZXNjcmlwdGlvbn1gLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHV0aWxzLmlzVmFsaWRQdWJsaWNLZXkoa2V5KS5zaG91bGQuYmUuZmFsc2UoKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnUHJpdmF0ZSBLZXkgVmFsaWRhdGlvbicsIGZ1bmN0aW9uICgpIHtcbiAgICBpdCgnc2hvdWxkIHZhbGlkYXRlIGVkMjU1MTkgc2VjcmV0IGtleXMgd2l0aCBjb3JyZWN0IGxlbmd0aCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgIC8vIEVkMjU1MTkgc2VjcmV0IGtleXMgYXJlIDEyOCBoZXggY2hhcnMgKDY0IGJ5dGVzOiAzMi1ieXRlIHNlZWQgKyAzMi1ieXRlIHB1YmxpYyBrZXkpXG4gICAgICBjb25zdCB2YWxpZFNlY3JldEtleSA9ICcwJy5yZXBlYXQoMTI4KTtcbiAgICAgIHV0aWxzLmlzVmFsaWRQcml2YXRlS2V5KHZhbGlkU2VjcmV0S2V5KS5zaG91bGQuYmUudHJ1ZSgpO1xuICAgIH0pO1xuXG4gICAgY29uc3QgaW52YWxpZFByaXZhdGVLZXlUZXN0Q2FzZXMgPSBbXG4gICAgICB7IGtleTogJ2ludmFsaWQnLCBkZXNjcmlwdGlvbjogJ2ludmFsaWQgZm9ybWF0JyB9LFxuICAgICAgeyBrZXk6ICcnLCBkZXNjcmlwdGlvbjogJ2VtcHR5IHN0cmluZycgfSxcbiAgICAgIHsga2V5OiAnMTIzJywgZGVzY3JpcHRpb246ICd0b28gc2hvcnQnIH0sXG4gICAgICB7IGtleTogJ2EnLnJlcGVhdCgzMiksIGRlc2NyaXB0aW9uOiAnMTYgYnl0ZXMgKHRvbyBzaG9ydCknIH0sXG4gICAgICB7IGtleTogJ2EnLnJlcGVhdCg2NCksIGRlc2NyaXB0aW9uOiAnMzIgYnl0ZXMgKHNlZWQgb25seSwgbm90IGZ1bGwgc2VjcmV0KScgfSxcbiAgICAgIHsga2V5OiAnYScucmVwZWF0KDI1NiksIGRlc2NyaXB0aW9uOiAnMTI4IGJ5dGVzICh0b28gbG9uZyknIH0sXG4gICAgXTtcblxuICAgIGludmFsaWRQcml2YXRlS2V5VGVzdENhc2VzLmZvckVhY2goKHsga2V5LCBkZXNjcmlwdGlvbiB9KSA9PiB7XG4gICAgICBpdChgc2hvdWxkIHJlamVjdCBwcml2YXRlIGtleTogJHtkZXNjcmlwdGlvbn1gLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHV0aWxzLmlzVmFsaWRQcml2YXRlS2V5KGtleSkuc2hvdWxkLmJlLmZhbHNlKCk7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ1RyYW5zYWN0aW9uIGFuZCBCbG9jayBJRCBWYWxpZGF0aW9uJywgZnVuY3Rpb24gKCkge1xuICAgIGl0KCdzaG91bGQgdmFsaWRhdGUgY29ycmVjdCB0cmFuc2FjdGlvbiBJRCAoYmFzZTU4KScsIGZ1bmN0aW9uICgpIHtcbiAgICAgIHV0aWxzLmlzVmFsaWRUcmFuc2FjdGlvbklkKCdCZnRFazNCZUtVV1RqOXV6VkdudGQ0S2ExNlFaRzhoVW5yNktzQWI3cTdidCcpLnNob3VsZC5iZS50cnVlKCk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHZhbGlkYXRlIGNvcnJlY3QgYmxvY2sgSUQgKGJhc2U1OCknLCBmdW5jdGlvbiAoKSB7XG4gICAgICB1dGlscy5pc1ZhbGlkQmxvY2tJZCgnR1pYWnZ2TFMzWm51RTRFOUN4UUpKMmlqNXhlTnN2VVhkQUtWclBDUUtyUHonKS5zaG91bGQuYmUudHJ1ZSgpO1xuICAgIH0pO1xuXG4gICAgY29uc3QgaW52YWxpZElkVGVzdENhc2VzID0gW1xuICAgICAge1xuICAgICAgICB2YWxpZGF0b3I6ICdpc1ZhbGlkVHJhbnNhY3Rpb25JZCcsXG4gICAgICAgIGNhc2VzOiBbXG4gICAgICAgICAgeyBpZDogJzB4ZmY4NmIxMjExODFhNDNkMDNkZjUyZTg5MzA3ODVhZjNkZGE5NDRlYzg3NjU0Y2RiYTNhMzc4ZmY1MThjZDc1YicsIGRlc2NyaXB0aW9uOiAnaGV4IGZvcm1hdCcgfSxcbiAgICAgICAgICB7IGlkOiAnQmZ0RWszQmVLVVdUajl1elZHbnRkNEthMTZRWkc4aFVucjZLc0FiN3E3YjUzdCcsIGRlc2NyaXB0aW9uOiAnd3JvbmcgbGVuZ3RoJyB9LFxuICAgICAgICAgIHsgaWQ6ICcweGFiY2RlZjEyMzQ1NicsIGRlc2NyaXB0aW9uOiAnaGV4IHdpdGggcHJlZml4JyB9LFxuICAgICAgICAgIHsgaWQ6ICcnLCBkZXNjcmlwdGlvbjogJ2VtcHR5IHN0cmluZycgfSxcbiAgICAgICAgXSxcbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIHZhbGlkYXRvcjogJ2lzVmFsaWRCbG9ja0lkJyxcbiAgICAgICAgY2FzZXM6IFtcbiAgICAgICAgICB7IGlkOiAnMHg5YWM2YTBjMzEzYzRhMDU2M2ExNjlkYWQyOWYxZDAxODY0NzY4M2JlNTRhMzE0ZWQyMjlhMjY5MzI5M2RmYzk4JywgZGVzY3JpcHRpb246ICdoZXggZm9ybWF0JyB9LFxuICAgICAgICAgIHsgaWQ6ICdHWlhadnZMUzNabnVFNEU5Q3hRSkoyaWo1eGVOc3ZVWGRBSzU2VnJQQ1FLclB6JywgZGVzY3JpcHRpb246ICd3cm9uZyBsZW5ndGgnIH0sXG4gICAgICAgICAgeyBpZDogJzB4YWJjZGVmJywgZGVzY3JpcHRpb246ICdoZXggd2l0aCBwcmVmaXgnIH0sXG4gICAgICAgICAgeyBpZDogJycsIGRlc2NyaXB0aW9uOiAnZW1wdHkgc3RyaW5nJyB9LFxuICAgICAgICBdLFxuICAgICAgfSxcbiAgICBdO1xuXG4gICAgaW52YWxpZElkVGVzdENhc2VzLmZvckVhY2goKHsgdmFsaWRhdG9yLCBjYXNlcyB9KSA9PiB7XG4gICAgICBjYXNlcy5mb3JFYWNoKCh7IGlkLCBkZXNjcmlwdGlvbiB9KSA9PiB7XG4gICAgICAgIGl0KGAke3ZhbGlkYXRvcn0gc2hvdWxkIHJlamVjdCAke2Rlc2NyaXB0aW9ufWAsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICB1dGlsc1t2YWxpZGF0b3JdKGlkKS5zaG91bGQuYmUuZmFsc2UoKTtcbiAgICAgICAgfSk7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ1NpZ25hdHVyZSBWYWxpZGF0aW9uJywgZnVuY3Rpb24gKCkge1xuICAgIGl0KCdzaG91bGQgdmFsaWRhdGUgY29ycmVjdCBiYXNlNjQtZW5jb2RlZCA2NC1ieXRlIHNpZ25hdHVyZScsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHZhbGlkU2lnbmF0dXJlID0gJ2lYcmNVamdRZ3BZVXNhN085MEtaaWNkVG1JZEpTakI5OSt0Slc2bDZ3UENxSS9sVVRvdTZzUTJzTG9aZ0MwbjRxUUtYK3ZGRHorbEJJWGw3Si9aZ0NnPT0nO1xuICAgICAgdXRpbHMuaXNWYWxpZFNpZ25hdHVyZSh2YWxpZFNpZ25hdHVyZSkuc2hvdWxkLmJlLnRydWUoKTtcbiAgICB9KTtcblxuICAgIGNvbnN0IGludmFsaWRTaWduYXR1cmVUZXN0Q2FzZXMgPSBbXG4gICAgICB7IHNpZzogJzB4OWFjNmEwYzMxM2M0YTA1NjNhMTY5ZGFkMjlmMWQwMTg2NDc2ODNiZTU0YTMxNGVkMjI5YTI2OTMyOTNkZmM5OCcsIGRlc2NyaXB0aW9uOiAnaGV4IGZvcm1hdCcgfSxcbiAgICAgIHsgc2lnOiAnZ29wcEJURGdMdUJiY1U1dFA5MG4zaWd2WkdIbWNFMjNIQ294TGZkSndPQ2NieXp0Vmg5cjBUUGFjSlJYbWpaNicsIGRlc2NyaXB0aW9uOiAnd3JvbmcgZm9ybWF0JyB9LFxuICAgICAgeyBzaWc6ICdkRzl2VTJodmNuUT0nLCBkZXNjcmlwdGlvbjogJ3RvbyBzaG9ydCAoYmFzZTY0KScgfSxcbiAgICAgIHsgc2lnOiAnbm90IGEgYmFzZTY0IHN0cmluZyEhIScsIGRlc2NyaXB0aW9uOiAnaW52YWxpZCBiYXNlNjQnIH0sXG4gICAgICB7IHNpZzogJycsIGRlc2NyaXB0aW9uOiAnZW1wdHkgc3RyaW5nJyB9LFxuICAgIF07XG5cbiAgICBpbnZhbGlkU2lnbmF0dXJlVGVzdENhc2VzLmZvckVhY2goKHsgc2lnLCBkZXNjcmlwdGlvbiB9KSA9PiB7XG4gICAgICBpdChgc2hvdWxkIHJlamVjdCAke2Rlc2NyaXB0aW9ufWAsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdXRpbHMuaXNWYWxpZFNpZ25hdHVyZShzaWcpLnNob3VsZC5iZS5mYWxzZSgpO1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdIZXggU3RyaW5nIFZhbGlkYXRpb24nLCBmdW5jdGlvbiAoKSB7XG4gICAgY29uc3QgaGV4VGVzdENhc2VzID0gW1xuICAgICAgeyBoZXg6ICcweGFiY2RlZicsIGxlbmd0aDogNiwgdmFsaWQ6IHRydWUsIGRlc2NyaXB0aW9uOiAnbG93ZXJjYXNlJyB9LFxuICAgICAgeyBoZXg6ICcweDEyMzQ1NicsIGxlbmd0aDogNiwgdmFsaWQ6IHRydWUsIGRlc2NyaXB0aW9uOiAnbnVtYmVycycgfSxcbiAgICAgIHsgaGV4OiAnMFhBQkNERUYnLCBsZW5ndGg6IDYsIHZhbGlkOiB0cnVlLCBkZXNjcmlwdGlvbjogJ3VwcGVyY2FzZSBwcmVmaXgnIH0sXG4gICAgICB7IGhleDogJzB4QUJDREVGJywgbGVuZ3RoOiA2LCB2YWxpZDogdHJ1ZSwgZGVzY3JpcHRpb246ICd1cHBlcmNhc2UnIH0sXG4gICAgICB7IGhleDogJzB4QWJDZEVmJywgbGVuZ3RoOiA2LCB2YWxpZDogdHJ1ZSwgZGVzY3JpcHRpb246ICdtaXhlZCBjYXNlJyB9LFxuICAgICAgeyBoZXg6ICcweGFiY2QnLCBsZW5ndGg6IDYsIHZhbGlkOiBmYWxzZSwgZGVzY3JpcHRpb246ICd0b28gc2hvcnQnIH0sXG4gICAgICB7IGhleDogJzB4YWJjZGVmZ2gnLCBsZW5ndGg6IDYsIHZhbGlkOiBmYWxzZSwgZGVzY3JpcHRpb246ICd0b28gbG9uZycgfSxcbiAgICAgIHsgaGV4OiAnYWJjZGVmJywgbGVuZ3RoOiA2LCB2YWxpZDogZmFsc2UsIGRlc2NyaXB0aW9uOiAnbm8gcHJlZml4JyB9LFxuICAgICAgeyBoZXg6ICcweGdoaWprbCcsIGxlbmd0aDogNiwgdmFsaWQ6IGZhbHNlLCBkZXNjcmlwdGlvbjogJ25vbi1oZXggY2hhcnMnIH0sXG4gICAgICB7IGhleDogJzB4YWJjZGVnJywgbGVuZ3RoOiA2LCB2YWxpZDogZmFsc2UsIGRlc2NyaXB0aW9uOiAnaW52YWxpZCBjaGFyIGF0IGVuZCcgfSxcbiAgICBdO1xuXG4gICAgaGV4VGVzdENhc2VzLmZvckVhY2goKHsgaGV4LCBsZW5ndGgsIHZhbGlkLCBkZXNjcmlwdGlvbiB9KSA9PiB7XG4gICAgICBpdChgc2hvdWxkICR7dmFsaWQgPyAnYWNjZXB0JyA6ICdyZWplY3QnfSAke2Rlc2NyaXB0aW9ufWAsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdXRpbHMuaXNWYWxpZEhleChoZXgsIGxlbmd0aCkuc2hvdWxkLmVxdWFsKHZhbGlkKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnQWRkcmVzcyBEZXJpdmF0aW9uIGZyb20gUHVibGljIEtleScsIGZ1bmN0aW9uICgpIHtcbiAgICBpdCgnc2hvdWxkIGdlbmVyYXRlIHZhbGlkIGFkZHJlc3MgZnJvbSBwdWJsaWMga2V5JywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgYWRkcmVzcyA9IHV0aWxzLmdldEFkZHJlc3NGcm9tUHVibGljS2V5KHRlc3REYXRhLnNlbmRlci5wdWJsaWNLZXkpO1xuICAgICAgc2hvdWxkLmV4aXN0KGFkZHJlc3MpO1xuICAgICAgdXRpbHMuaXNWYWxpZEFkZHJlc3MoYWRkcmVzcykuc2hvdWxkLmJlLnRydWUoKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgZ2VuZXJhdGUgY29uc2lzdGVudCBhZGRyZXNzZXMgZnJvbSBzYW1lIGtleScsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGFkZHJlc3MxID0gdXRpbHMuZ2V0QWRkcmVzc0Zyb21QdWJsaWNLZXkodGVzdERhdGEuc2VuZGVyLnB1YmxpY0tleSk7XG4gICAgICBjb25zdCBhZGRyZXNzMiA9IHV0aWxzLmdldEFkZHJlc3NGcm9tUHVibGljS2V5KHRlc3REYXRhLnNlbmRlci5wdWJsaWNLZXkpO1xuICAgICAgYWRkcmVzczEuc2hvdWxkLmVxdWFsKGFkZHJlc3MyKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgZ2VuZXJhdGUgZGlmZmVyZW50IGFkZHJlc3NlcyBmb3IgZGlmZmVyZW50IGtleXMnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBhZGRyZXNzMSA9IHV0aWxzLmdldEFkZHJlc3NGcm9tUHVibGljS2V5KHRlc3REYXRhLnNlbmRlci5wdWJsaWNLZXkpO1xuICAgICAgY29uc3QgYWRkcmVzczIgPSB1dGlscy5nZXRBZGRyZXNzRnJvbVB1YmxpY0tleSh0ZXN0RGF0YS5nYXNTcG9uc29yLnB1YmxpY0tleSk7XG4gICAgICBhZGRyZXNzMS5zaG91bGQubm90LmVxdWFsKGFkZHJlc3MyKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ0Jhc2U2NCBTdHJpbmcgQ29udmVyc2lvbicsIGZ1bmN0aW9uICgpIHtcbiAgICBjb25zdCBjb252ZXJzaW9uVGVzdENhc2VzID0gW1xuICAgICAgeyBpbnB1dDogbmV3IFVpbnQ4QXJyYXkoWzcyLCAxMDEsIDEwOCwgMTA4LCAxMTFdKSwgZGVzY3JpcHRpb246ICdVaW50OEFycmF5IChcIkhlbGxvXCIpJyB9LFxuICAgICAgeyBpbnB1dDogJzQ4NjU2YzZjNmYnLCBkZXNjcmlwdGlvbjogJ2hleCBzdHJpbmcgKFwiSGVsbG9cIiknIH0sXG4gICAgICB7IGlucHV0OiBuZXcgVWludDhBcnJheShbXSksIGRlc2NyaXB0aW9uOiAnZW1wdHkgVWludDhBcnJheScgfSxcbiAgICAgIHsgaW5wdXQ6IG5ldyBVaW50OEFycmF5KEJ1ZmZlci5mcm9tKCdIZWxsbyBXb3JsZCcpKSwgZGVzY3JpcHRpb246ICdCdWZmZXIgYXMgVWludDhBcnJheScgfSxcbiAgICBdO1xuXG4gICAgY29udmVyc2lvblRlc3RDYXNlcy5mb3JFYWNoKCh7IGlucHV0LCBkZXNjcmlwdGlvbiB9KSA9PiB7XG4gICAgICBpdChgc2hvdWxkIGNvbnZlcnQgJHtkZXNjcmlwdGlvbn0gdG8gYmFzZTY0YCwgZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCByZXN1bHQgPSB1dGlscy5nZXRCYXNlNjRTdHJpbmcoaW5wdXQpO1xuICAgICAgICBzaG91bGQuZXhpc3QocmVzdWx0KTtcbiAgICAgICAgc2hvdWxkLmVxdWFsKHR5cGVvZiByZXN1bHQsICdzdHJpbmcnKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBwcm9kdWNlIGNvbnNpc3RlbnQgb3V0cHV0IGZvciBzYW1lIGlucHV0JywgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgdWludDhBcnJheSA9IG5ldyBVaW50OEFycmF5KFsxLCAyLCAzLCA0LCA1XSk7XG4gICAgICBjb25zdCByZXN1bHQxID0gdXRpbHMuZ2V0QmFzZTY0U3RyaW5nKHVpbnQ4QXJyYXkpO1xuICAgICAgY29uc3QgcmVzdWx0MiA9IHV0aWxzLmdldEJhc2U2NFN0cmluZyhuZXcgVWludDhBcnJheShbMSwgMiwgMywgNCwgNV0pKTtcbiAgICAgIHJlc3VsdDEuc2hvdWxkLmVxdWFsKHJlc3VsdDIpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnUmF3IFRyYW5zYWN0aW9uIFZhbGlkYXRpb24nLCBmdW5jdGlvbiAoKSB7XG4gICAgaXQoJ3Nob3VsZCB2YWxpZGF0ZSBwcm9wZXJseSBidWlsdCB0cmFuc2FjdGlvbiAoYmFzZTY0KScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHR4QnVpbGRlciA9IGNyZWF0ZVRyYW5zZmVyQnVpbGRlcldpdGhHYXMoKTtcbiAgICAgIGNvbnN0IHR4ID0gYXdhaXQgdHhCdWlsZGVyLmJ1aWxkKCk7XG4gICAgICBjb25zdCByYXdUeCA9IGF3YWl0IHR4LnRvQnJvYWRjYXN0Rm9ybWF0KCk7XG5cbiAgICAgIHV0aWxzLmlzVmFsaWRSYXdUcmFuc2FjdGlvbihyYXdUeCkuc2hvdWxkLmJlLnRydWUoKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgdmFsaWRhdGUgdHJhbnNhY3Rpb24gYXMgVWludDhBcnJheScsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHR4QnVpbGRlciA9IGNyZWF0ZVRyYW5zZmVyQnVpbGRlcldpdGhHYXMoKTtcbiAgICAgIGNvbnN0IHR4ID0gYXdhaXQgdHhCdWlsZGVyLmJ1aWxkKCk7XG4gICAgICBjb25zdCByYXdUeCA9IGF3YWl0IHR4LnRvQnJvYWRjYXN0Rm9ybWF0KCk7XG4gICAgICBjb25zdCByYXdUeEJ5dGVzID0gQnVmZmVyLmZyb20ocmF3VHgsICdiYXNlNjQnKTtcblxuICAgICAgdXRpbHMuaXNWYWxpZFJhd1RyYW5zYWN0aW9uKHJhd1R4Qnl0ZXMpLnNob3VsZC5iZS50cnVlKCk7XG4gICAgfSk7XG5cbiAgICBjb25zdCBpbnZhbGlkUmF3VHhUZXN0Q2FzZXMgPSBbXG4gICAgICB7IHR4OiAnaW52YWxpZFJhd1R4JywgZGVzY3JpcHRpb246ICdpbnZhbGlkIHN0cmluZycgfSxcbiAgICAgIHsgdHg6ICcnLCBkZXNjcmlwdGlvbjogJ2VtcHR5IHN0cmluZycgfSxcbiAgICAgIHsgdHg6ICcweDEyMzQ1NicsIGRlc2NyaXB0aW9uOiAnaGV4IGZvcm1hdCcgfSxcbiAgICAgIHsgdHg6ICdub3QtYmFzZTY0ISEhJywgZGVzY3JpcHRpb246ICdpbnZhbGlkIGJhc2U2NCcgfSxcbiAgICAgIHsgdHg6IEJ1ZmZlci5mcm9tKCdtYWxmb3JtZWQgZGF0YScpLnRvU3RyaW5nKCdiYXNlNjQnKSwgZGVzY3JpcHRpb246ICdtYWxmb3JtZWQgZGF0YScgfSxcbiAgICBdO1xuXG4gICAgaW52YWxpZFJhd1R4VGVzdENhc2VzLmZvckVhY2goKHsgdHgsIGRlc2NyaXB0aW9uIH0pID0+IHtcbiAgICAgIGl0KGBzaG91bGQgcmVqZWN0ICR7ZGVzY3JpcHRpb259YCwgZnVuY3Rpb24gKCkge1xuICAgICAgICB1dGlscy5pc1ZhbGlkUmF3VHJhbnNhY3Rpb24odHgpLnNob3VsZC5iZS5mYWxzZSgpO1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH0pO1xufSk7XG4iXX0=