@bitgo-beta/sdk-core 8.2.1-beta.1810 → 8.2.1-beta.1812
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/src/bitgo/defi/defiVault.d.ts +79 -0
- package/dist/src/bitgo/defi/defiVault.d.ts.map +1 -0
- package/dist/src/bitgo/defi/defiVault.js +198 -0
- package/dist/src/bitgo/defi/iDefiVault.d.ts +59 -0
- package/dist/src/bitgo/defi/iDefiVault.d.ts.map +1 -0
- package/dist/src/bitgo/defi/iDefiVault.js +6 -0
- package/dist/src/bitgo/defi/index.d.ts +3 -0
- package/dist/src/bitgo/defi/index.d.ts.map +1 -0
- package/dist/src/bitgo/defi/index.js +22 -0
- package/dist/src/bitgo/index.d.ts +1 -0
- package/dist/src/bitgo/index.d.ts.map +1 -1
- package/dist/src/bitgo/index.js +2 -1
- package/dist/src/bitgo/utils/mpcUtils.d.ts.map +1 -1
- package/dist/src/bitgo/utils/mpcUtils.js +16 -1
- package/dist/src/bitgo/utils/tss/baseTypes.d.ts +24 -2
- package/dist/src/bitgo/utils/tss/baseTypes.d.ts.map +1 -1
- package/dist/src/bitgo/utils/tss/baseTypes.js +1 -1
- package/dist/src/bitgo/wallet/iWallet.d.ts +2 -0
- package/dist/src/bitgo/wallet/iWallet.d.ts.map +1 -1
- package/dist/src/bitgo/wallet/iWallet.js +1 -1
- package/dist/src/bitgo/wallet/wallet.d.ts +6 -0
- package/dist/src/bitgo/wallet/wallet.d.ts.map +1 -1
- package/dist/src/bitgo/wallet/wallet.js +38 -1
- package/dist/test/unit/bitgo/defi/defiVault.d.ts +2 -0
- package/dist/test/unit/bitgo/defi/defiVault.d.ts.map +1 -0
- package/dist/test/unit/bitgo/defi/defiVault.js +292 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +8 -8
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"defiVault.d.ts","sourceRoot":"","sources":["../../../../../test/unit/bitgo/defi/defiVault.ts"],"names":[],"mappings":"AAEA,OAAO,QAAQ,CAAC"}
|
|
@@ -0,0 +1,292 @@
|
|
|
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 sinon_1 = __importDefault(require("sinon"));
|
|
7
|
+
const assert_1 = __importDefault(require("assert"));
|
|
8
|
+
require("should");
|
|
9
|
+
const src_1 = require("../../../../src");
|
|
10
|
+
describe('DefiVault', function () {
|
|
11
|
+
let wallet;
|
|
12
|
+
let defiVault;
|
|
13
|
+
let mockBitGo;
|
|
14
|
+
let mockBaseCoin;
|
|
15
|
+
// Helper to create a chainable request mock
|
|
16
|
+
function mockRequest(result) {
|
|
17
|
+
return {
|
|
18
|
+
send: sinon_1.default.stub().returnsThis(),
|
|
19
|
+
query: sinon_1.default.stub().returnsThis(),
|
|
20
|
+
result: sinon_1.default.stub().resolves(result),
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
beforeEach(function () {
|
|
24
|
+
mockBitGo = {
|
|
25
|
+
post: sinon_1.default.stub(),
|
|
26
|
+
get: sinon_1.default.stub(),
|
|
27
|
+
del: sinon_1.default.stub(),
|
|
28
|
+
url: sinon_1.default.stub().callsFake((path, version) => `https://bitgo.com/api/v${version}${path}`),
|
|
29
|
+
microservicesUrl: sinon_1.default.stub().callsFake((path) => `https://bitgo.com${path}`),
|
|
30
|
+
setRequestTracer: sinon_1.default.stub(),
|
|
31
|
+
};
|
|
32
|
+
mockBaseCoin = {
|
|
33
|
+
getFamily: sinon_1.default.stub().returns('eth'),
|
|
34
|
+
url: sinon_1.default.stub(),
|
|
35
|
+
keychains: sinon_1.default.stub(),
|
|
36
|
+
supportsTss: sinon_1.default.stub().returns(true),
|
|
37
|
+
getMPCAlgorithm: sinon_1.default.stub(),
|
|
38
|
+
};
|
|
39
|
+
const mockWalletData = {
|
|
40
|
+
id: 'test-wallet-id',
|
|
41
|
+
coin: 'eth',
|
|
42
|
+
keys: ['user-key', 'backup-key', 'bitgo-key'],
|
|
43
|
+
};
|
|
44
|
+
wallet = new src_1.Wallet(mockBitGo, mockBaseCoin, mockWalletData);
|
|
45
|
+
defiVault = wallet.defi;
|
|
46
|
+
});
|
|
47
|
+
afterEach(function () {
|
|
48
|
+
sinon_1.default.restore();
|
|
49
|
+
});
|
|
50
|
+
describe('depositToVault', function () {
|
|
51
|
+
it('should call sendMany for approve and deposit on happy path', async function () {
|
|
52
|
+
const operationId = 'op-uuid-123';
|
|
53
|
+
// Pre-flight: no active operations
|
|
54
|
+
const preflightReq = mockRequest({ items: [] });
|
|
55
|
+
mockBitGo.get.onFirstCall().returns(preflightReq);
|
|
56
|
+
// Mock sendMany for approve and deposit
|
|
57
|
+
const sendManyStub = sinon_1.default.stub(wallet, 'sendMany');
|
|
58
|
+
sendManyStub.onFirstCall().resolves({
|
|
59
|
+
txRequest: {
|
|
60
|
+
txRequestId: 'txreq-approve-1',
|
|
61
|
+
intent: { intentType: 'defi-approve', operationId },
|
|
62
|
+
},
|
|
63
|
+
});
|
|
64
|
+
sendManyStub.onSecondCall().resolves({
|
|
65
|
+
txRequest: {
|
|
66
|
+
txRequestId: 'txreq-deposit-1',
|
|
67
|
+
intent: { intentType: 'defi-deposit', operationId },
|
|
68
|
+
},
|
|
69
|
+
});
|
|
70
|
+
const result = await defiVault.depositToVault({
|
|
71
|
+
vaultId: 'vlt-galaxy-usdc',
|
|
72
|
+
amount: '1000000',
|
|
73
|
+
});
|
|
74
|
+
result.operationId.should.equal(operationId);
|
|
75
|
+
result.txRequestIds.approve.should.equal('txreq-approve-1');
|
|
76
|
+
result.txRequestIds.deposit.should.equal('txreq-deposit-1');
|
|
77
|
+
// Verify pre-flight was called with correct query
|
|
78
|
+
preflightReq.query.calledWith({ vaultId: 'vlt-galaxy-usdc', state: 'active' }).should.be.true();
|
|
79
|
+
// Verify sendMany was called with correct params for approve
|
|
80
|
+
sendManyStub.calledTwice.should.be.true();
|
|
81
|
+
const approveArgs = sendManyStub.firstCall.args[0];
|
|
82
|
+
approveArgs.type.should.equal('defiApprove');
|
|
83
|
+
approveArgs.defiParams.vaultId.should.equal('vlt-galaxy-usdc');
|
|
84
|
+
approveArgs.defiParams.amount.should.equal('1000000');
|
|
85
|
+
// Verify sendMany was called with correct params for deposit
|
|
86
|
+
const depositArgs = sendManyStub.secondCall.args[0];
|
|
87
|
+
depositArgs.type.should.equal('defiDeposit');
|
|
88
|
+
depositArgs.defiParams.operationId.should.equal(operationId);
|
|
89
|
+
});
|
|
90
|
+
it('should reject when an active operation already exists', async function () {
|
|
91
|
+
const preflightReq = mockRequest({
|
|
92
|
+
items: [{ operationId: 'existing-op-id', state: 'APPROVE_TX_REQUESTED' }],
|
|
93
|
+
});
|
|
94
|
+
mockBitGo.get.returns(preflightReq);
|
|
95
|
+
await assert_1.default.rejects(() => defiVault.depositToVault({ vaultId: 'vlt-galaxy-usdc', amount: '1000000' }), (err) => {
|
|
96
|
+
(err instanceof src_1.ActiveOperationExistsError).should.be.true();
|
|
97
|
+
err.operationId.should.equal('existing-op-id');
|
|
98
|
+
return true;
|
|
99
|
+
});
|
|
100
|
+
});
|
|
101
|
+
it('should propagate deposit sendMany failure without cleanup', async function () {
|
|
102
|
+
const operationId = 'op-uuid-456';
|
|
103
|
+
// Pre-flight: no active operations
|
|
104
|
+
const preflightReq = mockRequest({ items: [] });
|
|
105
|
+
mockBitGo.get.returns(preflightReq);
|
|
106
|
+
// Mock sendMany: approve succeeds, deposit fails
|
|
107
|
+
const sendManyStub = sinon_1.default.stub(wallet, 'sendMany');
|
|
108
|
+
sendManyStub.onFirstCall().resolves({
|
|
109
|
+
txRequest: {
|
|
110
|
+
txRequestId: 'txreq-approve-2',
|
|
111
|
+
intent: { intentType: 'defi-approve', operationId },
|
|
112
|
+
},
|
|
113
|
+
});
|
|
114
|
+
sendManyStub.onSecondCall().rejects(new Error('deposit creation failed'));
|
|
115
|
+
await assert_1.default.rejects(() => defiVault.depositToVault({ vaultId: 'vlt-galaxy-usdc', amount: '1000000' }), {
|
|
116
|
+
message: 'deposit creation failed',
|
|
117
|
+
});
|
|
118
|
+
// SDK does not attempt cleanup — reconciler handles orphaned approvals
|
|
119
|
+
mockBitGo.del.called.should.be.false();
|
|
120
|
+
});
|
|
121
|
+
it('should throw if vaultId is missing', async function () {
|
|
122
|
+
await assert_1.default.rejects(() => defiVault.depositToVault({ vaultId: '', amount: '1000000' }), {
|
|
123
|
+
message: 'vaultId is required',
|
|
124
|
+
});
|
|
125
|
+
});
|
|
126
|
+
it('should throw if amount is missing', async function () {
|
|
127
|
+
await assert_1.default.rejects(() => defiVault.depositToVault({ vaultId: 'vlt-1', amount: '' }), {
|
|
128
|
+
message: 'amount is required',
|
|
129
|
+
});
|
|
130
|
+
});
|
|
131
|
+
it('should pass clientIdempotencyKey and walletPassphrase when provided', async function () {
|
|
132
|
+
const operationId = 'op-uuid-789';
|
|
133
|
+
const preflightReq = mockRequest({ items: [] });
|
|
134
|
+
mockBitGo.get.returns(preflightReq);
|
|
135
|
+
const sendManyStub = sinon_1.default.stub(wallet, 'sendMany');
|
|
136
|
+
sendManyStub.onFirstCall().resolves({
|
|
137
|
+
txRequest: {
|
|
138
|
+
txRequestId: 'txreq-approve-3',
|
|
139
|
+
intent: { intentType: 'defi-approve', operationId },
|
|
140
|
+
},
|
|
141
|
+
});
|
|
142
|
+
sendManyStub.onSecondCall().resolves({
|
|
143
|
+
txRequest: {
|
|
144
|
+
txRequestId: 'txreq-deposit-3',
|
|
145
|
+
intent: { intentType: 'defi-deposit', operationId },
|
|
146
|
+
},
|
|
147
|
+
});
|
|
148
|
+
await defiVault.depositToVault({
|
|
149
|
+
vaultId: 'vlt-galaxy-usdc',
|
|
150
|
+
amount: '1000000',
|
|
151
|
+
clientIdempotencyKey: 'idem-key-123',
|
|
152
|
+
walletPassphrase: 'test-passphrase',
|
|
153
|
+
});
|
|
154
|
+
const approveArgs = sendManyStub.firstCall.args[0];
|
|
155
|
+
approveArgs.defiParams.clientIdempotencyKey.should.equal('idem-key-123');
|
|
156
|
+
approveArgs.walletPassphrase.should.equal('test-passphrase');
|
|
157
|
+
const depositArgs = sendManyStub.secondCall.args[0];
|
|
158
|
+
depositArgs.defiParams.clientIdempotencyKey.should.equal('idem-key-123');
|
|
159
|
+
depositArgs.walletPassphrase.should.equal('test-passphrase');
|
|
160
|
+
});
|
|
161
|
+
});
|
|
162
|
+
describe('resumeDeposit', function () {
|
|
163
|
+
it('should issue the deposit sendMany for a partial operation', async function () {
|
|
164
|
+
const operation = {
|
|
165
|
+
operationId: 'op-resume-1',
|
|
166
|
+
walletId: 'test-wallet-id',
|
|
167
|
+
vaultId: 'vlt-galaxy-usdc',
|
|
168
|
+
type: 'DEPOSIT',
|
|
169
|
+
assetAmount: '1000000',
|
|
170
|
+
state: 'APPROVE_TX_REQUESTED',
|
|
171
|
+
txRequestId: 'txreq-approve-existing',
|
|
172
|
+
associatedTxRequestId: undefined,
|
|
173
|
+
createdAt: '2026-05-14T07:12:00Z',
|
|
174
|
+
updatedAt: '2026-05-14T07:12:00Z',
|
|
175
|
+
};
|
|
176
|
+
// getOperation call
|
|
177
|
+
const getOpReq = mockRequest(operation);
|
|
178
|
+
mockBitGo.get.returns(getOpReq);
|
|
179
|
+
// deposit sendMany
|
|
180
|
+
const sendManyStub = sinon_1.default.stub(wallet, 'sendMany');
|
|
181
|
+
sendManyStub.resolves({
|
|
182
|
+
txRequest: {
|
|
183
|
+
txRequestId: 'txreq-deposit-resume',
|
|
184
|
+
intent: { intentType: 'defi-deposit', operationId: 'op-resume-1' },
|
|
185
|
+
},
|
|
186
|
+
});
|
|
187
|
+
const result = await defiVault.resumeDeposit({ operationId: 'op-resume-1' });
|
|
188
|
+
result.operationId.should.equal('op-resume-1');
|
|
189
|
+
result.txRequestIds.approve.should.equal('txreq-approve-existing');
|
|
190
|
+
result.txRequestIds.deposit.should.equal('txreq-deposit-resume');
|
|
191
|
+
// Verify sendMany was called with correct defiParams
|
|
192
|
+
const depositArgs = sendManyStub.firstCall.args[0];
|
|
193
|
+
depositArgs.type.should.equal('defiDeposit');
|
|
194
|
+
depositArgs.defiParams.vaultId.should.equal('vlt-galaxy-usdc');
|
|
195
|
+
depositArgs.defiParams.amount.should.equal('1000000');
|
|
196
|
+
depositArgs.defiParams.operationId.should.equal('op-resume-1');
|
|
197
|
+
});
|
|
198
|
+
it('should throw if deposit txRequest already exists', async function () {
|
|
199
|
+
const operation = {
|
|
200
|
+
operationId: 'op-already-done',
|
|
201
|
+
walletId: 'test-wallet-id',
|
|
202
|
+
vaultId: 'vlt-galaxy-usdc',
|
|
203
|
+
type: 'DEPOSIT',
|
|
204
|
+
assetAmount: '1000000',
|
|
205
|
+
state: 'DEPOSIT_TX_REQUESTED',
|
|
206
|
+
txRequestId: 'txreq-approve-x',
|
|
207
|
+
associatedTxRequestId: 'txreq-deposit-x',
|
|
208
|
+
createdAt: '2026-05-14T07:12:00Z',
|
|
209
|
+
updatedAt: '2026-05-14T07:12:00Z',
|
|
210
|
+
};
|
|
211
|
+
const getOpReq = mockRequest(operation);
|
|
212
|
+
mockBitGo.get.returns(getOpReq);
|
|
213
|
+
await assert_1.default.rejects(() => defiVault.resumeDeposit({ operationId: 'op-already-done' }), {
|
|
214
|
+
message: 'Deposit txRequest already exists for this operation; nothing to resume',
|
|
215
|
+
});
|
|
216
|
+
});
|
|
217
|
+
it('should throw if operationId is missing', async function () {
|
|
218
|
+
await assert_1.default.rejects(() => defiVault.resumeDeposit({ operationId: '' }), { message: 'operationId is required' });
|
|
219
|
+
});
|
|
220
|
+
});
|
|
221
|
+
describe('getOperation', function () {
|
|
222
|
+
it('should fetch an operation by ID', async function () {
|
|
223
|
+
const operation = {
|
|
224
|
+
operationId: 'op-get-1',
|
|
225
|
+
walletId: 'test-wallet-id',
|
|
226
|
+
vaultId: 'vlt-galaxy-usdc',
|
|
227
|
+
type: 'DEPOSIT',
|
|
228
|
+
assetAmount: '1000000',
|
|
229
|
+
state: 'COMPLETED',
|
|
230
|
+
txRequestId: 'txreq-1',
|
|
231
|
+
associatedTxRequestId: 'txreq-2',
|
|
232
|
+
createdAt: '2026-05-14T07:12:00Z',
|
|
233
|
+
updatedAt: '2026-05-14T07:18:00Z',
|
|
234
|
+
};
|
|
235
|
+
const req = mockRequest(operation);
|
|
236
|
+
mockBitGo.get.returns(req);
|
|
237
|
+
const result = await defiVault.getOperation({ operationId: 'op-get-1' });
|
|
238
|
+
result.should.deepEqual(operation);
|
|
239
|
+
});
|
|
240
|
+
it('should throw if operationId is missing', async function () {
|
|
241
|
+
await assert_1.default.rejects(() => defiVault.getOperation({ operationId: '' }), { message: 'operationId is required' });
|
|
242
|
+
});
|
|
243
|
+
});
|
|
244
|
+
describe('listOperations', function () {
|
|
245
|
+
it('should list operations for a vault', async function () {
|
|
246
|
+
const listResult = {
|
|
247
|
+
items: [
|
|
248
|
+
{
|
|
249
|
+
operationId: 'op-1',
|
|
250
|
+
walletId: 'test-wallet-id',
|
|
251
|
+
vaultId: 'vlt-galaxy-usdc',
|
|
252
|
+
type: 'DEPOSIT',
|
|
253
|
+
assetAmount: '1000000',
|
|
254
|
+
state: 'COMPLETED',
|
|
255
|
+
createdAt: '2026-05-14T07:12:00Z',
|
|
256
|
+
updatedAt: '2026-05-14T07:18:00Z',
|
|
257
|
+
},
|
|
258
|
+
],
|
|
259
|
+
nextCursor: 'cursor-abc',
|
|
260
|
+
};
|
|
261
|
+
const req = mockRequest(listResult);
|
|
262
|
+
mockBitGo.get.returns(req);
|
|
263
|
+
const result = await defiVault.listOperations({
|
|
264
|
+
vaultId: 'vlt-galaxy-usdc',
|
|
265
|
+
state: 'COMPLETED',
|
|
266
|
+
limit: 10,
|
|
267
|
+
});
|
|
268
|
+
result.items.length.should.equal(1);
|
|
269
|
+
result.nextCursor.should.equal('cursor-abc');
|
|
270
|
+
// Verify query params
|
|
271
|
+
const queryArgs = req.query.firstCall.args[0];
|
|
272
|
+
queryArgs.vaultId.should.equal('vlt-galaxy-usdc');
|
|
273
|
+
queryArgs.state.should.equal('COMPLETED');
|
|
274
|
+
queryArgs.limit.should.equal(10);
|
|
275
|
+
});
|
|
276
|
+
it('should throw if vaultId is missing', async function () {
|
|
277
|
+
await assert_1.default.rejects(() => defiVault.listOperations({ vaultId: '' }), { message: 'vaultId is required' });
|
|
278
|
+
});
|
|
279
|
+
});
|
|
280
|
+
describe('wallet.defi getter', function () {
|
|
281
|
+
it('should return a DefiVault instance', function () {
|
|
282
|
+
const defi = wallet.defi;
|
|
283
|
+
(defi instanceof src_1.DefiVault).should.be.true();
|
|
284
|
+
});
|
|
285
|
+
it('should return the same instance on subsequent calls', function () {
|
|
286
|
+
const defi1 = wallet.defi;
|
|
287
|
+
const defi2 = wallet.defi;
|
|
288
|
+
(defi1 === defi2).should.be.true();
|
|
289
|
+
});
|
|
290
|
+
});
|
|
291
|
+
});
|
|
292
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGVmaVZhdWx0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vdGVzdC91bml0L2JpdGdvL2RlZmkvZGVmaVZhdWx0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBQUEsa0RBQTBCO0FBQzFCLG9EQUE0QjtBQUM1QixrQkFBZ0I7QUFDaEIseUNBQWdGO0FBRWhGLFFBQVEsQ0FBQyxXQUFXLEVBQUU7SUFDcEIsSUFBSSxNQUFjLENBQUM7SUFDbkIsSUFBSSxTQUFvQixDQUFDO0lBQ3pCLElBQUksU0FBYyxDQUFDO0lBQ25CLElBQUksWUFBaUIsQ0FBQztJQUV0Qiw0Q0FBNEM7SUFDNUMsU0FBUyxXQUFXLENBQUMsTUFBVztRQUM5QixPQUFPO1lBQ0wsSUFBSSxFQUFFLGVBQUssQ0FBQyxJQUFJLEVBQUUsQ0FBQyxXQUFXLEVBQUU7WUFDaEMsS0FBSyxFQUFFLGVBQUssQ0FBQyxJQUFJLEVBQUUsQ0FBQyxXQUFXLEVBQUU7WUFDakMsTUFBTSxFQUFFLGVBQUssQ0FBQyxJQUFJLEVBQUUsQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDO1NBQ3RDLENBQUM7SUFDSixDQUFDO0lBRUQsVUFBVSxDQUFDO1FBQ1QsU0FBUyxHQUFHO1lBQ1YsSUFBSSxFQUFFLGVBQUssQ0FBQyxJQUFJLEVBQUU7WUFDbEIsR0FBRyxFQUFFLGVBQUssQ0FBQyxJQUFJLEVBQUU7WUFDakIsR0FBRyxFQUFFLGVBQUssQ0FBQyxJQUFJLEVBQUU7WUFDakIsR0FBRyxFQUFFLGVBQUssQ0FBQyxJQUFJLEVBQUUsQ0FBQyxTQUFTLENBQUMsQ0FBQyxJQUFZLEVBQUUsT0FBZSxFQUFFLEVBQUUsQ0FBQywwQkFBMEIsT0FBTyxHQUFHLElBQUksRUFBRSxDQUFDO1lBQzFHLGdCQUFnQixFQUFFLGVBQUssQ0FBQyxJQUFJLEVBQUUsQ0FBQyxTQUFTLENBQUMsQ0FBQyxJQUFZLEVBQUUsRUFBRSxDQUFDLG9CQUFvQixJQUFJLEVBQUUsQ0FBQztZQUN0Rixn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QUNuQyxDQUFDLENBQUMsQ0FBQztRQUVILEVBQUUsQ0FBQyxvQ0FBb0MsRUFBRSxLQUFLO1lBQzVDLE1BQU0sZ0JBQU0sQ0FBQyxPQUFPLENBQUMsR0FBRyxFQUFFLENBQUMsU0FBUyxDQUFDLGNBQWMsQ0FBQyxFQUFFLE9BQU8sRUFBRSxFQUFFLEVBQUUsQ0FBQyxFQUFFLEVBQUUsT0FBTyxFQUFFLHFCQUFxQixFQUFFLENBQUMsQ0FBQztRQUM1RyxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQyxDQUFDO0lBRUgsUUFBUSxDQUFDLG9CQUFvQixFQUFFO1FBQzdCLEVBQUUsQ0FBQyxvQ0FBb0MsRUFBRTtZQUN2QyxNQUFNLElBQUksR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDO1lBQ3pCLENBQUMsSUFBSSxZQUFZLGVBQVMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsSUFBSSxFQUFFLENBQUM7UUFDL0MsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMscURBQXFELEVBQUU7WUFDeEQsTUFBTSxLQUFLLEdBQUcsTUFBTSxDQUFDLElBQUksQ0FBQztZQUMxQixNQUFNLEtBQUssR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDO1lBQzFCLENBQUMsS0FBSyxLQUFLLEtBQUssQ0FBQyxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsSUFBSSxFQUFFLENBQUM7UUFDckMsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztBQUNMLENBQUMsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHNpbm9uIGZyb20gJ3Npbm9uJztcbmltcG9ydCBhc3NlcnQgZnJvbSAnYXNzZXJ0JztcbmltcG9ydCAnc2hvdWxkJztcbmltcG9ydCB7IEFjdGl2ZU9wZXJhdGlvbkV4aXN0c0Vycm9yLCBEZWZpVmF1bHQsIFdhbGxldCB9IGZyb20gJy4uLy4uLy4uLy4uL3NyYyc7XG5cbmRlc2NyaWJlKCdEZWZpVmF1bHQnLCBmdW5jdGlvbiAoKSB7XG4gIGxldCB3YWxsZXQ6IFdhbGxldDtcbiAgbGV0IGRlZmlWYXVsdDogRGVmaVZhdWx0O1xuICBsZXQgbW9ja0JpdEdvOiBhbnk7XG4gIGxldCBtb2NrQmFzZUNvaW46IGFueTtcblxuICAvLyBIZWxwZXIgdG8gY3JlYXRlIGEgY2hhaW5hYmxlIHJlcXVlc3QgbW9ja1xuICBmdW5jdGlvbiBtb2NrUmVxdWVzdChyZXN1bHQ6IGFueSkge1xuICAgIHJldHVybiB7XG4gICAgICBzZW5kOiBzaW5vbi5zdHViKCkucmV0dXJuc1RoaXMoKSxcbiAgICAgIHF1ZXJ5OiBzaW5vbi5zdHViKCkucmV0dXJuc1RoaXMoKSxcbiAgICAgIHJlc3VsdDogc2lub24uc3R1YigpLnJlc29sdmVzKHJlc3VsdCksXG4gICAgfTtcbiAgfVxuXG4gIGJlZm9yZUVhY2goZnVuY3Rpb24gKCkge1xuICAgIG1vY2tCaXRHbyA9IHtcbiAgICAgIHBvc3Q6IHNpbm9uLnN0dWIoKSxcbiAgICAgIGdldDogc2lub24uc3R1YigpLFxuICAgICAgZGVsOiBzaW5vbi5zdHViKCksXG4gICAgICB1cmw6IHNpbm9uLnN0dWIoKS5jYWxsc0Zha2UoKHBhdGg6IHN0cmluZywgdmVyc2lvbjogbnVtYmVyKSA9PiBgaHR0cHM6Ly9iaXRnby5jb20vYXBpL3Yke3ZlcnNpb259JHtwYXRofWApLFxuICAgICAgbWljcm9zZXJ2aWNlc1VybDogc2lub24uc3R1YigpLmNhbGxzRmFrZSgocGF0aDogc3RyaW5nKSA9PiBgaHR0cHM6Ly9iaXRnby5jb20ke3BhdGh9YCksXG4gICAgICBzZXRSZXF1ZXN0VHJhY2VyOiBzaW5vbi5zdHViKCksXG4gICAgfTtcblxuICAgIG1vY2tCYXNlQ29pbiA9IHtcbiAgICAgIGdldEZhbWlseTogc2lub24uc3R1YigpLnJldHVybnMoJ2V0aCcpLFxuICAgICAgdXJsOiBzaW5vbi5zdHViKCksXG4gICAgICBrZXljaGFpbnM6IHNpbm9uLnN0dWIoKSxcbiAgICAgIHN1cHBvcnRzVHNzOiBzaW5vbi5zdHViKCkucmV0dXJucyh0cnVlKSxcbiAgICAgIGdldE1QQ0FsZ29yaXRobTogc2lub24uc3R1YigpLFxuICAgIH07XG5cbiAgICBjb25zdCBtb2NrV2FsbGV0RGF0YSA9IHtcbiAgICAgIGlkOiAndGVzdC13YWxsZXQtaWQnLFxuICAgICAgY29pbjogJ2V0aCcsXG4gICAgICBrZXlzOiBbJ3VzZXIta2V5JywgJ2JhY2t1cC1rZXknLCAnYml0Z28ta2V5J10sXG4gICAgfTtcblxuICAgIHdhbGxldCA9IG5ldyBXYWxsZXQobW9ja0JpdEdvLCBtb2NrQmFzZUNvaW4sIG1vY2tXYWxsZXREYXRhKTtcbiAgICBkZWZpVmF1bHQgPSB3YWxsZXQuZGVmaTtcbiAgfSk7XG5cbiAgYWZ0ZXJFYWNoKGZ1bmN0aW9uICgpIHtcbiAgICBzaW5vbi5yZXN0b3JlKCk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdkZXBvc2l0VG9WYXVsdCcsIGZ1bmN0aW9uICgpIHtcbiAgICBpdCgnc2hvdWxkIGNhbGwgc2VuZE1hbnkgZm9yIGFwcHJvdmUgYW5kIGRlcG9zaXQgb24gaGFwcHkgcGF0aCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IG9wZXJhdGlvbklkID0gJ29wLXV1aWQtMTIzJztcblxuICAgICAgLy8gUHJlLWZsaWdodDogbm8gYWN0aXZlIG9wZXJhdGlvbnNcbiAgICAgIGNvbnN0IHByZWZsaWdodFJlcSA9IG1vY2tSZXF1ZXN0KHsgaXRlbXM6IFtdIH0pO1xuICAgICAgbW9ja0JpdEdvLmdldC5vbkZpcnN0Q2FsbCgpLnJldHVybnMocHJlZmxpZ2h0UmVxKTtcblxuICAgICAgLy8gTW9jayBzZW5kTWFueSBmb3IgYXBwcm92ZSBhbmQgZGVwb3NpdFxuICAgICAgY29uc3Qgc2VuZE1hbnlTdHViID0gc2lub24uc3R1Yih3YWxsZXQsICdzZW5kTWFueScpO1xuICAgICAgc2VuZE1hbnlTdHViLm9uRmlyc3RDYWxsKCkucmVzb2x2ZXMoe1xuICAgICAgICB0eFJlcXVlc3Q6IHtcbiAgICAgICAgICB0eFJlcXVlc3RJZDogJ3R4cmVxLWFwcHJvdmUtMScsXG4gICAgICAgICAgaW50ZW50OiB7IGludGVudFR5cGU6ICdkZWZpLWFwcHJvdmUnLCBvcGVyYXRpb25JZCB9LFxuICAgICAgICB9LFxuICAgICAgfSk7XG4gICAgICBzZW5kTWFueVN0dWIub25TZWNvbmRDYWxsKCkucmVzb2x2ZXMoe1xuICAgICAgICB0eFJlcXVlc3Q6IHtcbiAgICAgICAgICB0eFJlcXVlc3RJZDogJ3R4cmVxLWRlcG9zaXQtMScsXG4gICAgICAgICAgaW50ZW50OiB7IGludGVudFR5cGU6ICdkZWZpLWRlcG9zaXQnLCBvcGVyYXRpb25JZCB9LFxuICAgICAgICB9LFxuICAgICAgfSk7XG5cbiAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGRlZmlWYXVsdC5kZXBvc2l0VG9WYXVsdCh7XG4gICAgICAgIHZhdWx0SWQ6ICd2bHQtZ2FsYXh5LXVzZGMnLFxuICAgICAgICBhbW91bnQ6ICcxMDAwMDAwJyxcbiAgICAgIH0pO1xuXG4gICAgICByZXN1bHQub3BlcmF0aW9uSWQuc2hvdWxkLmVxdWFsKG9wZXJhdGlvbklkKTtcbiAgICAgIHJlc3VsdC50eFJlcXVlc3RJZHMuYXBwcm92ZS5zaG91bGQuZXF1YWwoJ3R4cmVxLWFwcHJvdmUtMScpO1xuICAgICAgcmVzdWx0LnR4UmVxdWVzdElkcy5kZXBvc2l0LnNob3VsZC5lcXVhbCgndHhyZXEtZGVwb3NpdC0xJyk7XG5cbiAgICAgIC8vIFZlcmlmeSBwcmUtZmxpZ2h0IHdhcyBjYWxsZWQgd2l0aCBjb3JyZWN0IHF1ZXJ5XG4gICAgICBwcmVmbGlnaHRSZXEucXVlcnkuY2FsbGVkV2l0aCh7IHZhdWx0SWQ6ICd2bHQtZ2FsYXh5LXVzZGMnLCBzdGF0ZTogJ2FjdGl2ZScgfSkuc2hvdWxkLmJlLnRydWUoKTtcblxuICAgICAgLy8gVmVyaWZ5IHNlbmRNYW55IHdhcyBjYWxsZWQgd2l0aCBjb3JyZWN0IHBhcmFtcyBmb3IgYXBwcm92ZVxuICAgICAgc2VuZE1hbnlTdHViLmNhbGxlZFR3aWNlLnNob3VsZC5iZS50cnVlKCk7XG4gICAgICBjb25zdCBhcHByb3ZlQXJnczogYW55ID0gc2VuZE1hbnlTdHViLmZpcnN0Q2FsbC5hcmdzWzBdO1xuICAgICAgYXBwcm92ZUFyZ3MudHlwZS5zaG91bGQuZXF1YWwoJ2RlZmlBcHByb3ZlJyk7XG4gICAgICBhcHByb3ZlQXJncy5kZWZpUGFyYW1zLnZhdWx0SWQuc2hvdWxkLmVxdWFsKCd2bHQtZ2FsYXh5LXVzZGMnKTtcbiAgICAgIGFwcHJvdmVBcmdzLmRlZmlQYXJhbXMuYW1vdW50LnNob3VsZC5lcXVhbCgnMTAwMDAwMCcpO1xuXG4gICAgICAvLyBWZXJpZnkgc2VuZE1hbnkgd2FzIGNhbGxlZCB3aXRoIGNvcnJlY3QgcGFyYW1zIGZvciBkZXBvc2l0XG4gICAgICBjb25zdCBkZXBvc2l0QXJnczogYW55ID0gc2VuZE1hbnlTdHViLnNlY29uZENhbGwuYXJnc1swXTtcbiAgICAgIGRlcG9zaXRBcmdzLnR5cGUuc2hvdWxkLmVxdWFsKCdkZWZpRGVwb3NpdCcpO1xuICAgICAgZGVwb3NpdEFyZ3MuZGVmaVBhcmFtcy5vcGVyYXRpb25JZC5zaG91bGQuZXF1YWwob3BlcmF0aW9uSWQpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZWplY3Qgd2hlbiBhbiBhY3RpdmUgb3BlcmF0aW9uIGFscmVhZHkgZXhpc3RzJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgcHJlZmxpZ2h0UmVxID0gbW9ja1JlcXVlc3Qoe1xuICAgICAgICBpdGVtczogW3sgb3BlcmF0aW9uSWQ6ICdleGlzdGluZy1vcC1pZCcsIHN0YXRlOiAnQVBQUk9WRV9UWF9SRVFVRVNURUQnIH1dLFxuICAgICAgfSk7XG4gICAgICBtb2NrQml0R28uZ2V0LnJldHVybnMocHJlZmxpZ2h0UmVxKTtcblxuICAgICAgYXdhaXQgYXNzZXJ0LnJlamVjdHMoXG4gICAgICAgICgpID0+IGRlZmlWYXVsdC5kZXBvc2l0VG9WYXVsdCh7IHZhdWx0SWQ6ICd2bHQtZ2FsYXh5LXVzZGMnLCBhbW91bnQ6ICcxMDAwMDAwJyB9KSxcbiAgICAgICAgKGVycjogRXJyb3IpID0+IHtcbiAgICAgICAgICAoZXJyIGluc3RhbmNlb2YgQWN0aXZlT3BlcmF0aW9uRXhpc3RzRXJyb3IpLnNob3VsZC5iZS50cnVlKCk7XG4gICAgICAgICAgKGVyciBhcyBBY3RpdmVPcGVyYXRpb25FeGlzdHNFcnJvcikub3BlcmF0aW9uSWQuc2hvdWxkLmVxdWFsKCdleGlzdGluZy1vcC1pZCcpO1xuICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9XG4gICAgICApO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBwcm9wYWdhdGUgZGVwb3NpdCBzZW5kTWFueSBmYWlsdXJlIHdpdGhvdXQgY2xlYW51cCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IG9wZXJhdGlvbklkID0gJ29wLXV1aWQtNDU2JztcblxuICAgICAgLy8gUHJlLWZsaWdodDogbm8gYWN0aXZlIG9wZXJhdGlvbnNcbiAgICAgIGNvbnN0IHByZWZsaWdodFJlcSA9IG1vY2tSZXF1ZXN0KHsgaXRlbXM6IFtdIH0pO1xuICAgICAgbW9ja0JpdEdvLmdldC5yZXR1cm5zKHByZWZsaWdodFJlcSk7XG5cbiAgICAgIC8vIE1vY2sgc2VuZE1hbnk6IGFwcHJvdmUgc3VjY2VlZHMsIGRlcG9zaXQgZmFpbHNcbiAgICAgIGNvbnN0IHNlbmRNYW55U3R1YiA9IHNpbm9uLnN0dWIod2FsbGV0LCAnc2VuZE1hbnknKTtcbiAgICAgIHNlbmRNYW55U3R1Yi5vbkZpcnN0Q2FsbCgpLnJlc29sdmVzKHtcbiAgICAgICAgdHhSZXF1ZXN0OiB7XG4gICAgICAgICAgdHhSZXF1ZXN0SWQ6ICd0eHJlcS1hcHByb3ZlLTInLFxuICAgICAgICAgIGludGVudDogeyBpbnRlbnRUeXBlOiAnZGVmaS1hcHByb3ZlJywgb3BlcmF0aW9uSWQgfSxcbiAgICAgICAgfSxcbiAgICAgIH0pO1xuICAgICAgc2VuZE1hbnlTdHViLm9uU2Vjb25kQ2FsbCgpLnJlamVjdHMobmV3IEVycm9yKCdkZXBvc2l0IGNyZWF0aW9uIGZhaWxlZCcpKTtcblxuICAgICAgYXdhaXQgYXNzZXJ0LnJlamVjdHMoKCkgPT4gZGVmaVZhdWx0LmRlcG9zaXRUb1ZhdWx0KHsgdmF1bHRJZDogJ3ZsdC1nYWxheHktdXNkYycsIGFtb3VudDogJzEwMDAwMDAnIH0pLCB7XG4gICAgICAgIG1lc3NhZ2U6ICdkZXBvc2l0IGNyZWF0aW9uIGZhaWxlZCcsXG4gICAgICB9KTtcblxuICAgICAgLy8gU0RLIGRvZXMgbm90IGF0dGVtcHQgY2xlYW51cCDigJQgcmVjb25jaWxlciBoYW5kbGVzIG9ycGhhbmVkIGFwcHJvdmFsc1xuICAgICAgbW9ja0JpdEdvLmRlbC5jYWxsZWQuc2hvdWxkLmJlLmZhbHNlKCk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHRocm93IGlmIHZhdWx0SWQgaXMgbWlzc2luZycsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGF3YWl0IGFzc2VydC5yZWplY3RzKCgpID0+IGRlZmlWYXVsdC5kZXBvc2l0VG9WYXVsdCh7IHZhdWx0SWQ6ICcnLCBhbW91bnQ6ICcxMDAwMDAwJyB9KSwge1xuICAgICAgICBtZXNzYWdlOiAndmF1bHRJZCBpcyByZXF1aXJlZCcsXG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgdGhyb3cgaWYgYW1vdW50IGlzIG1pc3NpbmcnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBhd2FpdCBhc3NlcnQucmVqZWN0cygoKSA9PiBkZWZpVmF1bHQuZGVwb3NpdFRvVmF1bHQoeyB2YXVsdElkOiAndmx0LTEnLCBhbW91bnQ6ICcnIH0pLCB7XG4gICAgICAgIG1lc3NhZ2U6ICdhbW91bnQgaXMgcmVxdWlyZWQnLFxuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHBhc3MgY2xpZW50SWRlbXBvdGVuY3lLZXkgYW5kIHdhbGxldFBhc3NwaHJhc2Ugd2hlbiBwcm92aWRlZCcsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IG9wZXJhdGlvbklkID0gJ29wLXV1aWQtNzg5JztcblxuICAgICAgY29uc3QgcHJlZmxpZ2h0UmVxID0gbW9ja1JlcXVlc3QoeyBpdGVtczogW10gfSk7XG4gICAgICBtb2NrQml0R28uZ2V0LnJldHVybnMocHJlZmxpZ2h0UmVxKTtcblxuICAgICAgY29uc3Qgc2VuZE1hbnlTdHViID0gc2lub24uc3R1Yih3YWxsZXQsICdzZW5kTWFueScpO1xuICAgICAgc2VuZE1hbnlTdHViLm9uRmlyc3RDYWxsKCkucmVzb2x2ZXMoe1xuICAgICAgICB0eFJlcXVlc3Q6IHtcbiAgICAgICAgICB0eFJlcXVlc3RJZDogJ3R4cmVxLWFwcHJvdmUtMycsXG4gICAgICAgICAgaW50ZW50OiB7IGludGVudFR5cGU6ICdkZWZpLWFwcHJvdmUnLCBvcGVyYXRpb25JZCB9LFxuICAgICAgICB9LFxuICAgICAgfSk7XG4gICAgICBzZW5kTWFueVN0dWIub25TZWNvbmRDYWxsKCkucmVzb2x2ZXMoe1xuICAgICAgICB0eFJlcXVlc3Q6IHtcbiAgICAgICAgICB0eFJlcXVlc3RJZDogJ3R4cmVxLWRlcG9zaXQtMycsXG4gICAgICAgICAgaW50ZW50OiB7IGludGVudFR5cGU6ICdkZWZpLWRlcG9zaXQnLCBvcGVyYXRpb25JZCB9LFxuICAgICAgICB9LFxuICAgICAgfSk7XG5cbiAgICAgIGF3YWl0IGRlZmlWYXVsdC5kZXBvc2l0VG9WYXVsdCh7XG4gICAgICAgIHZhdWx0SWQ6ICd2bHQtZ2FsYXh5LXVzZGMnLFxuICAgICAgICBhbW91bnQ6ICcxMDAwMDAwJyxcbiAgICAgICAgY2xpZW50SWRlbXBvdGVuY3lLZXk6ICdpZGVtLWtleS0xMjMnLFxuICAgICAgICB3YWxsZXRQYXNzcGhyYXNlOiAndGVzdC1wYXNzcGhyYXNlJyxcbiAgICAgIH0pO1xuXG4gICAgICBjb25zdCBhcHByb3ZlQXJnczogYW55ID0gc2VuZE1hbnlTdHViLmZpcnN0Q2FsbC5hcmdzWzBdO1xuICAgICAgYXBwcm92ZUFyZ3MuZGVmaVBhcmFtcy5jbGllbnRJZGVtcG90ZW5jeUtleS5zaG91bGQuZXF1YWwoJ2lkZW0ta2V5LTEyMycpO1xuICAgICAgYXBwcm92ZUFyZ3Mud2FsbGV0UGFzc3BocmFzZS5zaG91bGQuZXF1YWwoJ3Rlc3QtcGFzc3BocmFzZScpO1xuXG4gICAgICBjb25zdCBkZXBvc2l0QXJnczogYW55ID0gc2VuZE1hbnlTdHViLnNlY29uZENhbGwuYXJnc1swXTtcbiAgICAgIGRlcG9zaXRBcmdzLmRlZmlQYXJhbXMuY2xpZW50SWRlbXBvdGVuY3lLZXkuc2hvdWxkLmVxdWFsKCdpZGVtLWtleS0xMjMnKTtcbiAgICAgIGRlcG9zaXRBcmdzLndhbGxldFBhc3NwaHJhc2Uuc2hvdWxkLmVxdWFsKCd0ZXN0LXBhc3NwaHJhc2UnKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ3Jlc3VtZURlcG9zaXQnLCBmdW5jdGlvbiAoKSB7XG4gICAgaXQoJ3Nob3VsZCBpc3N1ZSB0aGUgZGVwb3NpdCBzZW5kTWFueSBmb3IgYSBwYXJ0aWFsIG9wZXJhdGlvbicsIGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IG9wZXJhdGlvbiA9IHtcbiAgICAgICAgb3BlcmF0aW9uSWQ6ICdvcC1yZXN1bWUtMScsXG4gICAgICAgIHdhbGxldElkOiAndGVzdC13YWxsZXQtaWQnLFxuICAgICAgICB2YXVsdElkOiAndmx0LWdhbGF4eS11c2RjJyxcbiAgICAgICAgdHlwZTogJ0RFUE9TSVQnLFxuICAgICAgICBhc3NldEFtb3VudDogJzEwMDAwMDAnLFxuICAgICAgICBzdGF0ZTogJ0FQUFJPVkVfVFhfUkVRVUVTVEVEJyxcbiAgICAgICAgdHhSZXF1ZXN0SWQ6ICd0eHJlcS1hcHByb3ZlLWV4aXN0aW5nJyxcbiAgICAgICAgYXNzb2NpYXRlZFR4UmVxdWVzdElkOiB1bmRlZmluZWQsXG4gICAgICAgIGNyZWF0ZWRBdDogJzIwMjYtMDUtMTRUMDc6MTI6MDBaJyxcbiAgICAgICAgdXBkYXRlZEF0OiAnMjAyNi0wNS0xNFQwNzoxMjowMFonLFxuICAgICAgfTtcblxuICAgICAgLy8gZ2V0T3BlcmF0aW9uIGNhbGxcbiAgICAgIGNvbnN0IGdldE9wUmVxID0gbW9ja1JlcXVlc3Qob3BlcmF0aW9uKTtcbiAgICAgIG1vY2tCaXRHby5nZXQucmV0dXJucyhnZXRPcFJlcSk7XG5cbiAgICAgIC8vIGRlcG9zaXQgc2VuZE1hbnlcbiAgICAgIGNvbnN0IHNlbmRNYW55U3R1YiA9IHNpbm9uLnN0dWIod2FsbGV0LCAnc2VuZE1hbnknKTtcbiAgICAgIHNlbmRNYW55U3R1Yi5yZXNvbHZlcyh7XG4gICAgICAgIHR4UmVxdWVzdDoge1xuICAgICAgICAgIHR4UmVxdWVzdElkOiAndHhyZXEtZGVwb3NpdC1yZXN1bWUnLFxuICAgICAgICAgIGludGVudDogeyBpbnRlbnRUeXBlOiAnZGVmaS1kZXBvc2l0Jywgb3BlcmF0aW9uSWQ6ICdvcC1yZXN1bWUtMScgfSxcbiAgICAgICAgfSxcbiAgICAgIH0pO1xuXG4gICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBkZWZpVmF1bHQucmVzdW1lRGVwb3NpdCh7IG9wZXJhdGlvbklkOiAnb3AtcmVzdW1lLTEnIH0pO1xuXG4gICAgICByZXN1bHQub3BlcmF0aW9uSWQuc2hvdWxkLmVxdWFsKCdvcC1yZXN1bWUtMScpO1xuICAgICAgcmVzdWx0LnR4UmVxdWVzdElkcy5hcHByb3ZlLnNob3VsZC5lcXVhbCgndHhyZXEtYXBwcm92ZS1leGlzdGluZycpO1xuICAgICAgcmVzdWx0LnR4UmVxdWVzdElkcy5kZXBvc2l0LnNob3VsZC5lcXVhbCgndHhyZXEtZGVwb3NpdC1yZXN1bWUnKTtcblxuICAgICAgLy8gVmVyaWZ5IHNlbmRNYW55IHdhcyBjYWxsZWQgd2l0aCBjb3JyZWN0IGRlZmlQYXJhbXNcbiAgICAgIGNvbnN0IGRlcG9zaXRBcmdzOiBhbnkgPSBzZW5kTWFueVN0dWIuZmlyc3RDYWxsLmFyZ3NbMF07XG4gICAgICBkZXBvc2l0QXJncy50eXBlLnNob3VsZC5lcXVhbCgnZGVmaURlcG9zaXQnKTtcbiAgICAgIGRlcG9zaXRBcmdzLmRlZmlQYXJhbXMudmF1bHRJZC5zaG91bGQuZXF1YWwoJ3ZsdC1nYWxheHktdXNkYycpO1xuICAgICAgZGVwb3NpdEFyZ3MuZGVmaVBhcmFtcy5hbW91bnQuc2hvdWxkLmVxdWFsKCcxMDAwMDAwJyk7XG4gICAgICBkZXBvc2l0QXJncy5kZWZpUGFyYW1zLm9wZXJhdGlvbklkLnNob3VsZC5lcXVhbCgnb3AtcmVzdW1lLTEnKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgdGhyb3cgaWYgZGVwb3NpdCB0eFJlcXVlc3QgYWxyZWFkeSBleGlzdHMnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBvcGVyYXRpb24gPSB7XG4gICAgICAgIG9wZXJhdGlvbklkOiAnb3AtYWxyZWFkeS1kb25lJyxcbiAgICAgICAgd2FsbGV0SWQ6ICd0ZXN0LXdhbGxldC1pZCcsXG4gICAgICAgIHZhdWx0SWQ6ICd2bHQtZ2FsYXh5LXVzZGMnLFxuICAgICAgICB0eXBlOiAnREVQT1NJVCcsXG4gICAgICAgIGFzc2V0QW1vdW50OiAnMTAwMDAwMCcsXG4gICAgICAgIHN0YXRlOiAnREVQT1NJVF9UWF9SRVFVRVNURUQnLFxuICAgICAgICB0eFJlcXVlc3RJZDogJ3R4cmVxLWFwcHJvdmUteCcsXG4gICAgICAgIGFzc29jaWF0ZWRUeFJlcXVlc3RJZDogJ3R4cmVxLWRlcG9zaXQteCcsXG4gICAgICAgIGNyZWF0ZWRBdDogJzIwMjYtMDUtMTRUMDc6MTI6MDBaJyxcbiAgICAgICAgdXBkYXRlZEF0OiAnMjAyNi0wNS0xNFQwNzoxMjowMFonLFxuICAgICAgfTtcblxuICAgICAgY29uc3QgZ2V0T3BSZXEgPSBtb2NrUmVxdWVzdChvcGVyYXRpb24pO1xuICAgICAgbW9ja0JpdEdvLmdldC5yZXR1cm5zKGdldE9wUmVxKTtcblxuICAgICAgYXdhaXQgYXNzZXJ0LnJlamVjdHMoKCkgPT4gZGVmaVZhdWx0LnJlc3VtZURlcG9zaXQoeyBvcGVyYXRpb25JZDogJ29wLWFscmVhZHktZG9uZScgfSksIHtcbiAgICAgICAgbWVzc2FnZTogJ0RlcG9zaXQgdHhSZXF1ZXN0IGFscmVhZHkgZXhpc3RzIGZvciB0aGlzIG9wZXJhdGlvbjsgbm90aGluZyB0byByZXN1bWUnLFxuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHRocm93IGlmIG9wZXJhdGlvbklkIGlzIG1pc3NpbmcnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBhd2FpdCBhc3NlcnQucmVqZWN0cygoKSA9PiBkZWZpVmF1bHQucmVzdW1lRGVwb3NpdCh7IG9wZXJhdGlvbklkOiAnJyB9KSwgeyBtZXNzYWdlOiAnb3BlcmF0aW9uSWQgaXMgcmVxdWlyZWQnIH0pO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnZ2V0T3BlcmF0aW9uJywgZnVuY3Rpb24gKCkge1xuICAgIGl0KCdzaG91bGQgZmV0Y2ggYW4gb3BlcmF0aW9uIGJ5IElEJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3Qgb3BlcmF0aW9uID0ge1xuICAgICAgICBvcGVyYXRpb25JZDogJ29wLWdldC0xJyxcbiAgICAgICAgd2FsbGV0SWQ6ICd0ZXN0LXdhbGxldC1pZCcsXG4gICAgICAgIHZhdWx0SWQ6ICd2bHQtZ2FsYXh5LXVzZGMnLFxuICAgICAgICB0eXBlOiAnREVQT1NJVCcsXG4gICAgICAgIGFzc2V0QW1vdW50OiAnMTAwMDAwMCcsXG4gICAgICAgIHN0YXRlOiAnQ09NUExFVEVEJyxcbiAgICAgICAgdHhSZXF1ZXN0SWQ6ICd0eHJlcS0xJyxcbiAgICAgICAgYXNzb2NpYXRlZFR4UmVxdWVzdElkOiAndHhyZXEtMicsXG4gICAgICAgIGNyZWF0ZWRBdDogJzIwMjYtMDUtMTRUMDc6MTI6MDBaJyxcbiAgICAgICAgdXBkYXRlZEF0OiAnMjAyNi0wNS0xNFQwNzoxODowMFonLFxuICAgICAgfTtcblxuICAgICAgY29uc3QgcmVxID0gbW9ja1JlcXVlc3Qob3BlcmF0aW9uKTtcbiAgICAgIG1vY2tCaXRHby5nZXQucmV0dXJucyhyZXEpO1xuXG4gICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBkZWZpVmF1bHQuZ2V0T3BlcmF0aW9uKHsgb3BlcmF0aW9uSWQ6ICdvcC1nZXQtMScgfSk7XG4gICAgICByZXN1bHQuc2hvdWxkLmRlZXBFcXVhbChvcGVyYXRpb24pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCB0aHJvdyBpZiBvcGVyYXRpb25JZCBpcyBtaXNzaW5nJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgYXdhaXQgYXNzZXJ0LnJlamVjdHMoKCkgPT4gZGVmaVZhdWx0LmdldE9wZXJhdGlvbih7IG9wZXJhdGlvbklkOiAnJyB9KSwgeyBtZXNzYWdlOiAnb3BlcmF0aW9uSWQgaXMgcmVxdWlyZWQnIH0pO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnbGlzdE9wZXJhdGlvbnMnLCBmdW5jdGlvbiAoKSB7XG4gICAgaXQoJ3Nob3VsZCBsaXN0IG9wZXJhdGlvbnMgZm9yIGEgdmF1bHQnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBsaXN0UmVzdWx0ID0ge1xuICAgICAgICBpdGVtczogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIG9wZXJhdGlvbklkOiAnb3AtMScsXG4gICAgICAgICAgICB3YWxsZXRJZDogJ3Rlc3Qtd2FsbGV0LWlkJyxcbiAgICAgICAgICAgIHZhdWx0SWQ6ICd2bHQtZ2FsYXh5LXVzZGMnLFxuICAgICAgICAgICAgdHlwZTogJ0RFUE9TSVQnLFxuICAgICAgICAgICAgYXNzZXRBbW91bnQ6ICcxMDAwMDAwJyxcbiAgICAgICAgICAgIHN0YXRlOiAnQ09NUExFVEVEJyxcbiAgICAgICAgICAgIGNyZWF0ZWRBdDogJzIwMjYtMDUtMTRUMDc6MTI6MDBaJyxcbiAgICAgICAgICAgIHVwZGF0ZWRBdDogJzIwMjYtMDUtMTRUMDc6MTg6MDBaJyxcbiAgICAgICAgICB9LFxuICAgICAgICBdLFxuICAgICAgICBuZXh0Q3Vyc29yOiAnY3Vyc29yLWFiYycsXG4gICAgICB9O1xuXG4gICAgICBjb25zdCByZXEgPSBtb2NrUmVxdWVzdChsaXN0UmVzdWx0KTtcbiAgICAgIG1vY2tCaXRHby5nZXQucmV0dXJucyhyZXEpO1xuXG4gICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBkZWZpVmF1bHQubGlzdE9wZXJhdGlvbnMoe1xuICAgICAgICB2YXVsdElkOiAndmx0LWdhbGF4eS11c2RjJyxcbiAgICAgICAgc3RhdGU6ICdDT01QTEVURUQnLFxuICAgICAgICBsaW1pdDogMTAsXG4gICAgICB9KTtcblxuICAgICAgcmVzdWx0Lml0ZW1zLmxlbmd0aC5zaG91bGQuZXF1YWwoMSk7XG4gICAgICByZXN1bHQubmV4dEN1cnNvciEuc2hvdWxkLmVxdWFsKCdjdXJzb3ItYWJjJyk7XG5cbiAgICAgIC8vIFZlcmlmeSBxdWVyeSBwYXJhbXNcbiAgICAgIGNvbnN0IHF1ZXJ5QXJncyA9IHJlcS5xdWVyeS5maXJzdENhbGwuYXJnc1swXTtcbiAgICAgIHF1ZXJ5QXJncy52YXVsdElkLnNob3VsZC5lcXVhbCgndmx0LWdhbGF4eS11c2RjJyk7XG4gICAgICBxdWVyeUFyZ3Muc3RhdGUuc2hvdWxkLmVxdWFsKCdDT01QTEVURUQnKTtcbiAgICAgIHF1ZXJ5QXJncy5saW1pdC5zaG91bGQuZXF1YWwoMTApO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCB0aHJvdyBpZiB2YXVsdElkIGlzIG1pc3NpbmcnLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICBhd2FpdCBhc3NlcnQucmVqZWN0cygoKSA9PiBkZWZpVmF1bHQubGlzdE9wZXJhdGlvbnMoeyB2YXVsdElkOiAnJyB9KSwgeyBtZXNzYWdlOiAndmF1bHRJZCBpcyByZXF1aXJlZCcgfSk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCd3YWxsZXQuZGVmaSBnZXR0ZXInLCBmdW5jdGlvbiAoKSB7XG4gICAgaXQoJ3Nob3VsZCByZXR1cm4gYSBEZWZpVmF1bHQgaW5zdGFuY2UnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBkZWZpID0gd2FsbGV0LmRlZmk7XG4gICAgICAoZGVmaSBpbnN0YW5jZW9mIERlZmlWYXVsdCkuc2hvdWxkLmJlLnRydWUoKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgcmV0dXJuIHRoZSBzYW1lIGluc3RhbmNlIG9uIHN1YnNlcXVlbnQgY2FsbHMnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBkZWZpMSA9IHdhbGxldC5kZWZpO1xuICAgICAgY29uc3QgZGVmaTIgPSB3YWxsZXQuZGVmaTtcbiAgICAgIChkZWZpMSA9PT0gZGVmaTIpLnNob3VsZC5iZS50cnVlKCk7XG4gICAgfSk7XG4gIH0pO1xufSk7XG4iXX0=
|