@bitgo/sdk-coin-flrp 1.8.0 → 1.9.0

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 (30) hide show
  1. package/dist/src/flrp.d.ts +8 -0
  2. package/dist/src/flrp.d.ts.map +1 -1
  3. package/dist/src/flrp.js +43 -1
  4. package/dist/src/lib/iface.d.ts +12 -2
  5. package/dist/src/lib/iface.d.ts.map +1 -1
  6. package/dist/src/lib/iface.js +1 -1
  7. package/dist/src/lib/index.d.ts +1 -0
  8. package/dist/src/lib/index.d.ts.map +1 -1
  9. package/dist/src/lib/index.js +4 -2
  10. package/dist/src/lib/permissionlessDelegatorTxBuilder.d.ts +108 -0
  11. package/dist/src/lib/permissionlessDelegatorTxBuilder.d.ts.map +1 -0
  12. package/dist/src/lib/permissionlessDelegatorTxBuilder.js +268 -0
  13. package/dist/src/lib/transaction.d.ts.map +1 -1
  14. package/dist/src/lib/transaction.js +30 -8
  15. package/dist/src/lib/transactionBuilderFactory.d.ts +6 -0
  16. package/dist/src/lib/transactionBuilderFactory.d.ts.map +1 -1
  17. package/dist/src/lib/transactionBuilderFactory.js +14 -1
  18. package/dist/src/lib/utils.d.ts +6 -0
  19. package/dist/src/lib/utils.d.ts.map +1 -1
  20. package/dist/src/lib/utils.js +24 -1
  21. package/dist/test/resources/transactionData/delegatorTx.d.ts +83 -0
  22. package/dist/test/resources/transactionData/delegatorTx.d.ts.map +1 -0
  23. package/dist/test/resources/transactionData/delegatorTx.js +77 -0
  24. package/dist/test/unit/flrp.js +72 -1
  25. package/dist/test/unit/lib/permissionlessDelegatorTxBuilder.d.ts +2 -0
  26. package/dist/test/unit/lib/permissionlessDelegatorTxBuilder.d.ts.map +1 -0
  27. package/dist/test/unit/lib/permissionlessDelegatorTxBuilder.js +235 -0
  28. package/dist/test/unit/lib/utils.js +11 -1
  29. package/dist/tsconfig.tsbuildinfo +1 -1
  30. package/package.json +6 -6
@@ -0,0 +1,235 @@
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 assert_1 = __importDefault(require("assert"));
7
+ require("should");
8
+ const statics_1 = require("@bitgo/statics");
9
+ const sdk_core_1 = require("@bitgo/sdk-core");
10
+ const lib_1 = require("../../../src/lib");
11
+ const account_1 = require("../../resources/account");
12
+ const utils_1 = __importDefault(require("../../../src/lib/utils"));
13
+ const delegatorTx_1 = require("../../resources/transactionData/delegatorTx");
14
+ describe('Flrp PermissionlessDelegatorTxBuilder', () => {
15
+ const coinConfig = statics_1.coins.get('tflrp');
16
+ const factory = new lib_1.TransactionBuilderFactory(coinConfig);
17
+ describe('getDelegatorBuilder', () => {
18
+ it('should return a PermissionlessDelegatorTxBuilder instance', () => {
19
+ const builder = factory.getDelegatorBuilder();
20
+ builder.should.be.instanceOf(lib_1.PermissionlessDelegatorTxBuilder);
21
+ });
22
+ });
23
+ describe('validate nodeID', () => {
24
+ it('should fail when nodeID is missing', () => {
25
+ const builder = factory.getDelegatorBuilder();
26
+ assert_1.default.throws(() => {
27
+ builder.nodeID('');
28
+ }, (e) => e.message === 'Invalid transaction: missing nodeID');
29
+ });
30
+ it('should fail when nodeID has invalid prefix', () => {
31
+ const builder = factory.getDelegatorBuilder();
32
+ assert_1.default.throws(() => {
33
+ builder.nodeID('InvalidPrefix-123456789');
34
+ }, (e) => e.message === 'Invalid transaction: invalid NodeID tag');
35
+ });
36
+ it('should accept valid nodeID format', () => {
37
+ const builder = factory.getDelegatorBuilder();
38
+ const validNodeID = 'NodeID-AK7sPBsZM9rQwse23aLhEEBPHZD5gkLrL';
39
+ (() => builder.nodeID(validNodeID)).should.not.throw();
40
+ });
41
+ });
42
+ describe('validate stake duration', () => {
43
+ it('should fail when end time is less than start time', () => {
44
+ const builder = factory.getDelegatorBuilder();
45
+ const startTime = BigInt(Math.floor(Date.now() / 1000) + 60);
46
+ const endTime = BigInt(Math.floor(Date.now() / 1000) - 60);
47
+ builder.startTime(startTime.toString());
48
+ builder.endTime(endTime.toString());
49
+ // The validation happens in buildFlareTransaction, but we can test validateStakeDuration directly
50
+ assert_1.default.throws(() => {
51
+ builder.validateStakeDuration(startTime, endTime);
52
+ }, (e) => e.message === 'End date cannot be less than start date');
53
+ });
54
+ it('should accept valid stake duration', () => {
55
+ const builder = factory.getDelegatorBuilder();
56
+ const startTime = BigInt(Math.floor(Date.now() / 1000) + 60);
57
+ const endTime = BigInt(Math.floor(Date.now() / 1000) + 86400 * 14); // 14 days later
58
+ (() => {
59
+ builder.validateStakeDuration(startTime, endTime);
60
+ }).should.not.throw();
61
+ });
62
+ });
63
+ describe('builder methods', () => {
64
+ it('should set startTime correctly', () => {
65
+ const builder = factory.getDelegatorBuilder();
66
+ const startTime = Math.floor(Date.now() / 1000) + 60;
67
+ (() => builder.startTime(startTime)).should.not.throw();
68
+ });
69
+ it('should set endTime correctly', () => {
70
+ const builder = factory.getDelegatorBuilder();
71
+ const endTime = Math.floor(Date.now() / 1000) + 86400 * 14;
72
+ (() => builder.endTime(endTime)).should.not.throw();
73
+ });
74
+ it('should set rewardAddress with P-chain address', () => {
75
+ const builder = factory.getDelegatorBuilder();
76
+ // P-chain Bech32 address
77
+ (() => builder.rewardAddress(account_1.SEED_ACCOUNT.addressTestnet)).should.not.throw();
78
+ });
79
+ });
80
+ describe('build validation', () => {
81
+ it('should fail build when nodeID is not set', async () => {
82
+ const builder = factory.getDelegatorBuilder();
83
+ const now = Math.floor(Date.now() / 1000);
84
+ builder
85
+ .startTime(now + 60)
86
+ .endTime(now + 86400 * 14)
87
+ .stakeAmount(BigInt(50000 * 1e9))
88
+ .fromPubKey([account_1.SEED_ACCOUNT.addressTestnet, account_1.ACCOUNT_1.addressTestnet])
89
+ .context(account_1.CONTEXT);
90
+ await builder.build().should.be.rejectedWith('NodeID is required for delegation');
91
+ });
92
+ it('should fail build when start time is not set', async () => {
93
+ const builder = factory.getDelegatorBuilder();
94
+ const now = Math.floor(Date.now() / 1000);
95
+ const validNodeID = 'NodeID-AK7sPBsZM9rQwse23aLhEEBPHZD5gkLrL';
96
+ builder
97
+ .nodeID(validNodeID)
98
+ .endTime(now + 86400 * 14)
99
+ .stakeAmount(BigInt(50000 * 1e9))
100
+ .fromPubKey([account_1.SEED_ACCOUNT.addressTestnet, account_1.ACCOUNT_1.addressTestnet])
101
+ .context(account_1.CONTEXT);
102
+ await builder.build().should.be.rejectedWith('Start time is required for delegation');
103
+ });
104
+ it('should fail build when end time is not set', async () => {
105
+ const builder = factory.getDelegatorBuilder();
106
+ const now = Math.floor(Date.now() / 1000);
107
+ const validNodeID = 'NodeID-AK7sPBsZM9rQwse23aLhEEBPHZD5gkLrL';
108
+ builder
109
+ .nodeID(validNodeID)
110
+ .startTime(now + 60)
111
+ .stakeAmount(BigInt(50000 * 1e9))
112
+ .fromPubKey([account_1.SEED_ACCOUNT.addressTestnet, account_1.ACCOUNT_1.addressTestnet])
113
+ .context(account_1.CONTEXT);
114
+ await builder.build().should.be.rejectedWith('End time is required for delegation');
115
+ });
116
+ it('should fail build when stake amount is not set', async () => {
117
+ const builder = factory.getDelegatorBuilder();
118
+ const now = Math.floor(Date.now() / 1000);
119
+ const validNodeID = 'NodeID-AK7sPBsZM9rQwse23aLhEEBPHZD5gkLrL';
120
+ builder
121
+ .nodeID(validNodeID)
122
+ .startTime(now + 60)
123
+ .endTime(now + 86400 * 14)
124
+ .fromPubKey([account_1.SEED_ACCOUNT.addressTestnet, account_1.ACCOUNT_1.addressTestnet])
125
+ .context(account_1.CONTEXT);
126
+ await builder.build().should.be.rejectedWith('Stake amount is required for delegation');
127
+ });
128
+ it('should fail build when context is not set', async () => {
129
+ const builder = factory.getDelegatorBuilder();
130
+ const now = Math.floor(Date.now() / 1000);
131
+ const validNodeID = 'NodeID-AK7sPBsZM9rQwse23aLhEEBPHZD5gkLrL';
132
+ builder
133
+ .nodeID(validNodeID)
134
+ .startTime(now + 60)
135
+ .endTime(now + 86400 * 14)
136
+ .stakeAmount(BigInt(50000 * 1e9))
137
+ .fromPubKey([account_1.SEED_ACCOUNT.addressTestnet, account_1.ACCOUNT_1.addressTestnet]);
138
+ await builder.build().should.be.rejectedWith('Context is required for delegation');
139
+ });
140
+ it('should fail build when from addresses are not set', async () => {
141
+ const builder = factory.getDelegatorBuilder();
142
+ const now = Math.floor(Date.now() / 1000);
143
+ const validNodeID = 'NodeID-AK7sPBsZM9rQwse23aLhEEBPHZD5gkLrL';
144
+ builder
145
+ .nodeID(validNodeID)
146
+ .startTime(now + 60)
147
+ .endTime(now + 86400 * 14)
148
+ .stakeAmount(BigInt(50000 * 1e9))
149
+ .context(account_1.CONTEXT);
150
+ await builder.build().should.be.rejectedWith('From addresses are required for delegation');
151
+ });
152
+ it('should fail build when fee state is not set', async () => {
153
+ const builder = factory.getDelegatorBuilder();
154
+ const now = Math.floor(Date.now() / 1000);
155
+ const validNodeID = 'NodeID-AK7sPBsZM9rQwse23aLhEEBPHZD5gkLrL';
156
+ builder
157
+ .nodeID(validNodeID)
158
+ .startTime(now + 60)
159
+ .endTime(now + 86400 * 14)
160
+ .stakeAmount(BigInt(50000 * 1e9))
161
+ .fromPubKey([account_1.SEED_ACCOUNT.addressTestnet, account_1.ACCOUNT_1.addressTestnet])
162
+ .context(account_1.CONTEXT);
163
+ await builder.build().should.be.rejectedWith('Fee state is required for delegation');
164
+ });
165
+ it('should fail build when UTXOs are not set', async () => {
166
+ const builder = factory.getDelegatorBuilder();
167
+ const now = Math.floor(Date.now() / 1000);
168
+ const validNodeID = 'NodeID-AK7sPBsZM9rQwse23aLhEEBPHZD5gkLrL';
169
+ const mockFeeState = { capacity: 100000n, excess: 0n, price: 1000n, timestamp: '1234567890' };
170
+ builder
171
+ .nodeID(validNodeID)
172
+ .startTime(now + 60)
173
+ .endTime(now + 86400 * 14)
174
+ .stakeAmount(BigInt(50000 * 1e9))
175
+ .fromPubKey([account_1.SEED_ACCOUNT.addressTestnet, account_1.ACCOUNT_1.addressTestnet])
176
+ .context(account_1.CONTEXT)
177
+ .feeState(mockFeeState);
178
+ await builder.build().should.be.rejectedWith('UTXOs are required for delegation');
179
+ });
180
+ });
181
+ describe('validate stake amount', () => {
182
+ it('should fail when stake amount is below minimum', () => {
183
+ const builder = factory.getDelegatorBuilder();
184
+ // Minimum is 50000 FLR, so 1000 should fail
185
+ assert_1.default.throws(() => {
186
+ builder.stakeAmount(BigInt(1000 * 1e9));
187
+ }, (e) => e.message.includes('Minimum delegation amount'));
188
+ });
189
+ it('should accept stake amount at or above minimum', () => {
190
+ const builder = factory.getDelegatorBuilder();
191
+ const stakeAmount = BigInt(50000 * 1e9);
192
+ (() => builder.stakeAmount(stakeAmount)).should.not.throw();
193
+ });
194
+ });
195
+ describe('transaction type support', () => {
196
+ it('should allow setting AddPermissionlessDelegator transaction type', () => {
197
+ const builder = factory.getDelegatorBuilder();
198
+ // The builder should successfully configure with AddPermissionlessDelegator type
199
+ // This verifies transaction.ts setTransactionType accepts the delegation type
200
+ builder.should.be.instanceof(lib_1.PermissionlessDelegatorTxBuilder);
201
+ });
202
+ it('should have correct minimum stake amount constant', () => {
203
+ // Verify the minimum stake amount is 50000 FLR (in nanoFLR)
204
+ const minStakeAmount = BigInt(50000 * 1e9);
205
+ minStakeAmount.should.equal(BigInt('50000000000000'));
206
+ });
207
+ });
208
+ describe('round-trip deserialization', () => {
209
+ it('should deserialize a signed delegation transaction from hex', async () => {
210
+ const rawTx = utils_1.default.removeHexPrefix(delegatorTx_1.DELEGATION_TX_2.signedHex);
211
+ const tx = (await factory.from(rawTx).build());
212
+ tx.type.should.equal(sdk_core_1.TransactionType.AddPermissionlessDelegator);
213
+ });
214
+ it('should correctly extract delegation parameters from deserialized transaction', async () => {
215
+ const rawTx = utils_1.default.removeHexPrefix(delegatorTx_1.DELEGATION_TX_2.signedHex);
216
+ const tx = (await factory.from(rawTx).build());
217
+ const explanation = tx.explainTransaction();
218
+ explanation.outputs.length.should.be.above(0);
219
+ explanation.outputAmount.should.equal(delegatorTx_1.DELEGATION_TX_2.stakeAmount);
220
+ });
221
+ it('should re-serialize to the same hex (round-trip)', async () => {
222
+ const rawTx = utils_1.default.removeHexPrefix(delegatorTx_1.DELEGATION_TX_2.signedHex);
223
+ const tx = (await factory.from(rawTx).build());
224
+ const reEncodedTx = utils_1.default.removeHexPrefix(tx.toBroadcastFormat());
225
+ reEncodedTx.should.equal(rawTx);
226
+ });
227
+ it('should have correct input/output counts', async () => {
228
+ const rawTx = utils_1.default.removeHexPrefix(delegatorTx_1.DELEGATION_TX_2.signedHex);
229
+ const tx = (await factory.from(rawTx).build());
230
+ tx.inputs.should.have.length(3);
231
+ tx.outputs.length.should.be.above(0);
232
+ });
233
+ });
234
+ });
235
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGVybWlzc2lvbmxlc3NEZWxlZ2F0b3JUeEJ1aWxkZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi90ZXN0L3VuaXQvbGliL3Blcm1pc3Npb25sZXNzRGVsZWdhdG9yVHhCdWlsZGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBQUEsb0RBQTRCO0FBQzVCLGtCQUFnQjtBQUNoQiw0Q0FBdUM7QUFDdkMsOENBQWtEO0FBQ2xELDBDQUE0RztBQUM1RyxxREFBMkU7QUFDM0UsbUVBQTJDO0FBQzNDLDZFQUE4RTtBQUU5RSxRQUFRLENBQUMsdUNBQXVDLEVBQUUsR0FBRyxFQUFFO0lBQ3JELE1BQU0sVUFBVSxHQUFHLGVBQUssQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFDLENBQUM7SUFDdEMsTUFBTSxPQUFPLEdBQUcsSUFBSSwrQkFBeUIsQ0FBQyxVQUFVLENBQUMsQ0FBQztJQUUxRCxRQUFRLENBQUMscUJBQXFCLEVBQUUsR0FBRyxFQUFFO1FBQ25DLEVBQUUsQ0FBQywyREFBMkQsRUFBRSxHQUFHLEVBQUU7WUFDbkUsTUFBTSxPQUFPLEdBQUcsT0FBTyxDQUFDLG1CQUFtQixFQUFFLENBQUM7WUFDOUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsVUFBVSxDQUFDLHNDQUFnQyxDQUFDLENBQUM7UUFDakUsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztJQUVILFFBQVEsQ0FBQyxpQkFBaUIsRUFBRSxHQUFHLEVBQUU7UUFDL0IsRUFBRSxDQUFDLG9DQUFvQyxFQUFFLEdBQUcsRUFBRTtZQUM1QyxNQUFNLE9BQU8sR0FBRyxPQUFPLENBQUMsbUJBQW1CLEVBQUUsQ0FBQztZQUM5QyxnQkFBTSxDQUFDLE1BQU0sQ0FDWCxHQUFHLEVBQUU7Z0JBQ0gsT0FBTyxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsQ0FBQztZQUNyQixDQUFDLEVBQ0QsQ0FBQyxDQUFNLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxPQUFPLEtBQUsscUNBQXFDLENBQ2hFLENBQUM7UUFDSixDQUFDLENBQUMsQ0FBQztRQUVILEVBQUUsQ0FBQyw0Q0FBNEMsRUFBRSxHQUFHLEVBQUU7WUFDcEQsTUFBTSxPQUFPLEdBQUcsT0FBTyxDQUFDLG1CQUFtQixFQUFFLENBQUM7WUFDOUMsZ0JBQU0sQ0FBQyxNQUFNLENBQ1gsR0FBRyxFQUFFO2dCQUNILE9BQU8sQ0FBQyxNQUFNLENBQUMseUJBQXlCLENBQUMsQ0FBQztZQUM1QyxDQUFDLEVBQ0QsQ0FBQyxDQUFNLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxPQUFPLEtBQUsseUNBQXlDLENBQ3BFLENBQUM7UUFDSixDQUFDLENBQUMsQ0FBQztRQUVILEVBQUUsQ0FBQyxtQ0FBbUMsRUFBRSxHQUFHLEVBQUU7WUFDM0MsTUFBTSxPQUFPLEdBQUcsT0FBTyxDQUFDLG1CQUFtQixFQUFFLENBQUM7WUFDOUMsTUFBTSxXQUFXLEdBQUcsMENBQTBDLENBQUM7WUFDL0QsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxLQUFLLEVBQUUsQ0FBQztRQUN6RCxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQyxDQUFDO0lBRUgsUUFBUSxDQUFDLHlCQUF5QixFQUFFLEdBQUcsRUFBRTtRQUN2QyxFQUFFLENBQUMsbURBQW1ELEVBQUUsR0FBRyxFQUFFO1lBQzNELE1BQU0sT0FBTyxHQUFHLE9BQU8sQ0FBQyxtQkFBbUIsRUFBRSxDQUFDO1lBQzlDLE1BQU0sU0FBUyxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxHQUFHLEVBQUUsR0FBRyxJQUFJLENBQUMsR0FBRyxFQUFFLENBQUMsQ0FBQztZQUM3RCxNQUFNLE9BQU8sR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsR0FBRyxFQUFFLEdBQUcsSUFBSSxDQUFDLEdBQUcsRUFBRSxDQUFDLENBQUM7WUFFM0QsT0FBTyxDQUFDLFNBQVMsQ0FBQyxTQUFTLENBQUMsUUFBUSxFQUFFLENBQUMsQ0FBQztZQUN4QyxPQUFPLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxRQUFRLEVBQUUsQ0FBQyxDQUFDO1lBRXBDLGtHQUFrRztZQUNsRyxnQkFBTSxDQUFDLE1BQU0sQ0FDWCxHQUFHLEVBQUU7Z0JBQ0gsT0FBTyxDQUFDLHFCQUFxQixDQUFDLFNBQVMsRUFBRSxPQUFPLENBQUMsQ0FBQztZQUNwRCxDQUFDLEVBQ0QsQ0FBQyxDQUFNLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxPQUFPLEtBQUsseUNBQXlDLENBQ3BFLENBQUM7UUFDSixDQUFDLENBQUMsQ0FBQztRQUVILEVBQUUsQ0FBQyxvQ0FBb0MsRUFBRSxHQUFHLEVBQUU7WUFDNUMsTUFBTSxPQUFPLEdBQUcsT0FBTyxDQUFDLG1CQUFtQixFQUFFLENBQUM7WUFDOUMsTUFBTSxTQUFTLEdBQUcsTUFBTSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLEdBQUcsRUFBRSxHQUFHLElBQUksQ0FBQyxHQUFHLEVBQUUsQ0FBQyxDQUFDO1lBQzdELE1BQU0sT0FBTyxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxHQUFHLEVBQUUsR0FBRyxJQUFJLENBQUMsR0FBRyxLQUFLLEdBQUcsRUFBRSxDQUFDLENBQUMsQ0FBQyxnQkFBZ0I7WUFFcEYsQ0FBQyxHQUFHLEVBQUU7Z0JBQ0osT0FBTyxDQUFDLHFCQUFxQixDQUFDLFNBQVMsRUFBRSxPQUFPLENBQUMsQ0FBQztZQUNwRCxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLEtBQUssRUFBRSxDQUFDO1FBQ3hCLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQyxDQUFDLENBQUM7SUFFSCxRQUFRLENBQUMsaUJBQWlCLEVBQUUsR0FBRyxFQUFFO1FBQy9CLEVBQUUsQ0FBQyxnQ0FBZ0MsRUFBRSxHQUFHLEVBQUU7WUFDeEMsTUFBTSxPQUFPLEdBQUcsT0FBTyxDQUFDLG1CQUFtQixFQUFFLENBQUM7WUFDOUMsTUFBTSxTQUFTLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsR0FBRyxFQUFFLEdBQUcsSUFBSSxDQUFDLEdBQUcsRUFBRSxDQUFDO1lBQ3JELENBQUMsR0FBRyxFQUFFLENBQUMsT0FBTyxDQUFDLFNBQVMsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsS0FBSyxFQUFFLENBQUM7UUFDMUQsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsOEJBQThCLEVBQUUsR0FBRyxFQUFFO1lBQ3RDLE1BQU0sT0FBTyxHQUFHLE9BQU8sQ0FBQyxtQkFBbUIsRUFBRSxDQUFDO1lBQzlDLE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLEdBQUcsRUFBRSxHQUFHLElBQUksQ0FBQyxHQUFHLEtBQUssR0FBRyxFQUFFLENBQUM7WUFDM0QsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxLQUFLLEVBQUUsQ0FBQztRQUN0RCxDQUFDLENBQUMsQ0FBQztRQUVILEVBQUUsQ0FBQywrQ0FBK0MsRUFBRSxHQUFHLEVBQUU7WUFDdkQsTUFBTSxPQUFPLEdBQUcsT0FBTyxDQUFDLG1CQUFtQixFQUFFLENBQUM7WUFDOUMseUJBQXlCO1lBQ3pCLENBQUMsR0FBRyxFQUFFLENBQUMsT0FBTyxDQUFDLGFBQWEsQ0FBQyxzQkFBWSxDQUFDLGNBQWMsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxLQUFLLEVBQUUsQ0FBQztRQUNoRixDQUFDLENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQyxDQUFDO0lBRUgsUUFBUSxDQUFDLGtCQUFrQixFQUFFLEdBQUcsRUFBRTtRQUNoQyxFQUFFLENBQUMsMENBQTBDLEVBQUUsS0FBSyxJQUFJLEVBQUU7WUFDeEQsTUFBTSxPQUFPLEdBQUcsT0FBTyxDQUFDLG1CQUFtQixFQUFFLENBQUM7WUFDOUMsTUFBTSxHQUFHLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsR0FBRyxFQUFFLEdBQUcsSUFBSSxDQUFDLENBQUM7WUFFMUMsT0FBTztpQkFDSixTQUFTLENBQUMsR0FBRyxHQUFHLEVBQUUsQ0FBQztpQkFDbkIsT0FBTyxDQUFDLEdBQUcsR0FBRyxLQUFLLEdBQUcsRUFBRSxDQUFDO2lCQUN6QixXQUFXLENBQUMsTUFBTSxDQUFDLEtBQUssR0FBRyxHQUFHLENBQUMsQ0FBQztpQkFDaEMsVUFBVSxDQUFDLENBQUMsc0JBQVksQ0FBQyxjQUFjLEVBQUUsbUJBQVMsQ0FBQyxjQUFjLENBQUMsQ0FBQztpQkFDbkUsT0FBTyxDQUFDLGlCQUFjLENBQUMsQ0FBQztZQUUzQixNQUFNLE9BQU8sQ0FBQyxLQUFLLEVBQUUsQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLFlBQVksQ0FBQyxtQ0FBbUMsQ0FBQyxDQUFDO1FBQ3BGLENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLDhDQUE4QyxFQUFFLEtBQUssSUFBSSxFQUFFO1lBQzVELE1BQU0sT0FBTyxHQUFHLE9BQU8sQ0FBQyxtQkFBbUIsRUFBRSxDQUFDO1lBQzlDLE1BQU0sR0FBRyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLEdBQUcsRUFBRSxHQUFHLElBQUksQ0FBQyxDQUFDO1lBQzFDLE1BQU0sV0FBVyxHQUFHLDBDQUEwQyxDQUFDO1lBRS9ELE9BQU87aUJBQ0osTUFBTSxDQUFDLFdBQVcsQ0FBQztpQkFDbkIsT0FBTyxDQUFDLEdBQUcsR0FBRyxLQUFLLEdBQUcsRUFBRSxDQUFDO2lCQUN6QixXQUFXLENBQUMsTUFBTSxDQUFDLEtBQUssR0FBRyxHQUFHLENBQUMsQ0FBQztpQkFDaEMsVUFBVSxDQUFDLENBQUMsc0JBQVksQ0FBQyxjQUFjLEVBQUUsbUJBQVMsQ0FBQyxjQUFjLENBQUMsQ0FBQztpQkFDbkUsT0FBTyxDQUFDLGlCQUFjLENBQUMsQ0FBQztZQUUzQixNQUFNLE9BQU8sQ0FBQyxLQUFLLEVBQUUsQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLFlBQVksQ0FBQyx1Q0FBdUMsQ0FBQyxDQUFDO1FBQ3hGLENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLDRDQUE0QyxFQUFFLEtBQUssSUFBSSxFQUFFO1lBQzFELE1BQU0sT0FBTyxHQUFHLE9BQU8sQ0FBQyxtQkFBbUIsRUFBRSxDQUFDO1lBQzlDLE1BQU0sR0FBRyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLEdBQUcsRUFBRSxHQUFHLElBQUksQ0FBQyxDQUFDO1lBQzFDLE1BQU0sV0FBVyxHQUFHLDBDQUEwQyxDQUFDO1lBRS9ELE9BQU87aUJBQ0osTUFBTSxDQUFDLFdBQVcsQ0FBQztpQkFDbkIsU0FBUyxDQUFDLEdBQUcsR0FBRyxFQUFFLENBQUM7aUJBQ25CLFdBQVcsQ0FBQyxNQUFNLENBQUMsS0FBSyxHQUFHLEdBQUcsQ0FBQyxDQUFDO2lCQUNoQyxVQUFVLENBQUMsQ0FBQyxzQkFBWSxDQUFDLGNBQWMsRUFBRSxtQkFBUyxDQUFDLGNBQWMsQ0FBQyxDQUFDO2lCQUNuRSxPQUFPLENBQUMsaUJBQWMsQ0FBQyxDQUFDO1lBRTNCLE1BQU0sT0FBTyxDQUFDLEtBQUssRUFBRSxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsWUFBWSxDQUFDLHFDQUFxQyxDQUFDLENBQUM7UUFDdEYsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsZ0RBQWdELEVBQUUsS0FBSyxJQUFJLEVBQUU7WUFDOUQsTUFBTSxPQUFPLEdBQUcsT0FBTyxDQUFDLG1CQUFtQixFQUFFLENBQUM7WUFDOUMsTUFBTSxHQUFHLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsR0FBRyxFQUFFLEdBQUcsSUFBSSxDQUFDLENBQUM7WUFDMUMsTUFBTSxXQUFXLEdBQUcsMENBQTBDLENBQUM7WUFFL0QsT0FBTztpQkFDSixNQUFNLENBQUMsV0FBVyxDQUFDO2lCQUNuQixTQUFTLENBQUMsR0FBRyxHQUFHLEVBQUUsQ0FBQztpQkFDbkIsT0FBTyxDQUFDLEdBQUcsR0FBRyxLQUFLLEdBQUcsRUFBRSxDQUFDO2lCQUN6QixVQUFVLENBQUMsQ0FBQyxzQkFBWSxDQUFDLGNBQWMsRUFBRSxtQkFBUyxDQUFDLGNBQWMsQ0FBQyxDQUFDO2lCQUNuRSxPQUFPLENBQUMsaUJBQWMsQ0FBQyxDQUFDO1lBRTNCLE1BQU0sT0FBTyxDQUFDLEtBQUssRUFBRSxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsWUFBWSxDQUFDLHlDQUF5QyxDQUFDLENBQUM7UUFDMUYsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsMkNBQTJDLEVBQUUsS0FBSyxJQUFJLEVBQUU7WUFDekQsTUFBTSxPQUFPLEdBQUcsT0FBTyxDQUFDLG1CQUFtQixFQUFFLENBQUM7WUFDOUMsTUFBTSxHQUFHLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsR0FBRyxFQUFFLEdBQUcsSUFBSSxDQUFDLENBQUM7WUFDMUMsTUFBTSxXQUFXLEdBQUcsMENBQTBDLENBQUM7WUFFL0QsT0FBTztpQkFDSixNQUFNLENBQUMsV0FBVyxDQUFDO2lCQUNuQixTQUFTLENBQUMsR0FBRyxHQUFHLEVBQUUsQ0FBQztpQkFDbkIsT0FBTyxDQUFDLEdBQUcsR0FBRyxLQUFLLEdBQUcsRUFBRSxDQUFDO2lCQUN6QixXQUFXLENBQUMsTUFBTSxDQUFDLEtBQUssR0FBRyxHQUFHLENBQUMsQ0FBQztpQkFDaEMsVUFBVSxDQUFDLENBQUMsc0JBQVksQ0FBQyxjQUFjLEVBQUUsbUJBQVMsQ0FBQyxjQUFjLENBQUMsQ0FBQyxDQUFDO1lBRXZFLE1BQU0sT0FBTyxDQUFDLEtBQUssRUFBRSxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsWUFBWSxDQUFDLG9DQUFvQyxDQUFDLENBQUM7UUFDckYsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsbURBQW1ELEVBQUUsS0FBSyxJQUFJLEVBQUU7WUFDakUsTUFBTSxPQUFPLEdBQUcsT0FBTyxDQUFDLG1CQUFtQixFQUFFLENBQUM7WUFDOUMsTUFBTSxHQUFHLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsR0FBRyxFQUFFLEdBQUcsSUFBSSxDQUFDLENBQUM7WUFDMUMsTUFBTSxXQUFXLEdBQUcsMENBQTBDLENBQUM7WUFFL0QsT0FBTztpQkFDSixNQUFNLENBQUMsV0FBVyxDQUFDO2lCQUNuQixTQUFTLENBQUMsR0FBRyxHQUFHLEVBQUUsQ0FBQztpQkFDbkIsT0FBTyxDQUFDLEdBQUcsR0FBRyxLQUFLLEdBQUcsRUFBRSxDQUFDO2lCQUN6QixXQUFXLENBQUMsTUFBTSxDQUFDLEtBQUssR0FBRyxHQUFHLENBQUMsQ0FBQztpQkFDaEMsT0FBTyxDQUFDLGlCQUFjLENBQUMsQ0FBQztZQUUzQixNQUFNLE9BQU8sQ0FBQyxLQUFLLEVBQUUsQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLFlBQVksQ0FBQyw0Q0FBNEMsQ0FBQyxDQUFDO1FBQzdGLENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLDZDQUE2QyxFQUFFLEtBQUssSUFBSSxFQUFFO1lBQzNELE1BQU0sT0FBTyxHQUFHLE9BQU8sQ0FBQyxtQkFBbUIsRUFBRSxDQUFDO1lBQzlDLE1BQU0sR0FBRyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLEdBQUcsRUFBRSxHQUFHLElBQUksQ0FBQyxDQUFDO1lBQzFDLE1BQU0sV0FBVyxHQUFHLDBDQUEwQyxDQUFDO1lBRS9ELE9BQU87aUJBQ0osTUFBTSxDQUFDLFdBQVcsQ0FBQztpQkFDbkIsU0FBUyxDQUFDLEdBQUcsR0FBRyxFQUFFLENBQUM7aUJBQ25CLE9BQU8sQ0FBQyxHQUFHLEdBQUcsS0FBSyxHQUFHLEVBQUUsQ0FBQztpQkFDekIsV0FBVyxDQUFDLE1BQU0sQ0FBQyxLQUFLLEdBQUcsR0FBRyxDQUFDLENBQUM7aUJBQ2hDLFVBQVUsQ0FBQyxDQUFDLHNCQUFZLENBQUMsY0FBYyxFQUFFLG1CQUFTLENBQUMsY0FBYyxDQUFDLENBQUM7aUJBQ25FLE9BQU8sQ0FBQyxpQkFBYyxDQUFDLENBQUM7WUFFM0IsTUFBTSxPQUFPLENBQUMsS0FBSyxFQUFFLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxZQUFZLENBQUMsc0NBQXNDLENBQUMsQ0FBQztRQUN2RixDQUFDLENBQUMsQ0FBQztRQUVILEVBQUUsQ0FBQywwQ0FBMEMsRUFBRSxLQUFLLElBQUksRUFBRTtZQUN4RCxNQUFNLE9BQU8sR0FBRyxPQUFPLENBQUMsbUJBQW1CLEVBQUUsQ0FBQztZQUM5QyxNQUFNLEdBQUcsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxHQUFHLEVBQUUsR0FBRyxJQUFJLENBQUMsQ0FBQztZQUMxQyxNQUFNLFdBQVcsR0FBRywwQ0FBMEMsQ0FBQztZQUMvRCxNQUFNLFlBQVksR0FBRyxFQUFFLFFBQVEsRUFBRSxPQUFPLEVBQUUsTUFBTSxFQUFFLEVBQUUsRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLFNBQVMsRUFBRSxZQUFZLEVBQUUsQ0FBQztZQUU5RixPQUFPO2lCQUNKLE1BQU0sQ0FBQyxXQUFXLENBQUM7aUJBQ25CLFNBQVMsQ0FBQyxHQUFHLEdBQUcsRUFBRSxDQUFDO2lCQUNuQixPQUFPLENBQUMsR0FBRyxHQUFHLEtBQUssR0FBRyxFQUFFLENBQUM7aUJBQ3pCLFdBQVcsQ0FBQyxNQUFNLENBQUMsS0FBSyxHQUFHLEdBQUcsQ0FBQyxDQUFDO2lCQUNoQyxVQUFVLENBQUMsQ0FBQyxzQkFBWSxDQUFDLGNBQWMsRUFBRSxtQkFBUyxDQUFDLGNBQWMsQ0FBQyxDQUFDO2lCQUNuRSxPQUFPLENBQUMsaUJBQWMsQ0FBQztpQkFDdkIsUUFBUSxDQUFDLFlBQVksQ0FBQyxDQUFDO1lBRTFCLE1BQU0sT0FBTyxDQUFDLEtBQUssRUFBRSxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsWUFBWSxDQUFDLG1DQUFtQyxDQUFDLENBQUM7UUFDcEYsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztJQUVILFFBQVEsQ0FBQyx1QkFBdUIsRUFBRSxHQUFHLEVBQUU7UUFDckMsRUFBRSxDQUFDLGdEQUFnRCxFQUFFLEdBQUcsRUFBRTtZQUN4RCxNQUFNLE9BQU8sR0FBRyxPQUFPLENBQUMsbUJBQW1CLEVBQUUsQ0FBQztZQUM5Qyw0Q0FBNEM7WUFDNUMsZ0JBQU0sQ0FBQyxNQUFNLENBQ1gsR0FBRyxFQUFFO2dCQUNILE9BQU8sQ0FBQyxXQUFXLENBQUMsTUFBTSxDQUFDLElBQUksR0FBRyxHQUFHLENBQUMsQ0FBQyxDQUFDO1lBQzFDLENBQUMsRUFDRCxDQUFDLENBQU0sRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUMsMkJBQTJCLENBQUMsQ0FDNUQsQ0FBQztRQUNKLENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLGdEQUFnRCxFQUFFLEdBQUcsRUFBRTtZQUN4RCxNQUFNLE9BQU8sR0FBRyxPQUFPLENBQUMsbUJBQW1CLEVBQUUsQ0FBQztZQUM5QyxNQUFNLFdBQVcsR0FBRyxNQUFNLENBQUMsS0FBSyxHQUFHLEdBQUcsQ0FBQyxDQUFDO1lBQ3hDLENBQUMsR0FBRyxFQUFFLENBQUMsT0FBTyxDQUFDLFdBQVcsQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsS0FBSyxFQUFFLENBQUM7UUFDOUQsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztJQUVILFFBQVEsQ0FBQywwQkFBMEIsRUFBRSxHQUFHLEVBQUU7UUFDeEMsRUFBRSxDQUFDLGtFQUFrRSxFQUFFLEdBQUcsRUFBRTtZQUMxRSxNQUFNLE9BQU8sR0FBRyxPQUFPLENBQUMsbUJBQW1CLEVBQUUsQ0FBQztZQUM5QyxpRkFBaUY7WUFDakYsOEVBQThFO1lBQzlFLE9BQU8sQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLFVBQVUsQ0FBQyxzQ0FBZ0MsQ0FBQyxDQUFDO1FBQ2pFLENBQUMsQ0FBQyxDQUFDO1FBRUgsRUFBRSxDQUFDLG1EQUFtRCxFQUFFLEdBQUcsRUFBRTtZQUMzRCw0REFBNEQ7WUFDNUQsTUFBTSxjQUFjLEdBQUcsTUFBTSxDQUFDLEtBQUssR0FBRyxHQUFHLENBQUMsQ0FBQztZQUMzQyxjQUFjLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsZ0JBQWdCLENBQUMsQ0FBQyxDQUFDO1FBQ3hELENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQyxDQUFDLENBQUM7SUFFSCxRQUFRLENBQUMsNEJBQTRCLEVBQUUsR0FBRyxFQUFFO1FBQzFDLEVBQUUsQ0FBQyw2REFBNkQsRUFBRSxLQUFLLElBQUksRUFBRTtZQUMzRSxNQUFNLEtBQUssR0FBRyxlQUFLLENBQUMsZUFBZSxDQUFDLDZCQUFlLENBQUMsU0FBUyxDQUFDLENBQUM7WUFDL0QsTUFBTSxFQUFFLEdBQUcsQ0FBQyxNQUFNLE9BQU8sQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsS0FBSyxFQUFFLENBQWdCLENBQUM7WUFDOUQsRUFBRSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLDBCQUFlLENBQUMsMEJBQTBCLENBQUMsQ0FBQztRQUNuRSxDQUFDLENBQUMsQ0FBQztRQUVILEVBQUUsQ0FBQyw4RUFBOEUsRUFBRSxLQUFLLElBQUksRUFBRTtZQUM1RixNQUFNLEtBQUssR0FBRyxlQUFLLENBQUMsZUFBZSxDQUFDLDZCQUFlLENBQUMsU0FBUyxDQUFDLENBQUM7WUFDL0QsTUFBTSxFQUFFLEdBQUcsQ0FBQyxNQUFNLE9BQU8sQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsS0FBSyxFQUFFLENBQWdCLENBQUM7WUFDOUQsTUFBTSxXQUFXLEdBQUcsRUFBRSxDQUFDLGtCQUFrQixFQUFFLENBQUM7WUFDNUMsV0FBVyxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDOUMsV0FBVyxDQUFDLFlBQVksQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLDZCQUFlLENBQUMsV0FBVyxDQUFDLENBQUM7UUFDckUsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsa0RBQWtELEVBQUUsS0FBSyxJQUFJLEVBQUU7WUFDaEUsTUFBTSxLQUFLLEdBQUcsZUFBSyxDQUFDLGVBQWUsQ0FBQyw2QkFBZSxDQUFDLFNBQVMsQ0FBQyxDQUFDO1lBQy9ELE1BQU0sRUFBRSxHQUFHLENBQUMsTUFBTSxPQUFPLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLEtBQUssRUFBRSxDQUFnQixDQUFDO1lBQzlELE1BQU0sV0FBVyxHQUFHLGVBQUssQ0FBQyxlQUFlLENBQUMsRUFBRSxDQUFDLGlCQUFpQixFQUFFLENBQUMsQ0FBQztZQUVsRSxXQUFXLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUNsQyxDQUFDLENBQUMsQ0FBQztRQUVILEVBQUUsQ0FBQyx5Q0FBeUMsRUFBRSxLQUFLLElBQUksRUFBRTtZQUN2RCxNQUFNLEtBQUssR0FBRyxlQUFLLENBQUMsZUFBZSxDQUFDLDZCQUFlLENBQUMsU0FBUyxDQUFDLENBQUM7WUFDL0QsTUFBTSxFQUFFLEdBQUcsQ0FBQyxNQUFNLE9BQU8sQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsS0FBSyxFQUFFLENBQWdCLENBQUM7WUFDOUQsRUFBRSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUNoQyxFQUFFLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUN2QyxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQyxDQUFDO0FBQ0wsQ0FBQyxDQUFDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgYXNzZXJ0IGZyb20gJ2Fzc2VydCc7XG5pbXBvcnQgJ3Nob3VsZCc7XG5pbXBvcnQgeyBjb2lucyB9IGZyb20gJ0BiaXRnby9zdGF0aWNzJztcbmltcG9ydCB7IFRyYW5zYWN0aW9uVHlwZSB9IGZyb20gJ0BiaXRnby9zZGstY29yZSc7XG5pbXBvcnQgeyBUcmFuc2FjdGlvbkJ1aWxkZXJGYWN0b3J5LCBQZXJtaXNzaW9ubGVzc0RlbGVnYXRvclR4QnVpbGRlciwgVHJhbnNhY3Rpb24gfSBmcm9tICcuLi8uLi8uLi9zcmMvbGliJztcbmltcG9ydCB7IFNFRURfQUNDT1VOVCwgQUNDT1VOVF8xLCBDT05URVhUIH0gZnJvbSAnLi4vLi4vcmVzb3VyY2VzL2FjY291bnQnO1xuaW1wb3J0IHV0aWxzIGZyb20gJy4uLy4uLy4uL3NyYy9saWIvdXRpbHMnO1xuaW1wb3J0IHsgREVMRUdBVElPTl9UWF8yIH0gZnJvbSAnLi4vLi4vcmVzb3VyY2VzL3RyYW5zYWN0aW9uRGF0YS9kZWxlZ2F0b3JUeCc7XG5cbmRlc2NyaWJlKCdGbHJwIFBlcm1pc3Npb25sZXNzRGVsZWdhdG9yVHhCdWlsZGVyJywgKCkgPT4ge1xuICBjb25zdCBjb2luQ29uZmlnID0gY29pbnMuZ2V0KCd0ZmxycCcpO1xuICBjb25zdCBmYWN0b3J5ID0gbmV3IFRyYW5zYWN0aW9uQnVpbGRlckZhY3RvcnkoY29pbkNvbmZpZyk7XG5cbiAgZGVzY3JpYmUoJ2dldERlbGVnYXRvckJ1aWxkZXInLCAoKSA9PiB7XG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gYSBQZXJtaXNzaW9ubGVzc0RlbGVnYXRvclR4QnVpbGRlciBpbnN0YW5jZScsICgpID0+IHtcbiAgICAgIGNvbnN0IGJ1aWxkZXIgPSBmYWN0b3J5LmdldERlbGVnYXRvckJ1aWxkZXIoKTtcbiAgICAgIGJ1aWxkZXIuc2hvdWxkLmJlLmluc3RhbmNlT2YoUGVybWlzc2lvbmxlc3NEZWxlZ2F0b3JUeEJ1aWxkZXIpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgndmFsaWRhdGUgbm9kZUlEJywgKCkgPT4ge1xuICAgIGl0KCdzaG91bGQgZmFpbCB3aGVuIG5vZGVJRCBpcyBtaXNzaW5nJywgKCkgPT4ge1xuICAgICAgY29uc3QgYnVpbGRlciA9IGZhY3RvcnkuZ2V0RGVsZWdhdG9yQnVpbGRlcigpO1xuICAgICAgYXNzZXJ0LnRocm93cyhcbiAgICAgICAgKCkgPT4ge1xuICAgICAgICAgIGJ1aWxkZXIubm9kZUlEKCcnKTtcbiAgICAgICAgfSxcbiAgICAgICAgKGU6IGFueSkgPT4gZS5tZXNzYWdlID09PSAnSW52YWxpZCB0cmFuc2FjdGlvbjogbWlzc2luZyBub2RlSUQnXG4gICAgICApO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBmYWlsIHdoZW4gbm9kZUlEIGhhcyBpbnZhbGlkIHByZWZpeCcsICgpID0+IHtcbiAgICAgIGNvbnN0IGJ1aWxkZXIgPSBmYWN0b3J5LmdldERlbGVnYXRvckJ1aWxkZXIoKTtcbiAgICAgIGFzc2VydC50aHJvd3MoXG4gICAgICAgICgpID0+IHtcbiAgICAgICAgICBidWlsZGVyLm5vZGVJRCgnSW52YWxpZFByZWZpeC0xMjM0NTY3ODknKTtcbiAgICAgICAgfSxcbiAgICAgICAgKGU6IGFueSkgPT4gZS5tZXNzYWdlID09PSAnSW52YWxpZCB0cmFuc2FjdGlvbjogaW52YWxpZCBOb2RlSUQgdGFnJ1xuICAgICAgKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgYWNjZXB0IHZhbGlkIG5vZGVJRCBmb3JtYXQnLCAoKSA9PiB7XG4gICAgICBjb25zdCBidWlsZGVyID0gZmFjdG9yeS5nZXREZWxlZ2F0b3JCdWlsZGVyKCk7XG4gICAgICBjb25zdCB2YWxpZE5vZGVJRCA9ICdOb2RlSUQtQUs3c1BCc1pNOXJRd3NlMjNhTGhFRUJQSFpENWdrTHJMJztcbiAgICAgICgoKSA9PiBidWlsZGVyLm5vZGVJRCh2YWxpZE5vZGVJRCkpLnNob3VsZC5ub3QudGhyb3coKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ3ZhbGlkYXRlIHN0YWtlIGR1cmF0aW9uJywgKCkgPT4ge1xuICAgIGl0KCdzaG91bGQgZmFpbCB3aGVuIGVuZCB0aW1lIGlzIGxlc3MgdGhhbiBzdGFydCB0aW1lJywgKCkgPT4ge1xuICAgICAgY29uc3QgYnVpbGRlciA9IGZhY3RvcnkuZ2V0RGVsZWdhdG9yQnVpbGRlcigpO1xuICAgICAgY29uc3Qgc3RhcnRUaW1lID0gQmlnSW50KE1hdGguZmxvb3IoRGF0ZS5ub3coKSAvIDEwMDApICsgNjApO1xuICAgICAgY29uc3QgZW5kVGltZSA9IEJpZ0ludChNYXRoLmZsb29yKERhdGUubm93KCkgLyAxMDAwKSAtIDYwKTtcblxuICAgICAgYnVpbGRlci5zdGFydFRpbWUoc3RhcnRUaW1lLnRvU3RyaW5nKCkpO1xuICAgICAgYnVpbGRlci5lbmRUaW1lKGVuZFRpbWUudG9TdHJpbmcoKSk7XG5cbiAgICAgIC8vIFRoZSB2YWxpZGF0aW9uIGhhcHBlbnMgaW4gYnVpbGRGbGFyZVRyYW5zYWN0aW9uLCBidXQgd2UgY2FuIHRlc3QgdmFsaWRhdGVTdGFrZUR1cmF0aW9uIGRpcmVjdGx5XG4gICAgICBhc3NlcnQudGhyb3dzKFxuICAgICAgICAoKSA9PiB7XG4gICAgICAgICAgYnVpbGRlci52YWxpZGF0ZVN0YWtlRHVyYXRpb24oc3RhcnRUaW1lLCBlbmRUaW1lKTtcbiAgICAgICAgfSxcbiAgICAgICAgKGU6IGFueSkgPT4gZS5tZXNzYWdlID09PSAnRW5kIGRhdGUgY2Fubm90IGJlIGxlc3MgdGhhbiBzdGFydCBkYXRlJ1xuICAgICAgKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgYWNjZXB0IHZhbGlkIHN0YWtlIGR1cmF0aW9uJywgKCkgPT4ge1xuICAgICAgY29uc3QgYnVpbGRlciA9IGZhY3RvcnkuZ2V0RGVsZWdhdG9yQnVpbGRlcigpO1xuICAgICAgY29uc3Qgc3RhcnRUaW1lID0gQmlnSW50KE1hdGguZmxvb3IoRGF0ZS5ub3coKSAvIDEwMDApICsgNjApO1xuICAgICAgY29uc3QgZW5kVGltZSA9IEJpZ0ludChNYXRoLmZsb29yKERhdGUubm93KCkgLyAxMDAwKSArIDg2NDAwICogMTQpOyAvLyAxNCBkYXlzIGxhdGVyXG5cbiAgICAgICgoKSA9PiB7XG4gICAgICAgIGJ1aWxkZXIudmFsaWRhdGVTdGFrZUR1cmF0aW9uKHN0YXJ0VGltZSwgZW5kVGltZSk7XG4gICAgICB9KS5zaG91bGQubm90LnRocm93KCk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdidWlsZGVyIG1ldGhvZHMnLCAoKSA9PiB7XG4gICAgaXQoJ3Nob3VsZCBzZXQgc3RhcnRUaW1lIGNvcnJlY3RseScsICgpID0+IHtcbiAgICAgIGNvbnN0IGJ1aWxkZXIgPSBmYWN0b3J5LmdldERlbGVnYXRvckJ1aWxkZXIoKTtcbiAgICAgIGNvbnN0IHN0YXJ0VGltZSA9IE1hdGguZmxvb3IoRGF0ZS5ub3coKSAvIDEwMDApICsgNjA7XG4gICAgICAoKCkgPT4gYnVpbGRlci5zdGFydFRpbWUoc3RhcnRUaW1lKSkuc2hvdWxkLm5vdC50aHJvdygpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBzZXQgZW5kVGltZSBjb3JyZWN0bHknLCAoKSA9PiB7XG4gICAgICBjb25zdCBidWlsZGVyID0gZmFjdG9yeS5nZXREZWxlZ2F0b3JCdWlsZGVyKCk7XG4gICAgICBjb25zdCBlbmRUaW1lID0gTWF0aC5mbG9vcihEYXRlLm5vdygpIC8gMTAwMCkgKyA4NjQwMCAqIDE0O1xuICAgICAgKCgpID0+IGJ1aWxkZXIuZW5kVGltZShlbmRUaW1lKSkuc2hvdWxkLm5vdC50aHJvdygpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBzZXQgcmV3YXJkQWRkcmVzcyB3aXRoIFAtY2hhaW4gYWRkcmVzcycsICgpID0+IHtcbiAgICAgIGNvbnN0IGJ1aWxkZXIgPSBmYWN0b3J5LmdldERlbGVnYXRvckJ1aWxkZXIoKTtcbiAgICAgIC8vIFAtY2hhaW4gQmVjaDMyIGFkZHJlc3NcbiAgICAgICgoKSA9PiBidWlsZGVyLnJld2FyZEFkZHJlc3MoU0VFRF9BQ0NPVU5ULmFkZHJlc3NUZXN0bmV0KSkuc2hvdWxkLm5vdC50aHJvdygpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnYnVpbGQgdmFsaWRhdGlvbicsICgpID0+IHtcbiAgICBpdCgnc2hvdWxkIGZhaWwgYnVpbGQgd2hlbiBub2RlSUQgaXMgbm90IHNldCcsIGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IGJ1aWxkZXIgPSBmYWN0b3J5LmdldERlbGVnYXRvckJ1aWxkZXIoKTtcbiAgICAgIGNvbnN0IG5vdyA9IE1hdGguZmxvb3IoRGF0ZS5ub3coKSAvIDEwMDApO1xuXG4gICAgICBidWlsZGVyXG4gICAgICAgIC5zdGFydFRpbWUobm93ICsgNjApXG4gICAgICAgIC5lbmRUaW1lKG5vdyArIDg2NDAwICogMTQpXG4gICAgICAgIC5zdGFrZUFtb3VudChCaWdJbnQoNTAwMDAgKiAxZTkpKVxuICAgICAgICAuZnJvbVB1YktleShbU0VFRF9BQ0NPVU5ULmFkZHJlc3NUZXN0bmV0LCBBQ0NPVU5UXzEuYWRkcmVzc1Rlc3RuZXRdKVxuICAgICAgICAuY29udGV4dChDT05URVhUIGFzIGFueSk7XG5cbiAgICAgIGF3YWl0IGJ1aWxkZXIuYnVpbGQoKS5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdOb2RlSUQgaXMgcmVxdWlyZWQgZm9yIGRlbGVnYXRpb24nKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgZmFpbCBidWlsZCB3aGVuIHN0YXJ0IHRpbWUgaXMgbm90IHNldCcsIGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IGJ1aWxkZXIgPSBmYWN0b3J5LmdldERlbGVnYXRvckJ1aWxkZXIoKTtcbiAgICAgIGNvbnN0IG5vdyA9IE1hdGguZmxvb3IoRGF0ZS5ub3coKSAvIDEwMDApO1xuICAgICAgY29uc3QgdmFsaWROb2RlSUQgPSAnTm9kZUlELUFLN3NQQnNaTTlyUXdzZTIzYUxoRUVCUEhaRDVna0xyTCc7XG5cbiAgICAgIGJ1aWxkZXJcbiAgICAgICAgLm5vZGVJRCh2YWxpZE5vZGVJRClcbiAgICAgICAgLmVuZFRpbWUobm93ICsgODY0MDAgKiAxNClcbiAgICAgICAgLnN0YWtlQW1vdW50KEJpZ0ludCg1MDAwMCAqIDFlOSkpXG4gICAgICAgIC5mcm9tUHViS2V5KFtTRUVEX0FDQ09VTlQuYWRkcmVzc1Rlc3RuZXQsIEFDQ09VTlRfMS5hZGRyZXNzVGVzdG5ldF0pXG4gICAgICAgIC5jb250ZXh0KENPTlRFWFQgYXMgYW55KTtcblxuICAgICAgYXdhaXQgYnVpbGRlci5idWlsZCgpLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoJ1N0YXJ0IHRpbWUgaXMgcmVxdWlyZWQgZm9yIGRlbGVnYXRpb24nKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgZmFpbCBidWlsZCB3aGVuIGVuZCB0aW1lIGlzIG5vdCBzZXQnLCBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCBidWlsZGVyID0gZmFjdG9yeS5nZXREZWxlZ2F0b3JCdWlsZGVyKCk7XG4gICAgICBjb25zdCBub3cgPSBNYXRoLmZsb29yKERhdGUubm93KCkgLyAxMDAwKTtcbiAgICAgIGNvbnN0IHZhbGlkTm9kZUlEID0gJ05vZGVJRC1BSzdzUEJzWk05clF3c2UyM2FMaEVFQlBIWkQ1Z2tMckwnO1xuXG4gICAgICBidWlsZGVyXG4gICAgICAgIC5ub2RlSUQodmFsaWROb2RlSUQpXG4gICAgICAgIC5zdGFydFRpbWUobm93ICsgNjApXG4gICAgICAgIC5zdGFrZUFtb3VudChCaWdJbnQoNTAwMDAgKiAxZTkpKVxuICAgICAgICAuZnJvbVB1YktleShbU0VFRF9BQ0NPVU5ULmFkZHJlc3NUZXN0bmV0LCBBQ0NPVU5UXzEuYWRkcmVzc1Rlc3RuZXRdKVxuICAgICAgICAuY29udGV4dChDT05URVhUIGFzIGFueSk7XG5cbiAgICAgIGF3YWl0IGJ1aWxkZXIuYnVpbGQoKS5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdFbmQgdGltZSBpcyByZXF1aXJlZCBmb3IgZGVsZWdhdGlvbicpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBmYWlsIGJ1aWxkIHdoZW4gc3Rha2UgYW1vdW50IGlzIG5vdCBzZXQnLCBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCBidWlsZGVyID0gZmFjdG9yeS5nZXREZWxlZ2F0b3JCdWlsZGVyKCk7XG4gICAgICBjb25zdCBub3cgPSBNYXRoLmZsb29yKERhdGUubm93KCkgLyAxMDAwKTtcbiAgICAgIGNvbnN0IHZhbGlkTm9kZUlEID0gJ05vZGVJRC1BSzdzUEJzWk05clF3c2UyM2FMaEVFQlBIWkQ1Z2tMckwnO1xuXG4gICAgICBidWlsZGVyXG4gICAgICAgIC5ub2RlSUQodmFsaWROb2RlSUQpXG4gICAgICAgIC5zdGFydFRpbWUobm93ICsgNjApXG4gICAgICAgIC5lbmRUaW1lKG5vdyArIDg2NDAwICogMTQpXG4gICAgICAgIC5mcm9tUHViS2V5KFtTRUVEX0FDQ09VTlQuYWRkcmVzc1Rlc3RuZXQsIEFDQ09VTlRfMS5hZGRyZXNzVGVzdG5ldF0pXG4gICAgICAgIC5jb250ZXh0KENPTlRFWFQgYXMgYW55KTtcblxuICAgICAgYXdhaXQgYnVpbGRlci5idWlsZCgpLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoJ1N0YWtlIGFtb3VudCBpcyByZXF1aXJlZCBmb3IgZGVsZWdhdGlvbicpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBmYWlsIGJ1aWxkIHdoZW4gY29udGV4dCBpcyBub3Qgc2V0JywgYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3QgYnVpbGRlciA9IGZhY3RvcnkuZ2V0RGVsZWdhdG9yQnVpbGRlcigpO1xuICAgICAgY29uc3Qgbm93ID0gTWF0aC5mbG9vcihEYXRlLm5vdygpIC8gMTAwMCk7XG4gICAgICBjb25zdCB2YWxpZE5vZGVJRCA9ICdOb2RlSUQtQUs3c1BCc1pNOXJRd3NlMjNhTGhFRUJQSFpENWdrTHJMJztcblxuICAgICAgYnVpbGRlclxuICAgICAgICAubm9kZUlEKHZhbGlkTm9kZUlEKVxuICAgICAgICAuc3RhcnRUaW1lKG5vdyArIDYwKVxuICAgICAgICAuZW5kVGltZShub3cgKyA4NjQwMCAqIDE0KVxuICAgICAgICAuc3Rha2VBbW91bnQoQmlnSW50KDUwMDAwICogMWU5KSlcbiAgICAgICAgLmZyb21QdWJLZXkoW1NFRURfQUNDT1VOVC5hZGRyZXNzVGVzdG5ldCwgQUNDT1VOVF8xLmFkZHJlc3NUZXN0bmV0XSk7XG5cbiAgICAgIGF3YWl0IGJ1aWxkZXIuYnVpbGQoKS5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdDb250ZXh0IGlzIHJlcXVpcmVkIGZvciBkZWxlZ2F0aW9uJyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGZhaWwgYnVpbGQgd2hlbiBmcm9tIGFkZHJlc3NlcyBhcmUgbm90IHNldCcsIGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IGJ1aWxkZXIgPSBmYWN0b3J5LmdldERlbGVnYXRvckJ1aWxkZXIoKTtcbiAgICAgIGNvbnN0IG5vdyA9IE1hdGguZmxvb3IoRGF0ZS5ub3coKSAvIDEwMDApO1xuICAgICAgY29uc3QgdmFsaWROb2RlSUQgPSAnTm9kZUlELUFLN3NQQnNaTTlyUXdzZTIzYUxoRUVCUEhaRDVna0xyTCc7XG5cbiAgICAgIGJ1aWxkZXJcbiAgICAgICAgLm5vZGVJRCh2YWxpZE5vZGVJRClcbiAgICAgICAgLnN0YXJ0VGltZShub3cgKyA2MClcbiAgICAgICAgLmVuZFRpbWUobm93ICsgODY0MDAgKiAxNClcbiAgICAgICAgLnN0YWtlQW1vdW50KEJpZ0ludCg1MDAwMCAqIDFlOSkpXG4gICAgICAgIC5jb250ZXh0KENPTlRFWFQgYXMgYW55KTtcblxuICAgICAgYXdhaXQgYnVpbGRlci5idWlsZCgpLnNob3VsZC5iZS5yZWplY3RlZFdpdGgoJ0Zyb20gYWRkcmVzc2VzIGFyZSByZXF1aXJlZCBmb3IgZGVsZWdhdGlvbicpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBmYWlsIGJ1aWxkIHdoZW4gZmVlIHN0YXRlIGlzIG5vdCBzZXQnLCBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCBidWlsZGVyID0gZmFjdG9yeS5nZXREZWxlZ2F0b3JCdWlsZGVyKCk7XG4gICAgICBjb25zdCBub3cgPSBNYXRoLmZsb29yKERhdGUubm93KCkgLyAxMDAwKTtcbiAgICAgIGNvbnN0IHZhbGlkTm9kZUlEID0gJ05vZGVJRC1BSzdzUEJzWk05clF3c2UyM2FMaEVFQlBIWkQ1Z2tMckwnO1xuXG4gICAgICBidWlsZGVyXG4gICAgICAgIC5ub2RlSUQodmFsaWROb2RlSUQpXG4gICAgICAgIC5zdGFydFRpbWUobm93ICsgNjApXG4gICAgICAgIC5lbmRUaW1lKG5vdyArIDg2NDAwICogMTQpXG4gICAgICAgIC5zdGFrZUFtb3VudChCaWdJbnQoNTAwMDAgKiAxZTkpKVxuICAgICAgICAuZnJvbVB1YktleShbU0VFRF9BQ0NPVU5ULmFkZHJlc3NUZXN0bmV0LCBBQ0NPVU5UXzEuYWRkcmVzc1Rlc3RuZXRdKVxuICAgICAgICAuY29udGV4dChDT05URVhUIGFzIGFueSk7XG5cbiAgICAgIGF3YWl0IGJ1aWxkZXIuYnVpbGQoKS5zaG91bGQuYmUucmVqZWN0ZWRXaXRoKCdGZWUgc3RhdGUgaXMgcmVxdWlyZWQgZm9yIGRlbGVnYXRpb24nKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgZmFpbCBidWlsZCB3aGVuIFVUWE9zIGFyZSBub3Qgc2V0JywgYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3QgYnVpbGRlciA9IGZhY3RvcnkuZ2V0RGVsZWdhdG9yQnVpbGRlcigpO1xuICAgICAgY29uc3Qgbm93ID0gTWF0aC5mbG9vcihEYXRlLm5vdygpIC8gMTAwMCk7XG4gICAgICBjb25zdCB2YWxpZE5vZGVJRCA9ICdOb2RlSUQtQUs3c1BCc1pNOXJRd3NlMjNhTGhFRUJQSFpENWdrTHJMJztcbiAgICAgIGNvbnN0IG1vY2tGZWVTdGF0ZSA9IHsgY2FwYWNpdHk6IDEwMDAwMG4sIGV4Y2VzczogMG4sIHByaWNlOiAxMDAwbiwgdGltZXN0YW1wOiAnMTIzNDU2Nzg5MCcgfTtcblxuICAgICAgYnVpbGRlclxuICAgICAgICAubm9kZUlEKHZhbGlkTm9kZUlEKVxuICAgICAgICAuc3RhcnRUaW1lKG5vdyArIDYwKVxuICAgICAgICAuZW5kVGltZShub3cgKyA4NjQwMCAqIDE0KVxuICAgICAgICAuc3Rha2VBbW91bnQoQmlnSW50KDUwMDAwICogMWU5KSlcbiAgICAgICAgLmZyb21QdWJLZXkoW1NFRURfQUNDT1VOVC5hZGRyZXNzVGVzdG5ldCwgQUNDT1VOVF8xLmFkZHJlc3NUZXN0bmV0XSlcbiAgICAgICAgLmNvbnRleHQoQ09OVEVYVCBhcyBhbnkpXG4gICAgICAgIC5mZWVTdGF0ZShtb2NrRmVlU3RhdGUpO1xuXG4gICAgICBhd2FpdCBidWlsZGVyLmJ1aWxkKCkuc2hvdWxkLmJlLnJlamVjdGVkV2l0aCgnVVRYT3MgYXJlIHJlcXVpcmVkIGZvciBkZWxlZ2F0aW9uJyk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCd2YWxpZGF0ZSBzdGFrZSBhbW91bnQnLCAoKSA9PiB7XG4gICAgaXQoJ3Nob3VsZCBmYWlsIHdoZW4gc3Rha2UgYW1vdW50IGlzIGJlbG93IG1pbmltdW0nLCAoKSA9PiB7XG4gICAgICBjb25zdCBidWlsZGVyID0gZmFjdG9yeS5nZXREZWxlZ2F0b3JCdWlsZGVyKCk7XG4gICAgICAvLyBNaW5pbXVtIGlzIDUwMDAwIEZMUiwgc28gMTAwMCBzaG91bGQgZmFpbFxuICAgICAgYXNzZXJ0LnRocm93cyhcbiAgICAgICAgKCkgPT4ge1xuICAgICAgICAgIGJ1aWxkZXIuc3Rha2VBbW91bnQoQmlnSW50KDEwMDAgKiAxZTkpKTtcbiAgICAgICAgfSxcbiAgICAgICAgKGU6IGFueSkgPT4gZS5tZXNzYWdlLmluY2x1ZGVzKCdNaW5pbXVtIGRlbGVnYXRpb24gYW1vdW50JylcbiAgICAgICk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGFjY2VwdCBzdGFrZSBhbW91bnQgYXQgb3IgYWJvdmUgbWluaW11bScsICgpID0+IHtcbiAgICAgIGNvbnN0IGJ1aWxkZXIgPSBmYWN0b3J5LmdldERlbGVnYXRvckJ1aWxkZXIoKTtcbiAgICAgIGNvbnN0IHN0YWtlQW1vdW50ID0gQmlnSW50KDUwMDAwICogMWU5KTtcbiAgICAgICgoKSA9PiBidWlsZGVyLnN0YWtlQW1vdW50KHN0YWtlQW1vdW50KSkuc2hvdWxkLm5vdC50aHJvdygpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgndHJhbnNhY3Rpb24gdHlwZSBzdXBwb3J0JywgKCkgPT4ge1xuICAgIGl0KCdzaG91bGQgYWxsb3cgc2V0dGluZyBBZGRQZXJtaXNzaW9ubGVzc0RlbGVnYXRvciB0cmFuc2FjdGlvbiB0eXBlJywgKCkgPT4ge1xuICAgICAgY29uc3QgYnVpbGRlciA9IGZhY3RvcnkuZ2V0RGVsZWdhdG9yQnVpbGRlcigpO1xuICAgICAgLy8gVGhlIGJ1aWxkZXIgc2hvdWxkIHN1Y2Nlc3NmdWxseSBjb25maWd1cmUgd2l0aCBBZGRQZXJtaXNzaW9ubGVzc0RlbGVnYXRvciB0eXBlXG4gICAgICAvLyBUaGlzIHZlcmlmaWVzIHRyYW5zYWN0aW9uLnRzIHNldFRyYW5zYWN0aW9uVHlwZSBhY2NlcHRzIHRoZSBkZWxlZ2F0aW9uIHR5cGVcbiAgICAgIGJ1aWxkZXIuc2hvdWxkLmJlLmluc3RhbmNlb2YoUGVybWlzc2lvbmxlc3NEZWxlZ2F0b3JUeEJ1aWxkZXIpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBoYXZlIGNvcnJlY3QgbWluaW11bSBzdGFrZSBhbW91bnQgY29uc3RhbnQnLCAoKSA9PiB7XG4gICAgICAvLyBWZXJpZnkgdGhlIG1pbmltdW0gc3Rha2UgYW1vdW50IGlzIDUwMDAwIEZMUiAoaW4gbmFub0ZMUilcbiAgICAgIGNvbnN0IG1pblN0YWtlQW1vdW50ID0gQmlnSW50KDUwMDAwICogMWU5KTtcbiAgICAgIG1pblN0YWtlQW1vdW50LnNob3VsZC5lcXVhbChCaWdJbnQoJzUwMDAwMDAwMDAwMDAwJykpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgncm91bmQtdHJpcCBkZXNlcmlhbGl6YXRpb24nLCAoKSA9PiB7XG4gICAgaXQoJ3Nob3VsZCBkZXNlcmlhbGl6ZSBhIHNpZ25lZCBkZWxlZ2F0aW9uIHRyYW5zYWN0aW9uIGZyb20gaGV4JywgYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3QgcmF3VHggPSB1dGlscy5yZW1vdmVIZXhQcmVmaXgoREVMRUdBVElPTl9UWF8yLnNpZ25lZEhleCk7XG4gICAgICBjb25zdCB0eCA9IChhd2FpdCBmYWN0b3J5LmZyb20ocmF3VHgpLmJ1aWxkKCkpIGFzIFRyYW5zYWN0aW9uO1xuICAgICAgdHgudHlwZS5zaG91bGQuZXF1YWwoVHJhbnNhY3Rpb25UeXBlLkFkZFBlcm1pc3Npb25sZXNzRGVsZWdhdG9yKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgY29ycmVjdGx5IGV4dHJhY3QgZGVsZWdhdGlvbiBwYXJhbWV0ZXJzIGZyb20gZGVzZXJpYWxpemVkIHRyYW5zYWN0aW9uJywgYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3QgcmF3VHggPSB1dGlscy5yZW1vdmVIZXhQcmVmaXgoREVMRUdBVElPTl9UWF8yLnNpZ25lZEhleCk7XG4gICAgICBjb25zdCB0eCA9IChhd2FpdCBmYWN0b3J5LmZyb20ocmF3VHgpLmJ1aWxkKCkpIGFzIFRyYW5zYWN0aW9uO1xuICAgICAgY29uc3QgZXhwbGFuYXRpb24gPSB0eC5leHBsYWluVHJhbnNhY3Rpb24oKTtcbiAgICAgIGV4cGxhbmF0aW9uLm91dHB1dHMubGVuZ3RoLnNob3VsZC5iZS5hYm92ZSgwKTtcbiAgICAgIGV4cGxhbmF0aW9uLm91dHB1dEFtb3VudC5zaG91bGQuZXF1YWwoREVMRUdBVElPTl9UWF8yLnN0YWtlQW1vdW50KTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmUtc2VyaWFsaXplIHRvIHRoZSBzYW1lIGhleCAocm91bmQtdHJpcCknLCBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCByYXdUeCA9IHV0aWxzLnJlbW92ZUhleFByZWZpeChERUxFR0FUSU9OX1RYXzIuc2lnbmVkSGV4KTtcbiAgICAgIGNvbnN0IHR4ID0gKGF3YWl0IGZhY3RvcnkuZnJvbShyYXdUeCkuYnVpbGQoKSkgYXMgVHJhbnNhY3Rpb247XG4gICAgICBjb25zdCByZUVuY29kZWRUeCA9IHV0aWxzLnJlbW92ZUhleFByZWZpeCh0eC50b0Jyb2FkY2FzdEZvcm1hdCgpKTtcblxuICAgICAgcmVFbmNvZGVkVHguc2hvdWxkLmVxdWFsKHJhd1R4KTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgaGF2ZSBjb3JyZWN0IGlucHV0L291dHB1dCBjb3VudHMnLCBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCByYXdUeCA9IHV0aWxzLnJlbW92ZUhleFByZWZpeChERUxFR0FUSU9OX1RYXzIuc2lnbmVkSGV4KTtcbiAgICAgIGNvbnN0IHR4ID0gKGF3YWl0IGZhY3RvcnkuZnJvbShyYXdUeCkuYnVpbGQoKSkgYXMgVHJhbnNhY3Rpb247XG4gICAgICB0eC5pbnB1dHMuc2hvdWxkLmhhdmUubGVuZ3RoKDMpO1xuICAgICAgdHgub3V0cHV0cy5sZW5ndGguc2hvdWxkLmJlLmFib3ZlKDApO1xuICAgIH0pO1xuICB9KTtcbn0pO1xuIl19